aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2016-01-18 19:05:48 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-01-18 19:05:48 +0100
commit1aa8fbb56e95d7aea04b338d3edf7d53077b804a (patch)
treea49dfa96f7e99c0b18bc5053b823b141ed2ded96 /src/dotty/tools/dotc/typer
parentdd733181fd943f5074af57b151da95df7c999fc9 (diff)
parent224232df2affa882c2c41fc8a6730ad7fc049679 (diff)
downloaddotty-1aa8fbb56e95d7aea04b338d3edf7d53077b804a.tar.gz
dotty-1aa8fbb56e95d7aea04b338d3edf7d53077b804a.tar.bz2
dotty-1aa8fbb56e95d7aea04b338d3edf7d53077b804a.zip
Merge pull request #1014 from dotty-staging/fix/deep-subtypes
Check all bounds and avoid infinite subtyping checks when intersecting denotations
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala1
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala15
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala17
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala3
4 files changed, 32 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index b3cda20b8..649b8088f 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -607,7 +607,6 @@ trait Applications extends Compatibility { self: Typer =>
case pt: PolyType =>
if (typedArgs.length <= pt.paramBounds.length)
typedArgs = typedArgs.zipWithConserve(pt.paramBounds)(adaptTypeArg)
- Checking.checkBounds(typedArgs, pt)
case _ =>
}
assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs)
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 6ded7c109..0b4787d15 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -48,6 +48,21 @@ object Checking {
def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
checkBounds(args, poly.paramBounds, _.substParams(poly, _))
+ /** Check all AppliedTypeTree nodes in this tree for legal bounds */
+ val boundsChecker = new TreeTraverser {
+ def traverse(tree: Tree)(implicit ctx: Context) = {
+ tree match {
+ case AppliedTypeTree(tycon, args) =>
+ val tparams = tycon.tpe.typeSymbol.typeParams
+ val bounds = tparams.map(tparam =>
+ tparam.info.asSeenFrom(tycon.tpe.normalizedPrefix, tparam.owner.owner).bounds)
+ checkBounds(args, bounds, _.substDealias(tparams, _))
+ case _ =>
+ }
+ traverseChildren(tree)
+ }
+ }
+
/** Check that `tp` refers to a nonAbstract class
* and that the instance conforms to the self type of the created class.
*/
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 406e7378f..ecbec7d07 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -869,7 +869,9 @@ class Namer { typer: Typer =>
if (tparamSyms.nonEmpty && !isDerived) tp.LambdaAbstract(tparamSyms)
//else if (toParameterize) tp.parameterizeWith(tparamSyms)
else tp
- sym.info = abstracted(TypeBounds.empty)
+
+ val dummyInfo = abstracted(TypeBounds.empty)
+ sym.info = dummyInfo
// Temporarily set info of defined type T to ` >: Nothing <: Any.
// This is done to avoid cyclic reference errors for F-bounds.
// This is subtle: `sym` has now an empty TypeBounds, but is not automatically
@@ -890,6 +892,19 @@ class Namer { typer: Typer =>
sym.info = NoCompleter
sym.info = checkNonCyclic(sym, unsafeInfo, reportErrors = true)
}
+
+ // Here we pay the price for the cavalier setting info to TypeBounds.empty above.
+ // We need to compensate by invalidating caches in references that might
+ // still contain the TypeBounds.empty. If we do not do this, stdlib factories
+ // fail with a bounds error in PostTyper.
+ def ensureUpToDate(tp: Type, outdated: Type) = tp match {
+ case tref: TypeRef if tref.info == outdated && sym.info != outdated =>
+ tref.uncheckedSetSym(null)
+ case _ =>
+ }
+ ensureUpToDate(sym.typeRef, dummyInfo)
+ ensureUpToDate(sym.typeRef.appliedTo(tparamSyms.map(_.typeRef)), TypeBounds.empty)
+
etaExpandArgs.apply(sym.info)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 511a12ea7..008eab0fd 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -961,8 +961,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val TypeDef(name, rhs) = tdef
checkLowerNotHK(sym, tdef.tparams.map(symbolOfTree), tdef.pos)
completeAnnotations(tdef, sym)
- val _ = typedType(rhs) // unused, typecheck only to remove from typedTree
- assignType(cpy.TypeDef(tdef)(name, TypeTree(sym.info), Nil), sym)
+ assignType(cpy.TypeDef(tdef)(name, typedType(rhs), Nil), sym)
}
def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = track("typedClassDef") {