Bug 9949 – template initialization when alias cannot be read at compile time

Status
RESOLVED
Resolution
WONTFIX
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-04-17T06:17:00Z
Last change time
2013-04-18T12:41:30Z
Assigned to
nobody
Creator
luka8088

Comments

Comment #0 by luka8088 — 2013-04-17T06:17:01Z
The following code compiles aldo s is not readable at compile time: struct S (alias T) { typeof(T) value; } void main () { auto s = "some"; s ~= "string"; S!s value; } The side effect of this is the following error: // Error: function literal __lambda3 (S!(s) a) is not // callable using argument types (S!(s)) module program; import std.stdio; struct S (alias T) { typeof(T) value; } void f (alias l = x => 1) (string s) { l(S!(s).init); } void main () { auto s = "some"; s ~= "string"; f!((S!s a) { return 1; })(s); } I am not sure what the correct behavior should be, I think that the first code should not compile. But if it should, and this is the correct behavior than the error message should definitely be improved because.
Comment #1 by andrej.mitrovich — 2013-04-18T05:23:37Z
(In reply to comment #0) > The following code compiles aldo s is not readable at compile time: > > struct S (alias T) { > typeof(T) value; > } > > void main () { > auto s = "some"; > s ~= "string"; > S!s value; > } That code isn't reading 's', it is only using it to get its type. And all types are known at compile-time. The code is ok. > > > The side effect of this is the following error: > > // Error: function literal __lambda3 (S!(s) a) is not > // callable using argument types (S!(s)) > > module program; > > import std.stdio; > > struct S (alias T) { > typeof(T) value; > } > > void f (alias l = x => 1) (string s) { > l(S!(s).init); > } > > void main () { > auto s = "some"; > s ~= "string"; > f!((S!s a) { return 1; })(s); > } It doesn't compile because 's' within 'main' and 's' within 'f' are two different variables. You'd have to pass 's' from within main as an alias parameter to 'f'. E.g.: ---- import std.stdio; struct S(alias T) { typeof(T) value; } void f(alias lambda = x => 1, alias str)() { lambda(S!str.init); } void main() { string str = "some"; f!((S!str a) { return 1; }, str)(); } ---- But I'd recommend changing the struct S definition to take a type and use typeof() at the call site to avoid having to use aliases everywhere.
Comment #2 by luka8088 — 2013-04-18T07:03:26Z
(In reply to comment #1) > (In reply to comment #0) > > The following code compiles aldo s is not readable at compile time: > > > > struct S (alias T) { > > typeof(T) value; > > } > > > > void main () { > > auto s = "some"; > > s ~= "string"; > > S!s value; > > } > > That code isn't reading 's', it is only using it to get its type. And all types > are known at compile-time. The code is ok. > Oh, I see, value can be used in runtime but compile time is only using it's type: import std.stdio; struct S (alias T) { typeof(T) value; void print () { writeln(T); } } void main () { auto s = "some"; s ~= "string"; S!s value; value.print(); } > > > > > > The side effect of this is the following error: > > > > // Error: function literal __lambda3 (S!(s) a) is not > > // callable using argument types (S!(s)) > > > > module program; > > > > import std.stdio; > > > > struct S (alias T) { > > typeof(T) value; > > } > > > > void f (alias l = x => 1) (string s) { > > l(S!(s).init); > > } > > > > void main () { > > auto s = "some"; > > s ~= "string"; > > f!((S!s a) { return 1; })(s); > > } > > It doesn't compile because 's' within 'main' and 's' within 'f' are two > different variables. You'd have to pass 's' from within main as an alias > parameter to 'f'. E.g.: > I agree, but shouldn't in that case 's' in error message be fully qualified? Or distinguishable in some way? > ---- > import std.stdio; > > struct S(alias T) > { > typeof(T) value; > } > > void f(alias lambda = x => 1, alias str)() > { > lambda(S!str.init); > } > > void main() > { > string str = "some"; > f!((S!str a) { return 1; }, str)(); > } > ---- > > But I'd recommend changing the struct S definition to take a type and use > typeof() at the call site to avoid having to use aliases everywhere. I wanted to only take a type without using typeof() so I wrote: template S(alias T) if (!is(T)) { alias S = S!(typeof(T)); } struct S (T) { // ... }
Comment #3 by andrej.mitrovich — 2013-04-18T10:35:19Z
(In reply to comment #2) > I agree, but shouldn't in that case 's' in error message be fully qualified? Or > distinguishable in some way? Yep. This is covered by Issue 9631, but you can add your test-case there so it isn't missed.