diff options
author | Abel Nieto <abeln@google.com> | 2017-03-17 16:27:36 -0400 |
---|---|---|
committer | Abel Nieto <abeln@google.com> | 2017-03-17 17:44:00 -0400 |
commit | 3920414761daf37106ff94ae75b87eb822d9430f (patch) | |
tree | 561efd3e8718604bcef72431f636b63d174a055a /compiler | |
parent | d0621108bad55f9fc66c1c5ade9a0b7edb3117e7 (diff) | |
download | dotty-3920414761daf37106ff94ae75b87eb822d9430f.tar.gz dotty-3920414761daf37106ff94ae75b87eb822d9430f.tar.bz2 dotty-3920414761daf37106ff94ae75b87eb822d9430f.zip |
Fix bug in typechecking super prefix with invalid enclosing class
When typechecking
class A {
C.super.foo()
}
If C isn't an enclosing class, the compiler was throwing because of an
unguarded pattern match.
Fix the issue by checking for ErrorType.
Tested:
Verified that the example above no longer throws.
Added a test.
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 3d20583f4..6d0fc08f9 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -291,26 +291,28 @@ trait TypeAssigner { def assignType(tree: untpd.Super, qual: Tree, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context) = { val mix = tree.mix - val qtype @ ThisType(_) = qual.tpe - val cls = qtype.cls - - def findMixinSuper(site: Type): Type = site.parents filter (_.name == mix.name) match { - case p :: Nil => - p - case Nil => - errorType(SuperQualMustBeParent(mix, cls), tree.pos) - case p :: q :: _ => - errorType("ambiguous parent class qualifier", tree.pos) + qual.tpe match { + case err: ErrorType => untpd.cpy.Super(tree)(qual, mix).withType(err) + case qtype @ ThisType(_) => + val cls = qtype.cls + def findMixinSuper(site: Type): Type = site.parents filter (_.name == mix.name) match { + case p :: Nil => + p + case Nil => + errorType(SuperQualMustBeParent(mix, cls), tree.pos) + case p :: q :: _ => + errorType("ambiguous parent class qualifier", tree.pos) + } + val owntype = + if (mixinClass.exists) mixinClass.typeRef + else if (!mix.isEmpty) findMixinSuper(cls.info) + else if (inConstrCall || ctx.erasedTypes) cls.info.firstParent + else { + val ps = cls.classInfo.parentsWithArgs + if (ps.isEmpty) defn.AnyType else ps.reduceLeft((x: Type, y: Type) => x & y) + } + tree.withType(SuperType(cls.thisType, owntype)) } - val owntype = - if (mixinClass.exists) mixinClass.typeRef - else if (!mix.isEmpty) findMixinSuper(cls.info) - else if (inConstrCall || ctx.erasedTypes) cls.info.firstParent - else { - val ps = cls.classInfo.parentsWithArgs - if (ps.isEmpty) defn.AnyType else ps.reduceLeft((x: Type, y: Type) => x & y) - } - tree.withType(SuperType(cls.thisType, owntype)) } def assignType(tree: untpd.Apply, fn: Tree, args: List[Tree])(implicit ctx: Context) = { |