Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion toolchain/check/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_(
Expand Down
13 changes: 0 additions & 13 deletions toolchain/check/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
//
Expand Down Expand Up @@ -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;

Expand Down
5 changes: 3 additions & 2 deletions toolchain/check/handle_binding_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,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(
Expand Down Expand Up @@ -151,7 +152,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,
Expand Down
6 changes: 4 additions & 2 deletions toolchain/check/handle_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
Expand Down
5 changes: 3 additions & 2 deletions toolchain/check/handle_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down
15 changes: 8 additions & 7 deletions toolchain/check/handle_let_and_var.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,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);
}

Expand Down Expand Up @@ -153,7 +153,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();
Expand Down Expand Up @@ -189,7 +189,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.
Expand Down Expand Up @@ -238,7 +239,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);
}
}
Expand Down Expand Up @@ -346,7 +347,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;
Expand Down Expand Up @@ -378,15 +379,15 @@ 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.
context.TODO(node_id, "Field initializer");
}
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);
Expand Down
3 changes: 2 additions & 1 deletion toolchain/check/merge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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.
Expand Down
13 changes: 9 additions & 4 deletions toolchain/check/scope_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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_;

Expand Down
5 changes: 5 additions & 0 deletions toolchain/sem_ir/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_; }
Expand Down