← Back to index
|
Original Bugzilla link
Bug 6418 – [CTFE] Cannot call a struct member function with name 'length'.
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
All
Creation time
2011-07-31T11:16:00Z
Last change time
2011-08-03T17:15:34Z
Keywords
ice-on-valid-code, rejects-valid
Assigned to
nobody
Creator
dmitry.olsh
Comments
Comment #0
by dmitry.olsh — 2011-07-31T11:16:16Z
Test case: import std.range; enum table = [2, 3, 5, 7, 11]; uint lookup(uint k) { auto tab = assumeSorted(table); tab.equalRange(k); //changing it to lowerBound works assert(!tab.empty); return 42; } enum t = lookup(7); invking dmd: dmd2/linux/bin/../../src/phobos/std/range.d(5572): Error: cannot evaluate this.length() at compile time dmd2/linux/bin/../../src/phobos/std/range.d(5620): Error: cannot evaluate this.getTransitionIndex(v) at compile time dmd2/linux/bin/../../src/phobos/std/range.d(5620): Error: cannot evaluate this.opSlice(0LU,this.getTransitionIndex(v)) at compile time dmd2/linux/bin/../../src/phobos/std/range.d(5693): Error: cannot evaluate this.opSlice(first,it).lowerBound(value) at compile time Segmentation fault (core dumped)
Comment #1
by kennytm — 2011-07-31T15:17:29Z
Reduced test case (which doesn't trigger the ICE, but should have the same cause): --------------------- struct Bug6418 { size_t length2() { return 1; } size_t length() { return 1; } } static assert(Bug6418.init.length2 == 1); // <-- ok static assert(Bug6418.init.length == 1); // <-- error --------------------- x.d(6): Error: cannot evaluate Bug6418().length() at compile time x.d(6): Error: static assert (Bug6418().length() == 1u) is not evaluatable at compile time --------------------- Temporary workaround to Phobos is to change all 'length' to '_input.length': diff --git a/std/range.d b/std/range.d index 622f7b8..a8e4e4e 100644 --- a/std/range.d +++ b/std/range.d @@ -5618,7 +5618,7 @@ if (isRandomAccessRange!Range) private size_t getTransitionIndex(SearchPolicy sp, alias test, V)(V v) if (sp == SearchPolicy.trotBackwards || sp == SearchPolicy.gallopBackwards) { - immutable count = length; + immutable count = _input.length; if (empty || !test(back, v)) return count; if (count == 1) return 0; size_t below = count - 2, above = count - 1, step = 2; @@ -5690,7 +5690,7 @@ if (isRandomAccessRange!Range) if (is(V : ElementType!Range)) { ElementType!Range v = value; - return this[getTransitionIndex!(sp, gt)(v) .. length]; + return this[getTransitionIndex!(sp, gt)(v) .. _input.length]; } // equalRange @@ -5739,12 +5739,12 @@ if (isRandomAccessRange!Range) // Gallop towards the left end as it's likely nearby immutable left = first + this[first .. it] - .lowerBound!(SearchPolicy.gallopBackwards)(value).length; + .lowerBound!(SearchPolicy.gallopBackwards)(value)._input.length; first += count; // Gallop towards the right end as it's likely nearby immutable right = first - this[it + 1 .. first] - .upperBound!(SearchPolicy.gallop)(value).length; + .upperBound!(SearchPolicy.gallop)(value)._input.length; return this[left .. right]; } }
Comment #2
by clugdbug — 2011-07-31T21:41:04Z
There are two bugs here. The segfault has a completely different cause from the rejects-valid bug.
Comment #3
by bugzilla — 2011-08-03T17:15:34Z
https://github.com/D-Programming-Language/dmd/commit/9318dc44c3e9aa75907966b9fd122c0cc6700891
https://github.com/D-Programming-Language/dmd/commit/571661646ca420aa4c3fb348e86e35ed8faae624