Skip to content

Commit d788ef2

Browse files
authored
Use the unwidened type when casting structural calls (#18527)
So if the call is to a stable val, the call will have a stable type.
2 parents 7b3682d + af81e64 commit d788ef2

File tree

5 files changed

+35
-9
lines changed

5 files changed

+35
-9
lines changed

Diff for: compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

+1-6
Original file line numberDiff line numberDiff line change
@@ -1005,16 +1005,11 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
10051005
!tree.symbol.exists
10061006
&& tree.isTerm
10071007
&& hasRefinement(tree.qualifier.tpe)
1008-
def loop(tree: Tree): Boolean = tree match
1009-
case TypeApply(fun, _) =>
1010-
loop(fun)
1011-
case Apply(fun, _) =>
1012-
loop(fun)
1008+
funPart(tree) match
10131009
case tree: Select =>
10141010
isStructuralTermSelect(tree)
10151011
case _ =>
10161012
false
1017-
loop(tree)
10181013
}
10191014

10201015
/** Return a pair consisting of (supercall, rest)

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

+2-2
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.widenExpr)
246246

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

Diff for: presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ object HoverProvider:
181181
findRefinement(parent)
182182
case _ => None
183183

184-
val refTpe = sel.tpe.metalsDealias match
184+
val refTpe = sel.tpe.widen.metalsDealias match
185185
case r: RefinedType => Some(r)
186186
case t: (TermRef | TypeProxy) => Some(t.termSymbol.info.metalsDealias)
187187
case _ => None

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

+16
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

Diff for: tests/pos/i18263.scala

+15
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)