Skip to content

Commit

Permalink
Sema: Refactor TypeChecker::diagnoseInlinableDeclRef()
Browse files Browse the repository at this point in the history
  • Loading branch information
slavapestov committed Oct 22, 2020
1 parent 051f4c4 commit 0f27312
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 42 deletions.
38 changes: 9 additions & 29 deletions lib/Sema/ResilienceDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,19 @@

using namespace swift;

bool TypeChecker::diagnoseInlinableDeclRef(SourceLoc loc,
const ValueDecl *D,
ExportContext where) {
auto fragileKind = where.getFragileFunctionKind();
if (fragileKind.kind == FragileFunctionKind::None)
return false;

// Do some important fast-path checks that apply to all cases.

// Type parameters are OK.
if (isa<AbstractTypeParamDecl>(D))
return false;

// Check whether the declaration is accessible.
if (diagnoseInlinableDeclRefAccess(loc, D, where))
return true;

// Check whether the declaration comes from a publically-imported module.
// Skip this check for accessors because the associated property or subscript
// will also be checked, and will provide a better error message.
if (!isa<AccessorDecl>(D))
if (diagnoseDeclRefExportability(loc, D, where))
return true;

return false;
}

bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc,
const ValueDecl *D,
ExportContext where) {
auto *DC = where.getDeclContext();
auto fragileKind = where.getFragileFunctionKind();
assert(fragileKind.kind != FragileFunctionKind::None);
if (fragileKind.kind == FragileFunctionKind::None)
return false;

// Local declarations are OK.
if (D->getDeclContext()->isLocalContext())
return false;

auto *DC = where.getDeclContext();

// Public declarations or SPI used from SPI are OK.
if (D->getFormalAccessScope(/*useDC=*/nullptr,
fragileKind.allowUsableFromInline).isPublic() &&
Expand Down Expand Up @@ -145,6 +120,11 @@ bool
TypeChecker::diagnoseDeclRefExportability(SourceLoc loc,
const ValueDecl *D,
ExportContext where) {
// Accessors cannot have exportability that's different than the storage,
// so skip them for now.
if (isa<AccessorDecl>(D))
return false;

if (!where.mustOnlyReferenceExportedDecls())
return false;

Expand Down
18 changes: 10 additions & 8 deletions lib/Sema/TypeCheckAvailability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2716,6 +2716,10 @@ AvailabilityWalker::diagAvailability(ConcreteDeclRef declRef, SourceRange R,
return false;
const ValueDecl *D = declRef.getDecl();

// Generic parameters are always available.
if (isa<GenericTypeParamDecl>(D))
return false;

if (auto *attr = AvailableAttr::isUnavailable(D)) {
if (diagnoseIncDecRemoval(D, R, attr))
return true;
Expand All @@ -2733,14 +2737,12 @@ AvailabilityWalker::diagAvailability(ConcreteDeclRef declRef, SourceRange R,
return false;
}

if (Where.getFragileFunctionKind().kind != FragileFunctionKind::None) {
if (R.isValid())
if (TypeChecker::diagnoseInlinableDeclRef(R.Start, D, Where))
return true;
} else if (Where.getExportabilityReason().hasValue()) {
if (R.isValid())
if (TypeChecker::diagnoseDeclRefExportability(R.Start, D, Where))
return true;
if (R.isValid()) {
if (TypeChecker::diagnoseInlinableDeclRefAccess(R.Start, D, Where))
return true;

if (TypeChecker::diagnoseDeclRefExportability(R.Start, D, Where))
return true;
}

if (R.isValid()) {
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/TypeCheckStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1696,8 +1696,8 @@ static bool checkSuperInit(ConstructorDecl *fromCtor,
}

// Make sure we can reference the designated initializer correctly.
TypeChecker::diagnoseInlinableDeclRef(
fromCtor->getLoc(), ctor,
diagnoseDeclAvailability(
ctor, fromCtor->getLoc(),
ExportContext::forFunctionBody(fromCtor));
}

Expand Down
5 changes: 2 additions & 3 deletions lib/Sema/TypeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -947,11 +947,10 @@ DeclName getObjectLiteralConstructorName(ASTContext &ctx,
/// we're parsing the standard library.
ModuleDecl *getStdlibModule(const DeclContext *dc);

/// \name Resilience diagnostics
bool diagnoseInlinableDeclRef(SourceLoc loc, const ValueDecl *D, ExportContext where);

Expr *buildDefaultInitializer(Type type);

/// \name Resilience diagnostics

bool diagnoseInlinableDeclRefAccess(SourceLoc loc, const ValueDecl *D,
ExportContext where);

Expand Down

0 comments on commit 0f27312

Please sign in to comment.