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 ***