Skip to content
Prev Previous commit
Next Next commit
suppress checking of for, try and partial functions
  • Loading branch information
liufengyun committed Jul 5, 2016
commit d681a78c554709f6893f6ff3512434534bbcbb41
16 changes: 10 additions & 6 deletions src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -616,16 +616,20 @@ object desugar {
*
* { cases }
* ==>
* x$1 => x$1 match { cases }
* x$1 => (x$1 @unchecked) match { cases }
*
* If `nparams` != 1, expand instead to
*
* (x$1, ..., x$n) => (x$0, ..., x${n-1}) match { cases }
* (x$1, ..., x$n) => (x$0, ..., x${n-1} @unchecked) match { cases }
*/
def makeCaseLambda(cases: List[CaseDef], nparams: Int = 1)(implicit ctx: Context) = {
def makeCaseLambda(cases: List[CaseDef], nparams: Int = 1, unchecked: Boolean = true)(implicit ctx: Context) = {
val params = (1 to nparams).toList.map(makeSyntheticParameter(_))
val selector = makeTuple(params.map(p => Ident(p.name)))
Function(params, Match(selector, cases))

if (unchecked)
Function(params, Match(Annotated(New(ref(defn.UncheckedAnnotType)), selector), cases))
else
Function(params, Match(selector, cases))
}

/** Map n-ary function `(p1, ..., pn) => body` where n != 1 to unary function as follows:
Expand Down Expand Up @@ -753,7 +757,7 @@ object desugar {
case VarPattern(named, tpt) =>
Function(derivedValDef(named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body)
case _ =>
makeCaseLambda(CaseDef(pat, EmptyTree, body) :: Nil)
makeCaseLambda(CaseDef(pat, EmptyTree, body) :: Nil, unchecked = false)
}

/** If `pat` is not an Identifier, a Typed(Ident, _), or a Bind, wrap
Expand Down Expand Up @@ -799,7 +803,7 @@ object desugar {
val cases = List(
CaseDef(pat, EmptyTree, Literal(Constant(true))),
CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false))))
Apply(Select(rhs, nme.withFilter), Match(EmptyTree, cases))
Apply(Select(rhs, nme.withFilter), makeCaseLambda(cases))
}

/** Is pattern `pat` irrefutable when matched against `rhs`?
Expand Down
3 changes: 2 additions & 1 deletion src/dotty/tools/dotc/transform/ExpandSAMs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
Bind(defaultSym, Underscore(selector.tpe.widen)),
EmptyTree,
Literal(Constant(false)))
cpy.Match(applyRhs)(paramRef, cases.map(translateCase) :+ defaultCase)
val annotated = Annotated(New(ref(defn.UncheckedAnnotType)), paramRef)
cpy.Match(applyRhs)(annotated, cases.map(translateCase) :+ defaultCase)
case _ =>
tru
}
Expand Down
6 changes: 3 additions & 3 deletions src/dotty/tools/dotc/transform/patmat/Space.scala
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
case UnApply(_, _, pats) =>
if (pat.tpe.classSymbol.is(CaseClass))
Kon(pat.tpe.stripAnnots, pats.map(pat => project(pat, roundUp)))
else if (roundUp) Typ(pat.tpe, false)
else if (roundUp) Typ(pat.tpe.stripAnnots, false)
else Empty
case Typed(pat @ UnApply(_, _, _), _) => project(pat)
case Typed(expr, _) => Typ(expr.tpe.stripAnnots, true)
Expand Down Expand Up @@ -392,9 +392,9 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
case _ => tp.show.stripSuffix("$")
}

val text = tp match {
val text = tp.stripAnnots match {
case tp: OrType => showType(tp.tp1) + " | " + showType(tp.tp2)
case _ => refine(tp)
case tp => refine(tp)
}

if (text.isEmpty) enclosingCls.show.stripSuffix("$")
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/typer/TypeAssigner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ trait TypeAssigner {
tree.withType(sym.nonMemberTermRef)

def assignType(tree: untpd.Annotated, annot: Tree, arg: Tree)(implicit ctx: Context) =
tree.withType(AnnotatedType(arg.tpe, Annotation(annot)))
tree.withType(AnnotatedType(arg.tpe.widen, Annotation(annot)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this change, but without it there will be several TreeChecker errors. Could you please advise @smarter ? Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is a good change. It makes val a : 1 = (1 : @annotation) not typecheck as type of 1 will get widened to Int.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment, I'll try remove it and investigate the errors in TreeChecker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This widen corresponds to the widen in the typer:

      val tpt = TypeTree(AnnotatedType(arg1.tpe.widen, Annotation(annot1)))
      assignType(cpy.Typed(tree)(arg1, tpt), tpt)

Disable widening in typer breaks a lot of assumptions elsewhere, for now I think it's OK to just keep this change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I think you should open an issue about this so that we don't forget it at least.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a hunch that this change will disable things like 42.type (SIP 23). If Dotty supports it in the future, we'll need to revisit this change...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


def assignType(tree: untpd.PackageDef, pid: Tree)(implicit ctx: Context) =
tree.withType(pid.symbol.valRef)
Expand Down
3 changes: 2 additions & 1 deletion src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
tree.selector match {
case EmptyTree =>
val (protoFormals, _) = decomposeProtoFunction(pt, 1)
typed(desugar.makeCaseLambda(tree.cases, protoFormals.length) withPos tree.pos, pt)
val unchecked = pt <:< defn.PartialFunctionType
typed(desugar.makeCaseLambda(tree.cases, protoFormals.length, unchecked) withPos tree.pos, pt)
case _ =>
val sel1 = typedExpr(tree.selector)
val selType = widenForMatchSelector(
Expand Down
8 changes: 4 additions & 4 deletions test/test/transform/PatmatExhaustivityTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import dotty.tools.dotc.reporting.ConsoleReporter

class PatmatExhaustivityTest {
val testsDir = "./tests/patmat"
val options = "-Ystop-after:splitter" // no need for code generation
// patmatexhaust-huge.scala crash compiler
// stop-after: patmatexhaust-huge.scala crash compiler
val options = List("-Ystop-after:splitter")

private def compileFile(file: File) = {
val stringBuffer = new StringWriter()
val reporter = new ConsoleReporter(writer = new PrintWriter(stringBuffer))

try {
Main.process(Array(file.getPath, options), reporter, null)
Main.process((file.getPath::options).toArray, reporter, null)
} catch {
case e: Throwable =>
println(s"Compile $file exception:")
Expand All @@ -45,7 +45,7 @@ class PatmatExhaustivityTest {
.map(_.jfile.getPath)

try {
Main.process((options::files).toArray, reporter, null)
Main.process((options ++ files).toArray, reporter, null)
} catch {
case e: Throwable =>
println(s"Compile $file exception:")
Expand Down
5 changes: 5 additions & 0 deletions tests/patmat/for.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Test {
def foo[A, B](l: List[(A, B)]): List[A] = {
for ((a, b) <- l) yield a
}
}
4 changes: 4 additions & 0 deletions tests/patmat/i947.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
./tests/patmat/i947.scala:10: warning: unreachable code
case ys: List[d18383] => false
^
one warning found
16 changes: 16 additions & 0 deletions tests/patmat/i947.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
object Test {

class c {

private var x: Int = 0

override def equals(other: Any) = other match {
case o: c => x == o.x
case xs: List[c] => false
case ys: List[d18383] => false
case _ => false
}


}
}
12 changes: 12 additions & 0 deletions tests/patmat/partial-function.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
sealed abstract class TA
sealed abstract class TB extends TA
case object B extends TB
case object B2 extends TB

case class CC(i: Int, tb: TB)

object Test {
def foo: PartialFunction[CC, Unit] = {
case CC(_, B) => ()
}
}
5 changes: 5 additions & 0 deletions tests/patmat/t1056.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Test {
type T = PartialFunction[String,String]
def g(h: T) = ()
g({case s: String => s})
}
5 changes: 5 additions & 0 deletions tests/patmat/try.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Test {
try 2/0 catch {
case e: Exception =>
}
}