Example #1
0
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.");
}
Example #2
0
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.");
}