Bug 18631 – std.random.choice does not work with const arrays
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-03-19T19:30:39Z
Last change time
2022-07-07T15:38:29Z
Keywords
pull
Assigned to
No Owner
Creator
elpenguino+D
Comments
Comment #0 by elpenguino+D — 2018-03-19T19:30:39Z
```
const x = [1,2];
auto y = choice(x);
```
results in
```
/dlang/dmd/linux/bin64/../../src/phobos/std/random.d(2033): Error: template std.random.choice cannot deduce function from argument types !()(const(int[]), MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 4022730752u, 18LU, 1812433253u)), candidates are:
/dlang/dmd/linux/bin64/../../src/phobos/std/random.d(2020): std.random.choice(Range, RandomGen = Random)(auto ref Range range, ref RandomGen urng) if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)
/dlang/dmd/linux/bin64/../../src/phobos/std/random.d(2031): std.random.choice(Range)(auto ref Range range)
onlineapp.d(5): Error: template instance `std.random.choice!(const(int[]))` error instantiating
```
It appears that the only thing keeping this from working is x not being a range, but the body of the function does not seem to actually require that be true.
Comment #1 by github-bugzilla — 2018-03-20T12:18:51Z
Comment #3 by snarwin+bugzilla — 2022-02-23T21:11:18Z
This is a special case of a general problem with ranges and const. A const object cannot implement popFront (which mutates its receiver), and therefore cannot be a range.
In this case, the problem can be worked around by using the [] operator to obtain a mutable slice over the const array:
---
const x = [1, 2];
auto y = choice(x[]);
---
*** This issue has been marked as a duplicate of issue 17771 ***
Comment #4 by schveiguy — 2022-07-04T20:58:00Z
This is not a duplicate of the general foreach problem. It's specific to choice.
Other range-accepting functions work with const arrays just fine. This is a problem with choice.
The fix is to remove the `auto ref` modifier on the range, which is nonsensical, since it doesn't actually modify the range at all. It probably was a premature optimization (verified it has been there from the start).
Comment #5 by dlang-bot — 2022-07-05T10:40:14Z
@GrimMaple created dlang/phobos pull request #8495 "Fix Issue 18631 - std.random.choice does not work with const arrays" fixing this issue:
- Fix Issue 18631 - std.random.choice does not work with const arrays
`auto ref` is not needed on `Range` param
https://github.com/dlang/phobos/pull/8495
Comment #6 by dlang-bot — 2022-07-07T15:38:29Z
dlang/phobos pull request #8495 "Fix Issue 18631 - std.random.choice does not work with const arrays" was merged into master:
- ee474f0cfc543e844bcbcf96a0da17fc3bf8c8f4 by Grim Maple:
Fix Issue 18631 - std.random.choice does not work with const arrays
`auto ref` is not needed on `Range` param
https://github.com/dlang/phobos/pull/8495