Skip to content

Commit fdbe018

Browse files
authored
Merge pull request #17279 from CodaFi/parametric-monomorphism
[NFC] Separate FunctionTypeRepr Input Resolution
2 parents b4d3a98 + e60bbd4 commit fdbe018

File tree

3 files changed

+124
-141
lines changed

3 files changed

+124
-141
lines changed

lib/Sema/TypeCheckPattern.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -960,12 +960,7 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc,
960960
bool hadError = false;
961961
SmallVector<TupleTypeElt, 8> typeElts;
962962

963-
// If this is the top level of a function input list, peel off the
964-
// ImmediateFunctionInput marker and install a FunctionInput one instead.
965-
auto elementOptions = withoutContext(options);
966-
if (options & TypeResolutionFlags::ImmediateFunctionInput)
967-
elementOptions |= TypeResolutionFlags::FunctionInput;
968-
963+
const auto elementOptions = withoutContext(options);
969964
bool missingType = false;
970965
for (unsigned i = 0, e = tuplePat->getNumElements(); i != e; ++i) {
971966
TuplePatternElt &elt = tuplePat->getElement(i);

lib/Sema/TypeCheckType.cpp

Lines changed: 97 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,6 @@ Type TypeChecker::resolveTypeInContext(
367367
static TypeResolutionOptions
368368
adjustOptionsForGenericArgs(TypeResolutionOptions options) {
369369
options -= TypeResolutionFlags::SILType;
370-
options -= TypeResolutionFlags::ImmediateFunctionInput;
371370
options -= TypeResolutionFlags::FunctionInput;
372371
options -= TypeResolutionFlags::TypeAliasUnderlyingType;
373372
options -= TypeResolutionFlags::AllowUnavailableProtocol;
@@ -1416,8 +1415,7 @@ static Type applyNonEscapingFromContext(DeclContext *DC,
14161415
// Remember whether this is a function parameter.
14171416
bool defaultNoEscape =
14181417
!options.contains(TypeResolutionFlags::EnumCase) &&
1419-
(options.contains(TypeResolutionFlags::FunctionInput) ||
1420-
options.contains(TypeResolutionFlags::ImmediateFunctionInput));
1418+
options.contains(TypeResolutionFlags::FunctionInput);
14211419

14221420
// Desugar here
14231421
auto *funcTy = ty->castTo<FunctionType>();
@@ -1553,6 +1551,12 @@ namespace {
15531551
TypeResolutionOptions options,
15541552
FunctionType::ExtInfo extInfo
15551553
= FunctionType::ExtInfo());
1554+
bool
1555+
resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
1556+
TypeResolutionOptions options,
1557+
bool requiresMappingOut,
1558+
SmallVectorImpl<AnyFunctionType::Param> &ps);
1559+
15561560
Type resolveSILFunctionType(FunctionTypeRepr *repr,
15571561
TypeResolutionOptions options,
15581562
SILCoroutineKind coroutineKind
@@ -1636,7 +1640,6 @@ Type TypeResolver::resolveType(TypeRepr *repr, TypeResolutionOptions options) {
16361640
if (!isa<SpecifierTypeRepr>(repr) && !isa<TupleTypeRepr>(repr) &&
16371641
!isa<AttributedTypeRepr>(repr) && !isa<FunctionTypeRepr>(repr) &&
16381642
!isa<IdentTypeRepr>(repr)) {
1639-
options -= TypeResolutionFlags::ImmediateFunctionInput;
16401643
options -= TypeResolutionFlags::FunctionInput;
16411644
options -= TypeResolutionFlags::TypeAliasUnderlyingType;
16421645
}
@@ -1741,8 +1744,7 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
17411744
};
17421745

17431746
// Remember whether this is a function parameter.
1744-
bool isParam = options.contains(TypeResolutionFlags::FunctionInput) ||
1745-
options.contains(TypeResolutionFlags::ImmediateFunctionInput);
1747+
bool isParam = options.contains(TypeResolutionFlags::FunctionInput);
17461748

17471749
bool isVariadicFunctionParam =
17481750
!options.contains(TypeResolutionFlags::EnumCase) &&
@@ -1772,7 +1774,6 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
17721774
// The instance type is not a SIL type.
17731775
auto instanceOptions = options;
17741776
instanceOptions -= TypeResolutionFlags::SILType;
1775-
instanceOptions -= TypeResolutionFlags::ImmediateFunctionInput;
17761777
instanceOptions -= TypeResolutionFlags::FunctionInput;
17771778
instanceOptions -= TypeResolutionFlags::TypeAliasUnderlyingType;
17781779

@@ -1989,7 +1990,6 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
19891990
}
19901991

19911992
auto instanceOptions = options;
1992-
instanceOptions -= TypeResolutionFlags::ImmediateFunctionInput;
19931993
instanceOptions -= TypeResolutionFlags::FunctionInput;
19941994
instanceOptions -= TypeResolutionFlags::TypeAliasUnderlyingType;
19951995

@@ -2114,17 +2114,78 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
21142114
return ty;
21152115
}
21162116

2117+
bool TypeResolver::resolveASTFunctionTypeParams(
2118+
TupleTypeRepr *inputRepr, TypeResolutionOptions options,
2119+
bool requiresMappingOut,
2120+
SmallVectorImpl<AnyFunctionType::Param> &elements) {
2121+
elements.reserve(inputRepr->getNumElements());
2122+
2123+
const auto elementOptions = withoutContext(options, true)
2124+
| TypeResolutionFlags::FunctionInput;
2125+
for (unsigned i = 0, end = inputRepr->getNumElements(); i != end; ++i) {
2126+
auto *eltTypeRepr = inputRepr->getElementType(i);
2127+
2128+
// If the element is a variadic parameter, resolve the parameter type as if
2129+
// it were in non-parameter position, since we want functions to be
2130+
// @escaping in this case.
2131+
auto thisElementOptions = elementOptions;
2132+
bool variadic = false;
2133+
if (inputRepr->hasEllipsis() &&
2134+
elements.size() == inputRepr->getEllipsisIndex()) {
2135+
thisElementOptions = withoutContext(elementOptions);
2136+
thisElementOptions |= TypeResolutionFlags::VariadicFunctionInput;
2137+
variadic = true;
2138+
}
2139+
2140+
Type ty = resolveType(eltTypeRepr, thisElementOptions);
2141+
if (!ty) return true;
2142+
2143+
if (ty->hasError()) {
2144+
elements.emplace_back(ErrorType::get(Context), Identifier(),
2145+
ParameterTypeFlags());
2146+
continue;
2147+
}
2148+
2149+
// Parameters of polymorphic functions speak in terms of interface types.
2150+
if (requiresMappingOut) {
2151+
ty = ty->mapTypeOutOfContext();
2152+
}
2153+
2154+
ValueOwnership ownership;
2155+
switch (eltTypeRepr->getKind()) {
2156+
case TypeReprKind::Shared:
2157+
ownership = ValueOwnership::Shared;
2158+
break;
2159+
case TypeReprKind::InOut:
2160+
ownership = ValueOwnership::InOut;
2161+
break;
2162+
case TypeReprKind::Owned:
2163+
ownership = ValueOwnership::Owned;
2164+
break;
2165+
default:
2166+
ownership = ValueOwnership::Default;
2167+
break;
2168+
}
2169+
ParameterTypeFlags paramFlags =
2170+
ParameterTypeFlags::fromParameterType(ty, variadic, ownership);
2171+
elements.emplace_back(ty->getInOutObjectType(), Identifier(), paramFlags);
2172+
}
2173+
2174+
return false;
2175+
}
2176+
21172177
Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr,
21182178
TypeResolutionOptions options,
21192179
FunctionType::ExtInfo extInfo) {
2120-
options -= TypeResolutionFlags::ImmediateFunctionInput;
21212180
options -= TypeResolutionFlags::FunctionInput;
21222181
options -= TypeResolutionFlags::TypeAliasUnderlyingType;
21232182
options -= TypeResolutionFlags::AllowIUO;
21242183

2125-
Type inputTy = resolveType(repr->getArgsTypeRepr(),
2126-
options | TypeResolutionFlags::ImmediateFunctionInput);
2127-
if (!inputTy || inputTy->hasError()) return inputTy;
2184+
SmallVector<AnyFunctionType::Param, 8> params;
2185+
if (resolveASTFunctionTypeParams(repr->getArgsTypeRepr(), options,
2186+
repr->getGenericEnvironment() != nullptr, params)) {
2187+
return Type();
2188+
}
21282189

21292190
Type outputTy = resolveType(repr->getResultTypeRepr(), options);
21302191
if (!outputTy || outputTy->hasError()) return outputTy;
@@ -2152,13 +2213,12 @@ Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr,
21522213

21532214
// SIL uses polymorphic function types to resolve overloaded member functions.
21542215
if (auto genericEnv = repr->getGenericEnvironment()) {
2155-
inputTy = inputTy->mapTypeOutOfContext();
21562216
outputTy = outputTy->mapTypeOutOfContext();
21572217
return GenericFunctionType::get(genericEnv->getGenericSignature(),
2158-
inputTy, outputTy, extInfo);
2218+
params, outputTy, extInfo);
21592219
}
21602220

2161-
auto fnTy = FunctionType::get(inputTy, outputTy, extInfo);
2221+
auto fnTy = FunctionType::get(params, outputTy, extInfo);
21622222
// If the type is a block or C function pointer, it must be representable in
21632223
// ObjC.
21642224
switch (auto rep = extInfo.getRepresentation()) {
@@ -2169,7 +2229,7 @@ Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr,
21692229
rep == AnyFunctionType::Representation::Block ? "block" : "c";
21702230
auto extInfo2 =
21712231
extInfo.withRepresentation(AnyFunctionType::Representation::Swift);
2172-
auto simpleFnTy = FunctionType::get(inputTy, outputTy, extInfo2);
2232+
auto simpleFnTy = FunctionType::get(params, outputTy, extInfo2);
21732233
TC.diagnose(repr->getStartLoc(), diag::objc_convention_invalid,
21742234
simpleFnTy, strName);
21752235
}
@@ -2266,7 +2326,6 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr,
22662326
SILFunctionType::ExtInfo extInfo,
22672327
ParameterConvention callee,
22682328
TypeRepr *witnessMethodProtocol) {
2269-
options -= TypeResolutionFlags::ImmediateFunctionInput;
22702329
options -= TypeResolutionFlags::FunctionInput;
22712330
options -= TypeResolutionFlags::TypeAliasUnderlyingType;
22722331

@@ -2305,7 +2364,7 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr,
23052364

23062365
for (auto elt : argsTuple->getElements()) {
23072366
auto param = resolveSILParameter(elt.Type,
2308-
options | TypeResolutionFlags::ImmediateFunctionInput);
2367+
options | TypeResolutionFlags::FunctionInput);
23092368
params.push_back(param);
23102369
if (!param.getType()) return nullptr;
23112370

@@ -2409,17 +2468,16 @@ SILYieldInfo TypeResolver::resolveSILYield(TypeAttributes &attrs,
24092468
TypeResolutionOptions options) {
24102469
AttributedTypeRepr attrRepr(attrs, repr);
24112470
SILParameterInfo paramInfo =
2412-
resolveSILParameter(&attrRepr, options |
2413-
TypeResolutionFlags::ImmediateFunctionInput);
2471+
resolveSILParameter(&attrRepr,
2472+
options | TypeResolutionFlags::FunctionInput);
24142473
return SILYieldInfo(paramInfo.getType(), paramInfo.getConvention());
24152474
}
24162475

24172476
SILParameterInfo TypeResolver::resolveSILParameter(
24182477
TypeRepr *repr,
24192478
TypeResolutionOptions options) {
2420-
assert((options & TypeResolutionFlags::FunctionInput)
2421-
| (options & TypeResolutionFlags::ImmediateFunctionInput) &&
2422-
"Parameters should be marked as inputs");
2479+
assert(options.contains(TypeResolutionFlags::FunctionInput)
2480+
&& "Parameters should be marked as inputs");
24232481
auto convention = DefaultParameterConvention;
24242482
Type type;
24252483
bool hadError = false;
@@ -2587,8 +2645,7 @@ Type TypeResolver::resolveSpecifierTypeRepr(SpecifierTypeRepr *repr,
25872645
// function parameters.
25882646
if ((options & TypeResolutionFlags::SubscriptParameters) ||
25892647
(options & TypeResolutionFlags::EnumCase) ||
2590-
(!(options & TypeResolutionFlags::FunctionInput) &&
2591-
!(options & TypeResolutionFlags::ImmediateFunctionInput))) {
2648+
(!(options & TypeResolutionFlags::FunctionInput))) {
25922649

25932650
decltype(diag::attr_only_on_parameters) diagID;
25942651
if (options & TypeResolutionFlags::SubscriptParameters) {
@@ -2618,7 +2675,6 @@ Type TypeResolver::resolveSpecifierTypeRepr(SpecifierTypeRepr *repr,
26182675
}
26192676

26202677
// Anything within the inout isn't a parameter anymore.
2621-
options -= TypeResolutionFlags::ImmediateFunctionInput;
26222678
options -= TypeResolutionFlags::FunctionInput;
26232679
options -= TypeResolutionFlags::TypeAliasUnderlyingType;
26242680

@@ -2742,112 +2798,48 @@ Type TypeResolver::resolveImplicitlyUnwrappedOptionalType(
27422798

27432799
Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
27442800
TypeResolutionOptions options) {
2745-
bool isImmediateFunctionInput = options.contains(
2746-
TypeResolutionFlags::ImmediateFunctionInput);
27472801
SmallVector<TupleTypeElt, 8> elements;
27482802
elements.reserve(repr->getNumElements());
27492803

2750-
// If this is the top level of a function input list, peel off the
2751-
// ImmediateFunctionInput marker and install a FunctionInput one instead.
2804+
27522805
auto elementOptions = options;
27532806
if (repr->isParenType()) {
27542807
// We also want to disallow IUO within even a paren.
27552808
elementOptions -= TypeResolutionFlags::AllowIUO;
2756-
2757-
// If we have a single ParenType, don't clear the context bits; we
2758-
// still want to parse the type contained therein as if it were in
2759-
// parameter position, meaning function types are not @escaping by
2760-
// default. We still want to reduce `ImmediateFunctionInput` to
2761-
// `FunctionInput` so that e.g. ((foo: Int)) -> Int is considered a
2762-
// tuple argument rather than a labeled Int argument.
2763-
if (isImmediateFunctionInput) {
2764-
elementOptions = withoutContext(elementOptions, true);
2765-
elementOptions |= TypeResolutionFlags::FunctionInput;
2766-
}
27672809
} else {
27682810
elementOptions = withoutContext(elementOptions, true);
2769-
if (isImmediateFunctionInput)
2770-
elementOptions |= TypeResolutionFlags::FunctionInput;
27712811
}
27722812

2773-
bool complained = false;
2774-
27752813
// Variadic tuples are not permitted.
2776-
if (repr->hasEllipsis() &&
2777-
!isImmediateFunctionInput) {
2814+
bool complained = false;
2815+
if (repr->hasEllipsis()) {
27782816
TC.diagnose(repr->getEllipsisLoc(), diag::tuple_ellipsis);
27792817
repr->removeEllipsis();
27802818
complained = true;
27812819
}
27822820

27832821
for (unsigned i = 0, end = repr->getNumElements(); i != end; ++i) {
27842822
auto *tyR = repr->getElementType(i);
2785-
Type ty;
2786-
Identifier name;
2787-
bool variadic = false;
27882823

2789-
// If the element has a label, stash the label.
2790-
// FIXME: Preserve and serialize parameter names in function types, maybe
2791-
// with a new sugar type.
2792-
if (!isImmediateFunctionInput)
2793-
name = repr->getElementName(i);
2794-
2795-
// If the element is a variadic parameter, resolve the parameter type as if
2796-
// it were in non-parameter position, since we want functions to be
2797-
// @escaping in this case.
2798-
auto thisElementOptions = elementOptions;
2799-
if (repr->hasEllipsis() &&
2800-
elements.size() == repr->getEllipsisIndex()) {
2801-
thisElementOptions = withoutContext(elementOptions);
2802-
thisElementOptions |= TypeResolutionFlags::VariadicFunctionInput;
2803-
variadic = true;
2804-
}
2805-
2806-
ty = resolveType(tyR, thisElementOptions);
2824+
Type ty = resolveType(tyR, elementOptions);
28072825
if (!ty || ty->hasError()) return ty;
28082826

2809-
// If the element is a variadic parameter, the underlying type is actually
2810-
// an ArraySlice of the element type.
2811-
if (variadic)
2812-
ty = TC.getArraySliceType(repr->getEllipsisLoc(), ty);
2813-
2814-
ParameterTypeFlags paramFlags;
2815-
if (isImmediateFunctionInput) {
2816-
ValueOwnership ownership;
2817-
switch (tyR->getKind()) {
2818-
case TypeReprKind::Shared:
2819-
ownership = ValueOwnership::Shared;
2820-
break;
2821-
case TypeReprKind::InOut:
2822-
ownership = ValueOwnership::InOut;
2823-
break;
2824-
case TypeReprKind::Owned:
2825-
ownership = ValueOwnership::Owned;
2826-
break;
2827-
default:
2828-
ownership = ValueOwnership::Default;
2829-
break;
2830-
}
2831-
paramFlags =
2832-
ParameterTypeFlags::fromParameterType(ty, variadic, ownership);
2833-
}
2834-
elements.emplace_back(ty->getInOutObjectType(), name, paramFlags);
2827+
elements.emplace_back(ty->getInOutObjectType(),
2828+
repr->getElementName(i), ParameterTypeFlags());
28352829
}
28362830

28372831
// Single-element labeled tuples are not permitted outside of declarations
28382832
// or SIL, either.
2839-
if (!isImmediateFunctionInput) {
2840-
if (elements.size() == 1 && elements[0].hasName()
2841-
&& !(options & TypeResolutionFlags::SILType)) {
2842-
if (!complained) {
2843-
TC.diagnose(repr->getElementNameLoc(0),
2844-
diag::tuple_single_element)
2845-
.fixItRemoveChars(repr->getElementNameLoc(0),
2846-
repr->getElementType(0)->getStartLoc());
2847-
}
2848-
2849-
elements[0] = TupleTypeElt(elements[0].getType());
2833+
if (elements.size() == 1 && elements[0].hasName()
2834+
&& !(options & TypeResolutionFlags::SILType)) {
2835+
if (!complained) {
2836+
TC.diagnose(repr->getElementNameLoc(0),
2837+
diag::tuple_single_element)
2838+
.fixItRemoveChars(repr->getElementNameLoc(0),
2839+
repr->getElementType(0)->getStartLoc());
28502840
}
2841+
2842+
elements[0] = TupleTypeElt(elements[0].getType());
28512843
}
28522844

28532845
return TupleType::get(elements, Context);

0 commit comments

Comments
 (0)