{
var type = li.Type;
- if (type.BuiltinType != BuiltinTypeSpec.Type.IDisposable && !type.ImplementsInterface (bc.BuiltinTypes.IDisposable, false)) {
+ if (type.BuiltinType != BuiltinTypeSpec.Type.IDisposable && !CanConvertToIDisposable (bc, type)) {
if (type.IsNullableType) {
// it's handled in CreateDisposeCall
return;
}
}
+ static bool CanConvertToIDisposable (BlockContext bc, TypeSpec type)
+ {
+ var target = bc.BuiltinTypes.IDisposable;
+ var tp = type as TypeParameterSpec;
+ if (tp != null)
+ return Convert.ImplicitTypeParameterConversion (null, tp, target) != null;
+
+ return type.ImplementsInterface (target, false);
+ }
+
protected virtual Statement CreateDisposeCall (BlockContext bc, LocalVariable lv)
{
var lvr = lv.CreateReferenceExpression (bc, lv.Location);
Statement dispose = new StatementExpression (new Invocation (dispose_mg, null), Location.Null);
// Add conditional call when disposing possible null variable
- if (!type.IsStruct || type.IsNullableType)
+ if (!TypeSpec.IsValueType (type) || type.IsNullableType)
dispose = new If (new Binary (Binary.Operator.Inequality, lvr, new NullLiteral (loc)), dispose, dispose.loc);
return dispose;
--- /dev/null
+using System;
+
+class R<T, U>
+ where T : System.IDisposable
+ where U : T
+{
+ public void M (U u)
+ {
+ using (u) {
+ }
+ }
+}
+
+struct S<T, U>
+ where T : System.IDisposable
+ where U : struct, T
+{
+ public void M (U u)
+ {
+ using (u) {
+ }
+ }
+}
+
+class X : IDisposable
+{
+ public void Dispose ()
+ {
+ }
+
+ public static void Main ()
+ {
+ new R<X, X> ().M (new X ());
+ new S<Y, Y> ().M (new Y ());
+ }
+}
+
+struct Y : IDisposable
+{
+ public void Dispose ()
+ {
+ }
+}
\ No newline at end of file
</method>\r
</type>\r
</test>\r
+ <test name="gtest-608.cs">\r
+ <type name="R`2[T,U]">\r
+ <method name="Void M(U)" attrs="134">\r
+ <size>36</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="S`2[T,U]">\r
+ <method name="Void M(U)" attrs="134">\r
+ <size>25</size>\r
+ </method>\r
+ </type>\r
+ <type name="X">\r
+ <method name="Void Dispose()" attrs="486">\r
+ <size>2</size>\r
+ </method>\r
+ <method name="Void Main()" attrs="150">\r
+ <size>41</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="Y">\r
+ <method name="Void Dispose()" attrs="486">\r
+ <size>2</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="gtest-anontype-01.cs">\r
<type name="Test">\r
<method name="Int32 Main()" attrs="150">\r