Fix #20318 Compiler should explain why implicit conversion to mutable fails (#20984)

This commit is contained in:
Abul Hossain Khan 2025-03-14 16:39:40 +05:30 committed by GitHub
parent 49dc576b9d
commit 6476cebd44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 65 additions and 1 deletions

View file

@ -149,6 +149,24 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
//type = type.typeSemantic(loc, sc);
//printf("type %s t %s\n", type.deco, t.deco);
auto ts = toAutoQualChars(e.type, t);
// Special case for improved diagnostic when const to mutable conversion
// fails due to struct/union having pointers
if (e.type.ty == Tstruct && t.ty == Tstruct &&
e.type.isTypeStruct().sym == t.isTypeStruct().sym &&
e.type.mod == MODFlags.const_ && t.mod == 0)
{
auto sym = e.type.isTypeStruct().sym;
sym.determineTypeProperties();
if (sym.hasPointerField)
{
const char* typeStr = sym.isUnionDeclaration() ? "union" : "struct";
error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s` because %s `%s` contains pointers or references",
e.toErrMsg(), ts[0], ts[1], typeStr, sym.toChars());
return ErrorExp.get();
}
}
error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
e.toErrMsg(), ts[0], ts[1]);
}

View file

@ -0,0 +1,46 @@
/*
TEST_OUTPUT:
---
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
}

View file

@ -2,7 +2,7 @@
REQUIRED_ARGS: -preview=fixImmutableConv
TEST_OUTPUT:
---
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
---
*/