diff options
author | Martin Odersky <odersky@gmail.com> | 2014-03-01 18:27:02 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-03-01 18:27:02 +0100 |
commit | b9e576ad1ba0ff02c550c821648f23905477e545 (patch) | |
tree | 5d8116af63cb38a52861941058a1eea62057e8d4 /src/dotty/tools/dotc/typer/Inferencing.scala | |
parent | 340ca0615bc40ca0232143b1d7e206c56e721c5c (diff) | |
download | dotty-b9e576ad1ba0ff02c550c821648f23905477e545.tar.gz dotty-b9e576ad1ba0ff02c550c821648f23905477e545.tar.bz2 dotty-b9e576ad1ba0ff02c550c821648f23905477e545.zip |
Check that inferred parent classes are feasible.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Inferencing.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 680096d38..ea3109afa 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -468,6 +468,7 @@ object Inferencing { case p :: _ if p.classSymbol.isRealClass => parents case _ => val pcls = (defn.ObjectClass /: parents)(improve) + typr.println(i"ensure first is class $parents%, % --> ${parents map (_ baseTypeWithArgs pcls)}%, %") val ptype = ctx.typeComparer.glb( defn.ObjectType :: (parents map (_ baseTypeWithArgs pcls))) ptype :: parents @@ -479,9 +480,22 @@ object Inferencing { case p :: ps if p.tpe.classSymbol.isRealClass => parents case _ => // add synthetic class type - val parentTypes = ensureFirstIsClass(parents.tpes) - assert(parentTypes.length > parents.length) - (TypeTree(parentTypes.head) withPos pos) :: parents + val first :: _ = ensureFirstIsClass(parents.tpes) + TypeTree(checkFeasible(first, pos, i"\n in inferred parent $first")).withPos(pos) :: parents + } + + /** Check that any top-level type arguments in this type are feasible, i.e. that + * their lower bound conforms to their upper cound. If a type argument is + * infeasible, issue and error and continue with upper bound. + */ + def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp match { + case tp: RefinedType => + tp.derivedRefinedType(tp.parent, tp.refinedName, checkFeasible(tp.refinedInfo, pos, where)) + case tp @ TypeBounds(lo, hi) if !(lo <:< hi) => + ctx.error(i"no type exists between low bound $lo and high bound $hi$where", pos) + tp.derivedTypeAlias(hi) + case _ => + tp } /** Check that class does not define */ |