Skip to content

Commit

Permalink
Mark AppliedType cachedSuper valid Nowhere when using provisional args (
Browse files Browse the repository at this point in the history
#20527)

It solves some stale caching issues with `AppliedType#superType` encountered in `neg/typeclass-encoding3` and when introducing more caching for match types in #20268.
These were caused by the fact that `appliedTo` may perform eta-reduction leading to different variance annotations depending on the instantiation of type params.

There seems to be no significant performance impact from the reduced opportunities for caching.
  • Loading branch information
EugeneFlesselle authored Jun 7, 2024
2 parents 27a3f80 + 81a1184 commit 04ada79
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
10 changes: 8 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4650,7 +4650,13 @@ object Types extends TypeUtils {
cachedSuper = tycon match
case tycon: HKTypeLambda => defn.AnyType
case tycon: TypeRef if tycon.symbol.isClass => tycon
case tycon: TypeProxy => tycon.superType.applyIfParameterized(args)
case tycon: TypeProxy =>
if validSuper != Nowhere && args.exists(_.isProvisional) then
// applyIfParameterized may perform eta-reduction leading to different
// variance annotations depending on the instantiation of type params
// see tests/pos/typeclass-encoding3b.scala:348 for an example
validSuper = Nowhere
tycon.superType.applyIfParameterized(args)
case _ => defn.AnyType
cachedSuper

Expand Down Expand Up @@ -4678,8 +4684,8 @@ object Types extends TypeUtils {
*/
override def underlyingMatchType(using Context): Type =
if ctx.period != validUnderlyingMatch then
validUnderlyingMatch = if tycon.isProvisional then Nowhere else ctx.period
cachedUnderlyingMatch = superType.underlyingMatchType
validUnderlyingMatch = validSuper
cachedUnderlyingMatch

override def tryNormalize(using Context): Type = tycon.stripTypeVar match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,5 +345,12 @@ object functors {
}

MonadFlatten.flattened(List(List(1, 2, 3), List(4, 5))) // ok, synthesizes (using ListMonad)
MonadFlatten.flattened(List(List(1, 2, 3), List(4, 5)))(using ListMonad) // error
MonadFlatten.flattened(List(List(1, 2, 3), List(4, 5)))(using ListMonad) // was an error
/*
Before the changes, when checking `ListMonad <:< functors.Monad.Impl[T]`
we eventually got to the comparison `[X] =>> T[X] <:< [+X] =>> List[X]`
because the `This` type member of `ListMonad` has a covariance annotation.
This failed the variance conformance checks despite the fact that T had been instantiated to List,
since it had been substituted into the refinement (and cached) before its instantiation.
*/
}

0 comments on commit 04ada79

Please sign in to comment.