From 58de34e5347d168eac92457656e217e0ac08802c Mon Sep 17 00:00:00 2001 From: Elliott Kalt <44716003+elkalt@users.noreply.github.com> Date: Tue, 2 Sep 2025 19:15:26 -0400 Subject: [PATCH] Decouple associated constants from let (#5973) Decouples associated constants from being special cased in let handlers. Enforces associated constant grammar restrictions in parsing instead of checking. Closes #5411 --- toolchain/check/handle_binding_pattern.cpp | 106 +++++----- toolchain/check/handle_let_and_var.cpp | 140 +++++++------ toolchain/check/handle_pattern_list.cpp | 9 - toolchain/check/node_stack.h | 2 + toolchain/check/testdata/for/actual.carbon | 24 +-- toolchain/check/testdata/for/basic.carbon | 4 +- .../testdata/impl/assoc_const_self.carbon | 22 +- .../impl/fail_undefined_interface.carbon | 12 +- .../check/testdata/impl/forward_decls.carbon | 70 +++---- .../testdata/impl/impl_assoc_const.carbon | 30 +-- .../impl/import_interface_assoc_const.carbon | 12 +- ...pecialization_with_symbolic_rewrite.carbon | 6 +- .../testdata/impl/use_assoc_const.carbon | 54 ++--- .../interface/compound_member_access.carbon | 2 +- .../interface/fail_assoc_const_alias.carbon | 2 +- .../fail_assoc_const_not_binding.carbon | 146 ------------- .../fail_assoc_const_not_constant.carbon | 25 --- .../fail_assoc_const_template.carbon | 56 ----- .../interface/fail_member_lookup.carbon | 2 +- .../check/testdata/interface/import.carbon | 2 +- .../check/testdata/patterns/underscore.carbon | 56 ----- .../check/testdata/tuple/tuple_pattern.carbon | 20 -- .../testdata/var/fail_in_interface.carbon | 41 ---- .../testdata/where_expr/designator.carbon | 2 +- .../testdata/where_expr/non_generic.carbon | 8 +- toolchain/diagnostics/diagnostic_kind.def | 7 +- toolchain/parse/context.cpp | 3 +- toolchain/parse/handle_decl_definition.cpp | 4 +- toolchain/parse/handle_decl_scope_loop.cpp | 34 ++- toolchain/parse/handle_let.cpp | 74 ++++++- toolchain/parse/handle_statement.cpp | 2 +- toolchain/parse/node_kind.def | 5 + toolchain/parse/parse.cpp | 2 +- toolchain/parse/state.def | 37 +++- .../interface/associated_constants.carbon | 88 ++++++-- .../fail_associated_constants.carbon | 196 ++++++++++++++++++ .../testdata/let/fail_missing_name.carbon | 6 +- .../parse/testdata/let/missing_value.carbon | 11 +- .../testdata/var/fail_in_interface.carbon | 53 +++++ .../parse/testdata/where_expr/basic.carbon | 11 +- .../testdata/where_expr/impl_where.carbon | 11 +- toolchain/parse/typed_nodes.h | 33 +++ toolchain/sem_ir/typed_insts.h | 2 +- 43 files changed, 755 insertions(+), 677 deletions(-) delete mode 100644 toolchain/check/testdata/interface/fail_assoc_const_not_binding.carbon delete mode 100644 toolchain/check/testdata/interface/fail_assoc_const_not_constant.carbon delete mode 100644 toolchain/check/testdata/interface/fail_assoc_const_template.carbon delete mode 100644 toolchain/check/testdata/var/fail_in_interface.carbon create mode 100644 toolchain/parse/testdata/generics/interface/fail_associated_constants.carbon create mode 100644 toolchain/parse/testdata/var/fail_in_interface.carbon diff --git a/toolchain/check/handle_binding_pattern.cpp b/toolchain/check/handle_binding_pattern.cpp index 8cada947ed42..4d061bfeed3e 100644 --- a/toolchain/check/handle_binding_pattern.cpp +++ b/toolchain/check/handle_binding_pattern.cpp @@ -14,6 +14,7 @@ #include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/diagnostics/format_providers.h" +#include "toolchain/parse/node_ids.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/pattern.h" @@ -87,61 +88,6 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id, context.emitter().Emit(node_id, SelfOutsideImplicitParamList); } - // 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.scope_stack().GetCurrentScopeAs(); - parent_interface_decl.has_value()) { - // TODO: diagnose this during parsing, to avoid near-duplicate error - // messages. - if (!is_generic) { - CARBON_DIAGNOSTIC(ExpectedSymbolicBindingInAssociatedConstant, Error, - "found runtime binding pattern in associated constant " - "declaration; expected a `:!` binding"); - context.emitter().Emit(node_id, - ExpectedSymbolicBindingInAssociatedConstant); - context.node_stack().Push(node_id, SemIR::ErrorInst::InstId); - return true; - } - if (name_id == SemIR::NameId::Underscore) { - // The action item here may be to document this as not allowed, and - // add a proper diagnostic. - context.TODO(node_id, "_ used as associated constant name"); - } - cast_type_id = AsCompleteType(context, cast_type_id, type_node, [&] { - CARBON_DIAGNOSTIC(IncompleteTypeInAssociatedConstantDecl, Error, - "associated constant has incomplete type {0}", - SemIR::TypeId); - return context.emitter().Build( - type_node, IncompleteTypeInAssociatedConstantDecl, cast_type_id); - }); - if (is_template) { - CARBON_DIAGNOSTIC(TemplateBindingInAssociatedConstantDecl, Error, - "associated constant has `template` binding"); - context.emitter().Emit(type_node, - TemplateBindingInAssociatedConstantDecl); - } - - SemIR::AssociatedConstantDecl assoc_const_decl = { - .type_id = cast_type_id, - .assoc_const_id = SemIR::AssociatedConstantId::None, - .decl_block_id = SemIR::InstBlockId::None}; - auto decl_id = AddPlaceholderInstInNoBlock( - context, - context.parse_tree().As(node_id), - assoc_const_decl); - assoc_const_decl.assoc_const_id = context.associated_constants().Add( - {.name_id = name_id, - .parent_scope_id = context.scope_stack().PeekNameScopeId(), - .decl_id = decl_id, - .generic_id = SemIR::GenericId::None, - .default_value_id = SemIR::InstId::None}); - ReplaceInstBeforeConstantUse(context, decl_id, assoc_const_decl); - - context.node_stack().Push(node_id, decl_id); - return true; - } - // Allocate an instruction of the appropriate kind, linked to the name for // error locations. switch (context.full_pattern_stack().CurrentKind()) { @@ -298,19 +244,20 @@ auto HandleParseNode(Context& context, context.scope_stack().Pop(); auto node_kind = Parse::NodeKind::CompileTimeBindingPattern; - const DeclIntroducerState& introducer = context.decl_introducer_state_stack().innermost(); if (introducer.kind == Lex::TokenKind::Let) { // Disallow `let` outside of function and interface definitions. // TODO: Find a less brittle way of doing this. A `scope_inst_id` of `None` // can represent a block scope, but is also used for other kinds of scopes - // that aren't necessarily part of an interface or function decl. + // that aren't necessarily part of a function decl. + // We don't need to check if the scope is an interface here as this is + // already caught in the parse phase by the separated associated constant + // logic. auto scope_inst_id = context.scope_stack().PeekInstId(); if (scope_inst_id.has_value()) { auto scope_inst = context.insts().Get(scope_inst_id); - if (!scope_inst.Is() && - !scope_inst.Is()) { + if (!scope_inst.Is()) { context.TODO( node_id, "`let` compile time binding outside function or interface"); @@ -322,6 +269,47 @@ auto HandleParseNode(Context& context, return HandleAnyBindingPattern(context, node_id, node_kind); } +auto HandleParseNode(Context& context, + Parse::AssociatedConstantNameAndTypeId node_id) -> bool { + auto [type_node, parsed_type_id] = context.node_stack().PopExprWithNodeId(); + auto [cast_type_inst_id, cast_type_id] = + ExprAsType(context, type_node, parsed_type_id); + + EndSubpatternAsExpr(context, cast_type_inst_id); + + auto [name_node, name_id] = context.node_stack().PopNameWithNodeId(); + + if (name_id == SemIR::NameId::Underscore) { + // The action item here may be to document this as not allowed, and + // add a proper diagnostic. + context.TODO(node_id, "_ used as associated constant name"); + } + cast_type_id = AsCompleteType(context, cast_type_id, type_node, [&] { + CARBON_DIAGNOSTIC(IncompleteTypeInAssociatedConstantDecl, Error, + "associated constant has incomplete type {0}", + SemIR::TypeId); + return context.emitter().Build( + type_node, IncompleteTypeInAssociatedConstantDecl, cast_type_id); + }); + + SemIR::AssociatedConstantDecl assoc_const_decl = { + .type_id = cast_type_id, + .assoc_const_id = SemIR::AssociatedConstantId::None, + .decl_block_id = SemIR::InstBlockId::None}; + auto decl_id = + AddPlaceholderInstInNoBlock(context, node_id, assoc_const_decl); + assoc_const_decl.assoc_const_id = context.associated_constants().Add( + {.name_id = name_id, + .parent_scope_id = context.scope_stack().PeekNameScopeId(), + .decl_id = decl_id, + .generic_id = SemIR::GenericId::None, + .default_value_id = SemIR::InstId::None}); + ReplaceInstBeforeConstantUse(context, decl_id, assoc_const_decl); + + context.node_stack().Push(node_id, decl_id); + return true; +} + auto HandleParseNode(Context& context, Parse::FieldNameAndTypeId node_id) -> bool { auto [type_node, parsed_type_id] = context.node_stack().PopExprWithNodeId(); diff --git a/toolchain/check/handle_let_and_var.cpp b/toolchain/check/handle_let_and_var.cpp index 54b7f3cdb429..61105cb269d3 100644 --- a/toolchain/check/handle_let_and_var.cpp +++ b/toolchain/check/handle_let_and_var.cpp @@ -18,6 +18,7 @@ #include "toolchain/diagnostics/diagnostic_emitter.h" #include "toolchain/diagnostics/format_providers.h" #include "toolchain/lex/token_kind.h" +#include "toolchain/parse/node_ids.h" #include "toolchain/parse/node_kind.h" #include "toolchain/parse/typed_nodes.h" #include "toolchain/sem_ir/ids.h" @@ -29,15 +30,6 @@ namespace Carbon::Check { -// Handles the start of a declaration of an associated constant. -static auto StartAssociatedConstant(Context& context) -> void { - // An associated constant is always generic. - StartGenericDecl(context); - // Collect the declarations nested in the associated constant in a decl - // block. This is popped by FinishAssociatedConstantDecl. - context.inst_block_stack().Push(); -} - // Handles the end of the declaration region of an associated constant. This is // called at the `=` or the `;` of the declaration, whichever comes first. static auto EndAssociatedConstantDeclRegion(Context& context, @@ -95,10 +87,16 @@ static auto HandleIntroducer(Context& context, Parse::NodeId node_id) -> bool { } auto HandleParseNode(Context& context, Parse::LetIntroducerId node_id) -> bool { - if (context.scope_stack().GetCurrentScopeAs()) { - StartAssociatedConstant(context); - } + return HandleIntroducer(context, node_id); +} +auto HandleParseNode(Context& context, + Parse::AssociatedConstantIntroducerId node_id) -> bool { + // An associated constant is always generic. + StartGenericDecl(context); + // Collect the declarations nested in the associated constant in a decl + // block. This is popped by FinishAssociatedConstantDecl. + context.inst_block_stack().Push(); return HandleIntroducer(context, node_id); } @@ -177,14 +175,18 @@ static auto HandleInitializer(Context& context, Parse::NodeId node_id) -> bool { auto HandleParseNode(Context& context, Parse::LetInitializerId node_id) -> bool { - if (auto interface_decl = - context.scope_stack().GetCurrentScopeAs()) { - auto generic_id = - EndAssociatedConstantDeclRegion(context, interface_decl->interface_id); + return HandleInitializer(context, node_id); +} - // Start building the definition region of the constant. - StartGenericDefinition(context, generic_id); - } +auto HandleParseNode(Context& context, + Parse::AssociatedConstantInitializerId node_id) -> bool { + auto interface_decl = + context.scope_stack().GetCurrentScopeAs(); + auto generic_id = + EndAssociatedConstantDeclRegion(context, interface_decl->interface_id); + + // Start building the definition region of the constant. + StartGenericDefinition(context, generic_id); return HandleInitializer(context, node_id); } @@ -232,11 +234,10 @@ static auto HandleDecl(Context& context) -> DeclInfo { } else { // For an associated constant declaration, handle the completed declaration // now. We will have done this at the `=` if there was an initializer. - if (IntroducerTokenKind == Lex::TokenKind::Let) { - if (auto interface_decl = - context.scope_stack().GetCurrentScopeAs()) { - EndAssociatedConstantDeclRegion(context, interface_decl->interface_id); - } + if (IntroducerNodeKind == Parse::NodeKind::AssociatedConstantIntroducer) { + auto interface_decl = + context.scope_stack().GetCurrentScopeAs(); + EndAssociatedConstantDeclRegion(context, interface_decl->interface_id); } EndFullPattern(context); @@ -261,23 +262,59 @@ static auto HandleDecl(Context& context) -> DeclInfo { return decl_info; } -// Finishes an associated constant declaration. This is called at the `;` to -// perform any final steps. The `AssociatedConstantDecl` instruction and the -// corresponding `AssociatedConstant` entity are built as part of handling the -// binding pattern, but we still need to finish building the `Generic` object -// and attach the default value, if any is specified. -static auto FinishAssociatedConstant(Context& context, Parse::LetDeclId node_id, - SemIR::InterfaceId interface_id, - DeclInfo& decl_info) -> void { +auto HandleParseNode(Context& context, Parse::LetDeclId node_id) -> bool { + auto decl_info = + HandleDecl(context); + + LimitModifiersOnDecl( + context, decl_info.introducer, + KeywordModifierSet::Access | KeywordModifierSet::Interface); + + // Diagnose interface modifiers given that we're not building an associated + // constant. We use this rather than `LimitModifiersOnDecl` to get a more + // specific error. + RequireDefaultFinalOnlyInInterfaces(context, decl_info.introducer, + std::nullopt); + + if (decl_info.init_id.has_value()) { + LocalPatternMatch(context, decl_info.pattern_id, decl_info.init_id); + } else { + CARBON_DIAGNOSTIC( + ExpectedInitializerAfterLet, Error, + "expected `=`; `let` declaration must have an initializer"); + context.emitter().Emit(LocIdForDiagnostics::TokenOnly(node_id), + ExpectedInitializerAfterLet); + } + return true; +} + +auto HandleParseNode(Context& context, Parse::AssociatedConstantDeclId node_id) + -> bool { + auto decl_info = + HandleDecl(context); + + LimitModifiersOnDecl( + context, decl_info.introducer, + KeywordModifierSet::Access | KeywordModifierSet::Interface); + + auto interface_scope = + context.scope_stack().GetCurrentScopeAs(); + // The `AssociatedConstantDecl` instruction and the + // corresponding `AssociatedConstant` entity are built as part of handling the + // binding pattern, but we still need to finish building the `Generic` object + // and attach the default value, if any is specified. if (decl_info.pattern_id == SemIR::ErrorInst::InstId) { context.name_scopes() - .Get(context.interfaces().Get(interface_id).scope_id) + .Get(context.interfaces().Get(interface_scope->interface_id).scope_id) .set_has_error(); if (decl_info.init_id.has_value()) { DiscardGenericDecl(context); } context.inst_block_stack().Pop(); - return; + return true; } auto decl = context.insts().GetAs( decl_info.pattern_id); @@ -306,41 +343,6 @@ static auto FinishAssociatedConstant(Context& context, Parse::LetDeclId node_id, ReplaceInstPreservingConstantValue(context, decl_info.pattern_id, decl); context.inst_block_stack().AddInstId(decl_info.pattern_id); -} - -auto HandleParseNode(Context& context, Parse::LetDeclId node_id) -> bool { - auto decl_info = - HandleDecl(context); - - LimitModifiersOnDecl( - context, decl_info.introducer, - KeywordModifierSet::Access | KeywordModifierSet::Interface); - - // At interface scope, we are forming an associated constant, which has - // different rules. - if (auto interface_scope = - context.scope_stack().GetCurrentScopeAs()) { - FinishAssociatedConstant(context, node_id, interface_scope->interface_id, - decl_info); - return true; - } - - // Diagnose interface modifiers given that we're not building an associated - // constant. We use this rather than `LimitModifiersOnDecl` to get a more - // specific error. - RequireDefaultFinalOnlyInInterfaces(context, decl_info.introducer, - std::nullopt); - - if (decl_info.init_id.has_value()) { - LocalPatternMatch(context, decl_info.pattern_id, decl_info.init_id); - } else { - CARBON_DIAGNOSTIC( - ExpectedInitializerAfterLet, Error, - "expected `=`; `let` declaration must have an initializer"); - context.emitter().Emit(LocIdForDiagnostics::TokenOnly(node_id), - ExpectedInitializerAfterLet); - } return true; } diff --git a/toolchain/check/handle_pattern_list.cpp b/toolchain/check/handle_pattern_list.cpp index 2f28bca48c88..e507e004e23d 100644 --- a/toolchain/check/handle_pattern_list.cpp +++ b/toolchain/check/handle_pattern_list.cpp @@ -74,15 +74,6 @@ auto HandleParseNode(Context& context, Parse::TuplePatternId node_id) -> bool { context.node_stack() .PopAndDiscardSoloNodeId(); - if (context.scope_stack().GetCurrentScopeAs()) { - CARBON_DIAGNOSTIC(ExpectedSingleBindingInAssociatedConstant, Error, - "found tuple pattern in associated constant declaration; " - "expected symbolic binding pattern"); - context.emitter().Emit(node_id, ExpectedSingleBindingInAssociatedConstant); - context.node_stack().Push(node_id, SemIR::ErrorInst::InstId); - EndSubpatternAsNonExpr(context); - return true; - } const auto& inst_block = context.inst_blocks().Get(refs_id); llvm::SmallVector type_inst_ids; type_inst_ids.reserve(inst_block.size()); diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index 552d6b38377f..a4cd5dad8210 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -457,6 +457,8 @@ class NodeStack { case Parse::NodeKind::InterfaceIntroducer: case Parse::NodeKind::LetInitializer: case Parse::NodeKind::LetIntroducer: + case Parse::NodeKind::AssociatedConstantIntroducer: + case Parse::NodeKind::AssociatedConstantInitializer: case Parse::NodeKind::ReturnStatementStart: case Parse::NodeKind::StructLiteralStart: case Parse::NodeKind::StructTypeLiteralField: diff --git a/toolchain/check/testdata/for/actual.carbon b/toolchain/check/testdata/for/actual.carbon index ef54947b8f4a..d0f9c7f018d7 100644 --- a/toolchain/check/testdata/for/actual.carbon +++ b/toolchain/check/testdata/for/actual.carbon @@ -220,28 +220,28 @@ fn Read() { // CHECK:STDOUT: %Core.import_ref.1c9: %Iterate.assoc_type = import_ref Core//prelude/iterate, loc12_18, loaded [concrete = constants.%assoc0.724] // CHECK:STDOUT: %Core.import_ref.ed6: %Iterate.assoc_type = import_ref Core//prelude/iterate, loc13_17, loaded [concrete = constants.%assoc1.02e] // CHECK:STDOUT: %Core.import_ref.9e6: type = import_ref Core//prelude/iterate, loc13_17, loaded [concrete = %CursorType] -// CHECK:STDOUT: %Core.import_ref.f49: @Optional.%Optional.None.type (%Optional.None.type.ef2) = import_ref Core//prelude/iterate, inst140 [indirect], loaded [symbolic = @Optional.%Optional.None (constants.%Optional.None.fd6)] -// CHECK:STDOUT: %Core.import_ref.1a8: @Optional.%Optional.Some.type (%Optional.Some.type.b2c) = import_ref Core//prelude/iterate, inst141 [indirect], loaded [symbolic = @Optional.%Optional.Some (constants.%Optional.Some.d0d)] -// CHECK:STDOUT: %Core.import_ref.36a9: @Optional.as.Destroy.impl.%Optional.as.Destroy.impl.Op.type (%Optional.as.Destroy.impl.Op.type.764) = import_ref Core//prelude/iterate, inst6891 [indirect], loaded [symbolic = @Optional.as.Destroy.impl.%Optional.as.Destroy.impl.Op (constants.%Optional.as.Destroy.impl.Op.bf8)] +// CHECK:STDOUT: %Core.import_ref.f49: @Optional.%Optional.None.type (%Optional.None.type.ef2) = import_ref Core//prelude/iterate, inst137 [indirect], loaded [symbolic = @Optional.%Optional.None (constants.%Optional.None.fd6)] +// CHECK:STDOUT: %Core.import_ref.1a8: @Optional.%Optional.Some.type (%Optional.Some.type.b2c) = import_ref Core//prelude/iterate, inst138 [indirect], loaded [symbolic = @Optional.%Optional.Some (constants.%Optional.Some.d0d)] +// CHECK:STDOUT: %Core.import_ref.36a9: @Optional.as.Destroy.impl.%Optional.as.Destroy.impl.Op.type (%Optional.as.Destroy.impl.Op.type.764) = import_ref Core//prelude/iterate, inst6889 [indirect], loaded [symbolic = @Optional.as.Destroy.impl.%Optional.as.Destroy.impl.Op (constants.%Optional.as.Destroy.impl.Op.bf8)] // CHECK:STDOUT: %Destroy.impl_witness_table.2ff = impl_witness_table (%Core.import_ref.36a9), @Optional.as.Destroy.impl [concrete] -// CHECK:STDOUT: %Core.import_ref.cf4: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/iterate, inst484 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] +// CHECK:STDOUT: %Core.import_ref.cf4: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/iterate, inst482 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.2b9 = impl_witness_table (%Core.import_ref.cf4), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.import_ref.741: @Int.as.Destroy.impl.%Int.as.Destroy.impl.Op.type (%Int.as.Destroy.impl.Op.type) = import_ref Core//prelude/iterate, inst452 [indirect], loaded [symbolic = @Int.as.Destroy.impl.%Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op)] +// CHECK:STDOUT: %Core.import_ref.741: @Int.as.Destroy.impl.%Int.as.Destroy.impl.Op.type (%Int.as.Destroy.impl.Op.type) = import_ref Core//prelude/iterate, inst450 [indirect], loaded [symbolic = @Int.as.Destroy.impl.%Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op)] // CHECK:STDOUT: %Destroy.impl_witness_table.1b4 = impl_witness_table (%Core.import_ref.741), @Int.as.Destroy.impl [concrete] -// CHECK:STDOUT: %Core.import_ref.19a: @OrderedWith.%OrderedWith.assoc_type (%OrderedWith.assoc_type.03c) = import_ref Core//prelude/iterate, inst864 [indirect], loaded [symbolic = @OrderedWith.%assoc0 (constants.%assoc0.5db)] -// CHECK:STDOUT: %Core.import_ref.b2b: @Int.as.OrderedWith.impl.db3.%Int.as.OrderedWith.impl.Less.type (%Int.as.OrderedWith.impl.Less.type.2c7) = import_ref Core//prelude/iterate, inst953 [indirect], loaded [symbolic = @Int.as.OrderedWith.impl.db3.%Int.as.OrderedWith.impl.Less (constants.%Int.as.OrderedWith.impl.Less.a5a)] -// CHECK:STDOUT: %Core.import_ref.ab6 = import_ref Core//prelude/iterate, inst954 [indirect], unloaded -// CHECK:STDOUT: %Core.import_ref.875 = import_ref Core//prelude/iterate, inst955 [indirect], unloaded -// CHECK:STDOUT: %Core.import_ref.82b = import_ref Core//prelude/iterate, inst956 [indirect], unloaded +// CHECK:STDOUT: %Core.import_ref.19a: @OrderedWith.%OrderedWith.assoc_type (%OrderedWith.assoc_type.03c) = import_ref Core//prelude/iterate, inst862 [indirect], loaded [symbolic = @OrderedWith.%assoc0 (constants.%assoc0.5db)] +// CHECK:STDOUT: %Core.import_ref.b2b: @Int.as.OrderedWith.impl.db3.%Int.as.OrderedWith.impl.Less.type (%Int.as.OrderedWith.impl.Less.type.2c7) = import_ref Core//prelude/iterate, inst951 [indirect], loaded [symbolic = @Int.as.OrderedWith.impl.db3.%Int.as.OrderedWith.impl.Less (constants.%Int.as.OrderedWith.impl.Less.a5a)] +// CHECK:STDOUT: %Core.import_ref.ab6 = import_ref Core//prelude/iterate, inst952 [indirect], unloaded +// CHECK:STDOUT: %Core.import_ref.875 = import_ref Core//prelude/iterate, inst953 [indirect], unloaded +// CHECK:STDOUT: %Core.import_ref.82b = import_ref Core//prelude/iterate, inst954 [indirect], unloaded // CHECK:STDOUT: %OrderedWith.impl_witness_table.476 = impl_witness_table (%Core.import_ref.b2b, %Core.import_ref.ab6, %Core.import_ref.875, %Core.import_ref.82b), @Int.as.OrderedWith.impl.db3 [concrete] -// CHECK:STDOUT: %Core.import_ref.13d: @OrderedWith.%OrderedWith.Less.type (%OrderedWith.Less.type.f19) = import_ref Core//prelude/iterate, inst1928 [indirect], loaded [symbolic = @OrderedWith.%OrderedWith.Less (constants.%OrderedWith.Less.02e)] +// CHECK:STDOUT: %Core.import_ref.13d: @OrderedWith.%OrderedWith.Less.type (%OrderedWith.Less.type.f19) = import_ref Core//prelude/iterate, inst1926 [indirect], loaded [symbolic = @OrderedWith.%OrderedWith.Less (constants.%OrderedWith.Less.02e)] // CHECK:STDOUT: %CursorType: type = assoc_const_decl @CursorType [concrete] {} // CHECK:STDOUT: %Core.import_ref.4f9: type = import_ref Core//prelude/iterate, loc12_18, loaded [concrete = %ElementType] // CHECK:STDOUT: %ElementType: type = assoc_const_decl @ElementType [concrete] {} // CHECK:STDOUT: %Core.Optional: %Optional.type = import_ref Core//prelude/types/optional, Optional, loaded [concrete = constants.%Optional.generic] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.OrderedWith: %OrderedWith.type.270 = import_ref Core//prelude/operators/comparison, OrderedWith, loaded [concrete = constants.%OrderedWith.generic] -// CHECK:STDOUT: %Core.import_ref.d49 = import_ref Core//prelude/iterate, inst6646 [indirect], unloaded +// CHECK:STDOUT: %Core.import_ref.d49 = import_ref Core//prelude/iterate, inst6644 [indirect], unloaded // CHECK:STDOUT: %Core.Inc: type = import_ref Core//prelude/operators/arithmetic, Inc, loaded [concrete = constants.%Inc.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/for/basic.carbon b/toolchain/check/testdata/for/basic.carbon index ca8e4bd1812e..aa8151337ef5 100644 --- a/toolchain/check/testdata/for/basic.carbon +++ b/toolchain/check/testdata/for/basic.carbon @@ -103,8 +103,8 @@ fn Run() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core.import_ref.cd6: @Optional.%Optional.HasValue.type (%Optional.HasValue.type.a15) = import_ref Core//prelude/parts/iterate, inst101 [indirect], loaded [symbolic = @Optional.%Optional.HasValue (constants.%Optional.HasValue.73f)] -// CHECK:STDOUT: %Core.import_ref.4fd: @Optional.%Optional.Get.type (%Optional.Get.type.e03) = import_ref Core//prelude/parts/iterate, inst102 [indirect], loaded [symbolic = @Optional.%Optional.Get (constants.%Optional.Get.971)] +// CHECK:STDOUT: %Core.import_ref.cd6: @Optional.%Optional.HasValue.type (%Optional.HasValue.type.a15) = import_ref Core//prelude/parts/iterate, inst98 [indirect], loaded [symbolic = @Optional.%Optional.HasValue (constants.%Optional.HasValue.73f)] +// CHECK:STDOUT: %Core.import_ref.4fd: @Optional.%Optional.Get.type (%Optional.Get.type.e03) = import_ref Core//prelude/parts/iterate, inst99 [indirect], loaded [symbolic = @Optional.%Optional.Get (constants.%Optional.Get.971)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @Run() { diff --git a/toolchain/check/testdata/impl/assoc_const_self.carbon b/toolchain/check/testdata/impl/assoc_const_self.carbon index 5278b1dc663c..4c22bad67bf9 100644 --- a/toolchain/check/testdata/impl/assoc_const_self.carbon +++ b/toolchain/check/testdata/impl/assoc_const_self.carbon @@ -282,9 +282,9 @@ fn CallF() { // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0.45f: %I.assoc_type = assoc_entity element0, @I.%V [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.258 [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.258, @I [symbolic_self] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet.74c: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %require_complete.d0c: = require_complete_type %.Self.as_type [symbolic_self] // CHECK:STDOUT: %impl.elem0: %.Self.as_type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] @@ -317,8 +317,8 @@ fn CallF() { // CHECK:STDOUT: %.loc15_7.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc15_7.2: type = converted %.loc15_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %V.ref: %I.assoc_type = name_ref V, @V.%assoc0 [concrete = constants.%assoc0.45f] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc15_20: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] @@ -409,9 +409,9 @@ fn CallF() { // CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert: %empty_tuple.type.as.ImplicitAs.impl.Convert.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.15e = facet_value %empty_tuple.type, (%ImplicitAs.impl_witness) [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] -// CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.258 [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.258, @I [symbolic_self] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet.74c: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %require_complete.d0c: = require_complete_type %.Self.as_type [symbolic_self] // CHECK:STDOUT: %impl.elem0: %.Self.as_type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] @@ -456,8 +456,8 @@ fn CallF() { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %V.ref: %I.assoc_type = name_ref V, @V.%assoc0 [concrete = constants.%assoc0.45f] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc18_19: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] @@ -761,11 +761,11 @@ fn CallF() { // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic] // CHECK:STDOUT: %require_complete.9b1: = require_complete_type %Self.as_type.b70 [symbolic] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0.45f: %I.assoc_type = assoc_entity element0, @I.%V [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] diff --git a/toolchain/check/testdata/impl/fail_undefined_interface.carbon b/toolchain/check/testdata/impl/fail_undefined_interface.carbon index 644e4712328a..6ef1adfba6d9 100644 --- a/toolchain/check/testdata/impl/fail_undefined_interface.carbon +++ b/toolchain/check/testdata/impl/fail_undefined_interface.carbon @@ -210,9 +210,9 @@ impl C as J where .Self impls Incomplete and .T = (); // CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] // CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%T [concrete] // CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete] -// CHECK:STDOUT: %.Self.968: %J.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.968 [symbolic_self] -// CHECK:STDOUT: %J.lookup_impl_witness: = lookup_impl_witness %.Self.968, @J [symbolic_self] +// CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %J.lookup_impl_witness: = lookup_impl_witness %.Self, @J [symbolic_self] // CHECK:STDOUT: %J.facet: %J.type = facet_value %.Self.as_type, (%J.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %J.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] @@ -231,12 +231,12 @@ impl C as J where .Self impls Incomplete and .T = (); // CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] -// CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.968] -// CHECK:STDOUT: %.Self.ref.loc15_19: %J.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.968] +// CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc15_19: %J.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] // CHECK:STDOUT: %.Self.as_type.loc15_19: type = facet_access_type %.Self.ref.loc15_19 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc15_19: type = converted %.Self.ref.loc15_19, %.Self.as_type.loc15_19 [symbolic_self = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.ref.loc15_46: %J.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.968] +// CHECK:STDOUT: %.Self.ref.loc15_46: %J.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref: %J.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc15_46: type = facet_access_type %.Self.ref.loc15_46 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc15_46: type = converted %.Self.ref.loc15_46, %.Self.as_type.loc15_46 [symbolic_self = constants.%.Self.as_type] diff --git a/toolchain/check/testdata/impl/forward_decls.carbon b/toolchain/check/testdata/impl/forward_decls.carbon index 6f75222fbdf9..e7f3eb8d8e3e 100644 --- a/toolchain/check/testdata/impl/forward_decls.carbon +++ b/toolchain/check/testdata/impl/forward_decls.carbon @@ -493,9 +493,9 @@ interface I { // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.258 [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.258, @I [symbolic_self] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete] @@ -520,8 +520,8 @@ interface I { // CHECK:STDOUT: %.loc6_7.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc6_7.2: type = converted %.loc6_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %I.ref.loc6: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc6: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc6: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref.loc6: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc6: type = facet_access_type %.Self.ref.loc6 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc6_20: type = converted %.Self.ref.loc6, %.Self.as_type.loc6 [symbolic_self = constants.%.Self.as_type] @@ -540,8 +540,8 @@ interface I { // CHECK:STDOUT: %.loc8_7.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %I.ref.loc8: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc8: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc8: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref.loc8: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc8: type = facet_access_type %.Self.ref.loc8 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc8_20: type = converted %.Self.ref.loc8, %.Self.as_type.loc8 [symbolic_self = constants.%.Self.as_type] @@ -598,9 +598,9 @@ interface I { // CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.258 [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.258, @I [symbolic_self] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet.74c: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete] @@ -632,8 +632,8 @@ interface I { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc7: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref.loc7: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc7: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc7: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref.loc7: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc7: type = facet_access_type %.Self.ref.loc7 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc7_19: type = converted %.Self.ref.loc7, %.Self.as_type.loc7 [symbolic_self = constants.%.Self.as_type] @@ -665,8 +665,8 @@ interface I { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc11: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref.loc11: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc11: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc11: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref.loc11: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc11: type = facet_access_type %.Self.ref.loc11 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc11_19: type = converted %.Self.ref.loc11, %.Self.as_type.loc11 [symbolic_self = constants.%.Self.as_type] @@ -761,9 +761,9 @@ interface I { // CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.258 [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.258, @I [symbolic_self] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet.74c: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete] @@ -795,8 +795,8 @@ interface I { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc7: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref.loc7: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc7: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc7: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref.loc7: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc7: type = facet_access_type %.Self.ref.loc7 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc7_19: type = converted %.Self.ref.loc7, %.Self.as_type.loc7 [symbolic_self = constants.%.Self.as_type] @@ -830,8 +830,8 @@ interface I { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc11: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref.loc11: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc11: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc11: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref.loc11: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc11: type = facet_access_type %.Self.ref.loc11 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc11_19: type = converted %.Self.ref.loc11, %.Self.as_type.loc11 [symbolic_self = constants.%.Self.as_type] @@ -1733,9 +1733,9 @@ interface I { // CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.258 [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.258, @I [symbolic_self] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete] @@ -1763,8 +1763,8 @@ interface I { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc9: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref.loc9: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc9: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc9: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref.loc9: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc9: type = facet_access_type %.Self.ref.loc9 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc9_19: type = converted %.Self.ref.loc9, %.Self.as_type.loc9 [symbolic_self = constants.%.Self.as_type] @@ -1782,8 +1782,8 @@ interface I { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc18: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref.loc18: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc18: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc18: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref.loc18: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc18: type = facet_access_type %.Self.ref.loc18 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc18_19: type = converted %.Self.ref.loc18, %.Self.as_type.loc18 [symbolic_self = constants.%.Self.as_type] @@ -2322,9 +2322,9 @@ interface I { // CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.258 [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.258, @I [symbolic_self] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %C> [symbolic] @@ -2442,8 +2442,8 @@ interface I { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc12_10: type = name_ref C, @I.F.%C.decl [symbolic = %C (constants.%C)] // CHECK:STDOUT: %I.ref.loc12: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc12: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc12: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %U.ref.loc12: %I.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc12: type = facet_access_type %.Self.ref.loc12 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc12_23: type = converted %.Self.ref.loc12, %.Self.as_type.loc12 [symbolic_self = constants.%.Self.as_type] @@ -2460,8 +2460,8 @@ interface I { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc21_10: type = name_ref C, @I.F.%C.decl [symbolic = %C (constants.%C)] // CHECK:STDOUT: %I.ref.loc21: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.258] -// CHECK:STDOUT: %.Self.ref.loc21: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc21: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %U.ref.loc21: %I.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc21: type = facet_access_type %.Self.ref.loc21 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc21_23: type = converted %.Self.ref.loc21, %.Self.as_type.loc21 [symbolic_self = constants.%.Self.as_type] diff --git a/toolchain/check/testdata/impl/impl_assoc_const.carbon b/toolchain/check/testdata/impl/impl_assoc_const.carbon index daea6e4a5514..335e892ce8df 100644 --- a/toolchain/check/testdata/impl/impl_assoc_const.carbon +++ b/toolchain/check/testdata/impl/impl_assoc_const.carbon @@ -404,9 +404,9 @@ fn G() { // CHECK:STDOUT: %L.assoc_type: type = assoc_entity_type @L [concrete] // CHECK:STDOUT: %assoc0: %L.assoc_type = assoc_entity element0, @L.%W [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %.Self.19e: %L.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.19e [symbolic_self] -// CHECK:STDOUT: %L.lookup_impl_witness: = lookup_impl_witness %.Self.19e, @L [symbolic_self] +// CHECK:STDOUT: %.Self: %L.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %L.lookup_impl_witness: = lookup_impl_witness %.Self, @L [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %L.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %tuple.type.2d5: type = tuple_type (%empty_tuple.type, %empty_tuple.type, %empty_tuple.type) [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] @@ -421,7 +421,7 @@ fn G() { // CHECK:STDOUT: %.loc13_7.2: type = converted %.loc13_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %L.ref: type = name_ref L, file.%L.decl [concrete = constants.%L.type] // CHECK:STDOUT: -// CHECK:STDOUT: %.Self.ref.loc13_20: %L.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.19e] +// CHECK:STDOUT: %.Self.ref.loc13_20: %L.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %W.ref.loc13_20: %L.assoc_type = name_ref W, @W.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc13_20: type = facet_access_type %.Self.ref.loc13_20 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_20: type = converted %.Self.ref.loc13_20, %.Self.as_type.loc13_20 [symbolic_self = constants.%.Self.as_type] @@ -434,7 +434,7 @@ fn G() { // CHECK:STDOUT: %.loc13_36.3: type = converted %.loc13_31, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %.loc13_36.4: type = converted %.loc13_35, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %.loc13_36.5: type = converted %.loc13_36.1, constants.%tuple.type.2d5 [concrete = constants.%tuple.type.2d5] -// CHECK:STDOUT: %.Self.ref.loc13_42: %L.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.19e] +// CHECK:STDOUT: %.Self.ref.loc13_42: %L.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %W.ref.loc13_42: %L.assoc_type = name_ref W, @W.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc13_42: type = facet_access_type %.Self.ref.loc13_42 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_42: type = converted %.Self.ref.loc13_42, %.Self.as_type.loc13_42 [symbolic_self = constants.%.Self.as_type] @@ -448,7 +448,7 @@ fn G() { // CHECK:STDOUT: %.loc13_58.3: type = converted %.loc13_53, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %.loc13_58.4: type = converted %.loc13_57, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %.loc13_58.5: type = converted %.loc13_58.1, constants.%tuple.type.e5a [concrete = constants.%tuple.type.e5a] -// CHECK:STDOUT: %.Self.ref.loc13_64: %L.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.19e] +// CHECK:STDOUT: %.Self.ref.loc13_64: %L.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %W.ref.loc13_64: %L.assoc_type = name_ref W, @W.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc13_64: type = facet_access_type %.Self.ref.loc13_64 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_64: type = converted %.Self.ref.loc13_64, %.Self.as_type.loc13_64 [symbolic_self = constants.%.Self.as_type] @@ -462,7 +462,7 @@ fn G() { // CHECK:STDOUT: %.loc13_80.3: type = converted %.loc13_75, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %.loc13_80.4: type = converted %.loc13_79, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %.loc13_80.5: type = converted %.loc13_80.1, constants.%tuple.type.d7e [concrete = constants.%tuple.type.d7e] -// CHECK:STDOUT: %.Self.ref.loc13_86: %L.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.19e] +// CHECK:STDOUT: %.Self.ref.loc13_86: %L.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %W.ref.loc13_86: %L.assoc_type = name_ref W, @W.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc13_86: type = facet_access_type %.Self.ref.loc13_86 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_86: type = converted %.Self.ref.loc13_86, %.Self.as_type.loc13_86 [symbolic_self = constants.%.Self.as_type] @@ -500,9 +500,9 @@ fn G() { // CHECK:STDOUT: %assoc1: %M.assoc_type = assoc_entity element1, @M.%Y [concrete] // CHECK:STDOUT: %assoc2: %M.assoc_type = assoc_entity element2, @M.%Z [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %.Self.a61: %M.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.a61 [symbolic_self] -// CHECK:STDOUT: %M.lookup_impl_witness: = lookup_impl_witness %.Self.a61, @M [symbolic_self] +// CHECK:STDOUT: %.Self: %M.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %M.lookup_impl_witness: = lookup_impl_witness %.Self, @M [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %M.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %impl.elem1: type = impl_witness_access %M.lookup_impl_witness, element1 [symbolic_self] // CHECK:STDOUT: %impl.elem2: type = impl_witness_access %M.lookup_impl_witness, element2 [symbolic_self] @@ -514,28 +514,28 @@ fn G() { // CHECK:STDOUT: %.loc13_7.2: type = converted %.loc13_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] // CHECK:STDOUT: -// CHECK:STDOUT: %.Self.ref.loc13_20: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.a61] +// CHECK:STDOUT: %.Self.ref.loc13_20: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %X.ref.loc13_20: %M.assoc_type = name_ref X, @X.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc13_20: type = facet_access_type %.Self.ref.loc13_20 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_20: type = converted %.Self.ref.loc13_20, %.Self.as_type.loc13_20 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %impl.elem0.loc13_20: type = impl_witness_access constants.%M.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0] -// CHECK:STDOUT: %.Self.ref.loc13_25: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.a61] +// CHECK:STDOUT: %.Self.ref.loc13_25: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %Y.ref.loc13_25: %M.assoc_type = name_ref Y, @Y.%assoc1 [concrete = constants.%assoc1] // CHECK:STDOUT: %.Self.as_type.loc13_25: type = facet_access_type %.Self.ref.loc13_25 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_25: type = converted %.Self.ref.loc13_25, %.Self.as_type.loc13_25 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %impl.elem1.loc13_25: type = impl_witness_access constants.%M.lookup_impl_witness, element1 [symbolic_self = constants.%impl.elem1] -// CHECK:STDOUT: %.Self.ref.loc13_32: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.a61] +// CHECK:STDOUT: %.Self.ref.loc13_32: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %Y.ref.loc13_32: %M.assoc_type = name_ref Y, @Y.%assoc1 [concrete = constants.%assoc1] // CHECK:STDOUT: %.Self.as_type.loc13_32: type = facet_access_type %.Self.ref.loc13_32 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_32: type = converted %.Self.ref.loc13_32, %.Self.as_type.loc13_32 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %impl.elem1.loc13_32: type = impl_witness_access constants.%M.lookup_impl_witness, element1 [symbolic_self = constants.%impl.elem1] -// CHECK:STDOUT: %.Self.ref.loc13_37: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.a61] +// CHECK:STDOUT: %.Self.ref.loc13_37: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %X.ref.loc13_37: %M.assoc_type = name_ref X, @X.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc13_37: type = facet_access_type %.Self.ref.loc13_37 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_37: type = converted %.Self.ref.loc13_37, %.Self.as_type.loc13_37 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %impl.elem0.loc13_37: type = impl_witness_access constants.%M.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0] // CHECK:STDOUT: %impl.elem0.subst: type = impl_witness_access_substituted %impl.elem0.loc13_37, %impl.elem1.loc13_25 [symbolic_self = constants.%impl.elem1] -// CHECK:STDOUT: %.Self.ref.loc13_44: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.a61] +// CHECK:STDOUT: %.Self.ref.loc13_44: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc2 [concrete = constants.%assoc2] // CHECK:STDOUT: %.Self.as_type.loc13_44: type = facet_access_type %.Self.ref.loc13_44 [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc13_44: type = converted %.Self.ref.loc13_44, %.Self.as_type.loc13_44 [symbolic_self = constants.%.Self.as_type] diff --git a/toolchain/check/testdata/impl/import_interface_assoc_const.carbon b/toolchain/check/testdata/impl/import_interface_assoc_const.carbon index 5f7b52e4660c..e577b8c7463f 100644 --- a/toolchain/check/testdata/impl/import_interface_assoc_const.carbon +++ b/toolchain/check/testdata/impl/import_interface_assoc_const.carbon @@ -740,7 +740,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: %Main.I = import_ref Main//interface, I, unloaded // CHECK:STDOUT: %Main.I3: type = import_ref Main//interface, I3, loaded [concrete = constants.%I3.type] // CHECK:STDOUT: %Main.NonType = import_ref Main//interface, NonType, unloaded -// CHECK:STDOUT: %Main.import_ref.148 = import_ref Main//interface, inst28 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.148 = import_ref Main//interface, inst26 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.f5f: %I3.assoc_type = import_ref Main//interface, loc6_9, loaded [concrete = constants.%assoc0] // CHECK:STDOUT: %Main.import_ref.680: %I3.assoc_type = import_ref Main//interface, loc7_9, loaded [concrete = constants.%assoc1] // CHECK:STDOUT: %Main.import_ref.181: %I3.assoc_type = import_ref Main//interface, loc8_9, loaded [concrete = constants.%assoc2] @@ -749,13 +749,13 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: %Main.T3 = import_ref Main//interface, T3, unloaded // CHECK:STDOUT: %Main.import_ref.5fb: type = import_ref Main//interface, loc6_9, loaded [concrete = %T1] // CHECK:STDOUT: %T1: type = assoc_const_decl @T1 [concrete] {} -// CHECK:STDOUT: %Main.import_ref.8a8474.1: %I3.type = import_ref Main//interface, inst28 [no loc], loaded [symbolic = constants.%Self] +// CHECK:STDOUT: %Main.import_ref.8a8474.1: %I3.type = import_ref Main//interface, inst26 [no loc], loaded [symbolic = constants.%Self] // CHECK:STDOUT: %Main.import_ref.e26: type = import_ref Main//interface, loc7_9, loaded [concrete = %T2] // CHECK:STDOUT: %T2: type = assoc_const_decl @T2 [concrete] {} -// CHECK:STDOUT: %Main.import_ref.8a8474.2: %I3.type = import_ref Main//interface, inst28 [no loc], loaded [symbolic = constants.%Self] +// CHECK:STDOUT: %Main.import_ref.8a8474.2: %I3.type = import_ref Main//interface, inst26 [no loc], loaded [symbolic = constants.%Self] // CHECK:STDOUT: %Main.import_ref.e32: type = import_ref Main//interface, loc8_9, loaded [concrete = %T3] // CHECK:STDOUT: %T3: type = assoc_const_decl @T3 [concrete] {} -// CHECK:STDOUT: %Main.import_ref.8a8474.3: %I3.type = import_ref Main//interface, inst28 [no loc], loaded [symbolic = constants.%Self] +// CHECK:STDOUT: %Main.import_ref.8a8474.3: %I3.type = import_ref Main//interface, inst26 [no loc], loaded [symbolic = constants.%Self] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1479,12 +1479,12 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: %Main.I = import_ref Main//interface, I, unloaded // CHECK:STDOUT: %Main.I3 = import_ref Main//interface, I3, unloaded // CHECK:STDOUT: %Main.NonType: type = import_ref Main//interface, NonType, loaded [concrete = constants.%NonType.type] -// CHECK:STDOUT: %Main.import_ref.8b7 = import_ref Main//interface, inst46 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.8b7 = import_ref Main//interface, inst41 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.9fa: %NonType.assoc_type = import_ref Main//interface, loc12_8, loaded [concrete = constants.%assoc0] // CHECK:STDOUT: %Main.Y: %struct_type.a.225 = import_ref Main//interface, Y, loaded [concrete = %Y] // CHECK:STDOUT: %Main.import_ref.f3d: %struct_type.a.225 = import_ref Main//interface, loc12_8, loaded [concrete = %Y] // CHECK:STDOUT: %Y: %struct_type.a.225 = assoc_const_decl @Y [concrete] {} -// CHECK:STDOUT: %Main.import_ref.86c: %NonType.type = import_ref Main//interface, inst46 [no loc], loaded [symbolic = constants.%Self] +// CHECK:STDOUT: %Main.import_ref.86c: %NonType.type = import_ref Main//interface, inst41 [no loc], loaded [symbolic = constants.%Self] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon b/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon index 5063dd5108e1..91b8c9917009 100644 --- a/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon +++ b/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon @@ -838,9 +838,9 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: constants { // CHECK:STDOUT: %Ptr.type: type = facet_type <@Ptr> [concrete] // CHECK:STDOUT: %Self: %Ptr.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %Ptr.assoc_type: type = assoc_entity_type @Ptr [concrete] // CHECK:STDOUT: %assoc0: %Ptr.assoc_type = assoc_entity element0, @Ptr.%Type [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %.Self.8b4: %Ptr.type = bind_symbolic_name .Self [symbolic_self] @@ -1017,9 +1017,9 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: constants { // CHECK:STDOUT: %Ptr.type: type = facet_type <@Ptr> [concrete] // CHECK:STDOUT: %Self: %Ptr.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %Ptr.assoc_type: type = assoc_entity_type @Ptr [concrete] // CHECK:STDOUT: %assoc0: %Ptr.assoc_type = assoc_entity element0, @Ptr.%Type [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %.Self.8b4: %Ptr.type = bind_symbolic_name .Self [symbolic_self] @@ -1206,9 +1206,9 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: constants { // CHECK:STDOUT: %Ptr.type: type = facet_type <@Ptr> [concrete] // CHECK:STDOUT: %Self: %Ptr.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %Ptr.assoc_type: type = assoc_entity_type @Ptr [concrete] // CHECK:STDOUT: %assoc0: %Ptr.assoc_type = assoc_entity element0, @Ptr.%Type [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %.Self.8b4: %Ptr.type = bind_symbolic_name .Self [symbolic_self] diff --git a/toolchain/check/testdata/impl/use_assoc_const.carbon b/toolchain/check/testdata/impl/use_assoc_const.carbon index 85aea99e1057..a20087e7f7b1 100644 --- a/toolchain/check/testdata/impl/use_assoc_const.carbon +++ b/toolchain/check/testdata/impl/use_assoc_const.carbon @@ -961,7 +961,6 @@ fn F() { // CHECK:STDOUT: constants { // CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] // CHECK:STDOUT: %Self.ccd: %J.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] // CHECK:STDOUT: %assoc0.411: %J.assoc_type = assoc_entity element0, @J.%U [concrete] // CHECK:STDOUT: %Self.as_type.3df: type = facet_access_type %Self.ccd [symbolic] @@ -1054,6 +1053,7 @@ fn F() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ce9: = bound_method %int_6.462, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.efa: = bound_method %int_6.462, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_6.e56: %i32 = int_value 6 [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %T: %J.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.28e: type = pattern_type %J.type [concrete] // CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] @@ -1638,7 +1638,6 @@ fn F() { // CHECK:STDOUT: %assoc0.ea8: %I.assoc_type = assoc_entity element0, @I.%I.Op.decl [concrete] // CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] // CHECK:STDOUT: %Self.ccd: %J.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] // CHECK:STDOUT: %assoc0.5be: %J.assoc_type = assoc_entity element0, @J.%U [concrete] // CHECK:STDOUT: %Self.as_type.3df: type = facet_access_type %Self.ccd [symbolic] @@ -1650,6 +1649,7 @@ fn F() { // CHECK:STDOUT: %J.F.type: type = fn_type @J.F [concrete] // CHECK:STDOUT: %J.F: %J.F.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %J.assoc_type = assoc_entity element1, @J.%J.F.decl [concrete] +// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %T: %J.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.28e: type = pattern_type %J.type [concrete] // CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] @@ -1942,7 +1942,6 @@ fn F() { // CHECK:STDOUT: constants { // CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] // CHECK:STDOUT: %Self: %J.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] // CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%U [concrete] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] @@ -1954,6 +1953,7 @@ fn F() { // CHECK:STDOUT: %J.G.type: type = fn_type @J.G [concrete] // CHECK:STDOUT: %J.G: %J.G.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %J.assoc_type = assoc_entity element1, @J.%J.G.decl [concrete] +// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %T: %J.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.28e: type = pattern_type %J.type [concrete] // CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] @@ -2152,7 +2152,6 @@ fn F() { // CHECK:STDOUT: constants { // CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] // CHECK:STDOUT: %Self.ccd: %J.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] // CHECK:STDOUT: %assoc0.411: %J.assoc_type = assoc_entity element0, @J.%U [concrete] // CHECK:STDOUT: %Self.as_type.3df: type = facet_access_type %Self.ccd [symbolic] @@ -2163,6 +2162,7 @@ fn F() { // CHECK:STDOUT: %J.F.type: type = fn_type @J.F [concrete] // CHECK:STDOUT: %J.F: %J.F.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %J.assoc_type = assoc_entity element1, @J.%J.F.decl [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %.Self.968: %J.type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.968 [symbolic_self] // CHECK:STDOUT: %J.lookup_impl_witness.25c: = lookup_impl_witness %.Self.968, @J [symbolic_self] @@ -2386,9 +2386,9 @@ fn F() { // CHECK:STDOUT: %J.F: %J.F.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %J.assoc_type = assoc_entity element1, @J.%J.F.decl [concrete] // CHECK:STDOUT: %E: type = class_type @E [concrete] -// CHECK:STDOUT: %.Self.968: %J.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.968 [symbolic_self] -// CHECK:STDOUT: %J.lookup_impl_witness.25c: = lookup_impl_witness %.Self.968, @J [symbolic_self] +// CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %J.lookup_impl_witness.25c: = lookup_impl_witness %.Self, @J [symbolic_self] // CHECK:STDOUT: %J.facet.330: %J.type = facet_value %.Self.as_type, (%J.lookup_impl_witness.25c) [symbolic_self] // CHECK:STDOUT: %impl.elem0.83f: type = impl_witness_access %J.lookup_impl_witness.25c, element0 [symbolic_self] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] @@ -2531,8 +2531,8 @@ fn F() { // CHECK:STDOUT: impl_decl @E.as.J.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [concrete = constants.%E] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] -// CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.968] -// CHECK:STDOUT: %.Self.ref: %J.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.968] +// CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %J.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %U.ref: %J.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0.411] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc9_26: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] @@ -2620,9 +2620,9 @@ fn F() { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %J2.F: %J2.F.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %J2.assoc_type = assoc_entity element1, @J2.%J2.F.decl [concrete] -// CHECK:STDOUT: %.Self.3d9: %J2.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.3d9 [symbolic_self] -// CHECK:STDOUT: %J2.lookup_impl_witness: = lookup_impl_witness %.Self.3d9, @J2 [symbolic_self] +// CHECK:STDOUT: %.Self: %J2.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %J2.lookup_impl_witness: = lookup_impl_witness %.Self, @J2 [symbolic_self] // CHECK:STDOUT: %J2.facet.e30: %J2.type = facet_value %.Self.as_type, (%J2.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %J2.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] @@ -2675,8 +2675,8 @@ fn F() { // CHECK:STDOUT: %.loc22_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc22_7.2: type = converted %.loc22_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %J2.ref: type = name_ref J2, file.%J2.decl [concrete = constants.%J2.type] -// CHECK:STDOUT: %.Self: %J2.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.3d9] -// CHECK:STDOUT: %.Self.ref: %J2.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.3d9] +// CHECK:STDOUT: %.Self: %J2.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %J2.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %U2.ref: %J2.assoc_type = name_ref U2, @U2.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc22_21: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] @@ -2695,8 +2695,8 @@ fn F() { // CHECK:STDOUT: impl_decl @C2.as.J2.impl [concrete] {} { // CHECK:STDOUT: %C2.ref.loc38_6: type = name_ref C2, file.%C2.decl [concrete = constants.%C2] // CHECK:STDOUT: %J2.ref: type = name_ref J2, file.%J2.decl [concrete = constants.%J2.type] -// CHECK:STDOUT: %.Self: %J2.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.3d9] -// CHECK:STDOUT: %.Self.ref: %J2.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.3d9] +// CHECK:STDOUT: %.Self: %J2.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %J2.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %U2.ref: %J2.assoc_type = name_ref U2, @U2.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc38_21: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] @@ -2945,9 +2945,9 @@ fn F() { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %K.F: %K.F.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %K.assoc_type = assoc_entity element1, @K.%K.F.decl [concrete] -// CHECK:STDOUT: %.Self.02e: %K.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.02e [symbolic_self] -// CHECK:STDOUT: %K.lookup_impl_witness.eb2: = lookup_impl_witness %.Self.02e, @K [symbolic_self] +// CHECK:STDOUT: %.Self: %K.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %K.lookup_impl_witness.eb2: = lookup_impl_witness %.Self, @K [symbolic_self] // CHECK:STDOUT: %K.facet.b09: %K.type = facet_value %.Self.as_type, (%K.lookup_impl_witness.eb2) [symbolic_self] // CHECK:STDOUT: %impl.elem0.52c: type = impl_witness_access %K.lookup_impl_witness.eb2, element0 [symbolic_self] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %empty_tuple.type} [concrete] @@ -2982,8 +2982,8 @@ fn F() { // CHECK:STDOUT: %.loc8_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [concrete = constants.%K.type] -// CHECK:STDOUT: %.Self: %K.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.02e] -// CHECK:STDOUT: %.Self.ref: %K.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.02e] +// CHECK:STDOUT: %.Self: %K.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %K.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %V.ref: %K.assoc_type = name_ref V, @V.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc8_20: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] @@ -3155,9 +3155,9 @@ fn F() { // CHECK:STDOUT: %M.G.type: type = fn_type @M.G [concrete] // CHECK:STDOUT: %M.G: %M.G.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %M.assoc_type = assoc_entity element1, @M.%M.G.decl [concrete] -// CHECK:STDOUT: %.Self.a61: %M.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.a61 [symbolic_self] -// CHECK:STDOUT: %M.lookup_impl_witness: = lookup_impl_witness %.Self.a61, @M [symbolic_self] +// CHECK:STDOUT: %.Self: %M.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %M.lookup_impl_witness: = lookup_impl_witness %.Self, @M [symbolic_self] // CHECK:STDOUT: %M.facet.caa: %M.type = facet_value %.Self.as_type, (%M.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: %struct_type.b.347 = impl_witness_access %M.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] @@ -3187,8 +3187,8 @@ fn F() { // CHECK:STDOUT: %.loc8_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] -// CHECK:STDOUT: %.Self: %M.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.a61] -// CHECK:STDOUT: %.Self.ref: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.a61] +// CHECK:STDOUT: %.Self: %M.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc8_20: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] @@ -3859,9 +3859,9 @@ fn F() { // CHECK:STDOUT: constants { // CHECK:STDOUT: %Z.type: type = facet_type <@Z> [concrete] // CHECK:STDOUT: %Self.6e6: %Z.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %Z.assoc_type: type = assoc_entity_type @Z [concrete] // CHECK:STDOUT: %assoc0.659: %Z.assoc_type = assoc_entity element0, @Z.%X [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] diff --git a/toolchain/check/testdata/interface/compound_member_access.carbon b/toolchain/check/testdata/interface/compound_member_access.carbon index 2fc52798b1db..82f0a65b7d44 100644 --- a/toolchain/check/testdata/interface/compound_member_access.carbon +++ b/toolchain/check/testdata/interface/compound_member_access.carbon @@ -196,9 +196,9 @@ fn Works() { // CHECK:STDOUT: constants { // CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] // CHECK:STDOUT: %Self: %J.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] // CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%U [concrete] +// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %T: %J.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.28e: type = pattern_type %J.type [concrete] // CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] diff --git a/toolchain/check/testdata/interface/fail_assoc_const_alias.carbon b/toolchain/check/testdata/interface/fail_assoc_const_alias.carbon index 71e8bc7b3532..aab15ef69eb1 100644 --- a/toolchain/check/testdata/interface/fail_assoc_const_alias.carbon +++ b/toolchain/check/testdata/interface/fail_assoc_const_alias.carbon @@ -266,10 +266,10 @@ interface C { // CHECK:STDOUT: constants { // CHECK:STDOUT: %I2.type: type = facet_type <@I2> [concrete] // CHECK:STDOUT: %Self.c7b: %I2.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %I2.assoc_type: type = assoc_entity_type @I2 [concrete] // CHECK:STDOUT: %assoc0.25f: %I2.assoc_type = assoc_entity element0, @I2.%T2 [concrete] // CHECK:STDOUT: %J2.type: type = facet_type <@J2> [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %V: %J2.type = bind_symbolic_name V, 0 [symbolic] // CHECK:STDOUT: %pattern_type.f47: type = pattern_type %J2.type [concrete] // CHECK:STDOUT: %V.as_type: type = facet_access_type %V [symbolic] diff --git a/toolchain/check/testdata/interface/fail_assoc_const_not_binding.carbon b/toolchain/check/testdata/interface/fail_assoc_const_not_binding.carbon deleted file mode 100644 index 436f948b12a3..000000000000 --- a/toolchain/check/testdata/interface/fail_assoc_const_not_binding.carbon +++ /dev/null @@ -1,146 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon -// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". -// EXTRA-ARGS: --dump-sem-ir-ranges=if-present -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/fail_assoc_const_not_binding.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/fail_assoc_const_not_binding.carbon - -// --- fail_tuple_pattern.carbon - -library "[[@TEST_NAME]]"; - -interface I { - // CHECK:STDERR: fail_tuple_pattern.carbon:[[@LINE+4]]:7: error: found tuple pattern in associated constant declaration; expected symbolic binding pattern [ExpectedSingleBindingInAssociatedConstant] - // CHECK:STDERR: let (T:! type, U:! type); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: - let (T:! type, U:! type); -} - -// --- fail_tuple_pattern_with_default.carbon - -library "[[@TEST_NAME]]"; - -interface I { - // CHECK:STDERR: fail_tuple_pattern_with_default.carbon:[[@LINE+4]]:15: error: found tuple pattern in associated constant declaration; expected symbolic binding pattern [ExpectedSingleBindingInAssociatedConstant] - // CHECK:STDERR: default let (T:! type, U:! type) = ({}, {}); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: - default let (T:! type, U:! type) = ({}, {}); -} - -// --- fail_var_pattern.carbon - -library "[[@TEST_NAME]]"; - -interface I { - // CHECK:STDERR: fail_var_pattern.carbon:[[@LINE+8]]:11: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] - // CHECK:STDERR: let var T:! type; - // CHECK:STDERR: ^~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_var_pattern.carbon:[[@LINE+4]]:19: error: `var` pattern cannot declare a compile-time binding [CompileTimeBindingInVarDecl] - // CHECK:STDERR: let var T:! type; - // CHECK:STDERR: ^ - // CHECK:STDERR: - let var T:! type; -} - -// --- fail_var_pattern_with_default.carbon - -library "[[@TEST_NAME]]"; - -interface I { - // CHECK:STDERR: fail_var_pattern_with_default.carbon:[[@LINE+8]]:19: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] - // CHECK:STDERR: default let var T:! type = {}; - // CHECK:STDERR: ^~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_var_pattern_with_default.carbon:[[@LINE+4]]:28: error: `var` pattern cannot declare a compile-time binding [CompileTimeBindingInVarDecl] - // CHECK:STDERR: default let var T:! type = {}; - // CHECK:STDERR: ^ - // CHECK:STDERR: - default let var T:! type = {}; -} - -// CHECK:STDOUT: --- fail_tuple_pattern.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: has_error -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: assoc_const @ T:! type; -// CHECK:STDOUT: -// CHECK:STDOUT: assoc_const @ U:! type; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_tuple_pattern_with_default.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: has_error -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: assoc_const @ T:! type; -// CHECK:STDOUT: -// CHECK:STDOUT: assoc_const @ U:! type; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_var_pattern.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = .inst17 -// CHECK:STDOUT: witness = invalid -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_var_pattern_with_default.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = .inst17 -// CHECK:STDOUT: witness = invalid -// CHECK:STDOUT: } -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/fail_assoc_const_not_constant.carbon b/toolchain/check/testdata/interface/fail_assoc_const_not_constant.carbon deleted file mode 100644 index 59b1b4b7cf50..000000000000 --- a/toolchain/check/testdata/interface/fail_assoc_const_not_constant.carbon +++ /dev/null @@ -1,25 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/fail_assoc_const_not_constant.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/fail_assoc_const_not_constant.carbon - -interface I { - // CHECK:STDERR: fail_assoc_const_not_constant.carbon:[[@LINE+4]]:7: error: found runtime binding pattern in associated constant declaration; expected a `:!` binding [ExpectedSymbolicBindingInAssociatedConstant] - // CHECK:STDERR: let a: {.b: ()}; - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: - let a: {.b: ()}; -} - -// We shouldn't issue further errors on uses of the invalid name. -alias UseA = I.a; - -// Ideally we would still diagnose this, but it's OK that we don't. -alias UseOther = I.other; diff --git a/toolchain/check/testdata/interface/fail_assoc_const_template.carbon b/toolchain/check/testdata/interface/fail_assoc_const_template.carbon deleted file mode 100644 index d7db1ee5ee2d..000000000000 --- a/toolchain/check/testdata/interface/fail_assoc_const_template.carbon +++ /dev/null @@ -1,56 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon -// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". -// EXTRA-ARGS: --dump-sem-ir-ranges=if-present -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/fail_assoc_const_template.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/fail_assoc_const_template.carbon - -interface I { - // CHECK:STDERR: fail_assoc_const_template.carbon:[[@LINE+4]]:20: error: associated constant has `template` binding [TemplateBindingInAssociatedConstantDecl] - // CHECK:STDERR: let template T:! type; - // CHECK:STDERR: ^~~~ - // CHECK:STDERR: - let template T:! type; -} - -// CHECK:STDOUT: --- fail_assoc_const_template.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] -// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] { -// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete = constants.%assoc0] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .T = @T.%assoc0 -// CHECK:STDOUT: witness = (%T) -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) { -// CHECK:STDOUT: assoc_const T:! type; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @T(constants.%Self) {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/fail_member_lookup.carbon b/toolchain/check/testdata/interface/fail_member_lookup.carbon index 0aaaed58b3ab..17fd3cd4e541 100644 --- a/toolchain/check/testdata/interface/fail_member_lookup.carbon +++ b/toolchain/check/testdata/interface/fail_member_lookup.carbon @@ -55,7 +55,6 @@ fn G(U:! Different) -> U.(Interface.T); // CHECK:STDOUT: %Interface.F: %Interface.F.type = struct_value () [concrete] // CHECK:STDOUT: %Interface.assoc_type: type = assoc_entity_type @Interface [concrete] // CHECK:STDOUT: %assoc0.b4c: %Interface.assoc_type = assoc_entity element0, @Interface.%Interface.F.decl [concrete] -// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %assoc1: %Interface.assoc_type = assoc_entity element1, @Interface.%T [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] @@ -64,6 +63,7 @@ fn G(U:! Different) -> U.(Interface.T); // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %Different.type: type = facet_type <@Different> [concrete] // CHECK:STDOUT: %Self.e7f: %Different.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %U: %Different.type = bind_symbolic_name U, 0 [symbolic] // CHECK:STDOUT: %pattern_type.855: type = pattern_type %Different.type [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] diff --git a/toolchain/check/testdata/interface/import.carbon b/toolchain/check/testdata/interface/import.carbon index 4b2162f4e5e4..36e8054173e9 100644 --- a/toolchain/check/testdata/interface/import.carbon +++ b/toolchain/check/testdata/interface/import.carbon @@ -199,7 +199,7 @@ var f: ForwardDeclared* = &f_ref.f; // CHECK:STDOUT: %Main.import_ref.760: %Basic.assoc_type = import_ref Main//a, loc9_9, loaded [concrete = constants.%assoc1.4ea] // CHECK:STDOUT: %Main.T.44f = import_ref Main//a, T, unloaded // CHECK:STDOUT: %Main.F.eea = import_ref Main//a, F, unloaded -// CHECK:STDOUT: %Main.import_ref.52b = import_ref Main//a, inst39 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.52b = import_ref Main//a, inst37 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.ad1: %ForwardDeclared.assoc_type = import_ref Main//a, loc16_8, loaded [concrete = constants.%assoc0.d40] // CHECK:STDOUT: %Main.import_ref.339: %ForwardDeclared.assoc_type = import_ref Main//a, loc17_9, loaded [concrete = constants.%assoc1.e3d] // CHECK:STDOUT: %Main.T.6ee = import_ref Main//a, T, unloaded diff --git a/toolchain/check/testdata/patterns/underscore.carbon b/toolchain/check/testdata/patterns/underscore.carbon index 487e11ae815e..aee0dcd2b497 100644 --- a/toolchain/check/testdata/patterns/underscore.carbon +++ b/toolchain/check/testdata/patterns/underscore.carbon @@ -90,18 +90,6 @@ class C { var _: (); } -// --- fail_interface.carbon - -library "[[@TEST_NAME]]"; - -interface I { - // CHECK:STDERR: fail_interface.carbon:[[@LINE+4]]:7: error: semantics TODO: `_ used as associated constant name` [SemanticsTodo] - // CHECK:STDERR: let _:! {}; - // CHECK:STDERR: ^~~~~~ - // CHECK:STDERR: - let _:! {}; -} - // --- fail_use.carbon fn F() -> {} { @@ -501,50 +489,6 @@ fn F() -> {} { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_interface.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] -// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%_ [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: import Core//prelude -// CHECK:STDOUT: import Core//prelude/... -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: %_: %empty_struct_type = assoc_const_decl @_ [concrete] { -// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%_ [concrete = constants.%assoc0] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: ._ = @_.%assoc0 -// CHECK:STDOUT: witness = (%_) -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic assoc_const @_(@I.%Self: %I.type) { -// CHECK:STDOUT: assoc_const _:! %empty_struct_type; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @_(constants.%Self) {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_use.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/tuple/tuple_pattern.carbon b/toolchain/check/testdata/tuple/tuple_pattern.carbon index 484febc8602a..06783d1faab4 100644 --- a/toolchain/check/testdata/tuple/tuple_pattern.carbon +++ b/toolchain/check/testdata/tuple/tuple_pattern.carbon @@ -67,26 +67,6 @@ library "[[@TEST_NAME]]"; let (x: {}, y: {}) = ({}, {}); //@dump-sem-ir-end -// --- fail_in_interface.carbon - -library "[[@TEST_NAME]]"; - -interface I { - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+12]]:8: error: found runtime binding pattern in associated constant declaration; expected a `:!` binding [ExpectedSymbolicBindingInAssociatedConstant] - // CHECK:STDERR: let (x: {}, y: {}); - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+8]]:15: error: found runtime binding pattern in associated constant declaration; expected a `:!` binding [ExpectedSymbolicBindingInAssociatedConstant] - // CHECK:STDERR: let (x: {}, y: {}); - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:7: error: found tuple pattern in associated constant declaration; expected symbolic binding pattern [ExpectedSingleBindingInAssociatedConstant] - // CHECK:STDERR: let (x: {}, y: {}); - // CHECK:STDERR: ^~~~~~~~~~~~~~ - // CHECK:STDERR: - let (x: {}, y: {}); -} - // --- fail_in_class.carbon library "[[@TEST_NAME]]"; diff --git a/toolchain/check/testdata/var/fail_in_interface.carbon b/toolchain/check/testdata/var/fail_in_interface.carbon deleted file mode 100644 index 8afcdaa3fb08..000000000000 --- a/toolchain/check/testdata/var/fail_in_interface.carbon +++ /dev/null @@ -1,41 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/var/fail_in_interface.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/var/fail_in_interface.carbon - -interface I { - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:11: error: found runtime binding pattern in associated constant declaration; expected a `:!` binding [ExpectedSymbolicBindingInAssociatedConstant] - // CHECK:STDERR: let var a: (); - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: - let var a: (); - - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:7: error: found runtime binding pattern in associated constant declaration; expected a `:!` binding [ExpectedSymbolicBindingInAssociatedConstant] - // CHECK:STDERR: var b: (); - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: - var b: (); - - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+8]]:11: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] - // CHECK:STDERR: let var c:! (); - // CHECK:STDERR: ^~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:17: error: `var` pattern cannot declare a compile-time binding [CompileTimeBindingInVarDecl] - // CHECK:STDERR: let var c:! (); - // CHECK:STDERR: ^ - // CHECK:STDERR: - let var c:! (); - - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:13: error: `var` pattern cannot declare a compile-time binding [CompileTimeBindingInVarDecl] - // CHECK:STDERR: var d:! (); - // CHECK:STDERR: ^ - // CHECK:STDERR: - var d:! (); -} diff --git a/toolchain/check/testdata/where_expr/designator.carbon b/toolchain/check/testdata/where_expr/designator.carbon index 4ef83e3d4468..97ec3c3a0e80 100644 --- a/toolchain/check/testdata/where_expr/designator.carbon +++ b/toolchain/check/testdata/where_expr/designator.carbon @@ -137,9 +137,9 @@ fn G(T:! type where C(()) impls I(.Self)) {} // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%Member [concrete] +// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where TODO> [concrete] diff --git a/toolchain/check/testdata/where_expr/non_generic.carbon b/toolchain/check/testdata/where_expr/non_generic.carbon index 54a73547c8d5..26f129e74890 100644 --- a/toolchain/check/testdata/where_expr/non_generic.carbon +++ b/toolchain/check/testdata/where_expr/non_generic.carbon @@ -23,9 +23,9 @@ fn NotGenericF(U: I where .T == i32) {} // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete] -// CHECK:STDOUT: %.Self.258: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.258 [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.258, @I [symbolic_self] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] @@ -47,7 +47,7 @@ fn NotGenericF(U: I where .T == i32) {} // CHECK:STDOUT: %.loc17_21.1: type = splice_block %.loc17_21.2 [concrete = constants.%I_where.type] { // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: -// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self.258] +// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %T.ref: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc17_27: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 2ddab7b957e9..3ae7cf297fac 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -158,6 +158,8 @@ CARBON_DIAGNOSTIC_KIND(ExpectedFieldIdentifier) CARBON_DIAGNOSTIC_KIND(ExpectedFieldColon) CARBON_DIAGNOSTIC_KIND(ImplExpectedAfterForall) CARBON_DIAGNOSTIC_KIND(ImplExpectedAs) +CARBON_DIAGNOSTIC_KIND(ExpectedAssociatedConstantIdentifier) +CARBON_DIAGNOSTIC_KIND(ExpectedAssociatedConstantColonExclaim) // Alias diagnostics. CARBON_DIAGNOSTIC_KIND(ExpectedAliasInitializer) @@ -351,11 +353,6 @@ CARBON_DIAGNOSTIC_KIND(MissingImplInMemberAccessNote) // Let declaration checking. CARBON_DIAGNOSTIC_KIND(ExpectedInitializerAfterLet) -CARBON_DIAGNOSTIC_KIND(ExpectedSymbolicBindingInAssociatedConstant) -CARBON_DIAGNOSTIC_KIND(ExpectedSingleBindingInAssociatedConstant) - -// Pattern checking. -CARBON_DIAGNOSTIC_KIND(TemplateBindingInAssociatedConstantDecl) // Qualified declaration name checking. CARBON_DIAGNOSTIC_KIND(QualifiedDeclOutsidePackage) diff --git a/toolchain/parse/context.cpp b/toolchain/parse/context.cpp index 57bc87a7ddc6..be33fad796ed 100644 --- a/toolchain/parse/context.cpp +++ b/toolchain/parse/context.cpp @@ -438,7 +438,8 @@ static auto ParsingInDeferredDefinitionScope(Context& context) -> bool { auto& stack = context.state_stack(); if (stack.size() < 2 || (stack.back().kind != StateKind::DeclScopeLoopAsClass && - stack.back().kind != StateKind::DeclScopeLoopAsNonClass)) { + stack.back().kind != StateKind::DeclScopeLoopAsInterface && + stack.back().kind != StateKind::DeclScopeLoopAsRegular)) { return false; } auto kind = stack[stack.size() - 2].kind; diff --git a/toolchain/parse/handle_decl_definition.cpp b/toolchain/parse/handle_decl_definition.cpp index 9285a4dafe03..f63a2d35c700 100644 --- a/toolchain/parse/handle_decl_definition.cpp +++ b/toolchain/parse/handle_decl_definition.cpp @@ -24,8 +24,10 @@ static auto HandleDeclOrDefinition(Context& context, NodeKind decl_kind, context.PushState(state, definition_finish_state); if (decl_kind == NodeKind::ClassDecl) { context.PushState(StateKind::DeclScopeLoopAsClass); + } else if (decl_kind == NodeKind::InterfaceDecl) { + context.PushState(StateKind::DeclScopeLoopAsInterface); } else { - context.PushState(StateKind::DeclScopeLoopAsNonClass); + context.PushState(StateKind::DeclScopeLoopAsRegular); } context.AddNode(definition_start_kind, context.Consume(), state.has_error); } diff --git a/toolchain/parse/handle_decl_scope_loop.cpp b/toolchain/parse/handle_decl_scope_loop.cpp index 87876ca7f2b0..94e2b8c4e69b 100644 --- a/toolchain/parse/handle_decl_scope_loop.cpp +++ b/toolchain/parse/handle_decl_scope_loop.cpp @@ -46,9 +46,10 @@ static auto ApplyIntroducer(Context& context, Context::State state, namespace { // The kind of context in which a declaration appears. enum DeclContextKind : int8_t { - NonClassContext = 0, + RegularContext = 0, ClassContext = 1, - MaxDeclContextKind = ClassContext, + InterfaceContext = 2, + MaxDeclContextKind = InterfaceContext, }; // The kind of declaration introduced by an introducer keyword. @@ -72,6 +73,9 @@ static constexpr auto DeclIntroducers = [] { {{{.introducer_kind = DeclIntroducerKind::Unrecognized, \ .node_kind = NodeKind::InvalidParse, \ .state_kind = StateKind::Invalid}, \ + {.introducer_kind = DeclIntroducerKind::Unrecognized, \ + .node_kind = NodeKind::InvalidParse, \ + .state_kind = StateKind::Invalid}, \ {.introducer_kind = DeclIntroducerKind::Unrecognized, \ .node_kind = NodeKind::InvalidParse, \ .state_kind = StateKind::Invalid}}}, @@ -126,8 +130,14 @@ static constexpr auto DeclIntroducers = [] { StateKind::TypeAfterIntroducerAsInterface); set(Lex::TokenKind::Namespace, NodeKind::NamespaceStart, StateKind::Namespace); - set(Lex::TokenKind::Let, NodeKind::LetIntroducer, StateKind::Let); - set_contextual(Lex::TokenKind::Var, NonClassContext, + set_contextual(Lex::TokenKind::Let, RegularContext, NodeKind::LetIntroducer, + StateKind::Let); + set_contextual(Lex::TokenKind::Let, ClassContext, NodeKind::LetIntroducer, + StateKind::Let); + set_contextual(Lex::TokenKind::Let, InterfaceContext, + NodeKind::AssociatedConstantIntroducer, + StateKind::AssociatedConstant); + set_contextual(Lex::TokenKind::Var, RegularContext, NodeKind::VariableIntroducer, StateKind::VarAsRegular); set_contextual(Lex::TokenKind::Var, ClassContext, NodeKind::FieldIntroducer, StateKind::FieldDecl); @@ -294,8 +304,12 @@ auto HandleDeclAsClass(Context& context) -> void { HandleDecl(context, ClassContext); } -auto HandleDeclAsNonClass(Context& context) -> void { - HandleDecl(context, NonClassContext); +auto HandleDeclAsInterface(Context& context) -> void { + HandleDecl(context, InterfaceContext); +} + +auto HandleDeclAsRegular(Context& context) -> void { + HandleDecl(context, RegularContext); } static auto HandleDeclScopeLoop(Context& context, StateKind decl_state_kind) @@ -315,8 +329,12 @@ auto HandleDeclScopeLoopAsClass(Context& context) -> void { HandleDeclScopeLoop(context, StateKind::DeclAsClass); } -auto HandleDeclScopeLoopAsNonClass(Context& context) -> void { - HandleDeclScopeLoop(context, StateKind::DeclAsNonClass); +auto HandleDeclScopeLoopAsInterface(Context& context) -> void { + HandleDeclScopeLoop(context, StateKind::DeclAsInterface); +} + +auto HandleDeclScopeLoopAsRegular(Context& context) -> void { + HandleDeclScopeLoop(context, StateKind::DeclAsRegular); } } // namespace Carbon::Parse diff --git a/toolchain/parse/handle_let.cpp b/toolchain/parse/handle_let.cpp index 9e7d54c753f6..b50af81c058c 100644 --- a/toolchain/parse/handle_let.cpp +++ b/toolchain/parse/handle_let.cpp @@ -2,8 +2,11 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include "toolchain/diagnostics/diagnostic.h" +#include "toolchain/lex/token_kind.h" #include "toolchain/parse/context.h" #include "toolchain/parse/handle.h" +#include "toolchain/parse/node_kind.h" namespace Carbon::Parse { @@ -11,14 +14,53 @@ auto HandleLet(Context& context) -> void { auto state = context.PopState(); // These will start at the `let`. - context.PushState(state, StateKind::LetFinish); - context.PushState(state, StateKind::LetAfterPattern); + context.PushState(state, StateKind::LetFinishAsRegular); + context.PushState(state, StateKind::LetAfterPatternAsRegular); // This will start at the pattern. context.PushState(StateKind::Pattern); } -auto HandleLetAfterPattern(Context& context) -> void { +auto HandleAssociatedConstant(Context& context) -> void { + auto state = context.PopState(); + + // Parse the associated constant pattern: identifier :! type + auto identifier = context.ConsumeIf(Lex::TokenKind::Identifier); + if (!identifier) { + CARBON_DIAGNOSTIC(ExpectedAssociatedConstantIdentifier, Error, + "expected identifier in associated constant declaration"); + context.emitter().Emit(*context.position(), + ExpectedAssociatedConstantIdentifier); + state.has_error = true; + } + + auto colon_exclaim = context.ConsumeIf(Lex::TokenKind::ColonExclaim); + if (identifier && !colon_exclaim) { + CARBON_DIAGNOSTIC(ExpectedAssociatedConstantColonExclaim, Error, + "found runtime binding pattern in associated constant " + "declaration; expected a `:!` binding"); + context.emitter().Emit(*context.position(), + ExpectedAssociatedConstantColonExclaim); + state.has_error = true; + } + + if (!identifier || !colon_exclaim) { + auto end_token = context.SkipPastLikelyEnd(*(context.position() - 1)); + context.AddNode(NodeKind::AssociatedConstantDecl, end_token, + /*has_error=*/true); + state.has_error = true; + return; + } + + context.AddLeafNode(NodeKind::IdentifierNameNotBeforeParams, *identifier); + state.token = *colon_exclaim; + context.PushState(state, StateKind::LetFinishAsAssociatedConstant); + context.PushState(state, StateKind::LetAfterPatternAsAssociatedConstant); + context.PushState(StateKind::Expr); +} + +static auto HandleLetAfterPattern(Context& context, NodeKind init_kind) + -> void { auto state = context.PopState(); if (state.has_error) { @@ -29,12 +71,24 @@ auto HandleLetAfterPattern(Context& context) -> void { } if (auto equals = context.ConsumeIf(Lex::TokenKind::Equal)) { - context.AddLeafNode(NodeKind::LetInitializer, *equals); + context.AddLeafNode(init_kind, *equals); context.PushState(StateKind::Expr); } } -auto HandleLetFinish(Context& context) -> void { +auto HandleLetAfterPatternAsRegular(Context& context) -> void { + HandleLetAfterPattern(context, NodeKind::LetInitializer); +} + +auto HandleLetAfterPatternAsAssociatedConstant(Context& context) -> void { + auto state = context.PopState(); + context.AddNode(NodeKind::AssociatedConstantNameAndType, state.token, + state.has_error); + context.PushState(state); + HandleLetAfterPattern(context, NodeKind::AssociatedConstantInitializer); +} + +static auto HandleLetFinish(Context& context, NodeKind node_kind) -> void { auto state = context.PopState(); auto end_token = state.token; @@ -45,7 +99,15 @@ auto HandleLetFinish(Context& context) -> void { state.has_error = true; end_token = context.SkipPastLikelyEnd(state.token); } - context.AddNode(NodeKind::LetDecl, end_token, state.has_error); + context.AddNode(node_kind, end_token, state.has_error); +} + +auto HandleLetFinishAsRegular(Context& context) -> void { + HandleLetFinish(context, NodeKind::LetDecl); +} + +auto HandleLetFinishAsAssociatedConstant(Context& context) -> void { + HandleLetFinish(context, NodeKind::AssociatedConstantDecl); } } // namespace Carbon::Parse diff --git a/toolchain/parse/handle_statement.cpp b/toolchain/parse/handle_statement.cpp index a593643d6bfd..317bf2884dcf 100644 --- a/toolchain/parse/handle_statement.cpp +++ b/toolchain/parse/handle_statement.cpp @@ -67,7 +67,7 @@ auto HandleStatement(Context& context) -> void { // We intentionally don't handle Package here, because `package.` can be // used at the start of an expression, and it's not worth disambiguating it. case Lex::TokenKind::Var: { - context.PushState(StateKind::DeclAsNonClass); + context.PushState(StateKind::DeclAsRegular); break; } default: { diff --git a/toolchain/parse/node_kind.def b/toolchain/parse/node_kind.def index 25ae8eada3a1..55dfecbfeec4 100644 --- a/toolchain/parse/node_kind.def +++ b/toolchain/parse/node_kind.def @@ -173,6 +173,7 @@ CARBON_PARSE_NODE_KIND(ArrayExprComma) CARBON_PARSE_NODE_KIND(ArrayExpr) CARBON_PARSE_NODE_KIND(LetBindingPattern) +CARBON_PARSE_NODE_KIND(AssociatedConstantNameAndType) CARBON_PARSE_NODE_KIND(VarBindingPattern) CARBON_PARSE_NODE_KIND(TemplateBindingName) CARBON_PARSE_NODE_KIND(CompileTimeBindingPatternStart) @@ -183,6 +184,10 @@ CARBON_PARSE_NODE_KIND(LetIntroducer) CARBON_PARSE_NODE_KIND(LetInitializer) CARBON_PARSE_NODE_KIND(LetDecl) +CARBON_PARSE_NODE_KIND(AssociatedConstantIntroducer) +CARBON_PARSE_NODE_KIND(AssociatedConstantInitializer) +CARBON_PARSE_NODE_KIND(AssociatedConstantDecl) + CARBON_PARSE_NODE_KIND(VariableIntroducer) CARBON_PARSE_NODE_KIND(ReturnedModifier) CARBON_PARSE_NODE_KIND(VariableInitializer) diff --git a/toolchain/parse/parse.cpp b/toolchain/parse/parse.cpp index 5c837781ff7b..0598c96f5594 100644 --- a/toolchain/parse/parse.cpp +++ b/toolchain/parse/parse.cpp @@ -31,7 +31,7 @@ auto Parse(Lex::TokenizedBuffer& tokens, ParseOptions options) -> Tree { context.AddLeafNode(NodeKind::FileStart, context.ConsumeChecked(Lex::TokenKind::FileStart)); - context.PushState(StateKind::DeclScopeLoopAsNonClass); + context.PushState(StateKind::DeclScopeLoopAsRegular); while (!context.state_stack().empty()) { switch (context.state_stack().back().kind) { diff --git a/toolchain/parse/state.def b/toolchain/parse/state.def index 12ede7a0416f..283ff96b4441 100644 --- a/toolchain/parse/state.def +++ b/toolchain/parse/state.def @@ -339,10 +339,14 @@ CARBON_PARSE_STATE(DeclNameAndParamsAfterParams) // ^~~~~~~~~ // 1. TypeAfterIntroducerAsInterface // -// let ... +// let ... (variant is Regular) // ^~~ // 1. Let // +// let ... (variant is Interface) +// ^~~ +// 1. AssociatedConstant +// // library ... (in packaging directives) // ^~~~~~~ // 1. Library @@ -355,7 +359,7 @@ CARBON_PARSE_STATE(DeclNameAndParamsAfterParams) // ^~~~~~~ // 1. Package // -// var ... (variant is NonClass) +// var ... (variant is Regular) // ^~~ // 1. VarAsRegular // @@ -370,7 +374,7 @@ CARBON_PARSE_STATE(DeclNameAndParamsAfterParams) // ??? ; // ^~~~~ // (state done) -CARBON_PARSE_STATE_VARIANTS2(Decl, Class, NonClass) +CARBON_PARSE_STATE_VARIANTS3(Decl, Class, Interface, Regular) // Handles processing of a declaration scope, which contains a sequence of // declarations. @@ -383,10 +387,10 @@ CARBON_PARSE_STATE_VARIANTS2(Decl, Class, NonClass) // // ... // ^ -// 1. DeclAs(Class|NonClass) -// 2. DeclScopeLoopAs(Class|NonClass) +// 1. DeclAs(Class|Interface|Regular) +// 2. DeclScopeLoopAs(Class|Interface|Regular) // -CARBON_PARSE_STATE_VARIANTS2(DeclScopeLoop, Class, NonClass) +CARBON_PARSE_STATE_VARIANTS3(DeclScopeLoop, Class, Interface, Regular) // Handles periods. Only does one `.` segment; the source is // responsible for handling chaining. @@ -1273,7 +1277,7 @@ CARBON_PARSE_STATE_VARIANTS3(TypeAfterIntroducer, Class, Interface, // // class/impl/interface/constraint name ( ... ) { // ^ -// 1. DeclScopeLoopAs(Class|NonClass) +// 1. DeclScopeLoopAs(Class|Regular) // 2. DeclDefinitionFinishAs(Class|Impl|Interface|NamedConstraint) // // class/impl/interface/constraint name ( ... ) ; @@ -1440,14 +1444,29 @@ CARBON_PARSE_STATE(Let) // let ... ??? ; // ^~~ // (state done) -CARBON_PARSE_STATE(LetAfterPattern) +CARBON_PARSE_STATE_VARIANTS2(LetAfterPattern, Regular, AssociatedConstant) // Handles `let` parsing at the end. // // let ... ; // ^ +// let ... ??? ; +// ^~~~~ // (state done) -CARBON_PARSE_STATE(LetFinish) +CARBON_PARSE_STATE_VARIANTS2(LetFinish, Regular, AssociatedConstant) + +// Handles the start of an associated constant declaration (`let` in an +// interface context). +// +// let name :! ... +// ^~~~~~~ +// 1. AssociatedConstantFinish +// let ??? ; +// ^~~~~ +// let name ??? ; +// ^~~~~~~~~ +// (state done) +CARBON_PARSE_STATE(AssociatedConstant) // Handles a choice's introducer. // diff --git a/toolchain/parse/testdata/generics/interface/associated_constants.carbon b/toolchain/parse/testdata/generics/interface/associated_constants.carbon index 74168a45cd71..41faf67e9946 100644 --- a/toolchain/parse/testdata/generics/interface/associated_constants.carbon +++ b/toolchain/parse/testdata/generics/interface/associated_constants.carbon @@ -8,35 +8,91 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/generics/interface/associated_constants.carbon -interface Foo { - // TODO: support `let T:! type;` +// --- associated_constants.carbon - final let I: i32 = 4; - default let D: bool = true; +library "[[@TEST_NAME]]"; + +interface I { + let T:! type; + final let I:! i32; + default let D:! bool; +} + +// --- initializer.carbon + +library "[[@TEST_NAME]]"; + +interface I { + let T:! type = (i32, i32); + final let I:! i32 = 42; + default let D:! bool = false; } // CHECK:STDOUT: - filename: associated_constants.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"associated_constants"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, // CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, +// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, // CHECK:STDOUT: {kind: 'FinalModifier', text: 'final'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, // CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'LetInitializer', text: '='}, -// CHECK:STDOUT: {kind: 'IntLiteral', text: '4'}, -// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, // CHECK:STDOUT: {kind: 'DefaultModifier', text: 'default'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'D'}, // CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'LetInitializer', text: '='}, -// CHECK:STDOUT: {kind: 'BoolLiteralTrue', text: 'true'}, -// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 20}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 21}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: initializer.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"initializer"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, +// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'FinalModifier', text: 'final'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '42'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'DefaultModifier', text: 'default'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'D'}, +// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'BoolLiteralFalse', text: 'false'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 31}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/generics/interface/fail_associated_constants.carbon b/toolchain/parse/testdata/generics/interface/fail_associated_constants.carbon new file mode 100644 index 000000000000..f64a6a2b56a0 --- /dev/null +++ b/toolchain/parse/testdata/generics/interface/fail_associated_constants.carbon @@ -0,0 +1,196 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/generics/interface/fail_associated_constants.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/generics/interface/fail_associated_constants.carbon + +// --- fail_tuple_pattern.carbon + +library "[[@TEST_NAME]]"; + +interface I { + // CHECK:STDERR: fail_tuple_pattern.carbon:[[@LINE+4]]:7: error: expected identifier in associated constant declaration [ExpectedAssociatedConstantIdentifier] + // CHECK:STDERR: let (T:! type, U:! type); + // CHECK:STDERR: ^ + // CHECK:STDERR: + let (T:! type, U:! type); +} + +// --- fail_tuple_pattern_with_default.carbon + +library "[[@TEST_NAME]]"; + +interface I { + // CHECK:STDERR: fail_tuple_pattern_with_default.carbon:[[@LINE+4]]:15: error: expected identifier in associated constant declaration [ExpectedAssociatedConstantIdentifier] + // CHECK:STDERR: default let (T:! type, U:! type) = ({}, {}); + // CHECK:STDERR: ^ + // CHECK:STDERR: + default let (T:! type, U:! type) = ({}, {}); +} + +// --- fail_var_pattern.carbon + +library "[[@TEST_NAME]]"; + +interface I { + // CHECK:STDERR: fail_var_pattern.carbon:[[@LINE+4]]:7: error: expected identifier in associated constant declaration [ExpectedAssociatedConstantIdentifier] + // CHECK:STDERR: let var T:! type; + // CHECK:STDERR: ^~~ + // CHECK:STDERR: + let var T:! type; +} + +// --- fail_var_pattern_with_default.carbon + +library "[[@TEST_NAME]]"; + +interface I { + // CHECK:STDERR: fail_var_pattern_with_default.carbon:[[@LINE+4]]:15: error: expected identifier in associated constant declaration [ExpectedAssociatedConstantIdentifier] + // CHECK:STDERR: default let var T:! type = {}; + // CHECK:STDERR: ^~~ + // CHECK:STDERR: + default let var T:! type = {}; +} + +// --- fail_not_constant.carbon + +library "[[@TEST_NAME]]"; + +interface I { + // CHECK:STDERR: fail_not_constant.carbon:[[@LINE+4]]:8: error: found runtime binding pattern in associated constant declaration; expected a `:!` binding [ExpectedAssociatedConstantColonExclaim] + // CHECK:STDERR: let a: {.b: ()}; + // CHECK:STDERR: ^ + // CHECK:STDERR: + let a: {.b: ()}; +} + +// --- fail_template.carbon + +library "[[@TEST_NAME]]"; + +interface I { + // CHECK:STDERR: fail_template.carbon:[[@LINE+4]]:7: error: expected identifier in associated constant declaration [ExpectedAssociatedConstantIdentifier] + // CHECK:STDERR: let template T:! type; + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: + let template T:! type; +} + + +// --- fail_underscore.carbon + +library "[[@TEST_NAME]]"; + +interface I { + // CHECK:STDERR: fail_underscore.carbon:[[@LINE+4]]:7: error: expected identifier in associated constant declaration [ExpectedAssociatedConstantIdentifier] + // CHECK:STDERR: let _:! {}; + // CHECK:STDERR: ^ + // CHECK:STDERR: + let _:! {}; +} + + +// CHECK:STDOUT: - filename: fail_tuple_pattern.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"tuple_pattern"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_tuple_pattern_with_default.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"tuple_pattern_with_default"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'DefaultModifier', text: 'default'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_var_pattern.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"var_pattern"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_var_pattern_with_default.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"var_pattern_with_default"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'DefaultModifier', text: 'default'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_not_constant.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"not_constant"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_template.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"template"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_underscore.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"underscore"'}, +// CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/let/fail_missing_name.carbon b/toolchain/parse/testdata/let/fail_missing_name.carbon index a94b3c8391b1..97bc329171d8 100644 --- a/toolchain/parse/testdata/let/fail_missing_name.carbon +++ b/toolchain/parse/testdata/let/fail_missing_name.carbon @@ -16,9 +16,9 @@ // CHECK:STDERR: let : i32 = 4; -// --- fail_complietime_binding.carbon +// --- fail_compiletime_binding.carbon -// CHECK:STDERR: fail_complietime_binding.carbon:[[@LINE+4]]:5: error: expected name in binding pattern [ExpectedBindingPattern] +// CHECK:STDERR: fail_compiletime_binding.carbon:[[@LINE+4]]:5: error: expected name in binding pattern [ExpectedBindingPattern] // CHECK:STDERR: let :! bool = true; // CHECK:STDERR: ^~ // CHECK:STDERR: @@ -36,7 +36,7 @@ let :! bool = true; // CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 7}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] -// CHECK:STDOUT: - filename: fail_complietime_binding.carbon +// CHECK:STDOUT: - filename: fail_compiletime_binding.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, diff --git a/toolchain/parse/testdata/let/missing_value.carbon b/toolchain/parse/testdata/let/missing_value.carbon index f5eae659051d..074d5d27ae9b 100644 --- a/toolchain/parse/testdata/let/missing_value.carbon +++ b/toolchain/parse/testdata/let/missing_value.carbon @@ -40,12 +40,11 @@ interface I { // CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, // CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, -// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':!', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, // CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'}, -// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':!', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 9}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/var/fail_in_interface.carbon b/toolchain/parse/testdata/var/fail_in_interface.carbon new file mode 100644 index 000000000000..fa98c033a93e --- /dev/null +++ b/toolchain/parse/testdata/var/fail_in_interface.carbon @@ -0,0 +1,53 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/var/fail_in_interface.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/var/fail_in_interface.carbon + +interface I { + // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:7: error: expected identifier in associated constant declaration [ExpectedAssociatedConstantIdentifier] + // CHECK:STDERR: let var a: (); + // CHECK:STDERR: ^~~ + // CHECK:STDERR: + let var a: (); + + // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:3: error: unrecognized declaration introducer [UnrecognizedDecl] + // CHECK:STDERR: var b: (); + // CHECK:STDERR: ^~~ + // CHECK:STDERR: + var b: (); + + // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:7: error: expected identifier in associated constant declaration [ExpectedAssociatedConstantIdentifier] + // CHECK:STDERR: let var c:! (); + // CHECK:STDERR: ^~~ + // CHECK:STDERR: + let var c:! (); + + // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:3: error: unrecognized declaration introducer [UnrecognizedDecl] + // CHECK:STDERR: var d:! (); + // CHECK:STDERR: ^~~ + // CHECK:STDERR: + var d:! (); +} + +// CHECK:STDOUT: - filename: fail_in_interface.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InvalidParseStart', text: 'var', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParseSubtree', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InvalidParseStart', text: 'var', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParseSubtree', text: ';', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 12}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/where_expr/basic.carbon b/toolchain/parse/testdata/where_expr/basic.carbon index a2d79fcf6a13..c54a9386d62b 100644 --- a/toolchain/parse/testdata/where_expr/basic.carbon +++ b/toolchain/parse/testdata/where_expr/basic.carbon @@ -40,9 +40,8 @@ fn F() { // CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'I'}, // CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, -// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':!', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, // CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'}, // CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, @@ -50,9 +49,9 @@ fn F() { // CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Bar'}, // CHECK:STDOUT: {kind: 'RequirementImpls', text: 'impls', subtree_size: 4}, // CHECK:STDOUT: {kind: 'WhereExpr', text: 'where', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':!', subtree_size: 10}, -// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 12}, -// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 16}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 15}, // CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, // CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':!', subtree_size: 2}, diff --git a/toolchain/parse/testdata/where_expr/impl_where.carbon b/toolchain/parse/testdata/where_expr/impl_where.carbon index 5c930ed3ab50..0c05e5754bcc 100644 --- a/toolchain/parse/testdata/where_expr/impl_where.carbon +++ b/toolchain/parse/testdata/where_expr/impl_where.carbon @@ -30,13 +30,12 @@ impl f64 as Interface where .T = (type where .Self impls type) { // CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Interface'}, // CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, -// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':!', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, // CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'}, -// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':!', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 9}, // CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'}, // CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, // CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2}, diff --git a/toolchain/parse/typed_nodes.h b/toolchain/parse/typed_nodes.h index fc74f1b23b29..13273eb4b22f 100644 --- a/toolchain/parse/typed_nodes.h +++ b/toolchain/parse/typed_nodes.h @@ -554,6 +554,39 @@ struct LetDecl { Lex::SemiTokenIndex token; }; +// Associated constant nodes +using AssociatedConstantIntroducer = + LeafNode; +using AssociatedConstantInitializer = + LeafNode; + +struct AssociatedConstantNameAndType { + static constexpr auto Kind = NodeKind::AssociatedConstantNameAndType.Define( + {.category = NodeCategory::Pattern, .child_count = 2}); + + AnyRuntimeBindingPatternName name; + Lex::ColonExclaimTokenIndex token; + AnyExprId type; +}; + +// An associated constant declaration: `let a:! i32;`. +struct AssociatedConstantDecl { + static constexpr auto Kind = NodeKind::AssociatedConstantDecl.Define( + {.category = NodeCategory::Decl, + .bracketed_by = AssociatedConstantIntroducer::Kind}); + + AssociatedConstantIntroducerId introducer; + llvm::SmallVector modifiers; + AssociatedConstantNameAndTypeId pattern; + + struct Initializer { + AssociatedConstantInitializerId equals; + AnyExprId initializer; + }; + std::optional initializer; + Lex::SemiTokenIndex token; +}; + // `var` nodes // ----------- diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index e98ededbceee..eaf9f3ecdd93 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -182,7 +182,7 @@ struct Assign { struct AssociatedConstantDecl { static constexpr auto Kind = InstKind::AssociatedConstantDecl - .Define( + .Define( {.ir_name = "assoc_const_decl", .constant_kind = InstConstantKind::AlwaysUnique, .is_lowered = false});