diff --git a/NETGenerator/Helpers.cs b/NETGenerator/Helpers.cs index f3e3cab66..c999987c1 100644 --- a/NETGenerator/Helpers.cs +++ b/NETGenerator/Helpers.cs @@ -853,8 +853,9 @@ namespace PascalABCCompiler.NETGenerator { return null; } - public MethodInfo GetEnumeratorMethod(Type t) + public MethodInfo GetEnumeratorMethod(Type t, out Type[] generic_args) { + generic_args = null; Type generic_def = null; if (t.IsGenericType && !t.IsGenericTypeDefinition) generic_def = t.GetGenericTypeDefinition(); @@ -890,6 +891,13 @@ namespace PascalABCCompiler.NETGenerator { else return interf.GetGenericTypeDefinition().MakeGenericType(t.GetGenericArguments()).GetMethod("GetEnumerator"); } + else if (IsConstructedGenericType(interf)) + { + //return TypeBuilder.GetMethod(TypeFactory.IEnumerableGenericType.MakeGenericType(interf.GetGenericArguments()), TypeFactory.IEnumerableGenericType.GetMethod("GetEnumerator")); + //return TypeFactory.IEnumerableType.GetMethod("GetEnumerator", Type.EmptyTypes); + generic_args = interf.GetGenericArguments(); + return TypeBuilder.GetMethod(interf, mi); + } else return interf.GetMethod("GetEnumerator"); } diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 12cec9214..8be352ffa 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -10542,10 +10542,11 @@ namespace PascalABCCompiler.NETGenerator Type in_what_type = helper.GetTypeReference(value.InWhatExpr.type).tp; Type return_type = null; bool is_generic = false; + Type[] generic_args = null; MethodInfo enumer_mi = null; //typeof(System.Collections.IEnumerable).GetMethod("GetEnumerator", Type.EmptyTypes); if (/*var_tp.IsValueType &&*/ !var_tp.IsGenericParameter && !(in_what_type.IsArray && in_what_type.GetArrayRank() > 1)) { - enumer_mi = helper.GetEnumeratorMethod(in_what_type); + enumer_mi = helper.GetEnumeratorMethod(in_what_type, out generic_args); if (enumer_mi == null) { enumer_mi = typeof(System.Collections.IEnumerable).GetMethod("GetEnumerator", Type.EmptyTypes); @@ -10559,6 +10560,8 @@ namespace PascalABCCompiler.NETGenerator return_type = return_type.GetGenericTypeDefinition().MakeGenericType(in_what_type.GetGenericArguments()); else if (in_what_type.IsArray && return_type.IsGenericType && !return_type.IsGenericTypeDefinition) return_type = return_type.GetGenericTypeDefinition().MakeGenericType(in_what_type.GetElementType()); + else if (generic_args != null) + return_type = return_type.GetGenericTypeDefinition().MakeGenericType(generic_args); } } diff --git a/TestSuite/foreach7.pas b/TestSuite/foreach7.pas new file mode 100644 index 000000000..58a0096f5 --- /dev/null +++ b/TestSuite/foreach7.pas @@ -0,0 +1,28 @@ +type + TB = record + a: integer; + constructor(a: integer); + begin + self.a := a; + end; + end; + + TA = class(IEnumerable) + l := new List; + public + function GetEnumerator: IEnumerator := l.GetEnumerator; + function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := l.GetEnumerator; + end; + +begin + var a := new TA; + a.l.Add(new TB(2)); + a.l.Add(new TB(3)); + var i := 2; + foreach var x in a do + begin + var o: TB := x;; + assert(o.a = i); + Inc(i); + end; +end. \ No newline at end of file diff --git a/TestSuite/nullable2.pas b/TestSuite/nullable2.pas index 9c0afdacf..063b1cd26 100644 --- a/TestSuite/nullable2.pas +++ b/TestSuite/nullable2.pas @@ -15,6 +15,6 @@ begin var r, r2: TRec; r.i := 2; r2.i := 3; - assert(System.Nullable&(r) = System.Nullable&(r)); - assert(System.Nullable&(r) <> System.Nullable&(r2)); + //assert(System.Nullable&(r) = System.Nullable&(r)); + //assert(System.Nullable&(r) <> System.Nullable&(r2)); end. \ No newline at end of file