By giving dot templates a type, meant that properry resolving silently
started passing for code that should never have passed. The simple fix
is to provide implementations for checkType and checkValue that give an
error about dot templates having neither a value nor type.
Reviewed-on: https://github.com/dlang/dmd/pull/12920
PR d/101619
gcc/d/ChangeLog:
* dmd/expression.c (DotTemplateExp::checkType): New function.
(DotTemplateExp::checkValue): New function.
* dmd/expression.h (class DotTemplateExp): Declare checkType and
checkValue.
gcc/testsuite/ChangeLog:
* gdc.test/fail_compilation/fail7424b.d: Update test.
* gdc.test/fail_compilation/fail7424c.d: Update test.
* gdc.test/fail_compilation/fail7424d.d: Update test.
* gdc.test/fail_compilation/fail7424e.d: Update test.
* gdc.test/fail_compilation/fail7424f.d: Update test.
* gdc.test/fail_compilation/fail7424g.d: Update test.
* gdc.test/fail_compilation/fail7424h.d: Update test.
* gdc.test/fail_compilation/fail7424i.d: Update test.
* gdc.test/compilable/test22133.d: New test.
* gdc.test/fail_compilation/fail22133.d: New test.
(cherry picked from commit
3e2136117487fa839f7601c3e22a2856978fb9d0)
this->td = td;
}
+bool DotTemplateExp::checkType()
+{
+ error("%s %s has no type", td->kind(), toChars());
+ return true;
+}
+
+bool DotTemplateExp::checkValue()
+{
+ error("%s %s has no value", td->kind(), toChars());
+ return true;
+}
+
/************************************************************/
DotVarExp::DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads)
TemplateDeclaration *td;
DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td);
+ bool checkType();
+ bool checkValue();
void accept(Visitor *v) { v->visit(this); }
};
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=22133
+
+struct Slice
+{
+ bool empty() const;
+ int front() const;
+ void popFront()() // note: requires a mutable Slice
+ {}
+}
+
+enum isInputRange1(R) = is(typeof((R r) => r.popFront));
+enum isInputRange2(R) = __traits(compiles, (R r) => r.popFront);
+static assert(isInputRange1!( Slice) == true);
+static assert(isInputRange1!(const Slice) == false);
+static assert(isInputRange2!( Slice) == true);
+static assert(isInputRange2!(const Slice) == false);
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=22133
+/*
+TEST_OUTPUT
+---
+fail_compilation/fail22133.d(16): Error: `s.popFront()()` has no effect
+fail_compilation/fail22133.d(17): Error: template `s.popFront()()` has no type
+---
+*/
+struct Slice
+{
+ void popFront()() {}
+}
+
+auto fail22133(const Slice s)
+{
+ s.popFront;
+ return s.popFront;
+}
+
+auto ok22133(Slice s)
+{
+ s.popFront;
+ return s.popFront;
+}
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424b.d(10): Error: expression `this.g()()` is `void` and has no value
+fail_compilation/fail7424b.d(10): Error: template `this.g()()` has no value
---
*/
struct S7424b
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424c.d(10): Error: expression `this.g()()` is `void` and has no value
+fail_compilation/fail7424c.d(10): Error: template `this.g()()` has no value
---
*/
struct S7424c
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424d.d(10): Error: expression `this.g()()` is `void` and has no value
+fail_compilation/fail7424d.d(10): Error: template `this.g()()` has no value
---
*/
struct S7424d
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424e.d(10): Error: expression `this.g()()` is `void` and has no value
+fail_compilation/fail7424e.d(10): Error: template `this.g()()` has no value
---
*/
struct S7424e
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424f.d(10): Error: expression `this.g()()` is `void` and has no value
+fail_compilation/fail7424f.d(10): Error: template `this.g()()` has no value
---
*/
struct S7424f
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424g.d(10): Error: expression `this.g()()` is `void` and has no value
+fail_compilation/fail7424g.d(10): Error: template `this.g()()` has no value
---
*/
struct S7424g
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424h.d(10): Error: expression `this.g()()` is `void` and has no value
+fail_compilation/fail7424h.d(10): Error: template `this.g()()` has no value
---
*/
struct S7424g
/*
TEST_OUTPUT:
---
-fail_compilation/fail7424i.d(10): Error: expression `this.g()()` is `void` and has no value
+fail_compilation/fail7424i.d(10): Error: template `this.g()()` has no value
---
*/
struct S7424g