Bug 4417 – uniform() doesn't check constness of RNG

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-07-02T05:31:00Z
Last change time
2014-02-16T02:18:42Z
Keywords
diagnostic
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2010-07-02T05:31:17Z
This D2 program is wrong, because the rnd field of Foo must change its state, so it can't be called in a const method bar(): import std.random: MinstdRand, uniform; struct Foo { MinstdRand rnd; int bar() const { return uniform(0, 10, rnd); } } void main() {} But dmd v2.047 shows bad error messages: ...\dmd\src\phobos\std\random.d(684): Error: function std.random.LinearCongruentialEngine!(uint,48271,0,2147483647).LinearCongruentialEngine.front () is not callable using argument types () ...\dmd\src\phobos\std\random.d(685): Error: function std.random.LinearCongruentialEngine!(uint,48271,0,2147483647).LinearCongruentialEngine.popFront () is not callable using argument types () ...\dmd\src\phobos\std\random.d(5): Error: template instance std.random.uniform!("[)",int,int,const(LinearCongruentialEngine!(uint,48271,0,2147483647))) error instantiating A better single error message can just say that uniform(_, _, rnd) can't be called inside bar() because uniform() tries to mutates rnd while bar is const. See also bug 4416
Comment #1 by andrej.mitrovich — 2013-01-20T13:08:30Z
I think this is an issue with Phobos, not the compiler. The error is now slightly better (first two shown): Error: mutable method std.random.LinearCongruentialEngine!(uint, 48271, 0, 2147483647).LinearCongruentialEngine.front is not callable using a const object Error: mutable method std.random.LinearCongruentialEngine!(uint, 48271, 0, 2147483647).LinearCongruentialEngine.popFront is not callable using a const object uniform() should probably reject a const random number generator. And this is probably true for all range-taking functions. If you can't call popFront then you can't do much with the range AFAICT. Not even .save helps in this case.
Comment #2 by github-bugzilla — 2014-02-15T23:37:19Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/26eecf465162ec60a8d7b595a1e72f9b226fb0ae Fix Issue 4417 - isUniformRNG constraints for std.random.uniform https://d.puremagic.com/issues/show_bug.cgi?id=4417 https://github.com/D-Programming-Language/phobos/commit/1a063adbd500b5a9ea1d2d4c31c964f792a53ae2 Merge pull request #1944 from Poita/bug4417 Fix Issue 4417 - isUniformRNG constraints for std.random.uniform
Comment #3 by peter.alexander.au — 2014-02-16T02:18:42Z
Fixed, the error is now: bug.d(5): Error: template std.random.uniform cannot deduce function from argument types !()(int, int, const(LinearCongruentialEngine!(uint, 48271, 0, 2147483647))), candidates are: std/random.d(1201): std.random.uniform(string boundaries = "[)", T1, T2)(T1 a, T2 b) if (!is(CommonType!(T1, T2) == void)) std/random.d(1238): std.random.uniform(string boundaries = "[)", T1, T2, UniformRandomNumberGenerator)(T1 a, T2 b, ref UniformRandomNumberGenerator urng) if (isFloatingPoint!(CommonType!(T1, T2)) && isUniformRNG!UniformRandomNumberGenerator) std/random.d(1333): std.random.uniform(string boundaries = "[)", T1, T2, RandomGen)(T1 a, T2 b, ref RandomGen rng) if ((isIntegral!(CommonType!(T1, T2)) || isSomeChar!(CommonType!(T1, T2))) && isUniformRNG!RandomGen) std/random.d(1484): std.random.uniform(T, UniformRandomNumberGenerator)(ref UniformRandomNumberGenerator urng) if (!is(T == enum) && (isIntegral!T || isSomeChar!T) && isUniformRNG!UniformRandomNumberGenerator) std/random.d(1504): std.random.uniform(T)() if (!is(T == enum) && (isIntegral!T || isSomeChar!T)) bug.d(69): ... (2 more, -v to show) ... It's still a bit cluttered, but that's a general problem of D template errors, no longer specific to uniform.