Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d53c798

Browse files
committedSep 1, 2024·
Fix pkg obj prefix of opaque tp ext meth
TypeOps.makePackageObjPrefixExplicit is a part of `accessibleType`, which is called on the result of findRef in typedIdent. But in `tryExtension` it's not. 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 ec1b115 commit d53c798

File tree

7 files changed

+96
-2
lines changed

7 files changed

+96
-2
lines changed
 

‎compiler/src/dotty/tools/dotc/typer/Typer.scala

+6-2
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
315315
else found
316316
end checkImportAlternatives
317317

318+
extension (tp: Type) def makePackageObjPrefixExplicit: Type = tp match
319+
case tp: NamedType => TypeOps.makePackageObjPrefixExplicit(tp)
320+
case tp => tp
321+
318322
def selection(imp: ImportInfo, name: Name, checkBounds: Boolean): Type =
319323
imp.importSym.info match
320324
case ImportType(expr) =>
@@ -341,7 +345,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
341345
// so we ignore that import.
342346
if reallyExists(denot) && !isScalaJsPseudoUnion then
343347
if unimported.isEmpty || !unimported.contains(pre.termSymbol) then
344-
return pre.select(name, denot)
348+
return pre.select(name, denot).makePackageObjPrefixExplicit
345349
case _ =>
346350
if imp.importSym.isCompleting then
347351
report.warning(i"cyclic ${imp.importSym}, ignored", pos)
@@ -501,7 +505,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
501505
defDenot.symbol.owner
502506
else
503507
curOwner
504-
effectiveOwner.thisType.select(name, defDenot)
508+
effectiveOwner.thisType.select(name, defDenot).makePackageObjPrefixExplicit
505509
}
506510
if !curOwner.is(Package) || isDefinedInCurrentUnit(defDenot) then
507511
result = checkNewOrShadowed(found, Definition) // no need to go further out, we found highest prec entry

‎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

‎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

‎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")

‎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] = ???

‎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 _ => ???

‎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)
Please sign in to comment.