diff --git a/compiler/src/dmd/dcast.d b/compiler/src/dmd/dcast.d index 1f9126069f..9e35dde296 100644 --- a/compiler/src/dmd/dcast.d +++ b/compiler/src/dmd/dcast.d @@ -161,8 +161,27 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t) return ErrorExp.get(); } - error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", - e.toErrMsg(), ts[0], ts[1]); + // Special case for pointer conversions + if (e.type.toBasetype().ty == Tpointer && t.toBasetype().ty == Tpointer) + { + Type fromPointee = e.type.nextOf(); + Type toPointee = t.nextOf(); + // Const -> mutable conversion (disallowed) + if (fromPointee.isConst() && !toPointee.isConst()) + { + error(e.loc, "cannot implicitly convert `%s` to `%s`", e.type.toChars(), t.toChars()); + errorSupplemental(e.loc, "Note: Converting const to mutable requires an explicit cast (`cast(int*)`)."); + return ErrorExp.get(); + } + // Incompatible pointee types (e.g., int* -> float* ) + else if (fromPointee.toBasetype().ty != toPointee.toBasetype().ty) + { + error(e.loc, "cannot implicitly convert `%s` to `%s`", e.type.toChars(), t.toChars()); + errorSupplemental(e.loc, "Note: Pointer types point to different base types (`%s` vs `%s`)", fromPointee.toChars(), toPointee.toChars()); + return ErrorExp.get(); + } + } + error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", e.toErrMsg(), ts[0], ts[1]); } } return ErrorExp.get(); diff --git a/compiler/test/fail_compilation/diag_ptr_conversion.d b/compiler/test/fail_compilation/diag_ptr_conversion.d new file mode 100644 index 0000000000..ea144b2c9d --- /dev/null +++ b/compiler/test/fail_compilation/diag_ptr_conversion.d @@ -0,0 +1,17 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/diag_ptr_conversion.d(15): Error: cannot implicitly convert `const(int)*` to `int*` +fail_compilation/diag_ptr_conversion.d(15): Note: Converting const to mutable requires an explicit cast (`cast(int*)`). +fail_compilation/diag_ptr_conversion.d(16): Error: cannot implicitly convert `int*` to `float*` +fail_compilation/diag_ptr_conversion.d(16): Note: Pointer types point to different base types (`int` vs `float`) +--- +*/ + +void testPointerConversions() +{ + int* p; + const(int)* cp = p; + p = cp; + float* f = p; +} diff --git a/compiler/test/fail_compilation/fail163.d b/compiler/test/fail_compilation/fail163.d index 7f8f028fa5..590bf23931 100644 --- a/compiler/test/fail_compilation/fail163.d +++ b/compiler/test/fail_compilation/fail163.d @@ -14,7 +14,8 @@ void test1() /* TEST_OUTPUT: --- -fail_compilation/fail163.d(24): Error: cannot implicitly convert expression `p` of type `const(int***)` to `const(int)***` +fail_compilation/fail163.d(25): Error: cannot implicitly convert `const(int***)` to `const(int)***` +fail_compilation/fail163.d(25): Note: Converting const to mutable requires an explicit cast (`cast(int*)`). --- */ void test2() @@ -27,7 +28,7 @@ void test2() /* TEST_OUTPUT: --- -fail_compilation/fail163.d(37): Error: cannot modify `const` expression `p` +fail_compilation/fail163.d(38): Error: cannot modify `const` expression `p` --- */ void test3() @@ -40,7 +41,7 @@ void test3() /* TEST_OUTPUT: --- -fail_compilation/fail163.d(50): Error: cannot implicitly convert expression `cp` of type `const(int)***[]` to `const(uint***)[]` +fail_compilation/fail163.d(51): Error: cannot implicitly convert expression `cp` of type `const(int)***[]` to `const(uint***)[]` --- */ void test4() @@ -53,7 +54,7 @@ void test4() /* TEST_OUTPUT: --- -fail_compilation/fail163.d(63): Error: cannot modify `const` expression `*p` +fail_compilation/fail163.d(64): Error: cannot modify `const` expression `*p` --- */ void test5() @@ -66,8 +67,8 @@ void test5() /* TEST_OUTPUT: --- -fail_compilation/fail163.d(76): Error: cannot implicitly convert expression `& x` of type `int*` to `immutable(int)*` -fail_compilation/fail163.d(77): Error: cannot modify `immutable` expression `*p` +fail_compilation/fail163.d(77): Error: cannot implicitly convert expression `& x` of type `int*` to `immutable(int)*` +fail_compilation/fail163.d(78): Error: cannot modify `immutable` expression `*p` --- */ void test6() @@ -80,7 +81,8 @@ void test6() /* TEST_OUTPUT: --- -fail_compilation/fail163.d(89): Error: cannot implicitly convert expression `& x` of type `const(int)*` to `int*` +fail_compilation/fail163.d(91): Error: cannot implicitly convert `const(int)*` to `int*` +fail_compilation/fail163.d(91): Note: Converting const to mutable requires an explicit cast (`cast(int*)`). --- */ void test7()