GenericSignature *TypeChecker::validateGenericSignature( GenericParamList *genericParams, DeclContext *dc, GenericSignature *parentSig, bool allowConcreteGenericParams, std::function<void(ArchetypeBuilder &)> inferRequirements) { assert(genericParams && "Missing generic parameters?"); // Create the archetype builder. Module *module = dc->getParentModule(); ArchetypeBuilder builder = createArchetypeBuilder(module); // Type check the generic parameters, treating all generic type // parameters as dependent, unresolved. DependentGenericTypeResolver dependentResolver(builder); checkGenericParamList(&builder, genericParams, parentSig, nullptr, &dependentResolver); /// Perform any necessary requirement inference. if (inferRequirements) inferRequirements(builder); // Finalize the generic requirements. (void)builder.finalize(genericParams->getSourceRange().Start, allowConcreteGenericParams); // The archetype builder now has all of the requirements, although there might // still be errors that have not yet been diagnosed. Revert the signature // and type-check it again, completely. revertGenericParamList(genericParams); CompleteGenericTypeResolver completeResolver(*this, builder); checkGenericParamList(nullptr, genericParams, nullptr, nullptr, &completeResolver); (void)builder.diagnoseRemainingRenames(genericParams->getSourceRange().Start); // Record the generic type parameter types and the requirements. auto sig = builder.getGenericSignature(); // Debugging of the archetype builder and generic signature generation. if (Context.LangOpts.DebugGenericSignatures) { dc->printContext(llvm::errs()); llvm::errs() << "\n"; builder.dump(llvm::errs()); llvm::errs() << "Generic signature: "; sig->print(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "Canonical generic signature: "; sig->getCanonicalSignature()->print(llvm::errs()); llvm::errs() << "\n"; } return sig; }
GenericSignature * TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) { bool invalid = false; // Create the archetype builder. ArchetypeBuilder builder = createArchetypeBuilder(func->getParentModule()); // Type check the function declaration, treating all generic type // parameters as dependent, unresolved. DependentGenericTypeResolver dependentResolver(builder); if (checkGenericFuncSignature(*this, &builder, func, dependentResolver)) invalid = true; // If this triggered a recursive validation, back out: we're done. // FIXME: This is an awful hack. if (func->hasInterfaceType()) return nullptr; // Finalize the generic requirements. (void)builder.finalize(func->getLoc()); // The archetype builder now has all of the requirements, although there might // still be errors that have not yet been diagnosed. Revert the generic // function signature and type-check it again, completely. revertGenericFuncSignature(func); CompleteGenericTypeResolver completeResolver(*this, builder); if (checkGenericFuncSignature(*this, nullptr, func, completeResolver)) invalid = true; if (builder.diagnoseRemainingRenames(func->getLoc())) invalid = true; // The generic function signature is complete and well-formed. Determine // the type of the generic function. auto sig = builder.getGenericSignature(); // For a generic requirement in a protocol, make sure that the requirement // set didn't add any requirements to Self or its associated types. if (!invalid && func->getGenericParams() && isa<ProtocolDecl>(func->getDeclContext())) { auto proto = cast<ProtocolDecl>(func->getDeclContext()); for (auto req : sig->getRequirements()) { // If one of the types in the requirement is dependent on a non-Self // type parameter, this requirement is okay. if (!isSelfDerivedOrConcrete(req.getFirstType()) || !isSelfDerivedOrConcrete(req.getSecondType())) continue; // The conformance of 'Self' to the protocol is okay. if (req.getKind() == RequirementKind::Conformance && req.getSecondType()->getAs<ProtocolType>()->getDecl() == proto && req.getFirstType()->is<GenericTypeParamType>()) continue; diagnose(func, Context.LangOpts.EffectiveLanguageVersion[0] >= 4 ? diag::requirement_restricts_self : diag::requirement_restricts_self_swift3, func->getDescriptiveKind(), func->getFullName(), req.getFirstType().getString(), static_cast<unsigned>(req.getKind()), req.getSecondType().getString()); if (Context.LangOpts.EffectiveLanguageVersion[0] >= 4) invalid = true; } } // Debugging of the archetype builder and generic signature generation. if (Context.LangOpts.DebugGenericSignatures) { func->dumpRef(llvm::errs()); llvm::errs() << "\n"; builder.dump(llvm::errs()); llvm::errs() << "Generic signature: "; sig->print(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "Canonical generic signature: "; sig->getCanonicalSignature()->print(llvm::errs()); llvm::errs() << "\n"; } if (invalid) { func->setInterfaceType(ErrorType::get(Context)); func->setInvalid(); // null doesn't mean error here: callers still expect the signature. return sig; } configureInterfaceType(func, sig); return sig; }