Skip to content

Commit b75cafd

Browse files
som-snytttgodzik
authored andcommitted
Check extension method at typer
[Cherry-picked a71b76c]
1 parent dc13b7d commit b75cafd

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,8 +1058,8 @@ object RefChecks {
10581058
* This check is suppressed if the method is an override. (Because the type of the receiver
10591059
* may be narrower in the override.)
10601060
*
1061-
* If the extension method is nilary, it is always hidden by a member of the same name.
1062-
* (Either the member is nilary, or the reference is taken as the eta-expansion of the member.)
1061+
* If the extension method is parameterless, it is always hidden by a member of the same name.
1062+
* (Either the member is parameterless, or the reference is taken as the eta-expansion of the member.)
10631063
*
10641064
* This check is in lieu of a more expensive use-site check that an application failed to use an extension.
10651065
* That check would account for accessibility and opacity. As a limitation, this check considers
@@ -1079,15 +1079,15 @@ object RefChecks {
10791079
* parameters of the extension method must be distinguishable from the member parameters, as described above.
10801080
*/
10811081
def checkExtensionMethods(sym: Symbol)(using Context): Unit =
1082-
if sym.is(Extension) then
1082+
if sym.is(Extension) then atPhase(typerPhase):
10831083
extension (tp: Type)
10841084
def explicit = Applications.stripImplicit(tp.stripPoly, wildcardOnly = true)
10851085
def hasImplicitParams = tp.stripPoly match { case mt: MethodType => mt.isImplicitMethod case _ => false }
1086-
def isNilary = tp.stripPoly match { case mt: MethodType => false case _ => true }
1086+
def isParamLess = tp.stripPoly match { case mt: MethodType => false case _ => true }
10871087
val explicitInfo = sym.info.explicit // consider explicit value params
10881088
def memberHidesMethod(member: Denotation): Boolean =
10891089
val methTp = explicitInfo.resultType // skip leading implicits and the "receiver" parameter
1090-
if methTp.isNilary then
1090+
if methTp.isParamLess then
10911091
return true // extension without parens is always hidden by a member of same name
10921092
val memberIsImplicit = member.info.hasImplicitParams
10931093
inline def paramsCorrespond =
@@ -1096,7 +1096,8 @@ object RefChecks {
10961096
else methTp.explicit.firstParamTypes
10971097
val memberParamTps = member.info.stripPoly.firstParamTypes
10981098
memberParamTps.corresponds(paramTps): (m, x) =>
1099-
m.typeSymbol.denot.isOpaqueAlias == x.typeSymbol.denot.isOpaqueAlias && (x frozen_<:< m)
1099+
m.typeSymbol.denot.isOpaqueAlias == x.typeSymbol.denot.isOpaqueAlias
1100+
&& (x frozen_<:< m)
11001101
memberIsImplicit && !methTp.hasImplicitParams || paramsCorrespond
11011102
def targetOfHiddenExtension: Symbol =
11021103
val target =

tests/warn/i16743.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ object Depending:
9393
def f(using d: Depends) = d.thing.y
9494
def g(using d: Depends) = d.thing.length()
9595

96+
class i24198:
97+
def m(ss: String*) = ss.foldLeft("")(_ + _)
98+
object i24198:
99+
extension (r: i24198) def m(ss: Seq[String]) = ss.foldRight("!")(_ + _)
100+
96101
@main def test() =
97102
val x = new T {}
98103
println(x.f(42)) // OK!
@@ -119,3 +124,6 @@ object Depending:
119124
given String = "42"
120125
x.w("27")
121126
}
127+
println:
128+
val sut = i24198()
129+
sut.m(List("hello", ", ", "world"))

0 commit comments

Comments
 (0)