Skip to content

Commit c792e95

Browse files
authored
Merge pull request #2754 from dotty-staging/fix-#2514-3
Fix #2514 Addendum
2 parents eddf030 + 37c5c7a commit c792e95

File tree

4 files changed

+30
-12
lines changed

4 files changed

+30
-12
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
1414
// Note: the <: Type constraint looks necessary (and is needed to make the file compile in dotc).
1515
// But Scalac accepts the program happily without it. Need to find out why.
1616

17-
def unsplice[T >: Untyped](tree: Trees.Tree[T]): Trees.Tree[T] = tree.asInstanceOf[untpd.Tree] match {
18-
case untpd.TypedSplice(tree1) => tree1.asInstanceOf[Trees.Tree[T]]
19-
case _ => tree
20-
}
17+
def unsplice(tree: Trees.Tree[T]): Trees.Tree[T] = tree
2118

2219
def isDeclarationOrTypeDef(tree: Tree): Boolean = unsplice(tree) match {
2320
case DefDef(_, _, _, _, EmptyTree)
@@ -116,7 +113,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
116113
case _ => false
117114
}
118115

119-
def isSuperSelection(tree: untpd.Tree) = unsplice(tree) match {
116+
def isSuperSelection(tree: Tree) = unsplice(tree) match {
120117
case Select(Super(_, _), _) => true
121118
case _ => false
122119
}
@@ -129,7 +126,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
129126
}
130127

131128
/** Is tree a variable pattern? */
132-
def isVarPattern(pat: untpd.Tree): Boolean = unsplice(pat) match {
129+
def isVarPattern(pat: Tree): Boolean = unsplice(pat) match {
133130
case x: BackquotedIdent => false
134131
case x: Ident => x.name.isVariableName
135132
case _ => false
@@ -160,7 +157,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
160157
def isLeftAssoc(operator: Name) = !operator.isEmpty && (operator.toSimpleName.last != ':')
161158

162159
/** can this type be a type pattern? */
163-
def mayBeTypePat(tree: untpd.Tree): Boolean = unsplice(tree) match {
160+
def mayBeTypePat(tree: Tree): Boolean = unsplice(tree) match {
164161
case AndTypeTree(tpt1, tpt2) => mayBeTypePat(tpt1) || mayBeTypePat(tpt2)
165162
case OrTypeTree(tpt1, tpt2) => mayBeTypePat(tpt1) || mayBeTypePat(tpt2)
166163
case RefinedTypeTree(tpt, refinements) => mayBeTypePat(tpt) || refinements.exists(_.isInstanceOf[Bind])
@@ -253,6 +250,13 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
253250
import TreeInfo._
254251
import untpd._
255252

253+
/** The underlying tree when stripping any TypedSplice or Parens nodes */
254+
override def unsplice(tree: Tree): Tree = tree match {
255+
case TypedSplice(tree1) => tree1
256+
case Parens(tree1) => unsplice(tree1)
257+
case _ => tree
258+
}
259+
256260
/** True iff definition is a val or def with no right-hand-side, or it
257261
* is an abstract typoe declaration
258262
*/

compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,12 @@ object ErrorReporting {
104104

105105
def patternConstrStr(tree: Tree): String = ???
106106

107-
def typeMismatch(tree: Tree, pt: Type, implicitFailure: SearchFailure = NoImplicitMatches): Tree =
108-
errorTree(tree, typeMismatchMsg(normalize(tree.tpe, pt), pt, implicitFailure.postscript))
107+
def typeMismatch(tree: Tree, pt: Type, implicitFailure: SearchFailure = NoImplicitMatches): Tree = {
108+
val normTp = normalize(tree.tpe, pt)
109+
val treeTp = if (normTp <:< pt) tree.tpe else normTp
110+
// use normalized type if that also shows an error, original type otherwise
111+
errorTree(tree, typeMismatchMsg(treeTp, pt, implicitFailure.postscript))
112+
}
109113

110114
/** A subtype log explaining why `found` does not conform to `expected` */
111115
def whyNoMatchStr(found: Type, expected: Type) = {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
316316
if (ctx.mode is Mode.Pattern) {
317317
if (name == nme.WILDCARD)
318318
return tree.withType(pt)
319-
if (isVarPattern(tree) && name.isTermName)
319+
if (untpd.isVarPattern(tree) && name.isTermName)
320320
return typed(desugar.patternVar(tree), pt)
321321
}
322322

@@ -496,7 +496,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
496496
* (x: T) to (x @ (w: T)). This is either `_` or `_*`.
497497
*/
498498
def cases(ifPat: => Tree, ifExpr: => Tree, wildName: TermName) = tree.expr match {
499-
case id: untpd.Ident if (ctx.mode is Mode.Pattern) && isVarPattern(id) =>
499+
case id: untpd.Ident if (ctx.mode is Mode.Pattern) && untpd.isVarPattern(id) =>
500500
if (id.name == nme.WILDCARD || id.name == nme.WILDCARD_STAR) ifPat
501501
else {
502502
import untpd._
@@ -1114,7 +1114,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
11141114
def typedArg(arg: untpd.Tree, tparam: ParamInfo) = {
11151115
val (desugaredArg, argPt) =
11161116
if (ctx.mode is Mode.Pattern)
1117-
(if (isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.paramInfo)
1117+
(if (untpd.isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.paramInfo)
11181118
else
11191119
(arg, WildcardType)
11201120
if (tpt1.symbol.isClass)

tests/neg/i2514a.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Foo {
2+
def foo(): Int = {
3+
val f: implicit Int => Int = implicit (x: Int) => 2 * x
4+
f(2)
5+
}
6+
7+
val f = implicit (x: Int) => x
8+
9+
(implicit (x: Int) => x): (implicit Int => Int) // error: no implicit argument found
10+
}

0 commit comments

Comments
 (0)