@@ -986,22 +986,35 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
986986    record(" typedSelect" 
987987
988988    def  typeSelectOnTerm (using  Context ):  Tree  = 
989-       val  qual  =  typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
990989      if  ctx.isJava then 
991-         javaSelection(qual)
990+         //  permitted selection depends on Java context (type or expression).
991+         //  we don't propagate (as a mode) whether a.b.m is a type name; OK since we only see type contexts.
992+         //  to allow correct selections, approximate by fallback for x.y: take x as class or (rooted) package.
993+         def  tryQualFallback (qual : untpd.Ident , name : Name )(using  Context ):  Tree  = 
994+           val  qualTpe  = 
995+             findRef(name.toTypeName, WildcardType , EmptyFlags , EmptyFlags , qual.srcPos) match 
996+             case  tpe : NamedType  if  tpe.symbol.isClass =>  tpe
997+             case  _ => 
998+               val  maybePackage  =  defn.RootPackage .info.member(name)
999+               if  maybePackage.exists then  maybePackage.info else  NoType 
1000+           if  qualTpe.exists then 
1001+             javaSelection(assignType(cpy.Ident (qual)(name), qualTpe))
1002+           else 
1003+             errorTree(tree, em " no class or package to resolve ` $name` " ) //  just fail fallback
1004+         def  tryQual (qual : untpd.Tree )(using  Context ):  Tree  = 
1005+           javaSelection(typedExpr(qual, shallowSelectionProto(tree.name, pt, this , tree.nameSpan)))
1006+         tree.qualifier match 
1007+         case  qual @  Ident (name) =>  tryAlternatively(tryQual(qual))(tryQualFallback(qual, name))
1008+         case  qual               =>  tryQual(qual)
9921009      else 
1010+         val  qual  =  typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
9931011        typedSelectWithAdapt(tree, pt, qual).withSpan(tree.span).computeNullable()
9941012
9951013    def  javaSelection (qual : Tree )(using  Context ) = 
9961014      qual match 
9971015      case  id @  Ident (name) if  id.symbol.is(Package ) &&  ! id.symbol.owner.isRoot => 
998-         def  nextPackage (last : Symbol )(using  Context ):  Type  = 
999-           val  startAt  =  ctx.outersIterator.dropWhile(_.owner !=  last.owner).drop(1 ).next()
1000-           val  next  =  findRef(name, WildcardType , required =  Package , EmptyFlags , qual.srcPos)(using  startAt)
1001-           if  next.exists &&  ! next.typeSymbol.owner.isRoot then  nextPackage(next.typeSymbol)
1002-           else  next
1003-         val  next  =  nextPackage(id.symbol)
1004-         val  qual1  =  if  next.exists then  assignType(cpy.Ident (id)(tree.name), next) else  qual
1016+         val  rooted  =  defn.RootPackage .info.member(name)
1017+         val  qual1  =  if  rooted.exists then  assignType(cpy.Ident (id)(name), rooted.info) else  qual
10051018        assignType(cpy.Select (tree)(qual1, tree.name), qual1)
10061019      case  _ => 
10071020        val  tree1  =  assignType(cpy.Select (tree)(qual, tree.name), qual)
@@ -1027,17 +1040,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
10271040        errorTree(tree, em " cannot convert to type selection " ) //  will never be printed due to fallback
10281041    }
10291042
1030-     def  selectWithFallback (fallBack : Context  ?=>  Tree ) = 
1031-       tryAlternatively(typeSelectOnTerm)(fallBack)
1032- 
10331043    if  (tree.qualifier.isType) {
10341044      val  qual1  =  typedType(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
10351045      assignType(cpy.Select (tree)(qual1, tree.name), qual1)
10361046    }
10371047    else  if  (ctx.isJava &&  tree.name.isTypeName)
1038-       //  SI- 3120 Java uses the same syntax, A.B, to express selection from the
1039-       //  value A and from the type A. We have to try both.
1040-       selectWithFallback( tryJavaSelectOnType)  //  !!! possibly exponential bcs of qualifier retyping 
1048+       //  scala/bug# 3120 Java uses the same syntax, A.B, to express selection from the
1049+       //  value A and from the type A. We have to try both. (possibly exponential bc of qualifier retyping) 
1050+       tryAlternatively(typeSelectOnTerm)( tryJavaSelectOnType)
10411051    else 
10421052      typeSelectOnTerm
10431053  }
0 commit comments