Files
swift-mirror/lib/Sema/MiscDiagnostics.h
Slava Pestov 94e999a1b5 Sema: Pull availability checking out of resolveType()
We used to diagnose references to unavailable declarations in
two places:

- inside Exprs, right after type checking the expression
- inside TypeReprs, from resolveType()

In broad terms, resolveType() is called with TypeReprs
stored inside both Stmts and Decls.

To handle the first case, I added a new overload of
diagAvailability() that takes a Stmt, to be called from
typeCheckStmt(). This doesn't actually walk into any Exprs
stored inside the statement; this means it only walks
Patterns and such.

For the second case, a new DeclAvailabilityChecker is
now defined in TypeCheckAccess.cpp. It's structure is
analogous to the other three walkers there:

- AccessControlChecker
- UsableFromInlineChecker
- ExportabilityChecker

The new implementation of availability checking for types
introduces a lot more code than the old online logic
it replaces. However, I hope to consolidate some of the
code duplication among the four checkers that are defined
in TypeCheckAccess.cpp, and do some other cleanups that
will make the benefit of the new approach apparent.
2020-10-14 23:42:02 -04:00

115 lines
4.6 KiB
C++

//===--- MiscDiagnostics.h - AST-Level Diagnostics --------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SEMA_MISC_DIAGNOSTICS_H
#define SWIFT_SEMA_MISC_DIAGNOSTICS_H
#include "swift/AST/AttrKind.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Identifier.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
namespace swift {
class AbstractFunctionDecl;
class ApplyExpr;
class CallExpr;
class DeclContext;
class Expr;
class InFlightDiagnostic;
class Stmt;
class TopLevelCodeDecl;
class ValueDecl;
/// Emit diagnostics for syntactic restrictions on a given expression.
void performSyntacticExprDiagnostics(const Expr *E, const DeclContext *DC,
bool isExprStmt);
/// Emit diagnostics for a given statement.
void performStmtDiagnostics(const Stmt *S, DeclContext *DC);
void performAbstractFuncDeclDiagnostics(AbstractFunctionDecl *AFD);
/// Perform diagnostics on the top level code declaration.
void performTopLevelDeclDiagnostics(TopLevelCodeDecl *TLCD);
/// Emit a fix-it to set the access of \p VD to \p desiredAccess.
///
/// This actually updates \p VD as well.
void fixItAccess(InFlightDiagnostic &diag,
ValueDecl *VD,
AccessLevel desiredAccess,
bool isForSetter = false,
bool shouldUseDefaultAccess = false);
/// Emit fix-its to correct the argument labels in \p expr, which is the
/// argument tuple or single argument of a call.
///
/// If \p existingDiag is null, the fix-its will be attached to an appropriate
/// error diagnostic.
///
/// \returns true if the issue was diagnosed
bool diagnoseArgumentLabelError(ASTContext &ctx,
Expr *expr,
ArrayRef<Identifier> newNames,
bool isSubscript,
InFlightDiagnostic *existingDiag = nullptr);
/// If \p assignExpr has a destination expression that refers to a declaration
/// with a non-owning attribute, such as 'weak' or 'unowned' and the initializer
/// expression refers to a class constructor, emit a warning that the assigned
/// instance will be immediately deallocated.
void diagnoseUnownedImmediateDeallocation(ASTContext &ctx,
const AssignExpr *assignExpr);
/// If \p pattern binds to a declaration with a non-owning attribute, such as
/// 'weak' or 'unowned' and \p initializer refers to a class constructor,
/// emit a warning that the bound instance will be immediately deallocated.
void diagnoseUnownedImmediateDeallocation(ASTContext &ctx,
const Pattern *pattern,
SourceLoc equalLoc,
const Expr *initializer);
/// If \p expr is a call to a known function with a requirement that some
/// arguments must be constants, whether those arguments are passed only
/// constants. Otherwise, diagnose and emit errors.
void diagnoseConstantArgumentRequirement(const Expr *expr,
const DeclContext *declContext);
/// Attempt to fix the type of \p decl so that it's a valid override for
/// \p base...but only if we're highly confident that we know what the user
/// should have written.
///
/// The \p diag closure allows the caller to control the diagnostic that is
/// emitted. It is passed true if the diagnostic will be emitted with fixits
/// attached, and false otherwise. If None is returned, no diagnostics are
/// emitted. Else the fixits are attached to the returned diagnostic.
///
/// \returns true iff any fix-its were attached to \p diag.
bool computeFixitsForOverridenDeclaration(
ValueDecl *decl, const ValueDecl *base,
llvm::function_ref<Optional<InFlightDiagnostic>(bool)> diag);
/// Emit fix-its to enclose trailing closure in argument parens.
void fixItEncloseTrailingClosure(ASTContext &ctx,
InFlightDiagnostic &diag,
const CallExpr *call,
Identifier closureLabel);
} // namespace swift
#endif // SWIFT_SEMA_MISC_DIAGNOSTICS_H