D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 8512 - Nasty bug about template
Summary: Nasty bug about template
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2012-08-05 00:51 UTC by Hisayuki Mima
Modified: 2020-03-21 03:56 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Hisayuki Mima 2012-08-05 00:51:34 UTC
I'm really sorry about this ambiguous summary, but I cannot come up with a suitable summary.
If you come up with a suitable summary of this bug, please change the summary.


struct Tuple(T...){ alias T Types; }

template TempType(T, alias temp){
    pragma(msg, temp.temp!T.Type); // [1]
    static assert(__traits(compiles, temp.temp!T.Type));
    static if(is(temp.temp!T.Type Unused == Result!U, U)){
        alias U TempType;
    }else{
        static assert(false);
    }
}

struct Result(T){}

template seq(T, temps...){
    static if(temps.length == 1){
        alias Tuple!(TempType!(T, temps[0]).Types) seq; // [2]
    }else{
        alias Tuple!(TempType!(T, temps[0]).Types, seq!(T, temps[1..$]).Types) seq; // [3]
    }
}

template temp1(){
    template temp(T){
        alias Result!(Tuple!()) Type;
        pragma(msg, seq!(T, temp2!(), temp2!()));
    }
}

template temp2(){
    template temp(T){
        alias Result!(Tuple!()) Type;
        pragma(msg, seq!(T, temp1!(), temp2!()));
    }
}

pragma(msg, temp1!().temp!int);


This code doesn't work with dmd 2.060.
And the error messages changes depending on whether line [1] is comment-outed or not.
If you remove all ".Types" from the lines [2] and [3], the code works well.
Comment 1 Kenji Hara 2012-12-12 22:08:20 UTC
I think this code has a forward reference error, so cannot compile.

The starting of forward reference is here.
template temp1(){
    template temp(T){
        alias Result!(Tuple!()) Type;
        pragma(msg, seq!(T, temp2!(), temp2!()));  // bad
    }
}

And the dependencies direction is:
1. temp1!().temp!int             instantiates temp2!()
2. temp2!()                      instantiates seq!(int, temp1!(), temp2!()))
3. seq!(int, temp1!(), temp2!()) instantiates TempType!(int, temp1!())  (at [2])
4. TempType!(int, temp1!())      instantiates temp1!().temp!int

1 to 4 makes forward reference.

In current dmd implementation, pragma(msg) requires *complete entities* for its arguments. It means that all semantic analysis for them are already done.