May 12, 2005
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 14, 2005
-----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-----