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.