https://issues.dlang.org/show_bug.cgi?id=14478
Issue ID: 14478 Summary: isInputRange failed to recognize some ranges Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: major Priority: P1 Component: Phobos Assignee: nob...@puremagic.com Reporter: ket...@ketmar.no-ip.org assume we have this code: import std.range; import std.stdio; struct S { int n; @disable this (this); } void main () { S[2] s0, s1; foreach (ref el; chain(s0[], s1[])) writeln(el.n); } if we try to compile it, we got error: (12): Error: template std.range.chain cannot deduce function from argument types yet if we will remove `@disable this (this);`, everything is working fine. the bug is in `isInputRange` template: template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range (HERE!) })); } line `auto h = r.front;` causes the bug. althru `front` returning ref here, we can't declare ref variables, so `h` looses `ref` and thus requires copying. yet we explicitly disabled copying for our struct, so `isInputRange` is failing. here is the proposed fix: template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() static void testfront(T) (auto ref T n) {} testfront(r.front); })); } here we using nested function with `auto ref` to not loose `ref` from `front`. it would be good to check if some other templates requires such fix too. p.s. with the proposed fix sample code works like a charm. --