@@ -1158,26 +1158,36 @@ object RefChecks {
11581158 */
11591159 def checkExtensionMethods (sym : Symbol )(using Context ): Unit =
11601160 if sym.is(Extension ) then atPhase(typerPhase):
1161- extension (tp : Type ) def explicit = Applications .stripImplicit(tp.widen, wildcardOnly = false )
1161+ extension (tp : Type )
1162+ def explicit = Applications .stripImplicit(tp.widen, wildcardOnly = false )
1163+ def hiBoundOpaque =
1164+ if tp.typeSymbol.isOpaqueAlias then
1165+ tp.typeSymbol.info match
1166+ case TypeBounds (lo, hi) if lo ne hi => hi
1167+ case _ => tp
1168+ else tp.hiBound
11621169 val explicitInfo = sym.info.explicit // consider explicit value params
11631170 def memberHidesMethod (member : Denotation ): Boolean =
11641171 val methTp = explicitInfo.stripPoly.resultType // skip leading implicits and the "receiver" parameter
11651172 val memberIsImplicit = member.info.isImplicitMethod
1166- inline def paramsCorrespond =
1173+ // are the params of the extension subsumed by the params of the member?
1174+ // an unbounded type param always subsumes.
1175+ // the params must have the same opacity to conclude the extension is hidden.
1176+ inline def paramsCorrespond = {
11671177 val paramTps =
1168- if memberIsImplicit then methTp.stripPoly. firstParamTypes
1178+ if memberIsImplicit then methTp.firstParamTypes
11691179 else methTp.explicit.firstParamTypes
1170- val memberParamTps = member.info.stripPoly. firstParamTypes
1180+ val memberParamTps = member.info.firstParamTypes
11711181 memberParamTps.corresponds(paramTps): (m, x) =>
11721182 m.typeSymbol.denot.isOpaqueAlias == x.typeSymbol.denot.isOpaqueAlias
1173- && (x frozen_<:< m)
1174-
1183+ && (m. isInstanceOf [ ParamRef ] && (m eq m.hiBound) || (x.hiBound frozen_<:< m.hiBound) )
1184+ }
11751185 methTp.isParameterless // extension without parens is always hidden by a member of same name
11761186 || memberIsImplicit && ! methTp.isImplicitMethod // see above
11771187 || paramsCorrespond // match by type and opacity
11781188 def targetOfHiddenExtension : Symbol =
11791189 val target = explicitInfo.firstParamTypes.head // required for extension method; the nominal receiver
1180- .typeSymbol.typeRef.dealiasKeepOpaques
1190+ .hiBound. typeSymbol.typeRef.dealiasKeepOpaques.hiBoundOpaque
11811191 val member = target.nonPrivateMember(sym.name)
11821192 .filterWithPredicate: member =>
11831193 member.symbol.isPublic && memberHidesMethod(member)
0 commit comments