Enable await expressions to work with dynamic binder
[mono.git] / mcs / mcs / class.cs
index b85b1658a77b91dc9097a2c4163f23fdb96327a7..c9dd88543849db374d6986df6c4a343541ed7461 100644 (file)
@@ -99,7 +99,7 @@ namespace Mono.CSharp
                                return tc.GetSignatureForError ();
                        }
 
-                       public IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceContainer scope)
+                       public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
                        {
                                return null;
                        }
@@ -738,7 +738,7 @@ namespace Mono.CSharp
                                        ExpressionStatement s = fi.ResolveStatement (ec);
                                        if (s == null) {
                                                s = EmptyExpressionStatement.Instance;
-                                       } else if (fi.IsComplexInitializer) {
+                                       } else if (!fi.IsSideEffectFree) {
                                                has_complex_initializer |= true;
                                        }
 
@@ -1130,16 +1130,19 @@ namespace Mono.CSharp
 
                                GenericMethod generic_method;
                                MemberName member_name;
+                               TypeArguments targs = null;
                                if (method.IsGeneric) {
                                        //
                                        // Copy all base generic method type parameters info
                                        //
                                        var hoisted_tparams = method.GenericDefinition.TypeParameters;
-                                       var targs = new TypeArguments ();
                                        var type_params = new TypeParameter[hoisted_tparams.Length];
+                                       targs = new TypeArguments ();
+                                       targs.Arguments = new TypeSpec[type_params.Length];
                                        for (int i = 0; i < type_params.Length; ++i) {
                                                var tp = hoisted_tparams[i];
                                                targs.Add (new TypeParameterName (tp.Name, null, Location));
+                                               targs.Arguments[i] = tp;
                                                type_params[i] = new TypeParameter (tp, this, null, new MemberName (tp.Name), null);
                                        }
 
@@ -1160,6 +1163,8 @@ namespace Mono.CSharp
 
                                var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
                                mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
+                               if (targs != null)
+                                       mg.SetTypeArguments (rc, targs);
 
                                // Get all the method parameters and pass them as arguments
                                var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
@@ -1215,20 +1220,6 @@ namespace Mono.CSharp
                                        if (!spec.AddInterface (iface_type))
                                                continue;
 
-                                       if (iface_type.IsGeneric && spec.Interfaces != null) {
-                                               foreach (var prev_iface in iface_exprs) {
-                                                       if (prev_iface == iface_type)
-                                                               break;
-
-                                                       if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
-                                                               continue;
-
-                                                       Report.Error (695, Location,
-                                                               "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
-                                                               GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
-                                               }
-                                       }
-
                                        TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
 
                                        // Ensure the base is always setup
@@ -1560,6 +1551,20 @@ namespace Mono.CSharp
                                                                GetSignatureForError (), iface_type.GetSignatureForError ());
                                                        return false;
                                                }
+
+                                               if (spec.Interfaces != null) {
+                                                       foreach (var prev_iface in iface_exprs) {
+                                                               if (prev_iface == iface_type)
+                                                                       break;
+
+                                                               if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
+                                                                       continue;
+
+                                                               Report.Error (695, Location,
+                                                                       "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
+                                                                       GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
+                                                       }
+                                               }
                                        }
                                }
                        }
@@ -1779,14 +1784,14 @@ namespace Mono.CSharp
                                                        continue;
                                                }
                                                
+                                               if ((f.caching_flags & Flags.IsAssigned) != 0)
+                                                       continue;
+
                                                //
                                                // Only report 649 on level 4
                                                //
                                                if (Report.WarningLevel < 4)
                                                        continue;
-                                               
-                                               if ((f.caching_flags & Flags.IsAssigned) != 0)
-                                                       continue;
 
                                                //
                                                // Don't be pendatic over serializable attributes
@@ -1795,8 +1800,24 @@ namespace Mono.CSharp
                                                        continue;
                                                
                                                Constant c = New.Constantify (f.MemberType, f.Location);
-                                               Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
-                                                       f.GetSignatureForError (), c == null ? "null" : c.GetValueAsLiteral ());
+                                               string value;
+                                               if (c != null) {
+                                                       value = c.GetValueAsLiteral ();
+                                               } else if (TypeSpec.IsReferenceType (f.MemberType)) {
+                                                       value = "null";
+                                               } else {
+                                                       // Ignore this warning for struct value fields (they are always initialized)
+                                                       if (f.MemberType.IsStruct)
+                                                               continue;
+
+                                                       value = null;
+                                               }
+
+                                               if (value != null)
+                                                       value = " `" + value + "'";
+
+                                               Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
+                                                       f.GetSignatureForError (), value);
                                        }
                                }
                        }
@@ -2416,18 +2437,19 @@ namespace Mono.CSharp
                        }
                }
 
-               public override IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceContainer scope)
+               public override ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
                {
                        DeclSpace top_level = Parent;
                        if (top_level != null) {
-                               var candidates = NamespaceEntry.NS.LookupExtensionMethod (this, extensionType, name, arity);
-                               if (candidates != null) {
-                                       scope = NamespaceEntry;
-                                       return candidates;
+                               var methods = NamespaceEntry.NS.LookupExtensionMethod (this, extensionType, name, arity);
+                               if (methods != null) {
+                                       return new ExtensionMethodCandidates (methods, NamespaceEntry, NamespaceEntry.NS) {
+                                               HasUninspectedMembers = true
+                                       };
                                }
                        }
 
-                       return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity, ref scope);
+                       return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity);
                }
 
                protected override TypeAttributes TypeAttr {