Skip to content

Commit ba965ec

Browse files
authored
Merge pull request #18610 from rjmccall/generic-subscript-accessor-signatures
Just use a generic subscript's generic context in its accessors (NFC)
2 parents a728305 + 9f7c5f5 commit ba965ec

File tree

1 file changed

+67
-64
lines changed

1 file changed

+67
-64
lines changed

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 67 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -547,26 +547,6 @@ static void checkGenericFuncSignature(TypeChecker &tc,
547547
source);
548548
}
549549
}
550-
551-
// If this is a materializeForSet, infer requirements from the
552-
// storage type instead, since it's not part of the accessor's
553-
// type signature.
554-
auto accessor = dyn_cast<AccessorDecl>(fn);
555-
if (accessor && accessor->isMaterializeForSet()) {
556-
if (builder) {
557-
auto *storage = accessor->getStorage();
558-
if (auto *subscriptDecl = dyn_cast<SubscriptDecl>(storage)) {
559-
auto source =
560-
GenericSignatureBuilder::FloatingRequirementSource::forInferred(
561-
subscriptDecl->getElementTypeLoc().getTypeRepr());
562-
563-
TypeLoc type(nullptr, subscriptDecl->getElementInterfaceType());
564-
assert(type.getType());
565-
builder->inferRequirements(*func->getParentModule(),
566-
type, source);
567-
}
568-
}
569-
}
570550
}
571551
}
572552

@@ -794,57 +774,80 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
794774
}
795775
}
796776

797-
void TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
777+
static GenericSignature *
778+
computeGenericFuncSignature(TypeChecker &tc, AbstractFunctionDecl *func) {
798779
auto *dc = func->getDeclContext();
799780

800-
GenericSignature *sig;
801-
if (auto gp = func->getGenericParams()) {
802-
gp->setOuterParameters(dc->getGenericParamsOfContext());
803-
prepareGenericParamList(gp, func);
781+
// Check whether the function is separately generic.
782+
auto gp = func->getGenericParams();
783+
if (!gp) {
784+
// If not, inherit the signature of our environment.
785+
func->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
786+
return dc->getGenericSignatureOfContext();
787+
}
804788

805-
// Create the generic signature builder.
806-
GenericSignatureBuilder builder(Context);
789+
// Do some initial configuration of the generic parameter lists that's
790+
// required in all cases.
791+
gp->setOuterParameters(dc->getGenericParamsOfContext());
792+
tc.prepareGenericParamList(gp, func);
793+
794+
// Accessors can always use the generic context of their storage
795+
// declarations. This is a compile-time optimization since it lets us
796+
// avoid the requirements-gathering phase, but it also simplifies that
797+
// work for accessors which don't mention the value type in their formal
798+
// signatures (like the read and modify coroutines, since yield types
799+
// aren't tracked in the AST type yet).
800+
//
801+
// Most accessors will implicitly have been handled above because they
802+
// aren't separately generic; we only get here for the accessors of
803+
// generic subscripts.
804+
if (auto accessor = dyn_cast<AccessorDecl>(func)) {
805+
auto subscript = cast<SubscriptDecl>(accessor->getStorage());
806+
auto sig = subscript->getGenericSignature();
807+
auto env = subscript->getGenericEnvironment();
808+
assert(sig && env && "accessor has generics but subscript is not generic");
809+
func->setGenericEnvironment(env);
810+
return sig;
811+
}
807812

808-
// Type check the function declaration, treating all generic type
809-
// parameters as dependent, unresolved.
810-
DependentGenericTypeResolver dependentResolver;
811-
checkGenericFuncSignature(*this, &builder, func, dependentResolver);
813+
// Create the generic signature builder.
814+
GenericSignatureBuilder builder(tc.Context);
815+
816+
// Type check the function declaration, treating all generic type
817+
// parameters as dependent, unresolved.
818+
DependentGenericTypeResolver dependentResolver;
819+
checkGenericFuncSignature(tc, &builder, func, dependentResolver);
820+
821+
// The generic function signature is complete and well-formed. Determine
822+
// the type of the generic function.
823+
auto sig = std::move(builder).computeGenericSignature(func->getLoc());
824+
825+
// The generic signature builder now has all of the requirements, although
826+
// there might still be errors that have not yet been diagnosed. Revert the
827+
// generic function signature and type-check it again, completely.
828+
revertGenericFuncSignature(func);
829+
tc.revertGenericParamList(gp);
830+
831+
// Debugging of the generic signature.
832+
if (tc.Context.LangOpts.DebugGenericSignatures) {
833+
func->dumpRef(llvm::errs());
834+
llvm::errs() << "\n";
835+
llvm::errs() << "Generic signature: ";
836+
sig->print(llvm::errs());
837+
llvm::errs() << "\n";
838+
llvm::errs() << "Canonical generic signature: ";
839+
sig->getCanonicalSignature()->print(llvm::errs());
840+
llvm::errs() << "\n";
841+
}
812842

813-
// The generic function signature is complete and well-formed. Determine
814-
// the type of the generic function.
815-
sig = std::move(builder).computeGenericSignature(func->getLoc());
843+
GenericEnvironment *env = sig->createGenericEnvironment();
844+
func->setGenericEnvironment(env);
816845

817-
// The generic signature builder now has all of the requirements, although
818-
// there might still be errors that have not yet been diagnosed. Revert the
819-
// generic function signature and type-check it again, completely.
820-
revertGenericFuncSignature(func);
821-
revertGenericParamList(gp);
822-
823-
// Debugging of the generic signature.
824-
if (Context.LangOpts.DebugGenericSignatures) {
825-
func->dumpRef(llvm::errs());
826-
llvm::errs() << "\n";
827-
llvm::errs() << "Generic signature: ";
828-
sig->print(llvm::errs());
829-
llvm::errs() << "\n";
830-
llvm::errs() << "Canonical generic signature: ";
831-
sig->getCanonicalSignature()->print(llvm::errs());
832-
llvm::errs() << "\n";
833-
}
846+
return sig;
847+
}
834848

835-
GenericEnvironment *env;
836-
if (auto accessor = dyn_cast<AccessorDecl>(func)) {
837-
env = cast<SubscriptDecl>(accessor->getStorage())->getGenericEnvironment();
838-
assert(env && "accessor has generics but subscript is not generic");
839-
} else {
840-
env = sig->createGenericEnvironment();
841-
}
842-
func->setGenericEnvironment(env);
843-
} else {
844-
// Inherit the signature of our environment.
845-
sig = dc->getGenericSignatureOfContext();
846-
func->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
847-
}
849+
void TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
850+
GenericSignature *sig = computeGenericFuncSignature(*this, func);
848851

849852
CompleteGenericTypeResolver completeResolver(*this, sig);
850853
checkGenericFuncSignature(*this, nullptr, func, completeResolver);

0 commit comments

Comments
 (0)