Skip to content

Make validateType a utility method #27179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions lib/Sema/CSGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1382,8 +1382,8 @@ namespace {
Type resolveTypeReferenceInExpression(TypeLoc &loc) {
TypeResolutionOptions options(TypeResolverContext::InExpression);
options |= TypeResolutionFlags::AllowUnboundGenerics;
bool hadError = CS.TC.validateType(
loc, TypeResolution::forContextual(CS.DC), options);
bool hadError = TypeChecker::validateType(
CS.TC.Context, loc, TypeResolution::forContextual(CS.DC), options);
return hadError ? Type() : loc.getType();
}

Expand Down Expand Up @@ -1640,7 +1640,8 @@ namespace {
for (size_t i = 0, size = specializations.size(); i < size; ++i) {
TypeResolutionOptions options(TypeResolverContext::InExpression);
options |= TypeResolutionFlags::AllowUnboundGenerics;
if (tc.validateType(specializations[i],
if (TypeChecker::validateType(tc.Context,
specializations[i],
TypeResolution::forContextual(CS.DC),
options))
return Type();
Expand Down Expand Up @@ -2280,9 +2281,10 @@ namespace {
// of is-patterns applied to an irrefutable pattern.
pattern = pattern->getSemanticsProvidingPattern();
while (auto isp = dyn_cast<IsPattern>(pattern)) {
if (CS.TC.validateType(isp->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC),
TypeResolverContext::InExpression)) {
if (TypeChecker::validateType(CS.TC.Context,
isp->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC),
TypeResolverContext::InExpression)) {
return false;
}

Expand Down Expand Up @@ -2618,8 +2620,10 @@ namespace {
// Validate the resulting type.
TypeResolutionOptions options(TypeResolverContext::ExplicitCastExpr);
options |= TypeResolutionFlags::AllowUnboundGenerics;
if (tc.validateType(expr->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC), options))
if (TypeChecker::validateType(tc.Context,
expr->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC),
options))
return nullptr;

// Open the type we're casting to.
Expand Down Expand Up @@ -2648,9 +2652,10 @@ namespace {
// Validate the resulting type.
TypeResolutionOptions options(TypeResolverContext::ExplicitCastExpr);
options |= TypeResolutionFlags::AllowUnboundGenerics;
if (tc.validateType(expr->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC),
options))
if (TypeChecker::validateType(tc.Context,
expr->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC),
options))
return nullptr;

// Open the type we're casting to.
Expand Down Expand Up @@ -2684,8 +2689,10 @@ namespace {
// Validate the resulting type.
TypeResolutionOptions options(TypeResolverContext::ExplicitCastExpr);
options |= TypeResolutionFlags::AllowUnboundGenerics;
if (tc.validateType(expr->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC), options))
if (TypeChecker::validateType(tc.Context,
expr->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC),
options))
return nullptr;

// Open the type we're casting to.
Expand Down Expand Up @@ -2713,8 +2720,10 @@ namespace {
auto &tc = CS.getTypeChecker();
TypeResolutionOptions options(TypeResolverContext::ExplicitCastExpr);
options |= TypeResolutionFlags::AllowUnboundGenerics;
if (tc.validateType(expr->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC), options))
if (TypeChecker::validateType(tc.Context,
expr->getCastTypeLoc(),
TypeResolution::forContextual(CS.DC),
options))
return nullptr;

// Open up the type we're checking.
Expand Down
1 change: 1 addition & 0 deletions lib/Sema/ResilienceDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ void TypeChecker::diagnoseGenericTypeExportability(const TypeLoc &TL,
GenericTypeFinder(const SourceFile &SF, Callback callback)
: SF(SF), callback(callback) {}


Action visitBoundGenericType(BoundGenericType *ty) override {
ModuleDecl *useModule = SF.getParentModule();
SubstitutionMap subs = ty->getContextSubstitutionMap(useModule,
Expand Down
15 changes: 9 additions & 6 deletions lib/Sema/TypeCheckConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1140,8 +1140,9 @@ namespace {

if (auto PlaceholderE = dyn_cast<EditorPlaceholderExpr>(expr)) {
if (!PlaceholderE->getTypeLoc().isNull()) {
if (!TC.validateType(PlaceholderE->getTypeLoc(),
TypeResolution::forContextual(DC), None))
if (!TypeChecker::validateType(TC.Context, PlaceholderE->getTypeLoc(),
TypeResolution::forContextual(DC),
None))
expr->setType(PlaceholderE->getTypeLoc().getType());
}
return finish(true, expr);
Expand Down Expand Up @@ -1375,8 +1376,9 @@ bool PreCheckExpression::walkToClosureExprPre(ClosureExpr *closure) {

// Validate the result type, if present.
if (closure->hasExplicitResultType() &&
TC.validateType(closure->getExplicitResultTypeLoc(), resolution,
TypeResolverContext::InExpression)) {
TypeChecker::validateType(TC.Context, closure->getExplicitResultTypeLoc(),
resolution,
TypeResolverContext::InExpression)) {
return false;
}

Expand All @@ -1392,7 +1394,7 @@ bool PreCheckExpression::walkToClosureExprPre(ClosureExpr *closure) {
// recurse into.
assert((closure->getParent() == DC ||
closure->getParent()->isChildContextOf(DC)) &&
"Decl context isn't correct");
"Decl context isn't correct");
DC = closure;
return true;
}
Expand Down Expand Up @@ -1987,7 +1989,8 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {

auto &typeLoc = typeExpr->getTypeLoc();
bool hadError =
TC.validateType(typeLoc, TypeResolution::forContextual(DC), options);
TypeChecker::validateType(TC.Context, typeLoc,
TypeResolution::forContextual(DC), options);

if (hadError)
return nullptr;
Expand Down
14 changes: 9 additions & 5 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,8 @@ static NominalTypeDecl *resolveSingleNominalTypeDecl(

TypeResolutionOptions options = TypeResolverContext::TypeAliasDecl;
options |= flags;
if (tc.validateType(typeLoc, TypeResolution::forInterface(DC), options))
if (TypeChecker::validateType(tc.Context, typeLoc,
TypeResolution::forInterface(DC), options))
return nullptr;

return typeLoc.getType()->getAnyNominal();
Expand Down Expand Up @@ -3477,8 +3478,9 @@ static void validateTypealiasType(TypeChecker &tc, TypeAliasDecl *typeAlias) {
return;
}

if (tc.validateType(typeAlias->getUnderlyingTypeLoc(),
TypeResolution::forInterface(typeAlias, &tc), options)) {
if (TypeChecker::validateType(tc.Context, typeAlias->getUnderlyingTypeLoc(),
TypeResolution::forInterface(typeAlias, &tc),
options)) {
typeAlias->setInvalid();
typeAlias->getUnderlyingTypeLoc().setInvalidType(tc.Context);
}
Expand Down Expand Up @@ -4202,8 +4204,10 @@ void TypeChecker::validateDeclForNameLookup(ValueDecl *D) {
TypeResolverContext::TypeAliasDecl));
auto &underlyingTL = typealias->getUnderlyingTypeLoc();
if (underlyingTL.isNull() ||
validateType(underlyingTL,
TypeResolution::forStructural(typealias), options)) {
TypeChecker::validateType(Context,
underlyingTL,
TypeResolution::forStructural(typealias),
options)) {
typealias->setInvalid();
underlyingTL.setInvalidType(Context);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Type TypeChecker::getOrCreateOpaqueResultType(TypeResolution resolution,
TypeLoc constraintTypeLoc(repr->getConstraint());
// Pass along the error type if resolving the repr failed.
bool validationError
= validateType(constraintTypeLoc, resolution, options);
= validateType(Context, constraintTypeLoc, resolution, options);
auto constraintType = constraintTypeLoc.getType();
if (validationError)
return constraintType;
Expand Down Expand Up @@ -569,7 +569,7 @@ void TypeChecker::validateGenericFuncOrSubscriptSignature(
resultTyLoc.setType(
getOrCreateOpaqueResultType(resolution, decl, opaqueTy));
} else {
validateType(resultTyLoc, resolution,
validateType(Context, resultTyLoc, resolution,
TypeResolverContext::FunctionResult);
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/Sema/TypeCheckPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ static bool validateTypedPattern(TypeChecker &TC,
hadError = true;
}
} else {
hadError = TC.validateType(TL, resolution, options);
hadError = TypeChecker::validateType(TC.Context, TL, resolution, options);
}

if (hadError) {
Expand Down Expand Up @@ -765,7 +765,7 @@ static bool validateParameterType(ParamDecl *decl, TypeResolution resolution,
// We might have a null typeLoc if this is a closure parameter list,
// where parameters are allowed to elide their types.
if (!TL.isNull()) {
hadError |= TC.validateType(TL, resolution, options);
hadError |= TypeChecker::validateType(TC.Context, TL, resolution, options);
}

Type Ty = TL.getType();
Expand Down Expand Up @@ -1296,7 +1296,7 @@ bool TypeChecker::coercePatternToType(Pattern *&P, TypeResolution resolution,

// Type-check the type parameter.
TypeResolutionOptions paramOptions(TypeResolverContext::InExpression);
if (validateType(IP->getCastTypeLoc(), resolution, paramOptions))
if (validateType(Context, IP->getCastTypeLoc(), resolution, paramOptions))
return true;

auto castType = IP->getCastTypeLoc().getType();
Expand Down
3 changes: 2 additions & 1 deletion lib/Sema/TypeCheckPropertyWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,8 @@ AttachedPropertyWrapperTypeRequest::evaluate(Evaluator &evaluator,
options |= TypeResolutionFlags::AllowUnboundGenerics;

auto &tc = *static_cast<TypeChecker *>(ctx.getLazyResolver());
if (tc.validateType(customAttr->getTypeLoc(), resolution, options))
if (TypeChecker::validateType(tc.Context, customAttr->getTypeLoc(),
resolution, options))
return ErrorType::get(ctx);

return customAttr->getTypeLoc().getType();
Expand Down
26 changes: 14 additions & 12 deletions lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1715,25 +1715,26 @@ Type TypeChecker::resolveIdentifierType(
/// Validate whether type associated with @autoclosure attribute is correct,
/// it supposed to be a function type with no parameters.
/// \returns true if there was an error, false otherwise.
static bool validateAutoClosureAttr(TypeChecker &TC, const SourceLoc &loc,
static bool validateAutoClosureAttr(DiagnosticEngine &Diags, const SourceLoc &loc,
Type paramType) {
if (auto *fnType = paramType->getAs<FunctionType>()) {
if (fnType->getNumParams() != 0) {
TC.diagnose(loc, diag::autoclosure_function_input_nonunit);
Diags.diagnose(loc, diag::autoclosure_function_input_nonunit);
return true;
}
// A function type with no parameters.
return false;
}

TC.diagnose(loc, diag::autoclosure_function_type);
Diags.diagnose(loc, diag::autoclosure_function_type);
return true;
}

/// Check whether the type associated with particular source location
/// has `@autoclosure` attribute, and if so, validate that such use is correct.
/// \returns true if there was an error, false otherwise.
static bool validateAutoClosureAttributeUse(TypeChecker &TC, const TypeLoc &loc,
static bool validateAutoClosureAttributeUse(DiagnosticEngine &Diags,
const TypeLoc &loc,
Type type,
TypeResolutionOptions options) {
auto *TR = loc.getTypeRepr();
Expand All @@ -1745,7 +1746,7 @@ static bool validateAutoClosureAttributeUse(TypeChecker &TC, const TypeLoc &loc,
if (auto *ATR = dyn_cast<AttributedTypeRepr>(TR)) {
const auto attrLoc = ATR->getAttrs().getLoc(TAK_autoclosure);
if (attrLoc.isValid())
return validateAutoClosureAttr(TC, attrLoc, type);
return validateAutoClosureAttr(Diags, attrLoc, type);
}
}

Expand All @@ -1759,7 +1760,7 @@ static bool validateAutoClosureAttributeUse(TypeChecker &TC, const TypeLoc &loc,
isValid &= llvm::none_of(
fnType->getParams(), [&](const FunctionType::Param &param) {
return param.isAutoClosure() &&
validateAutoClosureAttr(TC, loc.getLoc(),
validateAutoClosureAttr(Diags, loc.getLoc(),
param.getPlainType());
});
}
Expand All @@ -1768,7 +1769,8 @@ static bool validateAutoClosureAttributeUse(TypeChecker &TC, const TypeLoc &loc,
return !isValid;
}

bool TypeChecker::validateType(TypeLoc &Loc, TypeResolution resolution,
bool TypeChecker::validateType(ASTContext &Context, TypeLoc &Loc,
TypeResolution resolution,
TypeResolutionOptions options) {
// If we've already validated this type, don't do so again.
if (Loc.wasValidated())
Expand All @@ -1785,10 +1787,11 @@ bool TypeChecker::validateType(TypeLoc &Loc, TypeResolution resolution,
// Diagnose types that are illegal in SIL.
} else if (options.contains(TypeResolutionFlags::SILType)
&& !type->isLegalSILType()) {
diagnose(Loc.getLoc(), diag::illegal_sil_type, type);
Context.Diags.diagnose(Loc.getLoc(), diag::illegal_sil_type, type);
Loc.setInvalidType(Context);
return true;
} else if (validateAutoClosureAttributeUse(*this, Loc, type, options)) {
} else if (validateAutoClosureAttributeUse(Context.Diags, Loc,
type, options)) {
type = ErrorType::get(Context);
}
}
Expand All @@ -1798,7 +1801,7 @@ bool TypeChecker::validateType(TypeLoc &Loc, TypeResolution resolution,
const DeclContext *DC = resolution.getDeclContext();
if (options.isAnyExpr() || DC->getParent()->isLocalContext())
if (DC->getResilienceExpansion() == ResilienceExpansion::Minimal)
diagnoseGenericTypeExportability(Loc, DC);
TypeChecker::diagnoseGenericTypeExportability(Loc, DC);
}

return type->hasError();
Expand Down Expand Up @@ -3618,8 +3621,7 @@ Type swift::resolveCustomAttrType(CustomAttr *attr, DeclContext *dc,
options |= TypeResolutionFlags::AllowUnboundGenerics;

ASTContext &ctx = dc->getASTContext();
auto &tc = *static_cast<TypeChecker *>(ctx.getLazyResolver());
if (tc.validateType(attr->getTypeLoc(), resolution, options))
if (TypeChecker::validateType(ctx, attr->getTypeLoc(), resolution, options))
return Type();

// We always require the type to resolve to a nominal type.
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ bool swift::performTypeLocChecking(ASTContext &Ctx, TypeLoc &T,
if (!ProduceDiagnostics)
suppression.emplace(Ctx.Diags);
TypeChecker &TC = createTypeChecker(Ctx);
return TC.validateType(T, resolution, options);
return TypeChecker::validateType(TC.Context, T, resolution, options);
}

/// Expose TypeChecker's handling of GenericParamList to SIL parsing.
Expand Down
11 changes: 6 additions & 5 deletions lib/Sema/TypeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,8 +757,9 @@ class TypeChecker final : public LazyResolver {
/// \param options Options that alter type resolution.
///
/// \returns true if type validation failed, or false otherwise.
bool validateType(TypeLoc &Loc, TypeResolution resolution,
TypeResolutionOptions options);
static bool validateType(ASTContext &Ctx, TypeLoc &Loc,
TypeResolution resolution,
TypeResolutionOptions options);

/// Check for unsupported protocol types in the given declaration.
void checkUnsupportedProtocolType(Decl *decl);
Expand Down Expand Up @@ -1747,17 +1748,17 @@ class TypeChecker final : public LazyResolver {
const DeclContext *DC,
FragileFunctionKind fragileKind);

public:
/// Given that a type is used from a particular context which
/// exposes it in the interface of the current module, diagnose if its
/// generic arguments require the use of conformances that cannot reasonably
/// be shared.
///
/// This method \e only checks how generic arguments are used; it is assumed
/// that the declarations involved have already been checked elsewhere.
void diagnoseGenericTypeExportability(const TypeLoc &TL,
const DeclContext *DC);
static void diagnoseGenericTypeExportability(const TypeLoc &TL,
const DeclContext *DC);

public:
/// Given that \p DC is within a fragile context for some reason, describe
/// why.
///
Expand Down