Skip to content

Commit 80e19f6

Browse files
committed
Warn universal extensions on opaque types
1 parent 4dc4668 commit 80e19f6

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,7 @@ object RefChecks {
11681168
def explicit = Applications.stripImplicit(tp.stripPoly, wildcardOnly = true)
11691169
def hasImplicitParams = tp.stripPoly match { case mt: MethodType => mt.isImplicitMethod case _ => false }
11701170
val explicitInfo = sym.info.explicit // consider explicit value params
1171-
val target = explicitInfo.firstParamTypes.head // required for extension method, the putative receiver
1171+
val target = explicitInfo.firstParamTypes.head.typeSymbol.info // required for extension method, the putative receiver
11721172
val methTp = explicitInfo.resultType // skip leading implicits and the "receiver" parameter
11731173
def hidden =
11741174
target.nonPrivateMember(sym.name)
@@ -1197,7 +1197,7 @@ object RefChecks {
11971197
sym.owner.info.member(getterName)
11981198
if getterDenot.exists
11991199
then report.warning(ExtensionHasDefault(sym), getterDenot.symbol.srcPos)
1200-
if !target.typeSymbol.isOpaqueAlias && !sym.nextOverriddenSymbol.exists && hidden
1200+
if !sym.nextOverriddenSymbol.exists && hidden
12011201
then report.warning(ExtensionNullifiedByMember(sym, target.typeSymbol), sym.srcPos)
12021202
end checkExtensionMethods
12031203

tests/warn/i22232.check

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-- [E194] Potential Issue Warning: tests/warn/i22232.scala:3:23 --------------------------------------------------------
2+
3 | extension (c: C) def equals(that: Any): Boolean = false // warn
3+
| ^
4+
| Extension method equals will never be selected from type C
5+
| because C already has a member with the same name and compatible parameter types.
6+
|
7+
| longer explanation available when compiling with `-explain`
8+
-- [E194] Potential Issue Warning: tests/warn/i22232.scala:9:25 --------------------------------------------------------
9+
9 | extension (d: D) def equals(that: Any): Boolean = false // warn
10+
| ^
11+
| Extension method equals will never be selected from type C
12+
| because C already has a member with the same name and compatible parameter types.
13+
|
14+
| longer explanation available when compiling with `-explain`
15+
-- [E194] Potential Issue Warning: tests/warn/i22232.scala:13:38 -------------------------------------------------------
16+
13 | extension (arr: MyString[Byte]) def length: Int = 0 // warn
17+
| ^
18+
| Extension method length will never be selected from type String
19+
| because String already has a member with the same name and compatible parameter types.
20+
|
21+
| longer explanation available when compiling with `-explain`
22+
-- [E194] Potential Issue Warning: tests/warn/i22232.scala:17:46 -------------------------------------------------------
23+
17 | extension [T <: MyString[Byte]](arr: T) def length: Int = 0 // warn
24+
| ^
25+
| Extension method length will never be selected from type String
26+
| because String already has a member with the same name and compatible parameter types.
27+
|
28+
| longer explanation available when compiling with `-explain`

tests/warn/i22232.scala

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class C
2+
object C:
3+
extension (c: C) def equals(that: Any): Boolean = false // warn
4+
5+
object X:
6+
class C
7+
opaque type D <: C = C
8+
object D:
9+
extension (d: D) def equals(that: Any): Boolean = false // warn
10+
11+
object Upperbound1:
12+
opaque type MyString[+T] <: String = String
13+
extension (arr: MyString[Byte]) def length: Int = 0 // warn
14+
15+
object Upperbound2:
16+
opaque type MyString[+T] <: String = String
17+
extension [T <: MyString[Byte]](arr: T) def length: Int = 0 // warn
18+
19+
object Upperbound3:
20+
opaque type MyString[+T] <: String = String
21+
extension [T](arr: T) def length: Int = 0 // nowarn
22+
23+
object NonUpperbound1:
24+
opaque type MyString[+T] = String
25+
extension (arr: MyString[Byte]) def length: Int = 0 // nowarn
26+
object NonUpperbound2:
27+
opaque type MyString[+T] = String
28+
extension [T <: MyString[Byte]](arr: T) def length2: Int = 0 // nowarn
29+
30+
object NonUpperbound3:
31+
opaque type MyString[+T] = String
32+
extension [T](arr: T) def length: Int = 0 // nowarn

0 commit comments

Comments
 (0)