From 7256a1243473cafc17057545d10a1836a8423de9 Mon Sep 17 00:00:00 2001 From: Aggelos Biboudis Date: Mon, 4 Sep 2017 18:38:01 +0200 Subject: [PATCH 1/4] Fix #3050 --- compiler/src/dotty/tools/dotc/typer/ReTyper.scala | 4 +++- compiler/src/dotty/tools/dotc/typer/Typer.scala | 3 ++- tests/pos/i3050.scala | 11 +++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 tests/pos/i3050.scala diff --git a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala index 67fee03c1964..00f6c72b0e76 100644 --- a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala +++ b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala @@ -58,7 +58,9 @@ class ReTyper extends Typer { } override def typedUnApply(tree: untpd.UnApply, selType: Type)(implicit ctx: Context): UnApply = { - val fun1 = typedExpr(tree.fun, AnyFunctionProto) + val funProto = new UnapplyFunProto(WildcardType, this) + + val fun1 = typedExpr(tree.fun, funProto) 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) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a9055e331ac0..2cfab8bcc3c1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2125,7 +2125,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit tree match { case _: RefTree | _: Literal if !isVarPattern(tree) && - !(tree.tpe <:< pt)(ctx.addMode(Mode.GADTflexible)) => + !(tree.tpe <:< pt)(ctx.addMode(Mode.GADTflexible)) && + !this.isInstanceOf[ReTyper] => val cmp = untpd.Apply( untpd.Select(untpd.TypedSplice(tree), nme.EQ), 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() +} From c938deb25eb14aa4aa8ebbe1479b337cb98fa10b Mon Sep 17 00:00:00 2001 From: Aggelos Biboudis Date: Tue, 5 Sep 2017 13:15:13 +0200 Subject: [PATCH 2/4] Use typedUnadapted instead of typedExpr in ReTyper.typedUnApply --- compiler/src/dotty/tools/dotc/typer/ReTyper.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala index 00f6c72b0e76..b457aebbb9ef 100644 --- a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala +++ b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala @@ -58,9 +58,7 @@ class ReTyper extends Typer { } override def typedUnApply(tree: untpd.UnApply, selType: Type)(implicit ctx: Context): UnApply = { - val funProto = new UnapplyFunProto(WildcardType, this) - - val fun1 = typedExpr(tree.fun, funProto) + 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) From c5acd9955df323a1d0c9e0d2968cfd75a9b1bd6f Mon Sep 17 00:00:00 2001 From: Aggelos Biboudis Date: Tue, 5 Sep 2017 13:24:41 +0200 Subject: [PATCH 3/4] Extract check to a protected method on Typer and override with an empty one on ReTyper --- .../src/dotty/tools/dotc/typer/ReTyper.scala | 2 + .../src/dotty/tools/dotc/typer/Typer.scala | 37 +++++++++++-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala index b457aebbb9ef..3768d4f26598 100644 --- a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala +++ b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala @@ -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 2cfab8bcc3c1..cdc7d0bf1e6a 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,18 +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)) && - !this.isInstanceOf[ReTyper] => - 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) { @@ -2278,4 +2269,18 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } } } + + 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)(ctx.retractMode(Mode.Pattern)) + case _ => + } + } } From 40a183af21b327792855b6e621e3a809165529e0 Mon Sep 17 00:00:00 2001 From: Aggelos Biboudis Date: Thu, 7 Sep 2017 16:27:51 +0200 Subject: [PATCH 4/4] Add a comment and remove extraneous retraction from context --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index cdc7d0bf1e6a..6b3406f1c426 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2270,6 +2270,12 @@ 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 @@ -2279,7 +2285,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit untpd.Apply( untpd.Select(untpd.TypedSplice(tree), nme.EQ), untpd.TypedSplice(dummyTreeOfType(pt))) - typedExpr(cmp, defn.BooleanType)(ctx.retractMode(Mode.Pattern)) + typedExpr(cmp, defn.BooleanType) case _ => } }