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

Initial support for binding patterns in SemIR #4221

Merged
merged 21 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
10 changes: 10 additions & 0 deletions toolchain/check/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Context::Context(const Lex::TokenizedBuffer& tokens, DiagnosticEmitter& emitter,
vlog_stream_(vlog_stream),
node_stack_(parse_tree, vlog_stream),
inst_block_stack_("inst_block_stack_", sem_ir, vlog_stream),
pattern_block_stack_("pattern_block_stack_", sem_ir, vlog_stream),
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),
Expand Down Expand Up @@ -81,6 +82,7 @@ auto Context::VerifyOnFinish() -> void {
// node_stack_ will still contain top-level entities.
scope_stack_.VerifyOnFinish();
inst_block_stack_.VerifyOnFinish();
pattern_block_stack_.VerifyOnFinish();
param_and_arg_refs_stack_.VerifyOnFinish();
}

Expand Down Expand Up @@ -147,6 +149,13 @@ auto Context::AddPlaceholderInst(SemIR::LocIdAndInst loc_id_and_inst)
return inst_id;
}

auto Context::AddPatternInst(SemIR::LocIdAndInst loc_id_and_inst)
-> SemIR::InstId {
auto inst_id = AddInstInNoBlock(loc_id_and_inst);
pattern_block_stack_.AddInstId(inst_id);
return inst_id;
}

auto Context::AddConstant(SemIR::Inst inst, bool is_symbolic)
-> SemIR::ConstantId {
auto const_id = constants().GetOrAdd(inst, is_symbolic);
Expand Down Expand Up @@ -1129,6 +1138,7 @@ auto Context::PrintForStackDump(llvm::raw_ostream& output) const -> void {
SemIR::Formatter formatter(*tokens_, *parse_tree_, *sem_ir_);
node_stack_.PrintForStackDump(formatter, Indent, output);
inst_block_stack_.PrintForStackDump(formatter, Indent, output);
pattern_block_stack_.PrintForStackDump(formatter, Indent, output);
param_and_arg_refs_stack_.PrintForStackDump(formatter, Indent, output);
args_type_info_stack_.PrintForStackDump(formatter, Indent, output);
}
Expand Down
16 changes: 16 additions & 0 deletions toolchain/check/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ class Context {
auto AddPlaceholderInstInNoBlock(SemIR::LocIdAndInst loc_id_and_inst)
-> SemIR::InstId;

// Adds an instruction to the current pattern block, returning the produced
// ID.
auto AddPatternInst(SemIR::LocIdAndInst loc_id_and_inst) -> SemIR::InstId;

// Convenience for AddPatternInst with typed nodes.
template <typename InstT>
requires(SemIR::Internal::HasNodeId<InstT>)
auto AddPatternInst(decltype(InstT::Kind)::TypedNodeId node_id, InstT inst)
-> SemIR::InstId {
return AddPatternInst(SemIR::LocIdAndInst(node_id, inst));
}

// Adds an instruction to the constants block, returning the produced ID.
auto AddConstant(SemIR::Inst inst, bool is_symbolic) -> SemIR::ConstantId;

Expand Down Expand Up @@ -392,6 +404,7 @@ class Context {
auto node_stack() -> NodeStack& { return node_stack_; }

auto inst_block_stack() -> InstBlockStack& { return inst_block_stack_; }
auto pattern_block_stack() -> InstBlockStack& { return pattern_block_stack_; }

auto param_and_arg_refs_stack() -> ParamAndArgRefsStack& {
return param_and_arg_refs_stack_;
Expand Down Expand Up @@ -529,6 +542,9 @@ class Context {
// The stack of instruction blocks being used for general IR generation.
InstBlockStack inst_block_stack_;

// The stack of instruction blocks that contain pattern instructions.
InstBlockStack pattern_block_stack_;

// The stack of instruction blocks being used for param and arg ref blocks.
ParamAndArgRefsStack param_and_arg_refs_stack_;

Expand Down
1 change: 1 addition & 0 deletions toolchain/check/decl_name_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class DeclNameStack {
.generic_id = SemIR::GenericId::Invalid,
.first_param_node_id = name.first_param_node_id,
.last_param_node_id = name.last_param_node_id,
.pattern_block_id = name.pattern_block_id,
.implicit_param_refs_id = name.implicit_params_id,
.param_refs_id = name.params_id,
.is_extern = is_extern,
Expand Down
2 changes: 2 additions & 0 deletions toolchain/check/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,7 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id,
case SemIR::AddrPattern::Kind:
case SemIR::Assign::Kind:
case SemIR::BindName::Kind:
case SemIR::BindingPattern::Kind:
case SemIR::BlockArg::Kind:
case SemIR::Branch::Kind:
case SemIR::BranchIf::Kind:
Expand All @@ -1478,6 +1479,7 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id,
case SemIR::ReturnExpr::Kind:
case SemIR::Return::Kind:
case SemIR::StructLiteral::Kind:
case SemIR::SymbolicBindingPattern::Kind:
case SemIR::TupleLiteral::Kind:
case SemIR::VarStorage::Kind:
break;
Expand Down
1 change: 1 addition & 0 deletions toolchain/check/global_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ auto GlobalInit::Finalize() -> void {
.generic_id = SemIR::GenericId::Invalid,
.first_param_node_id = Parse::NodeId::Invalid,
.last_param_node_id = Parse::NodeId::Invalid,
.pattern_block_id = SemIR::InstBlockId::Empty,
.implicit_param_refs_id = SemIR::InstBlockId::Invalid,
.param_refs_id = SemIR::InstBlockId::Empty,
.is_extern = false,
Expand Down
1 change: 1 addition & 0 deletions toolchain/check/handle_alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ auto HandleParseNode(Context& context, Parse::AliasIntroducerId /*node_id*/)
-> bool {
context.decl_introducer_state_stack().Push<Lex::TokenKind::Alias>();
context.decl_name_stack().PushScopeAndStartName();
context.pattern_block_stack().Push();
return true;
}

Expand Down
14 changes: 14 additions & 0 deletions toolchain/check/handle_binding_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,20 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
// TODO: Bindings should come into scope immediately in other contexts
// too.
context.AddNameToLookup(name_id, bind_id);
auto entity_name_id =
context.insts().GetAs<SemIR::AnyBindName>(bind_id).entity_name_id;
if (is_generic) {
context.AddPatternInst<SemIR::SymbolicBindingPattern>(
name_node,
{.type_id = cast_type_id, .entity_name_id = entity_name_id});
} else {
context.AddPatternInst<SemIR::BindingPattern>(
name_node,
{.type_id = cast_type_id, .entity_name_id = entity_name_id});
}
// TODO: use the pattern insts to generate the pattern-match insts
// at the end of the full pattern, instead of eagerly generating them
// here.
break;
}

Expand Down
2 changes: 2 additions & 0 deletions toolchain/check/handle_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ auto HandleParseNode(Context& context, Parse::ClassIntroducerId node_id)
context.decl_name_stack().PushScopeAndStartName();
// This class is potentially generic.
StartGenericDecl(context);
// Start a new pattern block for the signature.
context.pattern_block_stack().Push();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note, but something else to consider with storage might be whether we want the parameters and implicit parameters to each have their own pattern block. A single block is fine for now, I'm not asking for a change in this PR, but it might be something that affects the implementation more later.

return true;
}

Expand Down
3 changes: 3 additions & 0 deletions toolchain/check/handle_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ auto HandleParseNode(Context& context, Parse::ExportIntroducerId /*node_id*/)
context.decl_introducer_state_stack().Push<Lex::TokenKind::Export>();
// TODO: Probably need to update DeclNameStack to restrict to only namespaces.
context.decl_name_stack().PushScopeAndStartName();
// The parser supports patterns after `export`, so we need a pattern block
// to handle them.
context.pattern_block_stack().Push();
return true;
}

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 @@ -34,6 +34,8 @@ auto HandleParseNode(Context& context, Parse::FunctionIntroducerId node_id)
context.decl_name_stack().PushScopeAndStartName();
// The function is potentially generic.
StartGenericDecl(context);
// Start a new pattern block for the signature.
context.pattern_block_stack().Push();
return true;
}

Expand Down Expand Up @@ -171,8 +173,6 @@ static auto BuildFunctionDecl(Context& context,
Parse::AnyFunctionDeclId node_id,
bool is_definition)
-> std::pair<SemIR::FunctionId, SemIR::InstId> {
auto decl_block_id = context.inst_block_stack().Pop();

auto return_storage_id = SemIR::InstId::Invalid;
if (auto [return_node, maybe_return_storage_id] =
context.node_stack().PopWithNodeIdIf<Parse::NodeKind::ReturnType>();
Expand Down Expand Up @@ -209,6 +209,7 @@ static auto BuildFunctionDecl(Context& context,
}

// Add the function declaration.
auto decl_block_id = context.inst_block_stack().Pop();
auto function_decl = SemIR::FunctionDecl{
SemIR::TypeId::Invalid, SemIR::FunctionId::Invalid, decl_block_id};
auto decl_id =
Expand Down
6 changes: 6 additions & 0 deletions toolchain/check/handle_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ auto HandleParseNode(Context& context, Parse::ImplIntroducerId node_id)
// consistent to imagine that it does. This also gives us a scope for implicit
// parameters.
context.decl_name_stack().PushScopeAndStartName();

// Push a pattern block for the signature.
context.pattern_block_stack().Push();

return true;
}

Expand Down Expand Up @@ -214,6 +218,8 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
// TODO: Does lookup in an impl file need to look for a prior impl declaration
// in the api file?
auto impl_id = context.impls().LookupOrAdd(self_type_id, constraint_type_id);
context.impls().Get(impl_id).pattern_block_id =
context.pattern_block_stack().Pop();
SemIR::ImplDecl impl_decl = {.impl_id = impl_id,
.decl_block_id = decl_block_id};
auto impl_decl_id = context.AddInst(node_id, impl_decl);
Expand Down
2 changes: 2 additions & 0 deletions toolchain/check/handle_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ auto HandleParseNode(Context& context, Parse::InterfaceIntroducerId node_id)
context.decl_name_stack().PushScopeAndStartName();
// This interface is potentially generic.
StartGenericDecl(context);
// Push a pattern block for the signature.
context.pattern_block_stack().Push();
return true;
}

Expand Down
8 changes: 7 additions & 1 deletion toolchain/check/handle_let_and_var.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ namespace Carbon::Check {
template <Lex::TokenKind::RawEnumType Kind>
static auto HandleIntroducer(Context& context, Parse::NodeId node_id) -> bool {
context.decl_introducer_state_stack().Push<Kind>();
// Push a bracketing node to establish the pattern context.
// Push a bracketing node and pattern block to establish the pattern context.
context.node_stack().Push(node_id);
context.pattern_block_stack().Push();
return true;
}

Expand Down Expand Up @@ -145,6 +146,11 @@ template <const Lex::TokenKind& IntroducerTokenKind,
static auto HandleDecl(Context& context, NodeT node_id)
-> std::optional<DeclInfo> {
std::optional<DeclInfo> decl_info = DeclInfo();

// TODO: update binding-pattern handling to use the pattern block even in
// a let/var context, and then consume it here.
context.pattern_block_stack().PopAndDiscard();

// Handle the optional initializer.
if (context.node_stack().PeekNextIs<InitializerNodeKind>()) {
decl_info->init_id = context.node_stack().PopExpr();
Expand Down
1 change: 1 addition & 0 deletions toolchain/check/handle_name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ auto HandleParseNode(Context& context, Parse::SelfValueNameExprId node_id)
auto HandleParseNode(Context& context, Parse::NameQualifierId /*node_id*/)
-> bool {
context.decl_name_stack().ApplyNameQualifier(PopNameComponent(context));
context.pattern_block_stack().Push();
return true;
}

Expand Down
1 change: 1 addition & 0 deletions toolchain/check/handle_namespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ auto HandleParseNode(Context& context, Parse::NamespaceStartId /*node_id*/)
// Optional modifiers and the name follow.
context.decl_introducer_state_stack().Push<Lex::TokenKind::Namespace>();
context.decl_name_stack().PushScopeAndStartName();
context.pattern_block_stack().Push();
return true;
}

Expand Down
1 change: 1 addition & 0 deletions toolchain/check/import_ref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ class ImportRefResolver {
.generic_id = MakeIncompleteGeneric(decl_id, import_base.generic_id),
.first_param_node_id = Parse::NodeId::Invalid,
.last_param_node_id = Parse::NodeId::Invalid,
.pattern_block_id = SemIR::InstBlockId::Invalid,
.implicit_param_refs_id = import_base.implicit_param_refs_id.is_valid()
? SemIR::InstBlockId::Empty
: SemIR::InstBlockId::Invalid,
Expand Down
1 change: 1 addition & 0 deletions toolchain/check/name_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ auto PopNameComponent(Context& context) -> NameComponent {
implicit_params_id.value_or(SemIR::InstBlockId::Invalid),
.params_loc_id = params_loc_id,
.params_id = params_id.value_or(SemIR::InstBlockId::Invalid),
.pattern_block_id = context.pattern_block_stack().Pop(),
};
}

Expand Down
3 changes: 3 additions & 0 deletions toolchain/check/name_component.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ struct NameComponent {
// The explicit parameter list.
Parse::NodeId params_loc_id;
SemIR::InstBlockId params_id;

// The pattern block.
SemIR::InstBlockId pattern_block_id;
};

// Pop a name component from the node stack.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ let d: c = {};
// CHECK:STDOUT: .c = %c
// CHECK:STDOUT: .d = @__global_init.%d
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %a: type = bind_alias a, %C.decl [template = constants.%C]
// CHECK:STDOUT: %a.ref: type = name_ref a, %a [template = constants.%C]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ var d: D* = &c;
// CHECK:STDOUT: .C = %C.decl
// CHECK:STDOUT: .D = %D
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C]
// CHECK:STDOUT: }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ let c_var: c = d;
// CHECK:STDOUT: .d = %d
// CHECK:STDOUT: .c_var = @__global_init.%c_var
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %D.decl: type = class_decl @D [template = constants.%D] {}
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %D.decl: type = class_decl @D [template = constants.%D] {} {}
// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %c: type = bind_alias c, %C.decl [template = constants.%C]
// CHECK:STDOUT: %D.ref: type = name_ref D, %D.decl [template = constants.%D]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn F() -> {} {
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %NS: <namespace> = namespace [template] {}
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {
// CHECK:STDOUT: %.loc13_12.1: %.1 = struct_literal ()
// CHECK:STDOUT: %.loc13_12.2: type = converted %.loc13_12.1, constants.%.1 [template = constants.%.1]
// CHECK:STDOUT: @F.%return: ref %.1 = var <return slot>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ extern alias C = Class;
// CHECK:STDOUT: .B = %B
// CHECK:STDOUT: .C = %C
// CHECK:STDOUT: }
// CHECK:STDOUT: %Class.decl: type = class_decl @Class [template = constants.%Class] {}
// CHECK:STDOUT: %Class.decl: type = class_decl @Class [template = constants.%Class] {} {}
// CHECK:STDOUT: %Class.ref.loc38: type = name_ref Class, %Class.decl [template = constants.%Class]
// CHECK:STDOUT: %A: type = bind_alias A, %Class.decl [template = constants.%Class]
// CHECK:STDOUT: %Class.ref.loc44: type = name_ref Class, %Class.decl [template = constants.%Class]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ alias b = C;
// CHECK:STDOUT: .a = %a.loc13
// CHECK:STDOUT: .b = %b
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %a.loc13: type = bind_alias a, %C.decl [template = constants.%C]
// CHECK:STDOUT: %C.ref.loc21: type = name_ref C, %C.decl [template = constants.%C]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn F() {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {}
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/testdata/alias/no_prelude/import.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: .c_alias = %c_alias
// CHECK:STDOUT: .a = %a
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %c_alias: type = bind_alias c_alias, %C.decl [template = constants.%C]
// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ var inst: Test.A = {};
// CHECK:STDOUT: .C = %C.decl
// CHECK:STDOUT: .A [private] = %A
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %A: type = bind_alias A, %C.decl [template = constants.%C]
// CHECK:STDOUT: }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: .c = %c
// CHECK:STDOUT: .d = %d
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %a: type = bind_alias a, %C.decl [template = constants.%C]
// CHECK:STDOUT: %a.ref: type = name_ref a, %a [template = constants.%C]
Expand Down
4 changes: 2 additions & 2 deletions toolchain/check/testdata/alias/no_prelude/in_namespace.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ fn F() -> NS.a {
// CHECK:STDOUT: .b = @__global_init.%b
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %NS: <namespace> = namespace [template] {
// CHECK:STDOUT: .a = %a
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %a: type = bind_alias a, %C.decl [template = constants.%C]
// CHECK:STDOUT: %NS.ref.loc16: <namespace> = name_ref NS, %NS [template = %NS]
// CHECK:STDOUT: %a.ref.loc16: type = name_ref a, %a [template = constants.%C]
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {
// CHECK:STDOUT: %NS.ref.loc18: <namespace> = name_ref NS, %NS [template = %NS]
// CHECK:STDOUT: %a.ref.loc18: type = name_ref a, %a [template = constants.%C]
// CHECK:STDOUT: @F.%return: ref %C = var <return slot>
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/testdata/alias/no_prelude/local.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn F() -> () {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {
// CHECK:STDOUT: %.loc11_12.1: %.1 = tuple_literal ()
// CHECK:STDOUT: %.loc11_12.2: type = converted %.loc11_12.1, constants.%.1 [template = constants.%.1]
// CHECK:STDOUT: @F.%return: ref %.1 = var <return slot>
Expand Down
Loading