Skip to content

Commit 32fae15

Browse files
committed
Fix Compiler should explain why implicit conversion to mutable fails
1 parent 35f1146 commit 32fae15

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

compiler/src/dmd/dcast.d

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,23 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
149149
//type = type.typeSemantic(loc, sc);
150150
//printf("type %s t %s\n", type.deco, t.deco);
151151
auto ts = toAutoQualChars(e.type, t);
152+
153+
// Special case for improved diagnostic when const to mutable conversion
154+
// fails due to struct having pointers
155+
if (e.type.ty == Tstruct && t.ty == Tstruct &&
156+
e.type.isTypeStruct().sym == t.isTypeStruct().sym &&
157+
e.type.mod == MODFlags.const_ && t.mod == 0)
158+
{
159+
auto sym = e.type.isTypeStruct().sym;
160+
sym.determineTypeProperties();
161+
if (sym.hasPointerField)
162+
{
163+
error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s` because struct `%s` contains pointers or references",
164+
e.toErrMsg(), ts[0], ts[1], sym.toChars());
165+
return ErrorExp.get();
166+
}
167+
}
168+
152169
error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
153170
e.toErrMsg(), ts[0], ts[1]);
154171
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
TEST_OUTPUT:
3+
---
4+
fail_compilation/fix20318.d(16): Error: cannot implicitly convert expression `c` of type `const(Bar)` to `Bar` because struct `Bar` contains pointers or references
5+
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
6+
---
7+
*/
8+
9+
void main() {
10+
// This should work - struct without pointers
11+
const Foo a;
12+
Foo b = a; // This is okay
13+
14+
// This should fail with improved diagnostic message
15+
const Bar c;
16+
Bar d = c; // Error with improved diagnostic message
17+
18+
// Test with a more complex struct with nested pointers
19+
const ComplexBar complex_c;
20+
ComplexBar complex_d = complex_c; // Give improved error message
21+
}
22+
23+
struct Foo {
24+
int value;
25+
}
26+
27+
struct Bar {
28+
void* ptr;
29+
}
30+
31+
// Simple struct without pointers
32+
struct Simple {
33+
int value;
34+
}
35+
36+
// Struct with a pointer
37+
struct WithPointer {
38+
int* ptr;
39+
}
40+
41+
// Complex struct that contains another struct with pointers
42+
struct ComplexBar {
43+
Simple simple; // This is fine
44+
int data; // This is fine
45+
WithPointer nested; // This field prevents implicit conversion
46+
}

0 commit comments

Comments
 (0)