Bläddra i källkod

Change Context::IsImplFile to File::is_impl (#4931)

Note this mirrors parse_tree().packaging_decl().is_impl, but I'm
preferring to keep the version that doesn't access the parse tree so
that we could change tree storage without hurting as much.
Jon Ross-Perkins 1 år sedan
förälder
incheckning
8af64ceca6

+ 1 - 1
toolchain/check/context.cpp

@@ -52,7 +52,7 @@ Context::Context(DiagnosticEmitter* emitter,
       param_and_arg_refs_stack_(*sem_ir, vlog_stream, node_stack_),
       args_type_info_stack_("args_type_info_stack_", *sem_ir, vlog_stream),
       decl_name_stack_(this),
-      scope_stack_(sem_ir_->identifiers()),
+      scope_stack_(sem_ir_),
       vtable_stack_("vtable_stack_", *sem_ir, vlog_stream),
       global_init_(this),
       region_stack_(

+ 0 - 13
toolchain/check/context.h

@@ -287,13 +287,6 @@ class Context {
   auto NoteUndefinedInterface(SemIR::InterfaceId interface_id,
                               DiagnosticBuilder& builder) -> void;
 
-  // Returns the current scope, if it is of the specified kind. Otherwise,
-  // returns nullopt.
-  template <typename InstT>
-  auto GetCurrentScopeAs() -> std::optional<InstT> {
-    return scope_stack().GetCurrentScopeAs<InstT>(sem_ir());
-  }
-
   // Returns the type ID for a constant that is a type value, i.e. it is a value
   // of type `TypeType`.
   //
@@ -390,12 +383,6 @@ class Context {
 
   auto Finalize() -> void;
 
-  // True if the current file is an impl file.
-  auto IsImplFile() -> bool {
-    return sem_ir_->import_irs().Get(SemIR::ImportIRId::ApiForImpl).sem_ir !=
-           nullptr;
-  }
-
   // Prints information for a stack dump.
   auto PrintForStackDump(llvm::raw_ostream& output) const -> void;
 

+ 3 - 2
toolchain/check/handle_binding_pattern.cpp

@@ -111,7 +111,8 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
 
   // A `var` binding in a class scope declares a field, not a true binding,
   // so we handle it separately.
-  if (auto parent_class_decl = context.GetCurrentScopeAs<SemIR::ClassDecl>();
+  if (auto parent_class_decl =
+          context.scope_stack().GetCurrentScopeAs<SemIR::ClassDecl>();
       parent_class_decl.has_value() &&
       node_kind == Parse::NodeKind::VarBindingPattern) {
     cast_type_id = AsConcreteType(
@@ -152,7 +153,7 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
   // A binding in an interface scope declares an associated constant, not a
   // true binding, so we handle it separately.
   if (auto parent_interface_decl =
-          context.GetCurrentScopeAs<SemIR::InterfaceDecl>();
+          context.scope_stack().GetCurrentScopeAs<SemIR::InterfaceDecl>();
       parent_interface_decl.has_value() && is_generic) {
     cast_type_id = AsCompleteType(context, cast_type_id, type_node, [&] {
       CARBON_DIAGNOSTIC(IncompleteTypeInAssociatedDecl, Error,

+ 4 - 2
toolchain/check/handle_class.cpp

@@ -10,6 +10,7 @@
 #include "toolchain/check/eval.h"
 #include "toolchain/check/generic.h"
 #include "toolchain/check/handle.h"
+#include "toolchain/check/import.h"
 #include "toolchain/check/import_ref.h"
 #include "toolchain/check/merge.h"
 #include "toolchain/check/modifiers.h"
@@ -265,7 +266,7 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id,
                          .specific_id = specific_id}));
   }
 
-  if (!is_definition && context.IsImplFile() && !is_extern) {
+  if (!is_definition && context.sem_ir().is_impl() && !is_extern) {
     context.definitions_required().push_back(class_decl_id);
   }
 
@@ -333,7 +334,8 @@ static auto DiagnoseClassSpecificDeclOutsideClass(Context& context,
 static auto GetCurrentScopeAsClassOrDiagnose(Context& context, SemIRLoc loc,
                                              Lex::TokenKind tok)
     -> std::optional<SemIR::ClassDecl> {
-  auto class_scope = context.GetCurrentScopeAs<SemIR::ClassDecl>();
+  auto class_scope =
+      context.scope_stack().GetCurrentScopeAs<SemIR::ClassDecl>();
   if (!class_scope) {
     DiagnoseClassSpecificDeclOutsideClass(context, loc, tok);
   }

+ 3 - 2
toolchain/check/handle_function.cpp

@@ -11,6 +11,7 @@
 #include "toolchain/check/function.h"
 #include "toolchain/check/generic.h"
 #include "toolchain/check/handle.h"
+#include "toolchain/check/import.h"
 #include "toolchain/check/import_ref.h"
 #include "toolchain/check/interface.h"
 #include "toolchain/check/literal.h"
@@ -280,7 +281,7 @@ static auto BuildFunctionDecl(Context& context,
 
   // Create a new function if this isn't a valid redeclaration.
   if (!function_decl.function_id.has_value()) {
-    if (function_info.is_extern && context.IsImplFile()) {
+    if (function_info.is_extern && context.sem_ir().is_impl()) {
       DiagnoseExternRequiresDeclInApiFile(context, node_id);
     }
     function_info.generic_id = BuildGenericDecl(context, decl_id);
@@ -343,7 +344,7 @@ static auto BuildFunctionDecl(Context& context,
     }
   }
 
-  if (!is_definition && context.IsImplFile() && !is_extern) {
+  if (!is_definition && context.sem_ir().is_impl() && !is_extern) {
     context.definitions_required().push_back(decl_id);
   }
 

+ 8 - 7
toolchain/check/handle_let_and_var.cpp

@@ -88,7 +88,7 @@ static auto HandleIntroducer(Context& context, Parse::NodeId node_id) -> bool {
 }
 
 auto HandleParseNode(Context& context, Parse::LetIntroducerId node_id) -> bool {
-  if (context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+  if (context.scope_stack().GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
     StartAssociatedConstant(context);
   }
 
@@ -154,7 +154,7 @@ auto HandleParseNode(Context& context, Parse::VariablePatternId node_id)
 // Handle the end of the full-pattern of a let/var declaration (before the
 // start of the initializer, if any).
 static auto EndFullPattern(Context& context) -> void {
-  if (context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+  if (context.scope_stack().GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
     // Don't emit NameBindingDecl for an associated constant, because it will
     // always be empty.
     context.pattern_block_stack().PopAndDiscard();
@@ -190,7 +190,8 @@ static auto HandleInitializer(Context& context, Parse::NodeId node_id) -> bool {
 
 auto HandleParseNode(Context& context, Parse::LetInitializerId node_id)
     -> bool {
-  if (auto interface_decl = context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+  if (auto interface_decl =
+          context.scope_stack().GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
     EndAssociatedConstantDeclRegion(context, interface_decl->interface_id);
 
     // Start building the definition region of the constant.
@@ -239,7 +240,7 @@ static auto HandleDecl(Context& context) -> DeclInfo {
     // now. We will have done this at the `=` if there was an initializer.
     if (IntroducerTokenKind == Lex::TokenKind::Let) {
       if (auto interface_decl =
-              context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+              context.scope_stack().GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
         EndAssociatedConstantDeclRegion(context, interface_decl->interface_id);
       }
     }
@@ -347,7 +348,7 @@ auto HandleParseNode(Context& context, Parse::LetDeclId node_id) -> bool {
   // At interface scope, we are forming an associated constant, which has
   // different rules.
   if (auto interface_scope =
-          context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+          context.scope_stack().GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
     FinishAssociatedConstant(context, node_id, interface_scope->interface_id,
                              decl_info);
     return true;
@@ -379,7 +380,7 @@ auto HandleParseNode(Context& context, Parse::VariableDeclId node_id) -> bool {
       context, decl_info.introducer,
       KeywordModifierSet::Access | KeywordModifierSet::Returned);
 
-  if (context.GetCurrentScopeAs<SemIR::ClassDecl>()) {
+  if (context.scope_stack().GetCurrentScopeAs<SemIR::ClassDecl>()) {
     if (decl_info.init_id.has_value()) {
       // TODO: In a class scope, we should instead save the initializer
       // somewhere so that we can use it as a default.
@@ -387,7 +388,7 @@ auto HandleParseNode(Context& context, Parse::VariableDeclId node_id) -> bool {
     }
     return true;
   }
-  if (context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+  if (context.scope_stack().GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
     CARBON_DIAGNOSTIC(VarInInterfaceDecl, Error,
                       "`var` declaration in interface");
     context.emitter().Emit(node_id, VarInInterfaceDecl);

+ 2 - 1
toolchain/check/merge.cpp

@@ -5,6 +5,7 @@
 #include "toolchain/check/merge.h"
 
 #include "toolchain/base/kind_switch.h"
+#include "toolchain/check/import.h"
 #include "toolchain/check/import_ref.h"
 #include "toolchain/diagnostics/format_providers.h"
 #include "toolchain/sem_ir/ids.h"
@@ -135,7 +136,7 @@ auto DiagnoseIfInvalidRedecl(Context& context, Lex::TokenKind decl_kind,
   }
 
   // Check for disallowed redeclarations cross-library.
-  if (new_decl.is_extern && context.IsImplFile()) {
+  if (new_decl.is_extern && context.sem_ir().is_impl()) {
     // We continue after issuing the "missing API declaration" diagnostic,
     // because it may still be helpful to note other issues with the
     // declarations.

+ 9 - 4
toolchain/check/scope_stack.h

@@ -20,8 +20,10 @@ namespace Carbon::Check {
 // checking within.
 class ScopeStack {
  public:
-  explicit ScopeStack(const CanonicalValueStore<IdentifierId>& identifiers)
-      : lexical_lookup_(identifiers), full_pattern_stack_(&lexical_lookup_) {}
+  explicit ScopeStack(const SemIR::File* sem_ir)
+      : sem_ir_(sem_ir),
+        lexical_lookup_(sem_ir->identifiers()),
+        full_pattern_stack_(&lexical_lookup_) {}
 
   // A scope in which `break` and `continue` can be used.
   struct BreakContinueScope {
@@ -99,12 +101,12 @@ class ScopeStack {
   // Returns the current scope, if it is of the specified kind. Otherwise,
   // returns nullopt.
   template <typename InstT>
-  auto GetCurrentScopeAs(const SemIR::File& sem_ir) -> std::optional<InstT> {
+  auto GetCurrentScopeAs() -> std::optional<InstT> {
     auto inst_id = PeekInstId();
     if (!inst_id.has_value()) {
       return std::nullopt;
     }
-    return sem_ir.insts().TryGetAs<InstT>(inst_id);
+    return sem_ir_->insts().TryGetAs<InstT>(inst_id);
   }
 
   // If there is no `returned var` in scope, sets the given instruction to be
@@ -225,6 +227,9 @@ class ScopeStack {
   auto VerifyNextCompileTimeBindIndex(llvm::StringLiteral label,
                                       const ScopeStackEntry& scope) -> void;
 
+  // The current file.
+  const SemIR::File* sem_ir_;
+
   // A stack of scopes from which we can `return`.
   llvm::SmallVector<ReturnScope> return_scope_stack_;
 

+ 5 - 0
toolchain/sem_ir/file.h

@@ -94,6 +94,11 @@ class File : public Printable<File> {
     return types().GetAs<PointerType>(pointer_id).pointee_id;
   }
 
+  // Returns true if this file is an `impl`.
+  auto is_impl() -> bool {
+    return import_irs().Get(SemIR::ImportIRId::ApiForImpl).sem_ir != nullptr;
+  }
+
   auto check_ir_id() const -> CheckIRId { return check_ir_id_; }
   auto package_id() const -> PackageNameId { return package_id_; }
   auto library_id() const -> SemIR::LibraryNameId { return library_id_; }