//===--- Verifier.cpp - AST Invariant Verification ------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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
//
//===----------------------------------------------------------------------===//
//
//  This file implements a verifier of AST invariants.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/AccessScope.h"
#include "swift/AST/Decl.h"
#include "swift/AST/ExistentialLayout.h"
#include "swift/AST/Expr.h"
#include "swift/AST/ForeignErrorConvention.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Initializer.h"
#include "swift/AST/Module.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/AST/Stmt.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Subsystems.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <functional>
#include <type_traits>
using namespace swift;

namespace {

template<typename T>
struct ASTNodeBase {};

#define EXPR(ID, PARENT) \
    template<> \
    struct ASTNodeBase<ID ## Expr *> { \
      typedef PARENT BaseTy; \
    };
#define ABSTRACT_EXPR(ID, PARENT) EXPR(ID, PARENT)
#include "swift/AST/ExprNodes.def"

#define STMT(ID, PARENT) \
    template<> \
    struct ASTNodeBase<ID ## Stmt *> { \
      typedef PARENT BaseTy; \
    };
#include "swift/AST/StmtNodes.def"

#define DECL(ID, PARENT) \
    template<> \
    struct ASTNodeBase<ID ## Decl *> { \
      typedef PARENT BaseTy; \
    };
#define ABSTRACT_DECL(ID, PARENT) DECL(ID, PARENT)
#include "swift/AST/DeclNodes.def"

#define PATTERN(ID, PARENT) \
    template<> \
    struct ASTNodeBase<ID ## Pattern *> { \
      typedef PARENT BaseTy; \
    };
#include "swift/AST/PatternNodes.def"

template <typename Ty>
struct is_apply_expr
    : public std::integral_constant<
          bool,
          std::is_same<Ty, CallExpr>::value ||
              std::is_same<Ty, PrefixUnaryExpr>::value ||
              std::is_same<Ty, PostfixUnaryExpr>::value ||
              std::is_same<Ty, BinaryExpr>::value ||
              std::is_same<Ty, DotSyntaxCallExpr>::value ||
              std::is_same<Ty, ConstructorRefCallExpr>::value> {};

template <typename Ty>
struct is_subscript_expr
    : public std::integral_constant<
          bool, std::is_same<Ty, SubscriptExpr>::value ||
                    std::is_same<Ty, DynamicSubscriptExpr>::value> {};

template <typename Ty>
struct is_autoclosure_expr
    : public std::integral_constant<bool,
                                    std::is_same<Ty, AutoClosureExpr>::value> {
};

template <typename Ty>
struct is_apply_subscript_or_autoclosure_expr
    : public std::integral_constant<bool, is_apply_expr<Ty>::value ||
                                              is_subscript_expr<Ty>::value ||
                                              is_autoclosure_expr<Ty>::value> {
};

template <typename Verifier, typename Kind>
std::pair<bool, Expr *> dispatchVisitPreExprHelper(
    Verifier &V,
    typename std::enable_if<
        is_apply_expr<typename std::remove_pointer<Kind>::type>::value,
        Kind>::type node) {
  if (V.shouldVerify(node)) {
    // Record any inout_to_pointer or array_to_pointer that we see in
    // the proper position.
    V.maybeRecordValidPointerConversion(node, node->getArg());
    return {true, node};
  }
  V.cleanup(node);
  return {false, node};
}

template <typename Verifier, typename Kind>
std::pair<bool, Expr *> dispatchVisitPreExprHelper(
    Verifier &V,
    typename std::enable_if<
        is_subscript_expr<typename std::remove_pointer<Kind>::type>::value,
        Kind>::type node) {
  if (V.shouldVerify(node)) {
    // Record any inout_to_pointer or array_to_pointer that we see in
    // the proper position.
    V.maybeRecordValidPointerConversion(node, node->getIndex());
    return {true, node};
  }
  V.cleanup(node);
  return {false, node};
}

template <typename Verifier, typename Kind>
std::pair<bool, Expr *> dispatchVisitPreExprHelper(
    Verifier &V,
    typename std::enable_if<
        is_autoclosure_expr<typename std::remove_pointer<Kind>::type>::value,
        Kind>::type node) {
  if (V.shouldVerify(node)) {
    // Record any inout_to_pointer or array_to_pointer that we see in
    // the proper position.
    V.maybeRecordValidPointerConversion(node, node->getSingleExpressionBody());
    return {true, node};
  }
  V.cleanup(node);
  return {false, node};
}

template <typename Verifier, typename Kind>
std::pair<bool, Expr *> dispatchVisitPreExprHelper(
    Verifier &V, typename std::enable_if<
                     !is_apply_subscript_or_autoclosure_expr<
                         typename std::remove_pointer<Kind>::type>::value,
                     Kind>::type node) {
  if (V.shouldVerify(node)) {
    return {true, node};
  }
  V.cleanup(node);
  return {false, node};
}

/// Describes a generic environment that might be lazily deserialized.
///
/// This class abstracts over a declaration context that may have a generic
/// environment, ensuring that we don't deserialize the environment.
struct LazyGenericEnvironment {
  llvm::PointerUnion<DeclContext *, GenericEnvironment *> storage;

  explicit operator bool() const {
    if (storage.dyn_cast<GenericEnvironment *>())
      return true;

    if (auto dc = storage.dyn_cast<DeclContext *>())
      return dc->getGenericSignatureOfContext();

    return false;
  }

  bool isLazy() const {
    if (auto dc = storage.dyn_cast<DeclContext *>())
      return dc->contextHasLazyGenericEnvironment();

    return false;
  }

  bool containsPrimaryArchetype(PrimaryArchetypeType *archetype) const {
    // Assume true so we don't deserialize.
    if (isLazy()) return true;

    if (auto genericEnv = storage.dyn_cast<GenericEnvironment *>())
      return archetype->getGenericEnvironment() == genericEnv;

    if (auto dc = storage.dyn_cast<DeclContext *>()) {
      if (auto genericEnv = dc->getGenericEnvironmentOfContext())
        return archetype->getGenericEnvironment() == genericEnv;
    }

    return false;
  }
};

namespace {
  /// Retrieve the "overridden" declaration of this declaration, but only if
  // it's already been computed.
  template<typename T>
  T *getOverriddenDeclIfAvailable(T *decl) {
    if (!decl->overriddenDeclsComputed()) return nullptr;

    return cast_or_null<T>(decl->getOverriddenDecl());
  }
}
class Verifier : public ASTWalker {
  PointerUnion<ModuleDecl *, SourceFile *> M;
  ASTContext &Ctx;
  llvm::raw_ostream &Out;
  const bool HadError;
  SmallVector<bool, 8> InImplicitBraceStmt;

  /// The stack of functions we're visiting.
  SmallVector<DeclContext *, 4> Functions;

  /// The stack of scopes we're visiting.
  using ScopeLike = llvm::PointerUnion<DeclContext *, BraceStmt *>;
  SmallVector<ScopeLike, 4> Scopes;

  /// The stack of generic environments.
  SmallVector<LazyGenericEnvironment, 2> GenericEnv;

  /// The stack of optional evaluations active at this point.
  SmallVector<OptionalEvaluationExpr *, 4> OptionalEvaluations;

  /// The set of opaque value expressions active at this point.
  llvm::DenseMap<OpaqueValueExpr *, unsigned> OpaqueValues;

  /// The set of opened existential archetypes that are currently
  /// active.
  llvm::DenseSet<OpenedArchetypeType *> OpenedExistentialArchetypes;

  /// The set of inout to pointer expr that match the following pattern:
  ///
  /// (call-expr
  ///    (brace-stmt
  ///      ... maybe other arguments ...
  ///      (inject_into_optional
  ///        (inout_to_pointer ...))
  ///      ... maybe other arguments ...))
  ///
  /// Any other inout to pointer expr that we see is invalid and the verifier
  /// will assert.
  llvm::DenseSet<InOutToPointerExpr *> ValidInOutToPointerExprs;
  llvm::DenseSet<ArrayToPointerExpr *> ValidArrayToPointerExprs;

  /// A key into ClosureDiscriminators is a combination of a
  /// ("canonicalized") local DeclContext* and a flag for whether to
  /// use the explicit closure sequence (false) or the implicit
  /// closure sequence (true).
  typedef llvm::PointerIntPair<DeclContext *, 1, bool> ClosureDiscriminatorKey;
  llvm::DenseMap<ClosureDiscriminatorKey, SmallBitVector>
      ClosureDiscriminators;
  DeclContext *CanonicalTopLevelContext = nullptr;

  Verifier(PointerUnion<ModuleDecl *, SourceFile *> M, DeclContext *DC)
      : M(M),
        Ctx(M.is<ModuleDecl *>() ? M.get<ModuleDecl *>()->getASTContext()
                                 : M.get<SourceFile *>()->getASTContext()),
        Out(llvm::errs()), HadError(Ctx.hadError()) {
    Scopes.push_back(DC);
    GenericEnv.push_back({DC});
  }

public:
  Verifier(ModuleDecl *M, DeclContext *DC)
      : Verifier(PointerUnion<ModuleDecl *, SourceFile *>(M), DC) {}
  Verifier(SourceFile &SF, DeclContext *DC) : Verifier(&SF, DC) {}

  static Verifier forDecl(const Decl *D) {
    DeclContext *DC = D->getDeclContext();
    DeclContext *topDC = DC->getModuleScopeContext();
    if (auto SF = dyn_cast<SourceFile>(topDC))
      return Verifier(*SF, DC);
    return Verifier(topDC->getParentModule(), DC);
  }

  std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
    switch (E->getKind()) {
#define DISPATCH(ID) return dispatchVisitPreExpr(static_cast<ID##Expr*>(E))
#define EXPR(ID, PARENT) \
      case ExprKind::ID: \
        DISPATCH(ID);
#define UNCHECKED_EXPR(ID, PARENT) \
      case ExprKind::ID: \
        assert((HadError || !M.is<SourceFile*>() || \
                M.get<SourceFile*>()->ASTStage < SourceFile::TypeChecked) && \
               #ID "in wrong phase");\
        DISPATCH(ID);
#include "swift/AST/ExprNodes.def"
#undef DISPATCH
      }
      llvm_unreachable("not all cases handled!");
    }

    Expr *walkToExprPost(Expr *E) override {
      switch (E->getKind()) {
#define DISPATCH(ID) return dispatchVisitPost(static_cast<ID##Expr*>(E))
#define EXPR(ID, PARENT) \
      case ExprKind::ID: \
        DISPATCH(ID);
#define UNCHECKED_EXPR(ID, PARENT) \
      case ExprKind::ID: \
        assert((HadError || !M.is<SourceFile*>() || \
                M.get<SourceFile*>()->ASTStage < SourceFile::TypeChecked) && \
               #ID "in wrong phase");\
        DISPATCH(ID);
#include "swift/AST/ExprNodes.def"
#undef DISPATCH
      }
      llvm_unreachable("not all cases handled!");
    }

    std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
      switch (S->getKind()) {
#define DISPATCH(ID) return dispatchVisitPreStmt(static_cast<ID##Stmt*>(S))
#define STMT(ID, PARENT) \
      case StmtKind::ID: \
        DISPATCH(ID);
#include "swift/AST/StmtNodes.def"
#undef DISPATCH
      }
      llvm_unreachable("not all cases handled!");
    }

    Stmt *walkToStmtPost(Stmt *S) override {
      switch (S->getKind()) {
#define DISPATCH(ID) return dispatchVisitPost(static_cast<ID##Stmt*>(S))
#define STMT(ID, PARENT) \
      case StmtKind::ID: \
        DISPATCH(ID);
#include "swift/AST/StmtNodes.def"
#undef DISPATCH
      }
      llvm_unreachable("not all cases handled!");
    }

    std::pair<bool, Pattern*> walkToPatternPre(Pattern *P) override {
      switch (P->getKind()) {
#define DISPATCH(ID) \
        return dispatchVisitPrePattern(static_cast<ID##Pattern*>(P))
#define PATTERN(ID, PARENT) \
      case PatternKind::ID: \
        DISPATCH(ID);
#include "swift/AST/PatternNodes.def"
#undef DISPATCH
      }
      llvm_unreachable("not all cases handled!");
    }

    Pattern *walkToPatternPost(Pattern *P) override {
      switch (P->getKind()) {
#define DISPATCH(ID) \
        return dispatchVisitPost(static_cast<ID##Pattern*>(P))
#define PATTERN(ID, PARENT) \
      case PatternKind::ID: \
        DISPATCH(ID);
#include "swift/AST/PatternNodes.def"
#undef DISPATCH
      }
      llvm_unreachable("not all cases handled!");
    }

    bool walkToDeclPre(Decl *D) override {
      switch (D->getKind()) {
#define DISPATCH(ID) return dispatchVisitPre(static_cast<ID##Decl*>(D))
#define DECL(ID, PARENT) \
      case DeclKind::ID: \
        DISPATCH(ID);
#include "swift/AST/DeclNodes.def"
#undef DISPATCH
      }
      llvm_unreachable("not all cases handled!");
    }

    bool walkToDeclPost(Decl *D) override {
      switch (D->getKind()) {
#define DISPATCH(ID) return dispatchVisitPost(static_cast<ID##Decl*>(D))
#define DECL(ID, PARENT) \
      case DeclKind::ID: \
        DISPATCH(ID);
#include "swift/AST/DeclNodes.def"
#undef DISPATCH
      }

      llvm_unreachable("Unhandled declaration kind");
    }

    /// Helper template for dispatching pre-visitation.
    /// If we're visiting in pre-order, don't validate the node yet;
    /// just check whether we should stop further descent.
    template <class T> bool dispatchVisitPre(T node) {
      if (shouldVerify(node))
        return true;
      cleanup(node);
      return false;
    }

    /// Helper template for dispatching pre-visitation.
    ///
    /// If we're visiting in pre-order, don't validate the node yet;
    /// just check whether we should stop further descent.
    template <class T> std::pair<bool, Expr *> dispatchVisitPreExpr(T node) {
      return dispatchVisitPreExprHelper<Verifier, T>(*this, node);
    }

    /// Helper template for dispatching pre-visitation.
    /// If we're visiting in pre-order, don't validate the node yet;
    /// just check whether we should stop further descent.
    template <class T> std::pair<bool, Stmt *> dispatchVisitPreStmt(T node) {
      if (shouldVerify(node))
        return { true, node };
      cleanup(node);
      return { false, node };
    }

    /// Helper template for dispatching pre-visitation.
    /// If we're visiting in pre-order, don't validate the node yet;
    /// just check whether we should stop further descent.
    template <class T>
    std::pair<bool, Pattern *> dispatchVisitPrePattern(T node) {
      if (shouldVerify(node))
        return { true, node };
      cleanup(node);
      return { false, node };
    }

    /// Helper template for dispatching post-visitation.
    template <class T> T dispatchVisitPost(T node) {
      // Verify source ranges if the AST node was parsed from source.
      auto *SF = M.dyn_cast<SourceFile *>();
      if (SF) {
        // If we are inside an implicit BraceStmt, don't verify source
        // locations.  LLDB creates implicit BraceStmts which contain a mix of
        // generated/user-written code.
        if (InImplicitBraceStmt.empty() || !InImplicitBraceStmt.back())
          checkSourceRanges(node);
      }

      // Check that nodes marked invalid have the correct type.
      checkErrors(node);

      // Always verify the node as a parsed node.
      verifyParsed(node);

      // If we've bound names already, verify as a bound node.
      if (!SF || SF->ASTStage >= SourceFile::NameBound)
        verifyBound(node);

      // If we've checked types already, do some extra verification.
      if (!SF || SF->ASTStage >= SourceFile::TypeChecked) {
        verifyCheckedAlways(node);
        if (!HadError && shouldVerifyChecked(node))
          verifyChecked(node);
      }

      // Clean up anything that we've placed into a stack to check.
      cleanup(node);

      // Always continue.
      return node;
    }

    // Default cases for whether we should verify within the given subtree.
    bool shouldVerify(Expr *E) { return true; }
    bool shouldVerify(Stmt *S) { return true; }
    bool shouldVerify(Pattern *S) { return true; }
    bool shouldVerify(Decl *S) { return true; }

    bool shouldVerify(TypeAliasDecl *typealias) {
      // Don't verify type aliases formed by the debugger; they violate some
      // AST invariants involving archetypes.
      if (typealias->isDebuggerAlias()) return false;

      return true;
    }

    // Default cases for whether we should verify a checked subtree.
    bool shouldVerifyChecked(Expr *E) {
      if (!E->getType()) {
        // For @objc enums, we serialize the pre-type-checked integer
        // literal raw values, and thus when they are deserialized
        // they do not have a type on them.
        if (!isa<IntegerLiteralExpr>(E)) {
          Out << "expression has no type\n";
          E->dump(Out);
          abort();
        }
      }
      return true;
    }
    bool shouldVerifyChecked(Stmt *S) { return true; }
    bool shouldVerifyChecked(Pattern *S) { return S->hasType(); }
    bool shouldVerifyChecked(Decl *S) { return true; }

    // Only verify functions if they have bodies we can safely walk.
    // FIXME: This is a bit of a hack; we should be able to check the
    // invariants of a parsed body as well.
    bool shouldVerify(AbstractFunctionDecl *afd) {
      switch (afd->getBodyKind()) {
      case AbstractFunctionDecl::BodyKind::None:
      case AbstractFunctionDecl::BodyKind::TypeChecked:
      case AbstractFunctionDecl::BodyKind::Skipped:
      case AbstractFunctionDecl::BodyKind::MemberwiseInitializer:
      case AbstractFunctionDecl::BodyKind::Deserialized:
        return true;

      case AbstractFunctionDecl::BodyKind::Unparsed:
      case AbstractFunctionDecl::BodyKind::Parsed:
      case AbstractFunctionDecl::BodyKind::Synthesize:
        if (auto SF = dyn_cast<SourceFile>(afd->getModuleScopeContext())) {
          return SF->ASTStage < SourceFile::TypeChecked;
        }

        return false;
      }
      llvm_unreachable("unhandled kind");
    }

    // Default cases for cleaning up as we exit a node.
    void cleanup(Expr *E) { }
    void cleanup(Stmt *S) { }
    void cleanup(Pattern *P) { }
    void cleanup(Decl *D) { }
    
    // Base cases for the various stages of verification.
    void verifyParsed(Expr *E) {}
    void verifyParsed(Stmt *S) {}
    void verifyParsed(Pattern *P) {}
    void verifyParsed(Decl *D) {
      if (!D->getDeclContext()) {
        Out << "every Decl should have a DeclContext";
        PrettyStackTraceDecl debugStack("verifying DeclContext", D);
        abort();
      }
    }
    template<typename T>
    void verifyParsedBase(T ASTNode) {
      verifyParsed(cast<typename ASTNodeBase<T>::BaseTy>(ASTNode));
    }

    void verifyBound(Expr *E) {}
    void verifyBound(Stmt *S) {}
    void verifyBound(Pattern *P) {}
    void verifyBound(Decl *D) {}

    /// @{
    /// These verification functions are always run on type checked ASTs
    /// (even if there were errors).
    void verifyCheckedAlways(Expr *E) {
      if (E->getType())
        verifyChecked(E->getType());
    }
    void verifyCheckedAlways(Stmt *S) {}
    void verifyCheckedAlways(Pattern *P) {
      if (P->hasType() && !P->getDelayedInterfaceType())
        verifyChecked(P->getType());
    }
    void verifyCheckedAlways(Decl *D) {
    }

    template<typename T>
    void verifyCheckedAlwaysBase(T ASTNode) {
      verifyCheckedAlways(cast<typename ASTNodeBase<T>::BaseTy>(ASTNode));
    }
    /// @}

    /// @{
    /// These verification functions are run on type checked ASTs if there were
    /// no errors.
    void verifyChecked(Expr *E) {
      // Some imported expressions don't have types, even in checked mode.
      // TODO: eliminate all these
      if (!E->getType()) {
        // For @objc enums, we serialize the pre-type-checked integer
        // literal raw values, and thus when they are deserialized
        // they do not have a type on them.
        if (!isa<IntegerLiteralExpr>(E)) {
          Out << "expression has no type\n";
          E->dump(Out);
          abort();
        }
        return;
      }
    }
    void verifyChecked(Stmt *S) {}
    void verifyChecked(Pattern *P) { }
    void verifyChecked(Decl *D) {}

    void verifyChecked(Type type) {
      llvm::SmallPtrSet<ArchetypeType *, 4> visitedArchetypes;
      verifyChecked(type, visitedArchetypes);
    }

    void
    verifyChecked(Type type,
                  llvm::SmallPtrSetImpl<ArchetypeType *> &visitedArchetypes) {
      if (!type)
        return;

      // Check for type variables that escaped the type checker.
      if (type->hasTypeVariable()) {
        Out << "a type variable escaped the type checker\n";
        abort();
      }

      if (!type->hasArchetype())
        return;

      bool foundError = type->getCanonicalType().findIf([&](Type type) -> bool {
        if (auto archetype = type->getAs<ArchetypeType>()) {
          // Only visit each archetype once.
          if (!visitedArchetypes.insert(archetype).second)
            return false;

          // We should know about archetypes corresponding to opened
          // existential archetypes.
          if (auto opened = dyn_cast<OpenedArchetypeType>(archetype)) {
            if (OpenedExistentialArchetypes.count(opened) == 0) {
              Out << "Found opened existential archetype "
                  << archetype->getString()
                  << " outside enclosing OpenExistentialExpr\n";
              return true;
            }

            return false;
          }

          // Otherwise, the archetype needs to be from this scope.
          if (GenericEnv.empty() || !GenericEnv.back()) {
            Out << "AST verification error: archetype outside of generic "
                   "context: " << archetype->getString() << "\n";
            return true;
          }

          // Get the primary archetype.
          auto *parent = archetype->getPrimary();

          if (!GenericEnv.back().containsPrimaryArchetype(parent)) {
            Out << "AST verification error: archetype "
                << archetype->getString() << " not allowed in this context\n";

            if (auto env = parent->getGenericEnvironment()) {
              if (auto owningDC = env->getOwningDeclContext()) {
                llvm::errs() << "archetype came from:\n";
                owningDC->dumpContext();
                llvm::errs() << "\n";
              }
            }

            return true;
          }

          // Make sure that none of the nested types are dependent.
          for (const auto &nested : archetype->getKnownNestedTypes()) {
            if (!nested.second)
              continue;
            
            if (auto nestedType = nested.second) {
              if (nestedType->hasTypeParameter()) {
                Out << "Nested type " << nested.first.str()
                    << " of archetype " << archetype->getString()
                    << " is dependent type " << nestedType->getString()
                    << "\n";
                return true;
              }
            }

            verifyChecked(nested.second, visitedArchetypes);
          }
        }

        return false;
      });
      
      if (foundError)
        abort();
    }

    template<typename T>
    void verifyCheckedBase(T ASTNode) {
      verifyChecked(cast<typename ASTNodeBase<T>::BaseTy>(ASTNode));
    }
    /// @}

    // Specialized verifiers.

    void pushScope(DeclContext *scope) {
      Scopes.push_back(scope);
      GenericEnv.push_back({scope});
    }
    void pushScope(BraceStmt *scope) {
      Scopes.push_back(scope);
    }
    void popScope(DeclContext *scope) {
      assert(Scopes.back().get<DeclContext*>() == scope);
      assert(GenericEnv.back().storage.get<DeclContext *>() == scope);
      Scopes.pop_back();
      GenericEnv.pop_back();
    }
    void popScope(BraceStmt *scope) {
      assert(Scopes.back().get<BraceStmt*>() == scope);
      Scopes.pop_back();
    }

    void pushFunction(DeclContext *functionScope) {
      pushScope(functionScope);
      Functions.push_back(functionScope);
    }
    void popFunction(DeclContext *functionScope) {
      assert(Functions.back() == functionScope);
      Functions.pop_back();
      popScope(functionScope);
    }

#define FUNCTION_LIKE(NODE)                                     \
    bool shouldVerify(NODE *fn) {                               \
      pushFunction(fn);                                         \
      return shouldVerify(cast<ASTNodeBase<NODE*>::BaseTy>(fn));\
    }                                                           \
    void cleanup(NODE *fn) {                                    \
      popFunction(fn);                                          \
    }
#define SCOPE_LIKE(NODE)                                        \
    bool shouldVerify(NODE *fn) {                               \
      pushScope(fn);                                            \
      if (fn->hasLazyMembers())                                 \
        return false;                                           \
      if (fn->getASTContext().hasUnparsedMembers(fn))           \
        return false;                                           \
      return shouldVerify(cast<ASTNodeBase<NODE*>::BaseTy>(fn));\
    }                                                           \
    void cleanup(NODE *fn) {                                    \
      popScope(fn);                                             \
    }

    FUNCTION_LIKE(AbstractClosureExpr)
    FUNCTION_LIKE(ConstructorDecl)
    FUNCTION_LIKE(DestructorDecl)
    FUNCTION_LIKE(FuncDecl)
    SCOPE_LIKE(NominalTypeDecl)
    SCOPE_LIKE(ExtensionDecl)

#undef SCOPE_LIKE
#undef FUNCTION_LIKE

    bool shouldVerify(BraceStmt *BS) {
      pushScope(BS);
      InImplicitBraceStmt.push_back(BS->isImplicit());
      return shouldVerify(cast<Stmt>(BS));
    }

    void cleanup(BraceStmt *BS) {
      InImplicitBraceStmt.pop_back();
      popScope(BS);
    }

    bool shouldVerify(OpenExistentialExpr *expr) {
      if (!shouldVerify(cast<Expr>(expr)))
        return false;

      // In rare instances we clear the opaque value because we no
      // longer have a subexpression that references it.
      if (!expr->getOpaqueValue())
        return true;

      assert(!OpaqueValues.count(expr->getOpaqueValue()));
      OpaqueValues[expr->getOpaqueValue()] = 0;
      assert(OpenedExistentialArchetypes.count(expr->getOpenedArchetype())==0);
      OpenedExistentialArchetypes.insert(expr->getOpenedArchetype());
      return true;
    }

    void cleanup(OpenExistentialExpr *expr) {
      // In rare instances we clear the opaque value because we no
      // longer have a subexpression that references it.
      if (!expr->getOpaqueValue())
        return;

      assert(OpaqueValues.count(expr->getOpaqueValue()));
      OpaqueValues.erase(expr->getOpaqueValue());
      assert(OpenedExistentialArchetypes.count(expr->getOpenedArchetype())==1);
      OpenedExistentialArchetypes.erase(expr->getOpenedArchetype());
    }

    bool shouldVerify(MakeTemporarilyEscapableExpr *expr) {
      if (!shouldVerify(cast<Expr>(expr)))
        return false;
      
      assert(!OpaqueValues.count(expr->getOpaqueValue()));
      OpaqueValues[expr->getOpaqueValue()] = 0;
      return true;
    }
    
    void cleanup(MakeTemporarilyEscapableExpr *expr) {
      assert(OpaqueValues.count(expr->getOpaqueValue()));
      OpaqueValues.erase(expr->getOpaqueValue());
    }

    // Keep a stack of the currently-live optional evaluations.
    bool shouldVerify(OptionalEvaluationExpr *expr) {
      if (!shouldVerify(cast<Expr>(expr)))
        return false;

      OptionalEvaluations.push_back(expr);
      return true;
    }
    void cleanup(OptionalEvaluationExpr *expr) {
      assert(OptionalEvaluations.back() == expr);
      OptionalEvaluations.pop_back();
    }

    // Register the OVEs in a collection upcast.
    bool shouldVerify(CollectionUpcastConversionExpr *expr) {
      if (!shouldVerify(cast<Expr>(expr)))
        return false;

      if (auto keyConversion = expr->getKeyConversion())
        OpaqueValues[keyConversion.OrigValue] = 0;
      if (auto valueConversion = expr->getValueConversion())
        OpaqueValues[valueConversion.OrigValue] = 0;
      return true;
    }
    void cleanup(CollectionUpcastConversionExpr *expr) {
      if (auto keyConversion = expr->getKeyConversion())
        OpaqueValues.erase(keyConversion.OrigValue);
      if (auto valueConversion = expr->getValueConversion())
        OpaqueValues.erase(valueConversion.OrigValue);
    }

    /// Canonicalize the given DeclContext pointer, in terms of
    /// producing something that can be looked up in
    /// ClosureDiscriminators.
    DeclContext *getCanonicalDeclContext(DeclContext *DC) {
      // All we really need to do is use a single TopLevelCodeDecl.
      if (auto topLevel = dyn_cast<TopLevelCodeDecl>(DC)) {
        if (!CanonicalTopLevelContext)
          CanonicalTopLevelContext = topLevel;
        return CanonicalTopLevelContext;
      }

      // TODO: check for uniqueness of initializer contexts?

      return DC;
    }

    /// Return the appropriate discriminator set for a closure expression.
    SmallBitVector &getClosureDiscriminators(AbstractClosureExpr *closure) {
      auto dc = getCanonicalDeclContext(closure->getParent());
      bool isAutoClosure = isa<AutoClosureExpr>(closure);
      return ClosureDiscriminators[ClosureDiscriminatorKey(dc, isAutoClosure)];
    }

    void verifyCheckedAlways(ValueDecl *D) {
      if (D->hasInterfaceType())
        verifyChecked(D->getInterfaceType());

      if (D->hasAccess()) {
        PrettyStackTraceDecl debugStack("verifying access", D);
        if (!D->getASTContext().isAccessControlDisabled() &&
            D->getFormalAccessScope().isPublic() &&
            D->getFormalAccess() < AccessLevel::Public) {
          Out << "non-public decl has no formal access scope\n";
          D->dump(Out);
          abort();
        }
        if (D->getEffectiveAccess() == AccessLevel::Private) {
          Out << "effective access should use 'fileprivate' for 'private'\n";
          D->dump(Out);
          abort();
        }
      }

      if (auto Overridden = getOverriddenDeclIfAvailable(D)) {
        if (D->getDeclContext() == Overridden->getDeclContext()) {
          PrettyStackTraceDecl debugStack("verifying overridden", D);
          Out << "cannot override a decl in the same DeclContext";
          D->dump(Out);
          Overridden->dump(Out);
          abort();
        }
      }
      
      if (D->didEarlyAttrValidation() &&
          D->getAttrs().hasAttribute<OverrideAttr>()) {
        if (!D->isInvalid() && D->hasInterfaceType() &&
            !isa<ClassDecl>(D->getDeclContext()) &&
            !isa<ProtocolDecl>(D->getDeclContext()) &&
            !isa<ExtensionDecl>(D->getDeclContext())) {
          PrettyStackTraceDecl debugStack("verifying override", D);
          Out << "'override' attribute outside of a class or protocol\n";
          D->dump(Out);
          abort();
        }
      }

      
      verifyCheckedAlwaysBase(D);
    }

    void verifyCheckedAlways(NominalTypeDecl *D) {
      verifyCheckedAlwaysBase(D);
    }

    bool shouldVerifyChecked(ThrowStmt *S) {
      return shouldVerifyChecked(S->getSubExpr());
    }

    void verifyChecked(ThrowStmt *S) {
      checkSameType(S->getSubExpr()->getType(),
                    checkExceptionTypeExists("throw expression"),
                    "throw operand");
      verifyCheckedBase(S);
    }

    bool shouldVerifyChecked(CatchStmt *S) {
      return shouldVerifyChecked(S->getErrorPattern());
    }

    void verifyChecked(CatchStmt *S) {
      checkSameType(S->getErrorPattern()->getType(),
                    checkExceptionTypeExists("catch statement"),
                    "catch pattern");
      verifyCheckedBase(S);
    }

    bool shouldVerifyChecked(ReturnStmt *S) {
      return !S->hasResult() || shouldVerifyChecked(S->getResult());
    }

    void verifyChecked(ReturnStmt *S) {
      auto func = Functions.back();
      Type resultType;
      if (auto *FD = dyn_cast<FuncDecl>(func)) {
        resultType = FD->getResultInterfaceType();
        resultType = FD->mapTypeIntoContext(resultType);
      } else if (auto closure = dyn_cast<AbstractClosureExpr>(func)) {
        resultType = closure->getResultType();
      } else {
        resultType = TupleType::getEmpty(Ctx);
      }
      
      if (S->hasResult()) {
        auto result = S->getResult();
        auto returnType = result->getType();
        // Make sure that the return has the same type as the function.
        checkSameType(resultType, returnType, "return type");
      } else {
        // Make sure that the function has a Void result type.
        checkSameType(resultType, TupleType::getEmpty(Ctx), "return type");
      }

      verifyCheckedBase(S);
    }
    void verifyChecked(DeferStmt *S) {
      auto FT = S->getTempDecl()->getInterfaceType()->castTo<AnyFunctionType>();
      assert(FT->isNoEscape() && "Defer statements must not escape");
      (void)FT;
      verifyCheckedBase(S);
    }

    void verifyChecked(FailStmt *S) {
      // Dig out the initializer we're in (if we are).
      ConstructorDecl *ctor = nullptr;
      if (!Functions.empty()) {
        ctor = dyn_cast<ConstructorDecl>(Functions.back());
      }

      // Fail statements are only permitted in initializers.
      if (!ctor) {
        Out << "'fail' statement outside of initializer\n";
        abort();
      }

      if (ctor->getFailability() == OTK_None && !ctor->isInvalid()) {
        Out << "non-failable initializer contains a 'fail' statement\n";
        ctor->dump(Out);
        abort();
      }
    }

    void checkConditionElement(const StmtConditionElement &elt) {
      switch (elt.getKind()) {
      case StmtConditionElement::CK_Availability: break;
      case StmtConditionElement::CK_Boolean: {
        auto *E = elt.getBoolean();
        if (shouldVerifyChecked(E))
          checkSameType(E->getType(), Ctx.getBoolDecl()->getDeclaredType(),
                        "condition type");
        break;
      }

      case StmtConditionElement::CK_PatternBinding:
        if (shouldVerifyChecked(elt.getPattern()) &&
            shouldVerifyChecked(elt.getInitializer())) {
          checkSameType(elt.getPattern()->getType(),
                    elt.getInitializer()->getType(),
                    "conditional binding type");
        }
        break;
      }
    }
    
    void checkCondition(StmtCondition C) {
      for (auto elt : C)
        checkConditionElement(elt);
    }
    
    void verifyChecked(IfStmt *S) {
      checkCondition(S->getCond());
      verifyCheckedBase(S);
    }

    void verifyChecked(GuardStmt *S) {
      checkCondition(S->getCond());
      verifyCheckedBase(S);
    }

    void verifyChecked(WhileStmt *S) {
      checkCondition(S->getCond());
      verifyCheckedBase(S);
    }

    Type checkAssignDest(Expr *Dest) {
      if (auto *TE = dyn_cast<TupleExpr>(Dest)) {
        SmallVector<TupleTypeElt, 4> lhsTupleTypes;
        for (unsigned i = 0; i != TE->getNumElements(); ++i) {
          Type SubType = checkAssignDest(TE->getElement(i));
          lhsTupleTypes.push_back(TupleTypeElt(SubType, TE->getElementName(i)));
        }
        return TupleType::get(lhsTupleTypes, Ctx);
      }
      return checkLValue(Dest->getType(), "LHS of assignment");
    }

    void verifyChecked(DeclRefExpr *E) {
      if (E->getType()->is<InOutType>()) {
        PrettyStackTraceExpr debugStack(Ctx, "verifying decl reference", E);
        Out << "reference with inout type "
          << E->getType().getString() << "\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      if (E->getType()->is<GenericFunctionType>()) {
        PrettyStackTraceExpr debugStack(Ctx, "verifying decl reference", E);
        Out << "unspecialized reference with polymorphic type "
          << E->getType().getString() << "\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      verifyCheckedBase(E);
    }

    void verifyChecked(AssignExpr *S) {
      Type lhsTy = checkAssignDest(S->getDest());
      checkSameType(lhsTy, S->getSrc()->getType(), "assignment operands");
      verifyCheckedBase(S);
    }
    
    void verifyChecked(EnumIsCaseExpr *E) {
      auto nom = E->getSubExpr()->getType()->getAnyNominal();
      if (!nom || !isa<EnumDecl>(nom)) {
        Out << "enum_is_decl operand is not an enum: ";
        E->getSubExpr()->getType().print(Out);
        Out << '\n';
        abort();
      }
      
      if (nom != E->getEnumElement()->getParentEnum()) {
        Out << "enum_is_decl case is not member of enum:\n";
        Out << "  case: ";
        E->getEnumElement()->print(Out);
        Out << "\n  type: ";
        E->getSubExpr()->getType().print(Out);
        Out << '\n';
        abort();
      }
    }

    void verifyChecked(TupleExpr *E) {
      const TupleType *exprTy = E->getType()->castTo<TupleType>();
      for_each(exprTy->getElements().begin(), exprTy->getElements().end(),
               E->getElements().begin(),
               [this](const TupleTypeElt &field, const Expr *elt) {
        if (!field.getType()->isEqual(elt->getType())) {
          Out << "tuple_expr element type mismatch:\n";
          Out << "  field: ";
          Out << field.getType() << "\n";
          Out << "  element: ";
          Out << elt->getType() << "\n";
          abort();
        }
      });
      // FIXME: Check all the variadic elements.
      verifyCheckedBase(E);
    }

    void verifyChecked(InOutExpr *E) {
      Type srcObj = checkLValue(E->getSubExpr()->getType(),
                                "result of InOutExpr");
      auto DestTy = E->getType()->castTo<InOutType>()->getObjectType();
      
      checkSameType(DestTy, srcObj, "object types for InOutExpr");
      verifyCheckedBase(E);
    }

    void verifyParsed(AbstractClosureExpr *E) {
      Type Ty = E->getType();
      if (!Ty)
        return;
      if (Ty->hasError())
        return;
      if (!Ty->is<FunctionType>()) {
        PrettyStackTraceExpr debugStack(Ctx, "verifying closure", E);
        Out << "a closure should have a function type";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      verifyParsedBase(E);
    }

    void verifyChecked(AbstractClosureExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying closure", E);

      assert(Scopes.back().get<DeclContext*>() == E);
      assert(E->getParent()->isLocalContext() &&
             "closure expression was not in local context!");

      // Check that the discriminator is unique in its context.
      auto &discriminatorSet = getClosureDiscriminators(E);
      unsigned discriminator = E->getDiscriminator();
      if (discriminator >= discriminatorSet.size()) {
        discriminatorSet.resize(discriminator+1);
        discriminatorSet.set(discriminator);
      } else if (discriminatorSet.test(discriminator)) {
        Out << "a closure must have a unique discriminator in its context\n";
        E->dump(Out);
        Out << "\n";
        abort();
      } else {
        discriminatorSet.set(discriminator);
      }

      // If the enclosing scope is a DC directly, rather than a local scope,
      // then the closure should be parented by an Initializer.  Otherwise,
      // it should be parented by the innermost function.
      auto enclosingScope = Scopes[Scopes.size() - 2];
      auto enclosingDC = enclosingScope.dyn_cast<DeclContext*>();
      if (enclosingDC && !isa<AbstractClosureExpr>(enclosingDC)
          && !(isa<SourceFile>(enclosingDC)
               && cast<SourceFile>(enclosingDC)->Kind == SourceFileKind::REPL)){
        auto parentDC = E->getParent();
        if (!isa<Initializer>(parentDC)) {
          Out << "a closure in non-local context should be parented "
                 "by an initializer or REPL context";
          E->dump(Out);
          Out << "\n";
          abort();
        } else if (parentDC->getParent() != enclosingDC) {
          Out << "closure in non-local context not grandparented by its "
                 "enclosing function";
          E->dump(Out);
          Out << "\n";
          abort();
        }
      } else if (Functions.size() >= 2 &&
                 Functions[Functions.size() - 2] != E->getParent()) {
        Out << "closure in local context not parented by its "
               "enclosing function";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      if (E->getDiscriminator() == AbstractClosureExpr::InvalidDiscriminator) {
        Out << "a closure expression should have a valid discriminator\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
    }

    void verifyChecked(MetatypeConversionExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying MetatypeConversion", E);

      auto destTy = checkMetatypeType(E->getType(),
                                      "result of MetatypeConversionExpr");
      auto srcTy = checkMetatypeType(E->getSubExpr()->getType(),
                                     "source of MetatypeConversionExpr");

      if (destTy->isEqual(srcTy)) {
        Out << "trivial MetatypeConversionExpr:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      checkTrivialSubtype(srcTy, destTy, "MetatypeConversionExpr");
      verifyCheckedBase(E);
    }
    
    void verifyChecked(ClassMetatypeToObjectExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying ClassMetatypeToObject", E);
      
      auto srcTy = checkMetatypeType(E->getSubExpr()->getType(),
                                     "source of ClassMetatypeToObject");
      
      if (!srcTy->mayHaveSuperclass()) {
        Out << "ClassMetatypeToObject with non-class metatype:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      
      if (!E->getType()->isEqual(Ctx.getAnyObjectType())) {
        Out << "ClassMetatypeToObject does not produce AnyObject:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
    }
    
    void verifyChecked(ExistentialMetatypeToObjectExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx,
                                    "verifying ExistentialMetatypeToObject", E);
      
      auto srcTy = checkMetatypeType(E->getSubExpr()->getType(),
                                     "source of ExistentialMetatypeToObject");
      
      if (!E->getSubExpr()->getType()->is<ExistentialMetatypeType>()) {
        Out << "ExistentialMetatypeToObject with non-existential "
               "metatype:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      if (!srcTy->isClassExistentialType()) {
        Out << "ExistentialMetatypeToObject with non-class existential "
               "metatype:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      
      if (!E->getType()->isEqual(Ctx.getAnyObjectType())) {
        Out << "ExistentialMetatypeToObject does not produce AnyObject:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
    }
    
    void verifyChecked(ProtocolMetatypeToObjectExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx,
                                    "verifying ProtocolMetatypeToObject", E);
      
      auto srcTy = checkMetatypeType(E->getSubExpr()->getType(),
                                     "source of ProtocolMetatypeToObject");
      if (E->getSubExpr()->getType()->is<ExistentialMetatypeType>()) {
        Out << "ProtocolMetatypeToObject with existential "
               "metatype:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      if (!srcTy->isExistentialType()) {
        Out << "ProtocolMetatypeToObject with non-existential metatype:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      auto layout = srcTy->getExistentialLayout();
      if (layout.explicitSuperclass ||
          !layout.isObjC() ||
          layout.getProtocols().size() != 1) {
        Out << "ProtocolMetatypeToObject with non-ObjC-protocol metatype:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      if (!E->getType()->getClassOrBoundGenericClass()) {
        Out << "ProtocolMetatypeToObject does not produce class:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
    }
    
    void verifyChecked(PointerToPointerExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx,
                                      "verifying PointerToPointer", E);

      auto fromElement = E->getSubExpr()->getType()->getAnyPointerElementType();
      auto toElement = E->getType()->getAnyPointerElementType();
      
      if (!fromElement || !toElement) {
        Out << "PointerToPointer does not convert between pointer types:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
    }
    
    void verifyChecked(InOutToPointerExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx,
                                      "verifying InOutToPointer", E);

      if (!ValidInOutToPointerExprs.count(E)) {
        Out << "InOutToPointerExpr in unexpected position!\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      auto fromElement = E->getSubExpr()->getType()->getInOutObjectType();
      auto toElement = E->getType()->getAnyPointerElementType();
      
      if (!E->getSubExpr()->getType()->is<InOutType>() && !toElement) {
        Out << "InOutToPointer does not convert from inout to pointer:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      
      // Ensure we don't convert an array to a void pointer this way.
      
      if (fromElement->getNominalOrBoundGenericNominal() == Ctx.getArrayDecl()
          && toElement->isEqual(Ctx.TheEmptyTupleType)) {
        Out << "InOutToPointer is converting an array to a void pointer; "
               "ArrayToPointer should be used instead:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
    }
    
    void verifyChecked(ArrayToPointerExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx,
                                      "verifying ArrayToPointer", E);

      if (!ValidArrayToPointerExprs.count(E)) {
        Out << "ArrayToPointer in invalid position?!\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      // The source may be optionally inout.
      auto fromArray = E->getSubExpr()->getType()->getInOutObjectType();
      
      if (fromArray->getNominalOrBoundGenericNominal() != Ctx.getArrayDecl()) {
        Out << "ArrayToPointer does not convert from array:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      
      auto toElement = E->getType()->getAnyPointerElementType();

      if (!toElement) {
        Out << "ArrayToPointer does not convert to pointer:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
    }
    
    void verifyChecked(StringToPointerExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx,
                                      "verifying StringToPointer", E);
      
      if (E->getSubExpr()->getType()->getNominalOrBoundGenericNominal()
            != Ctx.getStringDecl()) {
        Out << "StringToPointer does not convert from string:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      
      PointerTypeKind PTK;
      auto toElement = E->getType()->getAnyPointerElementType(PTK);
      if (!toElement) {
        Out << "StringToPointer does not convert to pointer:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      if (PTK != PTK_UnsafePointer && PTK != PTK_UnsafeRawPointer) {
        Out << "StringToPointer converts to non-const pointer:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
    }
    
    void verifyChecked(CollectionUpcastConversionExpr *E) {
      verifyChecked(E->getSubExpr());
      verifyCheckedBase(E);
    }
        
    void verifyChecked(DerivedToBaseExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying DerivedToBaseExpr", E);

      auto destTy = E->getType();
      auto srcTy = E->getSubExpr()->getType();
      if (destTy->isEqual(srcTy)) {
        Out << "trivial DerivedToBaseExpr:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      if (!destTy->getClassOrBoundGenericClass() ||
          !(srcTy->getClassOrBoundGenericClass() ||
            srcTy->is<DynamicSelfType>())) {
        Out << "DerivedToBaseExpr does not involve class types:\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      checkTrivialSubtype(srcTy, destTy, "DerivedToBaseExpr");
      verifyCheckedBase(E);
    }

    void verifyChecked(ErasureExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying ErasureExpr", E);

      if (!E->getType()->isAnyExistentialType()) {
        Out << "ErasureExpr result is not an existential: ";
        E->getType()->print(Out);
        Out << "\n";
        abort();
      }

      auto erasedTy = E->getType();
      auto concreteTy = E->getSubExpr()->getType();
      
      // Erasure can be from concrete to existential or from existential to more
      // general existential. If we look through metatypes then we're forced
      // into one or the other by context; otherwise, it doesn't matter.
      enum {
        AnyErasure,
        ConcreteErasureOnly,
        ExistentialErasureOnly,
      } knownConcreteErasure = AnyErasure;
      
      // Existential metatypes should be erased from (existential or concrete)
      // metatypes.
      while (auto meta = erasedTy->getAs<ExistentialMetatypeType>()) {
        erasedTy = meta->getInstanceType();
        if (auto concreteMeta = concreteTy->getAs<MetatypeType>()) {
          // If this is already forced to be an existential erasure, we
          // shouldn't be here, since (P & Q).Protocol.Type doesn't exist as
          // a type.
          assert(knownConcreteErasure != ExistentialErasureOnly);
          knownConcreteErasure = ConcreteErasureOnly;
          concreteTy = concreteMeta->getInstanceType();
        } else if (concreteTy->is<ExistentialMetatypeType>()) {
          // If this is already forced to be a concrete erasure (say we're going
          // from (P & Q).Type.Protocol to P.Type.Type), then this is invalid,
          // because it would require the existential metatype to be
          // "self-conforming" to the protocol's static requirements (in other
          // words, (P & Q).Type.self would have to be able to witness all of P's
          // static requirements), which is currently never the case.
          if (knownConcreteErasure == true) {
            Out << "ErasureExpr concrete metatype is not a subtype of the "
                   "existential metatype\n"
                   "Destination type: ";
            E->getType()->print(Out);
            Out << "\nSource type: ";
            E->getSubExpr()->getType()->print(Out);
            Out << "\n";
            abort();
          }
          knownConcreteErasure = ExistentialErasureOnly;
          concreteTy = concreteMeta->getInstanceType();
        } else {
          // Anything else wouldn't be a valid erasure to an existential
          // metatype.
          Out << "ErasureExpr from non-metatype to existential metatype\n"
                 "Destination type: ";
          E->getType()->print(Out);
          Out << "\nSource type: ";
          E->getSubExpr()->getType()->print(Out);
          Out << "\n";
          abort();
        }
      }

      auto erasedLayout = erasedTy->getCanonicalType()->getExistentialLayout();

      // An existential-to-existential erasure ought to reduce the set of
      // constraints.
      if (knownConcreteErasure != ConcreteErasureOnly
          && concreteTy->isExistentialType()) {
        // TODO
      } else {
        // Check class constraints.
        if (erasedLayout.requiresClass()) {
          // A class constraint can be satisfied by a class, class-constrained
          // archetype, or a class-constrained existential with no witness table
          // requirements.
          bool canBeClass;
          if (concreteTy->mayHaveSuperclass()) {
            canBeClass = true;
          } else if (concreteTy->isExistentialType()) {
            auto concreteLayout = concreteTy->getCanonicalType()
                                            ->getExistentialLayout();
            canBeClass = concreteLayout.getKind() == ExistentialLayout::Kind::Class
              && !concreteLayout.containsNonObjCProtocol;
          } else {
            canBeClass = false;
          }
          
          if (!canBeClass) {
            Out << "ErasureExpr from non-class to existential that requires a "
                   "class\n"
                   "Destination type: ";
            E->getType()->print(Out);
            Out << "\nSource type: ";
            E->getSubExpr()->getType()->print(Out);
            Out << "\n";
            abort();
          }
        }
        
        auto superclass = erasedLayout.getSuperclass();
        if (superclass
            && !superclass->isExactSuperclassOf(concreteTy)) {
          Out << "ErasureExpr from class to existential with a superclass "
                 "constraint that does not match the class\n"
                 "Destination type: ";
          E->getType()->print(Out);
          Out << "\nSource type: ";
          E->getSubExpr()->getType()->print(Out);
          Out << "\n";
          abort();
        }
        
        // A concrete-to-existential erasure should have conformances on hand
        // for all of the existential's requirements.
        auto conformances = E->getConformances();
        for (auto proto : erasedLayout.getProtocols()) {
          if (std::find_if(conformances.begin(), conformances.end(),
                           [&](ProtocolConformanceRef ref) -> bool {
                             return ref.getRequirement() == proto->getDecl();
                           })
              == conformances.end()) {
            Out << "ErasureExpr is missing conformance for required protocol\n";
            E->getType()->print(Out);
            Out << "\nSource type: ";
            E->getSubExpr()->getType()->print(Out);
            Out << "\n";
            abort();
          }
          // TODO: Verify that the conformance applies to the type?
        }
        
        // TODO: Check layout constraints?
      }
    }

    void verifyChecked(AnyHashableErasureExpr *E) {
      auto anyHashableDecl = Ctx.getAnyHashableDecl();
      if (!anyHashableDecl) {
        Out << "AnyHashable declaration could not be found\n";
        abort();
      }

      auto hashableDecl = Ctx.getProtocol(KnownProtocolKind::Hashable);
      if (!hashableDecl) {
        Out << "Hashable declaration could not be found\n";
        abort();
      }

      checkSameType(E->getType(), anyHashableDecl->getDeclaredType(),
                    "AnyHashableErasureExpr and the standard AnyHashable type");

      if (E->getConformance().getRequirement() != hashableDecl) {
        Out << "conformance on AnyHashableErasureExpr was not for Hashable\n";
        E->getConformance().dump();
        abort();
      }

      verifyConformance(E->getSubExpr()->getType(), E->getConformance());

      verifyCheckedBase(E);
    }

    void verifyChecked(TupleElementExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying TupleElementExpr", E);

      Type resultType = E->getType();
      Type baseType = E->getBase()->getType();
      checkSameLValueness(baseType, resultType,
                          "base and result of TupleElementExpr");

      TupleType *tupleType = baseType->getAs<TupleType>();
      if (!tupleType) {
        Out << "base of TupleElementExpr does not have tuple type: ";
        E->getBase()->getType().print(Out);
        Out << "\n";
        abort();
      }

      if (E->getFieldNumber() >= tupleType->getNumElements()) {
        Out << "field index " << E->getFieldNumber()
            << " for TupleElementExpr is out of range [0,"
            << tupleType->getNumElements() << ")\n";
        abort();
      }

      checkSameType(resultType, tupleType->getElementType(E->getFieldNumber()),
                    "TupleElementExpr and the corresponding tuple element");
      verifyCheckedBase(E);
    }

    void maybeRecordValidPointerConversion(Expr *Base, Expr *Arg) {
      auto handleSubExpr = [&](Expr *origSubExpr) {
        auto subExpr = origSubExpr;
        unsigned optionalDepth = 0;

        auto checkIsBindOptional = [&](Expr *expr) {
          for (unsigned depth = optionalDepth; depth; --depth) {
            if (auto bind = dyn_cast<BindOptionalExpr>(expr)) {
              expr = bind->getSubExpr();
            } else {
              Out << "malformed optional pointer conversion\n";
              origSubExpr->dump(Out);
              Out << '\n';
              abort();
            }
          }
        };

        // FIXME: This doesn't seem like a particularly robust
        //        approach to tracking whether pointer conversions
        //        always appear as call arguments.
        while (true) {
          // Look through optional evaluations.
          if (auto *optionalEval = dyn_cast<OptionalEvaluationExpr>(subExpr)) {
            subExpr = optionalEval->getSubExpr();
            optionalDepth++;
            continue;
          }

          // Look through injections into Optional<Pointer>.
          if (auto *injectIntoOpt = dyn_cast<InjectIntoOptionalExpr>(subExpr)) {
            subExpr = injectIntoOpt->getSubExpr();
            continue;
          }

          // FIXME: This is only handling the value conversion, not
          //        the key conversion. What this verifier check
          //        should probably do is just track whether we're
          //        currently visiting arguments of an apply when we
          //        find these conversions.
          if (auto *upcast =
                  dyn_cast<CollectionUpcastConversionExpr>(subExpr)) {
            subExpr = upcast->getValueConversion().Conversion;
            continue;
          }

          break;
        }

        // Record inout-to-pointer conversions.
        if (auto *inOutToPtr = dyn_cast<InOutToPointerExpr>(subExpr)) {
          ValidInOutToPointerExprs.insert(inOutToPtr);
          checkIsBindOptional(inOutToPtr->getSubExpr());
          return;
        }

        // Record array-to-pointer conversions.
        if (auto *arrayToPtr = dyn_cast<ArrayToPointerExpr>(subExpr)) {
          ValidArrayToPointerExprs.insert(arrayToPtr);
          checkIsBindOptional(arrayToPtr->getSubExpr());
          return;
        }
      };

      // If we have a tuple_shuffle, strip it off. We want to visit the
      // underlying paren or tuple expr.
      if (auto *TupleShuffle = dyn_cast<TupleShuffleExpr>(Arg)) {
        Arg = TupleShuffle->getSubExpr();
      }

      if (auto *ParentExprArg = dyn_cast<ParenExpr>(Arg)) {
        return handleSubExpr(ParentExprArg->getSubExpr());
      }

      if (auto *TupleArg = dyn_cast<TupleExpr>(Arg)) {
        for (auto *SubExpr : TupleArg->getElements()) {
          handleSubExpr(SubExpr);
        }
        return;
      }

      // Otherwise, just run it through handle sub expr. This case can happen if
      // we have an autoclosure.
      if (isa<AutoClosureExpr>(Base)) {
        handleSubExpr(Arg);
        return;
      }
    }

    void verifyChecked(ApplyExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying ApplyExpr", E);

      FunctionType *FT = E->getFn()->getType()->getAs<FunctionType>();
      if (!FT) {
        Out << "callee of apply expression does not have function type:";
        E->getFn()->getType().print(Out);
        Out << "\n";
        abort();
      }
      Type ResultExprTy = E->getType();
      if (!ResultExprTy->isEqual(FT->getResult())) {
        Out << "result of ApplyExpr does not match result type of callee:";
        E->getType().print(Out);
        Out << " vs. ";
        FT->getResult()->print(Out);
        Out << "\n";
        abort();
      }

      SmallVector<AnyFunctionType::Param, 8> Args;
      Type InputExprTy = E->getArg()->getType();
      AnyFunctionType::decomposeInput(InputExprTy, Args);
      auto Params = FT->getParams();
      if (!AnyFunctionType::equalParams(Args, Params)) {
        Out << "Argument type does not match parameter type in ApplyExpr:"
               "\nArgument type: ";
        InputExprTy.print(Out);
        Out << "\nParameter types: ";
        FT->printParams(Out);
        Out << "\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      if (!E->isThrowsSet()) {
        Out << "apply expression is not marked as throwing or non-throwing\n";
        E->dump(Out);
        Out << "\n";
        abort();
      } else if (E->throws() && !FT->throws()) {
        Out << "apply expression is marked as throwing, but function operand"
               "does not have a throwing function type\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      if (E->isSuper() != E->getArg()->isSuperExpr()) {
        Out << "Function application's isSuper() bit mismatch.\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      verifyCheckedBase(E);
    }

    void verifyChecked(MemberRefExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying MemberRefExpr", E);

      if (!E->getMember()) {
        Out << "Member reference is missing declaration\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      
      // The base of a member reference cannot be an existential type.
      if (E->getBase()->getType()->getWithoutSpecifierType()
            ->isAnyExistentialType()) {
        Out << "Member reference into an unopened existential type\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      // The only time the base is allowed to be inout is if we are accessing
      // a computed property or if the base is a protocol or existential.
      if (auto *baseIOT = E->getBase()->getType()->getAs<InOutType>()) {
        if (!baseIOT->getObjectType()->is<ArchetypeType>()) {
          auto *VD = dyn_cast<VarDecl>(E->getMember().getDecl());
          if (!VD || VD->getAllAccessors().empty()) {
            Out << "member_ref_expr on value of inout type\n";
            E->dump(Out);
            Out << "\n";
            abort();
          }
        }
      }
      
      // FIXME: Check container/member types through substitutions.

      verifyCheckedBase(E);
    }

    void verifyChecked(DynamicMemberRefExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying DynamicMemberRefExpr", E);

      // The base of a dynamic member reference cannot be an
      // existential type.
      if (E->getBase()->getType()->getWithoutSpecifierType()
            ->isAnyExistentialType()) {
        Out << "Member reference into an unopened existential type\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      verifyCheckedBase(E);
    }

    void verifyChecked(SubscriptExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying SubscriptExpr", E);

      if (!E->hasDecl()) {
        Out << "Subscript expression is missing subscript declaration";
        abort();
      }

      // The base of a subscript cannot be an existential type.
      if (E->getBase()->getType()->getWithoutSpecifierType()
            ->isAnyExistentialType()) {
        Out << "Member reference into an unopened existential type\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      // FIXME: Check base/member types through substitutions.

      verifyCheckedBase(E);
    }

    void verifyChecked(DynamicSubscriptExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying DynamicSubscriptExpr", E);

      // The base of a subscript cannot be an existential type.
      if (E->getBase()->getType()->getWithoutSpecifierType()
            ->isAnyExistentialType()) {
        Out << "Member reference into an unopened existential type\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      // FIXME: Check base/member types through substitutions.

      verifyCheckedBase(E);
    }
    
    void checkOptionalObjectType(Type optionalType,
                                 Type objectType,
                                 Expr *E) {
      auto optionalRVType = optionalType->getRValueType();
      auto objectRVType = objectType->getRValueType();

      checkSameType(objectRVType, optionalRVType->getOptionalObjectType(),
                    "optional object type");

      if (objectType->is<LValueType>() != optionalType->is<LValueType>()) {
        Out << "optional operation must preserve lvalue-ness of base\n";
        E->dump(Out);
        abort();
      }
    }

    void verifyChecked(OptionalEvaluationExpr *E) {
      if (E->getType()->hasLValueType()) {
        Out << "Optional evaluation should not produce an lvalue";
        E->dump(Out);
        abort();
      }
      checkSameType(E->getType(), E->getSubExpr()->getType(),
                    "OptionalEvaluation cannot change type");
    }
    
    void verifyChecked(BindOptionalExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying BindOptionalExpr", E);

      if (E->getDepth() >= OptionalEvaluations.size()) {
        Out << "BindOptional expression is out of its depth\n";
        E->dump(Out);
        abort();
      }
      
      checkOptionalObjectType(E->getSubExpr()->getType(),
                              E->getType(), E);
      
      verifyCheckedBase(E);
    }

    void verifyChecked(CheckedCastExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying CheckCastExpr", E);

      if (!E->isResolved()) {
        Out << "CheckedCast kind not resolved\n";
        abort();
      }

      verifyCheckedBase(E);
    }

    void verifyChecked(CoerceExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying CoerceExpr", E);

      checkSameType(E->getType(), E->getSubExpr()->getType(),
                    "coercion type and subexpression type");

      verifyCheckedBase(E);
    }

    void verifyChecked(IdentityExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying IdentityExpr", E);
      if (!E->getType()->isEqual(E->getSubExpr()->getType())) {
        Out << "Unexpected types in IdentityExpr\n";
        abort();
      }

      verifyCheckedBase(E);
    }

    void verifyChecked(AnyTryExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying AnyTryExpr", E);

      if (!isa<OptionalTryExpr>(E)) {
        checkSameType(E->getType(), E->getSubExpr()->getType(),
                      "AnyTryExpr and sub-expression");
      }

      verifyCheckedBase(E);
    }

    void verifyChecked(OptionalTryExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying OptionalTryExpr", E);

      if (Ctx.LangOpts.isSwiftVersionAtLeast(5)) {
        checkSameType(E->getType(), E->getSubExpr()->getType(),
                      "OptionalTryExpr and sub-expression");
      }
      else {
        Type unwrappedType = E->getType()->getOptionalObjectType();
        if (!unwrappedType) {
          Out << "OptionalTryExpr result type is not optional\n";
          abort();
        }
        
        checkSameType(unwrappedType, E->getSubExpr()->getType(),
                      "OptionalTryExpr and sub-expression");
      }
      
      verifyCheckedBase(E);
    }

    void verifyChecked(TupleShuffleExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying TupleShuffleExpr", E);

      auto getSubElementType = [&](unsigned i) {
        if (E->isSourceScalar()) {
          assert(i == 0);
          return E->getSubExpr()->getType();
        } else {
          return (E->getSubExpr()->getType()->castTo<TupleType>()
                   ->getElementType(i));
        }
      };

      /// Retrieve the ith element type from the resulting tuple type.
      auto getOuterElementType = [&](unsigned i) -> Type {
        if (E->isResultScalar()) {
          assert(i == 0);
          return E->getType()->getWithoutParens();
        } else {
          return E->getType()->castTo<TupleType>()->getElementType(i);
        }
      };

      Type varargsType;
      unsigned callerDefaultArgIndex = 0;
      for (unsigned i = 0, e = E->getElementMapping().size(); i != e; ++i) {
        int subElem = E->getElementMapping()[i];
        if (subElem == TupleShuffleExpr::DefaultInitialize)
          continue;
        if (subElem == TupleShuffleExpr::Variadic) {
          varargsType = (E->getType()->castTo<TupleType>()
                          ->getElement(i).getVarargBaseTy());
          break;
        }
        if (subElem == TupleShuffleExpr::CallerDefaultInitialize) {
          auto init = E->getCallerDefaultArgs()[callerDefaultArgIndex++];
          if (!getOuterElementType(i)->isEqual(init->getType())) {
            Out << "Type mismatch in TupleShuffleExpr\n";
            abort();
          }
          continue;
        }
        if (!getOuterElementType(i)->isEqual(getSubElementType(subElem))) {
          Out << "Type mismatch in TupleShuffleExpr\n";
          abort();
        }
      }
      if (varargsType) {
        for (auto sourceIdx : E->getVariadicArgs()) {
          if (!getSubElementType(sourceIdx)->isEqual(varargsType)) {
            Out << "Vararg type mismatch in TupleShuffleExpr\n";
            abort();
          }
        }
      }

      verifyCheckedBase(E);
    }
    
    void verifyChecked(DynamicTypeExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying DynamicTypeExpr", E);

      auto metatype = E->getType()->getAs<AnyMetatypeType>();
      if (!metatype) {
        Out << "DynamicTypeExpr must have metatype type\n";
        abort();
      }

      checkSameType(E->getBase()->getType(), metatype->getInstanceType(),
                    "base type of .Type expression");
      verifyCheckedBase(E);
    }

    void verifyChecked(InjectIntoOptionalExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying InjectIntoOptionalExpr",
                                      E);

      auto valueType = E->getType()->getOptionalObjectType();
      if (!valueType) {
        Out << "InjectIntoOptionalExpr is not of Optional type";
        abort();
      }

      if (!E->getSubExpr()->getType()->isEqual(valueType)) {
        Out << "InjectIntoOptionalExpr operand is not of the value type";
        abort();
      }
      verifyCheckedBase(E);
    }

    void verifyChecked(IfExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying IfExpr", E);

      auto condTy = E->getCondExpr()->getType();
      if (!condTy->isBool()) {
        Out << "IfExpr condition is not Bool\n";
        abort();
      }

      checkSameType(E->getThenExpr()->getType(),
                    E->getElseExpr()->getType(),
                    "then and else branches of an if-expr");
      verifyCheckedBase(E);
    }
    
    void verifyChecked(SuperRefExpr *expr) {
      verifyCheckedBase(expr);
    }

    void verifyChecked(TypeExpr *expr) {
      if (!expr->getType()->is<AnyMetatypeType>()) {
        Out << "TypeExpr must have metatype type\n";
        abort();
      }

      verifyCheckedBase(expr);
    }

    void verifyChecked(ForceValueExpr *E) {
      checkOptionalObjectType(E->getSubExpr()->getType(),
                              E->getType(), E);
      
      verifyCheckedBase(E);
    }

    void verifyChecked(OpaqueValueExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying OpaqueValueExpr", E);

      if (!OpaqueValues.count(E)) {
        Out << "OpaqueValueExpr not introduced at this point in AST\n";
        abort();
      }

      ++OpaqueValues[E];

      // Make sure opaque values are uniquely-referenced.
      if (OpaqueValues[E] > 1) {
        Out << "Multiple references to unique OpaqueValueExpr\n";
        abort();
      }
      verifyCheckedBase(E);
    }
    
    void verifyChecked(MakeTemporarilyEscapableExpr *E) {
      PrettyStackTraceExpr debugStack(
        Ctx, "verifying MakeTemporarilyEscapableExpr", E);
      
      // Expression type should match subexpression.
      if (!E->getType()->isEqual(E->getSubExpr()->getType())) {
        Out << "MakeTemporarilyEscapableExpr type does not match subexpression";
        abort();
      }

      auto call = dyn_cast<CallExpr>(E->getSubExpr());
      if (!call) {
        Out << "MakeTemporarilyEscapableExpr subexpression is not a call\n";
        abort();
      }

      auto callFnTy = call->getFn()->getType()->getAs<FunctionType>();
      if (!callFnTy) {
        Out << "MakeTemporarilyEscapableExpr call does not call function\n";
        abort();
      }
      if (!callFnTy->getExtInfo().isNoEscape()) {
        Out << "MakeTemporarilyEscapableExpr called function is not noescape\n";
        abort();
      }

      auto callArgTy = call->getArg()->getType()->getAs<FunctionType>();
      if (!callArgTy) {
        Out << "MakeTemporarilyEscapableExpr call argument is not a function\n";
        abort();
      }

      // Closure and opaque value should both be functions, with the closure
      // noescape and the opaque value escapable but otherwise matching.
      auto closureFnTy =
          E->getNonescapingClosureValue()->getType()->getAs<FunctionType>();
      if (!closureFnTy) {
        Out << "MakeTemporarilyEscapableExpr closure type is not a closure\n";
        abort();
      }
      auto opaqueValueFnTy =
          E->getOpaqueValue()->getType()->getAs<FunctionType>();
      if (!opaqueValueFnTy) {
        Out << "MakeTemporarilyEscapableExpr opaque value type is not a "
               "closure\n";
        abort();
      }
      auto closureFnNoEscape =
          closureFnTy->withExtInfo(closureFnTy->getExtInfo().withNoEscape());
      auto opaqueValueNoEscape = opaqueValueFnTy->withExtInfo(
          opaqueValueFnTy->getExtInfo().withNoEscape());
      if (!closureFnNoEscape->isEqual(opaqueValueNoEscape)) {
        Out << "MakeTemporarilyEscapableExpr closure and opaque value type "
               "don't match\n";
        abort();
      }
    }
  
    void verifyChecked(KeyPathApplicationExpr *E) {
      PrettyStackTraceExpr debugStack(
        Ctx, "verifying KeyPathApplicationExpr", E);
      
      auto baseTy = E->getBase()->getType();
      auto keyPathTy = E->getKeyPath()->getType();
      auto resultTy = E->getType();
      
      if (auto nom = keyPathTy->getAs<NominalType>()) {
        if (nom->getDecl() == Ctx.getAnyKeyPathDecl()) {
          // AnyKeyPath application is <T> rvalue T -> rvalue Any?
          if (baseTy->is<LValueType>()) {
            Out << "AnyKeyPath application base is not an rvalue\n";
            abort();
          }
          auto resultObjTy = resultTy->getOptionalObjectType();
          if (!resultObjTy || !resultObjTy->isAny()) {
            Out << "AnyKeyPath application result must be Any?\n";
            abort();
          }
          return;
        }
      } else if (auto bgt = keyPathTy->getAs<BoundGenericType>()) {
        if (bgt->getDecl() == Ctx.getPartialKeyPathDecl()) {
          // PartialKeyPath<T> application is rvalue T -> rvalue Any
          if (!baseTy->isEqual(bgt->getGenericArgs()[0])) {
            Out << "PartialKeyPath application base doesn't match type\n";
            abort();
          }
          if (!resultTy->isAny()) {
            Out << "PartialKeyPath application result must be Any?\n";
            abort();
          }
          return;
        } else if (bgt->getDecl() == Ctx.getKeyPathDecl()) {
          // KeyPath<T, U> application is rvalue T -> rvalue U
          if (!baseTy->isEqual(bgt->getGenericArgs()[0])) {
            Out << "KeyPath application base doesn't match type\n";
            abort();
          }
          if (!resultTy->isEqual(bgt->getGenericArgs()[1])) {
            Out << "KeyPath application result doesn't match type\n";
            abort();
          }
          return;
        } else if (bgt->getDecl() == Ctx.getWritableKeyPathDecl()) {
          // WritableKeyPath<T, U> application is
          //    lvalue T -> lvalue U
          // or rvalue T -> rvalue U
          if (baseTy->is<LValueType>()) {
            if (!resultTy->is<LValueType>()) {
              Out << "WritableKeyPath base and result don't match lvalue-ness\n";
              abort();
            }
            baseTy = baseTy->getRValueType();
            resultTy = resultTy->getRValueType();
          }
          
          if (!baseTy->isEqual(bgt->getGenericArgs()[0])) {
            Out << "WritableKeyPath application base doesn't match type\n";
            abort();
          }
          if (!resultTy->isEqual(bgt->getGenericArgs()[1])) {
            Out << "WritableKeyPath application result doesn't match type\n";
            abort();
          }
          return;
        } else if (bgt->getDecl() == Ctx.getReferenceWritableKeyPathDecl()) {
          // ReferenceWritableKeyPath<T, U> application is
          //    rvalue T -> lvalue U
          // or lvalue T -> lvalue U
          // or rvalue T -> rvalue U
          if (baseTy->is<LValueType>()) {
            if (!resultTy->is<LValueType>()) {
              Out << "ReferenceWritableKeyPath base and result don't "
                     "match lvalue-ness\n";
              abort();
            }
            baseTy = baseTy->getRValueType();
            resultTy = resultTy->getRValueType();
          } else {
            resultTy = resultTy->getRValueType();
          }

          if (!baseTy->isEqual(bgt->getGenericArgs()[0])) {
            Out << "ReferenceWritableKeyPath application base doesn't "
                   "match type\n";
            abort();
          }
          if (!resultTy->isEqual(bgt->getGenericArgs()[1])) {
            Out << "ReferenceWritableKeyPath application result doesn't "
                   "match type\n";
            abort();
          }
          return;
        }
      }
      
      Out << "invalid key path type\n";
      abort();
    }

    void verifyChecked(LoadExpr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying LoadExpr", E);

      auto *subExpr = E->getSubExpr();
      if (isa<ParenExpr>(subExpr) || isa<ForceValueExpr>(subExpr)) {
        Out << "Immediate ParenExpr/ForceValueExpr should preceed a LoadExpr\n";
        E->dump(Out);
        Out << "\n";
        abort();
      }

      verifyCheckedBase(E);
    }

    void verifyChecked(ValueDecl *VD) {
      if (VD->getInterfaceType()->hasError()) {
        Out << "checked decl cannot have error type\n";
        VD->dump(Out);
        abort();
      }

      // Make sure that there are no archetypes in the interface type.
      if (!isa<VarDecl>(VD) && VD->getInterfaceType()->hasArchetype()) {
        Out << "Interface type contains archetypes\n";
        VD->dump(Out);
        abort();
      }

      if (VD->hasAccess()) {
        if (VD->getFormalAccess() == AccessLevel::Open) {
          if (!isa<ClassDecl>(VD) && !VD->isPotentiallyOverridable()) {
            Out << "decl cannot be 'open'\n";
            VD->dump(Out);
            abort();
          }
          if (VD->isFinal()) {
            Out << "decl cannot be both 'open' and 'final'\n";
            VD->dump(Out);
            abort();
          }
        }
      }

      verifyCheckedBase(VD);
    }

    bool shouldWalkIntoLazyInitializers() override {
      // We don't want to walk into lazy initializers because they should
      // have been reparented to their synthesized getter, which will
      // invalidate various invariants.
      return false;
    }

    void verifyChecked(PatternBindingDecl *binding) {
      // Look at all of the VarDecls being bound.
      for (auto entry : binding->getPatternList())
        if (auto *P = entry.getPattern())
          P->forEachVariable([&](VarDecl *VD) {
            // ParamDecls never get PBD's.
            assert(!isa<ParamDecl>(VD) && "ParamDecl has a PatternBindingDecl?");
          });
    }

    void verifyChecked(AbstractStorageDecl *ASD) {
      if (ASD->hasAccess() && ASD->isSettable(nullptr)) {
        auto setterAccess = ASD->getSetterFormalAccess();
        if (ASD->getSetter() &&
            ASD->getSetter()->getFormalAccess() != setterAccess) {
          Out << "AbstractStorageDecl's setter access is out of sync"
                 " with the access actually on the setter\n";
          abort();
        }
      }

      if (auto getter = ASD->getGetter()) {
        if (getter->isMutating() != ASD->isGetterMutating()) {
          Out << "AbstractStorageDecl::isGetterMutating is out of sync"
                 " with whether the getter is actually mutating\n";
          abort();
        }
      }
      if (auto setter = ASD->getSetter()) {
        if (setter->isMutating() != ASD->isSetterMutating()) {
          Out << "AbstractStorageDecl::isSetterMutating is out of sync"
                 " with whether the setter is actually mutating\n";
          abort();
        }
      }
      if (auto addressor = ASD->getAddressor()) {
        if (addressor->isMutating() != ASD->isGetterMutating()) {
          Out << "AbstractStorageDecl::isGetterMutating is out of sync"
                 " with whether immutable addressor is mutating";
          abort();
        }
      }
      if (auto reader = ASD->getReadCoroutine()) {
        if (reader->isMutating() != ASD->isGetterMutating()) {
          Out << "AbstractStorageDecl::isGetterMutating is out of sync"
                 " with whether read accessor is mutating";
          abort();
        }
      }
      if (auto addressor = ASD->getMutableAddressor()) {
        if (addressor->isMutating() != ASD->isSetterMutating()) {
          Out << "AbstractStorageDecl::isSetterMutating is out of sync"
                 " with whether mutable addressor is mutating";
          abort();
        }
      }
      if (auto modifier = ASD->getModifyCoroutine()) {
        if (modifier->isMutating() !=
            (ASD->isSetterMutating() || ASD->isGetterMutating())) {
          Out << "AbstractStorageDecl::isSetterMutating is out of sync"
                 " with whether modify addressor is mutating";
          abort();
        }
      }

      verifyCheckedBase(ASD);
    }

    void verifyChecked(VarDecl *var) {
      PrettyStackTraceDecl debugStack("verifying VarDecl", var);

      // Variables must have materializable type, unless they are parameters,
      // in which case they must either have l-value type or be anonymous.
      if (!var->getInterfaceType()->isMaterializable()) {
        if (!isa<ParamDecl>(var)) {
          Out << "VarDecl has non-materializable type: ";
          var->getType().print(Out);
          Out << "\n";
          abort();
        }

        if (!var->isInOut() && var->hasName()) {
          Out << "ParamDecl may only have non-materializable tuple type "
                 "when it is anonymous: ";
          var->getType().print(Out);
          Out << "\n";
          abort();
        }
      }

      // The fact that this is *directly* be a reference storage type
      // cuts the code down quite a bit in getTypeOfReference.
      if (var->getAttrs().hasAttribute<ReferenceOwnershipAttr>() !=
          isa<ReferenceStorageType>(var->getInterfaceType().getPointer())) {
        if (var->getAttrs().hasAttribute<ReferenceOwnershipAttr>()) {
          Out << "VarDecl has an ownership attribute, but its type"
                 " is not a ReferenceStorageType: ";
        } else {
          Out << "VarDecl has no ownership attribute, but its type"
                 " is a ReferenceStorageType: ";
        }
        var->getInterfaceType().print(Out);
        abort();
      }

      Type typeForAccessors = var->getValueInterfaceType();
      if (!var->getDeclContext()->contextHasLazyGenericEnvironment()) {
        typeForAccessors =
            var->getDeclContext()->mapTypeIntoContext(typeForAccessors);
        if (const FuncDecl *getter = var->getGetter()) {
          if (getter->getParameters()->size() != 0) {
            Out << "property getter has parameters\n";
            abort();
          }
          Type getterResultType = getter->getResultInterfaceType();
          getterResultType =
              var->getDeclContext()->mapTypeIntoContext(getterResultType);
          if (!getterResultType->isEqual(typeForAccessors)) {
            Out << "property and getter have mismatched types: '";
            typeForAccessors.print(Out);
            Out << "' vs. '";
            getterResultType.print(Out);
            Out << "'\n";
            abort();
          }
        }
      }

      if (const FuncDecl *setter = var->getSetter()) {
        if (!setter->getResultInterfaceType()->isVoid()) {
          Out << "property setter has non-Void result type\n";
          abort();
        }
        if (setter->getParameters()->size() == 0) {
          Out << "property setter has no parameters\n";
          abort();
        }
        if (setter->getParameters()->size() != 1) {
          Out << "property setter has 2+ parameters\n";
          abort();
        }
        const ParamDecl *param = setter->getParameters()->get(0);
        Type paramType = param->getInterfaceType();
        if (!var->getDeclContext()->contextHasLazyGenericEnvironment()) {
          paramType = var->getDeclContext()->mapTypeIntoContext(paramType);
          if (!paramType->isEqual(typeForAccessors)) {
            Out << "property and setter param have mismatched types:\n";
            typeForAccessors.dump(Out, 2);
            Out << "vs.\n";
            paramType.dump(Out, 2);
            abort();
          }
        }
      }

      if (var->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
        auto varTy = var->getInterfaceType()
                         ->getReferenceStorageReferent();

        // FIXME: Update to look for plain Optional once
        // ImplicitlyUnwrappedOptional is removed
        if (!varTy->getOptionalObjectType()) {
          Out << "implicitly unwrapped optional attribute should only be set on VarDecl "
                 "with optional type\n";
          abort();
        }
      }

      verifyCheckedBase(var);
    }

    // Dump a reference to the given declaration.
    void dumpRef(Decl *decl) {
      if (auto value = dyn_cast<ValueDecl>(decl))
        value->dumpRef(Out);
      else if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
        Out << "extension of ";
        if (ext->getExtendedType())
          ext->getExtendedType().print(Out);
      }
    }

    /// Verify that the given conformance makes sense for the given
    /// type.
    void verifyConformance(Type type, ProtocolConformanceRef conformance) {
      if (conformance.isAbstract()) {
        if (!type->is<ArchetypeType>() && !type->isAnyExistentialType()) {
          Out << "type " << type
              << " should not have an abstract conformance to "
              << conformance.getRequirement()->getName();
          abort();
        }

        return;
      }

      if (!type->isEqual(conformance.getConcrete()->getType())) {
        Out << "conforming type does not match conformance\n";
        Out << "conforming type:\n";
        type.dump(Out, 2);
        Out << "\nconformance:\n";
        conformance.getConcrete()->dump(Out, 2);
        Out << "\n";
        abort();
      }
    }

    void verifyChecked(SubstitutionMap substitutions){
      // FIXME: Check replacement types without forcing anything.
    }

    /// Check the given explicit protocol conformance.
    void verifyConformance(Decl *decl, ProtocolConformance *conformance) {
      PrettyStackTraceDecl debugStack("verifying protocol conformance", decl);

      if (!conformance) {
        // FIXME: Eventually, this should itself be a verification
        // failure.
        return;
      }

      switch (conformance->getState()) {
      case ProtocolConformanceState::Complete:
        // More checking below.
        break;
        
      case ProtocolConformanceState::Incomplete:
        // Ignore incomplete conformances; we didn't need them.
        return;

      case ProtocolConformanceState::CheckingTypeWitnesses:
      case ProtocolConformanceState::Checking:
        dumpRef(decl);
        Out << " has a protocol conformance that is still being checked "
            << conformance->getProtocol()->getName().str() << "\n";
        abort();
      }

      auto normal = dyn_cast<NormalProtocolConformance>(conformance);
      if (!normal)
        return;

      // If the conformance is lazily resolved, don't check it; that can cause
      // massive deserialization at a point where the compiler cannot handle it.
      if (normal->isLazilyLoaded()) return;

      // Translate the owning declaration into a DeclContext.
      auto *nominal = dyn_cast<NominalTypeDecl>(decl);
      DeclContext *conformingDC;
      if (nominal) {
        conformingDC = nominal;
      } else {
        auto ext = cast<ExtensionDecl>(decl);
        conformingDC = ext;
        nominal = ext->getExtendedNominal();
      }

      auto proto = conformance->getProtocol();
      if (normal->getDeclContext() != conformingDC) {
        Out << "AST verification error: conformance of "
            << nominal->getName().str() << " to protocol "
            << proto->getName().str() << " is in the wrong context.\n"
            << "Owning context:\n";
        conformingDC->printContext(Out);
        Out << "Conformance context:\n";
        normal->getDeclContext()->printContext(Out);
        abort();
      }

      // Check that a normal protocol conformance is complete.
      for (auto member : proto->getMembers()) {
        if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
          if (!normal->hasTypeWitness(assocType)) {
            dumpRef(decl);
            Out << " is missing type witness for "
                << conformance->getProtocol()->getName().str() 
                << "." << assocType->getName().str()
                << "\n";
            abort();
          }

          // Make sure that the replacement type only uses archetypes allowed
          // in the context where the normal conformance exists.
          auto replacementType = normal->getTypeWitness(assocType, nullptr);
          Verifier(M, normal->getDeclContext())
            .verifyChecked(replacementType);
          continue;
        }
          
        // No witness necessary for type aliases
        if (isa<TypeAliasDecl>(member))
          continue;
        
        // If this is an accessor for something, ignore it.
        if (isa<AccessorDecl>(member))
          continue;


        if (auto req = dyn_cast<ValueDecl>(member)) {
          if (!normal->hasWitness(req)) {
            if ((req->getAttrs().isUnavailable(Ctx) ||
                 req->getAttrs().hasAttribute<OptionalAttr>()) &&
                proto->isObjC()) {
              continue;
            }

            dumpRef(decl);
            Out << " is missing witness for "
                << conformance->getProtocol()->getName().str() 
                << "." << req->getBaseName()
                << "\n";
            abort();
          }

          // Check the witness substitutions.
          const auto &witness = normal->getWitness(req, nullptr);

          if (auto *genericEnv = witness.getSyntheticEnvironment())
            GenericEnv.push_back({genericEnv});

          verifyChecked(witness.getRequirementToSyntheticSubs());
          verifyChecked(witness.getSubstitutions());

          if (auto *genericEnv = witness.getSyntheticEnvironment()) {
            assert(GenericEnv.back().storage.dyn_cast<GenericEnvironment *>()
                     == genericEnv);
            GenericEnv.pop_back();
          }

          continue;
        }
      }

      // Make sure we have the right signature conformances.
      if (!normal->isInvalid()){
        auto conformances = normal->getSignatureConformances();
        unsigned idx = 0;
        for (const auto &req : proto->getRequirementSignature()) {
          if (req.getKind() != RequirementKind::Conformance)
            continue;

          if (idx >= conformances.size()) {
            Out << "error: not enough conformances for requirement signature\n";
            normal->dump(Out);
            abort();
          }

          auto reqProto =
            req.getSecondType()->castTo<ProtocolType>()->getDecl();
          if (reqProto != conformances[idx].getRequirement()) {
            Out << "error: wrong protocol in signature conformances: have "
              << conformances[idx].getRequirement()->getName().str()
              << ", expected " << reqProto->getName().str()<< "\n";
            normal->dump(Out);
            abort();
          }

          ++idx;
        }

        if (idx != conformances.size()) {
          Out << "error: too many conformances for requirement signature\n";
          normal->dump(Out);
          abort();
        }
      }
    }

    void verifyGenericEnvironment(Decl *D,
                                  GenericSignature *sig,
                                  GenericEnvironment *env) {
      if (!sig && !env)
        return;

      if (sig && env) {
        for (auto *paramTy : sig->getGenericParams()) {
          (void)env->mapTypeIntoContext(paramTy);
        }

        return;
      }

      Out << "Decl must have both signature and environment, or neither\n";
      D->dump(Out);
      abort();
    }

    void verifyChecked(GenericTypeDecl *generic) {
      if (!generic->hasLazyGenericEnvironment()) {
        verifyGenericEnvironment(generic,
                                 generic->getGenericSignature(),
                                 generic->getGenericEnvironment());
      }

      verifyCheckedBase(generic);
    }

    void verifyChecked(NominalTypeDecl *nominal) {
      // Make sure that the protocol conformances are complete.
      // Only do so within the source file of the nominal type,
      // because anywhere else this can trigger new type-check requests.
      if (auto sf = M.dyn_cast<SourceFile *>()) {
        if (nominal->getParentSourceFile() == sf) {
          for (auto conformance : nominal->getLocalConformances()) {
            verifyConformance(nominal, conformance);
          }
        }
      }

      verifyCheckedBase(nominal);
    }

    void verifyCheckedAlways(GenericTypeParamDecl *GTPD) {
      PrettyStackTraceDecl debugStack("verifying GenericTypeParamDecl", GTPD);

      const DeclContext *DC = GTPD->getDeclContext();
      if (!GTPD->getDeclContext()->isInnermostContextGeneric()) {
        Out << "DeclContext of GenericTypeParamDecl does not have "
               "generic params\n";
        abort();
      }

      GenericParamList *paramList =
          static_cast<const GenericContext *>(DC)->getGenericParams();
      if (!paramList) {
        Out << "DeclContext of GenericTypeParamDecl does not have "
               "generic params\n";
        abort();
      }

      if (paramList->getOuterParameters() &&
          !isa<ExtensionDecl>(DC)) {
        Out << "GenericParamList can only have outer parameters in an "
               "extension\n";
        abort();
      }

      unsigned currentDepth = DC->getGenericContextDepth();
      if (currentDepth < GTPD->getDepth()) {
        Out << "GenericTypeParamDecl has incorrect depth\n";
        abort();
      }
      while (currentDepth > GTPD->getDepth()) {
        paramList = paramList->getOuterParameters();
        --currentDepth;
      }
      assert(paramList && "this is guaranteed by the parameter list's depth");

      if (paramList->size() <= GTPD->getIndex() ||
          paramList->getParams()[GTPD->getIndex()] != GTPD) {
        if (llvm::is_contained(paramList->getParams(), GTPD))
          Out << "GenericTypeParamDecl has incorrect index\n";
        else
          Out << "GenericTypeParamDecl not found in GenericParamList; "
                 "incorrect depth or wrong DeclContext\n";
        abort();
      }

      verifyCheckedBase(GTPD);
    }

    void verifyChecked(ExtensionDecl *ext) {
      // Make sure that the protocol conformances are complete.
      for (auto conformance : ext->getLocalConformances()) {
        verifyConformance(ext, conformance);
      }

      verifyCheckedBase(ext);
    }

    void verifyParsed(EnumElementDecl *UED) {
      PrettyStackTraceDecl debugStack("verifying EnumElementDecl", UED);

      if (!isa<EnumDecl>(UED->getDeclContext())) {
        Out << "EnumElementDecl has wrong DeclContext";
        abort();
      }

      verifyParsedBase(UED);
    }

    void verifyParsed(AbstractFunctionDecl *AFD) {
      PrettyStackTraceDecl debugStack("verifying AbstractFunctionDecl", AFD);

      // All of the parameter names should match.
      if (!isa<DestructorDecl>(AFD)) { // Destructor has no non-self params.
        auto paramNames = AFD->getFullName().getArgumentNames();
        bool checkParamNames = (bool)AFD->getFullName();
        auto *firstParams = AFD->getParameters();

        if (checkParamNames &&
            paramNames.size() != firstParams->size()) {
          Out << "Function name does not match its argument pattern ("
              << paramNames.size() << " elements instead of "
              << firstParams->size() << ")\n";
          AFD->dump(Out);
          abort();
        }

        // This doesn't use for_each because paramNames shouldn't be checked
        // when the function is anonymous.
        for (size_t i = 0, e = firstParams->size(); i < e; ++i) {
          auto &param = firstParams->get(i);

          if (checkParamNames &&
              param->getArgumentName() != paramNames[i]) {
            Out << "Function full name doesn't match parameter's arg name\n";
            AFD->dump(Out);
            abort();
          }
        }
      }

      verifyParsedBase(AFD);
    }

    void verifyParsed(ConstructorDecl *CD) {
      PrettyStackTraceDecl debugStack("verifying ConstructorDecl", CD);

      auto *DC = CD->getDeclContext();
      if (!isa<NominalTypeDecl>(DC) && !isa<ExtensionDecl>(DC) &&
          !CD->isInvalid()) {
        Out << "ConstructorDecls outside nominal types and extensions "
               "should be marked invalid";
        abort();
      }

      verifyParsedBase(CD);
    }

    void verifyChecked(ProtocolDecl *PD) {
      PrettyStackTraceDecl debugStack("verifying ProtocolDecl", PD);

      if (PD->isObjC() && !PD->requiresClass()) {
        Out << "@objc protocols should be class protocols as well";
        abort();
      }
      verifyCheckedBase(PD);
    }

    void verifyChecked(ConstructorDecl *CD) {
      PrettyStackTraceDecl debugStack("verifying ConstructorDecl", CD);

      auto *ND = CD->getDeclContext()->getSelfNominalTypeDecl();
      if (!isa<ClassDecl>(ND) && !isa<StructDecl>(ND) && !isa<EnumDecl>(ND) &&
          !isa<ProtocolDecl>(ND) && !CD->isInvalid()) {
        Out << "ConstructorDecls outside structs, classes or enums "
               "should be marked invalid";
        abort();
      }

      // Verify that the optionality of the result type of the
      // initializer matches the failability of the initializer.
      if (!CD->isInvalid() &&
          CD->getDeclContext()->getDeclaredInterfaceType()->getAnyNominal() !=
              Ctx.getOptionalDecl()) {
        bool resultIsOptional = (bool) CD->getResultInterfaceType()->getOptionalObjectType();
        auto declIsOptional = CD->getFailability() != OTK_None;

        if (resultIsOptional != declIsOptional) {
          Out << "Initializer has result optionality/failability mismatch\n";
          CD->dump(llvm::errs());
          abort();
        }

        // Also check the interface type.
        if (auto genericFn 
              = CD->getInterfaceType()->getAs<GenericFunctionType>()) {
          resultIsOptional = (bool) genericFn->getResult()
              ->castTo<AnyFunctionType>()
              ->getResult()
              ->getOptionalObjectType();
          if (resultIsOptional != declIsOptional) {
            Out << "Initializer has result optionality/failability mismatch\n";
            CD->dump(llvm::errs());
            abort();
          }
        }
      }

      if (CD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
        if (!CD->getInterfaceType() ||
            !CD->getInterfaceType()->is<AnyFunctionType>()) {
          Out << "Expected ConstructorDecl to have a function type!\n";
          CD->dump(llvm::errs());
          abort();
        }

        if (CD->getFailability() != OTK_ImplicitlyUnwrappedOptional) {
          Out << "Expected IUO failability for constructor with IUO decl "
                 "attribute!\n";
          CD->dump(llvm::errs());
          abort();
        }

        auto resultTy = CD->getResultInterfaceType();

        // FIXME: Update to look for plain Optional once
        // ImplicitlyUnwrappedOptional is removed
        if (!resultTy->getOptionalObjectType()) {
          Out << "implicitly unwrapped optional attribute should only be set "
                 "on constructors with optional return types\n";
          CD->dump(llvm::errs());
          abort();
        }
      } else {
        if (CD->getFailability() == OTK_ImplicitlyUnwrappedOptional) {
          Out << "Expected IUO decl attribute for constructor with IUO "
                 "failability!\n";
          CD->dump(llvm::errs());
          abort();
        }
      }

      verifyCheckedBase(CD);
    }

    void verifyParsed(DestructorDecl *DD) {
      PrettyStackTraceDecl debugStack("verifying DestructorDecl", DD);

      if (DD->isGeneric()) {
        Out << "DestructorDecl cannot be generic";
        abort();
      }

      auto *DC = DD->getDeclContext();
      if (!isa<NominalTypeDecl>(DC) && !isa<ExtensionDecl>(DC) &&
          !DD->isInvalid()) {
        Out << "DestructorDecls outside nominal types and extensions "
               "should be marked invalid";
        abort();
      }

      verifyParsedBase(DD);
    }

    void verifyChecked(AbstractFunctionDecl *AFD) {
      PrettyStackTraceDecl debugStack("verifying AbstractFunctionDecl", AFD);

      // If this function is generic or is within a generic context, it should
      // have an interface type.
      if (AFD->isGenericContext() !=
          AFD->getInterfaceType()->is<GenericFunctionType>()) {
        Out << "Functions in generic context must have an interface type\n";
        AFD->dump(Out);
        abort();
      }

      // If the function has a generic interface type, it should also have a
      // generic signature.
      if (AFD->isGenericContext() !=
          (AFD->getGenericSignature() != nullptr)) {
        Out << "Functions in generic context must have a generic signature\n";
        AFD->dump(Out);
        abort();
      }

      if (!AFD->hasLazyGenericEnvironment()) {
        verifyGenericEnvironment(AFD,
                                 AFD->getGenericSignature(),
                                 AFD->getGenericEnvironment());
      }

      // If there is an interface type, it shouldn't have any unresolved
      // dependent member types.
      // FIXME: This is a general property of the type system.
      auto interfaceTy = AFD->getInterfaceType();
      if (auto unresolvedDependentTy
            = interfaceTy->findUnresolvedDependentMemberType()) {
        Out << "Unresolved dependent member type ";
        unresolvedDependentTy->print(Out);
        abort();
      }

      // Check that type members have an interface type of the form
      // (Self) -> (Args...) -> Result.
      if (AFD->hasImplicitSelfDecl()) {
        if (!interfaceTy->castTo<AnyFunctionType>()
              ->getResult()->is<FunctionType>()) {
          Out << "Interface type of method must return a function";
          interfaceTy->dump(Out);
          abort();
        }
      }

      // Throwing @objc methods must have a foreign error convention.
      if (AFD->isObjC() &&
          static_cast<bool>(AFD->getForeignErrorConvention())
            != AFD->hasThrows()) {
        if (AFD->hasThrows())
          Out << "@objc method throws but does not have a foreign error "
              << "convention";
        else
          Out << "@objc method has a foreign error convention but does not "
              << "throw";
        abort();
      }

      // If a decl has the Throws bit set, the ThrowsLoc should be valid,
      // and vice versa, unless the decl was imported, de-serialized, or
      // implicit.
      if (!AFD->isImplicit() &&
          isa<SourceFile>(AFD->getModuleScopeContext()) &&
          (AFD->getThrowsLoc().isValid() != AFD->hasThrows())) {
        Out << "function 'throws' location does not match 'throws' flag\n";
        AFD->dump(Out);
        abort();
      }

      // If a decl has the Throws bit set, the function type should throw,
      // and vice versa.
      auto fnTy = AFD->getInterfaceType()->castTo<AnyFunctionType>();
      if (AFD->hasImplicitSelfDecl())
        fnTy = fnTy->getResult()->castTo<FunctionType>();

      if (AFD->hasThrows() != fnTy->getExtInfo().throws()) {
        Out << "function 'throws' flag does not match function type\n";
        AFD->dump(Out);
        abort();
      }

      if (AFD->getForeignErrorConvention()
          && !AFD->isObjC() && !AFD->getAttrs().hasAttribute<CDeclAttr>()) {
        Out << "foreign error convention on non-@objc, non-@_cdecl function\n";
        AFD->dump(Out);
        abort();
      }

      verifyCheckedBase(AFD);
    }

    void verifyChecked(DestructorDecl *DD) {
      PrettyStackTraceDecl debugStack("verifying DestructorDecl", DD);

      auto *ND = DD->getDeclContext()->getSelfNominalTypeDecl();
      if (!isa<ClassDecl>(ND) && !DD->isInvalid()) {
        Out << "DestructorDecls outside classes should be marked invalid";
        abort();
      }
      verifyCheckedBase(DD);
    }

    void verifyChecked(FuncDecl *FD) {
      PrettyStackTraceDecl debugStack("verifying FuncDecl", FD);

      // Note that there's nothing inherently wrong with wanting to use this on
      // non-accessors in the future, but you should visit all call sites and
      // make sure we do the right thing, because this flag conflates several
      // different behaviors.
      if (FD->hasForcedStaticDispatch()) {
        auto *AD = dyn_cast<AccessorDecl>(FD);
        if (AD == nullptr) {
          Out << "hasForcedStaticDispatch() set on non-accessor\n";
          abort();
        }

        if (AD->getStorage()->requiresOpaqueAccessor(AD->getAccessorKind())) {
          Out << "hasForcedStaticDispatch() set on accessor that's opaque "
                 "for its storage\n";
          abort();
        }
      }

      if (FD->isMutating()) {
        if (!FD->isInstanceMember()) {
          Out << "mutating function is not an instance member\n";
          abort();
        }
        if (FD->getDeclContext()->getSelfClassDecl()) {
          Out << "mutating function in a class\n";
          abort();
        }
        const ParamDecl *selfParam = FD->getImplicitSelfDecl(
            /*createIfNeeded=*/false);
        if (selfParam && !selfParam->isInOut()) {
          Out << "mutating function does not have inout 'self'\n";
          abort();
        }
      } else {
        const ParamDecl *selfParam = FD->getImplicitSelfDecl(
            /*createIfNeeded=*/false);
        if (selfParam && selfParam->isInOut()) {
          Out << "non-mutating function has inout 'self'\n";
          abort();
        }
      }

      if (FD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
        if (!FD->getInterfaceType() ||
            !FD->getInterfaceType()->is<AnyFunctionType>()) {
          Out << "Expected FuncDecl to have a function type!\n";
          abort();
        }

        auto resultTy = FD->getResultInterfaceType();

        // FIXME: Update to look for plain Optional once
        // ImplicitlyUnwrappedOptional is removed
        if (!resultTy->getOptionalObjectType()) {
          Out << "implicitly unwrapped optional attribute should only be set "
                 "on functions with optional return types\n";
          abort();
        }
      }

      verifyCheckedBase(FD);
    }

    void verifyChecked(AccessorDecl *FD) {
      PrettyStackTraceDecl debugStack("verifying AccessorDecl", FD);

      auto *storageDecl = FD->getStorage();
      if (!storageDecl) {
        Out << "Missing storage decl\n";
        abort();
      }

      if (FD->isGetterOrSetter()) {
        if (FD->isFinal() != storageDecl->isFinal()) {
          Out << "Property and accessor do not match for 'final'\n";
          abort();
        }
        if (FD->isDynamic() != storageDecl->isDynamic() &&
            // We allow a non dynamic setter if there is a dynamic modify,
            // observer, or mutable addressor.
            !(FD->isSetter() &&
              (storageDecl->getWriteImpl() == WriteImplKind::Modify ||
               storageDecl->getWriteImpl() ==
                   WriteImplKind::StoredWithObservers ||
               storageDecl->getWriteImpl() == WriteImplKind::MutableAddress) &&
              storageDecl->isNativeDynamic()) &&
            // We allow a non dynamic getter if there is a dynamic read.
            !(FD->isGetter() &&
              (storageDecl->getReadImpl() == ReadImplKind::Read ||
               storageDecl->getReadImpl() == ReadImplKind::Address) &&
              storageDecl->isNativeDynamic())) {
          Out << "Property and accessor do not match for 'dynamic'\n";
          abort();
        }
        if (FD->isDynamic()) {
          if (FD->isObjC() != storageDecl->isObjC()) {
            Out << "Property and accessor do not match for '@objc'\n";
            abort();
          }
        }
      }

      auto storedAccessor = storageDecl->getAccessor(FD->getAccessorKind());
      if (storedAccessor != FD) {
        Out << "storage declaration has different accessor for this kind\n";
        abort();
      }

      verifyCheckedBase(FD);
    }

    void verifyParsed(FuncDecl *FD) {
      PrettyStackTraceDecl debugStack("verifying FuncDecl", FD);

      verifyParsedBase(FD);
    }

    void verifyParsed(AccessorDecl *FD) {
      PrettyStackTraceDecl debugStack("verifying AccessorDecl", FD);

      auto storage = FD->getStorage();
      if (storage->isStatic() != FD->isStatic()) {
        Out << "accessor static-ness must match static-ness of storage\n";
        abort();
      }

      verifyParsedBase(FD);
    }

    void verifyChecked(ClassDecl *CD) {
      PrettyStackTraceDecl debugStack("verifying ClassDecl", CD);
      
      if (!CD->hasLazyMembers()) {
        unsigned NumDestructors = 0;
        for (auto Member : CD->getMembers()) {
          if (isa<DestructorDecl>(Member)) {
            NumDestructors++;
          }
        }
        if (NumDestructors != 1) {
          Out << "every class should have exactly one destructor, "
                 "explicitly provided or created by the type checker\n";
          abort();
        }
      }
      
      if (!CD->hasDestructor()) {
        Out << "every class's 'has destructor' bit must be set\n";
        abort();
      }

      verifyCheckedBase(CD);
    }

    void verifyParsed(AssociatedTypeDecl *ATD) {
      PrettyStackTraceDecl debugStack("verifying AssociatedTypeDecl", ATD);

      auto *DC = ATD->getDeclContext();
      if (!isa<NominalTypeDecl>(DC) ||
          !isa<ProtocolDecl>(cast<NominalTypeDecl>(DC))) {
        Out << "AssociatedTypeDecl should only occur inside a protocol\n";
        abort();
      }
      verifyParsedBase(ATD);
    }

    void verifyParsed(TuplePattern *TP) {
      PrettyStackTracePattern debugStack(Ctx, "verifying TuplePattern", TP);
      verifyParsedBase(TP);
    }

    void verifyChecked(TuplePattern *TP) {
      PrettyStackTracePattern debugStack(Ctx, "verifying TuplePattern", TP);
      verifyCheckedBase(TP);
    }

    /// Look through a possible l-value type, returning true if it was
    /// an l-value.
    bool lookThroughLValue(Type &type, bool &isInOut) {
      if (LValueType *lv = type->getAs<LValueType>()) {
        Type objectType = lv->getObjectType();
        if (objectType->is<LValueType>()) {
          Out << "type is an lvalue of lvalue type: ";
          type.print(Out);
          Out << "\n";
        }
        isInOut = false;
        type = objectType;
        return true;
      }
      if (InOutType *io = type->getAs<InOutType>()) {
        Type objectType = io->getObjectType();
        if (objectType->is<InOutType>()) {
          Out << "type is an inout of inout type: ";
          type.print(Out);
          Out << "\n";
        }
        isInOut = true;
        type = objectType;
        return true;
      }
      return false;
    }

    /// The two types are required to either both be l-values or
    /// both not be l-values.  They are adjusted to not be l-values.
    /// Returns true if they are both l-values.
    bool checkSameLValueness(Type &T0, Type &T1,
                             const char *what) {
      bool Q0, Q1;
      bool isLValue0 = lookThroughLValue(T0, Q0);
      bool isLValue1 = lookThroughLValue(T1, Q1);
      
      if (isLValue0 != isLValue1) {
        Out << "lvalue-ness of " << what << " do not match: "
            << isLValue0 << ", " << isLValue1 << "\n";
        abort();
      }

      if (isLValue0 && Q0 != Q1) {
        Out << "qualification of " << what << " do not match\n";
        abort();
      }

      return isLValue0;
    }

    Type checkLValue(Type T, const char *what) {
      LValueType *LV = T->getAs<LValueType>();
      if (LV)
        return LV->getObjectType();

      Out << "type is not an l-value in " << what << ": ";
      T.print(Out);
      Out << "\n";
      abort();
    }

    // Verification utilities.
    Type checkMetatypeType(Type type, const char *what) {
      auto metatype = type->getAs<AnyMetatypeType>();
      if (metatype) return metatype->getInstanceType();

      Out << what << " is not a metatype: ";
      type.print(Out);
      Out << "\n";
      abort();
    }

    void checkSameType(Type T0, Type T1, const char *what) {
      if (T0->isEqual(T1))
        return;

      Out << "different types for " << what << ": ";
      T0.print(Out);
      Out << " vs. ";
      T1.print(Out);
      Out << "\n";
      abort();
    }

    void checkTrivialSubtype(Type srcTy, Type destTy, const char *what) {
      if (srcTy->isEqual(destTy)) return;

      if (auto srcMetatype = srcTy->getAs<AnyMetatypeType>()) {
        if (auto destMetatype = destTy->getAs<AnyMetatypeType>()) {
          return checkTrivialSubtype(srcMetatype->getInstanceType(),
                                     destMetatype->getInstanceType(),
                                     what);
        }
        goto fail;
      }

      // If the destination is a class, walk the supertypes of the source.
      if (destTy->getClassOrBoundGenericClass()) {
        if (!destTy->isBindableToSuperclassOf(srcTy)) {
          srcTy.print(Out);
          Out << " is not a superclass of ";
          destTy.print(Out);
          Out << " for " << what << "\n";
          abort();
        }

        return;
      }

      // FIXME: Tighten up checking for conversions to protocol types.
      if (destTy->isExistentialType())
        return;

    fail:
      Out << "subtype conversion in " << what << " is invalid: ";
      srcTy.print(Out);
      Out << " to ";
      destTy.print(Out);
      Out << "\n";
      abort();
    }

    void checkSameOrSubType(Type T0, Type T1, const char *what) {
      if (T0->isEqual(T1))
        return;

      // Protocol subtyping.
      if (auto Proto0 = T0->getAs<ProtocolType>())
        if (auto Proto1 = T1->getAs<ProtocolType>())
          if (Proto0->getDecl()->inheritsFrom(Proto1->getDecl()))
            return;
      
      // FIXME: Actually check this?
      if (T0->isExistentialType() || T1->isExistentialType())
        return;
      
      Out << "incompatible types for " << what << ": ";
      T0.print(Out);
      Out << " vs. ";
      T1.print(Out);
      Out << "\n";
      abort();
    }

    Type checkExceptionTypeExists(const char *where) {
      auto exn = Ctx.getErrorDecl();
      if (exn) return exn->getDeclaredType();

      Out << "exception type does not exist in " << where << "\n";
      abort();
    }

    bool isGoodSourceRange(SourceRange SR) {
      if (SR.isInvalid())
        return false;
      (void) Ctx.SourceMgr.findBufferContainingLoc(SR.Start);
      (void) Ctx.SourceMgr.findBufferContainingLoc(SR.End);
      return true;
    }
    
    template<typename T>
    void checkSourceRangesBase(T ASTNode) {
      checkSourceRanges(cast<typename ASTNodeBase<T>::BaseTy>(ASTNode));
    }
    
    void checkSourceRanges(Expr *E) {
      PrettyStackTraceExpr debugStack(Ctx, "verifying ranges", E);

      if (!E->getSourceRange().isValid()) {
        // We don't care about source ranges on implicitly-generated
        // expressions.
        if (E->isImplicit())
          return;

        Out << "invalid source range for expression: ";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      if (!isGoodSourceRange(E->getSourceRange())) {
        Out << "bad source range for expression: ";
        E->dump(Out);
        Out << "\n";
        abort();
      }
      // FIXME: Re-visit this to always do the check.
      if (!E->isImplicit())
        checkSourceRanges(E->getSourceRange(), Parent,
                          [&]{ E->dump(Out); } );
    }

    void checkSourceRanges(Stmt *S) {
      PrettyStackTraceStmt debugStack(Ctx, "verifying ranges", S);

      if (!S->getSourceRange().isValid()) {
        // We don't care about source ranges on implicitly-generated
        // statements.
        if (S->isImplicit())
          return;

        Out << "invalid source range for statement: ";
        S->dump(Out);
        Out << "\n";
        abort();
      }
      if (!isGoodSourceRange(S->getSourceRange())) {
        Out << "bad source range for statement: ";
        S->dump(Out);
        Out << "\n";
        abort();
      }
      checkSourceRanges(S->getSourceRange(), Parent,
                        [&]{ S->dump(Out); });
    }

    void checkSourceRanges(IfConfigDecl *ICD) {
      checkSourceRangesBase(ICD);

      SourceLoc Location = ICD->getStartLoc();
      for (auto &Clause : ICD->getClauses()) {
        // Clause start, note that the first clause start location is the
        // same as that of the whole statement
        if (Location == ICD->getStartLoc()) {
          if (Location != Clause.Loc) {
            Out << "bad start location of IfConfigDecl first clause\n";
            ICD->print(Out);
            abort();
          }
        } else {
          if (!Ctx.SourceMgr.isBeforeInBuffer(Location, Clause.Loc)) {
            Out << "bad start location of IfConfigDecl clause\n";
            ICD->print(Out);
            abort();
          }
        }
        Location = Clause.Loc;

        // Condition if present
        Expr *Cond = Clause.Cond;
        if (Cond) {
          if (!Ctx.SourceMgr.isBeforeInBuffer(Location, Cond->getStartLoc())) {
            Out << "invalid IfConfigDecl clause condition start location\n";
            ICD->print(Out);
            abort();
          }
          Location = Cond->getEndLoc();
        }
        
        // Body elements
        auto StoredLoc = Location;
        for (auto &Element : Clause.Elements) {
          auto StartLocation = Element.getStartLoc();
          if (StartLocation.isInvalid()) {
            continue;
          }
          
          if (!Ctx.SourceMgr.isBeforeInBuffer(StoredLoc, StartLocation)) {
            Out << "invalid IfConfigDecl clause element start location\n";
            ICD->print(Out);
            abort();
          }
          
          auto EndLocation = Element.getEndLoc();
          if (EndLocation.isValid() &&
              Ctx.SourceMgr.isBeforeInBuffer(Location, EndLocation)) {
            Location = EndLocation;
          }
        }
      }

      if (Ctx.SourceMgr.isBeforeInBuffer(ICD->getEndLoc(), Location)) {
        Out << "invalid IfConfigDecl end location\n";
        ICD->print(Out);
        abort();
      }
    }
    
    void checkSourceRanges(Pattern *P) {
      PrettyStackTracePattern debugStack(Ctx, "verifying ranges", P);

      // We don't care about source ranges on implicitly-generated
      // patterns.
      if (P->isImplicit())
        return;

      if (!P->getSourceRange().isValid()) {
        Out << "invalid source range for pattern: ";
        P->print(Out);
        Out << "\n";
        abort();
      }
      if (!isGoodSourceRange(P->getSourceRange())) {
        Out << "bad source range for pattern: ";
        P->print(Out);
        Out << "\n";
        abort();
      }
      checkSourceRanges(P->getSourceRange(), Parent,
                        [&]{ P->print(Out); });
    }

    void assertValidRegion(Decl *D) {
      auto R = D->getSourceRange();
      if (R.isValid() && Ctx.SourceMgr.isBeforeInBuffer(R.End, R.Start)) {
        Out << "invalid type source range for decl: ";
        D->print(Out);
        Out << "\n";
        abort();
      }
    }

    void checkSourceRanges(ParamDecl *PD) {
      assertValidRegion(PD);
    }

    void checkSourceRanges(Decl *D) {
      PrettyStackTraceDecl debugStack("verifying ranges", D);

      if (!D->getSourceRange().isValid()) {
        // We don't care about source ranges on implicitly-generated
        // decls.
        if (D->isImplicit())
          return;
        
        Out << "invalid source range for decl: ";
        D->print(Out);
        Out << "\n";
        abort();
      }
      checkSourceRanges(D->getSourceRange(), Parent,
                        [&]{ D->print(Out); });
    }

    /// Verify that the given source ranges is contained within the
    /// parent's source range.
    void checkSourceRanges(SourceRange Current, ASTWalker::ParentTy Parent,
                           llvm::function_ref<void()> printEntity) {
      SourceRange Enclosing;
      if (Parent.isNull())
          return;

      if (Parent.getAsModule()) {
        return;
      } else if (Decl *D = Parent.getAsDecl()) {
        Enclosing = D->getSourceRange();
        if (D->isImplicit())
          return;
        // FIXME: This is not working well for decl parents.
        return;
      } else if (Stmt *S = Parent.getAsStmt()) {
        Enclosing = S->getSourceRange();
        if (S->isImplicit())
          return;
      } else if (Pattern *P = Parent.getAsPattern()) {
        Enclosing = P->getSourceRange();
        if (P->isImplicit())
          return;
      } else if (Expr *E = Parent.getAsExpr()) {
        // FIXME: This hack is required because the inclusion check below
        // doesn't compares the *start* of the ranges, not the end of the
        // ranges.  In the case of an interpolated string literal expr, the
        // subexpressions are contained within the string token.  This means
        // that comparing the start of the string token to the end of an
        // embedded expression will fail.
        if (isa<InterpolatedStringLiteralExpr>(E))
          return;

        if (E->isImplicit())
          return;
        
        Enclosing = E->getSourceRange();
      } else if (TypeRepr *TyR = Parent.getAsTypeRepr()) {
        Enclosing = TyR->getSourceRange();
      } else {
        llvm_unreachable("impossible parent node");
      }
      
      if (!Ctx.SourceMgr.rangeContains(Enclosing, Current)) {
        Out << "child source range not contained within its parent: ";
        printEntity();
        Out << "\n  parent range: ";
        Enclosing.print(Out, Ctx.SourceMgr);
        Out << "\n  child range: ";
        Current.print(Out, Ctx.SourceMgr);
        Out << "\n";
        abort();
      }
    }

    void checkErrors(Expr *E) {}
    void checkErrors(Stmt *S) {}
    void checkErrors(Pattern *P) {}
    void checkErrors(Decl *D) {}
    void checkErrors(ValueDecl *D) {
      PrettyStackTraceDecl debugStack("verifying errors", D);

      if (!D->hasInterfaceType())
        return;
      if (D->getInterfaceType()->hasError() && !D->isInvalid()) {
        Out << "Valid decl has error type!\n";
        D->dump(Out);
        abort();
      }
    }
  };
} // end anonymous namespace

void swift::verify(SourceFile &SF) {
#if !(defined(NDEBUG) || defined(SWIFT_DISABLE_AST_VERIFIER))
  Verifier verifier(SF, &SF);
  SF.walk(verifier);
#endif
}

bool swift::shouldVerify(const Decl *D, const ASTContext &Context) {
#if !(defined(NDEBUG) || defined(SWIFT_DISABLE_AST_VERIFIER))
  if (const auto *ED = dyn_cast<ExtensionDecl>(D)) {
    return shouldVerify(ED->getExtendedNominal(), Context);
  }

  const auto *VD = dyn_cast<ValueDecl>(D);
  if (!VD) {
    // Verify declarations without names everywhere.
    return true;
  }

  return true;
#else
  return false;
#endif
}

void swift::verify(Decl *D) {
#if !(defined(NDEBUG) || defined(SWIFT_DISABLE_AST_VERIFIER))
  Verifier V = Verifier::forDecl(D);
  D->walk(V);
#endif
}

