@@ -1022,20 +1022,44 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1022
1022
record(" typedSelect" )
1023
1023
1024
1024
def typeSelectOnTerm (using Context ): Tree =
1025
- val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
1026
1025
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)
1028
1045
else
1046
+ val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
1029
1047
typedSelectWithAdapt(tree, pt, qual).withSpan(tree.span).computeNullable()
1030
1048
1031
1049
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
1039
1063
1040
1064
def tryJavaSelectOnType (using Context ): Tree = tree.qualifier match {
1041
1065
case sel @ Select (qual, name) =>
@@ -1052,17 +1076,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1052
1076
errorTree(tree, em " cannot convert to type selection " ) // will never be printed due to fallback
1053
1077
}
1054
1078
1055
- def selectWithFallback (fallBack : Context ?=> Tree ) =
1056
- tryAlternatively(typeSelectOnTerm)(fallBack)
1057
-
1058
1079
if (tree.qualifier.isType) {
1059
1080
val qual1 = typedType(tree.qualifier, shallowSelectionProto(tree.name, pt, this , tree.nameSpan))
1060
1081
assignType(cpy.Select (tree)(qual1, tree.name), qual1)
1061
1082
}
1062
1083
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)
1066
1087
else
1067
1088
typeSelectOnTerm
1068
1089
}
0 commit comments