@@ -69,7 +69,7 @@ trait ImportSuggestions:
6969 && ! (root.name == nme.raw.BAR && ctx.settings.scalajs.value && root == JSDefinitions .jsdefn.PseudoUnionModule )
7070 }
7171
72- def nestedRoots (site : Type )(using Context ): List [Symbol ] =
72+ def nestedRoots (site : Type , parentSymbols : Set [ Symbol ] )(using Context ): List [Symbol ] =
7373 val seenNames = mutable.Set [Name ]()
7474 site.baseClasses.flatMap { bc =>
7575 bc.info.decls.filter { dcl =>
@@ -79,34 +79,37 @@ trait ImportSuggestions:
7979 }
8080 }
8181
82- def rootsStrictlyIn (ref : Type )(using Context ): List [TermRef ] =
82+ def rootsStrictlyIn (ref : Type , parentSymbols : Set [ Symbol ] = Set () )(using Context ): List [TermRef ] =
8383 val site = ref.widen
8484 val refSym = site.typeSymbol
85- val nested =
86- if refSym.is(Package ) then
87- if refSym == defn.EmptyPackageClass // Don't search the empty package
88- || refSym == defn.JavaPackageClass // As an optimization, don't search java...
89- || refSym == defn.JavaLangPackageClass // ... or java.lang.
90- then Nil
91- else refSym.info.decls.filter(lookInside)
92- else if refSym.infoOrCompleter.isInstanceOf [StubInfo ] then
93- Nil // Don't chase roots that do not exist
94- else
95- if ! refSym.is(Touched ) then
96- refSym.ensureCompleted() // JavaDefined is reliably known only after completion
97- if refSym.is(JavaDefined ) then Nil
98- else nestedRoots(site)
99- nested
100- .map(mbr => TermRef (ref, mbr.asTerm))
101- .flatMap(rootsIn)
102- .toList
85+ if parentSymbols.contains(refSym) then Nil
86+ else
87+ val nested =
88+ if refSym.is(Package ) then
89+ if refSym == defn.EmptyPackageClass // Don't search the empty package
90+ || refSym == defn.JavaPackageClass // As an optimization, don't search java...
91+ || refSym == defn.JavaLangPackageClass // ... or java.lang.
92+ then Nil
93+ else refSym.info.decls.filter(lookInside)
94+ else if refSym.infoOrCompleter.isInstanceOf [StubInfo ] then
95+ Nil // Don't chase roots that do not exist
96+ else
97+ if ! refSym.is(Touched ) then
98+ refSym.ensureCompleted() // JavaDefined is reliably known only after completion
99+ if refSym.is(JavaDefined ) then Nil
100+ else nestedRoots(site, parentSymbols)
101+ val newParentSymbols = parentSymbols + refSym
102+ nested
103+ .map(mbr => TermRef (ref, mbr.asTerm))
104+ .flatMap(rootsIn(_, newParentSymbols))
105+ .toList
103106
104- def rootsIn (ref : TermRef )(using Context ): List [TermRef ] =
107+ def rootsIn (ref : TermRef , parentSymbols : Set [ Symbol ] = Set () )(using Context ): List [TermRef ] =
105108 if seen.contains(ref) then Nil
106109 else
107110 implicitsDetailed.println(i " search for suggestions in ${ref.symbol.fullName}" )
108111 seen += ref
109- ref :: rootsStrictlyIn(ref)
112+ ref :: rootsStrictlyIn(ref, parentSymbols )
110113
111114 def rootsOnPath (tp : Type )(using Context ): List [TermRef ] = tp match
112115 case ref : TermRef => rootsIn(ref) ::: rootsOnPath(ref.prefix)
0 commit comments