Index: vala/valaforeachstatement.vala =================================================================== --- vala/valaforeachstatement.vala (revision 602) +++ vala/valaforeachstatement.vala (working copy) @@ -49,8 +49,13 @@ _collection.parent_node = this; } } - + /** + * Specifies the method that returns the iterator + */ + public Method! iterator_method { get; set; } + + /** * Specifies the loop body. */ public Block body { Index: vala/valasemanticanalyzer.vala =================================================================== --- vala/valasemanticanalyzer.vala (revision 602) +++ vala/valasemanticanalyzer.vala (working copy) @@ -886,15 +886,20 @@ stmt.collection_variable_declarator.active = true; var collection_type = stmt.collection.static_type.data_type; - if (iterable_type != null && collection_type.is_subtype_of (iterable_type)) { + + TypeReference iter_as_reference = new TypeReference (); + iter_as_reference.data_type = iterator_type; + Method m = symbol_lookup_inherited (collection_type, "get_iterator") as Method; + + if (m != null && is_type_compatible (m.return_type, iter_as_reference) && m.get_parameters().size == 0) { stmt.iterator_variable_declarator = new VariableDeclarator ("%s_it".printf (stmt.variable_name)); stmt.iterator_variable_declarator.type_reference = new TypeReference (); stmt.iterator_variable_declarator.type_reference.data_type = iterator_type; stmt.iterator_variable_declarator.type_reference.takes_ownership = true; stmt.iterator_variable_declarator.type_reference.add_type_argument (stmt.type_reference); - stmt.add_local_variable (stmt.iterator_variable_declarator); stmt.iterator_variable_declarator.active = true; + stmt.iterator_method = m; } else if (!(collection_type is Array || collection_type == glist_type || collection_type == gslist_type)) { stmt.error = true; Report.error (stmt.source_reference, "Collection not iterable"); Index: gobject/valacodegenerator.vala =================================================================== --- gobject/valacodegenerator.vala (revision 602) +++ gobject/valacodegenerator.vala (working copy) @@ -1635,13 +1635,13 @@ cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next"))); cblock.add_statement (cfor); - } else if (stmt.collection.static_type.data_type.is_subtype_of (iterable_type)) { + } else if (stmt.iterator_method != null) { var it_name = "%s_it".printf (stmt.variable_name); var citdecl = new CCodeDeclaration (iterator_type.get_cname () + "*"); - var it_method = (Method) iterable_type.scope.lookup ("iterator"); + var it_method = stmt.iterator_method; var it_ccall = new CCodeFunctionCall (new CCodeIdentifier (it_method.get_cname ())); - it_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), iterable_type)); + it_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), (DataType ) it_method.parent_symbol)); var citvardecl = new CCodeVariableDeclarator.with_initializer (it_name, it_ccall); citvardecl.line = cblock.line; citdecl.add_declarator (citvardecl);