Bug 19703 – std.typecons.ReplaceType wrongly evaluates alias this
Status
RESOLVED
Resolution
DUPLICATE
Severity
major
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2019-02-26T21:55:50Z
Last change time
2019-07-31T23:16:33Z
Keywords
pull
Assigned to
No Owner
Creator
skocznymr
Comments
Comment #0 by skocznymr — 2019-02-26T21:55:50Z
import std.variant;
struct Vector(int T)
{
float[T] elements;
}
struct Color
{
Vector!4 vec;
alias vec this;
}
Algebraic!(Color,Vector!4) foo;
void main()
{
foo = Color();
}
according to run.dlang.io:
Up to 2.068.2: Success and no output
2.069.2: Failure with output:
-----
/path/to/dmd/dmd2/linux/bin64/../../src/phobos/std/variant.d(578): Error: static assert "Cannot store a Color in a VariantN!(16LU, Color, Vector!4). Valid types are (Vector!4, Vector!4)"
onlineapp.d(18): instantiated from here: opAssign!(Color)
-----
2.070.2: Failure with output: (same as above)
2.071.2: Failure with output: (same as above)
2.072.2: Failure with output: (same as above)
2.073.2: Failure with output: (same as above)
2.074.1 to 2.075.1: Failure with output: (same as above)
2.076.1 to 2.078.1: Failure with output: (same as above)
2.079.1 to 2.080.1: Failure with output: (same as above)
2.081.2 to 2.083.1: Failure with output: (same as above)
Since 2.084.0: Failure with output: (same as above)
Comment #1 by simen.kjaras — 2019-02-26T23:18:17Z
Reduced example:
import std.typecons : ReplaceType;
struct S1(int n) { }
struct S2 {
S1!4 s1;
alias s1 this;
}
static assert(is(ReplaceType!(int, int, S2)[0] == S2));
The problem is this line in std.typecons:
https://github.com/dlang/phobos/blob/13705f53bd3322168de5701d64a5f7c8cf791867/std/typecons.d#L8682
It aggressively matches alias this where it shouldn't.
It should check if T[0]'s alias this is what's being matched instead of T[0] itself. Here's one possible fix:
private template isAliasThis(T, alias U, V...) {
static foreach (at; __traits(getAliasThis, T)) {
static if (is(typeof(__traits(getMember, T, at)) : U!V)) {
enum isAliasThis = true;
}
}
static if (!__traits(compiles, assert(isAliasThis))) {
enum isAliasThis = false;
}
}
And replacing the offending line with this:
else static if (is(T[0] : U!V, alias U, V...) && !isAliasThis!(T, U, V))
Comment #2 by dlang-bot — 2019-02-27T12:27:43Z
@Biotronic created dlang/phobos pull request #6880 "Fix issue 19703 - std.typecons.ReplaceType wrongly evaluates alias this" fixing this issue:
- Fix issue 19703
https://github.com/dlang/phobos/pull/6880
Comment #3 by snarwin+bugzilla — 2019-07-31T23:16:33Z
*** This issue has been marked as a duplicate of issue 19696 ***