Skip to content

Commit fd97de5

Browse files
committed
Use the unwidened type when casting structural calls
So if the call is to a stable val, the call will have a stable type.
1 parent fef4245 commit fd97de5

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,14 @@ trait Dynamic {
235235
if ValueClasses.isDerivedValueClass(tpe.classSymbol) && qual.tpe <:< defn.ReflectSelectableTypeRef then
236236
val genericUnderlying = ValueClasses.valueClassUnbox(tpe.classSymbol.asClass)
237237
val underlying = tpe.select(genericUnderlying).widen.resultType
238-
New(tpe, tree.cast(underlying) :: Nil)
238+
New(tpe.widen, tree.cast(underlying) :: Nil)
239239
else
240240
tree
241241
maybeBoxed.cast(tpe)
242242

243243
fun.tpe.widen match {
244244
case tpe: ValueType =>
245-
structuralCall(nme.selectDynamic, Nil).maybeBoxingCast(tpe)
245+
structuralCall(nme.selectDynamic, Nil).maybeBoxingCast(fun.tpe)
246246

247247
case tpe: MethodType =>
248248
def isDependentMethod(tpe: Type): Boolean = tpe match {

tests/pos/i18263.orig.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
sealed trait Scope
2+
sealed trait Domain extends Scope
3+
object Domain extends Domain
4+
5+
trait Baz[T]
6+
def baz(using ck: Scope): Baz[ck.type] = ???
7+
8+
class Foo extends scala.reflect.Selectable:
9+
type TScope = Domain
10+
final protected given TScope = Domain
11+
12+
object ID:
13+
val internal1 = new Foo:
14+
val ii = new Foo:
15+
val x = baz
16+
val z = internal1.ii.x //error

tests/pos/i18263.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
final class Bar
2+
final class Inv[T]
3+
class Foo extends scala.reflect.Selectable:
4+
type Boo = Bar
5+
final given boo1: Boo = new Bar
6+
7+
class Test:
8+
def mkInv(using bar: Bar): Inv[bar.type] = new Inv()
9+
10+
def test: Unit =
11+
val foo1 /* : Foo { val foo2: { z1 => Foo { val inv1: Inv[(z1.boo1 : z1.Boo)] }}} */ = new Foo:
12+
val foo2 /* : { z1 => Foo { val inv1: Inv[(z1.boo1 : z1.Boo)] }} */ = new Foo:
13+
val inv1 /* : Inv[( boo1 : Boo)] */ = mkInv /* (this.boo1) */
14+
val inv2 = foo1.foo2.inv1 // error
15+
()

0 commit comments

Comments
 (0)