std.range.hasLength does not work if the .length member is defined inside a static if. It's a common case for ranges wrapping other ranges and trying to expose their input's properties: --- static if (hasLength!Input) int length() { return _input.length;} ---- for example. Here is some code demonstrating the problem: ---- import std.range; struct Lengthy(bool i) { int front() { return 1;} void popFront(); static if (i) int length() { return 1;} } void main() { Lengthy!true i; Lengthy!false ni; assert(hasLength!(typeof(i))); // Error: AssertError. Considers i has no .length defined. assert(!hasLength!(typeof(ni))); } ---- And a possible solution that seems to work quite well in practice: ---- template hasLength(R) { enum bool hasLength = __traits(compiles, R.length); } ----
"static if" has nothing to do with this issue. length method should be a property.