- error(e.loc, "the ordering of pointers to unrelated memory blocks is indeterminate in CTFE. To check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`", e.toChars(), e.e1.toChars(), dir, e.e2.toChars());
+ error(e.loc, "the ordering of pointers to unrelated memory blocks is indeterminate in CTFE.");
+ errorSupplemental(e.loc, "to check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`", e.toChars(), e.e1.toChars(), dir, e.e2.toChars());
- /* To merge the type of e with commonType, add 0 of type commonType
- */
- if (!ed.memtype)
- e = new AddExp(em.loc, e, new IntegerExp(em.loc, 0, commonType));
-
- e = e.expressionSemantic(sc);
- e = resolveProperties(sc, e);
- e = e.integralPromotions(sc);
- e = e.ctfeInterpret();
- if (e.op == EXP.error)
- return errorReturn(em);
- auto ie = e.isIntegerExp();
- if (!ie)
- {
- // C11 6.7.2.2-2
- .error(em.loc, "%s `%s` enum member must be an integral constant expression, not `%s` of type `%s`", em.kind, em.toPrettyChars, e.toChars(), e.type.toChars());
- return errorReturn(em);
- }
- if (ed.memtype && !ir.contains(getIntRange(ie)))
- {
- // C11 6.7.2.2-2
- .error(em.loc, "%s `%s` enum member value `%s` does not fit in `%s`", em.kind, em.toPrettyChars, e.toChars(), commonType.toChars());
- return errorReturn(em);
- }
- nextValue = ie.toInteger();
- if (!ed.memtype)
- commonType = e.type;
- em.value = new IntegerExp(em.loc, nextValue, commonType);
- }
- else
- {
- // C11 6.7.2.2-3 add 1 to value of previous enumeration constant
- bool first = (em == (*em.ed.members)[0]);
- if (!first)
- {
- Expression max = getProperty(commonType, null, em.loc, Id.max, 0);
- if (nextValue == max.toInteger())
- {
- .error(em.loc, "%s `%s` initialization with `%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars, max.toChars(), commonType.toChars());
- return errorReturn(em);
- }
- nextValue += 1;
- }
- em.value = new IntegerExp(em.loc, nextValue, commonType);
- }
- em.type = commonType;
- em.semanticRun = PASS.semanticdone;
- }
-
- ed.members.foreachDsymbol( (s)
- {
- if (EnumMember em = s.isEnumMember())
- emSemantic(em, nextValue);
- });
-
- if (!ed.memtype)
- {
- // cast all members to commonType
- ed.members.foreachDsymbol( (s)
- {
- if (EnumMember em = s.isEnumMember())
- {
- em.type = commonType;
- // optimize out the cast so that other parts of the compiler can
- // assume that an integral enum's members are `IntegerExp`s.
+ else if (funcdecl.isOverride() && !parent.isTemplateInstance())
+ .error(funcdecl.loc, "%s `%s` `override` only applies to class member functions", funcdecl.kind, funcdecl.toPrettyChars);
+
+ if (auto ti = parent.isTemplateInstance)
+ {
+ objc.setSelector(funcdecl, sc);
+ objc.setAsOptional(funcdecl, sc);
+ }
- if (funcdecl.isCtorDeclaration())
+ objc.validateSelector(funcdecl);
+ objc.validateOptional(funcdecl);
+ // Reflect this.type to f because it could be changed by findVtblIndex
+ f = funcdecl.type.toTypeFunction();
+
+Ldone:
+ if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())
+ .error(funcdecl.loc, "%s `%s` `in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract", funcdecl.kind, funcdecl.toPrettyChars);
+
+ /* Do not allow template instances to add virtual functions
- "`%s` cannot be annotated with `@disable` because it is overriding a function in the base class",
- funcdecl.toPrettyChars);
+ // Supplemental error for parameter scope differences
+ auto tf1 = cast(TypeFunction)funcdecl.type;
+ auto tf2 = cast(TypeFunction)fd.type;
- if (funcdecl.isDeprecated && !(funcdecl.foverrides.length && funcdecl.foverrides[0].isDeprecated))
- deprecation(funcdecl.loc,
- "`%s` cannot be marked as `deprecated` because it is overriding a function in the base class",
- funcdecl.toPrettyChars);
- }
+ if (tf1 && tf2)
+ {
+ auto params1 = tf1.parameterList;
+ auto params2 = tf2.parameterList;
- }
- else if (funcdecl.isOverride() && !parent.isTemplateInstance())
- .error(funcdecl.loc, "%s `%s` `override` only applies to class member functions", funcdecl.kind, funcdecl.toPrettyChars);
+ if (params1.length == params2.length)
+ {
+ bool hasScopeDifference = false;
- if (auto ti = parent.isTemplateInstance)
- {
- objc.setSelector(funcdecl, sc);
- objc.setAsOptional(funcdecl, sc);
- }
+ for (size_t i = 0; i < params1.length; i++)
+ {
+ auto p1 = params1[i];
+ auto p2 = params2[i];
- objc.validateSelector(funcdecl);
- objc.validateOptional(funcdecl);
- // Reflect this.type to f because it could be changed by findVtblIndex
- f = funcdecl.type.toTypeFunction();
+ if ((p1.storageClass & STC.scope_) == (p2.storageClass & STC.scope_))
+ continue;
-Ldone:
- if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())
- .error(funcdecl.loc, "%s `%s` `in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract", funcdecl.kind, funcdecl.toPrettyChars);
+ if (!(p2.storageClass & STC.scope_))
+ continue;
- /* Do not allow template instances to add virtual functions
+ /* To merge the type of e with commonType, add 0 of type commonType
+ */
+ if (!ed.memtype)
+ e = new AddExp(em.loc, e, new IntegerExp(em.loc, 0, commonType));
+
+ e = e.expressionSemantic(sc);
+ e = resolveProperties(sc, e);
+ e = e.integralPromotions(sc);
+ e = e.ctfeInterpret();
+ if (e.op == EXP.error)
+ return errorReturn(em);
+ auto ie = e.isIntegerExp();
+ if (!ie)
+ {
+ // C11 6.7.2.2-2
+ .error(em.loc, "%s `%s` enum member must be an integral constant expression, not `%s` of type `%s`", em.kind, em.toPrettyChars, e.toChars(), e.type.toChars());
+ return errorReturn(em);
+ }
+ if (ed.memtype && !ir.contains(getIntRange(ie)))
+ {
+ // C11 6.7.2.2-2
+ .error(em.loc, "%s `%s` enum member value `%s` does not fit in `%s`", em.kind, em.toPrettyChars, e.toChars(), commonType.toChars());
+ return errorReturn(em);
+ }
+ nextValue = ie.toInteger();
+ if (!ed.memtype)
+ commonType = e.type;
+ em.value = new IntegerExp(em.loc, nextValue, commonType);
+ }
+ else
+ {
+ // C11 6.7.2.2-3 add 1 to value of previous enumeration constant
+ bool first = (em == (*em.ed.members)[0]);
+ if (!first)
+ {
+ Expression max = getProperty(commonType, null, em.loc, Id.max, 0);
+ if (nextValue == max.toInteger())
+ {
+ .error(em.loc, "%s `%s` initialization with `%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars, max.toChars(), commonType.toChars());
+ return errorReturn(em);
+ }
+ nextValue += 1;
+ }
+ em.value = new IntegerExp(em.loc, nextValue, commonType);
+ }
+ em.type = commonType;
+ em.semanticRun = PASS.semanticdone;
+ }
+
+ ed.members.foreachDsymbol( (s)
+ {
+ if (EnumMember em = s.isEnumMember())
+ emSemantic(em, nextValue);
+ });
+
+ if (!ed.memtype)
+ {
+ // cast all members to commonType
+ ed.members.foreachDsymbol( (s)
+ {
+ if (EnumMember em = s.isEnumMember())
+ {
+ em.type = commonType;
+ // optimize out the cast so that other parts of the compiler can
+ // assume that an integral enum's members are `IntegerExp`s.
@@ -1072,7+1072,8 @@ Expression optimize(Expression e, int result, bool keepLvalue = false)
// All negative integral powers are illegal.
if (e.e1.type.isIntegral() && (e.e2.op == EXP.int64) && cast(sinteger_t)e.e2.toInteger() < 0)
{
- error(e.loc, "cannot raise `%s` to a negative integer power. Did you mean `(cast(real)%s)^^%s` ?", e.e1.type.toBasetype().toChars(), e.e1.toChars(), e.e2.toChars());
+ error(e.loc, "cannot raise `%s` to a negative integer power.", e.e1.type.toBasetype().toChars());
+ errorSupplemental(e.loc, "did you mean `(cast(real)%s)^^%s` ?", e.e1.toChars(), e.e2.toChars());
return errorReturn();
}
// If e2 *could* have been an integer, make it one.
@@ -287,7+287,10 @@ private extern(C++) final class Semantic2Visitor : Visitor
}
if (hasInvalidEnumInitializer(ei.exp))
- .error(vd.loc, "%s `%s` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.", vd.kind, vd.toPrettyChars);
+ {
+ .error(vd.loc, "%s `%s` : Unable to initialize enum with class or pointer to struct", vd.kind, vd.toPrettyChars);
@@ -298,13+301,20 @@ private extern(C++) final class Semantic2Visitor : Visitor
{
ExpInitializer ei = vd._init.isExpInitializer();
if (ei && ei.exp.op == EXP.classReference)
- .error(vd.loc, "%s `%s` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.", vd.kind, vd.toPrettyChars);
+ {
+ .error(vd.loc, "%s `%s` is a thread-local class and cannot have a static initializer", vd.kind, vd.toPrettyChars);
+ .errorSupplemental(vd.loc, "use `static this()` to initialize instead");
if (ei && ei.exp.op == EXP.address && (cast(AddrExp)ei.exp).e1.op == EXP.structLiteral)
- .error(vd.loc, "%s `%s` is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead.", vd.kind, vd.toPrettyChars);
+ {
+ .error(vd.loc, "%s `%s` is a thread-local pointer to struct and cannot have a static initializer", vd.kind, vd.toPrettyChars);
+ .errorSupplemental(vd.loc, "use `static this()` to initialize instead");
@@ -13,12+13,12 @@ fail_compilation/diag20888.d(49): Error: return value `callback` of type `int de
fail_compilation/diag20888.d(54): Error: return value `() => 3755` of type `int function() pure nothrow @nogc @safe` does not match return type `int`, and cannot be implicitly converted
fail_compilation/diag20888.d(54): Did you intend to call the function pointer?
-fail_compilation/diag20888.d(64): Error: cannot return non-void from `void` function
fail_compilation/diag20888.d(70): Error: return value `() => i` of type `int delegate() pure nothrow @nogc @safe` does not match return type `int`, and cannot be implicitly converted
fail_compilation/diag20888.d(70): Did you intend to call the delegate?
fail_compilation/diag9679.d(93): Deprecation: `auto` and `ref` storage classes should be adjacent
fail_compilation/diag9679.d(93): Deprecation: `auto` and `ref` storage classes should be adjacent
-fail_compilation/diag9679.d(15): Error: rvalue `1` cannot be assigned to `ref n`
-fail_compilation/diag9679.d(16): Error: variable `diag9679.main.n` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?
-fail_compilation/diag9679.d(17): Error: variable `diag9679.main.S.a` - field declarations cannot be `ref`
-fail_compilation/diag9679.d(24): Error: returning `r` escapes a reference to local variable `i`
+fail_compilation/diag9679.d(94): Deprecation: `auto ref` return type must have `auto` and `ref` adjacent
+fail_compilation/diag9679.d(100): Deprecation: `auto ref` return type must have `auto` and `ref` adjacent
+fail_compilation/diag9679.d(16): Error: rvalue `1` cannot be assigned to `ref n`
+fail_compilation/diag9679.d(17): Error: variable `diag9679.main.n` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?
+fail_compilation/diag9679.d(18): Error: variable `diag9679.main.S.a` - field declarations cannot be `ref`
+fail_compilation/diag9679.d(25): Error: returning `r` escapes a reference to local variable `i`
+fail_compilation\enum_auto_increment.d(17): Error: cannot automatically assign value to enum member `enum_auto_increment.A2.d` because base type `A1` is an enum; provide an explicit value\r
-fail_compilation/fail109.d(50): Error: cannot check `fail109.B.end` value for overflow
-fail_compilation/fail109.d(50): Error: comparison between different enumeration types `B` and `C`; If this behavior is intended consider using `std.conv.asOriginalType`
-fail_compilation/fail109.d(50): Error: enum member `fail109.B.end` initialization with `B.start+1` causes overflow for type `C`
+fail_compilation\fail109.d(48): Error: cannot automatically assign value to enum member `fail109.B.end` because base type `C` is an enum; provide an explicit value
-fail_compilation/fail11714.d(14): Error: variable `fail11714.c` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.
-fail_compilation/fail11714.d(21): Error: variable `fail11714.s` is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead.
+fail_compilation/fail11714.d(16): Error: variable `fail11714.c` is a thread-local class and cannot have a static initializer
+fail_compilation/fail11714.d(16): use `static this()` to initialize instead
+fail_compilation/fail11714.d(23): Error: variable `fail11714.s` is a thread-local pointer to struct and cannot have a static initializer
+fail_compilation/fail11714.d(23): use `static this()` to initialize instead
-fail_compilation/fail15361.d(8): Error: unexpected `(` after `errorize`, inside `is` expression. Try enclosing the contents of `is` with a `typeof` expression
+fail_compilation/fail15361.d(9): Error: unexpected `(` after `errorize`, inside `is` expression
+fail_compilation/fail15361.d(9): try enclosing the contents of `is` with a `typeof` expression
-fail_compilation/fail23439.d(13): Error: variable `fail23439.ice23439` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.
+fail_compilation/fail23439.d(14): Error: variable `fail23439.ice23439` is a thread-local class and cannot have a static initializer
+fail_compilation/fail23439.d(14): use `static this()` to initialize instead
-fail_compilation/fail98.d(17): Error: cannot implicitly convert expression `256` of type `int` to `E`
+fail_compilation/fail98.d(20): Error: cannot implicitly convert expression `256` of type `int` to `E`
+fail_compilation/fail98.d(21): Error: cannot automatically assign value to enum member `fail98.D3DTS_WORLD1` because base type `E` is an enum; provide an explicit value
+fail_compilation/fail98.d(22): Error: cannot automatically assign value to enum member `fail98.D3DTS_WORLD2` because base type `E` is an enum; provide an explicit value
+fail_compilation/fail98.d(23): Error: cannot automatically assign value to enum member `fail98.D3DTS_WORLD3` because base type `E` is an enum; provide an explicit value
+fail_compilation/fix20075.d(15): Error: none of the overloads of `this` can construct an immutable object with argument types `(int*)`. Expected `immutable(int*)`
+fail_compilation/fix20075.d(11): Candidate is: `fix20075.Foo.this(immutable(int*) a) immutable`
+fail_compilation/fix20318.d(16): Error: cannot implicitly convert expression `c` of type `const(Bar)` to `Bar` because struct `Bar` contains pointers or references
+fail_compilation/fix20318.d(20): Error: cannot implicitly convert expression `complex_c` of type `const(ComplexBar)` to `ComplexBar` because struct `ComplexBar` contains pointers or references
+---
+*/
+
+void main() {
+ // This should work - struct without pointers
+ const Foo a;
+ Foo b = a; // This is okay
+
+ // This should fail with improved diagnostic message
+ const Bar c;
+ Bar d = c; // Error with improved diagnostic message
+
+ // Test with a more complex struct with nested pointers
+ const ComplexBar complex_c;
+ ComplexBar complex_d = complex_c; // Give improved error message
+}
+
+struct Foo {
+ int value;
+}
+
+struct Bar {
+ void* ptr;
+}
+
+// Simple struct without pointers
+struct Simple {
+ int value;
+}
+
+// Struct with a pointer
+struct WithPointer {
+ int* ptr;
+}
+
+// Complex struct that contains another struct with pointers
+struct ComplexBar {
+ Simple simple; // This is fine
+ int data; // This is fine
+ WithPointer nested; // This field prevents implicit conversion
fail_compilation/retscope3.d(4003): Error: escaping a reference to parameter `u` by copying `u[]` into allocated memory is not allowed in a `@safe` function
fail_compilation/retscope3.d(4016): Error: storing reference to outer local variable `i` into allocated memory causes it to escape
+fail_compilation/retscope3.d(4025): Deprecation: slice of static array temporary returned by `makeSA()` assigned to longer lived variable `a`
fail_compilation/retscope3.d(4025): Error: escaping reference to stack allocated value returned by `makeSA()` into allocated memory
+fail_compilation/retscope3.d(4032): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function
-fail_compilation/test15989.d(39): Error: variable `test15989.main.ctRegex` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.
-fail_compilation/test15989.d(48): Error: variable `test15989.test.c` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.
-fail_compilation/test15989.d(49): Error: cannot use non-constant CTFE pointer in an initializer `new int(3)`
+fail_compilation/test15989.d(41): Error: variable `test15989.main.ctRegex` : Unable to initialize enum with class or pointer to struct
+fail_compilation/test15989.d(41): use static const variable instead
+fail_compilation/test15989.d(50): Error: variable `test15989.test.c` : Unable to initialize enum with class or pointer to struct
+fail_compilation/test15989.d(50): use static const variable instead
+fail_compilation/test15989.d(51): Error: cannot use non-constant CTFE pointer in an initializer `new int(3)`
+fail_compilation/test20489.d(19): Error: function `pure nothrow @nogc @safe int test20489.D.f(int delegate(int) pure nothrow @nogc @safe body)` does not override any function, did you mean to override `pure nothrow @nogc @safe int test20489.B.f(scope int delegate(int) pure nothrow @nogc @safe)`?
+fail_compilation/test20489.d(19): Did you intend to override:
+fail_compilation/test20489.d(19): `pure nothrow @nogc @safe int test20489.B.f(scope int delegate(int) pure nothrow @nogc @safe)`
+fail_compilation/test20489.d(19): Parameter 1 is missing `scope`
+---
+*/
+
+// Test case for https://github.com/dlang/dmd/issues/20489
+// Improved error message on override mismatches
+
+class B {
+ pure nothrow @nogc @safe int f(scope int delegate(int) pure nothrow @nogc @safe) { return 0; }
+}
+
+class D : B {
+ override pure nothrow @nogc @safe int f(int delegate(int) pure nothrow @nogc @safe body) { return 0; }
fail_compilation/testrvaluecpctor.d(16): Error: cannot define both an rvalue constructor and a copy constructor for `struct Foo`
fail_compilation/testrvaluecpctor.d(24): Template instance `testrvaluecpctor.Foo!int.Foo.__ctor!(immutable(Foo!int), immutable(Foo!int))` creates an rvalue constructor for `struct Foo`
-fail_compilation/testrvaluecpctor.d(24): Error: none of the overloads of `this` can construct a `immutable` object with argument types `(immutable(Foo!int))`
+fail_compilation/testrvaluecpctor.d(24): Error: none of the overloads of `this` can construct an immutable object with argument types `(immutable(Foo!int))`. Expected `immutable(immutable(Foo!int))`
-fail_compilation/union_conv.d(18): Error: cannot implicitly convert expression `c` of type `const(U)` to `U`
+fail_compilation/union_conv.d(18): Error: cannot implicitly convert expression `c` of type `const(U)` to `U` because union `U` contains pointers or references