{
public DynamicSiteClass (DeclSpace parent)
: base (parent, new MemberName (CompilerGeneratedClass.MakeName (null, "c", "DynamicSite", 0)),
- Modifiers.INTERNAL | Modifiers.STATIC)
+ Modifiers.PRIVATE | Modifiers.STATIC)
{
}
}
Upper = 2
}
- class BoundInfo
+ class BoundInfo : IEquatable<BoundInfo>
{
public readonly TypeSpec Type;
public readonly BoundKind Kind;
public BoundInfo (TypeSpec type, BoundKind kind)
{
- // Unify dynamic and object to simplify best candidate resolution
- if (type == InternalType.Dynamic)
- type = TypeManager.object_type;
-
this.Type = type;
this.Kind = kind;
}
return Type.GetHashCode ();
}
- public override bool Equals (object obj)
+ #region IEquatable<BoundInfo> Members
+
+ public bool Equals (BoundInfo other)
{
- BoundInfo a = (BoundInfo) obj;
- return Type == a.Type && Kind == a.Kind;
+ return Type == other.Type && Kind == other.Kind;
}
+
+ #endregion
}
readonly TypeSpec[] unfixed_types;
if (cii != candidates_count)
continue;
- if (best_candidate != null && best_candidate != bound.Type)
- return false;
+ //
+ // We already have the best candidate, break if thet are different
+ //
+ // Dynamic is never ambiguous as we prefer dynamic over other best candidate types
+ //
+ if (best_candidate != null) {
+
+ if (best_candidate == InternalType.Dynamic)
+ continue;
+
+ if (bound.Type != InternalType.Dynamic && best_candidate != bound.Type)
+ return false;
+ }
best_candidate = bound.Type;
}
VarExpr ve = var_type as VarExpr;
if (ve != null) {
- // Infer implicitly typed local variable from foreach enumerable type
- var_type = new TypeExpression (current_pe.Type, var_type.Location);
+ if (is_dynamic) {
+ // Source type is dynamic, set element type to dynamic too
+ var_type = new TypeExpression (InternalType.Dynamic, var_type.Location);
+ } else {
+ // Infer implicitly typed local variable from foreach enumerable type
+ var_type = new TypeExpression (current_pe.Type, var_type.Location);
+ }
}
var_type = var_type.ResolveAsTypeTerminal (ec, false);
Console.WriteLine (res);
return res == 31;
}
+
+ bool ForEachTest_2()
+ {
+ dynamic c = new int [2] { 5, 7 };
+ int total = 0;
+ foreach (var v in c)
+ {
+ total += v;
+ }
+
+ return total == 12;
+ }
bool UsingTest ()
{
if (!t.ForEachTest ())
return 1;
- if (!t.UsingTest ())
+ if (!t.ForEachTest_2 ())
return 2;
+
+ if (!t.UsingTest ())
+ return 3;
Console.WriteLine ("ok");
return 0;
--- /dev/null
+public class C
+{
+ void Method ()
+ {
+ }
+
+ public static int Main ()
+ {
+ dynamic d = new C ();
+ var a = new [] { d, (object) null };
+ a[0].Method();
+ return 0;
+ }
+}
\ No newline at end of file
<size>1</size>
</method>
<method name="Void ConvertImplicitTest()">
- <size>1017</size>
+ <size>1331</size>
</method>
<method name="Int32 ConvertImplicitReturnTest()">
<size>75</size>
<size>862</size>
</method>
<method name="Int32 Main()">
- <size>44</size>
+ <size>57</size>
</method>
<method name="Void .ctor()">
<size>7</size>
</method>
+ <method name="Boolean ForEachTest_2()">
+ <size>300</size>
+ </method>
</type>
</test>
<test name="dtest-009.cs">
</method>
</type>
</test>
+ <test name="dtest-implicitarray-01.cs">
+ <type name="C">
+ <method name="Void Method()">
+ <size>1</size>
+ </method>
+ <method name="Int32 Main()">
+ <size>104</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="dtest-iter-01.cs">
<type name="Program">
<method name="IEnumerable`1 D1()">