Bug 7483 – Can't recursively call function with auto return

Status
RESOLVED
Resolution
WORKSFORME
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-02-11T10:59:00Z
Last change time
2016-08-27T22:34:34Z
Keywords
diagnostic, spec
Assigned to
nobody
Creator
andrej.mitrovich

Comments

Comment #0 by andrej.mitrovich — 2012-02-11T10:59:16Z
module test; auto test(int x) { return test(1); } void main() { } test.d(5): Error: forward reference to test I was using tuple() returns and ran into this. Luckily I can work around it by explicitly setting the return type, e.g. "Tuple!(bool, string, string) foo()".
Comment #1 by code — 2012-02-11T12:14:25Z
Your example function is an infinite recursion. Both for determining the return type as well as hypothetically at runtime.
Comment #2 by andrej.mitrovich — 2012-02-12T02:48:48Z
(In reply to comment #1) > Your example function is an infinite recursion. Both for determining the return > type as well as hypothetically at runtime. I've rushed too quickly and posted a silly example. My use-case was code like this: auto foo(bool check) { if (check) { check = false; return foo(check); } else { return 1; } } I don't know whether this would be too difficult for the compiler to figure out on its own. But the basic idea is: if there's at least one known type for a return expression then the function's return type becomes that type and there's no longer a forward reference error. If there are any other return expressions they all must have the same type (just like usual functions). E.g. this would be legal: auto foo(int state) { if (state == 1) { state++; return foo(state); } else if (state == 2) { return tuple(0, 0); } else { return tuple(0, 0); } } The return type is std.typecons.Tuple!(int,int).Tuple for the last two return expressions, the first return is not taken into account since it's a recursive call, and all other return expression types match. This one would be illegal since all the return types don't match: auto foo(int state) { if (state == 1) { state++; return foo(state); } else if (state == 2) { return tuple(0, 0); } else { return tuple(0, 0, 0); } } The OP sample would still be invalid since you can't figure out the return type at all in that case.
Comment #3 by smjg — 2012-02-12T10:58:10Z
http://www.d-programming-language.org/function.html "If there are multiple ReturnStatements, the types of them must match exactly. If there are no ReturnStatements, the return type is inferred to be void." But it doesn't comment on whether this is meant to work. But since it isn't a forward reference, the error message doesn't make sense in any case.
Comment #4 by code — 2012-02-12T11:09:38Z
Yeah, it should be possible to infer recursive return types.
Comment #5 by andrej.mitrovich — 2016-08-27T22:34:34Z
The diagnostic is better these days and mentions the inferred return type.