mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
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.
This commit is contained in:
@@ -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_(
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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_; }
|
||||
|
||||
Reference in New Issue
Block a user