Thread overview
[Issue 18260] ICE on template this parameter and alias this
Jan 18, 2018
anonymous4
Jan 19, 2018
Simen Kjaeraas
Feb 21, 2018
Simen Kjaeraas
Mar 29, 2018
Seb
Jul 16
Basile-z
January 18, 2018
https://issues.dlang.org/show_bug.cgi?id=18260

anonymous4 <dfj1esp02@sneakemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|x86                         |All
                 OS|Windows                     |All

--
January 18, 2018
https://issues.dlang.org/show_bug.cgi?id=18260

Andrei Alexandrescu <andrei@erdani.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei@erdani.com

--- Comment #1 from Andrei Alexandrescu <andrei@erdani.com> ---
There is a workaround to this:

struct R {
    int[] arr;

    alias get this;

    R get(this This)()
    {
        return R.init;
    }

    R get(this This)() const
    {
        return R.init;
    }
}

unittest
{
    const(R) b = const(R).init;
}

--
January 18, 2018
https://issues.dlang.org/show_bug.cgi?id=18260

--- Comment #2 from Andrei Alexandrescu <andrei@erdani.com> ---
A better workaround:

struct R {
    int[] arr;

    alias get this;

    This get(this This)()
    {
        return This.init;
    }
}

unittest
{
    const(R) b = const(R).init;
}

I suspect the problem is an infinite recursion during semantic checking.

--
January 19, 2018
https://issues.dlang.org/show_bug.cgi?id=18260

--- Comment #3 from Simen Kjaeraas <simen.kjaras@gmail.com> ---
Slightly different version where the given workarounds don't work:

struct R(T) {
    // Used 'auto' here, but 'This' or 'R!(const int)' gives same behavior.
    // Marking the method const or immutable likewise has no effect.
    auto get(this This)() {
        return R!(const int).init;
    }
    alias get this;
}
unittest {
    R!int a;
    R!(const int) b = a;
}

Note that the array is no longer needed.
Interestingly, adding pragma(msg, This) inside get() provides no output.

--
February 21, 2018
https://issues.dlang.org/show_bug.cgi?id=18260

--- Comment #4 from Simen Kjaeraas <simen.kjaras@gmail.com> ---
This seems flaky. The example in comment #3 compiles under 2.078.3, but the first example still causes DMD to freeze.

--
March 29, 2018
https://issues.dlang.org/show_bug.cgi?id=18260

Seb <greensunny12@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |greensunny12@gmail.com

--- Comment #5 from Seb <greensunny12@gmail.com> ---
> but the first example still causes DMD to freeze.

Here's a stack trace - it looks like compare_overload runs into an endless recursion:

---
0x00005555559cf3de in rt.util.array._enforceNoOverlap(const(char[]), ulong,
ulong, const(ulong)) ()
#0  0x00005555559cf3de in rt.util.array._enforceNoOverlap(const(char[]), ulong,
ulong, const(ulong)) ()
#1  0x00005555559c98ef in _d_arraycopy ()
#2  0x00005555559c3166 in _d_newclass (ci=0x555555ab4860 <ClassInfo for
dmd.dsymbol.ScopeDsymbol>) at dmd/root/rmem.d:210
#3  0x00005555557f2adc in
TemplateDeclaration::deduceFunctionTemplateMatch(TemplateInstance*, Scope*,
FuncDeclaration*&, Type*, Array<Expression*>*) (this=0x7ffff7e9f7d0,
ti=0x7ffff510e330, sc=0x7ffff69f8f70, fd=@0x7fffff7ff960: 0x7ffff7e9f470,
tthis=0x7ffff7e9fb20, fargs=0x0) at dmd/dtemplate.d:1118
#4  0x00005555557f7048 in int
dmd.dtemplate.functionResolve(dmd.declaration.Match*, dmd.dsymbol.Dsymbol,
dmd.globals.Loc, dmd.dscope.Scope*,
dmd.root.array.Array!(dmd.root.rootobject.RootObject).Array*, dmd.mtype.Type,
dmd.root.array.Array!(dmd.expression.Expression).Array*,
const(char)**).applyTemplate(dmd.dtemplate.TemplateDeclaration)
(this=0x7fffff7ffb50, td=0x7ffff7e9f7d0) at dmd/dtemplate.d:2690
#5  0x00005555557f7500 in int
dmd.dtemplate.functionResolve(dmd.declaration.Match*, dmd.dsymbol.Dsymbol,
dmd.globals.Loc, dmd.dscope.Scope*,
dmd.root.array.Array!(dmd.root.rootobject.RootObject).Array*, dmd.mtype.Type,
dmd.root.array.Array!(dmd.expression.Expression).Array*,
const(char)**).__lambda11(dmd.dsymbol.Dsymbol) (this=0x7fffff7ffb50,
s=0x7ffff7e9f7d0) at dmd/dtemplate.d:2797
#6  0x000055555583bc34 in int dmd.func.overloadApply(dmd.dsymbol.Dsymbol, int
delegate(dmd.dsymbol.Dsymbol), dmd.dscope.Scope*) (sc=0x7ffff69f8f70, dg=...,
fstart=0x7ffff7e9f7d0) at dmd/func.d:2414
#7  0x00005555557f5e21 in void
dmd.dtemplate.functionResolve(dmd.declaration.Match*, dmd.dsymbol.Dsymbol,
dmd.globals.Loc, dmd.dscope.Scope*,
dmd.root.array.Array!(dmd.root.rootobject.RootObject).Array*, dmd.mtype.Type,
dmd.root.array.Array!(dmd.expression.Expression).Array*, const(char)**)
(pMessage=0x7fffff7ffbb0, fargs=0x0, tthis=0x7ffff7e9fb20, tiargs=0x0,
sc=0x7ffff69f8f70, loc=..., dstart=0x7ffff7e9f7d0, m=0x7fffff7ffb90) at
dmd/dtemplate.d:2799
#8  0x000055555583bfff in resolveFuncCall(Loc const&, Scope*, Dsymbol*,
Array<RootObject*>*, Type*, Array<Expression*>*, int) (loc=...,
sc=0x7ffff69f8f70, s=0x7ffff7e9f7d0, tiargs=0x0, tthis=0x7ffff7e9fb20,
fargs=0x0, flags=0) at dmd/func.d:2575
#9  0x0000555555821b86 in ExpressionSemanticVisitor::visit(CallExp*)
(this=0x7fffff800788, exp=0x7ffff510e2e0) at dmd/expressionsem.d:3142
#10 0x00005555558144ae in CallExp::accept(Visitor*) (this=0x7ffff510e2e0,
v=0x7fffff800788) at dmd/expression.d:5607
#11 0x000055555583461f in expressionSemantic(Expression*, Scope*)
(e=0x7ffff510e2e0, sc=0x7ffff69f8f70) at dmd/expressionsem.d:9367
#12 0x0000555555819509 in dmd.expression.Expression
dmd.expressionsem.resolvePropertiesX(dmd.dscope.Scope*,
dmd.expression.Expression, dmd.expression.Expression) (e2=0x0,
e1=0x7ffff510d7d0, sc=0x7ffff69f8f70) at dmd/expressionsem.d:253
#13 0x00005555558198a7 in resolveProperties(Scope*, Expression*)
(sc=0x7ffff69f8f70, e=0x7ffff510d7d0) at dmd/expressionsem.d:329
#14 0x000055555583457d in dmd.expression.Expression
dmd.expressionsem.binSemanticProp(dmd.expression.BinExp, dmd.dscope.Scope*)
(sc=0x7ffff69f8f70, e=0x555555f54b40) at dmd/expressionsem.d:9352
#15 0x000055555583320e in ExpressionSemanticVisitor::visit(EqualExp*)
(this=0x7fffff800d18, exp=0x555555f54b40) at dmd/expressionsem.d:8900
#16 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f54b40,
v=0x7fffff800d18) at dmd/expression.d:6981
#17 0x000055555583461f in expressionSemantic(Expression*, Scope*)
(e=0x555555f54b40, sc=0x7ffff69f8f70) at dmd/expressionsem.d:9367
#18 0x000055555583440c in dmd.expression.Expression
dmd.expressionsem.trySemantic(dmd.expression.Expression, dmd.dscope.Scope*)
(sc=0x7ffff69f8f70, exp=0x555555f54b40) at dmd/expressionsem.d:9294
#19 0x000055555588bd8c in dmd.expression.Expression
dmd.opover.compare_overload(dmd.expression.BinExp, dmd.dscope.Scope*,
dmd.identifier.Identifier) (id=0x7ffff7e9d3c0, sc=0x7ffff69f8f70,
e=0x555555f547d0) at dmd/opover.d:1666
#20 0x000055555588a171 in op_overload::OpOverload::visit(EqualExp*)
(this=0x7fffff8012a0, e=0x555555f547d0) at dmd/opover.d:1175
#21 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f547d0,
v=0x7fffff8012a0) at dmd/expression.d:6981
#22 0x000055555588797d in op_overload(Expression*, Scope*) (e=0x555555f547d0,
sc=0x7ffff69f8f70) at dmd/opover.d:1536
#23 0x000055555580d551 in Expression::op_overload(Scope*) (this=0x555555f547d0,
sc=0x7ffff69f8f70) at dmd/expression.d:2516
#24 0x0000555555833435 in ExpressionSemanticVisitor::visit(EqualExp*)
(this=0x7fffff801508, exp=0x555555f547d0) at dmd/expressionsem.d:8966
#25 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f547d0,
v=0x7fffff801508) at dmd/expression.d:6981
#26 0x000055555583461f in expressionSemantic(Expression*, Scope*)
(e=0x555555f547d0, sc=0x7ffff69f8f70) at dmd/expressionsem.d:9367
#27 0x000055555583440c in dmd.expression.Expression
dmd.expressionsem.trySemantic(dmd.expression.Expression, dmd.dscope.Scope*)
(sc=0x7ffff69f8f70, exp=0x555555f547d0) at dmd/expressionsem.d:9294
#28 0x000055555588bd8c in dmd.expression.Expression
dmd.opover.compare_overload(dmd.expression.BinExp, dmd.dscope.Scope*,
dmd.identifier.Identifier) (id=0x7ffff7e9d3c0, sc=0x7ffff69f8f70,
e=0x555555f54460) at dmd/opover.d:1666
#29 0x000055555588a171 in op_overload::OpOverload::visit(EqualExp*)
(this=0x7fffff801a90, e=0x555555f54460) at dmd/opover.d:1175
#30 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f54460,
v=0x7fffff801a90) at dmd/expression.d:6981
#31 0x000055555588797d in op_overload(Expression*, Scope*) (e=0x555555f54460,
sc=0x7ffff69f8f70) at dmd/opover.d:1536
#32 0x000055555580d551 in Expression::op_overload(Scope*) (this=0x555555f54460,
sc=0x7ffff69f8f70) at dmd/expression.d:2516
#33 0x0000555555833435 in ExpressionSemanticVisitor::visit(EqualExp*)
(this=0x7fffff801cf8, exp=0x555555f54460) at dmd/expressionsem.d:8966
#34 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f54460,
v=0x7fffff801cf8) at dmd/expression.d:6981
#35 0x000055555583461f in expressionSemantic(Expression*, Scope*)
(e=0x555555f54460, sc=0x7ffff69f8f70) at dmd/expressionsem.d:9367
#36 0x000055555583440c in dmd.expression.Expression
dmd.expressionsem.trySemantic(dmd.expression.Expression, dmd.dscope.Scope*)
(sc=0x7ffff69f8f70, exp=0x555555f54460) at dmd/expressionsem.d:9294
#37 0x000055555588bd8c in dmd.expression.Expression
dmd.opover.compare_overload(dmd.expression.BinExp, dmd.dscope.Scope*,
dmd.identifier.Identifier) (id=0x7ffff7e9d3c0, sc=0x7ffff69f8f70,
e=0x555555f540f0) at dmd/opover.d:1666
#38 0x000055555588a171 in op_overload::OpOverload::visit(EqualExp*)
(this=0x7fffff802280, e=0x555555f540f0) at dmd/opover.d:1175
#39 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f540f0,
v=0x7fffff802280) at dmd/expression.d:6981
#40 0x000055555588797d in op_overload(Expression*, Scope*) (e=0x555555f540f0,
sc=0x7ffff69f8f70) at dmd/opover.d:1536
#41 0x000055555580d551 in Expression::op_overload(Scope*) (this=0x555555f540f0,
sc=0x7ffff69f8f70) at dmd/expression.d:2516
#42 0x0000555555833435 in ExpressionSemanticVisitor::visit(EqualExp*)
(this=0x7fffff8024e8, exp=0x555555f540f0) at dmd/expressionsem.d:8966
#43 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f540f0,
v=0x7fffff8024e8) at dmd/expression.d:6981
---

The log says the same:

---
BinExp::compare_overload(id = opEquals) p == q
BinExp::compare_overload(id = opEquals) p.get() == q
BinExp::compare_overload(id = opEquals) p.get().get() == q
BinExp::compare_overload(id = opEquals) p.get().get().get() == q
BinExp::compare_overload(id = opEquals) p.get().get().get().get() == q
BinExp::compare_overload(id = opEquals) p.get().get().get().get().get() == q
BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get()
== q
BinExp::compare_overload(id = opEquals)
p.get().get().get().get().get().get().get() == q
BinExp::compare_overload(id = opEquals)
p.get().get().get().get().get().get().get().get() == q
BinExp::compare_overload(id = opEquals)
p.get().get().get().get().get().get().get().get().get() == q
BinExp::compare_overload(id = opEquals)
p.get().get().get().get().get().get().get().get().get().get() == q
BinExp::compare_overload(id = opEquals)
p.get().get().get().get().get().get().get().get().get().get().get() == q
BinExp::compare_overload(id = opEquals)
p.get().get().get().get().get().get().get().get().get().get().get().get() == q
BinExp::compare_overload(id = opEquals)
p.get().get().get().get().get().get().get().get().get().get().get().get().get()
== q
BinExp::compare_overload(id = opEquals)
p.get().get().get().get().get().get().get().get().get().get().get().get().get().get()
== q
---

--
July 16
https://issues.dlang.org/show_bug.cgi?id=18260

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |b2.temp@gmx.com
         Resolution|---                         |WORKSFORME

--- Comment #6 from Basile-z <b2.temp@gmx.com> ---
fixed since 2.086

--