summaryrefslogtreecommitdiff
path: root/test/files/pos/t5294c.scala
Commit message (Collapse)AuthorAgeFilesLines
* SI-5294 Use bounds of abstract prefix in asSeenFromJason Zaugg2016-08-231-0/+30
ASF was failing to recognize the correspondence between a prefix if it has an abstract type symbol, even if it is bounded by the currently considered class. Distilling the test cases, this led to incorrect typechecking of the RHS of `G` in: ``` trait T { type A trait HasH { type H[U] <: U } type F[N <: HasH] = N#H[T] type G[N <: HasH] = F[N]#A // RHS was incorrectly reduced to T.this.A } ``` In the fuller examples (included as test cases), this meant that type level functions written as members of `HList` could not be implemented in terms of each other, e.g. defining `Apply[N]` as `Drop[N]#Head` had the wrong semantics. This commit checks checks if the prefix has the candidate class as a base type, rather than checking if its type symbol has this as a base class. The latter formulation discarded information about the instantation of the abstract type. Using the example above: ``` scala> val F = typeOf[T].member(TypeName("F")).info F: $r.intp.global.Type = [N <: T.this.HasH]N#H[T] scala> F.resultType.typeSymbol.baseClasses // old approach res14: List[$r.intp.global.Symbol] = List(class Any) scala> F.resultType.baseClasses // new approach res13: List[$r.intp.global.Symbol] = List(trait T, class Object, class Any) ``` It is worth noting that dotty rejects some of these programs, as it introduces the rule that: > // A type T is a legal prefix in a type selection T#A if > // T is stable or T contains no abstract types except possibly A. > final def isLegalPrefixFor(selector: Name)(implicit ctx: Context) However, typechecking the program above in this comment in dotty yields: <trait> trait T() extends Object { type A <trait> trait HasH() extends Object { type H <: [HK$0] => <: HK$0 } type F = [HK$0] => HK$0#H{HK$0 = T}#Apply type G = [HK$0] => HK$0#H{HK$0 = T}#Apply#A } As the equivalent code [1] in dotc's `asSeenFrom` already looks for a base type of the prefix, rather than looking for a superclass of the prefix's type symbol. [1] https://github.com/lampepfl/dotty/blob/d2c96d02fccef3a82b88ee1ff31253b6ef17f900/src/dotty/tools/dotc/core/TypeOps.scala#L62