www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Nested opApply and 'return'

reply pragma <pragma_member pathlink.com> writes:
Using: Digital Mars D Compiler v0.123 on WinXP

Description:

Recently, I had a foreach, within a foreach both of which used opApply for
iteration.  The innermost loop had a return statement, which generated the
following error.

test.d(15): cannot implicitly convert expression (new Foobar ) of type
test.Foobar to int 
cannot implicitly convert expression (__result) of type int to test.Foobar

This error only manifests when two (and presumably more) nested foreach loops
are used, both using opApply for iteration.

Workaround:

Using a goto, to a label at the end of the function seemed to be good
workaround, as it only required a minimal amount of extra code.


Code Exmaple:

#// test.d
#class Collection{
#	int opApply(int delegate(inout int) dg){
#		return 0;
#	}
#}
#
#class Foobar{}
#
#Foobar test(){
#	Collection a,b;
#	
#	foreach(int x; a){
#		foreach(int y; b){
#			return new Foobar(); // fails here
#		}
#	}
#}

Comments:

I think the problem lies within DMD's behavior of generating an anonymous
function or enclosure, which is then passed to opApply().  I think the 'return'
statement is being interpreted as attempting to return from that enclosure,
rather than from the parent function.  The big clue here is from the complaint
about the return type not being of type 'int', which is the return type for the
opApply delegate (and not that of the parent function).

- EricAnderton at yahoo
May 12 2005
parent Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pragma schrieb am Thu, 12 May 2005 16:41:59 +0000 (UTC):
 Using: Digital Mars D Compiler v0.123 on WinXP

 Description:

 Recently, I had a foreach, within a foreach both of which used opApply for
 iteration.  The innermost loop had a return statement, which generated the
 following error.

 test.d(15): cannot implicitly convert expression (new Foobar ) of type
 test.Foobar to int 
 cannot implicitly convert expression (__result) of type int to test.Foobar

 This error only manifests when two (and presumably more) nested foreach loops
 are used, both using opApply for iteration.

 Workaround:

 Using a goto, to a label at the end of the function seemed to be good
 workaround, as it only required a minimal amount of extra code.


 Code Exmaple:

 #// test.d
 #class Collection{
 #	int opApply(int delegate(inout int) dg){
 #		return 0;
 #	}
 #}
 #
 #class Foobar{}
 #
 #Foobar test(){
 #	Collection a,b;
 #	
 #	foreach(int x; a){
 #		foreach(int y; b){
 #			return new Foobar(); // fails here
 #		}
 #	}
 #}

 Comments:

 I think the problem lies within DMD's behavior of generating an anonymous
 function or enclosure, which is then passed to opApply().  I think the 'return'
 statement is being interpreted as attempting to return from that enclosure,
 rather than from the parent function.  The big clue here is from the complaint
 about the return type not being of type 'int', which is the return type for the
 opApply delegate (and not that of the parent function).

Added to DStress as http://dstress.kuehne.cn/compile/f/foreach_30_A.d http://dstress.kuehne.cn/compile/f/foreach_30_B.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFChaXH3w+/yD4P9tIRAr1zAKCjts6azR2p18RZcvestJ2gsPYLaACfQtW5 IHxogBR90P+fJFPRf4wToOU= =XeKQ -----END PGP SIGNATURE-----
May 14 2005