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