GenericEnvironment * TypeChecker::markInvalidGenericSignature(DeclContext *DC) { GenericParamList *genericParams = DC->getGenericParamsOfContext(); GenericSignature *genericSig = DC->getGenericSignatureOfContext(); // Build new archetypes without any generic requirements. DeclContext *parentDC = DC->getParent(); auto builder = createArchetypeBuilder(parentDC->getParentModule()); auto parentSig = parentDC->getGenericSignatureOfContext(); auto parentEnv = parentDC->getGenericEnvironmentOfContext(); assert(parentSig != nullptr || DC->isInnermostContextGeneric()); if (parentSig != nullptr) builder.addGenericSignature(parentSig, parentEnv); if (DC->isInnermostContextGeneric()) { // Visit each of the generic parameters. for (auto param : *genericParams) builder.addGenericParameter(param); } // Wire up the archetypes. auto genericEnv = builder.getGenericEnvironment( genericSig->getGenericParams()); return genericEnv; }
void TypeChecker::validateGenericSubscriptSignature(SubscriptDecl *subscript) { auto *dc = subscript->getDeclContext(); GenericSignature *sig; if (auto *gp = subscript->getGenericParams()) { gp->setOuterParameters(dc->getGenericParamsOfContext()); prepareGenericParamList(gp, subscript); // Create the generic signature builder. GenericSignatureBuilder builder(Context); // Type check the function declaration, treating all generic type // parameters as dependent, unresolved. checkGenericSubscriptSignature(*this, &builder, subscript, TypeResolution::forStructural(subscript)); // The generic subscript signature is complete and well-formed. Determine // the type of the generic subscript. sig = std::move(builder).computeGenericSignature(subscript->getLoc()); // The generic signature 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. revertGenericSubscriptSignature(subscript); revertGenericParamList(*this, gp); // Debugging of generic signature generation. if (Context.LangOpts.DebugGenericSignatures) { subscript->dumpRef(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "Generic signature: "; sig->print(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "Canonical generic signature: "; sig->getCanonicalSignature()->print(llvm::errs()); llvm::errs() << "\n"; } subscript->setGenericEnvironment(sig->createGenericEnvironment()); } else { // Inherit the signature of our environment. sig = dc->getGenericSignatureOfContext(); subscript->setGenericEnvironment(dc->getGenericEnvironmentOfContext()); } checkGenericSubscriptSignature(*this, nullptr, subscript, TypeResolution::forInterface(subscript, sig)); subscript->computeType(); }
static void initDocGenericParams(const Decl *D, DocEntityInfo &Info) { auto *DC = dyn_cast<DeclContext>(D); if (DC == nullptr || !DC->isInnermostContextGeneric()) return; GenericSignature *GenericSig = DC->getGenericSignatureOfContext(); if (!GenericSig) return; // FIXME: Not right for extensions of nested generic types for (auto *GP : GenericSig->getInnermostGenericParams()) { if (GP->getDecl()->isImplicit()) continue; DocGenericParam Param; Param.Name = GP->getName().str(); Info.GenericParams.push_back(Param); } ProtocolDecl *proto = nullptr; if (auto *typeDC = DC->getInnermostTypeContext()) proto = typeDC->getAsProtocolOrProtocolExtensionContext(); for (auto &Req : GenericSig->getRequirements()) { if (Req.getKind() == RequirementKind::WitnessMarker) continue; // Skip protocol Self requirement. if (proto && Req.getKind() == RequirementKind::Conformance && Req.getFirstType()->isEqual(proto->getSelfInterfaceType()) && Req.getSecondType()->getAnyNominal() == proto) continue; std::string ReqStr; PrintOptions Opts; llvm::raw_string_ostream OS(ReqStr); Req.print(OS, Opts); OS.flush(); Info.GenericRequirements.push_back(std::move(ReqStr)); } }
GenericEnvironment *TypeChecker::checkGenericEnvironment( GenericParamList *genericParams, DeclContext *dc, GenericSignature *parentSig, bool allowConcreteGenericParams, ExtensionDecl *ext, llvm::function_ref<void(GenericSignatureBuilder &)> inferRequirements, bool mustInferRequirements) { assert(genericParams && "Missing generic parameters?"); bool recursivelyVisitGenericParams = genericParams->getOuterParameters() && !parentSig; GenericSignature *sig; if (!ext || mustInferRequirements || ext->getTrailingWhereClause() || getExtendedTypeGenericDepth(ext) != genericParams->getDepth()) { // Collect the generic parameters. SmallVector<GenericTypeParamType *, 4> allGenericParams; if (recursivelyVisitGenericParams) { visitOuterToInner(genericParams, [&](GenericParamList *gpList) { addGenericParamTypes(gpList, allGenericParams); }); } else { if (parentSig) { allGenericParams.append(parentSig->getGenericParams().begin(), parentSig->getGenericParams().end()); } addGenericParamTypes(genericParams, allGenericParams); } // Create the generic signature builder. GenericSignatureBuilder builder(Context); // Type check the generic parameters, treating all generic type // parameters as dependent, unresolved. if (recursivelyVisitGenericParams) { visitOuterToInner(genericParams, [&](GenericParamList *gpList) { auto genericParamsDC = gpList->begin()[0]->getDeclContext(); TypeResolution structuralResolution = TypeResolution::forStructural(genericParamsDC); checkGenericParamList(*this, &builder, gpList, nullptr, structuralResolution); }); } else { auto genericParamsDC = genericParams->begin()[0]->getDeclContext(); TypeResolution structuralResolution = TypeResolution::forStructural(genericParamsDC); checkGenericParamList(*this, &builder, genericParams, parentSig, structuralResolution); } /// Perform any necessary requirement inference. inferRequirements(builder); // Record the generic type parameter types and the requirements. sig = std::move(builder).computeGenericSignature( genericParams->getSourceRange().Start, allowConcreteGenericParams); // The generic signature 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. if (recursivelyVisitGenericParams) { visitOuterToInner(genericParams, [&](GenericParamList *gpList) { revertGenericParamList(*this, gpList); }); } else { revertGenericParamList(*this, genericParams); } // Debugging of the generic signature builder and generic signature // generation. if (Context.LangOpts.DebugGenericSignatures) { dc->printContext(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "Generic signature: "; sig->print(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "Canonical generic signature: "; sig->getCanonicalSignature()->print(llvm::errs()); llvm::errs() << "\n"; } } else { // Re-use the signature of the type being extended. sig = ext->getSelfNominalTypeDecl()->getGenericSignatureOfContext(); } if (recursivelyVisitGenericParams) { visitOuterToInner(genericParams, [&](GenericParamList *gpList) { auto paramsDC = gpList->getParams().front()->getDeclContext(); TypeResolution interfaceResolution = TypeResolution::forInterface(paramsDC, sig); checkGenericParamList(*this, nullptr, gpList, nullptr, interfaceResolution); }); } else { auto paramsDC = genericParams->getParams().front()->getDeclContext(); TypeResolution interfaceResolution = TypeResolution::forInterface(paramsDC, sig); checkGenericParamList(*this, nullptr, genericParams, parentSig, interfaceResolution); } // Form the generic environment. return sig->createGenericEnvironment(); }
GenericSignature * TypeChecker::validateGenericSubscriptSignature(SubscriptDecl *subscript) { bool invalid = false; GenericSignature *sig; if (auto *gp = subscript->getGenericParams()) { prepareGenericParamList(gp, subscript); // Create the generic signature builder. GenericSignatureBuilder builder(Context); // Type check the function declaration, treating all generic type // parameters as dependent, unresolved. DependentGenericTypeResolver dependentResolver; if (checkGenericSubscriptSignature(*this, &builder, subscript, dependentResolver)) invalid = true; // The generic subscript signature is complete and well-formed. Determine // the type of the generic subscript. sig = std::move(builder).computeGenericSignature(subscript->getLoc()); // The generic signature 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. revertGenericSubscriptSignature(subscript); revertGenericParamList(gp); // Debugging of generic signature generation. if (Context.LangOpts.DebugGenericSignatures) { subscript->dumpRef(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "Generic signature: "; sig->print(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "Canonical generic signature: "; sig->getCanonicalSignature()->print(llvm::errs()); llvm::errs() << "\n"; } } else { // Inherit the signature of our environment. sig = subscript->getDeclContext()->getGenericSignatureOfContext(); } CompleteGenericTypeResolver completeResolver(*this, sig); if (checkGenericSubscriptSignature(*this, nullptr, subscript, completeResolver)) invalid = true; if (!invalid) invalid = checkProtocolSelfRequirements(sig, subscript, *this); if (invalid) { subscript->setInterfaceType(ErrorType::get(Context)); subscript->setInvalid(); // null doesn't mean error here: callers still expect the signature. return sig; } configureInterfaceType(subscript, sig); return sig; }