Skip to content

Commit b0627b3

Browse files
fix: Fix extracting refinements from intersection types in dynamic select hovers (#23640)
closes #22919 --------- Co-authored-by: Bulby <26726264+thedrawingcoder-gamer@users.noreply.github.com>
1 parent 40843f7 commit b0627b3

File tree

2 files changed

+90
-5
lines changed

2 files changed

+90
-5
lines changed

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import scala.meta.pc.SymbolSearch
1313
import dotty.tools.dotc.ast.tpd.*
1414
import dotty.tools.dotc.core.Constants.*
1515
import dotty.tools.dotc.core.Contexts.*
16+
import dotty.tools.dotc.core.Decorators.*
1617
import dotty.tools.dotc.core.Flags.*
1718
import dotty.tools.dotc.core.Names.*
1819
import dotty.tools.dotc.core.StdNames.*
@@ -221,12 +222,21 @@ object HoverProvider:
221222
findRefinement(parent)
222223
case _ => None
223224

224-
val refTpe = sel.typeOpt.widen.deepDealiasAndSimplify match
225-
case r: RefinedType => Some(r)
226-
case t: (TermRef | TypeProxy) => Some(t.termSymbol.info.deepDealiasAndSimplify)
227-
case _ => None
225+
def extractRefinements(t: Type): List[Type] = t match
226+
case r: RefinedType => List(r)
227+
case t: (TypeRef | AppliedType) =>
228+
// deepDealiasAndSimplify can succeed with no progress, so we have to avoid infinite loops
229+
val t1 = t.deepDealiasAndSimplify
230+
if t1 == t then Nil
231+
else extractRefinements(t1)
232+
case t: TermRef => extractRefinements(t.widen)
233+
case t: TypeProxy => List(t.termSymbol.info.deepDealiasAndSimplify)
234+
case AndType(l , r) => List(extractRefinements(l), extractRefinements(r)).flatten
235+
case _ => Nil
228236

229-
refTpe.flatMap(findRefinement).asJava
237+
val refTpe: List[Type] = extractRefinements(sel.typeOpt)
238+
239+
refTpe.flatMap(findRefinement).headOption.asJava
230240
case _ =>
231241
ju.Optional.empty().nn
232242

presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,3 +851,78 @@ class HoverTermSuite extends BaseHoverSuite:
851851
|""".stripMargin,
852852
"val thisIsAVeryLongName: Int".hover
853853
)
854+
855+
@Test def `intersection_of_selectable-1` =
856+
check(
857+
"""|class Record extends Selectable:
858+
| def selectDynamic(name: String): Any = ???
859+
|
860+
|type A = Record { val aa: Int }
861+
|type B = Record { val bb: String }
862+
|type AB = A & B
863+
|
864+
|val ab: AB = Record().asInstanceOf[AB]
865+
|val ab_a = ab.a@@a
866+
|""".stripMargin,
867+
"val aa: Int".hover
868+
)
869+
870+
@Test def `intersection_of_selectable-2` =
871+
check(
872+
"""|class Record extends Selectable:
873+
| def selectDynamic(name: String): Any = ???
874+
|
875+
|type A = Record { val aa: Int }
876+
|type B = Record { val aa: String }
877+
|type AB = A & B
878+
|
879+
|val ab: AB = Record().asInstanceOf[AB]
880+
|val ab_a = ab.a@@a
881+
|""".stripMargin,
882+
"val aa: Int & String".hover
883+
)
884+
885+
@Test def `intersection_of_selectable-3` =
886+
check(
887+
"""|class Record extends Selectable:
888+
| def selectDynamic(name: String): Any = ???
889+
|
890+
|type A = Record { val aa: Int }
891+
|type B = Record { val bb: String }
892+
|type AB = A & B
893+
|
894+
|val ab: AB = Record().asInstanceOf[AB]
895+
|val ab_a = ab.b@@b
896+
|""".stripMargin,
897+
"val bb: String".hover
898+
)
899+
900+
@Test def `intersection_of_selectable-4` =
901+
check(
902+
"""|class Record extends Selectable:
903+
| def selectDynamic(name: String): Any = ???
904+
|
905+
|type A = Record { val aa: Int }
906+
|type B = Record { val bb: String }
907+
|type C = Record { val cc: Float }
908+
|type AB = A & B
909+
|type ABC = AB & C
910+
|
911+
|val abc: ABC = Record().asInstanceOf[ABC]
912+
|val abc_a = abc.a@@a
913+
|""".stripMargin,
914+
"val aa: Int".hover
915+
)
916+
917+
@Test def `intersection_of_selectable-5` =
918+
check(
919+
"""|class Record extends Selectable:
920+
| def selectDynamic(name: String): Any = ???
921+
|
922+
|type AL = List[Int] & Record { val aa: Int }
923+
|
924+
|val al: AL = ???.asInstanceOf[ABC]
925+
|val al_a = al.a@@a
926+
|""".stripMargin,
927+
"val aa: Int".hover
928+
)

0 commit comments

Comments
 (0)