Skip to content

Commit 9de5e1f

Browse files
KacperFKorbanTheDrawingCoder-Gamer
authored andcommitted
fix: Fix extracting refinements from intersection types in dynamic select hovers (scala#23640)
closes scala#22919 --------- Co-authored-by: Bulby <26726264+thedrawingcoder-gamer@users.noreply.github.com> [Cherry-picked b0627b3]
1 parent 4059d1c commit 9de5e1f

File tree

2 files changed

+91
-6
lines changed

2 files changed

+91
-6
lines changed

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

Lines changed: 16 additions & 6 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.*
@@ -202,12 +203,21 @@ object HoverProvider:
202203
findRefinement(parent)
203204
case _ => None
204205

205-
val refTpe = sel.typeOpt.widen.deepDealiasAndSimplify match
206-
case r: RefinedType => Some(r)
207-
case t: (TermRef | TypeProxy) => Some(t.termSymbol.info.deepDealiasAndSimplify)
208-
case _ => None
209-
210-
refTpe.flatMap(findRefinement).asJava
206+
def extractRefinements(t: Type): List[Type] = t match
207+
case r: RefinedType => List(r)
208+
case t: (TypeRef | AppliedType) =>
209+
// deepDealiasAndSimplify can succeed with no progress, so we have to avoid infinite loops
210+
val t1 = t.deepDealiasAndSimplify
211+
if t1 == t then Nil
212+
else extractRefinements(t1)
213+
case t: TermRef => extractRefinements(t.widen)
214+
case t: TypeProxy => List(t.termSymbol.info.deepDealiasAndSimplify)
215+
case AndType(l , r) => List(extractRefinements(l), extractRefinements(r)).flatten
216+
case _ => Nil
217+
218+
val refTpe: List[Type] = extractRefinements(sel.typeOpt)
219+
220+
refTpe.flatMap(findRefinement).headOption.asJava
211221
case _ =>
212222
ju.Optional.empty().nn
213223

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

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,3 +783,78 @@ class HoverTermSuite extends BaseHoverSuite:
783783
|""".stripMargin,
784784
"val thisIsAVeryLongName: Int".hover
785785
)
786+
787+
@Test def `intersection_of_selectable-1` =
788+
check(
789+
"""|class Record extends Selectable:
790+
| def selectDynamic(name: String): Any = ???
791+
|
792+
|type A = Record { val aa: Int }
793+
|type B = Record { val bb: String }
794+
|type AB = A & B
795+
|
796+
|val ab: AB = Record().asInstanceOf[AB]
797+
|val ab_a = ab.a@@a
798+
|""".stripMargin,
799+
"val aa: Int".hover
800+
)
801+
802+
@Test def `intersection_of_selectable-2` =
803+
check(
804+
"""|class Record extends Selectable:
805+
| def selectDynamic(name: String): Any = ???
806+
|
807+
|type A = Record { val aa: Int }
808+
|type B = Record { val aa: String }
809+
|type AB = A & B
810+
|
811+
|val ab: AB = Record().asInstanceOf[AB]
812+
|val ab_a = ab.a@@a
813+
|""".stripMargin,
814+
"val aa: Int & String".hover
815+
)
816+
817+
@Test def `intersection_of_selectable-3` =
818+
check(
819+
"""|class Record extends Selectable:
820+
| def selectDynamic(name: String): Any = ???
821+
|
822+
|type A = Record { val aa: Int }
823+
|type B = Record { val bb: String }
824+
|type AB = A & B
825+
|
826+
|val ab: AB = Record().asInstanceOf[AB]
827+
|val ab_a = ab.b@@b
828+
|""".stripMargin,
829+
"val bb: String".hover
830+
)
831+
832+
@Test def `intersection_of_selectable-4` =
833+
check(
834+
"""|class Record extends Selectable:
835+
| def selectDynamic(name: String): Any = ???
836+
|
837+
|type A = Record { val aa: Int }
838+
|type B = Record { val bb: String }
839+
|type C = Record { val cc: Float }
840+
|type AB = A & B
841+
|type ABC = AB & C
842+
|
843+
|val abc: ABC = Record().asInstanceOf[ABC]
844+
|val abc_a = abc.a@@a
845+
|""".stripMargin,
846+
"val aa: Int".hover
847+
)
848+
849+
@Test def `intersection_of_selectable-5` =
850+
check(
851+
"""|class Record extends Selectable:
852+
| def selectDynamic(name: String): Any = ???
853+
|
854+
|type AL = List[Int] & Record { val aa: Int }
855+
|
856+
|val al: AL = ???.asInstanceOf[ABC]
857+
|val al_a = al.a@@a
858+
|""".stripMargin,
859+
"val aa: Int".hover
860+
)

0 commit comments

Comments
 (0)