@@ -2375,7 +2375,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
23752375 Annotation (defn.RequiresCapabilityAnnot , cap, tree.span))))
23762376 else res
23772377
2378- def typedSeqLiteral (tree : untpd.SeqLiteral , pt : Type )(using Context ): SeqLiteral = {
2378+ def typedSeqLiteral (tree : untpd.SeqLiteral , pt : Type )(using Context ): Tree =
23792379 val elemProto = pt.stripNull().elemType match {
23802380 case NoType => WildcardType
23812381 case bounds : TypeBounds => WildcardType (bounds)
@@ -2385,25 +2385,78 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
23852385 def assign (elems1 : List [Tree ], elemtpt1 : Tree ) =
23862386 assignType(cpy.SeqLiteral (tree)(elems1, elemtpt1), elems1, elemtpt1)
23872387
2388- if (! tree.elemtpt.isEmpty) {
2388+ // Seq literal used in varargs: elem type is given
2389+ def varargSeqLiteral =
23892390 val elemtpt1 = typed(tree.elemtpt, elemProto)
23902391 val elems1 = tree.elems.mapconserve(typed(_, elemtpt1.tpe))
23912392 assign(elems1, elemtpt1)
2392- }
2393- else {
2394- assert(tree. isInstanceOf [ Trees . JavaSeqLiteral [ ? ]])
2393+
2394+ // Seq literal used in Java annotations: elem type needs to be computed
2395+ def javaSeqLiteral =
23952396 val elems1 = tree.elems.mapconserve(typed(_, elemProto))
23962397 val elemtptType =
2397- if ( isFullyDefined(elemProto, ForceDegree .none))
2398+ if isFullyDefined(elemProto, ForceDegree .none) then
23982399 elemProto
2399- else if ( tree.elems.isEmpty && tree. isInstanceOf [ Trees . JavaSeqLiteral [ ? ]])
2400+ else if tree.elems.isEmpty then
24002401 defn.ObjectType // generic empty Java varargs are of type Object[]
24012402 else
24022403 TypeComparer .lub(elems1.tpes)
24032404 val elemtpt1 = typed(tree.elemtpt, elemtptType)
24042405 assign(elems1, elemtpt1)
2405- }
2406- }
2406+
2407+ // Stand-alone collection literal [x1, ..., xN]
2408+ def collectionLiteral =
2409+ def isArrow (tree : untpd.Tree ) = tree match
2410+ case untpd.InfixOp (_, Ident (nme.PUREARROW ), _) => true
2411+ case _ => false
2412+
2413+ // The default maker if no typeclass is searched or found
2414+ def defaultMaker =
2415+ if tree.elems.nonEmpty && tree.elems.forall(isArrow)
2416+ then untpd.ref(defn.MapModule )
2417+ else untpd.ref(defn.SeqModule )
2418+
2419+ // We construct and typecheck a term `maker(tree.elems)`, where `maker`
2420+ // is either a given instance of type ExpressibleAsCollectionLiteralClass
2421+ // or a default instance. The default instance is either Seq or Map,
2422+ // depending on the forms of `tree.elems`. We search for a type class if
2423+ // the expected type is a value type that is not an uninstantiated type variable.
2424+ val maker = pt match
2425+ case pt : TypeVar if ! pt.isInstantiated =>
2426+ defaultMaker
2427+ case pt : ValueType =>
2428+ val tc = defn.ExpressibleAsCollectionLiteralClass .typeRef.appliedTo(pt)
2429+ val nestedCtx = ctx.fresh.setNewTyperState()
2430+ val maker = inContext(nestedCtx):
2431+ // Find given instance `witness` of type `ExpressibleAsCollectionLiteral[<pt>]`
2432+ val witness = inferImplicitArg(tc, tree.span.startPos)
2433+ if witness.tpe.isInstanceOf [SearchFailureType ] then
2434+ val msg = missingArgMsg(witness, pt, " " )
2435+ if isAmbiguousGiven(witness) then report.error(msg, tree.srcPos)
2436+ else typr.println(i " failed collection literal witness: ${msg.toString}" )
2437+ defaultMaker
2438+ else
2439+ // Instantiate local type variables in witness.tpe, so that nested
2440+ // SeqLiterals don't get typed as default Seq due to first case above
2441+ def isLocal (tv : TypeVar ) =
2442+ val state = tv.owningState
2443+ state != null && (state.get eq ctx.typerState)
2444+ instantiateSelected(witness.tpe, isLocal, minimize = false )
2445+ // Continue with typing `witness.fromLiteral` as the constructor
2446+ untpd.TypedSplice (witness.select(nme.fromLiteral))
2447+ nestedCtx.typerState.commit()
2448+ maker
2449+ case _ =>
2450+ defaultMaker
2451+ typed(
2452+ untpd.Apply (maker, tree.elems).withSpan(tree.span)
2453+ .showing(i " typed collection literal $tree ---> $result" , typr)
2454+ , pt)
2455+
2456+ if ! tree.elemtpt.isEmpty then varargSeqLiteral
2457+ else if tree.isInstanceOf [Trees .JavaSeqLiteral [? ]] then javaSeqLiteral
2458+ else collectionLiteral
2459+ end typedSeqLiteral
24072460
24082461 def typedInlined (tree : untpd.Inlined , pt : Type )(using Context ): Tree =
24092462 throw new UnsupportedOperationException (" cannot type check a Inlined node" )
0 commit comments