@@ -241,38 +241,40 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
241241 ! owner.isEmptyPackage || ctx.owner.enclosingPackageClass.isEmptyPackage
242242 }
243243
244+ import BindingPrec .*
245+ type Result = (Type , BindingPrec )
246+ val NoResult = (NoType , NothingBound )
247+
244248 /** Find the denotation of enclosing `name` in given context `ctx`.
245- * @param previous A denotation that was found in a more deeply nested scope,
246- * or else `NoDenotation` if nothing was found yet.
247- * @param prevPrec The binding precedence of the previous denotation,
248- * or else `nothingBound` if nothing was found yet.
249+ * @param prevResult A type that was found in a more deeply nested scope,
250+ * and its precedence, or NoResult if nothing was found yet.
249251 * @param prevCtx The context of the previous denotation,
250252 * or else `NoContext` if nothing was found yet.
251253 */
252- def findRefRecur (previous : Type , prevPrec : BindingPrec , prevCtx : Context )(using Context ): Type = {
253- import BindingPrec . *
254+ def findRefRecur (prevResult : Result , prevCtx : Context )(using Context ): Result = {
255+ val (previous, prevPrec) = prevResult
254256
255257 /** Check that any previously found result from an inner context
256258 * does properly shadow the new one from an outer context.
257- * @param found The newly found result
258- * @param newPrec Its precedence
259+ * @param newResult The newly found type and its precedence.
259260 * @param scala2pkg Special mode where we check members of the same package, but defined
260261 * in different compilation units under Scala2. If set, and the
261262 * previous and new contexts do not have the same scope, we select
262263 * the previous (inner) definition. This models what scalac does.
263264 */
264- def checkNewOrShadowed (found : Type , newPrec : BindingPrec , scala2pkg : Boolean = false )(using Context ): Type =
265+ def checkNewOrShadowed (newResult : Result , scala2pkg : Boolean = false )(using Context ): Result =
266+ val (found, newPrec) = newResult
265267 if ! previous.exists || TypeComparer .isSameRef(previous, found) then
266- found
268+ newResult
267269 else if (prevCtx.scope eq ctx.scope) && newPrec.beats(prevPrec) then
268270 // special cases: definitions beat imports, and named imports beat
269271 // wildcard imports, provided both are in contexts with same scope
270- found
272+ newResult
271273 else
272274 if ! scala2pkg && ! previous.isError && ! found.isError then
273275 fail(AmbiguousReference (name, newPrec, prevPrec, prevCtx,
274276 isExtension = previous.termSymbol.is(ExtensionMethod ) && found.termSymbol.is(ExtensionMethod )))
275- previous
277+ prevResult
276278
277279 /** Assemble and check alternatives to an imported reference. This implies:
278280 * - If we expand an extension method (i.e. altImports != null),
@@ -285,12 +287,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
285287 * shadowed. This order of checking is necessary since an outer package-level
286288 * definition might trump two conflicting inner imports, so no error should be
287289 * issued in that case. See i7876.scala.
288- * @param previous the previously found reference (which is an import)
289- * @param prevPrec the precedence of the reference (either NamedImport or WildImport)
290+ * @param prevResult the previously found reference (which is an import), and
291+ * the precedence of the reference (either NamedImport or WildImport)
290292 * @param prevCtx the context in which the reference was found
291293 * @param using_Context the outer context of `precCtx`
292294 */
293- def checkImportAlternatives (previous : Type , prevPrec : BindingPrec , prevCtx : Context )(using Context ): Type =
295+ def checkImportAlternatives (prevResult : Result , prevCtx : Context )(using Context ): Result =
296+ val (previous, prevPrec) = prevResult
294297
295298 def addAltImport (altImp : TermRef ) =
296299 if ! TypeComparer .isSameRef(previous, altImp)
@@ -305,20 +308,20 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
305308 if prevPrec == WildImport then
306309 // Discard all previously found references and continue with `altImp`
307310 altImports.clear()
308- checkImportAlternatives(altImp, NamedImport , ctx)(using ctx.outer)
311+ checkImportAlternatives(( altImp, NamedImport ) , ctx)(using ctx.outer)
309312 else
310313 addAltImport(altImp)
311- checkImportAlternatives(previous, prevPrec , prevCtx)(using ctx.outer)
314+ checkImportAlternatives(prevResult , prevCtx)(using ctx.outer)
312315 case _ =>
313316 if prevPrec == WildImport then
314317 wildImportRef(curImport) match
315318 case altImp : TermRef => addAltImport(altImp)
316319 case _ =>
317- checkImportAlternatives(previous, prevPrec , prevCtx)(using ctx.outer)
320+ checkImportAlternatives(prevResult , prevCtx)(using ctx.outer)
318321 else
319- val found = findRefRecur(previous, prevPrec , prevCtx)
320- if found eq previous then checkNewOrShadowed(found, prevPrec )(using prevCtx)
321- else found
322+ val foundResult = findRefRecur(prevResult , prevCtx)
323+ if foundResult._1 eq previous then checkNewOrShadowed(foundResult )(using prevCtx)
324+ else foundResult
322325 end checkImportAlternatives
323326
324327 def selection (imp : ImportInfo , name : Name , checkBounds : Boolean ): Type =
@@ -408,10 +411,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
408411 ! noImports &&
409412 (prevPrec.ordinal < prec.ordinal || prevPrec == prec && (prevCtx.scope eq ctx.scope))
410413
411- @ tailrec def loop (lastCtx : Context )(using Context ): Type =
412- if (ctx.scope eq EmptyScope ) previous
414+ @ tailrec def loop (lastCtx : Context )(using Context ): Result =
415+ if (ctx.scope eq EmptyScope ) prevResult
413416 else {
414- var result : Type = NoType
417+ var result : Result = NoResult
415418 val curOwner = ctx.owner
416419
417420 /** Is curOwner a package object that should be skipped?
@@ -510,37 +513,36 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
510513 effectiveOwner.thisType.select(name, defDenot).makePackageObjPrefixExplicit
511514 }
512515 if ! curOwner.is(Package ) || isDefinedInCurrentUnit(defDenot) then
513- result = checkNewOrShadowed(found, Definition ) // no need to go further out, we found highest prec entry
516+ result = checkNewOrShadowed(( found, Definition ) ) // no need to go further out, we found highest prec entry
514517 found match
515518 case found : NamedType
516519 if curOwner.isClass && isInherited(found.denot) && ! ctx.compilationUnit.isJava =>
517520 checkNoOuterDefs(found.denot, ctx, ctx)
518521 case _ =>
519522 else
520523 if migrateTo3 && ! foundUnderScala2.exists then
521- foundUnderScala2 = checkNewOrShadowed(found, Definition , scala2pkg = true )
524+ foundUnderScala2 = checkNewOrShadowed(( found, Definition ) , scala2pkg = true )._1
522525 if (defDenot.symbol.is(Package ))
523- result = checkNewOrShadowed(previous orElse found, PackageClause )
526+ result = checkNewOrShadowed(( previous orElse found, PackageClause ) )
524527 else if (prevPrec.ordinal < PackageClause .ordinal)
525- result = findRefRecur(found, PackageClause , ctx)(using ctx.outer)
528+ result = findRefRecur(( found, PackageClause ) , ctx)(using ctx.outer)
526529 }
527530
528- if result.exists then result
531+ if result._1. exists then result
529532 else { // find import
530533 val outer = ctx.outer
531534 val curImport = ctx.importInfo
532- def updateUnimported () =
533- if (curImport.nn.unimported ne NoSymbol ) unimported += curImport.nn.unimported
534535 if (curOwner.is(Package ) && curImport != null && curImport.isRootImport && previous.exists)
535- previous // no more conflicts possible in this case
536- else if (isPossibleImport(NamedImport ) && (curImport nen outer.importInfo)) {
537- val namedImp = namedImportRef(curImport.uncheckedNN)
536+ prevResult // no more conflicts possible in this case
537+ else if (isPossibleImport(NamedImport ) && curImport != null && (curImport ne outer.importInfo)) {
538+ def updateUnimported () = if curImport.unimported ne NoSymbol then unimported += curImport.unimported
539+ val namedImp = namedImportRef(curImport)
538540 if (namedImp.exists)
539- checkImportAlternatives(namedImp, NamedImport , ctx)(using outer)
540- else if (isPossibleImport(WildImport ) && ! curImport.nn. importSym.isCompleting) {
541- val wildImp = wildImportRef(curImport.uncheckedNN )
541+ checkImportAlternatives(( namedImp, NamedImport ) , ctx)(using outer)
542+ else if (isPossibleImport(WildImport ) && ! curImport.importSym.isCompleting) {
543+ val wildImp = wildImportRef(curImport)
542544 if (wildImp.exists)
543- checkImportAlternatives(wildImp, WildImport , ctx)(using outer)
545+ checkImportAlternatives(( wildImp, WildImport ) , ctx)(using outer)
544546 else {
545547 updateUnimported()
546548 loop(ctx)(using outer)
@@ -559,7 +561,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
559561 loop(NoContext )
560562 }
561563
562- findRefRecur(NoType , BindingPrec .NothingBound , NoContext )
564+ val (foundRef, foundPrec) = findRefRecur(NoResult , NoContext )
565+ foundRef
563566 }
564567
565568 /** If `tree`'s type is a `TermRef` identified by flow typing to be non-null, then
0 commit comments