bool TypeChecker::validateRequirement(SourceLoc whereLoc, RequirementRepr &req, DeclContext *lookupDC, TypeResolutionOptions options, GenericTypeResolver *resolver) { if (req.isInvalid()) return true; switch (req.getKind()) { case RequirementReprKind::TypeConstraint: { // Validate the types. if (validateType(req.getSubjectLoc(), lookupDC, options, resolver)) { req.setInvalid(); } if (validateType(req.getConstraintLoc(), lookupDC, options, resolver)) { req.setInvalid(); } return req.isInvalid(); } case RequirementReprKind::LayoutConstraint: { // Validate the types. if (validateType(req.getSubjectLoc(), lookupDC, options, resolver)) { req.setInvalid(); } if (req.getLayoutConstraintLoc().isNull()) { req.setInvalid(); } return req.isInvalid(); } case RequirementReprKind::SameType: { if (validateType(req.getFirstTypeLoc(), lookupDC, options, resolver)) { req.setInvalid(); } if (validateType(req.getSecondTypeLoc(), lookupDC, options, resolver)) { req.setInvalid(); } return req.isInvalid(); } } llvm_unreachable("Unhandled RequirementKind in switch."); }
bool TypeChecker::validateRequirement(SourceLoc whereLoc, RequirementRepr &req, TypeResolution resolution, TypeResolutionOptions options) { if (req.isInvalid()) return true; // Protocol where clauses cannot add conformance and superclass constraints // to 'Self', because we need to be able to resolve inherited protocols and // protocol superclasses before computing the protocol requirement signature. if (options.is(TypeResolverContext::ProtocolWhereClause)) { if (req.getKind() == RequirementReprKind::TypeConstraint || req.getKind() == RequirementReprKind::LayoutConstraint) { if (auto *subjectTyR = req.getSubjectLoc().getTypeRepr()) { if (auto *componentTyR = dyn_cast<ComponentIdentTypeRepr>(subjectTyR)) { if (componentTyR->getIdentifier() == Context.Id_Self) { diagnose(req.getSubjectLoc().getLoc(), diag::protocol_where_clause_self_requirement); req.getSubjectLoc().setType(ErrorType::get(Context)); if (req.getKind() == RequirementReprKind::TypeConstraint) req.getConstraintLoc().setType(ErrorType::get(Context)); req.setInvalid(); return true; } } } } } // Note that we are resolving within a requirement. options.setContext(None); options.setContext(TypeResolverContext::GenericRequirement); switch (req.getKind()) { case RequirementReprKind::TypeConstraint: { // Validate the types. if (validateType(req.getSubjectLoc(), resolution, options)) { req.setInvalid(); } if (validateType(req.getConstraintLoc(), resolution, options)) { req.setInvalid(); } return req.isInvalid(); } case RequirementReprKind::LayoutConstraint: { // Validate the types. if (validateType(req.getSubjectLoc(), resolution, options)) { req.setInvalid(); } if (req.getLayoutConstraintLoc().isNull()) { req.setInvalid(); } return req.isInvalid(); } case RequirementReprKind::SameType: { if (validateType(req.getFirstTypeLoc(), resolution, options)) { req.setInvalid(); } if (validateType(req.getSecondTypeLoc(), resolution, options)) { req.setInvalid(); } return req.isInvalid(); } } llvm_unreachable("Unhandled RequirementKind in switch."); }