From 1ace5c08f87317830e6545f39f0167113f0bd303 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Wed, 24 Jan 2018 16:12:22 +0000 Subject: [PATCH 1/2] Improve error message when aggregate template is used as a type Note: s.kind is just "struct" for struct templates. Note: When td.onemember is an alias, we don't know if it resolves to a type or not until the template is instantiated. --- src/dmd/typesem.d | 7 ++++++- test/fail_compilation/diag6539.d | 2 +- test/fail_compilation/notype.d | 31 +++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/fail_compilation/notype.d diff --git a/src/dmd/typesem.d b/src/dmd/typesem.d index 4e636314874c..768dd4888673 100644 --- a/src/dmd/typesem.d +++ b/src/dmd/typesem.d @@ -1156,7 +1156,12 @@ private extern (C++) final class TypeSemanticVisitor : Visitor { if (s) { - s.error(loc, "is used as a type"); + auto td = s.isTemplateDeclaration; + if (td && td.onemember && td.onemember.isAggregateDeclaration) + mtype.error(loc, "%s template `%s` is used as a type without instantiation", + s.kind, s.toPrettyChars); + else + mtype.error(loc, "%s `%s` is used as a type", s.kind, s.toPrettyChars); //assert(0); } else diff --git a/test/fail_compilation/diag6539.d b/test/fail_compilation/diag6539.d index eddb5d2ef838..c202548aac53 100644 --- a/test/fail_compilation/diag6539.d +++ b/test/fail_compilation/diag6539.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/diag6539.d(21): Error: overloadset diag6539.Rectangle is used as a type +fail_compilation/diag6539.d(21): Error: overloadset `diag6539.Rectangle` is used as a type --- */ diff --git a/test/fail_compilation/notype.d b/test/fail_compilation/notype.d new file mode 100644 index 000000000000..835fb1637d4a --- /dev/null +++ b/test/fail_compilation/notype.d @@ -0,0 +1,31 @@ +struct S(int var = 3) { + int a; +} +S s; + +alias A() = int; +A a; + +enum e() = 5; +e val; + +interface I() +{ +} +I i; + +template t() +{ +} +t tv; + +/* +TEST_OUTPUT: +--- +fail_compilation/notype.d(4): Error: struct template `notype.S(int var = 3)` is used as a type without instantiation +fail_compilation/notype.d(7): Error: template `notype.A()` is used as a type +fail_compilation/notype.d(10): Error: template `notype.e()` is used as a type +fail_compilation/notype.d(15): Error: interface template `notype.I()` is used as a type without instantiation +fail_compilation/notype.d(20): Error: template `notype.t()` is used as a type +--- +*/ From 6f6132a5bfd155fc206ae5897883097450572e65 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Thu, 25 Jan 2018 11:44:08 +0000 Subject: [PATCH 2/2] Suggest corrective action --- src/dmd/typesem.d | 5 +++-- test/fail_compilation/notype.d | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dmd/typesem.d b/src/dmd/typesem.d index 768dd4888673..ffa74d83fe09 100644 --- a/src/dmd/typesem.d +++ b/src/dmd/typesem.d @@ -1158,8 +1158,9 @@ private extern (C++) final class TypeSemanticVisitor : Visitor { auto td = s.isTemplateDeclaration; if (td && td.onemember && td.onemember.isAggregateDeclaration) - mtype.error(loc, "%s template `%s` is used as a type without instantiation", - s.kind, s.toPrettyChars); + mtype.error(loc, "template %s `%s` is used as a type without instantiation" + ~ "; to instantiate it use `%s!(arguments)`", + s.kind, s.toPrettyChars, s.ident.toChars); else mtype.error(loc, "%s `%s` is used as a type", s.kind, s.toPrettyChars); //assert(0); diff --git a/test/fail_compilation/notype.d b/test/fail_compilation/notype.d index 835fb1637d4a..1825968517ed 100644 --- a/test/fail_compilation/notype.d +++ b/test/fail_compilation/notype.d @@ -22,10 +22,10 @@ t tv; /* TEST_OUTPUT: --- -fail_compilation/notype.d(4): Error: struct template `notype.S(int var = 3)` is used as a type without instantiation +fail_compilation/notype.d(4): Error: template struct `notype.S(int var = 3)` is used as a type without instantiation; to instantiate it use `S!(arguments)` fail_compilation/notype.d(7): Error: template `notype.A()` is used as a type fail_compilation/notype.d(10): Error: template `notype.e()` is used as a type -fail_compilation/notype.d(15): Error: interface template `notype.I()` is used as a type without instantiation +fail_compilation/notype.d(15): Error: template interface `notype.I()` is used as a type without instantiation; to instantiate it use `I!(arguments)` fail_compilation/notype.d(20): Error: template `notype.t()` is used as a type --- */