@@ -1386,13 +1386,10 @@ class Namer { typer: Typer =>
13861386 }
13871387 end inherited
13881388
1389- /** The proto-type to be used when inferring the result type from
1390- * the right hand side. This is `WildcardType` except if the definition
1391- * is a default getter. In that case, the proto-type is the type of
1392- * the corresponding parameter where bound parameters are replaced by
1393- * Wildcards.
1389+ /** If this is a default getter, the type of the corresponding method parameter,
1390+ * otherwise NoType.
13941391 */
1395- def rhsProto = sym.asTerm. name collect {
1392+ def defaultParamType = sym.name match
13961393 case DefaultGetterName (original, idx) =>
13971394 val meth : Denotation =
13981395 if (original.isConstructorName && (sym.owner.is(ModuleClass )))
@@ -1401,37 +1398,24 @@ class Namer { typer: Typer =>
14011398 ctx.defContext(sym).denotNamed(original)
14021399 def paramProto (paramss : List [List [Type ]], idx : Int ): Type = paramss match {
14031400 case params :: paramss1 =>
1404- if (idx < params.length) wildApprox( params(idx) )
1401+ if (idx < params.length) params(idx)
14051402 else paramProto(paramss1, idx - params.length)
14061403 case nil =>
1407- WildcardType
1404+ NoType
14081405 }
14091406 val defaultAlts = meth.altsWith(_.hasDefaultParams)
14101407 if (defaultAlts.length == 1 )
14111408 paramProto(defaultAlts.head.info.widen.paramInfoss, idx)
14121409 else
1413- WildcardType
1414- } getOrElse WildcardType
1410+ NoType
1411+ case _ =>
1412+ NoType
14151413
14161414 // println(s"final inherited for $sym: ${inherited.toString}") !!!
14171415 // println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
14181416 // TODO Scala 3.1: only check for inline vals (no final ones)
14191417 def isInlineVal = sym.isOneOf(FinalOrInline , butNot = Method | Mutable )
14201418
1421- // Widen rhs type and eliminate `|' but keep ConstantTypes if
1422- // definition is inline (i.e. final in Scala2) and keep module singleton types
1423- // instead of widening to the underlying module class types.
1424- // We also drop the @Repeated annotation here to avoid leaking it in method result types
1425- // (see run/inferred-repeated-result).
1426- def widenRhs (tp : Type ): Type =
1427- tp.widenTermRefExpr.simplified match
1428- case ctp : ConstantType if isInlineVal => ctp
1429- case tp => TypeComparer .widenInferred(tp, rhsProto)
1430-
1431- // Replace aliases to Unit by Unit itself. If we leave the alias in
1432- // it would be erased to BoxedUnit.
1433- def dealiasIfUnit (tp : Type ) = if (tp.isRef(defn.UnitClass )) defn.UnitType else tp
1434-
14351419 var rhsCtx = ctx.fresh.addMode(Mode .InferringReturnType )
14361420 if sym.isInlineMethod then rhsCtx = rhsCtx.addMode(Mode .InlineableBody )
14371421 if sym.is(ExtensionMethod ) then rhsCtx = rhsCtx.addMode(Mode .InExtensionMethod )
@@ -1443,8 +1427,32 @@ class Namer { typer: Typer =>
14431427 rhsCtx.setFreshGADTBounds
14441428 rhsCtx.gadt.addToConstraint(typeParams)
14451429 }
1446- def rhsType = PrepareInlineable .dropInlineIfError(sym,
1447- typedAheadExpr(mdef.rhs, (inherited orElse rhsProto).widenExpr)(using rhsCtx)).tpe
1430+
1431+ def typedAheadRhs (pt : Type ) =
1432+ PrepareInlineable .dropInlineIfError(sym,
1433+ typedAheadExpr(mdef.rhs, pt)(using rhsCtx))
1434+
1435+ def rhsType =
1436+ // For default getters, we use the corresponding parameter type as an
1437+ // expected type but we run it through `wildApprox` to allow default
1438+ // parameters like in `def mkList[T](value: T = 1): List[T]`.
1439+ val defaultTp = defaultParamType
1440+ val pt = inherited.orElse(wildApprox(defaultTp)).orElse(WildcardType ).widenExpr
1441+ val tp = typedAheadRhs(pt).tpe
1442+ if (defaultTp eq pt) && (tp frozen_<:< defaultTp) then
1443+ // When possible, widen to the default getter parameter type to permit a
1444+ // larger choice of overrides (see `default-getter.scala`).
1445+ // For justification on the use of `@uncheckedVariance`, see
1446+ // `default-getter-variance.scala`.
1447+ AnnotatedType (defaultTp, Annotation (defn.UncheckedVarianceAnnot ))
1448+ else tp.widenTermRefExpr.simplified match
1449+ case ctp : ConstantType if isInlineVal => ctp
1450+ case tp =>
1451+ TypeComparer .widenInferred(tp, pt)
1452+
1453+ // Replace aliases to Unit by Unit itself. If we leave the alias in
1454+ // it would be erased to BoxedUnit.
1455+ def dealiasIfUnit (tp : Type ) = if (tp.isRef(defn.UnitClass )) defn.UnitType else tp
14481456
14491457 // Approximate a type `tp` with a type that does not contain skolem types.
14501458 val deskolemize = new ApproximatingTypeMap {
@@ -1455,7 +1463,7 @@ class Namer { typer: Typer =>
14551463 }
14561464 }
14571465
1458- def cookedRhsType = deskolemize(dealiasIfUnit(widenRhs( rhsType) ))
1466+ def cookedRhsType = deskolemize(dealiasIfUnit(rhsType))
14591467 def lhsType = fullyDefinedType(cookedRhsType, " right-hand side" , mdef.span)
14601468 // if (sym.name.toString == "y") println(i"rhs = $rhsType, cooked = $cookedRhsType")
14611469 if (inherited.exists)
0 commit comments