mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Improve opIndex/opSlice error messages (#20791)
This commit is contained in:
parent
cfd2dde588
commit
a55dff5f28
6 changed files with 95 additions and 29 deletions
|
@ -30,12 +30,26 @@ Error: `app.bar` called with argument types `(string)` matches multiple overload
|
|||
*/
|
||||
---
|
||||
|
||||
When there's no operator overload found for a type, a new supplemental message points to the declaration.
|
||||
When there's no index / slice operator overload found for a type, a new supplemental message suggests where to implement it.
|
||||
|
||||
---
|
||||
struct S {}
|
||||
|
||||
void main()
|
||||
{
|
||||
S s;
|
||||
const x = s[3 .. "4"];
|
||||
}
|
||||
|
||||
/*
|
||||
app.d(8): Error: no `[]` operator overload for type `U`
|
||||
app.d(6): `app.U` declared here
|
||||
Before:
|
||||
|
||||
app.d(6): Error: no `[]` operator overload for type `S`
|
||||
|
||||
After:
|
||||
|
||||
app.d(6): Error: no `[3.."4"]` operator overload for type `S`
|
||||
app.d(1): perhaps define `auto opSlice(int lower, string upper) {}` for `app.S`
|
||||
*/
|
||||
---
|
||||
|
||||
|
|
|
@ -9706,8 +9706,39 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
|
||||
if (auto ad = isAggregate(exp.e1.type))
|
||||
{
|
||||
error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
|
||||
errorSupplemental(ad.loc, "`%s` declared here", ad.toPrettyChars());
|
||||
if (exp.arguments.length == 0)
|
||||
{
|
||||
error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
|
||||
errorSupplemental(ad.loc, "perhaps define `auto opIndex() {}` for `%s`", ad.toPrettyChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
const(char)* typeString(Expression exp)
|
||||
{
|
||||
if (auto e = exp.trySemantic(sc))
|
||||
return e.type.toChars();
|
||||
else
|
||||
return "__error__";
|
||||
}
|
||||
|
||||
if (auto ie = (*exp.arguments)[0].isIntervalExp())
|
||||
{
|
||||
error(exp.loc, "no `[%s]` operator overload for type `%s`", ie.toChars(), exp.e1.type.toChars());
|
||||
errorSupplemental(ad.loc, "perhaps define `auto opSlice(%s lower, %s upper) {}` for `%s`",
|
||||
typeString(ie.lwr), typeString(ie.upr), ad.toPrettyChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
OutBuffer buf;
|
||||
buf.printf("%s", typeString((*exp.arguments)[0]));
|
||||
foreach (e; (*exp.arguments)[1 .. $])
|
||||
buf.printf(", %s", typeString(e));
|
||||
|
||||
error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
|
||||
errorSupplemental(ad.loc, "perhaps define `auto opIndex(%s) {}` for `%s`",
|
||||
buf.extractChars, ad.toPrettyChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (exp.e1.op == EXP.type && exp.e1.type.ty != Ttuple)
|
||||
error(exp.loc, "static array of `%s` with multiple lengths not allowed", exp.e1.type.toChars());
|
||||
|
|
|
@ -403,9 +403,9 @@ Expression opOverloadArray(ArrayExp ae, Scope* sc)
|
|||
|
||||
if (result.op == EXP.error)
|
||||
{
|
||||
if (!e0 && !search_function(ad, Id.dollar)) {
|
||||
ae.loc.errorSupplemental("Aggregate declaration '%s' does not define 'opDollar'", ae.e1.toChars());
|
||||
}
|
||||
if (!e0 && !search_function(ad, Id.dollar))
|
||||
ad.loc.errorSupplemental("perhaps define `opDollar` for `%s`", ad.toChars());
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Rewrite a[i..j] as:
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail20616.d(16): Error: undefined identifier `$`
|
||||
fail_compilation/fail20616.d(16): Aggregate declaration 'X()' does not define 'opDollar'
|
||||
fail_compilation/fail20616.d(13): perhaps define `opDollar` for `X`
|
||||
fail_compilation/fail20616.d(18): Error: undefined identifier `$`
|
||||
fail_compilation/fail20616.d(18): Aggregate declaration 'b' does not define 'opDollar'
|
||||
fail_compilation/fail20616.d(13): perhaps define `opDollar` for `X`
|
||||
---
|
||||
*/
|
||||
module fail20616;
|
||||
|
|
|
@ -6,7 +6,7 @@ fail_compilation/fail_arrayexp.d(25): Error: cannot use `[]` operator on express
|
|||
fail_compilation/fail_arrayexp.d(26): Error: static array of `const(int)[]` with multiple lengths not allowed
|
||||
fail_compilation/fail_arrayexp.d(27): Error: only one index allowed to index `string`
|
||||
fail_compilation/fail_arrayexp.d(28): Error: no `[]` operator overload for type `U`
|
||||
fail_compilation/fail_arrayexp.d(16): `fail_arrayexp.U` declared here
|
||||
fail_compilation/fail_arrayexp.d(16): perhaps define `auto opIndex() {}` for `fail_arrayexp.U`
|
||||
fail_compilation/fail_arrayexp.d(29): Error: only one index allowed to index `(int, string)`
|
||||
---
|
||||
*/
|
||||
|
@ -29,3 +29,24 @@ void test19534() // https://issues.dlang.org/show_bug.cgi?id=19534
|
|||
auto t = agg[];
|
||||
auto u = getTuple!(int, string)[1, 2];
|
||||
}
|
||||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_arrayexp.d(49): Error: no `[3.."4"]` operator overload for type `S`
|
||||
fail_compilation/fail_arrayexp.d(42): perhaps define `auto opSlice(int lower, string upper) {}` for `fail_arrayexp.S`
|
||||
fail_compilation/fail_arrayexp.d(50): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_arrayexp.d(42): perhaps define `auto opIndex(int, string, char) {}` for `fail_arrayexp.S`
|
||||
---
|
||||
*/
|
||||
|
||||
struct S
|
||||
{
|
||||
}
|
||||
|
||||
void testSlice()
|
||||
{
|
||||
S s;
|
||||
const b = s[3 .. "4"];
|
||||
const c = s[3, "4", 'c'];
|
||||
}
|
||||
|
|
|
@ -4,33 +4,33 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_opover.d(39): Error: no `[]` operator overload for type `object.Object`
|
||||
$p:object.d$(110): `object.Object` declared here
|
||||
$p:object.d$(110): perhaps define `auto opIndex() {}` for `object.Object`
|
||||
fail_compilation/fail_opover.d(43): Error: no `[]` operator overload for type `TestS`
|
||||
fail_compilation/fail_opover.d(41): `fail_opover.test1.TestS` declared here
|
||||
fail_compilation/fail_opover.d(41): perhaps define `auto opIndex() {}` for `fail_opover.test1.TestS`
|
||||
fail_compilation/fail_opover.d(55): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(56): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(57): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(57): Error: no `[1..2]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(58): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(59): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(60): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(60): Error: no `[1..2]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(61): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(62): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(63): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(63): Error: no `[1..2]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(64): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(65): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(66): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(66): Error: no `[1..2]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
|
||||
---
|
||||
*/
|
||||
void test1()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue