Skip to content

Commit

Permalink
Merge pull request scala#12513 from dotty-staging/refactor-typed
Browse files Browse the repository at this point in the history
Tighten Ycheck of type ascriptions
  • Loading branch information
abgruszecki authored May 25, 2021
2 parents 2bfa8e2 + 7029ee1 commit 1f4d125
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 8 deletions.
24 changes: 24 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,30 @@ class TreeChecker extends Phase with SymTransformer {
assert(tree.qual.tpe.isInstanceOf[ThisType], i"expect prefix of Super to be This, actual = ${tree.qual}")
super.typedSuper(tree, pt)

override def typedTyped(tree: untpd.Typed, pt: Type)(using Context): Tree =
val tpt1 = checkSimpleKinded(typedType(tree.tpt))
val expr1 = tree.expr match
case id: untpd.Ident if (ctx.mode is Mode.Pattern) && untpd.isVarPattern(id) && (id.name == nme.WILDCARD || id.name == nme.WILDCARD_STAR) =>
tree.expr.withType(tpt1.tpe)
case _ =>
var pt1 = tpt1.tpe
if pt1.isRepeatedParam then
pt1 = pt1.translateFromRepeated(toArray = tree.expr.typeOpt.derivesFrom(defn.ArrayClass))
val isAfterInlining =
val inliningPhase = ctx.base.inliningPhase
inliningPhase.exists && ctx.phase.id > inliningPhase.id
if isAfterInlining then
// The staging phase destroys in PCPCheckAndHeal the property that
// tree.expr.tpe <:< pt1. A test case where this arises is run-macros/enum-nat-macro.
// We should follow up why this happens. If the problem is fixed, we can
// drop the isAfterInlining special case. To reproduce the problem, just
// change the condition from `isAfterInlining` to `false`.
typed(tree.expr)
else
//println(i"typing $tree, ${tree.expr.typeOpt}, $pt1, ${ctx.mode is Mode.Pattern}")
typed(tree.expr, pt1)
untpd.cpy.Typed(tree)(expr1, tpt1).withType(tree.typeOpt)

private def checkOwner(tree: untpd.Tree)(using Context): Unit = {
def ownerMatches(symOwner: Symbol, ctxOwner: Symbol): Boolean =
symOwner == ctxOwner ||
Expand Down
23 changes: 15 additions & 8 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -814,11 +814,9 @@ class Typer extends Namer
val underlyingTreeTpe =
if (isRepeatedParamType(tpt)) TypeTree(defn.SeqType.appliedTo(pt :: Nil))
else tpt

val expr1 =
if (isRepeatedParamType(tpt)) tree.expr.withType(defn.SeqType.appliedTo(pt :: Nil))
else if (isWildcard) tree.expr.withType(tpt.tpe)
else typed(tree.expr, tpt.tpe.widenSkolem)
if isWildcard then tree.expr.withType(underlyingTreeTpe.tpe)
else typed(tree.expr, underlyingTreeTpe.tpe.widenSkolem)
assignType(cpy.Typed(tree)(expr1, tpt), underlyingTreeTpe)
.withNotNullInfo(expr1.notNullInfo)
}
Expand All @@ -844,8 +842,10 @@ class Typer extends Namer
// We need to make sure its type is no longer nullable
expr0.castToNonNullable
else expr0
val fromCls = if expr1.tpe.derivesFrom(defn.ArrayClass)
then defn.ArrayClass else defn.SeqClass
val fromCls =
if expr1.tpe.derivesFrom(defn.ArrayClass)
then defn.ArrayClass
else defn.SeqClass
val tpt1 = TypeTree(expr1.tpe.widen.translateToRepeated(fromCls)).withSpan(tree.tpt.span)
assignType(cpy.Typed(tree)(expr1, tpt1), tpt1)
}
Expand Down Expand Up @@ -1055,7 +1055,14 @@ class Typer extends Namer
val expr1 = ascribeType(expr, pt)
cpy.Block(block)(stats, expr1) withType expr1.tpe // no assignType here because avoid is redundant
case _ =>
Typed(tree, TypeTree(pt.simplified))
val target = pt.simplified
if tree.tpe <:< target then Typed(tree, TypeTree(pt.simplified))
else
// This case should not normally arise. It currently does arise in test cases
// pos/t4080b.scala and pos/i7067.scala. In that case, a type ascription is wrong
// and would not pass Ycheck. We have to use a cast instead. TODO: follow-up why
// the cases arise and eliminate them, if possible.
tree.cast(target)
}
def noLeaks(t: Tree): Boolean = escapingRefs(t, localSyms).isEmpty
if (noLeaks(tree)) tree
Expand Down Expand Up @@ -3693,7 +3700,7 @@ class Typer extends Namer
gadts.println(i"GADT-approximated $wtp ~~ $gadtApprox")
if pt.isMatchedBy(gadtApprox) then
gadts.println(i"Member selection healed by GADT approximation")
tpd.Typed(tree, TypeTree(gadtApprox))
tree.cast(gadtApprox)
else tree
else tree // other adaptations for selections are handled in typedSelect
case _ if ctx.mode.is(Mode.ImplicitsEnabled) && tree.tpe.isValueType =>
Expand Down
3 changes: 3 additions & 0 deletions compiler/test/dotc/pos-from-tasty.blacklist
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ rbtree.scala

# transitive reduction of match types
i10511.scala

# Violates tightened condition in Retyper#typedTyped
i11247.scala

0 comments on commit 1f4d125

Please sign in to comment.