Skip to content

Commit 6d40d1d

Browse files
committed
Add more examples to Typer
1 parent f0c360d commit 6d40d1d

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

src/dotty/tools/dotc/reporting/Examples.scala

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package dotty.tools
22
package dotc
33
package reporting
44

5-
import dotc.core.Contexts.Context
5+
import dotc.core._
6+
import Contexts.Context, Decorators._, Symbols._
67
import dotc.printing.SyntaxHighlighting._
8+
import util.{SourcePosition, NoSourcePosition}
79

810
object ErrorExplanations {
911
import dotc.ast.Trees._
@@ -73,4 +75,32 @@ object ErrorExplanations {
7375
val msg =
7476
hl"""A ${"try"} without ${"catch"} or ${"finally"} is equivalent to putting its body in a block; no exceptions are handled."""
7577
}
78+
79+
case class DuplicateBind(bind: untpd.Bind, tree: untpd.CaseDef)(implicit ctx: Context) extends Explanation {
80+
val msg =
81+
em"duplicate pattern variable: `${bind.name}`"
82+
83+
val explanation = {
84+
val pat = tree.pat.show
85+
val guard = tree.guard match {
86+
case untpd.EmptyTree => ""
87+
case guard => s"if ${guard.show}"
88+
}
89+
90+
val body = tree.body match {
91+
case Block(Nil, untpd.EmptyTree) => ""
92+
case body => s" ${body.show}"
93+
}
94+
95+
val caseDef = s"case $pat$guard => $body"
96+
97+
hl"""|Explanation
98+
|===========
99+
|For each ${"case"} bound variable names have to be unique. In:
100+
|
101+
|$caseDef
102+
|
103+
|`${bind.name}` is not unique. Rename one of the binds!""".stripMargin
104+
}
105+
}
76106
}

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import rewrite.Rewrites.patch
3636
import NavigateAST._
3737
import transform.SymUtils._
3838
import language.implicitConversions
39+
import printing.SyntaxHighlighting._
40+
import reporting.ErrorExplanations._
3941

4042
object Typer {
4143

@@ -140,9 +142,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
140142
* imported by <tree>
141143
* or defined in <symbol>
142144
*/
143-
def bindingString(prec: Int, whereFound: Context, qualifier: String = "")(implicit ctx: Context) =
144-
if (prec == wildImport || prec == namedImport) ex"imported$qualifier by ${whereFound.importInfo}"
145-
else ex"defined$qualifier in ${whereFound.owner}"
145+
def bindingString(prec: Int, whereFound: Context, qualifier: String = "") =
146+
if (prec == wildImport || prec == namedImport) {
147+
ex"""imported$qualifier by ${hl"${whereFound.importInfo.toString}"}"""
148+
} else
149+
ex"""defined$qualifier in ${hl"${whereFound.owner.toString}"}"""
146150

147151
/** Check that any previously found result from an inner context
148152
* does properly shadow the new one from an outer context.
@@ -165,9 +169,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
165169
else {
166170
if (!scala2pkg && !previous.isError && !found.isError) {
167171
error(
168-
ex"""reference to $name is ambiguous;
169-
|it is both ${bindingString(newPrec, ctx, "")}
170-
|and ${bindingString(prevPrec, prevCtx, " subsequently")}""",
172+
ex"""|reference to `$name` is ambiguous
173+
|it is both ${bindingString(newPrec, ctx, "")}
174+
|and ${bindingString(prevPrec, prevCtx, " subsequently")}""",
171175
tree.pos)
172176
}
173177
previous
@@ -180,7 +184,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
180184
def checkUnambiguous(found: Type) = {
181185
val other = namedImportRef(site, selectors.tail)
182186
if (other.exists && found.exists && (found != other))
183-
error(em"reference to $name is ambiguous; it is imported twice in ${ctx.tree}",
187+
error(em"reference to `$name` is ambiguous; it is imported twice in ${ctx.tree}",
184188
tree.pos)
185189
found
186190
}
@@ -844,11 +848,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
844848
mapOver(t)
845849
}
846850
}
847-
override def transform(tree: Tree)(implicit ctx: Context) =
848-
super.transform(tree.withType(elimWildcardSym(tree.tpe))) match {
851+
override def transform(trt: Tree)(implicit ctx: Context) =
852+
super.transform(trt.withType(elimWildcardSym(trt.tpe))) match {
849853
case b: Bind =>
850854
if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(b.symbol)
851-
else ctx.error(em"duplicate pattern variable: ${b.name}", b.pos)
855+
else ctx.explainError(DuplicateBind(b, tree), b.pos)
852856
b.symbol.info = elimWildcardSym(b.symbol.info)
853857
b
854858
case t => t

0 commit comments

Comments
 (0)