diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index d96b37dd3c55..43a2cc9d0b32 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -1168,7 +1168,7 @@ object RefChecks { def explicit = Applications.stripImplicit(tp.stripPoly, wildcardOnly = true) def hasImplicitParams = tp.stripPoly match { case mt: MethodType => mt.isImplicitMethod case _ => false } val explicitInfo = sym.info.explicit // consider explicit value params - val target = explicitInfo.firstParamTypes.head // required for extension method, the putative receiver + val target = explicitInfo.firstParamTypes.head.typeSymbol.info // required for extension method, the putative receiver val methTp = explicitInfo.resultType // skip leading implicits and the "receiver" parameter def hidden = target.nonPrivateMember(sym.name) @@ -1197,7 +1197,7 @@ object RefChecks { sym.owner.info.member(getterName) if getterDenot.exists then report.warning(ExtensionHasDefault(sym), getterDenot.symbol.srcPos) - if !target.typeSymbol.isOpaqueAlias && !sym.nextOverriddenSymbol.exists && hidden + if !sym.nextOverriddenSymbol.exists && hidden then report.warning(ExtensionNullifiedByMember(sym, target.typeSymbol), sym.srcPos) end checkExtensionMethods diff --git a/tests/warn/i22232.check b/tests/warn/i22232.check new file mode 100644 index 000000000000..cf3d6d4e004e --- /dev/null +++ b/tests/warn/i22232.check @@ -0,0 +1,28 @@ +-- [E194] Potential Issue Warning: tests/warn/i22232.scala:3:23 -------------------------------------------------------- +3 | extension (c: C) def equals(that: Any): Boolean = false // warn + | ^ + | Extension method equals will never be selected from type C + | because C already has a member with the same name and compatible parameter types. + | + | longer explanation available when compiling with `-explain` +-- [E194] Potential Issue Warning: tests/warn/i22232.scala:9:25 -------------------------------------------------------- +9 | extension (d: D) def equals(that: Any): Boolean = false // warn + | ^ + | Extension method equals will never be selected from type C + | because C already has a member with the same name and compatible parameter types. + | + | longer explanation available when compiling with `-explain` +-- [E194] Potential Issue Warning: tests/warn/i22232.scala:13:38 ------------------------------------------------------- +13 | extension (arr: MyString[Byte]) def length: Int = 0 // warn + | ^ + | Extension method length will never be selected from type String + | because String already has a member with the same name and compatible parameter types. + | + | longer explanation available when compiling with `-explain` +-- [E194] Potential Issue Warning: tests/warn/i22232.scala:17:46 ------------------------------------------------------- +17 | extension [T <: MyString[Byte]](arr: T) def length: Int = 0 // warn + | ^ + | Extension method length will never be selected from type String + | because String already has a member with the same name and compatible parameter types. + | + | longer explanation available when compiling with `-explain` diff --git a/tests/warn/i22232.scala b/tests/warn/i22232.scala new file mode 100644 index 000000000000..79b8317a7329 --- /dev/null +++ b/tests/warn/i22232.scala @@ -0,0 +1,32 @@ +class C +object C: + extension (c: C) def equals(that: Any): Boolean = false // warn + +object X: + class C + opaque type D <: C = C + object D: + extension (d: D) def equals(that: Any): Boolean = false // warn + +object Upperbound1: + opaque type MyString[+T] <: String = String + extension (arr: MyString[Byte]) def length: Int = 0 // warn + +object Upperbound2: + opaque type MyString[+T] <: String = String + extension [T <: MyString[Byte]](arr: T) def length: Int = 0 // warn + +object Upperbound3: + opaque type MyString[+T] <: String = String + extension [T](arr: T) def length: Int = 0 // nowarn + +object NonUpperbound1: + opaque type MyString[+T] = String + extension (arr: MyString[Byte]) def length: Int = 0 // nowarn +object NonUpperbound2: + opaque type MyString[+T] = String + extension [T <: MyString[Byte]](arr: T) def length2: Int = 0 // nowarn + +object NonUpperbound3: + opaque type MyString[+T] = String + extension [T](arr: T) def length: Int = 0 // nowarn