Skip to content

Commit baa7cbd

Browse files
authored
Merge pull request #18036 from slavapestov/remove-third-pass
Remove third pass when validating generic function parameter lists
2 parents 5828a98 + b181b93 commit baa7cbd

10 files changed

+173
-310
lines changed

lib/AST/Decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5402,8 +5402,8 @@ bool EnumElementDecl::computeType() {
54025402

54035403
// The type of the enum element is either (T) -> T or (T) -> ArgType -> T.
54045404
if (auto *PL = getParameterList()) {
5405-
auto paramTy = PL->getType(getASTContext());
5406-
resultTy = FunctionType::get(paramTy->mapTypeOutOfContext(), resultTy);
5405+
auto paramTy = PL->getInterfaceType(getASTContext());
5406+
resultTy = FunctionType::get(paramTy, resultTy);
54075407
}
54085408

54095409
if (auto *genericSig = ED->getGenericSignatureOfContext())

lib/Sema/GenericTypeResolver.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,6 @@ class GenericTypeResolver {
5757
/// Determine whether the given types are equivalent within the generic
5858
/// context.
5959
virtual bool areSameType(Type type1, Type type2) = 0;
60-
61-
/// Set the contextual type or the interface type of the parameter.
62-
virtual void recordParamType(ParamDecl *decl, Type ty) = 0;
6360
};
6461

6562
/// Generic type resolver that leaves all generic types dependent.
@@ -78,8 +75,6 @@ class DependentGenericTypeResolver : public GenericTypeResolver {
7875
ComponentIdentTypeRepr *ref);
7976

8077
virtual bool areSameType(Type type1, Type type2);
81-
82-
virtual void recordParamType(ParamDecl *decl, Type ty);
8378
};
8479

8580
/// Generic type resolver that maps a generic type parameter type to its
@@ -106,8 +101,6 @@ class GenericTypeToArchetypeResolver : public GenericTypeResolver {
106101
ComponentIdentTypeRepr *ref);
107102

108103
virtual bool areSameType(Type type1, Type type2);
109-
110-
virtual void recordParamType(ParamDecl *decl, Type ty);
111104
};
112105

113106
/// Generic type resolver that only handles what can appear in a protocol
@@ -126,8 +119,6 @@ class ProtocolRequirementTypeResolver : public GenericTypeResolver {
126119
ComponentIdentTypeRepr *ref);
127120

128121
virtual bool areSameType(Type type1, Type type2);
129-
130-
virtual void recordParamType(ParamDecl *decl, Type ty);
131122
};
132123

133124
/// Generic type resolver that performs complete resolution of dependent
@@ -140,7 +131,7 @@ class ProtocolRequirementTypeResolver : public GenericTypeResolver {
140131
class CompleteGenericTypeResolver : public GenericTypeResolver {
141132
TypeChecker &tc;
142133
GenericSignature *genericSig;
143-
GenericSignatureBuilder &builder;
134+
GenericSignatureBuilder *builder;
144135

145136
public:
146137
CompleteGenericTypeResolver(TypeChecker &tc, GenericSignature *genericSig);
@@ -155,8 +146,6 @@ class CompleteGenericTypeResolver : public GenericTypeResolver {
155146
ComponentIdentTypeRepr *ref);
156147

157148
virtual bool areSameType(Type type1, Type type2);
158-
159-
virtual void recordParamType(ParamDecl *decl, Type ty);
160149
};
161150

162151
} // end namespace swift

lib/Sema/TypeCheckDecl.cpp

Lines changed: 44 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,20 +1195,31 @@ static void configureImplicitSelf(TypeChecker &tc,
11951195
selfDecl->setSpecifier(specifier);
11961196

11971197
selfDecl->setInterfaceType(selfParam.getPlainType());
1198+
1199+
if (selfParam.getPlainType()->is<ErrorType>())
1200+
selfDecl->setInvalid();
11981201
}
11991202

1200-
/// Record the context type of 'self' after the generic environment of
1201-
/// the function has been determined.
1202-
static void recordSelfContextType(AbstractFunctionDecl *func) {
1203-
auto selfDecl = func->getImplicitSelfDecl();
1204-
auto selfParam = computeSelfParam(func, /*isInitializingCtor*/true,
1205-
/*wantDynamicSelf*/true);
1203+
static void recordParamContextTypes(AbstractFunctionDecl *func) {
1204+
auto *env = func->getGenericEnvironment();
1205+
for (auto paramList : func->getParameterLists()) {
1206+
for (auto param : *paramList) {
1207+
if (!env)
1208+
param->setType(param->getInterfaceType());
1209+
else
1210+
param->setType(env->mapTypeIntoContext(param->getInterfaceType()));
1211+
}
1212+
}
1213+
}
12061214

1207-
auto selfTy = func->mapTypeIntoContext(selfParam.getType());
1208-
if (selfParam.getParameterFlags().isInOut()) {
1209-
selfDecl->setSpecifier(VarDecl::Specifier::InOut);
1215+
static void recordIndexContextTypes(SubscriptDecl *subscript) {
1216+
auto *env = subscript->getGenericEnvironment();
1217+
for (auto param : *subscript->getIndices()) {
1218+
if (!env)
1219+
param->setType(param->getInterfaceType());
1220+
else
1221+
param->setType(env->mapTypeIntoContext(param->getInterfaceType()));
12101222
}
1211-
selfDecl->setType(selfTy->getInOutObjectType());
12121223
}
12131224

12141225
/// If we need to infer 'dynamic', do so now.
@@ -4105,7 +4116,7 @@ void TypeChecker::validateDecl(ValueDecl *D) {
41054116
auto accessorParam = valueParams->get(valueParams->size() - e + i);
41064117
accessorParam->setType(paramTy);
41074118
accessorParam->setInterfaceType(paramIfaceTy);
4108-
accessorParam->getTypeLoc().setType(paramTy);
4119+
accessorParam->getTypeLoc().setType(paramIfaceTy);
41094120
}
41104121
}
41114122

@@ -4155,64 +4166,21 @@ void TypeChecker::validateDecl(ValueDecl *D) {
41554166
configureImplicitSelf(*this, FD);
41564167

41574168
// If we have generic parameters, check the generic signature now.
4158-
if (auto gp = FD->getGenericParams()) {
4159-
gp->setOuterParameters(FD->getDeclContext()->getGenericParamsOfContext());
4160-
4161-
auto *sig = validateGenericFuncSignature(FD);
4169+
if (FD->getGenericParams() || !isa<AccessorDecl>(FD)) {
4170+
validateGenericFuncSignature(FD);
4171+
recordParamContextTypes(FD);
4172+
} else {
4173+
// We've inherited all of the type information already.
4174+
configureInterfaceType(FD,
4175+
FD->getDeclContext()->getGenericSignatureOfContext());
41624176

4163-
GenericEnvironment *env;
4164-
if (auto AD = dyn_cast<AccessorDecl>(FD)) {
4165-
env = cast<SubscriptDecl>(AD->getStorage())->getGenericEnvironment();
4166-
assert(env && "accessor has generics but subscript is not generic");
4167-
} else {
4168-
env = sig->createGenericEnvironment();
4169-
}
4170-
FD->setGenericEnvironment(env);
4171-
4172-
// Revert the types within the signature so it can be type-checked with
4173-
// archetypes below.
4174-
revertGenericFuncSignature(FD);
4175-
} else if (auto genericSig =
4176-
FD->getDeclContext()->getGenericSignatureOfContext()) {
4177-
if (!isa<AccessorDecl>(FD)) {
4178-
(void)validateGenericFuncSignature(FD);
4179-
4180-
// Revert all of the types within the signature of the function.
4181-
revertGenericFuncSignature(FD);
4182-
} else {
4183-
// We've inherited all of the type information already.
4184-
configureInterfaceType(FD, genericSig);
4177+
if (FD->getInterfaceType()->hasError()) {
4178+
FD->setInterfaceType(ErrorType::get(Context));
4179+
FD->setInvalid();
41854180
}
41864181

41874182
FD->setGenericEnvironment(
4188-
FD->getDeclContext()->getGenericEnvironmentOfContext());
4189-
}
4190-
4191-
// Set the context type of 'self'.
4192-
if (FD->getDeclContext()->isTypeContext())
4193-
recordSelfContextType(FD);
4194-
4195-
// Type check the parameters and return type again, now with archetypes.
4196-
GenericTypeToArchetypeResolver resolver(FD);
4197-
4198-
bool badType = false;
4199-
if (!FD->getBodyResultTypeLoc().isNull()) {
4200-
TypeResolutionOptions options = TypeResolutionFlags::AllowIUO;
4201-
if (FD->hasDynamicSelf())
4202-
options |= TypeResolutionFlags::DynamicSelfResult;
4203-
4204-
if (validateType(FD->getBodyResultTypeLoc(), FD, options,
4205-
&resolver)) {
4206-
badType = true;
4207-
}
4208-
}
4209-
4210-
badType |= typeCheckParameterLists(FD, resolver);
4211-
4212-
if (badType) {
4213-
FD->setInterfaceType(ErrorType::get(Context));
4214-
FD->setInvalid();
4215-
break;
4183+
FD->getDeclContext()->getGenericEnvironmentOfContext());
42164184
}
42174185

42184186
if (!isa<AccessorDecl>(FD) || cast<AccessorDecl>(FD)->isGetter()) {
@@ -4224,9 +4192,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
42244192
}
42254193
}
42264194

4227-
if (!FD->getGenericSignatureOfContext())
4228-
configureInterfaceType(FD, FD->getGenericSignature());
4229-
42304195
// We want the function to be available for name lookup as soon
42314196
// as it has a valid interface type.
42324197
FD->setSignatureIsValidated();
@@ -4258,9 +4223,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
42584223
// had an @objc or @iboutlet property.
42594224

42604225
AbstractStorageDecl *storage = accessor->getStorage();
4261-
// Validate the subscript or property because it might not be type
4262-
// checked yet.
4263-
validateDecl(storage);
42644226

42654227
if (storage->getAttrs().hasAttribute<NonObjCAttr>())
42664228
isObjC = None;
@@ -4383,40 +4345,8 @@ void TypeChecker::validateDecl(ValueDecl *D) {
43834345
if (CD->getDeclContext()->isTypeContext())
43844346
configureImplicitSelf(*this, CD);
43854347

4386-
if (auto gp = CD->getGenericParams()) {
4387-
// Write up generic parameters and check the generic parameter list.
4388-
gp->setOuterParameters(CD->getDeclContext()->getGenericParamsOfContext());
4389-
4390-
auto *sig = validateGenericFuncSignature(CD);
4391-
auto *env = sig->createGenericEnvironment();
4392-
CD->setGenericEnvironment(env);
4393-
4394-
// Revert the types within the signature so it can be type-checked with
4395-
// archetypes below.
4396-
revertGenericFuncSignature(CD);
4397-
} else if (CD->getDeclContext()->getGenericSignatureOfContext()) {
4398-
(void)validateGenericFuncSignature(CD);
4399-
4400-
// Revert all of the types within the signature of the constructor.
4401-
revertGenericFuncSignature(CD);
4402-
4403-
CD->setGenericEnvironment(
4404-
CD->getDeclContext()->getGenericEnvironmentOfContext());
4405-
}
4406-
4407-
// Set the context type of 'self'.
4408-
if (CD->getDeclContext()->isTypeContext())
4409-
recordSelfContextType(CD);
4410-
4411-
// Type check the constructor parameters.
4412-
GenericTypeToArchetypeResolver resolver(CD);
4413-
if (typeCheckParameterLists(CD, resolver) || CD->isInvalid()) {
4414-
CD->setInterfaceType(ErrorType::get(Context));
4415-
CD->setInvalid();
4416-
} else {
4417-
if (!CD->getGenericSignatureOfContext())
4418-
configureInterfaceType(CD, CD->getGenericSignature());
4419-
}
4348+
validateGenericFuncSignature(CD);
4349+
recordParamContextTypes(CD);
44204350

44214351
// We want the constructor to be available for name lookup as soon
44224352
// as it has a valid interface type.
@@ -4470,23 +4400,8 @@ void TypeChecker::validateDecl(ValueDecl *D) {
44704400

44714401
configureImplicitSelf(*this, DD);
44724402

4473-
if (DD->getDeclContext()->getGenericSignatureOfContext()) {
4474-
(void)validateGenericFuncSignature(DD);
4475-
DD->setGenericEnvironment(
4476-
DD->getDeclContext()->getGenericEnvironmentOfContext());
4477-
}
4478-
4479-
// Set the context type of 'self'.
4480-
recordSelfContextType(DD);
4481-
4482-
GenericTypeToArchetypeResolver resolver(DD);
4483-
if (typeCheckParameterLists(DD, resolver)) {
4484-
DD->setInterfaceType(ErrorType::get(Context));
4485-
DD->setInvalid();
4486-
}
4487-
4488-
if (!DD->getGenericSignatureOfContext())
4489-
configureInterfaceType(DD, DD->getGenericSignature());
4403+
validateGenericFuncSignature(DD);
4404+
recordParamContextTypes(DD);
44904405

44914406
DD->setSignatureIsValidated();
44924407

@@ -4508,49 +4423,8 @@ void TypeChecker::validateDecl(ValueDecl *D) {
45084423

45094424
DeclValidationRAII IBV(SD);
45104425

4511-
auto dc = SD->getDeclContext();
4512-
4513-
if (auto gp = SD->getGenericParams()) {
4514-
// Write up generic parameters and check the generic parameter list.
4515-
gp->setOuterParameters(dc->getGenericParamsOfContext());
4516-
4517-
auto *sig = validateGenericSubscriptSignature(SD);
4518-
auto *env = sig->createGenericEnvironment();
4519-
SD->setGenericEnvironment(env);
4520-
4521-
// Revert the types within the signature so it can be type-checked with
4522-
// archetypes below.
4523-
revertGenericSubscriptSignature(SD);
4524-
} else if (dc->getGenericSignatureOfContext()) {
4525-
(void)validateGenericSubscriptSignature(SD);
4526-
4527-
// Revert all of the types within the signature of the subscript.
4528-
revertGenericSubscriptSignature(SD);
4529-
4530-
SD->setGenericEnvironment(
4531-
SD->getDeclContext()->getGenericEnvironmentOfContext());
4532-
}
4533-
4534-
// Type check the subscript parameters.
4535-
GenericTypeToArchetypeResolver resolver(SD);
4536-
4537-
bool isInvalid = validateType(SD->getElementTypeLoc(), SD,
4538-
TypeResolutionFlags::AllowIUO,
4539-
&resolver);
4540-
TypeResolutionOptions options;
4541-
options |= TypeResolutionFlags::SubscriptParameters;
4542-
4543-
isInvalid |= typeCheckParameterList(SD->getIndices(), SD,
4544-
options,
4545-
resolver);
4546-
4547-
if (isInvalid || SD->isInvalid()) {
4548-
SD->setInterfaceType(ErrorType::get(Context));
4549-
SD->setInvalid();
4550-
} else {
4551-
if (!SD->getGenericSignatureOfContext())
4552-
configureInterfaceType(SD, SD->getGenericSignature());
4553-
}
4426+
validateGenericSubscriptSignature(SD);
4427+
recordIndexContextTypes(SD);
45544428

45554429
SD->setSignatureIsValidated();
45564430

@@ -4566,7 +4440,7 @@ void TypeChecker::validateDecl(ValueDecl *D) {
45664440
}
45674441

45684442
// Member subscripts need some special validation logic.
4569-
if (dc->isTypeContext()) {
4443+
if (SD->getDeclContext()->isTypeContext()) {
45704444
// If this is a class member, mark it final if the class is final.
45714445
inferFinalAndDiagnoseIfNeeded(*this, SD, StaticSpellingKind::None);
45724446

@@ -4590,14 +4464,15 @@ void TypeChecker::validateDecl(ValueDecl *D) {
45904464

45914465
case DeclKind::EnumElement: {
45924466
auto *EED = cast<EnumElementDecl>(D);
4467+
EnumDecl *ED = EED->getParentEnum();
45934468

45944469
checkDeclAttributesEarly(EED);
45954470
validateAttributes(*this, EED);
45964471

45974472
DeclValidationRAII IBV(EED);
45984473

45994474
if (auto *PL = EED->getParameterList()) {
4600-
GenericTypeToArchetypeResolver resolver(EED->getParentEnum());
4475+
CompleteGenericTypeResolver resolver(*this, ED->getGenericSignature());
46014476

46024477
bool isInvalid
46034478
= typeCheckParameterList(PL, EED->getParentEnum(),
@@ -4613,7 +4488,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
46134488

46144489
// If we have a raw value, make sure there's a raw type as well.
46154490
if (auto *rawValue = EED->getRawValueExpr()) {
4616-
EnumDecl *ED = EED->getParentEnum();
46174491
if (!ED->hasRawType()) {
46184492
diagnose(rawValue->getLoc(),diag::enum_raw_value_without_raw_type);
46194493
// Recover by setting the raw type as this element's type.
@@ -4630,8 +4504,8 @@ void TypeChecker::validateDecl(ValueDecl *D) {
46304504

46314505
// Now that we have an argument type we can set the element's declared
46324506
// type.
4633-
if (!EED->hasInterfaceType() && !EED->computeType())
4634-
break;
4507+
if (!EED->isInvalid())
4508+
EED->computeType();
46354509

46364510
EED->setSignatureIsValidated();
46374511

0 commit comments

Comments
 (0)