diff --git a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala index 67fee03c1964..3768d4f26598 100644 --- a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala +++ b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala @@ -58,7 +58,7 @@ class ReTyper extends Typer { } override def typedUnApply(tree: untpd.UnApply, selType: Type)(implicit ctx: Context): UnApply = { - val fun1 = typedExpr(tree.fun, AnyFunctionProto) + val fun1 = typedUnadapted(tree.fun, AnyFunctionProto) val implicits1 = tree.implicits.map(typedExpr(_)) val patterns1 = tree.patterns.mapconserve(pat => typed(pat, pat.tpe)) untpd.cpy.UnApply(tree)(fun1, implicits1, patterns1).withType(tree.tpe) @@ -104,4 +104,6 @@ class ReTyper extends Typer { Implicits.NoImplicitMatches override def checkCanEqual(ltp: Type, rtp: Type, pos: Position)(implicit ctx: Context): Unit = () override def inlineExpansion(mdef: DefDef)(implicit ctx: Context): List[Tree] = mdef :: Nil + + override protected def checkEqualityEvidence(tree: tpd.Tree, pt: Type)(implicit ctx: Context): Unit = () } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a9055e331ac0..6b3406f1c426 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3,7 +3,7 @@ package dotc package typer import core._ -import ast._ +import ast.{tpd, _} import Trees._ import Constants._ import StdNames._ @@ -28,15 +28,17 @@ import EtaExpansion.etaExpand import dotty.tools.dotc.transform.Erasure.Boxing import util.Positions._ import util.common._ -import util.{SourcePosition, Property} +import util.{Property, SourcePosition} + import collection.mutable import annotation.tailrec import Implicits._ -import util.Stats.{track, record} -import config.Printers.{typr, gadts} +import util.Stats.{record, track} +import config.Printers.{gadts, typr} import rewrite.Rewrites.patch import NavigateAST._ import transform.SymUtils._ + import language.implicitConversions import printing.SyntaxHighlighting._ @@ -2122,17 +2124,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit typed(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt) } else if (ctx.mode is Mode.Pattern) { - tree match { - case _: RefTree | _: Literal - if !isVarPattern(tree) && - !(tree.tpe <:< pt)(ctx.addMode(Mode.GADTflexible)) => - val cmp = - untpd.Apply( - untpd.Select(untpd.TypedSplice(tree), nme.EQ), - untpd.TypedSplice(dummyTreeOfType(pt))) - typedExpr(cmp, defn.BooleanType)(ctx.retractMode(Mode.Pattern)) - case _ => - } + checkEqualityEvidence(tree, pt) tree } else if (tree.tpe <:< pt) { @@ -2277,4 +2269,24 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } } } + + /** Check that `tree == x: pt` is typeable. Used when checking a pattern + * against a selector of type `pt`. This implementation accounts for + * user-defined definitions of `==`. + * + * Overwritten to no-op in ReTyper. + */ + protected def checkEqualityEvidence(tree: tpd.Tree, pt: Type)(implicit ctx: Context) : Unit = { + tree match { + case _: RefTree | _: Literal + if !isVarPattern(tree) && + !(tree.tpe <:< pt) (ctx.addMode(Mode.GADTflexible)) => + val cmp = + untpd.Apply( + untpd.Select(untpd.TypedSplice(tree), nme.EQ), + untpd.TypedSplice(dummyTreeOfType(pt))) + typedExpr(cmp, defn.BooleanType) + case _ => + } + } } diff --git a/tests/pos/i3050.scala b/tests/pos/i3050.scala new file mode 100644 index 000000000000..799dbdc1a0dc --- /dev/null +++ b/tests/pos/i3050.scala @@ -0,0 +1,11 @@ +object Test { + inline def openImpl(): Int = + Some(42) match { case Some(i) => i } + + def open(): Int = openImpl() + + inline def openImpl2(): Int = + Some(42) match { case None => 42 } + + def open2(): Int = openImpl2() +}