@@ -1779,6 +1779,8 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
17791779 bool isFunctionParam =
17801780 options.contains (TR_FunctionInput) ||
17811781 options.contains (TR_ImmediateFunctionInput);
1782+ bool isVariadicFunctionParam =
1783+ options.contains (TR_VariadicFunctionInput);
17821784
17831785 // The type we're working with, in case we want to build it differently
17841786 // based on the attributes we see.
@@ -1959,7 +1961,9 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
19591961 // @autoclosure is only valid on parameters.
19601962 if (!isFunctionParam && attrs.has (TAK_autoclosure)) {
19611963 TC.diagnose (attrs.getLoc (TAK_autoclosure),
1962- diag::attr_only_only_on_parameters, " @autoclosure" );
1964+ isVariadicFunctionParam
1965+ ? diag::attr_not_on_variadic_parameters
1966+ : diag::attr_only_on_parameters, " @autoclosure" );
19631967 attrs.clearAttribute (TAK_autoclosure);
19641968 }
19651969
@@ -2390,7 +2394,11 @@ Type TypeResolver::resolveInOutType(InOutTypeRepr *repr,
23902394 // inout is only valid for function parameters.
23912395 if (!(options & TR_FunctionInput) &&
23922396 !(options & TR_ImmediateFunctionInput)) {
2393- TC.diagnose (repr->getInOutLoc (), diag::inout_only_parameter);
2397+ TC.diagnose (repr->getInOutLoc (),
2398+ (options & TR_VariadicFunctionInput)
2399+ ? diag::attr_not_on_variadic_parameters
2400+ : diag::attr_only_on_parameters,
2401+ " 'inout'" );
23942402 repr->setInvalid ();
23952403 return ErrorType::get (Context);
23962404 }
@@ -2510,38 +2518,58 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
25102518 if (options & TR_ImmediateFunctionInput)
25112519 elementOptions |= TR_FunctionInput;
25122520 }
2513-
2521+
2522+ bool complained = false ;
2523+
2524+ // Variadic tuples are not permitted.
2525+ if (repr->hasEllipsis () &&
2526+ !(options & TR_ImmediateFunctionInput)) {
2527+ TC.diagnose (repr->getEllipsisLoc (), diag::tuple_ellipsis);
2528+ repr->removeEllipsis ();
2529+ complained = true ;
2530+ }
2531+
25142532 for (auto tyR : repr->getElements ()) {
25152533 NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR);
2516- if (namedTyR && !(options & TR_ImmediateFunctionInput)) {
2517- Type ty = resolveType (namedTyR-> getTypeRepr (), elementOptions) ;
2518- if (!ty || ty-> is <ErrorType>()) return ty ;
2534+ Type ty;
2535+ Identifier name ;
2536+ bool variadic = false ;
25192537
2520- elements. push_back ( TupleTypeElt (ty, namedTyR-> getName ()));
2521- } else {
2538+ // If the element has a label, stash the label and get the underlying type.
2539+ if (namedTyR) {
25222540 // FIXME: Preserve and serialize parameter names in function types, maybe
25232541 // with a new sugar type.
2524- Type ty = resolveType (namedTyR ? namedTyR->getTypeRepr () : tyR,
2525- elementOptions);
2526- if (!ty || ty->is <ErrorType>()) return ty;
2542+ if (!(options & TR_ImmediateFunctionInput))
2543+ name = namedTyR->getName ();
25272544
2528- elements. push_back ( TupleTypeElt (ty) );
2545+ tyR = namedTyR-> getTypeRepr ( );
25292546 }
2530- }
25312547
2532- // Tuple representations are limited outside of function inputs.
2533- if (!(options & TR_ImmediateFunctionInput)) {
2534- bool complained = false ;
2548+ // If the element is a variadic parameter, resolve the parameter type as if
2549+ // it were in non-parameter position, since we want functions to be
2550+ // @escaping in this case.
2551+ auto thisElementOptions = elementOptions;
2552+ if (repr->hasEllipsis () &&
2553+ elements.size () == repr->getEllipsisIndex ()) {
2554+ thisElementOptions = withoutContext (elementOptions);
2555+ thisElementOptions |= TR_VariadicFunctionInput;
2556+ variadic = true ;
2557+ }
2558+
2559+ ty = resolveType (tyR, thisElementOptions);
2560+ if (!ty || ty->is <ErrorType>()) return ty;
2561+
2562+ // If the element is a variadic parameter, the underlying type is actually
2563+ // an ArraySlice of the element type.
2564+ if (variadic)
2565+ ty = TC.getArraySliceType (repr->getEllipsisLoc (), ty);
25352566
2536- // Variadic tuples are not permitted.
2537- if (repr->hasEllipsis ()) {
2538- TC.diagnose (repr->getEllipsisLoc (), diag::tuple_ellipsis);
2539- repr->removeEllipsis ();
2540- complained = true ;
2541- }
2567+ elements.push_back (TupleTypeElt (ty, name, variadic));
2568+ }
25422569
2543- // Single-element labeled tuples are not permitted outside of declarations
2544- // or SIL, either.
2570+ // Single-element labeled tuples are not permitted outside of declarations
2571+ // or SIL, either.
2572+ if (!(options & TR_ImmediateFunctionInput)) {
25452573 if (elements.size () == 1 && elements[0 ].hasName ()
25462574 && !(options & TR_SILType)
25472575 && !(options & TR_EnumCase)) {
@@ -2557,14 +2585,6 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
25572585 }
25582586 }
25592587
2560- if (repr->hasEllipsis ()) {
2561- auto &element = elements[repr->getEllipsisIndex ()];
2562- Type baseTy = element.getType ();
2563- Type fullTy = TC.getArraySliceType (repr->getEllipsisLoc (), baseTy);
2564- Identifier name = element.getName ();
2565- element = TupleTypeElt (fullTy, name, true );
2566- }
2567-
25682588 return TupleType::get (elements, Context);
25692589}
25702590
0 commit comments