@@ -3564,39 +3564,55 @@ object Types {
35643564 pt => List .fill(n)(TypeBounds .empty), pt => defn.AnyType )
35653565
35663566 override def fromParams [PI <: ParamInfo .Of [TypeName ]](params : List [PI ], resultType : Type )(implicit ctx : Context ): Type =
3567- fromParams(params, resultType, useVariances = resultType.isInstanceOf [TypeBounds ])
3567+ resultType match
3568+ case bounds : TypeBounds => boundsFromParams(params, bounds)
3569+ case _ => super .fromParams(params, resultType)
35683570
35693571 /** Distributes Lambda inside type bounds. Examples:
35703572 *
35713573 * type T[X] = U becomes type T = [X] -> U
35723574 * type T[X] <: U becomes type T >: Nothing <: ([X] -> U)
35733575 * type T[X] >: L <: U becomes type T >: ([X] -> L) <: ([X] -> U)
35743576 *
3575- * @param useVariances If true, set parameter variances of the type lambda to be as in `params`,
3576- * If false, TypeBounds types and match aliases aways get their variances set
3577- * and type aliases get variances set if some parameter is not invariant,
3578- * but variances of parameters of other types are determined structurally,
3579- * by looking how the parameter is used in the result type.
3577+ * The variances of regular TypeBounds types, as well as of match aliases
3578+ * and of opaque aliases are always determined from the given parameters
3579+ * `params`. The variances of other type aliases are determined from
3580+ * the given parameters only if one of these parameters carries a `+`
3581+ * or `-` variance annotation. Type aliases without variance annotation
3582+ * are treated structurally. That is, their parameter variances are
3583+ * determined by how the parameter(s) appear in the result type.
3584+ *
3585+ * Examples:
3586+ *
3587+ * type T[X] >: A // X is invariant
3588+ * type T[X] <: List[X] // X is invariant
3589+ * type T[X] = List[X] // X is covariant (determined structurally)
3590+ * opaque type T[X] = List[X] // X is invariant
3591+ * opaque type T[+X] = List[X] // X is covariant
3592+ * type T[A, B] = A => B // A is contravariant, B is covariant (determined structurally)
3593+ * type T[A, +B] = A => B // A is invariant, B is covariant
35803594 */
3581- def fromParams [PI <: ParamInfo .Of [TypeName ]](params : List [PI ], resultType : Type , useVariances : Boolean )(implicit ctx : Context ): Type = {
3595+ def boundsFromParams [PI <: ParamInfo .Of [TypeName ]](params : List [PI ], bounds : TypeBounds )(implicit ctx : Context ): TypeBounds = {
35823596 def expand (tp : Type , useVariances : Boolean ) =
35833597 if params.nonEmpty && useVariances then
35843598 apply(params.map(_.paramName), params.map(_.paramVariance))(
35853599 tl => params.map(param => toPInfo(tl.integrate(params, param.paramInfo))),
35863600 tl => tl.integrate(params, tp))
35873601 else
35883602 super .fromParams(params, tp)
3589- resultType match {
3590- case rt : MatchAlias =>
3591- rt.derivedAlias(expand(rt.alias, true ))
3592- case rt : TypeAlias =>
3593- rt.derivedAlias(expand(rt.alias, params.exists(! _.paramVariance.isEmpty)))
3594- case rt @ TypeBounds (lo, hi) =>
3595- rt.derivedTypeBounds(
3596- if (lo.isRef(defn.NothingClass )) lo else expand(lo, true ),
3603+ def isOpaqueAlias = params match
3604+ case (param : Symbol ) :: _ => param.owner.is(Opaque )
3605+ case _ => false
3606+ bounds match {
3607+ case bounds : MatchAlias =>
3608+ bounds.derivedAlias(expand(bounds.alias, true ))
3609+ case bounds : TypeAlias =>
3610+ bounds.derivedAlias(expand(bounds.alias,
3611+ isOpaqueAlias | params.exists(! _.paramVariance.isEmpty)))
3612+ case TypeBounds (lo, hi) =>
3613+ bounds.derivedTypeBounds(
3614+ if lo.isRef(defn.NothingClass ) then lo else expand(lo, true ),
35973615 expand(hi, true ))
3598- case rt =>
3599- expand(rt, useVariances)
36003616 }
36013617 }
36023618 }
0 commit comments