Skip to content

Commit 3b06cad

Browse files
committed
Fix pkg obj prefix of opaque tp ext meth
There is use of `makePackageObjPrefixExplicit` within `accessibleType`, which is called on the result of findRef in typedIdent. But in `tryExtension` it's no such use. We could fix it in the usage of the results in `tryExtension`, but I thought perhaps we could fix it for all call sites, by handling it within findRef.
1 parent f9145d7 commit 3b06cad

File tree

7 files changed

+92
-2
lines changed

7 files changed

+92
-2
lines changed

Diff for: compiler/src/dotty/tools/dotc/typer/Typer.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
344344
// so we ignore that import.
345345
if reallyExists(denot) && !isScalaJsPseudoUnion then
346346
if unimported.isEmpty || !unimported.contains(pre.termSymbol) then
347-
return pre.select(name, denot)
347+
return pre.select(name, denot).makePackageObjPrefixExplicit
348348
case _ =>
349349
if imp.importSym.isCompleting then
350350
report.warning(i"cyclic ${imp.importSym}, ignored", pos)
@@ -504,7 +504,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
504504
defDenot.symbol.owner
505505
else
506506
curOwner
507-
effectiveOwner.thisType.select(name, defDenot)
507+
effectiveOwner.thisType.select(name, defDenot).makePackageObjPrefixExplicit
508508
}
509509
if !curOwner.is(Package) || isDefinedInCurrentUnit(defDenot) then
510510
result = checkNewOrShadowed(found, Definition) // no need to go further out, we found highest prec entry

Diff for: tests/pos/i18097.1.scala

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
opaque type Pos = Double
2+
3+
object Pos:
4+
extension (x: Pos)
5+
def mult1(y: Pos): Pos = x * y
6+
7+
extension (x: Pos)
8+
def mult2(y: Pos): Pos = x * y
9+
10+
class Test:
11+
def test(key: String, a: Pos, b: Pos): Unit =
12+
val tup1 = new Tuple1(Pos.mult1(a)(b))
13+
val res1: Pos = tup1._1
14+
15+
val tup2 = new Tuple1(a.mult1(b))
16+
val res2: Pos = tup2._1
17+
18+
val tup3 = new Tuple1(mult2(a)(b))
19+
val res3: Pos = tup3._1
20+
21+
val tup4 = new Tuple1(a.mult2(b))
22+
val res4: Pos = tup4._1 // was error: Found: (tup4._4 : Double) Required: Pos

Diff for: tests/pos/i18097.2.scala

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
opaque type Namespace = List[String]
2+
3+
object Namespace:
4+
def apply(head: String): Namespace = List(head)
5+
6+
extension (ns: Namespace)
7+
def appended(segment: String): Namespace = ns.appended(segment)
8+
9+
object Main:
10+
def main(args: Array[String]): Unit =
11+
val a: Namespace = Namespace("a")
12+
.appended("B")
13+
.appended("c") // was error: Found: List[String] Required: Namespace

Diff for: tests/pos/i18097.2.works.scala

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
object Main:
2+
opaque type Namespace = List[String]
3+
4+
object Namespace:
5+
def apply(head: String): Namespace = List(head)
6+
7+
extension (ns: Namespace)
8+
def appended(segment: String): Namespace = ns.appended(segment)
9+
10+
def main(args: Array[String]): Unit =
11+
val a: Namespace = Namespace("a")
12+
.appended("B")
13+
.appended("c")

Diff for: tests/pos/i18097.3/Opaque.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package test
2+
3+
type Foo = Unit
4+
val bar: Foo = ()
5+
6+
opaque type Opaque = Unit
7+
8+
extension (foo: Foo)
9+
def go: Option[Opaque] = ???

Diff for: tests/pos/i18097.3/Test.scala

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package test
2+
3+
final case class Test(value: Opaque)
4+
5+
def test: Test =
6+
bar.go match
7+
case Some(value) => Test(value) // was error: Found: (value : Unit) Required: test.Opaque
8+
case _ => ???
9+
10+
def test2: Test =
11+
go(bar) match
12+
case Some(value) => Test(value)
13+
case _ => ???

Diff for: tests/pos/i18097.orig.scala

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
opaque type PositiveNumber = Double
2+
3+
object PositiveNumber:
4+
extension (x: PositiveNumber)
5+
def mult1(other: PositiveNumber): PositiveNumber =
6+
x * other
7+
8+
extension (x: PositiveNumber)
9+
def mult2(other: PositiveNumber): PositiveNumber =
10+
x * other
11+
12+
object Test:
13+
def multMap1[A](x: Map[A, PositiveNumber], num: PositiveNumber): Map[A, PositiveNumber] = x.map((key, value) => key -> value.mult1(num)).toMap
14+
15+
def multMap2[A](x: Map[A, PositiveNumber], num: PositiveNumber): Map[A, PositiveNumber] = x.map((key, value) => key -> value.mult2(num)).toMap // was error
16+
// ^
17+
// Cannot prove that (A, Double) <:< (A, V2).
18+
//
19+
// where: V2 is a type variable with constraint <: PositiveNumber
20+
def multMap2_2[A](x: Map[A, PositiveNumber], num: PositiveNumber): Map[A, PositiveNumber] = x.map((key, value) => key -> mult2(value)(num)).toMap

0 commit comments

Comments
 (0)