Skip to content

Fix #3050: Avoid retyping synthesised code #3065

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/ReTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 = ()
}
42 changes: 27 additions & 15 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package dotc
package typer

import core._
import ast._
import ast.{tpd, _}
import Trees._
import Constants._
import StdNames._
Expand All @@ -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._

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 _ =>
}
}
}
11 changes: 11 additions & 0 deletions tests/pos/i3050.scala
Original file line number Diff line number Diff line change
@@ -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()
}