"Don Clugston" <d...@nospam.com> wrote in message news:jlecab$9gh$1...@digitalmars.com... > > If you have type inference of function returns, things can get nasty: > > void foo() > { > auto b() { return a(); } > X x = whatever; > auto a() { return x; } > } > Now b actually depends on the declaration of x. So it's not enough to say > that only function declarations are immune to ordering rules.
Does being inside a function really make the type deduction any harder (or different?) than this?: auto b() { return a(); } enum X x = whatever; auto a() { return x; } > Furthermore, any declaration before x, which calls b(), is using x even > though x hasn't been initialized (or even declared) yet. Suddenly all > kinds of horrible situations become possible, which could never happen > before. > (Don't know if this makes any sence, but I'm throwing it out there...) Suppose we did the approach I mentioned elsewhere in this thread: "the compiler rewrites nested func decls as delegate vars and anon funcs". Suppose we also use the rule: "A nested func is not *callable* (by either the parent function *or* another nested function) until after (ie "further down in the code") all the sibling symbols it accesses have been declared." If it's reasonable for type deduction to happen before all this (I have no idea how realistic that is), then with your example, the compiler first deduces the types just like it would outside a function: void foo() { X b() { return a(); } X x = whatever; X a() { return x; } } Then it gets rewritten: void foo() { delegate X() b; delegate X() a; b = X() { return a(); } X x = whatever; a = X() { return x; } } This would now be flagged as an error because "b" is calling "a" before (ie "earlier in the code than") all of the symbols "a" accesses (namely "x") have been declared. The following would also be an error for the same reason: void foo() { auto b() { return a(); } X w = b(); X x = whatever; auto a() { return x; } } However, this would still be perfectly ok: void foo() { X x = whatever; auto b() { return a(); } auto a() { return x; } } Because it turns into: void foo() { delegate X() b; delegate X() a; X x = whatever; b = X() { return a(); } a = X() { return x; } } And now, at the point in the code where "b" calls "a", everything "a" accesses (namely "x") has *already* been declared and inited. And of couse, "b" *can* call "a" because "a" is already declared way at the top.