@@ -1022,20 +1022,44 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
10221022 record(" typedSelect" )
10231023
10241024 def typeSelectOnTerm (using Context ): Tree =
1025- val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
10261025 if ctx.isJava then
1027- javaSelection(qual)
1026+ // permitted selection depends on Java context (type or expression).
1027+ // we don't propagate (as a mode) whether a.b.m is a type name; OK since we only see type contexts.
1028+ // to allow correct selections, approximate by fallback for x.y: take x as class or (rooted) package.
1029+ def tryQualFallback (qual : untpd.Ident , name : Name )(using Context ): Tree =
1030+ val qualTpe =
1031+ findRef(name.toTypeName, WildcardType , EmptyFlags , EmptyFlags , qual.srcPos) match
1032+ case tpe : NamedType if tpe.symbol.isClass => tpe
1033+ case _ =>
1034+ val maybePackage = defn.RootPackage .info.member(name)
1035+ if maybePackage.exists then maybePackage.info else NoType
1036+ if qualTpe.exists then
1037+ javaSelection(assignType(cpy.Ident (qual)(name), qualTpe))
1038+ else
1039+ errorTree(tree, em " no class or package to resolve ` $name` " ) // just fail fallback
1040+ def tryQual (qual : untpd.Tree )(using Context ): Tree =
1041+ javaSelection(typedExpr(qual, shallowSelectionProto(tree.name, pt, this , tree.nameSpan)))
1042+ tree.qualifier match
1043+ case qual @ Ident (name) => tryAlternatively(tryQual(qual))(tryQualFallback(qual, name))
1044+ case qual => tryQual(qual)
10281045 else
1046+ val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
10291047 typedSelectWithAdapt(tree, pt, qual).withSpan(tree.span).computeNullable()
10301048
10311049 def javaSelection (qual : Tree )(using Context ) =
1032- val tree1 = assignType(cpy.Select (tree)(qual, tree.name), qual)
1033- tree1.tpe match
1034- case moduleRef : TypeRef if moduleRef.symbol.is(ModuleClass , butNot = JavaDefined ) =>
1035- // handle unmangling of module names (Foo$ -> Foo[ModuleClass])
1036- cpy.Select (tree)(qual, tree.name.unmangleClassName).withType(moduleRef)
1037- case _ =>
1038- tree1
1050+ qual match
1051+ case id @ Ident (name) if id.symbol.is(Package ) && ! id.symbol.owner.isRoot =>
1052+ val rooted = defn.RootPackage .info.member(name)
1053+ val qual1 = if rooted.exists then assignType(cpy.Ident (id)(name), rooted.info) else qual
1054+ assignType(cpy.Select (tree)(qual1, tree.name), qual1)
1055+ case _ =>
1056+ val tree1 = assignType(cpy.Select (tree)(qual, tree.name), qual)
1057+ tree1.tpe match
1058+ case moduleRef : TypeRef if moduleRef.symbol.is(ModuleClass , butNot = JavaDefined ) =>
1059+ // handle unmangling of module names (Foo$ -> Foo[ModuleClass])
1060+ cpy.Select (tree)(qual, tree.name.unmangleClassName).withType(moduleRef)
1061+ case _ =>
1062+ tree1
10391063
10401064 def tryJavaSelectOnType (using Context ): Tree = tree.qualifier match {
10411065 case sel @ Select (qual, name) =>
@@ -1052,17 +1076,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
10521076 errorTree(tree, em " cannot convert to type selection " ) // will never be printed due to fallback
10531077 }
10541078
1055- def selectWithFallback (fallBack : Context ?=> Tree ) =
1056- tryAlternatively(typeSelectOnTerm)(fallBack)
1057-
10581079 if (tree.qualifier.isType) {
10591080 val qual1 = typedType(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
10601081 assignType(cpy.Select (tree)(qual1, tree.name), qual1)
10611082 }
10621083 else if (ctx.isJava && tree.name.isTypeName)
1063- // SI- 3120 Java uses the same syntax, A.B, to express selection from the
1064- // value A and from the type A. We have to try both.
1065- selectWithFallback( tryJavaSelectOnType) // !!! possibly exponential bcs of qualifier retyping
1084+ // scala/bug# 3120 Java uses the same syntax, A.B, to express selection from the
1085+ // value A and from the type A. We have to try both. (possibly exponential bc of qualifier retyping)
1086+ tryAlternatively(typeSelectOnTerm)( tryJavaSelectOnType)
10661087 else
10671088 typeSelectOnTerm
10681089 }
0 commit comments