@@ -8,7 +8,7 @@ import Symbols.*, StdNames.*, Trees.*, ContextOps.*
88import Decorators .*
99import Annotations .Annotation
1010import NameKinds .{UniqueName , ContextBoundParamName , ContextFunctionParamName , DefaultGetterName , WildcardParamName }
11- import typer .{Namer , Checking }
11+ import typer .{Namer , Checking , ErrorReporting }
1212import util .{Property , SourceFile , SourcePosition , SrcPos , Chars }
1313import config .{Feature , Config }
1414import config .Feature .{sourceVersion , migrateTo3 , enabled , betterForsEnabled }
@@ -199,9 +199,10 @@ object desugar {
199199 def valDef (vdef0 : ValDef )(using Context ): Tree =
200200 val vdef @ ValDef (_, tpt, rhs) = vdef0
201201 val valName = normalizeName(vdef, tpt).asTermName
202+ val tpt1 = qualifiedType(tpt, valName)
202203 var mods1 = vdef.mods
203204
204- val vdef1 = cpy.ValDef (vdef)(name = valName).withMods(mods1)
205+ val vdef1 = cpy.ValDef (vdef)(name = valName, tpt = tpt1 ).withMods(mods1)
205206
206207 if isSetterNeeded(vdef) then
207208 val setterParam = makeSyntheticParameter(tpt = SetterParamTree ().watching(vdef))
@@ -2158,6 +2159,10 @@ object desugar {
21582159 case PatDef (mods, pats, tpt, rhs) =>
21592160 val pats1 = if (tpt.isEmpty) pats else pats map (Typed (_, tpt))
21602161 flatTree(pats1 map (makePatDef(tree, mods, _, rhs)))
2162+ case QualifiedTypeTree (parent, None , qualifier) =>
2163+ ErrorReporting .errorTree(parent, em " missing parameter name in qualified type " , tree.srcPos)
2164+ case QualifiedTypeTree (parent, Some (paramName), qualifier) =>
2165+ qualifiedType(parent, paramName, qualifier, tree.span)
21612166 case ext : ExtMethods =>
21622167 Block (List (ext), syntheticUnitLiteral.withSpan(ext.span))
21632168 case f : FunctionWithMods if f.hasErasedParams => makeFunctionWithValDefs(f, pt)
@@ -2336,4 +2341,23 @@ object desugar {
23362341 collect(tree)
23372342 buf.toList
23382343 }
2344+
2345+ /** If `tree` is a `QualifiedTypeTree`, then desugars it using `paramName` as
2346+ * the qualified parameter name. Otherwise, returns `tree` unchanged.
2347+ */
2348+ def qualifiedType (tree : Tree , paramName : TermName )(using Context ): Tree = tree match
2349+ case QualifiedTypeTree (parent, None , qualifier) => qualifiedType(parent, paramName, qualifier, tree.span)
2350+ case _ => tree
2351+
2352+ /** Returns the annotated type used to represent the qualified type with the
2353+ * given components:
2354+ * `parent @qualified[parent]((paramName: parent) => qualifier)`.
2355+ */
2356+ def qualifiedType (parent : Tree , paramName : TermName , qualifier : Tree , span : Span )(using Context ): Tree =
2357+ val param = makeParameter(paramName, parent, EmptyModifiers ) // paramName: parent
2358+ val predicate = WildcardFunction (List (param), qualifier) // (paramName: parent) => qualifier
2359+ val qualifiedAnnot = scalaAnnotationDot(nme.qualified)
2360+ val annot = Apply (TypeApply (qualifiedAnnot, List (parent)), predicate).withSpan(span) // @qualified[parent](predicate)
2361+ Annotated (parent, annot).withSpan(span) // parent @qualified[parent](predicate)
2362+
23392363}
0 commit comments