Bug 8542 – crosstalk between template instantiations
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-08-12T12:41:00Z
Last change time
2013-02-03T19:24:48Z
Keywords
rejects-valid
Assigned to
nobody
Creator
timon.gehr
Comments
Comment #0 by timon.gehr — 2012-08-12T12:41:55Z
With DMD 2.060, the following code compiles and runs correctly with dmd
-version=A and dmd -version=B, but it fails to compile with
dmd -version=A -version=B
The code should compile and run correctly even when both version specifiers are set.
import std.stdio, std.algorithm, std.range, std.bigint;
template Apply(alias a,T...){ alias a!T Apply; }
auto fun(T)(T n, T function(T) i, T function(T) d){
return
(z=>((T delegate(T,T) delegate(T delegate(T delegate(T,T),T,T)) AOY)
=>((m,e)=>reduce!((a,b)=>AOY((f,a,b)=>z(a)?b:i(f(d(a),
b)))(a,b))(zip([(T[] a)=>a.map!((T x)=>m(i(i(n)),x)).array,(T[]
a)=>a.map!((T x)=>m(i(i(i(n))),x)).array,delegate(T[] a)=>a.map!
(a=>a).array].map!(a=>&Apply!(map!a,T[][])),[[i(n),i(i(n)),i(i(i(n))),
i(i(i(i(n)))),i(i(i(i(i(n))))),i(i(i(i(i(i(n))))))],
[i(i(i(i(i(n))))),i(i(i(i(i(i(n)))))),i(i(i(i(i(i(i(n))))))),i(i(i(i(i(i(i(i(n)))))))),
i(i(i(i(i(i(i(i(i(n))))))))),i(i(i(i(n))))],[e(n,i(n)),e(i(n),i(i(n))),e(i(i(n)),i(n))]]
).map!(t=>t[0](t[1].map!(a=>[a,i(a),m(a,i(i(n)))]).array)).joiner.map!(a=>zip(a,retro(a))
.map!(t=>AOY((f,a,b)=>z(a)?b:i(f(d(a),b)))(t[0],t[1]))).joiner.chain(repeat(
i(i(i(i(i(i(i(i(i(i(i(i(n))))))))))))).map!(a=>AOY
((f,a,b)=>z(b)?a:f(d(a),d(b)))(a,i(i(i(i(i(i(i(i(i(i(i(i(i(n)))))))))))
)))).take(1))))((T a,T b)=>AOY((f,a,b)=>z(a)?n:AOY((g,a,b)=>z(a)?
b:i(g(d(a),b)))(b,f(d(a),b)))(a,b),AOY((h,a,b)=>z(a)?z(b)?i(n):n:z(b)?n:h(d(a),d(b)))))(
(a){struct S{ T delegate(T,T) delegate(S) r; } return
((x)=>x(S(x)))((S x)=>(T u,T v)=>a(x.r(x),u,v)); }))((T a)=>a==n);
}
void main(){
version(A) assert(fun(0,(int a)=>a+1,(int a)=>a-1)==1337);
static inc(int[] a){
if(!a.length) return [1];
if(a[0]<0) return a[0..$-1];
return a~(a[$-1]+1);
}
static dec(int[] a){
if(!a.length) return [-1];
if(a[0]>0) return a[0..$-1];
return a~(a[$-1]-1);
}
version(B) assert(fun((int[]).init,&inc,&dec).equal(iota(1,1338)));
}
Comment #1 by timon.gehr — 2012-08-12T12:45:44Z
importing std.bigint is not required to reproduce.
Comment #2 by bearophile_hugs — 2012-08-12T15:52:31Z
Are you able to minimize (and reformat in a human way) it a little?
Comment #3 by deadalnix — 2012-08-17T08:04:37Z
import std.algorithm, std.range;
template Apply(alias a,T...){ alias a!T Apply; }
auto fun(T)(T n, T function(T) i, T function(T) ){
(z=>(T delegate(T,T) delegate(T delegate(T delegate(T,T),T,T)) AOY)
=>((m,e)=>reduce!((a,b)=>AOY((f,a,b)=>z?b:i(a))(a,b))(zip([(T[] a)=>a.map!(x=>m(n,x))].map!(a=>&Apply!(map!a,T[][])),[[n]]).map!(t=>t[0](t[1].map!(a=>[a]).array)).joiner.map!(a=>zip(a,retro(a)).map!(t=>AOY((f,a,b)=>z?b:i(a))(t[0],t[1]))).joiner.chain))((T a,T b)=>AOY((f,a,b)=>z?n:AOY((g,a,b)=>z?b:i(a))(b,f(a,b)))(a,b),AOY))((T a)=>a==n);
}
void main(){
version(A) fun(0,(int a)=>a+1,(int a)=>a-1);
static inc(int[] a){
return a;
}
static dec(int[] a){
return a;
}
version(B) fun((int[]).init,&inc,&dec);
}
I reduced it to that. I fail to got further.
Comment #4 by hsteoh — 2012-10-16T17:24:02Z
Here's a somewhat simpler case:
auto cprod(R1,R2)(R1 A, R2 B)
{
return zip(sequence!"n"(cast(size_t)0), A.save, B.save, repeat(A), repeat(B))
.map!(function(a) => chain(
zip(repeat(a[1]), take(a[4].save,a[0])),
zip(take(a[3].save,a[0]+1), repeat(a[2]))
)).joiner;
}
void main()
{
auto A = sequence!"2*n"(0);
auto B = sequence!"2*n+1"(0);
auto AB = cprod(A,B);
auto C = sequence!"100+n"(0);
auto D = sequence!"200+n"(0);
auto CD = cprod(C,D);
}
Produces the error:
Error: function test3.cprod!(Sequence!("2*n",Tuple!(int)),Sequence!("2*n+1",Tuple!(int))).cprod.map!(__
funcliteral2).map!(Zip!(Sequence!("n",Tuple!(uint)),Sequence!("100+n",Tuple!(int)),Sequence!("200+n",Tupl
e!(int)),Repeat!(Sequence!("100+n",Tuple!(int))),Repeat!(Sequence!("200+n",Tuple!(int))))).map is a neste
d function and cannot be accessed from test3.cprod!(Sequence!("100+n",Tuple!(int)),Sequence!("200+n",Tupl
e!(int))).cprod
Commenting out either the first three lines (A, B, AB) or the second three lines (C, D, CD) makes the problem go away.
Comment #5 by Jesse.K.Phillips+D — 2012-10-19T11:23:02Z
Here's an unexpected data point: I discovered that this bug may be linked to the -property compiler flag. To reproduce this odd effect, checkout the code from: https://github.com/D-Programming-Language/phobos/pull/856, build Phobos without unittest, then check the output of the following commands (I tested this on Linux/64):
1) This one compiles just fine:
dmd -unittest -m64 std/algorithm.d generated/linux/debug/64/emptymain.d -of/tmp/x
2) This one produces a whole bunch of template crosstalk errors:
dmd -property -unittest -m64 std/algorithm.d generated/linux/debug/64/emptymain.d -of/tmp/x
Comment #7 by hsteoh — 2013-01-03T21:43:08Z
Hmm, the -property effect also happens with the simpler test case I posted earlier in comment 4:
$ dmd test.d
$ # Compiled successfully
$ dmd -property test.d
test.d(5): Error: no property 'map' for type 'Zip!(Sequence!("n", Tuple!(ulong)), Sequence!("2*n", Tuple!(int)), Sequence!("2*n+1", Tuple!(int)), Repeat!(Sequence!("2*n", Tuple!(int))), Repeat!(Sequence!("2*n+1", Tuple!(int))))'
test.d(17): Error: template instance test.cprod!(Sequence!("2*n", Tuple!(int)), Sequence!("2*n+1", Tuple!(int))) error instantiating
test.d(5): Error: no property 'map' for type 'Zip!(Sequence!("n", Tuple!(ulong)), Sequence!("100+n", Tuple!(int)), Sequence!("200+n", Tuple!(int)), Repeat!(Sequence!("100+n", Tuple!(int))), Repeat!(Sequence!("200+n", Tuple!(int))))'
test.d(21): Error: template instance test.cprod!(Sequence!("100+n", Tuple!(int)), Sequence!("200+n", Tuple!(int))) error instantiating
$
Comment #8 by hsteoh — 2013-01-03T21:49:54Z
Actually, nevermind that. I just realized that -property requires () for map and joiner because they aren't declared with @property (and UFCS does not alleviate the need for parentheses).
The sad thing, though, is that my reduced test case no longer produces template crosstalk in git HEAD. :-(
Comment #9 by hsteoh — 2013-01-03T22:01:51Z
Hmph. It seems that Timon's original code also compiles fine in git head (without -property). With -property it fails, but seems the reason is that -property requires functions like map and joiner to have trailing parentheses (). The template crosstalk problem seems to have gone away.
Comment #10 by hsteoh — 2013-01-03T22:28:37Z
git bisect appears to indicate that it was dmd commit 688f7ce593eef75997a2b8f2527d3cd9338692aa that fixed this issue.
Comment #11 by bugzilla — 2013-01-03T23:46:02Z
Then we can resolve this as WORKSFORME.
Comment #12 by github-bugzilla — 2013-02-03T19:24:48Z