File tree Expand file tree Collapse file tree 3 files changed +29
-7
lines changed
compiler/src/dotty/tools/dotc Expand file tree Collapse file tree 3 files changed +29
-7
lines changed Original file line number Diff line number Diff line change @@ -3713,8 +3713,19 @@ object Types {
37133713 tp match {
37143714 case tp : NamedType =>
37153715 if (stopAtStatic && tp.symbol.isStatic) tp
3716- else derivedSelect(tp, this (tp.prefix))
3717-
3716+ else {
3717+ val saved = variance
3718+ variance = variance max 0
3719+ // A prefix is never contravariant. Even if say `p.A` is used in a contravariant
3720+ // context, we cannot assume contravariance for `p` because `p`'s lower
3721+ // bound might not have a binding for `A` (e.g. the lower bound could be `Nothing`).
3722+ // By contrast, covariance does translate to the prefix, since we have that
3723+ // if `p <: q` then `p.A <: q.A`, and well-formedness requires that `A` is a member
3724+ // of `p`'s upper bound.
3725+ val prefix1 = this (tp.prefix)
3726+ variance = saved
3727+ derivedSelect(tp, prefix1)
3728+ }
37183729 case _ : ThisType
37193730 | _ : BoundType
37203731 | NoPrefix => tp
@@ -3913,9 +3924,9 @@ object Types {
39133924
39143925 protected var variance = 1
39153926
3916- protected def applyToPrefix (x : T , tp : NamedType ) = {
3927+ protected final def applyToPrefix (x : T , tp : NamedType ) = {
39173928 val saved = variance
3918- variance = 0
3929+ variance = variance max 0 // see remark on NamedType case in TypeMap
39193930 val result = this (x, tp.prefix)
39203931 variance = saved
39213932 result
Original file line number Diff line number Diff line change @@ -319,8 +319,6 @@ object Inferencing {
319319 case _ =>
320320 foldOver(vmap, t)
321321 }
322- override def applyToPrefix (vmap : VarianceMap , t : NamedType ) =
323- apply(vmap, t.prefix)
324322 }
325323
326324 /** Include in `vmap` type variables occurring in the constraints of type variables
Original file line number Diff line number Diff line change @@ -268,7 +268,20 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
268268 if (qualifies(defDenot)) {
269269 val found =
270270 if (isSelfDenot(defDenot)) curOwner.enclosingClass.thisType
271- else curOwner.thisType.select(name, defDenot)
271+ else {
272+ val effectiveOwner =
273+ if (curOwner.isTerm && defDenot.symbol.isType)
274+ // Don't mix NoPrefix and thisType prefixes, since type comparer
275+ // would not detect types to be compatible. Note: If we replace the
276+ // 2nd condition by `defDenot.symbol.maybeOwner.isType` we get lots
277+ // of failures in the `tastyBootstrap` test. Trying to compile these
278+ // files in isolation works though.
279+ // TODO: Investigate why that happens.
280+ defDenot.symbol.owner
281+ else
282+ curOwner
283+ effectiveOwner.thisType.select(name, defDenot)
284+ }
272285 if (! (curOwner is Package ) || isDefinedInCurrentUnit(defDenot))
273286 result = checkNewOrShadowed(found, definition) // no need to go further out, we found highest prec entry
274287 else {
You can’t perform that action at this time.
0 commit comments