Skip to content

Commit a69cc97

Browse files
committed
Fallback to Type.member for refinements who can't access to the tree
For example, ```scala trait SpecialRefinement { def pickOne(as: String*): Option[Any] } class PickOneRefinement_1[S <: SpecialRefinement { def pickOne(as: String*): Option[String] }] { def run(s: S, as: String*): Option[String] = s.pickOne(as:_*) } ``` In the typed AST, the SpecialRefinement is inside of the TypeTree and cannot access to the refinement (pickOne) from tree, therefore we can't register the symbol of pickOne to symbol table. In this case, fallback to `Type.member` to find the symbol of `pickOne`.
1 parent 21e39e0 commit a69cc97

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed

compiler/src/dotty/tools/dotc/semanticdb/TypeOps.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,17 @@ class TypeOps:
279279
val (parent, refinedInfos) = flatten(rt, List.empty)
280280
val stpe = s.IntersectionType(flattenParent(parent))
281281

282-
val decls = refinedInfos.flatMap { (name, _) =>
283-
refinementSymtab.getOrErr((rt, name), sym)
282+
val decls = refinedInfos.map { (name, info) =>
283+
// In case refinement cannot be accessed from traverser and
284+
// no symbols are registered to the symtab
285+
// fall back to Type.member
286+
val decl = refinementSymtab.getOrElse(
287+
(rt, name),
288+
rt.member(name).symbol
289+
)
290+
if decl == NoSymbol then
291+
symbolNotFound(rt, name, sym)
292+
decl
284293
}
285294
val sdecls = decls.sscopeOpt(using LinkMode.HardlinkChildren)
286295
s.StructuralType(stpe, sdecls)

tests/semanticdb/expect/RecOrRefined.expect.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,11 @@ type Person/*<-example::RecOrRefined$package.Person#*/ = Record/*->example::Reco
2424
// RecType
2525
class C/*<-example::C#*/ { type T1/*<-example::C#T1#*/; type T2/*<-example::C#T2#*/ }
2626
type C2/*<-example::RecOrRefined$package.C2#*/ = C/*->example::C#*/ { type T1/*<-local17*/; type T2/*<-local18*/ = T1/*->local17*/ }
27+
28+
trait SpecialRefinement/*<-example::SpecialRefinement#*/ {
29+
def pickOne/*<-example::SpecialRefinement#pickOne().*/(as/*<-example::SpecialRefinement#pickOne().(as)*/: String/*->scala::Predef.String#*/*): Option/*->scala::Option#*/[Any/*->scala::Any#*/]
30+
}
31+
32+
class PickOneRefinement_1/*<-example::PickOneRefinement_1#*/[S/*<-example::PickOneRefinement_1#[S]*/ <: SpecialRefinement { def pickOne(as: String*): Option[String] }] {
33+
def run/*<-example::PickOneRefinement_1#run().*/(s/*<-example::PickOneRefinement_1#run().(s)*/: S/*->example::PickOneRefinement_1#[S]*/, as/*<-example::PickOneRefinement_1#run().(as)*/: String/*->scala::Predef.String#*/*): Option/*->scala::Option#*/[String/*->scala::Predef.String#*/] = s/*->example::PickOneRefinement_1#run().(s)*/.pickOne/*->example::SpecialRefinement#pickOne().*/(as/*->example::PickOneRefinement_1#run().(as)*/:_*)
34+
}

tests/semanticdb/expect/RecOrRefined.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,11 @@ type Person = Record {
2424
// RecType
2525
class C { type T1; type T2 }
2626
type C2 = C { type T1; type T2 = T1 }
27+
28+
trait SpecialRefinement {
29+
def pickOne(as: String*): Option[Any]
30+
}
31+
32+
class PickOneRefinement_1[S <: SpecialRefinement { def pickOne(as: String*): Option[String] }] {
33+
def run(s: S, as: String*): Option[String] = s.pickOne(as:_*)
34+
}

tests/semanticdb/metac.expect

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,14 +2830,20 @@ Schema => SemanticDB v4
28302830
Uri => RecOrRefined.scala
28312831
Text => empty
28322832
Language => Scala
2833-
Symbols => 51 entries
2834-
Occurrences => 89 entries
2833+
Symbols => 61 entries
2834+
Occurrences => 109 entries
28352835

28362836
Symbols:
28372837
example/C# => class C extends Object { self: C => +3 decls }
28382838
example/C#T1# => type T1
28392839
example/C#T2# => type T2
28402840
example/C#`<init>`(). => primary ctor <init> (): C
2841+
example/PickOneRefinement_1# => class PickOneRefinement_1 [typeparam S <: SpecialRefinement { abstract method pickOne (param as: String*): Option[Any] }] extends Object { self: PickOneRefinement_1[S] => +3 decls }
2842+
example/PickOneRefinement_1#[S] => typeparam S <: SpecialRefinement { abstract method pickOne (param as: String*): Option[Any] }
2843+
example/PickOneRefinement_1#`<init>`(). => primary ctor <init> [typeparam S <: SpecialRefinement { abstract method pickOne (param as: String*): Option[Any] }](): PickOneRefinement_1[S]
2844+
example/PickOneRefinement_1#run(). => method run (param s: S, param as: String*): Option[String]
2845+
example/PickOneRefinement_1#run().(as) => param as: String*
2846+
example/PickOneRefinement_1#run().(s) => param s: S
28412847
example/PolyHolder# => trait PolyHolder extends Object { self: PolyHolder => +2 decls }
28422848
example/PolyHolder#`<init>`(). => primary ctor <init> (): PolyHolder
28432849
example/PolyHolder#foo(). => abstract method foo [typeparam T ](param t: T): Any
@@ -2866,6 +2872,10 @@ example/Record#elems. => private[this] val method elems Tuple2[String, Any]*
28662872
example/Record#fields. => private[this] val method fields Map[String, Any]
28672873
example/Record#selectDynamic(). => method selectDynamic (param name: String): Any
28682874
example/Record#selectDynamic().(name) => param name: String
2875+
example/SpecialRefinement# => trait SpecialRefinement extends Object { self: SpecialRefinement => +2 decls }
2876+
example/SpecialRefinement#`<init>`(). => primary ctor <init> (): SpecialRefinement
2877+
example/SpecialRefinement#pickOne(). => abstract method pickOne (param as: String*): Option[Any]
2878+
example/SpecialRefinement#pickOne().(as) => param as: String*
28692879
local0 => abstract val method x Int
28702880
local1 => abstract val method x Int
28712881
local2 => abstract method y => Int
@@ -2976,6 +2986,26 @@ Occurrences:
29762986
[25:19..25:21): T1 <- local17
29772987
[25:28..25:30): T2 <- local18
29782988
[25:33..25:35): T1 -> local17
2989+
[27:6..27:23): SpecialRefinement <- example/SpecialRefinement#
2990+
[28:2..28:2): <- example/SpecialRefinement#`<init>`().
2991+
[28:6..28:13): pickOne <- example/SpecialRefinement#pickOne().
2992+
[28:14..28:16): as <- example/SpecialRefinement#pickOne().(as)
2993+
[28:18..28:24): String -> scala/Predef.String#
2994+
[28:28..28:34): Option -> scala/Option#
2995+
[28:35..28:38): Any -> scala/Any#
2996+
[31:6..31:25): PickOneRefinement_1 <- example/PickOneRefinement_1#
2997+
[31:25..31:25): <- example/PickOneRefinement_1#`<init>`().
2998+
[31:26..31:27): S <- example/PickOneRefinement_1#[S]
2999+
[32:6..32:9): run <- example/PickOneRefinement_1#run().
3000+
[32:10..32:11): s <- example/PickOneRefinement_1#run().(s)
3001+
[32:13..32:14): S -> example/PickOneRefinement_1#[S]
3002+
[32:16..32:18): as <- example/PickOneRefinement_1#run().(as)
3003+
[32:20..32:26): String -> scala/Predef.String#
3004+
[32:30..32:36): Option -> scala/Option#
3005+
[32:37..32:43): String -> scala/Predef.String#
3006+
[32:47..32:48): s -> example/PickOneRefinement_1#run().(s)
3007+
[32:49..32:56): pickOne -> example/SpecialRefinement#pickOne().
3008+
[32:57..32:59): as -> example/PickOneRefinement_1#run().(as)
29793009

29803010
expect/RightAssociativeExtension.scala
29813011
--------------------------------------

0 commit comments

Comments
 (0)