Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #20888 - Compiler spits out implicit conversion technobabble when a return statement doesn't match the return type of a function #20890

Merged
merged 1 commit into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion compiler/src/dmd/semantic3.d
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,37 @@
// if a copy constructor is present, the return type conversion will be handled by it
const hasCopyCtor = exp.type.ty == Tstruct && (cast(TypeStruct)exp.type).sym.hasCopyCtor;
if (!hasCopyCtor || !exp.isLvalue())
exp = exp.implicitCastTo(sc2, tret);
{
const errors = global.startGagging();
auto implicitlyCastedExp = exp.implicitCastTo(sc2, tret);
global.endGagging(errors);

// <https://github.com/dlang/dmd/issues/20888>
if (implicitlyCastedExp.isErrorExp())
{
auto types = toAutoQualChars(exp.type, tret);
error(
exp.loc,
"return value `%s` of type `%s` does not match return type `%s`"
~ ", and cannot be implicitly converted",
exp.toErrMsg(),
types[0],
types[1],
);

if (const func = exp.type.isFunction_Delegate_PtrToFunction())
if (func.next.equals(tret))
errorSupplemental(

Check warning on line 956 in compiler/src/dmd/semantic3.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/semantic3.d#L955-L956

Added lines #L955 - L956 were not covered by tests
exp.loc,
"Did you intend to call the %s?",
(exp.type.isPtrToFunction())
? "function pointer"
: exp.type.kind

Check warning on line 961 in compiler/src/dmd/semantic3.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/semantic3.d#L960-L961

Added lines #L960 - L961 were not covered by tests
);
}

exp = implicitlyCastedExp;
}

exp = exp.optimize(WANTvalue);

Expand Down
71 changes: 71 additions & 0 deletions compiler/test/fail_compilation/diag20888.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag20888.d(24): Error: return value `callback` of type `int function()` does not match return type `int`, and cannot be implicitly converted
fail_compilation/diag20888.d(24): Did you intend to call the function pointer?
fail_compilation/diag20888.d(29): Error: return value `s` of type `string` does not match return type `int`, and cannot be implicitly converted
fail_compilation/diag20888.d(34): Error: return value `callback` of type `int delegate()` does not match return type `int`, and cannot be implicitly converted
fail_compilation/diag20888.d(34): Did you intend to call the delegate?
fail_compilation/diag20888.d(39): Error: return value `callback` of type `int delegate()` does not match return type `int`, and cannot be implicitly converted
fail_compilation/diag20888.d(39): Did you intend to call the delegate?
fail_compilation/diag20888.d(44): Error: return value `callback` of type `int delegate()*` does not match return type `int`, and cannot be implicitly converted
fail_compilation/diag20888.d(49): Error: return value `callback` of type `int delegate()` does not match return type `string`, and cannot be implicitly converted
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(59): Error: `return` expression expected
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?
---
*/

int alpha(int function() callback)
{
return callback;
}

int beta(string s)
{
return s;
}

int gamma(int delegate() callback)
{
return callback;
}

int delta(int delegate() callback)
{
return callback;
}

int epsilon(int delegate()* callback)
{
return callback; // no supplemental yet
}

string zeta(int delegate() callback)
{
return callback;
}

int eta()
{
return () => 0xEAB;
}

int theta()
{
return;
}

void iota()
{
return 0xEAB;
}

int kappa()
{
int i = 0xEAB;
return () { return i; };
}
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/fail100.d
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail100.d(24): Error: cannot implicitly convert expression `f` of type `Class[]` to `I[]`
fail_compilation/fail100.d(24): Error: return value `f` of type `Class[]` does not match return type `I[]`, and cannot be implicitly converted
---
*/

Expand Down
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/fail13498.d
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail13498.d(11): Error: cannot implicitly convert expression `"foo"` of type `string` to `int`
fail_compilation/fail13498.d(11): Error: return value `"foo"` of type `string` does not match return type `int`, and cannot be implicitly converted
fail_compilation/fail13498.d(16): Error: template instance `fail13498.foo!()` error instantiating
---
*/
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/fail20073.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
TEST_OUTPUT:
---
fail_compilation/fail20073.d(20): Error: cannot implicitly convert expression `s` of type `S` to `string`
fail_compilation/fail20073.d(21): Error: cannot implicitly convert expression `s` of type `S` to `string`
fail_compilation/fail20073.d(21): Error: return value `s` of type `S` does not match return type `string`, and cannot be implicitly converted
---
*/

Expand Down
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/fail20376.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail20376.d(17): Error: cannot implicitly convert expression `Foo()` of type `Foo` to `ubyte`
fail_compilation/fail20376.d(17): Error: return value `Foo()` of type `Foo` does not match return type `ubyte`, and cannot be implicitly converted
---
*/

Expand Down
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/noreturn2.d
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ NR returns()
/+
TEST_OUTPUT:
---
fail_compilation/noreturn2.d(64): Error: cannot implicitly convert expression `1` of type `int` to `noreturn`
fail_compilation/noreturn2.d(64): Error: return value `1` of type `int` does not match return type `noreturn`, and cannot be implicitly converted
---
+/

Expand Down
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/shared.d
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fail_compilation/shared.d(2216): return value `getSharedObject()` is not
fail_compilation/shared.d(2222): Error: direct access to shared `a` is not allowed, see `core.atomic`
fail_compilation/shared.d(2220): Error: function `shared.test_inference_4` function returns `shared` but cannot be inferred `ref`
fail_compilation/shared.d(2222): cannot implicitly convert `a` of type `shared(const(Object))` to `object.Object`
fail_compilation/shared.d(2222): Error: cannot implicitly convert expression `a` of type `shared(const(Object))` to `object.Object`
fail_compilation/shared.d(2222): Error: return value `a` of type `shared(const(Object))` does not match return type `object.Object`, and cannot be implicitly converted
---
*/

Expand Down
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/test14538.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/test14538.d(18): Error: cannot implicitly convert expression `x ? cast(uint)this.fCells[x].code : 32u` of type `uint` to `Cell`
fail_compilation/test14538.d(18): Error: return value `x ? cast(uint)this.fCells[x].code : 32u` of type `uint` does not match return type `Cell`, and cannot be implicitly converted
---
*/

Expand Down
34 changes: 17 additions & 17 deletions compiler/test/fail_compilation/testInference.d
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/testInference.d(24): Error: cannot implicitly convert expression `this.a` of type `inout(A8998)` to `immutable(A8998)`
fail_compilation/testInference.d(24): Error: return value `this.a` of type `inout(A8998)` does not match return type `immutable(A8998)`, and cannot be implicitly converted
---
*/

Expand All @@ -28,10 +28,10 @@ class C8998
/*
TEST_OUTPUT:
---
fail_compilation/testInference.d(39): Error: cannot implicitly convert expression `s` of type `const(char[])` to `string`
fail_compilation/testInference.d(44): Error: cannot implicitly convert expression `a` of type `int[]` to `immutable(int[])`
fail_compilation/testInference.d(49): Error: cannot implicitly convert expression `a` of type `int[]` to `immutable(int[])`
fail_compilation/testInference.d(54): Error: cannot implicitly convert expression `a` of type `int[]` to `immutable(int[])`
fail_compilation/testInference.d(39): Error: return value `s` of type `const(char[])` does not match return type `string`, and cannot be implicitly converted
fail_compilation/testInference.d(44): Error: return value `a` of type `int[]` does not match return type `immutable(int[])`, and cannot be implicitly converted
fail_compilation/testInference.d(49): Error: return value `a` of type `int[]` does not match return type `immutable(int[])`, and cannot be implicitly converted
fail_compilation/testInference.d(54): Error: return value `a` of type `int[]` does not match return type `immutable(int[])`, and cannot be implicitly converted
---
*/
string foo(in char[] s) pure
Expand All @@ -58,18 +58,18 @@ immutable(int[]) x3(immutable(int[]) org) /*pure*/
/*
TEST_OUTPUT:
---
fail_compilation/testInference.d(94): Error: cannot implicitly convert expression `c` of type `testInference.C1` to `immutable(C1)`
fail_compilation/testInference.d(95): Error: cannot implicitly convert expression `c` of type `testInference.C1` to `immutable(C1)`
fail_compilation/testInference.d(96): Error: cannot implicitly convert expression `c` of type `testInference.C3` to `immutable(C3)`
fail_compilation/testInference.d(97): Error: cannot implicitly convert expression `c` of type `testInference.C3` to `immutable(C3)`
fail_compilation/testInference.d(94): Error: return value `c` of type `testInference.C1` does not match return type `immutable(C1)`, and cannot be implicitly converted
fail_compilation/testInference.d(95): Error: return value `c` of type `testInference.C1` does not match return type `immutable(C1)`, and cannot be implicitly converted
fail_compilation/testInference.d(96): Error: return value `c` of type `testInference.C3` does not match return type `immutable(C3)`, and cannot be implicitly converted
fail_compilation/testInference.d(97): Error: return value `c` of type `testInference.C3` does not match return type `immutable(C3)`, and cannot be implicitly converted
fail_compilation/testInference.d(100): Error: undefined identifier `X1`, did you mean function `x1`?
fail_compilation/testInference.d(106): Error: cannot implicitly convert expression `s` of type `S1` to `immutable(S1)`
fail_compilation/testInference.d(109): Error: cannot implicitly convert expression `a` of type `int*[]` to `immutable(int*[])`
fail_compilation/testInference.d(110): Error: cannot implicitly convert expression `a` of type `const(int)*[]` to `immutable(int*[])`
fail_compilation/testInference.d(114): Error: cannot implicitly convert expression `s` of type `S2` to `immutable(S2)`
fail_compilation/testInference.d(115): Error: cannot implicitly convert expression `s` of type `S2` to `immutable(S2)`
fail_compilation/testInference.d(116): Error: cannot implicitly convert expression `s` of type `S2` to `immutable(S2)`
fail_compilation/testInference.d(118): Error: cannot implicitly convert expression `a` of type `const(int)*[]` to `immutable(int*[])`
fail_compilation/testInference.d(106): Error: return value `s` of type `S1` does not match return type `immutable(S1)`, and cannot be implicitly converted
fail_compilation/testInference.d(109): Error: return value `a` of type `int*[]` does not match return type `immutable(int*[])`, and cannot be implicitly converted
fail_compilation/testInference.d(110): Error: return value `a` of type `const(int)*[]` does not match return type `immutable(int*[])`, and cannot be implicitly converted
fail_compilation/testInference.d(114): Error: return value `s` of type `S2` does not match return type `immutable(S2)`, and cannot be implicitly converted
fail_compilation/testInference.d(115): Error: return value `s` of type `S2` does not match return type `immutable(S2)`, and cannot be implicitly converted
fail_compilation/testInference.d(116): Error: return value `s` of type `S2` does not match return type `immutable(S2)`, and cannot be implicitly converted
fail_compilation/testInference.d(118): Error: return value `a` of type `const(int)*[]` does not match return type `immutable(int*[])`, and cannot be implicitly converted
---
*/
immutable(Object) get(inout int*) pure
Expand Down Expand Up @@ -122,7 +122,7 @@ immutable(int*[]) bar2c( S2 prm) pure { immutable(int)*[] a; return
/*
TEST_OUTPUT:
---
fail_compilation/testInference.d(134): Error: cannot implicitly convert expression `f10063(cast(inout(void*))p)` of type `inout(void)*` to `immutable(void)*`
fail_compilation/testInference.d(134): Error: return value `f10063(cast(inout(void*))p)` of type `inout(void)*` does not match return type `immutable(void)*`, and cannot be implicitly converted
---
*/
inout(void)* f10063(inout void* p) pure
Expand Down
Loading