Browse Source

Implement unused pattern bindings, continued (#6518)

Implementation of unused pattern bindings #2022, continued.

Whereas previous PR #6460 took care of parsing, and PR #6479 prepared
the stage by using _ in some test cases, this PR has the the actual
implementation, using a simple dataflow analysis.

---------

Co-authored-by: Burak Emir <bqe@google.com>
Co-authored-by: jonmeow <jperkins@google.com>
Burak Emir 2 months ago
parent
commit
fdb188ccfd
100 changed files with 2443 additions and 2040 deletions
  1. 1 1
      core/prelude/iterate.carbon
  2. 2 2
      core/prelude/types/cpp/nullptr.carbon
  3. 8 29
      toolchain/check/BUILD
  4. 2 1
      toolchain/check/check_unit.cpp
  5. 1 1
      toolchain/check/context.cpp
  6. 4 2
      toolchain/check/cpp/import.cpp
  7. 5 3
      toolchain/check/decl_name_stack.cpp
  8. 3 1
      toolchain/check/decl_name_stack.h
  9. 5 8
      toolchain/check/facet_type.cpp
  10. 5 4
      toolchain/check/function.cpp
  11. 2 1
      toolchain/check/function.h
  12. 72 7
      toolchain/check/handle_binding_pattern.cpp
  13. 2 1
      toolchain/check/handle_choice.cpp
  14. 2 1
      toolchain/check/handle_codeblock.cpp
  15. 69 7
      toolchain/check/handle_function.cpp
  16. 3 2
      toolchain/check/handle_struct.cpp
  17. 2 1
      toolchain/check/handle_where.cpp
  18. 1 1
      toolchain/check/import_ref.cpp
  19. 2 1
      toolchain/check/interface.cpp
  20. 16 3
      toolchain/check/lexical_lookup.h
  21. 13 2
      toolchain/check/merge.cpp
  22. 10 6
      toolchain/check/name_lookup.cpp
  23. 4 4
      toolchain/check/pattern.cpp
  24. 5 2
      toolchain/check/pattern.h
  25. 3 2
      toolchain/check/return.cpp
  26. 1 1
      toolchain/check/return.h
  27. 99 26
      toolchain/check/scope_stack.cpp
  28. 38 19
      toolchain/check/scope_stack.h
  29. 51 51
      toolchain/check/testdata/array/basics.carbon
  30. 26 26
      toolchain/check/testdata/array/init_dependent_bound.carbon
  31. 20 20
      toolchain/check/testdata/as/adapter_conversion.carbon
  32. 58 58
      toolchain/check/testdata/as/basics.carbon
  33. 82 82
      toolchain/check/testdata/as/const.carbon
  34. 123 123
      toolchain/check/testdata/as/maybe_unformed.carbon
  35. 114 114
      toolchain/check/testdata/as/partial.carbon
  36. 8 8
      toolchain/check/testdata/as/var_init.carbon
  37. 1 1
      toolchain/check/testdata/basics/dump_sem_ir_ranges.carbon
  38. 16 16
      toolchain/check/testdata/basics/duplicate_name_same_line.carbon
  39. 12 12
      toolchain/check/testdata/basics/include_in_dumps.carbon
  40. 4 4
      toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon
  41. 1 1
      toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon
  42. 1 1
      toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon
  43. 64 64
      toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon
  44. 1 1
      toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon
  45. 1 1
      toolchain/check/testdata/builtins/float/negate.carbon
  46. 1 1
      toolchain/check/testdata/builtins/int/snegate.carbon
  47. 1 1
      toolchain/check/testdata/builtins/int/unegate.carbon
  48. 10 10
      toolchain/check/testdata/builtins/read/char.carbon
  49. 8 8
      toolchain/check/testdata/builtins/type/and.carbon
  50. 8 8
      toolchain/check/testdata/class/access_modifers.carbon
  51. 9 9
      toolchain/check/testdata/class/adapter/convert_incomplete.carbon
  52. 51 51
      toolchain/check/testdata/class/derived_to_base.carbon
  53. 18 18
      toolchain/check/testdata/class/destroy_calls.carbon
  54. 36 40
      toolchain/check/testdata/class/fail_abstract.carbon
  55. 6 6
      toolchain/check/testdata/class/fail_abstract_in_struct.carbon
  56. 47 47
      toolchain/check/testdata/class/fail_abstract_in_tuple.carbon
  57. 5 5
      toolchain/check/testdata/class/fail_error_recovery.carbon
  58. 10 10
      toolchain/check/testdata/class/fail_generic_method.carbon
  59. 4 4
      toolchain/check/testdata/class/fail_incomplete.carbon
  60. 9 9
      toolchain/check/testdata/class/fail_modifiers.carbon
  61. 4 4
      toolchain/check/testdata/class/fail_self.carbon
  62. 14 14
      toolchain/check/testdata/class/field_access.carbon
  63. 14 14
      toolchain/check/testdata/class/field_access_in_value.carbon
  64. 22 22
      toolchain/check/testdata/class/generic/base_is_generic.carbon
  65. 10 10
      toolchain/check/testdata/class/generic/complete_in_conversion.carbon
  66. 8 8
      toolchain/check/testdata/class/generic/import.carbon
  67. 40 40
      toolchain/check/testdata/class/generic/member_out_of_line.carbon
  68. 28 28
      toolchain/check/testdata/class/generic/self.carbon
  69. 6 6
      toolchain/check/testdata/class/generic_method.carbon
  70. 9 9
      toolchain/check/testdata/class/import.carbon
  71. 9 9
      toolchain/check/testdata/class/import_access.carbon
  72. 1 1
      toolchain/check/testdata/class/import_member_cycle.carbon
  73. 6 6
      toolchain/check/testdata/class/nested.carbon
  74. 1 1
      toolchain/check/testdata/class/nested_name.carbon
  75. 12 12
      toolchain/check/testdata/class/raw_self_type.carbon
  76. 4 4
      toolchain/check/testdata/class/redeclaration.carbon
  77. 40 40
      toolchain/check/testdata/class/reorder_qualified.carbon
  78. 2 2
      toolchain/check/testdata/class/scope.carbon
  79. 275 275
      toolchain/check/testdata/class/virtual_modifiers.carbon
  80. 2 2
      toolchain/check/testdata/const/basics.carbon
  81. 199 38
      toolchain/check/testdata/dataflow/unused.carbon
  82. 115 115
      toolchain/check/testdata/deduce/array.carbon
  83. 39 39
      toolchain/check/testdata/deduce/binding_pattern.carbon
  84. 21 21
      toolchain/check/testdata/deduce/generic_type.carbon
  85. 36 36
      toolchain/check/testdata/deduce/int_float.carbon
  86. 7 7
      toolchain/check/testdata/deduce/symbolic_facets.carbon
  87. 27 27
      toolchain/check/testdata/deduce/tuple.carbon
  88. 106 106
      toolchain/check/testdata/deduce/value_with_type_through_access.carbon
  89. 4 4
      toolchain/check/testdata/deduce/where.carbon
  90. 51 51
      toolchain/check/testdata/eval/aggregates.carbon
  91. 11 11
      toolchain/check/testdata/eval/call.carbon
  92. 2 2
      toolchain/check/testdata/eval/symbolic.carbon
  93. 8 8
      toolchain/check/testdata/facet/access.carbon
  94. 17 17
      toolchain/check/testdata/facet/combine.carbon
  95. 6 6
      toolchain/check/testdata/facet/convert_class_type_to_facet_type.carbon
  96. 53 45
      toolchain/check/testdata/facet/convert_class_type_to_generic_facet_value.carbon
  97. 3 3
      toolchain/check/testdata/facet/convert_class_value_to_facet_value_value.carbon
  98. 31 31
      toolchain/check/testdata/facet/convert_class_value_to_generic_facet_value_value.carbon
  99. 12 15
      toolchain/check/testdata/facet/convert_facet_type_to_facet_value.carbon
  100. 2 2
      toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon

+ 1 - 1
core/prelude/iterate.carbon

@@ -20,7 +20,7 @@ interface Iterate {
 impl forall [T:! Copy & Destroy, N:! IntLiteral()]
     array(T, N) as Iterate
     where .ElementType = T and .CursorType = i32 {
-  fn NewCursor[self: Self]() -> i32 { return 0; }
+  fn NewCursor[unused self: Self]() -> i32 { return 0; }
   fn Next[self: Self](cursor: i32*) -> Optional(T) {
     if (*cursor < N) {
       ++*cursor;

+ 2 - 2
core/prelude/types/cpp/nullptr.carbon

@@ -35,7 +35,7 @@ class CppCompat.NullptrT {
   }
 
   impl as Copy {
-    fn Op[self: Self]() -> Self {
+    fn Op[unused self: Self]() -> Self {
       return Make();
     }
   }
@@ -43,7 +43,7 @@ class CppCompat.NullptrT {
   // TODO: impl as EqWith(Self)
 
   impl forall [T:! type] as ImplicitAs(Optional(T*)) {
-    fn Convert[self: Self]() -> Optional(T*) {
+    fn Convert[unused self: Self]() -> Optional(T*) {
       return Optional(T*).None();
     }
   }

+ 8 - 29
toolchain/check/BUILD

@@ -66,11 +66,13 @@ cc_library(
         "pattern_match.cpp",
         "pointer_dereference.cpp",
         "return.cpp",
+        "scope_stack.cpp",
         "subst.cpp",
         "thunk.cpp",
         "type.cpp",
         "type_completion.cpp",
         "type_structure.cpp",
+        "unused.cpp",
     ],
     hdrs = [
         "action.h",
@@ -101,6 +103,7 @@ cc_library(
         "eval.h",
         "eval_inst.h",
         "facet_type.h",
+        "full_pattern_stack.h",
         "function.h",
         "generic.h",
         "global_init.h",
@@ -113,6 +116,7 @@ cc_library(
         "inst_block_stack.h",
         "interface.h",
         "keyword_modifier_set.h",
+        "lexical_lookup.h",
         "literal.h",
         "member_access.h",
         "merge.h",
@@ -129,11 +133,14 @@ cc_library(
         "pointer_dereference.h",
         "region_stack.h",
         "return.h",
+        "scope_index.h",
+        "scope_stack.h",
         "subst.h",
         "thunk.h",
         "type.h",
         "type_completion.h",
         "type_structure.h",
+        "unused.h",
     ],
     deps = [
         ":core_identifier",
@@ -146,6 +153,7 @@ cc_library(
         "//common:find",
         "//common:growing_range",
         "//common:map",
+        "//common:move_only",
         "//common:ostream",
         "//common:raw_string_ostream",
         "//common:set",
@@ -158,7 +166,6 @@ cc_library(
         "//toolchain/base:value_ids",
         "//toolchain/base:value_store",
         "//toolchain/check:generic_region_stack",
-        "//toolchain/check:scope_stack",
         "//toolchain/diagnostics:emitter",
         "//toolchain/diagnostics:format_providers",
         "//toolchain/lex:token_info",
@@ -224,7 +231,6 @@ cc_library(
         ":core_identifier",
         ":dump",
         ":emitter",
-        ":scope_stack",
         "//common:check",
         "//common:error",
         "//common:find",
@@ -301,33 +307,6 @@ cc_library(
     ],
 )
 
-cc_library(
-    name = "scope_stack",
-    srcs = ["scope_stack.cpp"],
-    hdrs = [
-        "full_pattern_stack.h",
-        "lexical_lookup.h",
-        "scope_index.h",
-        "scope_stack.h",
-    ],
-    deps = [
-        "//common:array_stack",
-        "//common:check",
-        "//common:move_only",
-        "//common:ostream",
-        "//common:set",
-        "//common:vlog",
-        "//toolchain/base:canonical_value_store",
-        "//toolchain/base:index_base",
-        "//toolchain/base:shared_value_stores",
-        "//toolchain/base:value_ids",
-        "//toolchain/base:value_store",
-        "//toolchain/sem_ir:file",
-        "//toolchain/sem_ir:typed_insts",
-        "@llvm-project//llvm:Support",
-    ],
-)
-
 cc_library(
     name = "core_identifier",
     srcs = ["core_identifier.cpp"],

+ 2 - 1
toolchain/check/check_unit.cpp

@@ -31,6 +31,7 @@
 #include "toolchain/check/node_id_traversal.h"
 #include "toolchain/check/type.h"
 #include "toolchain/check/type_structure.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/diagnostics/diagnostic.h"
 #include "toolchain/sem_ir/function.h"
 #include "toolchain/sem_ir/ids.h"
@@ -593,7 +594,7 @@ auto CheckUnit::FinishRun() -> void {
 
   // Pop information for the file-level scope.
   context_.sem_ir().set_top_inst_block_id(context_.inst_block_stack().Pop());
-  context_.scope_stack().Pop();
+  context_.scope_stack().Pop(/*check_unused=*/true);
 
   // Finalizes the list of exports on the IR.
   context_.inst_blocks().ReplacePlaceholder(SemIR::InstBlockId::Exports,

+ 1 - 1
toolchain/check/context.cpp

@@ -29,7 +29,7 @@ Context::Context(DiagnosticEmitterBase* emitter,
       param_and_arg_refs_stack_(*sem_ir, vlog_stream, node_stack_),
       args_type_info_stack_("args_type_info_stack_", *sem_ir, vlog_stream),
       decl_name_stack_(this),
-      scope_stack_(sem_ir_),
+      scope_stack_(*this),
       deferred_definition_worklist_(vlog_stream),
       generic_region_stack_(vlog_stream),
       vtable_stack_("vtable_stack_", *sem_ir, vlog_stream),

+ 4 - 2
toolchain/check/cpp/import.cpp

@@ -53,6 +53,7 @@
 #include "toolchain/check/pattern_match.h"
 #include "toolchain/check/type.h"
 #include "toolchain/check/type_completion.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/parse/node_ids.h"
 #include "toolchain/sem_ir/clang_decl.h"
 #include "toolchain/sem_ir/class.h"
@@ -1448,7 +1449,8 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
   auto function_params_insts =
       CreateFunctionSignatureInsts(context, loc_id, clang_decl, signature);
 
-  auto [pattern_block_id, decl_block_id] = FinishFunctionSignature(context);
+  auto [pattern_block_id, decl_block_id] =
+      FinishFunctionSignature(context, /*check_unused=*/false);
 
   if (!function_params_insts.has_value()) {
     return std::nullopt;
@@ -1706,7 +1708,7 @@ static auto ImportVarDecl(Context& context, SemIR::LocId loc_id,
   SemIR::EntityNameId entity_name_id =
       context.entity_names().AddSymbolicBindingName(
           var_name_id, GetParentNameScopeId(context, var_decl),
-          SemIR::CompileTimeBindIndex::None, false);
+          SemIR::CompileTimeBindIndex::None, false, /*is_unused=*/false);
 
   // Create `RefBindingPattern` and `VarPattern`. Mirror the behavior of
   // import_ref and don't create a `NameBindingDecl` here; we'd never use it for

+ 5 - 3
toolchain/check/decl_name_stack.cpp

@@ -14,6 +14,7 @@
 #include "toolchain/check/name_component.h"
 #include "toolchain/check/name_lookup.h"
 #include "toolchain/check/type_completion.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/diagnostics/diagnostic.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/name_scope.h"
@@ -86,10 +87,11 @@ auto DeclNameStack::FinishImplName() -> NameContext {
   return result;
 }
 
-auto DeclNameStack::PopScope() -> void {
+auto DeclNameStack::PopScope(bool check_unused) -> void {
   CARBON_CHECK(decl_name_stack_.back().state == NameContext::State::Finished,
                "Missing call to FinishName before PopScope");
-  context_->scope_stack().PopTo(decl_name_stack_.back().initial_scope_index);
+  context_->scope_stack().PopTo(decl_name_stack_.back().initial_scope_index,
+                                check_unused);
   decl_name_stack_.pop_back();
 }
 
@@ -248,7 +250,7 @@ static auto PushNameQualifierScope(Context& context, SemIR::LocId loc_id,
     -> SemIR::NameScopeId {
   // If the qualifier has no parameters, we don't need to keep around a
   // parameter scope.
-  context.scope_stack().PopIfEmpty();
+  context.scope_stack().PopIfEmpty(/*check_unused=*/true);
 
   auto self_specific_id = SemIR::SpecificId::None;
   if (generic_id.has_value()) {

+ 3 - 1
toolchain/check/decl_name_stack.h

@@ -217,7 +217,9 @@ class DeclNameStack {
   // the `A.B` in `fn A.B.F()`.
   //
   // This should be called at the end of the declaration.
-  auto PopScope() -> void;
+  // If check_unused is true, then performs unused bindings checks and emits
+  // associated diagnostics.
+  auto PopScope(bool check_unused = false) -> void;
 
   // Peeks the current parent scope of the name on top of the stack. Note
   // that if we're still processing the name qualifiers, this can change before

+ 5 - 8
toolchain/check/facet_type.cpp

@@ -4,13 +4,9 @@
 
 #include "toolchain/check/facet_type.h"
 
-#include <compare>
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
 #include "toolchain/base/kind_switch.h"
-#include "toolchain/check/convert.h"
-#include "toolchain/check/diagnostic_helpers.h"
+#include "toolchain/check/context.h"
+#include "toolchain/check/control_flow.h"
 #include "toolchain/check/generic.h"
 #include "toolchain/check/import_ref.h"
 #include "toolchain/check/inst.h"
@@ -418,8 +414,9 @@ auto MakePeriodSelfFacetValue(Context& context, SemIR::TypeId self_type_id)
                    // `None` because there is no equivalent non-symbolic value.
                    .value_id = SemIR::InstId::None,
                }));
-  auto existing =
-      context.scope_stack().LookupOrAddName(SemIR::NameId::PeriodSelf, inst_id);
+  auto existing = context.scope_stack().LookupOrAddName(
+      SemIR::NameId::PeriodSelf, inst_id, ScopeIndex::None,
+      IsCurrentPositionReachable(context));
   // Shouldn't have any names in newly created scope.
   CARBON_CHECK(!existing.has_value());
   return inst_id;

+ 5 - 4
toolchain/check/function.cpp

@@ -153,7 +153,8 @@ auto MakeBuiltinFunction(Context& context, SemIR::LocId loc_id,
                          return_patterns_id);
 
   context.full_pattern_stack().PopFullPattern();
-  auto [pattern_block_id, decl_block_id] = FinishFunctionSignature(context);
+  auto [pattern_block_id, decl_block_id] =
+      FinishFunctionSignature(context, /*check_unused=*/false);
 
   // Add the function declaration.
   // TODO: This should probably handle generics.
@@ -409,11 +410,11 @@ auto StartFunctionSignature(Context& context) -> void {
   context.pattern_block_stack().Push();
 }
 
-auto FinishFunctionSignature(Context& context)
+auto FinishFunctionSignature(Context& context, bool check_unused)
     -> FinishFunctionSignatureResult {
   auto pattern_block_id = context.pattern_block_stack().Pop();
   auto decl_block_id = context.inst_block_stack().Pop();
-  context.scope_stack().Pop();
+  context.scope_stack().Pop(check_unused);
   return {.pattern_block_id = pattern_block_id, .decl_block_id = decl_block_id};
 }
 
@@ -461,7 +462,7 @@ auto StartFunctionDefinition(Context& context, SemIR::InstId decl_id,
 auto FinishFunctionDefinition(Context& context, SemIR::FunctionId function_id)
     -> void {
   context.inst_block_stack().Pop();
-  context.scope_stack().Pop();
+  context.scope_stack().Pop(/*check_unused=*/true);
 
   auto& function = context.functions().Get(function_id);
   function.body_block_ids = context.region_stack().PopRegion();

+ 2 - 1
toolchain/check/function.h

@@ -112,7 +112,8 @@ struct FinishFunctionSignatureResult {
 };
 
 // Finishes signatures started by `StartFunctionSignature`.
-auto FinishFunctionSignature(Context& context) -> FinishFunctionSignatureResult;
+auto FinishFunctionSignature(Context& context, bool check_unused = true)
+    -> FinishFunctionSignatureResult;
 
 // Creates a function object for the given function declaration. The caller must
 // add the returned `decl_id` to a block (typically the current block or

+ 72 - 7
toolchain/check/handle_binding_pattern.cpp

@@ -2,6 +2,9 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+#include <utility>
+
+#include "toolchain/base/kind_switch.h"
 #include "toolchain/check/context.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/facet_type.h"
@@ -13,6 +16,7 @@
 #include "toolchain/check/return.h"
 #include "toolchain/check/type.h"
 #include "toolchain/check/type_completion.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/diagnostics/format_providers.h"
 #include "toolchain/parse/node_ids.h"
 #include "toolchain/sem_ir/ids.h"
@@ -102,7 +106,8 @@ static auto IsValidParamForIntroducer(Context& context, Parse::NodeId node_id,
 
 // TODO: make this function shorter by factoring pieces out.
 static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
-                                    Parse::NodeKind node_kind) -> bool {
+                                    Parse::NodeKind node_kind,
+                                    bool is_unused = false) -> bool {
   // TODO: split this into smaller, more focused functions.
   auto [type_node, parsed_type_id] = context.node_stack().PopExprWithNodeId();
   auto [cast_type_inst_id, cast_type_id] =
@@ -134,9 +139,9 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
   auto make_binding_pattern = [&]() -> SemIR::InstId {
     // TODO: Eventually the name will need to support associations with other
     // scopes, but right now we don't support qualified names here.
-    auto binding =
-        AddBindingPattern(context, name_node, name_id, cast_type_id,
-                          type_expr_region_id, pattern_inst_kind, is_template);
+    auto binding = AddBindingPattern(context, name_node, name_id, cast_type_id,
+                                     type_expr_region_id, pattern_inst_kind,
+                                     is_template, is_unused);
 
     // TODO: If `is_generic`, then `binding.bind_id is a SymbolicBinding. Subst
     // the `.Self` of type `type` in the `cast_type_id` type (a `FacetType`)
@@ -279,7 +284,7 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
                              .bind_name_id;
           RegisterReturnedVar(context,
                               introducer.modifier_node_id(ModifierOrder::Decl),
-                              type_node, cast_type_id, bind_id);
+                              type_node, cast_type_id, bind_id, name_id);
         }
       }
       context.node_stack().Push(node_id, binding_pattern_id);
@@ -328,7 +333,7 @@ auto HandleParseNode(Context& context,
                      Parse::CompileTimeBindingPatternId node_id) -> bool {
   // Pop the `.Self` facet value name introduced by the
   // CompileTimeBindingPatternStart.
-  context.scope_stack().Pop();
+  context.scope_stack().Pop(/*check_unused=*/true);
 
   auto node_kind = Parse::NodeKind::CompileTimeBindingPattern;
   const DeclIntroducerState& introducer =
@@ -449,8 +454,68 @@ auto HandleParseNode(Context& context, Parse::TemplateBindingNameId node_id)
   return true;
 }
 
+// Within a pattern with an unused modifier, sets the is_unused on all
+// entity names and also returns whether any names were found. The result
+// is needed to emit a diagnostic when the unused modifier is
+// unnecessary.
+static auto MarkPatternUnused(Context& context, SemIR::InstId inst_id) -> bool {
+  bool found_name = false;
+  llvm::SmallVector<SemIR::InstId> worklist;
+  worklist.push_back(inst_id);
+  while (!worklist.empty()) {
+    auto current_inst_id = worklist.pop_back_val();
+    auto inst = context.insts().Get(current_inst_id);
+    CARBON_KIND_SWITCH(inst) {
+      case SemIR::OutParamPattern::Kind:
+      case SemIR::RefParamPattern::Kind:
+      case SemIR::ValueParamPattern::Kind:
+      case SemIR::VarParamPattern::Kind: {
+        auto param = inst.As<SemIR::AnyParamPattern>();
+        worklist.push_back(param.subpattern_id);
+        break;
+      }
+      case SemIR::RefBindingPattern::Kind:
+      case SemIR::SymbolicBindingPattern::Kind:
+      case SemIR::ValueBindingPattern::Kind: {
+        auto bind = inst.As<SemIR::AnyBindingPattern>();
+        auto& name = context.entity_names().Get(bind.entity_name_id);
+        name.is_unused = true;
+        // We treat `_` as not marking the pattern as unused for the purpose of
+        // deciding whether to issue a warning for `unused` on a pattern that
+        // doesn't contain any bindings. `_` is implicitly unused, so marking it
+        // `unused` is redundant but harmless.
+        if (name.name_id != SemIR::NameId::Underscore) {
+          found_name = true;
+        }
+        break;
+      }
+      case CARBON_KIND(SemIR::TuplePattern tuple): {
+        for (auto elem_id : context.inst_blocks().Get(tuple.elements_id)) {
+          worklist.push_back(elem_id);
+        }
+        break;
+      }
+      case CARBON_KIND(SemIR::VarPattern var): {
+        worklist.push_back(var.subpattern_id);
+        break;
+      }
+      default:
+        break;
+    }
+  }
+  return found_name;
+}
+
 auto HandleParseNode(Context& context, Parse::UnusedPatternId node_id) -> bool {
-  return context.TODO(node_id, "unused");
+  auto [child_node, child_inst_id] =
+      context.node_stack().PopPatternWithNodeId();
+  if (!MarkPatternUnused(context, child_inst_id)) {
+    CARBON_DIAGNOSTIC(UnusedPatternNoBindings, Warning,
+                      "`unused` modifier on pattern without bindings");
+    context.emitter().Emit(node_id, UnusedPatternNoBindings);
+  }
+  context.node_stack().Push(node_id, child_inst_id);
+  return true;
 }
 
 }  // namespace Carbon::Check

+ 2 - 1
toolchain/check/handle_choice.cpp

@@ -12,6 +12,7 @@
 #include "toolchain/check/literal.h"
 #include "toolchain/check/name_component.h"
 #include "toolchain/check/type.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/diagnostics/diagnostic.h"
 #include "toolchain/lex/token_kind.h"
 #include "toolchain/sem_ir/ids.h"
@@ -307,7 +308,7 @@ auto HandleParseNode(Context& context, Parse::ChoiceDefinitionId node_id)
   // The scopes and blocks for the choice itself.
   context.inst_block_stack().Pop();
   context.decl_introducer_state_stack().Pop<Lex::TokenKind::Choice>();
-  context.scope_stack().Pop();
+  context.scope_stack().Pop(/*check_unused=*/true);
   context.decl_name_stack().PopScope();
 
   FinishGenericDefinition(context, class_info.generic_id);

+ 2 - 1
toolchain/check/handle_codeblock.cpp

@@ -4,6 +4,7 @@
 
 #include "toolchain/check/context.h"
 #include "toolchain/check/handle.h"
+#include "toolchain/check/unused.h"
 
 namespace Carbon::Check {
 
@@ -15,7 +16,7 @@ auto HandleParseNode(Context& context, Parse::CodeBlockStartId node_id)
 }
 
 auto HandleParseNode(Context& context, Parse::CodeBlockId /*node_id*/) -> bool {
-  context.scope_stack().Pop();
+  context.scope_stack().Pop(/*check_unused=*/true);
   context.node_stack()
       .PopAndDiscardSoloNodeId<Parse::NodeKind::CodeBlockStart>();
   return true;

+ 69 - 7
toolchain/check/handle_function.cpp

@@ -10,22 +10,19 @@
 #include "toolchain/check/control_flow.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/decl_introducer_state.h"
-#include "toolchain/check/decl_name_stack.h"
-#include "toolchain/check/function.h"
 #include "toolchain/check/generic.h"
 #include "toolchain/check/handle.h"
-#include "toolchain/check/import.h"
 #include "toolchain/check/import_ref.h"
-#include "toolchain/check/inst.h"
 #include "toolchain/check/interface.h"
-#include "toolchain/check/keyword_modifier_set.h"
 #include "toolchain/check/literal.h"
 #include "toolchain/check/merge.h"
 #include "toolchain/check/modifiers.h"
 #include "toolchain/check/name_component.h"
 #include "toolchain/check/name_lookup.h"
+#include "toolchain/check/return.h"
 #include "toolchain/check/type.h"
 #include "toolchain/check/type_completion.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/lex/token_kind.h"
 #include "toolchain/parse/node_ids.h"
 #include "toolchain/sem_ir/builtin_function_kind.h"
@@ -607,8 +604,73 @@ static auto BuildFunctionDecl(Context& context,
   return {function_decl.function_id, decl_id};
 }
 
+// Checks that "unused" marker is only used in definitions, and emits a
+// diagnostic for every binding that is marked unused.
+static auto CheckUnusedBindingsInPattern(Context& context,
+                                         SemIR::InstId pattern_id) -> void {
+  llvm::SmallVector<SemIR::InstId> work_list;
+  work_list.push_back(pattern_id);
+
+  while (!work_list.empty()) {
+    auto current_id = work_list.pop_back_val();
+    auto inst = context.insts().Get(current_id);
+    CARBON_KIND_SWITCH(inst) {
+      case SemIR::OutParamPattern::Kind:
+      case SemIR::RefParamPattern::Kind:
+      case SemIR::ValueParamPattern::Kind:
+      case SemIR::VarParamPattern::Kind: {
+        auto param = inst.As<SemIR::AnyParamPattern>();
+        work_list.push_back(param.subpattern_id);
+        break;
+      }
+      case SemIR::RefBindingPattern::Kind:
+      case SemIR::SymbolicBindingPattern::Kind:
+      case SemIR::ValueBindingPattern::Kind: {
+        auto bind = inst.As<SemIR::AnyBindingPattern>();
+        auto& entity_name = context.entity_names().Get(bind.entity_name_id);
+        // We need special treatment for the name "_" which is implicitly
+        // unused but actually permitted in declarations.
+        if (entity_name.is_unused &&
+            entity_name.name_id != SemIR::NameId::Underscore) {
+          CARBON_DIAGNOSTIC(UnusedModifierOnDeclaration, Error,
+                            "`unused` modifier on declaration");
+          context.emitter().Emit(current_id, UnusedModifierOnDeclaration);
+        }
+        break;
+      }
+      case CARBON_KIND(SemIR::VarPattern var_pattern): {
+        work_list.push_back(var_pattern.subpattern_id);
+        break;
+      }
+      case CARBON_KIND(SemIR::TuplePattern tuple_pattern): {
+        auto elements = context.inst_blocks().Get(tuple_pattern.elements_id);
+        for (auto element_id : llvm::reverse(elements)) {
+          work_list.push_back(element_id);
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
+}
+
+static auto DiagnoseUnusedMarkersInDeclaration(Context& context,
+                                               SemIR::FunctionId function_id)
+    -> void {
+  const auto& function = context.functions().Get(function_id);
+  if (function.param_patterns_id.has_value()) {
+    for (auto pattern_id :
+         context.inst_blocks().Get(function.param_patterns_id)) {
+      CheckUnusedBindingsInPattern(context, pattern_id);
+    }
+  }
+}
+
 auto HandleParseNode(Context& context, Parse::FunctionDeclId node_id) -> bool {
-  BuildFunctionDecl(context, node_id, /*is_definition=*/false);
+  auto [function_id, decl_id] =
+      BuildFunctionDecl(context, node_id, /*is_definition=*/false);
+  DiagnoseUnusedMarkersInDeclaration(context, function_id);
   context.decl_name_stack().PopScope();
   return true;
 }
@@ -672,7 +734,7 @@ auto HandleParseNode(Context& context, Parse::FunctionDefinitionId node_id)
   }
 
   FinishFunctionDefinition(context, function_id);
-  context.decl_name_stack().PopScope();
+  context.decl_name_stack().PopScope(/*check_unused=*/true);
 
   return true;
 }

+ 3 - 2
toolchain/check/handle_struct.cpp

@@ -8,6 +8,7 @@
 #include "toolchain/check/handle.h"
 #include "toolchain/check/inst.h"
 #include "toolchain/check/type.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/diagnostics/format_providers.h"
 
 namespace Carbon::Check {
@@ -137,7 +138,7 @@ auto HandleParseNode(Context& context, Parse::StructLiteralId node_id) -> bool {
   auto elements_id = context.param_and_arg_refs_stack().EndAndPop(
       Parse::NodeKind::StructLiteralStart);
 
-  context.scope_stack().Pop();
+  context.scope_stack().Pop(/*check_unused=*/true);
   context.node_stack()
       .PopAndDiscardSoloNodeId<Parse::NodeKind::StructLiteralStart>();
 
@@ -163,7 +164,7 @@ auto HandleParseNode(Context& context, Parse::StructTypeLiteralId node_id)
   llvm::SmallVector<Parse::NodeId> field_name_nodes =
       PopFieldNameNodes(context, fields.size());
 
-  context.scope_stack().Pop();
+  context.scope_stack().Pop(/*check_unused=*/true);
   context.node_stack()
       .PopAndDiscardSoloNodeId<Parse::NodeKind::StructTypeLiteralStart>();
 

+ 2 - 1
toolchain/check/handle_where.cpp

@@ -9,6 +9,7 @@
 #include "toolchain/check/handle.h"
 #include "toolchain/check/inst.h"
 #include "toolchain/check/type.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/sem_ir/facet_type_info.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/inst.h"
@@ -188,7 +189,7 @@ auto HandleParseNode(Context& context, Parse::WhereExprId node_id) -> bool {
   context.rewrites_stack().pop_back();
   // Remove `PeriodSelf` from name lookup, undoing the `Push` done for the
   // `WhereOperand`.
-  context.scope_stack().Pop();
+  context.scope_stack().Pop(/*check_unused=*/true);
   SemIR::InstId period_self_id =
       context.node_stack().Pop<Parse::NodeKind::WhereOperand>();
   SemIR::InstBlockId requirements_id = context.args_type_info_stack().Pop();

+ 1 - 1
toolchain/check/import_ref.cpp

@@ -644,7 +644,7 @@ static auto GetLocalSymbolicEntityNameId(
   auto name_id = GetLocalNameId(context, import_entity_name.name_id);
   return context.local_entity_names().AddSymbolicBindingName(
       name_id, SemIR::NameScopeId::None, import_entity_name.bind_index(),
-      import_entity_name.is_template);
+      import_entity_name.is_template, import_entity_name.is_unused);
 }
 
 // Gets the local constant values corresponding to an imported inst block.

+ 2 - 1
toolchain/check/interface.cpp

@@ -139,7 +139,8 @@ auto AddSelfSymbolicBindingToScope(Context& context,
                                    bool is_template) -> SemIR::InstId {
   auto entity_name_id = context.entity_names().AddSymbolicBindingName(
       SemIR::NameId::SelfType, scope_id,
-      context.scope_stack().AddCompileTimeBinding(), is_template);
+      context.scope_stack().AddCompileTimeBinding(), is_template,
+      /*is_unused=*/false);
   // Because there is no equivalent non-symbolic value, we use `None` as
   // the `value_id` on the `SymbolicBinding`.
   auto self_param_inst_id =

+ 16 - 3
toolchain/check/lexical_lookup.h

@@ -29,6 +29,10 @@ class LexicalLookup {
     SemIR::InstId inst_id;
     // The scope in which the instruction was added.
     ScopeIndex scope_index;
+    // Whether the name was declared in a reachable position.
+    bool is_decl_reachable = true;
+    // The location of the first use of the name, if any.
+    SemIR::LocId use_loc_id = SemIR::LocId::None;
   };
 
   // A lookup result that has been temporarily removed from scope.
@@ -38,6 +42,10 @@ class LexicalLookup {
     uint32_t index;
     // The lookup result.
     SemIR::InstId inst_id;
+    // Whether the name was declared in a reachable position.
+    bool is_decl_reachable;
+    // The location of the first use of the name, if any.
+    SemIR::LocId use_loc_id;
   };
 
   explicit LexicalLookup(const SharedValueStores::IdentifierStore& identifiers)
@@ -65,14 +73,19 @@ class LexicalLookup {
                  name_id);
     CARBON_CHECK(index <= std::numeric_limits<uint32_t>::max(),
                  "Unexpectedly large index {0} for name ID", index);
+    auto result = results.pop_back_val();
     return {.index = static_cast<uint32_t>(index),
-            .inst_id = results.pop_back_val().inst_id};
+            .inst_id = result.inst_id,
+            .is_decl_reachable = result.is_decl_reachable,
+            .use_loc_id = result.use_loc_id};
   }
 
   // Restore a previously-suspended lookup result.
   auto Restore(SuspendedResult sus, ScopeIndex index) -> void {
-    lookup_[sus.index].push_back(
-        {.inst_id = sus.inst_id, .scope_index = index});
+    lookup_[sus.index].push_back({.inst_id = sus.inst_id,
+                                  .scope_index = index,
+                                  .is_decl_reachable = sus.is_decl_reachable,
+                                  .use_loc_id = sus.use_loc_id});
   }
 
  private:

+ 13 - 2
toolchain/check/merge.cpp

@@ -450,12 +450,23 @@ static auto CheckRedeclParamSyntax(Context& context,
   for (; new_iter != new_end && prev_iter != prev_end;
        ++new_iter, ++prev_iter) {
     auto new_node_id = *new_iter;
+    auto new_node_kind = context.parse_tree().node_kind(new_node_id);
+    // Skip over "unused" markers.
+    if (new_node_kind == Parse::NodeKind::UnusedPattern) {
+      ++new_iter;
+      new_node_id = *new_iter;
+      new_node_kind = context.parse_tree().node_kind(new_node_id);
+    }
     auto prev_node_id = *prev_iter;
+    auto prev_node_kind = context.parse_tree().node_kind(prev_node_id);
+    if (prev_node_kind == Parse::NodeKind::UnusedPattern) {
+      ++prev_iter;
+      prev_node_id = *prev_iter;
+      prev_node_kind = context.parse_tree().node_kind(prev_node_id);
+    }
     if (!IsNodeSyntaxEqual(context, new_node_id, prev_node_id)) {
       // Skip difference if it is `Self as` vs. `as` in an `impl` declaration.
       // https://github.com/carbon-language/carbon-lang/blob/trunk/proposals/p3763.md#redeclarations
-      auto new_node_kind = context.parse_tree().node_kind(new_node_id);
-      auto prev_node_kind = context.parse_tree().node_kind(prev_node_id);
       if (new_node_kind == Parse::NodeKind::ImplDefaultSelfAs &&
           prev_node_kind == Parse::NodeKind::SelfTypeNameExpr &&
           context.parse_tree().node_kind(prev_iter[1]) ==

+ 10 - 6
toolchain/check/name_lookup.cpp

@@ -7,6 +7,7 @@
 #include <optional>
 
 #include "common/raw_string_ostream.h"
+#include "toolchain/check/control_flow.h"
 #include "toolchain/check/cpp/import.h"
 #include "toolchain/check/facet_type.h"
 #include "toolchain/check/generic.h"
@@ -26,8 +27,8 @@ namespace Carbon::Check {
 
 auto AddNameToLookup(Context& context, SemIR::NameId name_id,
                      SemIR::InstId target_id, ScopeIndex scope_index) -> void {
-  if (auto existing = context.scope_stack().LookupOrAddName(name_id, target_id,
-                                                            scope_index);
+  if (auto existing = context.scope_stack().LookupOrAddName(
+          name_id, target_id, scope_index, IsCurrentPositionReachable(context));
       existing.has_value()) {
     // TODO: Add coverage to this use case and use the location of the name
     // instead of the target.
@@ -72,10 +73,12 @@ auto LookupNameInDecl(Context& context, SemIR::LocId loc_id,
     //      class C(C:! type);
     //    }
     //
-    //    In this case, the class C is not a redeclaration of its parameter, but
-    //    we find the parameter in order to diagnose a redeclaration error.
+    // In this case, the class C is not a redeclaration of its parameter, but
+    // we find the parameter in order to diagnose a redeclaration error.
     return SemIR::ScopeLookupResult::MakeWrappedLookupResult(
-        context.scope_stack().LookupInLexicalScopesWithin(name_id, scope_index),
+        context.scope_stack().LookupInLexicalScopesWithin(
+            name_id, scope_index, /*use_loc_id=*/SemIR::LocId::None,
+            /*is_reachable=*/true),
         SemIR::AccessKind::Public);
   } else {
     // We do not look into `extend`ed scopes here. A qualified name in a
@@ -101,7 +104,8 @@ auto LookupUnqualifiedName(Context& context, SemIR::LocId loc_id,
   // Find the results from ancestor lexical scopes. These will be combined with
   // results from non-lexical scopes such as namespaces and classes.
   auto [lexical_result, non_lexical_scopes] =
-      context.scope_stack().LookupInLexicalScopes(name_id);
+      context.scope_stack().LookupInLexicalScopes(
+          name_id, loc_id, IsCurrentPositionReachable(context));
 
   // Walk the non-lexical scopes and perform lookups into each of them.
   for (auto [index, lookup_scope_id, specific_id] :

+ 4 - 4
toolchain/check/pattern.cpp

@@ -49,8 +49,8 @@ auto EndSubpatternAsNonExpr(Context& context) -> void {
 auto AddBindingPattern(Context& context, SemIR::LocId name_loc,
                        SemIR::NameId name_id, SemIR::TypeId type_id,
                        SemIR::ExprRegionId type_region_id,
-                       SemIR::InstKind pattern_kind, bool is_template)
-    -> BindingPatternInfo {
+                       SemIR::InstKind pattern_kind, bool is_template,
+                       bool is_unused) -> BindingPatternInfo {
   SemIR::InstKind bind_name_kind;
   switch (pattern_kind) {
     case SemIR::InstKind::RefBindingPattern:
@@ -71,7 +71,7 @@ auto AddBindingPattern(Context& context, SemIR::LocId name_loc,
       name_id, context.scope_stack().PeekNameScopeId(),
       is_generic ? context.scope_stack().AddCompileTimeBinding()
                  : SemIR::CompileTimeBindIndex::None,
-      is_template);
+      is_template, is_unused || name_id == SemIR::NameId::Underscore);
 
   auto bind_id = AddInstInNoBlock(
       context,
@@ -147,7 +147,7 @@ auto AddParamPattern(Context& context, SemIR::LocId loc_id,
   SemIR::InstId pattern_id =
       AddBindingPattern(context, loc_id, name_id, type_id, type_expr_region_id,
                         binding_pattern_kind,
-                        /*is_template=*/false)
+                        /*is_template=*/false, /*is_unused=*/false)
           .pattern_id;
 
   const auto& param_pattern_kind =

+ 5 - 2
toolchain/check/pattern.h

@@ -37,13 +37,16 @@ struct BindingPatternInfo {
 
 // Creates a binding pattern. Returns the binding pattern and the bind name
 // instruction.
+// - `pattern_kind` specifies the kind of instruction to create.
+// - `is_template` indicates whether this is a template binding.
+// - `is_unused` indicates whether the binding was explicitly marked `unused`.
 // TODO: remove is_template once we have a separate InstKind for template
 // bindings.
 auto AddBindingPattern(Context& context, SemIR::LocId name_loc,
                        SemIR::NameId name_id, SemIR::TypeId type_id,
                        SemIR::ExprRegionId type_region_id,
-                       SemIR::InstKind pattern_kind, bool is_template)
-    -> BindingPatternInfo;
+                       SemIR::InstKind pattern_kind, bool is_template,
+                       bool is_unused) -> BindingPatternInfo;
 
 // Creates storage for `var` patterns nested within the given pattern at the
 // current location in the output SemIR. For a `returned var`, this

+ 3 - 2
toolchain/check/return.cpp

@@ -73,7 +73,7 @@ static auto NoteReturnedVar(DiagnosticBuilder& diag,
 
 auto RegisterReturnedVar(Context& context, Parse::NodeId returned_node,
                          Parse::NodeId type_node, SemIR::TypeId type_id,
-                         SemIR::InstId bind_id) -> void {
+                         SemIR::InstId bind_id, SemIR::NameId name_id) -> void {
   auto& function = GetCurrentFunctionForReturn(context);
   auto return_type_id = function.GetDeclaredReturnType(context.sem_ir());
 
@@ -111,7 +111,8 @@ auto RegisterReturnedVar(Context& context, Parse::NodeId returned_node,
     diag.Emit();
   }
 
-  auto existing_id = context.scope_stack().SetReturnedVarOrGetExisting(bind_id);
+  auto existing_id =
+      context.scope_stack().SetReturnedVarOrGetExisting(bind_id, name_id);
   if (existing_id.has_value()) {
     CARBON_DIAGNOSTIC(ReturnedVarShadowed, Error,
                       "cannot declare a `returned var` in the scope of "

+ 1 - 1
toolchain/check/return.h

@@ -24,7 +24,7 @@ auto GetReturnedVarParam(Context& context, const SemIR::Function& function)
 // var` in this scope.
 auto RegisterReturnedVar(Context& context, Parse::NodeId returned_node,
                          Parse::NodeId type_node, SemIR::TypeId type_id,
-                         SemIR::InstId bind_id) -> void;
+                         SemIR::InstId bind_id, SemIR::NameId name_id) -> void;
 
 // Checks and builds SemIR for a `return;` statement.
 auto BuildReturnWithNoExpr(Context& context, SemIR::LocId loc_id) -> void;

+ 99 - 26
toolchain/check/scope_stack.cpp

@@ -7,10 +7,21 @@
 #include <utility>
 
 #include "common/check.h"
+#include "toolchain/check/context.h"
+#include "toolchain/check/unused.h"
 #include "toolchain/sem_ir/ids.h"
 
 namespace Carbon::Check {
 
+ScopeStack::ScopeStack(Context& context)
+    : context_(&context),
+      lexical_lookup_(context.sem_ir().identifiers()),
+      full_pattern_stack_(&lexical_lookup_) {}
+
+auto ScopeStack::sem_ir() const -> const SemIR::File& {
+  return context_->sem_ir();
+}
+
 auto ScopeStack::VerifyOnFinish() const -> void {
   CARBON_CHECK(return_scope_stack_.empty(), "{0}", return_scope_stack_.size());
   CARBON_CHECK(break_continue_stack_.empty(), "{0}",
@@ -88,7 +99,7 @@ auto ScopeStack::PushForEntity(SemIR::InstId scope_inst_id,
                                SemIR::SpecificId specific_id,
                                bool lexical_lookup_has_load_error) -> void {
   CARBON_CHECK(scope_inst_id.has_value());
-  CARBON_DCHECK(!sem_ir_->insts().Is<SemIR::FunctionDecl>(scope_inst_id));
+  CARBON_DCHECK(!sem_ir().insts().Is<SemIR::FunctionDecl>(scope_inst_id));
   Push(scope_inst_id, scope_id, specific_id, lexical_lookup_has_load_error);
   MarkNestingIfInReturnScope();
 }
@@ -99,7 +110,7 @@ auto ScopeStack::PushForSameRegion() -> void {
 }
 
 auto ScopeStack::PushForFunctionBody(SemIR::InstId scope_inst_id) -> void {
-  CARBON_DCHECK(sem_ir_->insts().Is<SemIR::FunctionDecl>(scope_inst_id));
+  CARBON_DCHECK(sem_ir().insts().Is<SemIR::FunctionDecl>(scope_inst_id));
   Push(scope_inst_id, SemIR::NameScopeId::None, SemIR::SpecificId::None,
        /*lexical_lookup_has_load_error=*/false);
 
@@ -107,13 +118,18 @@ auto ScopeStack::PushForFunctionBody(SemIR::InstId scope_inst_id) -> void {
   destroy_id_stack_.PushArray();
 }
 
-auto ScopeStack::Pop() -> void {
+auto ScopeStack::Pop(bool check_unused) -> void {
   auto scope = scope_stack_.pop_back_val();
 
-  scope.names.ForEach([&](SemIR::NameId str_id) {
-    auto& lexical_results = lexical_lookup_.Get(str_id);
+  // TODO: Multiple diagnostics on same line has non-deterministic order.
+  // Add second sort key in diagnostics sorting.
+  scope.names.ForEach([&, check_unused](SemIR::NameId name_id) {
+    auto& lexical_results = lexical_lookup_.Get(name_id);
     CARBON_CHECK(lexical_results.back().scope_index == scope.index,
-                 "Inconsistent scope index for name {0}", str_id);
+                 "Inconsistent scope index for name {0}", name_id);
+    if (check_unused) {
+      CheckUnusedBinding(*context_, name_id, lexical_results.back());
+    }
     lexical_results.pop_back();
   });
 
@@ -144,19 +160,52 @@ auto ScopeStack::Pop() -> void {
   compile_time_binding_stack_.PopArray();
 }
 
-auto ScopeStack::PopTo(ScopeIndex index) -> void {
+auto ScopeStack::PopTo(ScopeIndex index, bool check_unused) -> void {
   while (PeekIndex() > index) {
-    Pop();
+    Pop(check_unused);
   }
   CARBON_CHECK(PeekIndex() == index,
                "Scope index {0} does not enclose the current scope {1}", index,
                PeekIndex());
 }
 
+auto ScopeStack::MarkUsed(SemIR::NameId name_id, SemIR::LocId loc_id,
+                          bool is_reachable) -> void {
+  auto& lexical_results = lexical_lookup_.Get(name_id);
+  if (lexical_results.empty()) {
+    return;
+  }
+  auto& result = lexical_results.back();
+  if (result.use_loc_id.has_value()) {
+    return;
+  }
+
+  // Determine if we should set use_loc_id.
+  if (result.inst_id.has_value() &&
+      result.inst_id != SemIR::InstId::InitTombstone) {
+    if (auto binding =
+            context_->insts().TryGetAs<SemIR::AnyBinding>(result.inst_id)) {
+      const auto& entity_name =
+          context_->entity_names().Get(binding->entity_name_id);
+      if (entity_name.is_unused && !is_reachable) {
+        return;
+      }
+    }
+  }
+  // For non-bindings (like namespaces), we just mark them as used.
+  // If the instruction is not valid (e.g. InitTombstone), we mark it as used
+  // to avoid spurious "unused" warnings, assuming the invalid state will be
+  // diagnosed elsewhere (e.g. used before init).
+  result.use_loc_id = loc_id;
+}
+
 auto ScopeStack::LookupInLexicalScopesWithin(SemIR::NameId name_id,
-                                             ScopeIndex scope_index)
+                                             ScopeIndex scope_index,
+                                             SemIR::LocId use_loc_id,
+                                             bool is_reachable)
     -> SemIR::InstId {
-  auto& lexical_results = lexical_lookup_.Get(name_id);
+  llvm::ArrayRef<LexicalLookup::Result> lexical_results =
+      lexical_lookup_.Get(name_id);
   if (lexical_results.empty()) {
     return SemIR::InstId::None;
   }
@@ -166,10 +215,15 @@ auto ScopeStack::LookupInLexicalScopesWithin(SemIR::NameId name_id,
     return SemIR::InstId::None;
   }
 
+  if (use_loc_id.has_value()) {
+    MarkUsed(name_id, use_loc_id, is_reachable);
+  }
   return result.inst_id;
 }
 
-auto ScopeStack::LookupInLexicalScopes(SemIR::NameId name_id)
+auto ScopeStack::LookupInLexicalScopes(SemIR::NameId name_id,
+                                       SemIR::LocId use_loc_id,
+                                       bool is_reachable)
     -> std::pair<SemIR::InstId, llvm::ArrayRef<NonLexicalScope>> {
   // Find the results from lexical scopes. These will be combined with results
   // from non-lexical scopes such as namespaces and classes.
@@ -183,6 +237,9 @@ auto ScopeStack::LookupInLexicalScopes(SemIR::NameId name_id)
             non_lexical_scope_stack_};
   }
 
+  if (use_loc_id.has_value()) {
+    MarkUsed(name_id, use_loc_id, is_reachable);
+  }
   // Find the first non-lexical scope that is within the scope of the lexical
   // lookup result.
   auto* first_non_lexical_scope = llvm::lower_bound(
@@ -196,7 +253,8 @@ auto ScopeStack::LookupInLexicalScopes(SemIR::NameId name_id)
 }
 
 auto ScopeStack::LookupOrAddName(SemIR::NameId name_id, SemIR::InstId target_id,
-                                 ScopeIndex scope_index) -> SemIR::InstId {
+                                 ScopeIndex scope_index, bool is_decl_reachable)
+    -> SemIR::InstId {
   // Find the corresponding scope depth.
   //
   // TODO: Consider passing in the depth rather than performing a scan for it.
@@ -231,23 +289,29 @@ auto ScopeStack::LookupOrAddName(SemIR::NameId name_id, SemIR::InstId target_id,
   ++scope_stack_[scope_depth].num_names;
 
   // Add a corresponding lexical lookup result.
-  lexical_results.push_back({.inst_id = target_id, .scope_index = scope_index});
+  lexical_results.push_back({.inst_id = target_id,
+                             .scope_index = scope_index,
+                             .is_decl_reachable = is_decl_reachable,
+                             .use_loc_id = SemIR::LocId::None});
   return SemIR::InstId::None;
 }
 
-auto ScopeStack::SetReturnedVarOrGetExisting(SemIR::InstId inst_id)
+auto ScopeStack::SetReturnedVarOrGetExisting(SemIR::InstId inst_id,
+                                             SemIR::NameId name_id)
     -> SemIR::InstId {
   CARBON_CHECK(!return_scope_stack_.empty(), "`returned var` in no function");
-  auto& returned_var = return_scope_stack_.back().returned_var;
-  if (returned_var.has_value()) {
-    return returned_var;
+  auto& return_scope = return_scope_stack_.back();
+  if (return_scope.returned_var.has_value()) {
+    return return_scope.returned_var;
   }
 
-  returned_var = inst_id;
+  return_scope.returned_var = inst_id;
   CARBON_CHECK(!scope_stack_.back().has_returned_var,
                "Scope has returned var but none is set");
   if (inst_id.has_value()) {
     scope_stack_.back().has_returned_var = true;
+    MarkUsed(name_id, SemIR::LocId(inst_id),
+             context_->inst_block_stack().is_current_block_reachable());
   }
   return SemIR::InstId::None;
 }
@@ -264,10 +328,14 @@ auto ScopeStack::Suspend() -> SuspendedScope {
                                  peek_compile_time_bindings.size());
 
   result.entry.names.ForEach([&](SemIR::NameId name_id) {
-    auto [index, inst_id] = lexical_lookup_.Suspend(name_id);
-    CARBON_CHECK(index !=
+    auto suspended = lexical_lookup_.Suspend(name_id);
+    CARBON_CHECK(suspended.index !=
                  SuspendedScope::ScopeItem::IndexForCompileTimeBinding);
-    result.suspended_items.push_back({.index = index, .inst_id = inst_id});
+    result.suspended_items.push_back(
+        {.index = suspended.index,
+         .inst_id = suspended.inst_id,
+         .is_decl_reachable = suspended.is_decl_reachable,
+         .use_loc_id = suspended.use_loc_id});
   });
   CARBON_CHECK(static_cast<int>(result.suspended_items.size()) ==
                result.entry.num_names);
@@ -276,7 +344,9 @@ auto ScopeStack::Suspend() -> SuspendedScope {
   for (auto inst_id : peek_compile_time_bindings) {
     result.suspended_items.push_back(
         {.index = SuspendedScope::ScopeItem::IndexForCompileTimeBinding,
-         .inst_id = inst_id});
+         .inst_id = inst_id,
+         .is_decl_reachable = true,
+         .use_loc_id = SemIR::LocId::None});
   }
   compile_time_binding_stack_.PopArray();
 
@@ -288,11 +358,14 @@ auto ScopeStack::Suspend() -> SuspendedScope {
 
 auto ScopeStack::Restore(SuspendedScope&& scope) -> void {
   compile_time_binding_stack_.PushArray();
-  for (auto [index, inst_id] : scope.suspended_items) {
-    if (index == SuspendedScope::ScopeItem::IndexForCompileTimeBinding) {
-      compile_time_binding_stack_.AppendToTop(inst_id);
+  for (auto item : scope.suspended_items) {
+    if (item.index == SuspendedScope::ScopeItem::IndexForCompileTimeBinding) {
+      compile_time_binding_stack_.AppendToTop(item.inst_id);
     } else {
-      lexical_lookup_.Restore({.index = index, .inst_id = inst_id},
+      lexical_lookup_.Restore({.index = item.index,
+                               .inst_id = item.inst_id,
+                               .is_decl_reachable = item.is_decl_reachable,
+                               .use_loc_id = item.use_loc_id},
                               scope.entry.index);
     }
   }

+ 38 - 19
toolchain/check/scope_stack.h

@@ -17,14 +17,13 @@
 
 namespace Carbon::Check {
 
+class Context;
+
 // A stack of lexical and semantic scopes that we are currently performing
 // checking within.
 class ScopeStack {
  public:
-  explicit ScopeStack(const SemIR::File* sem_ir)
-      : sem_ir_(sem_ir),
-        lexical_lookup_(sem_ir->identifiers()),
-        full_pattern_stack_(&lexical_lookup_) {}
+  explicit ScopeStack(Context& context);
 
   // A scope in which `break` and `continue` can be used.
   struct BreakContinueScope {
@@ -66,17 +65,18 @@ class ScopeStack {
   auto PushForFunctionBody(SemIR::InstId scope_inst_id) -> void;
 
   // Pops the top scope from scope_stack_. Removes names from lexical_lookup_.
-  auto Pop() -> void;
+  // If `check_unused` is set, checks and emits diagnostics for unused names.
+  auto Pop(bool check_unused = false) -> void;
 
   // Pops the top scope from scope_stack_ if it contains no names.
-  auto PopIfEmpty() -> void {
+  auto PopIfEmpty(bool check_unused = false) -> void {
     if (scope_stack_.back().num_names == 0) {
-      Pop();
+      Pop(check_unused);
     }
   }
 
   // Pops scopes until we return to the specified scope index.
-  auto PopTo(ScopeIndex index) -> void;
+  auto PopTo(ScopeIndex index, bool check_unused = false) -> void;
 
   // Returns the scope index associated with the current scope.
   auto PeekIndex() const -> ScopeIndex { return Peek().index; }
@@ -111,7 +111,7 @@ class ScopeStack {
     if (!inst_id.has_value()) {
       return std::nullopt;
     }
-    return sem_ir_->insts().TryGetAs<InstT>(inst_id);
+    return sem_ir().insts().TryGetAs<InstT>(inst_id);
   }
 
   // Returns the current scope, assuming it is of the specified kind.
@@ -121,13 +121,14 @@ class ScopeStack {
   auto GetCurrentScopeAs() -> InstT {
     auto inst_id = PeekInstId();
     CARBON_CHECK(inst_id.has_value());
-    return sem_ir_->insts().GetAs<InstT>(inst_id);
+    return sem_ir().insts().GetAs<InstT>(inst_id);
   }
 
   // If there is no `returned var` in scope, sets the given instruction to be
   // the current `returned var` and returns an `None`. If there
   // is already a `returned var`, returns it instead.
-  auto SetReturnedVarOrGetExisting(SemIR::InstId inst_id) -> SemIR::InstId;
+  auto SetReturnedVarOrGetExisting(SemIR::InstId inst_id, SemIR::NameId name_id)
+      -> SemIR::InstId;
 
   // Returns the `returned var` instruction that's currently in scope, or `None`
   // if there isn't one.
@@ -144,23 +145,29 @@ class ScopeStack {
 
   // Looks up the name `name_id` in the current scope and enclosing scopes, but
   // do not look past `scope_index`. Returns the existing lookup result, if any.
+  // If `use_loc_id` is specified, the name is marked as used at that location.
   auto LookupInLexicalScopesWithin(SemIR::NameId name_id,
-                                   ScopeIndex scope_index) -> SemIR::InstId;
+                                   ScopeIndex scope_index,
+                                   SemIR::LocId use_loc_id, bool is_reachable)
+      -> SemIR::InstId;
 
   // Looks up the name `name_id` in the current scope and related lexical
   // scopes. Returns the innermost lexical lookup result, if any, along with a
   // list of non-lexical scopes in which lookup should also be performed,
-  // ordered from outermost to innermost.
-  auto LookupInLexicalScopes(SemIR::NameId name_id)
+  // ordered from outermost to innermost. If `use_loc_id` is specified, the
+  // name is marked as used at that location.
+  auto LookupInLexicalScopes(SemIR::NameId name_id, SemIR::LocId use_loc_id,
+                             bool is_reachable)
       -> std::pair<SemIR::InstId, llvm::ArrayRef<NonLexicalScope>>;
 
   // Looks up the name `name_id` in the current scope, or in `scope_index` if
   // specified. Returns the existing instruction if the name is already declared
   // in that scope or any unfinished scope within it, and otherwise adds the
-  // name with the value `target_id` and returns `None`.
+  // name with the value `target_id` and returns `None`. `is_decl_reachable`
+  // indicates whether the name was declared in a reachable position.
   auto LookupOrAddName(SemIR::NameId name_id, SemIR::InstId target_id,
-                       ScopeIndex scope_index = ScopeIndex::None)
-      -> SemIR::InstId;
+                       ScopeIndex scope_index = ScopeIndex::None,
+                       bool is_decl_reachable = true) -> SemIR::InstId;
 
   // Prepares to add a compile-time binding in the current scope, and returns
   // its index. The added binding must then be pushed using
@@ -200,6 +207,10 @@ class ScopeStack {
   auto full_pattern_stack() -> FullPatternStack& { return full_pattern_stack_; }
 
  private:
+  auto sem_ir() const -> const SemIR::File&;
+
+  auto lexical_lookup() -> LexicalLookup& { return lexical_lookup_; }
+
   // An entry in scope_stack_.
   struct ScopeStackEntry : public MoveOnly<ScopeStackEntry> {
     auto is_lexical_scope() const -> bool { return !scope_id.has_value(); }
@@ -286,6 +297,10 @@ class ScopeStack {
     }
   }
 
+  // Marks the name `name_id` as used at the given location.
+  auto MarkUsed(SemIR::NameId name_id, SemIR::LocId loc_id, bool is_reachable)
+      -> void;
+
   // Checks that the provided scope's `next_compile_time_bind_index` matches the
   // full size of the current `compile_time_binding_stack_`. The values should
   // always match, and this is used to validate the correspondence during
@@ -293,8 +308,8 @@ class ScopeStack {
   auto VerifyNextCompileTimeBindIndex(llvm::StringLiteral label,
                                       const ScopeStackEntry& scope) -> void;
 
-  // The current file.
-  const SemIR::File* sem_ir_;
+  // Context, used only for checks and emitting diagnostics.
+  Context* context_;
 
   // A stack of scopes from which we can `return`.
   llvm::SmallVector<ReturnScope> return_scope_stack_;
@@ -344,6 +359,10 @@ struct ScopeStack::SuspendedScope : public MoveOnly<SuspendedScope> {
     uint32_t index;
     // The instruction within the scope.
     SemIR::InstId inst_id;
+    // Whether the name was declared in a reachable position.
+    bool is_decl_reachable;
+    // The location of the first use of the name, if any.
+    SemIR::LocId use_loc_id;
   };
 
   // The suspended scope stack entry.

+ 51 - 51
toolchain/check/testdata/array/basics.carbon

@@ -35,7 +35,7 @@ fn F() -> (C, C, C);
 
 fn G() {
   //@dump-sem-ir-begin
-  var v: array((C, C, C), 2) = (F(), F());
+  var unused v: array((C, C, C), 2) = (F(), F());
   //@dump-sem-ir-end
 }
 
@@ -46,8 +46,8 @@ library "[[@TEST_NAME]]";
 fn G() {
   // These should have two different constant values.
   //@dump-sem-ir-begin
-  var a: array((), 3);
-  var b: ((), (), ());
+  var unused a: array((), 3);
+  var unused b: ((), (), ());
   //@dump-sem-ir-end
 }
 
@@ -59,7 +59,7 @@ fn F() -> ((),) { return ((),); }
 
 fn Run() {
   //@dump-sem-ir-begin
-  var t: array((), 1) = F();
+  var unused t: array((), 1) = F();
   //@dump-sem-ir-end
 }
 
@@ -195,30 +195,30 @@ var a: array(1, 1);
 // CHECK:STDOUT:     %v.var_patt: %pattern_type.709 = var_pattern %v.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v.var: ref %array_type = var %v.var_patt
-// CHECK:STDOUT:   %F.ref.loc10_33: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
-// CHECK:STDOUT:   %.loc10_41.1: ref %tuple.type.e56 = splice_block %.loc10_41.6 {
+// CHECK:STDOUT:   %F.ref.loc10_40: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
+// CHECK:STDOUT:   %.loc10_48.1: ref %tuple.type.e56 = splice_block %.loc10_48.6 {
 // CHECK:STDOUT:     %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0]
-// CHECK:STDOUT:     %.loc10_41.6: ref %tuple.type.e56 = array_index %v.var, %int_0
+// CHECK:STDOUT:     %.loc10_48.6: ref %tuple.type.e56 = array_index %v.var, %int_0
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %F.call.loc10_35: init %tuple.type.e56 to %.loc10_41.1 = call %F.ref.loc10_33()
-// CHECK:STDOUT:   %F.ref.loc10_38: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
-// CHECK:STDOUT:   %.loc10_41.2: ref %tuple.type.e56 = splice_block %.loc10_41.5 {
+// CHECK:STDOUT:   %F.call.loc10_42: init %tuple.type.e56 to %.loc10_48.1 = call %F.ref.loc10_40()
+// CHECK:STDOUT:   %F.ref.loc10_45: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
+// CHECK:STDOUT:   %.loc10_48.2: ref %tuple.type.e56 = splice_block %.loc10_48.5 {
 // CHECK:STDOUT:     %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
-// CHECK:STDOUT:     %.loc10_41.5: ref %tuple.type.e56 = array_index %v.var, %int_1
+// CHECK:STDOUT:     %.loc10_48.5: ref %tuple.type.e56 = array_index %v.var, %int_1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %F.call.loc10_40: init %tuple.type.e56 to %.loc10_41.2 = call %F.ref.loc10_38()
-// CHECK:STDOUT:   %.loc10_41.3: %tuple.type.708 = tuple_literal (%F.call.loc10_35, %F.call.loc10_40)
-// CHECK:STDOUT:   %.loc10_41.4: init %array_type to %v.var = array_init (%F.call.loc10_35, %F.call.loc10_40)
-// CHECK:STDOUT:   %.loc10_3: init %array_type = converted %.loc10_41.3, %.loc10_41.4
+// CHECK:STDOUT:   %F.call.loc10_47: init %tuple.type.e56 to %.loc10_48.2 = call %F.ref.loc10_45()
+// CHECK:STDOUT:   %.loc10_48.3: %tuple.type.708 = tuple_literal (%F.call.loc10_42, %F.call.loc10_47)
+// CHECK:STDOUT:   %.loc10_48.4: init %array_type to %v.var = array_init (%F.call.loc10_42, %F.call.loc10_47)
+// CHECK:STDOUT:   %.loc10_3: init %array_type = converted %.loc10_48.3, %.loc10_48.4
 // CHECK:STDOUT:   assign %v.var, %.loc10_3
-// CHECK:STDOUT:   %.loc10_28: type = splice_block %array_type [concrete = constants.%array_type] {
-// CHECK:STDOUT:     %C.ref.loc10_17: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:     %C.ref.loc10_20: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:     %C.ref.loc10_23: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:     %.loc10_24.1: %tuple.type.ff9 = tuple_literal (%C.ref.loc10_17, %C.ref.loc10_20, %C.ref.loc10_23) [concrete = constants.%tuple]
+// CHECK:STDOUT:   %.loc10_35: type = splice_block %array_type [concrete = constants.%array_type] {
+// CHECK:STDOUT:     %C.ref.loc10_24: type = name_ref C, file.%C.decl [concrete = constants.%C]
+// CHECK:STDOUT:     %C.ref.loc10_27: type = name_ref C, file.%C.decl [concrete = constants.%C]
+// CHECK:STDOUT:     %C.ref.loc10_30: type = name_ref C, file.%C.decl [concrete = constants.%C]
+// CHECK:STDOUT:     %.loc10_31.1: %tuple.type.ff9 = tuple_literal (%C.ref.loc10_24, %C.ref.loc10_27, %C.ref.loc10_30) [concrete = constants.%tuple]
 // CHECK:STDOUT:     %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2]
-// CHECK:STDOUT:     %.loc10_24.2: type = converted %.loc10_24.1, constants.%tuple.type.e56 [concrete = constants.%tuple.type.e56]
-// CHECK:STDOUT:     %array_type: type = array_type %int_2, %.loc10_24.2 [concrete = constants.%array_type]
+// CHECK:STDOUT:     %.loc10_31.2: type = converted %.loc10_31.1, constants.%tuple.type.e56 [concrete = constants.%tuple.type.e56]
+// CHECK:STDOUT:     %array_type: type = array_type %int_2, %.loc10_31.2 [concrete = constants.%array_type]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v: ref %array_type = ref_binding v, %v.var
 // CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %v.var, constants.%DestroyOp
@@ -255,11 +255,11 @@ var a: array(1, 1);
 // CHECK:STDOUT:     %a.var_patt: %pattern_type.035 = var_pattern %a.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.var: ref %array_type = var %a.var_patt
-// CHECK:STDOUT:   %.loc7_21: type = splice_block %array_type [concrete = constants.%array_type] {
-// CHECK:STDOUT:     %.loc7_17.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:   %.loc7_28: type = splice_block %array_type [concrete = constants.%array_type] {
+// CHECK:STDOUT:     %.loc7_24.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
 // CHECK:STDOUT:     %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3]
-// CHECK:STDOUT:     %.loc7_17.2: type = converted %.loc7_17.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
-// CHECK:STDOUT:     %array_type: type = array_type %int_3, %.loc7_17.2 [concrete = constants.%array_type]
+// CHECK:STDOUT:     %.loc7_24.2: type = converted %.loc7_24.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
+// CHECK:STDOUT:     %array_type: type = array_type %int_3, %.loc7_24.2 [concrete = constants.%array_type]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a: ref %array_type = ref_binding a, %a.var
 // CHECK:STDOUT:   name_binding_decl {
@@ -267,15 +267,15 @@ var a: array(1, 1);
 // CHECK:STDOUT:     %b.var_patt: %pattern_type.8c1 = var_pattern %b.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %b.var: ref %tuple.type = var %b.var_patt
-// CHECK:STDOUT:   %.loc8_21.1: type = splice_block %.loc8_21.6 [concrete = constants.%tuple.type] {
-// CHECK:STDOUT:     %.loc8_12: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:     %.loc8_16: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:     %.loc8_20: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:     %.loc8_21.2: %tuple.type = tuple_literal (%.loc8_12, %.loc8_16, %.loc8_20) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc8_21.3: type = converted constants.%empty_tuple, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
-// CHECK:STDOUT:     %.loc8_21.4: type = converted constants.%empty_tuple, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
-// CHECK:STDOUT:     %.loc8_21.5: type = converted constants.%empty_tuple, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
-// CHECK:STDOUT:     %.loc8_21.6: type = converted %.loc8_21.2, constants.%tuple.type [concrete = constants.%tuple.type]
+// CHECK:STDOUT:   %.loc8_28.1: type = splice_block %.loc8_28.6 [concrete = constants.%tuple.type] {
+// CHECK:STDOUT:     %.loc8_19: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:     %.loc8_23: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:     %.loc8_27: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:     %.loc8_28.2: %tuple.type = tuple_literal (%.loc8_19, %.loc8_23, %.loc8_27) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc8_28.3: type = converted constants.%empty_tuple, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
+// CHECK:STDOUT:     %.loc8_28.4: type = converted constants.%empty_tuple, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
+// CHECK:STDOUT:     %.loc8_28.5: type = converted constants.%empty_tuple, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
+// CHECK:STDOUT:     %.loc8_28.6: type = converted %.loc8_28.2, constants.%tuple.type [concrete = constants.%tuple.type]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %b: ref %tuple.type = ref_binding b, %b.var
 // CHECK:STDOUT:   %DestroyOp.bound.loc8: <bound method> = bound_method %b.var, constants.%DestroyOp.b0ebf8.1
@@ -302,7 +302,7 @@ var a: array(1, 1);
 // CHECK:STDOUT:   %pattern_type.fe8: type = pattern_type %array_type [concrete]
 // CHECK:STDOUT:   %int_0: Core.IntLiteral = int_value 0 [concrete]
 // CHECK:STDOUT:   %array: %array_type = tuple_value (%empty_tuple) [concrete]
-// CHECK:STDOUT:   %DestroyOp.type.3e79c2.1: type = fn_type @DestroyOp.loc8_27 [concrete]
+// CHECK:STDOUT:   %DestroyOp.type.3e79c2.1: type = fn_type @DestroyOp.loc8_34 [concrete]
 // CHECK:STDOUT:   %DestroyOp.b0ebf8.1: %DestroyOp.type.3e79c2.1 = struct_value () [concrete]
 // CHECK:STDOUT:   %DestroyOp.type.3e79c2.2: type = fn_type @DestroyOp.loc8_3 [concrete]
 // CHECK:STDOUT:   %DestroyOp.b0ebf8.2: %DestroyOp.type.3e79c2.2 = struct_value () [concrete]
@@ -320,31 +320,31 @@ var a: array(1, 1);
 // CHECK:STDOUT:   %t.var: ref %array_type = var %t.var_patt
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
 // CHECK:STDOUT:   %F.call: init %tuple.type = call %F.ref()
-// CHECK:STDOUT:   %.loc8_27.1: ref %tuple.type = temporary_storage
-// CHECK:STDOUT:   %.loc8_27.2: ref %tuple.type = temporary %.loc8_27.1, %F.call
-// CHECK:STDOUT:   %tuple.elem0: ref %empty_tuple.type = tuple_access %.loc8_27.2, element0
+// CHECK:STDOUT:   %.loc8_34.1: ref %tuple.type = temporary_storage
+// CHECK:STDOUT:   %.loc8_34.2: ref %tuple.type = temporary %.loc8_34.1, %F.call
+// CHECK:STDOUT:   %tuple.elem0: ref %empty_tuple.type = tuple_access %.loc8_34.2, element0
 // CHECK:STDOUT:   %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0]
-// CHECK:STDOUT:   %.loc8_27.3: ref %empty_tuple.type = array_index %t.var, %int_0
-// CHECK:STDOUT:   %.loc8_27.4: init %empty_tuple.type = tuple_init () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc8_27.5: init %empty_tuple.type = converted %tuple.elem0, %.loc8_27.4 [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc8_27.6: init %array_type to %t.var = array_init (%.loc8_27.5) [concrete = constants.%array]
-// CHECK:STDOUT:   %.loc8_3: init %array_type = converted %F.call, %.loc8_27.6 [concrete = constants.%array]
+// CHECK:STDOUT:   %.loc8_34.3: ref %empty_tuple.type = array_index %t.var, %int_0
+// CHECK:STDOUT:   %.loc8_34.4: init %empty_tuple.type = tuple_init () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:   %.loc8_34.5: init %empty_tuple.type = converted %tuple.elem0, %.loc8_34.4 [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:   %.loc8_34.6: init %array_type to %t.var = array_init (%.loc8_34.5) [concrete = constants.%array]
+// CHECK:STDOUT:   %.loc8_3: init %array_type = converted %F.call, %.loc8_34.6 [concrete = constants.%array]
 // CHECK:STDOUT:   assign %t.var, %.loc8_3
-// CHECK:STDOUT:   %.loc8_21: type = splice_block %array_type [concrete = constants.%array_type] {
-// CHECK:STDOUT:     %.loc8_17.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:   %.loc8_28: type = splice_block %array_type [concrete = constants.%array_type] {
+// CHECK:STDOUT:     %.loc8_24.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
 // CHECK:STDOUT:     %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
-// CHECK:STDOUT:     %.loc8_17.2: type = converted %.loc8_17.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
-// CHECK:STDOUT:     %array_type: type = array_type %int_1, %.loc8_17.2 [concrete = constants.%array_type]
+// CHECK:STDOUT:     %.loc8_24.2: type = converted %.loc8_24.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
+// CHECK:STDOUT:     %array_type: type = array_type %int_1, %.loc8_24.2 [concrete = constants.%array_type]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %t: ref %array_type = ref_binding t, %t.var
-// CHECK:STDOUT:   %DestroyOp.bound.loc8_27: <bound method> = bound_method %.loc8_27.2, constants.%DestroyOp.b0ebf8.1
-// CHECK:STDOUT:   %DestroyOp.call.loc8_27: init %empty_tuple.type = call %DestroyOp.bound.loc8_27(%.loc8_27.2)
+// CHECK:STDOUT:   %DestroyOp.bound.loc8_34: <bound method> = bound_method %.loc8_34.2, constants.%DestroyOp.b0ebf8.1
+// CHECK:STDOUT:   %DestroyOp.call.loc8_34: init %empty_tuple.type = call %DestroyOp.bound.loc8_34(%.loc8_34.2)
 // CHECK:STDOUT:   %DestroyOp.bound.loc8_3: <bound method> = bound_method %t.var, constants.%DestroyOp.b0ebf8.2
 // CHECK:STDOUT:   %DestroyOp.call.loc8_3: init %empty_tuple.type = call %DestroyOp.bound.loc8_3(%t.var)
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @DestroyOp.loc8_27(%self.param: ref %tuple.type) = "no_op";
+// CHECK:STDOUT: fn @DestroyOp.loc8_34(%self.param: ref %tuple.type) = "no_op";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @DestroyOp.loc8_3(%self.param: ref %array_type) = "no_op";
 // CHECK:STDOUT:

+ 26 - 26
toolchain/check/testdata/array/init_dependent_bound.carbon

@@ -17,7 +17,7 @@ library "[[@TEST_NAME]]";
 fn G(T:! type) {
   // We can initialize this without knowing T.
   //@dump-sem-ir-begin
-  var arr: array(T, 0) = ();
+  var unused arr: array(T, 0) = ();
   //@dump-sem-ir-end
 }
 
@@ -32,11 +32,11 @@ fn H() {
 library "[[@TEST_NAME]]";
 
 fn F(N:! i32) {
-  // CHECK:STDERR: fail_init_dependent_bound.carbon:[[@LINE+4]]:28: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound]
-  // CHECK:STDERR:   var arr: array(i32, N) = (1, 2, 3);
-  // CHECK:STDERR:                            ^~~~~~~~~
+  // CHECK:STDERR: fail_init_dependent_bound.carbon:[[@LINE+4]]:35: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound]
+  // CHECK:STDERR:   var unused arr: array(i32, N) = (1, 2, 3);
+  // CHECK:STDERR:                                   ^~~~~~~~~
   // CHECK:STDERR:
-  var arr: array(i32, N) = (1, 2, 3);
+  var unused arr: array(i32, N) = (1, 2, 3);
 }
 
 // --- fail_todo_init_template_dependent_bound.carbon
@@ -46,11 +46,11 @@ library "[[@TEST_NAME]]";
 // TODO: This should be valid.
 fn G(template N:! i32) {
   //@dump-sem-ir-begin
-  // CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE+4]]:12: error: cannot evaluate type expression [TypeExprEvaluationFailure]
-  // CHECK:STDERR:   var arr: array(i32, N) = (1, 2, 3);
-  // CHECK:STDERR:            ^~~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE+4]]:19: error: cannot evaluate type expression [TypeExprEvaluationFailure]
+  // CHECK:STDERR:   var unused arr: array(i32, N) = (1, 2, 3);
+  // CHECK:STDERR:                   ^~~~~~~~~~~~~
   // CHECK:STDERR:
-  var arr: array(i32, N) = (1, 2, 3);
+  var unused arr: array(i32, N) = (1, 2, 3);
   //@dump-sem-ir-end
 }
 
@@ -94,12 +94,12 @@ fn H() { G(3); }
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %array_type.loc7_22.2: type = array_type constants.%int_0, %T.loc4_6.1 [symbolic = %array_type.loc7_22.2 (constants.%array_type.1b3)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc7_22.2 [symbolic = %require_complete (constants.%require_complete)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc7_22.2 [symbolic = %pattern_type (constants.%pattern_type.bd6)]
-// CHECK:STDOUT:   %array: @G.%array_type.loc7_22.2 (%array_type.1b3) = tuple_value () [symbolic = %array (constants.%array.ca4)]
-// CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.loc7_22.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
-// CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %array_type.loc7_22.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.15e)]
+// CHECK:STDOUT:   %array_type.loc7_29.2: type = array_type constants.%int_0, %T.loc4_6.1 [symbolic = %array_type.loc7_29.2 (constants.%array_type.1b3)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc7_29.2 [symbolic = %require_complete (constants.%require_complete)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc7_29.2 [symbolic = %pattern_type (constants.%pattern_type.bd6)]
+// CHECK:STDOUT:   %array: @G.%array_type.loc7_29.2 (%array_type.1b3) = tuple_value () [symbolic = %array (constants.%array.ca4)]
+// CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.loc7_29.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
+// CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %array_type.loc7_29.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.15e)]
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type: type = fn_type @Destroy.WithSelf.Op, @Destroy(%Destroy.facet) [symbolic = %Destroy.WithSelf.Op.type (constants.%Destroy.WithSelf.Op.type.427)]
 // CHECK:STDOUT:   %.loc7_3.2: type = fn_type_with_self_type %Destroy.WithSelf.Op.type, %Destroy.facet [symbolic = %.loc7_3.2 (constants.%.6d6)]
 // CHECK:STDOUT:   %impl.elem0.loc7_3.2: @G.%.loc7_3.2 (%.6d6) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
@@ -111,17 +111,17 @@ fn H() { G(3); }
 // CHECK:STDOUT:       %arr.patt: @G.%pattern_type (%pattern_type.bd6) = ref_binding_pattern arr [concrete]
 // CHECK:STDOUT:       %arr.var_patt: @G.%pattern_type (%pattern_type.bd6) = var_pattern %arr.patt [concrete]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %arr.var: ref @G.%array_type.loc7_22.2 (%array_type.1b3) = var %arr.var_patt
-// CHECK:STDOUT:     %.loc7_27.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:     %.loc7_27.2: init @G.%array_type.loc7_22.2 (%array_type.1b3) to %arr.var = array_init () [symbolic = %array (constants.%array.ca4)]
-// CHECK:STDOUT:     %.loc7_3.1: init @G.%array_type.loc7_22.2 (%array_type.1b3) = converted %.loc7_27.1, %.loc7_27.2 [symbolic = %array (constants.%array.ca4)]
+// CHECK:STDOUT:     %arr.var: ref @G.%array_type.loc7_29.2 (%array_type.1b3) = var %arr.var_patt
+// CHECK:STDOUT:     %.loc7_34.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:     %.loc7_34.2: init @G.%array_type.loc7_29.2 (%array_type.1b3) to %arr.var = array_init () [symbolic = %array (constants.%array.ca4)]
+// CHECK:STDOUT:     %.loc7_3.1: init @G.%array_type.loc7_29.2 (%array_type.1b3) = converted %.loc7_34.1, %.loc7_34.2 [symbolic = %array (constants.%array.ca4)]
 // CHECK:STDOUT:     assign %arr.var, %.loc7_3.1
-// CHECK:STDOUT:     %.loc7_22: type = splice_block %array_type.loc7_22.1 [symbolic = %array_type.loc7_22.2 (constants.%array_type.1b3)] {
+// CHECK:STDOUT:     %.loc7_29: type = splice_block %array_type.loc7_29.1 [symbolic = %array_type.loc7_29.2 (constants.%array_type.1b3)] {
 // CHECK:STDOUT:       %T.ref: type = name_ref T, %T.loc4_6.2 [symbolic = %T.loc4_6.1 (constants.%T)]
 // CHECK:STDOUT:       %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0]
-// CHECK:STDOUT:       %array_type.loc7_22.1: type = array_type %int_0, %T.ref [symbolic = %array_type.loc7_22.2 (constants.%array_type.1b3)]
+// CHECK:STDOUT:       %array_type.loc7_29.1: type = array_type %int_0, %T.ref [symbolic = %array_type.loc7_29.2 (constants.%array_type.1b3)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %arr: ref @G.%array_type.loc7_22.2 (%array_type.1b3) = ref_binding arr, %arr.var
+// CHECK:STDOUT:     %arr: ref @G.%array_type.loc7_29.2 (%array_type.1b3) = ref_binding arr, %arr.var
 // CHECK:STDOUT:     %impl.elem0.loc7_3.1: @G.%.loc7_3.2 (%.6d6) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
 // CHECK:STDOUT:     %bound_method.loc7_3.1: <bound method> = bound_method %arr.var, %impl.elem0.loc7_3.1
 // CHECK:STDOUT:     %specific_impl_fn.loc7_3.1: <specific function> = specific_impl_function %impl.elem0.loc7_3.1, @Destroy.WithSelf.Op(constants.%Destroy.facet.15e) [symbolic = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn)]
@@ -141,7 +141,7 @@ fn H() { G(3); }
 // CHECK:STDOUT:   %T.loc4_6.1 => constants.%C
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %array_type.loc7_22.2 => constants.%array_type.70a
+// CHECK:STDOUT:   %array_type.loc7_29.2 => constants.%array_type.70a
 // CHECK:STDOUT:   %require_complete => constants.%complete_type.95b
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.f2c
 // CHECK:STDOUT:   %array => constants.%array.40f
@@ -200,7 +200,7 @@ fn H() { G(3); }
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %.loc11_23.2: <instruction> = convert_to_value_action %N.ref, Core.IntLiteral [template]
+// CHECK:STDOUT:   %.loc11_30.2: <instruction> = convert_to_value_action %N.ref, Core.IntLiteral [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:
@@ -212,7 +212,7 @@ fn H() { G(3); }
 // CHECK:STDOUT:     %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
 // CHECK:STDOUT:     %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2]
 // CHECK:STDOUT:     %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba]
-// CHECK:STDOUT:     %.loc11_36: %tuple.type = tuple_literal (%int_1, %int_2, %int_3) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc11_43: %tuple.type = tuple_literal (%int_1, %int_2, %int_3) [concrete = constants.%tuple]
 // CHECK:STDOUT:     assign %arr.var, <error>
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:     %arr: ref <error> = ref_binding arr, <error> [concrete = <error>]
@@ -228,6 +228,6 @@ fn H() { G(3); }
 // CHECK:STDOUT:   %N.loc5_15.1 => constants.%int_3.822
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %.loc11_23.2 => constants.%inst.splice_block
+// CHECK:STDOUT:   %.loc11_30.2 => constants.%inst.splice_block
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 20 - 20
toolchain/check/testdata/as/adapter_conversion.carbon

@@ -123,7 +123,7 @@ class A {
 
 fn F(a: A) {
   //@dump-sem-ir-begin
-  let a_value: A = (a as ({}, Noncopyable)) as A;
+  let unused a_value: A = (a as ({}, Noncopyable)) as A;
   //@dump-sem-ir-end
 }
 
@@ -146,16 +146,16 @@ fn F(a: A) {
   // behavior.
 
   // CHECK:STDERR: fail_init_tuple_variable.carbon:[[@LINE+10]]:3: error: cannot copy value of type `Noncopyable` [CopyOfUncopyableType]
-  // CHECK:STDERR:   var a_init: A = (a as ({}, Noncopyable)) as A;
-  // CHECK:STDERR:   ^~~~~~~~~~~~~
+  // CHECK:STDERR:   var unused a_init: A = (a as ({}, Noncopyable)) as A;
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_init_tuple_variable.carbon:[[@LINE+7]]:3: note: type `Noncopyable` does not implement interface `Core.Copy` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   var a_init: A = (a as ({}, Noncopyable)) as A;
-  // CHECK:STDERR:   ^~~~~~~~~~~~~
-  // CHECK:STDERR: fail_init_tuple_variable.carbon:[[@LINE+4]]:19: note: in copy of `A` [InCopy]
-  // CHECK:STDERR:   var a_init: A = (a as ({}, Noncopyable)) as A;
-  // CHECK:STDERR:                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR:   var unused a_init: A = (a as ({}, Noncopyable)) as A;
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_init_tuple_variable.carbon:[[@LINE+4]]:26: note: in copy of `A` [InCopy]
+  // CHECK:STDERR:   var unused a_init: A = (a as ({}, Noncopyable)) as A;
+  // CHECK:STDERR:                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var a_init: A = (a as ({}, Noncopyable)) as A;
+  var unused a_init: A = (a as ({}, Noncopyable)) as A;
 }
 
 // --- fail_adapt_init_from_struct.carbon
@@ -446,18 +446,18 @@ var b: B = {.x = ()} as B;
 // CHECK:STDOUT:     %a_value.patt: %pattern_type = value_binding_pattern a_value [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.ref: %A = name_ref a, %a
-// CHECK:STDOUT:   %.loc14_28: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
+// CHECK:STDOUT:   %.loc14_35: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
 // CHECK:STDOUT:   %Noncopyable.ref: type = name_ref Noncopyable, file.%Noncopyable.decl [concrete = constants.%Noncopyable]
-// CHECK:STDOUT:   %.loc14_42.1: %tuple.type.c8c = tuple_literal (%.loc14_28, %Noncopyable.ref) [concrete = constants.%tuple]
-// CHECK:STDOUT:   %.loc14_42.2: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
-// CHECK:STDOUT:   %.loc14_42.3: type = converted %.loc14_42.1, constants.%tuple.type.037 [concrete = constants.%tuple.type.037]
-// CHECK:STDOUT:   %.loc14_23.1: %tuple.type.037 = as_compatible %a.ref
-// CHECK:STDOUT:   %.loc14_23.2: %tuple.type.037 = converted %a.ref, %.loc14_23.1
-// CHECK:STDOUT:   %A.ref.loc14_48: type = name_ref A, file.%A.decl [concrete = constants.%A]
-// CHECK:STDOUT:   %.loc14_45.1: %A = as_compatible %.loc14_23.2
-// CHECK:STDOUT:   %.loc14_45.2: %A = converted %.loc14_23.2, %.loc14_45.1
-// CHECK:STDOUT:   %A.ref.loc14_16: type = name_ref A, file.%A.decl [concrete = constants.%A]
-// CHECK:STDOUT:   %a_value: %A = value_binding a_value, %.loc14_45.2
+// CHECK:STDOUT:   %.loc14_49.1: %tuple.type.c8c = tuple_literal (%.loc14_35, %Noncopyable.ref) [concrete = constants.%tuple]
+// CHECK:STDOUT:   %.loc14_49.2: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:   %.loc14_49.3: type = converted %.loc14_49.1, constants.%tuple.type.037 [concrete = constants.%tuple.type.037]
+// CHECK:STDOUT:   %.loc14_30.1: %tuple.type.037 = as_compatible %a.ref
+// CHECK:STDOUT:   %.loc14_30.2: %tuple.type.037 = converted %a.ref, %.loc14_30.1
+// CHECK:STDOUT:   %A.ref.loc14_55: type = name_ref A, file.%A.decl [concrete = constants.%A]
+// CHECK:STDOUT:   %.loc14_52.1: %A = as_compatible %.loc14_30.2
+// CHECK:STDOUT:   %.loc14_52.2: %A = converted %.loc14_30.2, %.loc14_52.1
+// CHECK:STDOUT:   %A.ref.loc14_23: type = name_ref A, file.%A.decl [concrete = constants.%A]
+// CHECK:STDOUT:   %a_value: %A = value_binding a_value, %.loc14_52.2
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 58 - 58
toolchain/check/testdata/as/basics.carbon

@@ -41,14 +41,14 @@ fn Make() -> X;
 fn Let() {
   // This should create value bindings for both tuple elements.
   //@dump-sem-ir-begin
-  let a: (X, X) = (Make(), Make()) as (X, X);
+  let unused a: (X, X) = (Make(), Make()) as (X, X);
   //@dump-sem-ir-end
 }
 
 fn Var() {
   // This should initialize both tuple elements in place.
   //@dump-sem-ir-begin
-  var b: (X, X) = (Make(), Make()) as (X, X);
+  var unused b: (X, X) = (Make(), Make()) as (X, X);
   //@dump-sem-ir-end
 }
 
@@ -62,13 +62,13 @@ class X {
 
 fn Value(n: X) {
   //@dump-sem-ir-begin
-  let m: X = n as X;
+  let unused m: X = n as X;
   //@dump-sem-ir-end
 }
 
 fn Reference(p: X*) {
   //@dump-sem-ir-begin
-  let q: X* = &(*p as X);
+  let unused q: X* = &(*p as X);
   //@dump-sem-ir-end
 }
 
@@ -76,7 +76,7 @@ fn Make() -> X;
 
 fn Initializing() {
   //@dump-sem-ir-begin
-  var x: X = (Make() as X);
+  var unused x: X = (Make() as X);
   //@dump-sem-ir-end
 }
 
@@ -227,34 +227,34 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %a.patt: %pattern_type.e9d = value_binding_pattern a [concrete]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Make.ref.loc13_20: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
-// CHECK:STDOUT:   %.loc13_25.1: ref %X = temporary_storage
-// CHECK:STDOUT:   %Make.call.loc13_25: init %X to %.loc13_25.1 = call %Make.ref.loc13_20()
-// CHECK:STDOUT:   %Make.ref.loc13_28: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
-// CHECK:STDOUT:   %.loc13_33.1: ref %X = temporary_storage
-// CHECK:STDOUT:   %Make.call.loc13_33: init %X to %.loc13_33.1 = call %Make.ref.loc13_28()
-// CHECK:STDOUT:   %.loc13_34.1: %tuple.type.2de = tuple_literal (%Make.call.loc13_25, %Make.call.loc13_33)
-// CHECK:STDOUT:   %X.ref.loc13_40: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %X.ref.loc13_43: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc13_44.1: %tuple.type.24b = tuple_literal (%X.ref.loc13_40, %X.ref.loc13_43) [concrete = constants.%tuple]
-// CHECK:STDOUT:   %.loc13_44.2: type = converted %.loc13_44.1, constants.%tuple.type.2de [concrete = constants.%tuple.type.2de]
-// CHECK:STDOUT:   %.loc13_15.1: type = splice_block %.loc13_15.3 [concrete = constants.%tuple.type.2de] {
-// CHECK:STDOUT:     %X.ref.loc13_11: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %X.ref.loc13_14: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %.loc13_15.2: %tuple.type.24b = tuple_literal (%X.ref.loc13_11, %X.ref.loc13_14) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc13_15.3: type = converted %.loc13_15.2, constants.%tuple.type.2de [concrete = constants.%tuple.type.2de]
+// CHECK:STDOUT:   %Make.ref.loc13_27: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
+// CHECK:STDOUT:   %.loc13_32.1: ref %X = temporary_storage
+// CHECK:STDOUT:   %Make.call.loc13_32: init %X to %.loc13_32.1 = call %Make.ref.loc13_27()
+// CHECK:STDOUT:   %Make.ref.loc13_35: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
+// CHECK:STDOUT:   %.loc13_40.1: ref %X = temporary_storage
+// CHECK:STDOUT:   %Make.call.loc13_40: init %X to %.loc13_40.1 = call %Make.ref.loc13_35()
+// CHECK:STDOUT:   %.loc13_41.1: %tuple.type.2de = tuple_literal (%Make.call.loc13_32, %Make.call.loc13_40)
+// CHECK:STDOUT:   %X.ref.loc13_47: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc13_50: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc13_51.1: %tuple.type.24b = tuple_literal (%X.ref.loc13_47, %X.ref.loc13_50) [concrete = constants.%tuple]
+// CHECK:STDOUT:   %.loc13_51.2: type = converted %.loc13_51.1, constants.%tuple.type.2de [concrete = constants.%tuple.type.2de]
+// CHECK:STDOUT:   %.loc13_22.1: type = splice_block %.loc13_22.3 [concrete = constants.%tuple.type.2de] {
+// CHECK:STDOUT:     %X.ref.loc13_18: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %X.ref.loc13_21: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %.loc13_22.2: %tuple.type.24b = tuple_literal (%X.ref.loc13_18, %X.ref.loc13_21) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc13_22.3: type = converted %.loc13_22.2, constants.%tuple.type.2de [concrete = constants.%tuple.type.2de]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc13_25.2: ref %X = temporary %.loc13_25.1, %Make.call.loc13_25
-// CHECK:STDOUT:   %.loc13_25.3: %X = acquire_value %.loc13_25.2
-// CHECK:STDOUT:   %.loc13_33.2: ref %X = temporary %.loc13_33.1, %Make.call.loc13_33
-// CHECK:STDOUT:   %.loc13_33.3: %X = acquire_value %.loc13_33.2
-// CHECK:STDOUT:   %tuple: %tuple.type.2de = tuple_value (%.loc13_25.3, %.loc13_33.3)
-// CHECK:STDOUT:   %.loc13_34.2: %tuple.type.2de = converted %.loc13_34.1, %tuple
-// CHECK:STDOUT:   %a: %tuple.type.2de = value_binding a, %.loc13_34.2
-// CHECK:STDOUT:   %DestroyOp.bound.loc13_33: <bound method> = bound_method %.loc13_33.2, constants.%DestroyOp.b0ebf8.1
-// CHECK:STDOUT:   %DestroyOp.call.loc13_33: init %empty_tuple.type = call %DestroyOp.bound.loc13_33(%.loc13_33.2)
-// CHECK:STDOUT:   %DestroyOp.bound.loc13_25: <bound method> = bound_method %.loc13_25.2, constants.%DestroyOp.b0ebf8.1
-// CHECK:STDOUT:   %DestroyOp.call.loc13_25: init %empty_tuple.type = call %DestroyOp.bound.loc13_25(%.loc13_25.2)
+// CHECK:STDOUT:   %.loc13_32.2: ref %X = temporary %.loc13_32.1, %Make.call.loc13_32
+// CHECK:STDOUT:   %.loc13_32.3: %X = acquire_value %.loc13_32.2
+// CHECK:STDOUT:   %.loc13_40.2: ref %X = temporary %.loc13_40.1, %Make.call.loc13_40
+// CHECK:STDOUT:   %.loc13_40.3: %X = acquire_value %.loc13_40.2
+// CHECK:STDOUT:   %tuple: %tuple.type.2de = tuple_value (%.loc13_32.3, %.loc13_40.3)
+// CHECK:STDOUT:   %.loc13_41.2: %tuple.type.2de = converted %.loc13_41.1, %tuple
+// CHECK:STDOUT:   %a: %tuple.type.2de = value_binding a, %.loc13_41.2
+// CHECK:STDOUT:   %DestroyOp.bound.loc13_40: <bound method> = bound_method %.loc13_40.2, constants.%DestroyOp.b0ebf8.1
+// CHECK:STDOUT:   %DestroyOp.call.loc13_40: init %empty_tuple.type = call %DestroyOp.bound.loc13_40(%.loc13_40.2)
+// CHECK:STDOUT:   %DestroyOp.bound.loc13_32: <bound method> = bound_method %.loc13_32.2, constants.%DestroyOp.b0ebf8.1
+// CHECK:STDOUT:   %DestroyOp.call.loc13_32: init %empty_tuple.type = call %DestroyOp.bound.loc13_32(%.loc13_32.2)
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -267,25 +267,25 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
 // CHECK:STDOUT:     %b.var_patt: %pattern_type.e9d = var_pattern %b.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %b.var: ref %tuple.type.2de = var %b.var_patt
-// CHECK:STDOUT:   %Make.ref.loc20_20: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
+// CHECK:STDOUT:   %Make.ref.loc20_27: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
 // CHECK:STDOUT:   %tuple.elem0: ref %X = tuple_access %b.var, element0
-// CHECK:STDOUT:   %Make.call.loc20_25: init %X to %tuple.elem0 = call %Make.ref.loc20_20()
-// CHECK:STDOUT:   %Make.ref.loc20_28: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
+// CHECK:STDOUT:   %Make.call.loc20_32: init %X to %tuple.elem0 = call %Make.ref.loc20_27()
+// CHECK:STDOUT:   %Make.ref.loc20_35: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
 // CHECK:STDOUT:   %tuple.elem1: ref %X = tuple_access %b.var, element1
-// CHECK:STDOUT:   %Make.call.loc20_33: init %X to %tuple.elem1 = call %Make.ref.loc20_28()
-// CHECK:STDOUT:   %.loc20_34.1: %tuple.type.2de = tuple_literal (%Make.call.loc20_25, %Make.call.loc20_33)
-// CHECK:STDOUT:   %X.ref.loc20_40: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %X.ref.loc20_43: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc20_44.1: %tuple.type.24b = tuple_literal (%X.ref.loc20_40, %X.ref.loc20_43) [concrete = constants.%tuple]
-// CHECK:STDOUT:   %.loc20_44.2: type = converted %.loc20_44.1, constants.%tuple.type.2de [concrete = constants.%tuple.type.2de]
-// CHECK:STDOUT:   %.loc20_34.2: init %tuple.type.2de to %b.var = tuple_init (%Make.call.loc20_25, %Make.call.loc20_33)
-// CHECK:STDOUT:   %.loc20_3: init %tuple.type.2de = converted %.loc20_34.1, %.loc20_34.2
+// CHECK:STDOUT:   %Make.call.loc20_40: init %X to %tuple.elem1 = call %Make.ref.loc20_35()
+// CHECK:STDOUT:   %.loc20_41.1: %tuple.type.2de = tuple_literal (%Make.call.loc20_32, %Make.call.loc20_40)
+// CHECK:STDOUT:   %X.ref.loc20_47: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc20_50: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc20_51.1: %tuple.type.24b = tuple_literal (%X.ref.loc20_47, %X.ref.loc20_50) [concrete = constants.%tuple]
+// CHECK:STDOUT:   %.loc20_51.2: type = converted %.loc20_51.1, constants.%tuple.type.2de [concrete = constants.%tuple.type.2de]
+// CHECK:STDOUT:   %.loc20_41.2: init %tuple.type.2de to %b.var = tuple_init (%Make.call.loc20_32, %Make.call.loc20_40)
+// CHECK:STDOUT:   %.loc20_3: init %tuple.type.2de = converted %.loc20_41.1, %.loc20_41.2
 // CHECK:STDOUT:   assign %b.var, %.loc20_3
-// CHECK:STDOUT:   %.loc20_15.1: type = splice_block %.loc20_15.3 [concrete = constants.%tuple.type.2de] {
-// CHECK:STDOUT:     %X.ref.loc20_11: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %X.ref.loc20_14: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %.loc20_15.2: %tuple.type.24b = tuple_literal (%X.ref.loc20_11, %X.ref.loc20_14) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc20_15.3: type = converted %.loc20_15.2, constants.%tuple.type.2de [concrete = constants.%tuple.type.2de]
+// CHECK:STDOUT:   %.loc20_22.1: type = splice_block %.loc20_22.3 [concrete = constants.%tuple.type.2de] {
+// CHECK:STDOUT:     %X.ref.loc20_18: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %X.ref.loc20_21: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %.loc20_22.2: %tuple.type.24b = tuple_literal (%X.ref.loc20_18, %X.ref.loc20_21) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc20_22.3: type = converted %.loc20_22.2, constants.%tuple.type.2de [concrete = constants.%tuple.type.2de]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %b: ref %tuple.type.2de = ref_binding b, %b.var
 // CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %b.var, constants.%DestroyOp.b0ebf8.2
@@ -318,8 +318,8 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
 // CHECK:STDOUT:     %m.patt: %pattern_type.05f = value_binding_pattern m [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %n.ref: %X = name_ref n, %n
-// CHECK:STDOUT:   %X.ref.loc10_19: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %X.ref.loc10_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc10_26: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc10_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:   %m: %X = value_binding m, %n.ref
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
@@ -330,12 +330,12 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
 // CHECK:STDOUT:     %q.patt: %pattern_type.37f = value_binding_pattern q [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %p.ref: %ptr.2a9 = name_ref p, %p
-// CHECK:STDOUT:   %.loc16_17: ref %X = deref %p.ref
-// CHECK:STDOUT:   %X.ref.loc16_23: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %addr: %ptr.2a9 = addr_of %.loc16_17
-// CHECK:STDOUT:   %.loc16_11: type = splice_block %ptr.loc16 [concrete = constants.%ptr.2a9] {
-// CHECK:STDOUT:     %X.ref.loc16_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %ptr.loc16: type = ptr_type %X.ref.loc16_10 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %.loc16_24: ref %X = deref %p.ref
+// CHECK:STDOUT:   %X.ref.loc16_30: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %addr: %ptr.2a9 = addr_of %.loc16_24
+// CHECK:STDOUT:   %.loc16_18: type = splice_block %ptr.loc16 [concrete = constants.%ptr.2a9] {
+// CHECK:STDOUT:     %X.ref.loc16_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %ptr.loc16: type = ptr_type %X.ref.loc16_17 [concrete = constants.%ptr.2a9]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %q: %ptr.2a9 = value_binding q, %addr
 // CHECK:STDOUT:   <elided>
@@ -351,9 +351,9 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
 // CHECK:STDOUT:   %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
 // CHECK:STDOUT:   %.loc24: ref %X = splice_block %x.var {}
 // CHECK:STDOUT:   %Make.call: init %X to %.loc24 = call %Make.ref()
-// CHECK:STDOUT:   %X.ref.loc24_25: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc24_32: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:   assign %x.var, %Make.call
-// CHECK:STDOUT:   %X.ref.loc24_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc24_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:   %x: ref %X = ref_binding x, %x.var
 // CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %x.var, constants.%DestroyOp
 // CHECK:STDOUT:   %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%x.var)

+ 82 - 82
toolchain/check/testdata/as/const.carbon

@@ -24,10 +24,10 @@ let ptr: X* = &reference;
 fn Use() {
   // TODO: Should some of these be valid without the `as`?
   //@dump-sem-ir-begin
-  var i: const X = Init() as const X;
-  let v: const X = value as const X;
-  let a: const X* = &(reference as const X);
-  let b: const X* = ptr as const X*;
+  var unused i: const X = Init() as const X;
+  let unused v: const X = value as const X;
+  let unused a: const X* = &(reference as const X);
+  let unused b: const X* = ptr as const X*;
   //@dump-sem-ir-end
 }
 
@@ -43,8 +43,8 @@ let value: const X = Init();
 fn Use() {
   // TODO: Should some of these be valid without the `as`?
   //@dump-sem-ir-begin
-  var i: X = Init() as X;
-  let v: X = value as X;
+  var unused i: X = Init() as X;
+  let unused v: X = value as X;
   //@dump-sem-ir-end
 }
 
@@ -58,22 +58,22 @@ var reference: const X;
 let ptr: const X* = &reference;
 
 fn Use() {
-  // CHECK:STDERR: fail_cannot_remove_const.carbon:[[@LINE+7]]:17: error: cannot convert expression of type `const X` to `X` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let a: X* = &(reference as X);
-  // CHECK:STDERR:                 ^~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_const.carbon:[[@LINE+4]]:17: note: type `const X` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let a: X* = &(reference as X);
-  // CHECK:STDERR:                 ^~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_const.carbon:[[@LINE+7]]:24: error: cannot convert expression of type `const X` to `X` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused a: X* = &(reference as X);
+  // CHECK:STDERR:                        ^~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_const.carbon:[[@LINE+4]]:24: note: type `const X` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused a: X* = &(reference as X);
+  // CHECK:STDERR:                        ^~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let a: X* = &(reference as X);
-  // CHECK:STDERR: fail_cannot_remove_const.carbon:[[@LINE+7]]:15: error: cannot convert expression of type `const X*` to `X*` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let b: X* = ptr as X*;
-  // CHECK:STDERR:               ^~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_const.carbon:[[@LINE+4]]:15: note: type `const X*` does not implement interface `Core.As(X*)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let b: X* = ptr as X*;
-  // CHECK:STDERR:               ^~~~~~~~~
+  let unused a: X* = &(reference as X);
+  // CHECK:STDERR: fail_cannot_remove_const.carbon:[[@LINE+7]]:22: error: cannot convert expression of type `const X*` to `X*` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused b: X* = ptr as X*;
+  // CHECK:STDERR:                      ^~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_const.carbon:[[@LINE+4]]:22: note: type `const X*` does not implement interface `Core.As(X*)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused b: X* = ptr as X*;
+  // CHECK:STDERR:                      ^~~~~~~~~
   // CHECK:STDERR:
-  let b: X* = ptr as X*;
+  let unused b: X* = ptr as X*;
 }
 
 // --- unsafe_remove_const.carbon
@@ -87,8 +87,8 @@ let ptr: const X* = &reference;
 
 fn Use() {
   //@dump-sem-ir-begin
-  let a: X* = &(reference unsafe as X);
-  let b: X* = ptr unsafe as X*;
+  let unused a: X* = &(reference unsafe as X);
+  let unused b: X* = ptr unsafe as X*;
   //@dump-sem-ir-end
 }
 
@@ -123,59 +123,59 @@ fn Use() {
 // CHECK:STDOUT:   %Init.ref: %Init.type = name_ref Init, file.%Init.decl [concrete = constants.%Init]
 // CHECK:STDOUT:   %.loc14_3: ref %const = splice_block %i.var {}
 // CHECK:STDOUT:   %Init.call: init %X to %.loc14_3 = call %Init.ref()
-// CHECK:STDOUT:   %X.ref.loc14_36: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %const.loc14_30: type = const_type %X.ref.loc14_36 [concrete = constants.%const]
-// CHECK:STDOUT:   %.loc14_27.1: init %const = as_compatible %Init.call
-// CHECK:STDOUT:   %.loc14_27.2: init %const = converted %Init.call, %.loc14_27.1
-// CHECK:STDOUT:   assign %i.var, %.loc14_27.2
-// CHECK:STDOUT:   %.loc14_10: type = splice_block %const.loc14_10 [concrete = constants.%const] {
-// CHECK:STDOUT:     %X.ref.loc14_16: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %const.loc14_10: type = const_type %X.ref.loc14_16 [concrete = constants.%const]
+// CHECK:STDOUT:   %X.ref.loc14_43: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %const.loc14_37: type = const_type %X.ref.loc14_43 [concrete = constants.%const]
+// CHECK:STDOUT:   %.loc14_34.1: init %const = as_compatible %Init.call
+// CHECK:STDOUT:   %.loc14_34.2: init %const = converted %Init.call, %.loc14_34.1
+// CHECK:STDOUT:   assign %i.var, %.loc14_34.2
+// CHECK:STDOUT:   %.loc14_17: type = splice_block %const.loc14_17 [concrete = constants.%const] {
+// CHECK:STDOUT:     %X.ref.loc14_23: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %const.loc14_17: type = const_type %X.ref.loc14_23 [concrete = constants.%const]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %i: ref %const = ref_binding i, %i.var
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %v.patt: %pattern_type.c9e = value_binding_pattern v [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %value.ref: %X = name_ref value, file.%value
-// CHECK:STDOUT:   %X.ref.loc15_35: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %const.loc15_29: type = const_type %X.ref.loc15_35 [concrete = constants.%const]
-// CHECK:STDOUT:   %.loc15_26.1: %const = as_compatible %value.ref
-// CHECK:STDOUT:   %.loc15_26.2: %const = converted %value.ref, %.loc15_26.1
-// CHECK:STDOUT:   %.loc15_10: type = splice_block %const.loc15_10 [concrete = constants.%const] {
-// CHECK:STDOUT:     %X.ref.loc15_16: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %const.loc15_10: type = const_type %X.ref.loc15_16 [concrete = constants.%const]
+// CHECK:STDOUT:   %X.ref.loc15_42: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %const.loc15_36: type = const_type %X.ref.loc15_42 [concrete = constants.%const]
+// CHECK:STDOUT:   %.loc15_33.1: %const = as_compatible %value.ref
+// CHECK:STDOUT:   %.loc15_33.2: %const = converted %value.ref, %.loc15_33.1
+// CHECK:STDOUT:   %.loc15_17: type = splice_block %const.loc15_17 [concrete = constants.%const] {
+// CHECK:STDOUT:     %X.ref.loc15_23: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %const.loc15_17: type = const_type %X.ref.loc15_23 [concrete = constants.%const]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %v: %const = value_binding v, %.loc15_26.2
+// CHECK:STDOUT:   %v: %const = value_binding v, %.loc15_33.2
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %a.patt: %pattern_type.bf1 = value_binding_pattern a [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %reference.ref: ref %X = name_ref reference, file.%reference [concrete = file.%reference.var]
-// CHECK:STDOUT:   %X.ref.loc16_42: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %const.loc16_36: type = const_type %X.ref.loc16_42 [concrete = constants.%const]
-// CHECK:STDOUT:   %.loc16_33.1: ref %const = as_compatible %reference.ref [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %.loc16_33.2: ref %const = converted %reference.ref, %.loc16_33.1 [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %addr: %ptr.d4c = addr_of %.loc16_33.2 [concrete = constants.%addr.160]
-// CHECK:STDOUT:   %.loc16_17: type = splice_block %ptr.loc16 [concrete = constants.%ptr.d4c] {
-// CHECK:STDOUT:     %X.ref.loc16_16: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %const.loc16_10: type = const_type %X.ref.loc16_16 [concrete = constants.%const]
-// CHECK:STDOUT:     %ptr.loc16: type = ptr_type %const.loc16_10 [concrete = constants.%ptr.d4c]
+// CHECK:STDOUT:   %X.ref.loc16_49: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %const.loc16_43: type = const_type %X.ref.loc16_49 [concrete = constants.%const]
+// CHECK:STDOUT:   %.loc16_40.1: ref %const = as_compatible %reference.ref [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %.loc16_40.2: ref %const = converted %reference.ref, %.loc16_40.1 [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %addr: %ptr.d4c = addr_of %.loc16_40.2 [concrete = constants.%addr.160]
+// CHECK:STDOUT:   %.loc16_24: type = splice_block %ptr.loc16 [concrete = constants.%ptr.d4c] {
+// CHECK:STDOUT:     %X.ref.loc16_23: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %const.loc16_17: type = const_type %X.ref.loc16_23 [concrete = constants.%const]
+// CHECK:STDOUT:     %ptr.loc16: type = ptr_type %const.loc16_17 [concrete = constants.%ptr.d4c]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a: %ptr.d4c = value_binding a, %addr
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %b.patt: %pattern_type.bf1 = value_binding_pattern b [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %ptr.ref: %ptr.2a9 = name_ref ptr, file.%ptr.loc9_5
-// CHECK:STDOUT:   %X.ref.loc17_34: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %const.loc17_28: type = const_type %X.ref.loc17_34 [concrete = constants.%const]
-// CHECK:STDOUT:   %ptr.loc17_35: type = ptr_type %const.loc17_28 [concrete = constants.%ptr.d4c]
-// CHECK:STDOUT:   %.loc17_25.1: %ptr.d4c = as_compatible %ptr.ref
-// CHECK:STDOUT:   %.loc17_25.2: %ptr.d4c = converted %ptr.ref, %.loc17_25.1
-// CHECK:STDOUT:   %.loc17_17: type = splice_block %ptr.loc17_17 [concrete = constants.%ptr.d4c] {
-// CHECK:STDOUT:     %X.ref.loc17_16: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %const.loc17_10: type = const_type %X.ref.loc17_16 [concrete = constants.%const]
-// CHECK:STDOUT:     %ptr.loc17_17: type = ptr_type %const.loc17_10 [concrete = constants.%ptr.d4c]
+// CHECK:STDOUT:   %X.ref.loc17_41: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %const.loc17_35: type = const_type %X.ref.loc17_41 [concrete = constants.%const]
+// CHECK:STDOUT:   %ptr.loc17_42: type = ptr_type %const.loc17_35 [concrete = constants.%ptr.d4c]
+// CHECK:STDOUT:   %.loc17_32.1: %ptr.d4c = as_compatible %ptr.ref
+// CHECK:STDOUT:   %.loc17_32.2: %ptr.d4c = converted %ptr.ref, %.loc17_32.1
+// CHECK:STDOUT:   %.loc17_24: type = splice_block %ptr.loc17_24 [concrete = constants.%ptr.d4c] {
+// CHECK:STDOUT:     %X.ref.loc17_23: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %const.loc17_17: type = const_type %X.ref.loc17_23 [concrete = constants.%const]
+// CHECK:STDOUT:     %ptr.loc17_24: type = ptr_type %const.loc17_17 [concrete = constants.%ptr.d4c]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %b: %ptr.d4c = value_binding b, %.loc17_25.2
+// CHECK:STDOUT:   %b: %ptr.d4c = value_binding b, %.loc17_32.2
 // CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %i.var, constants.%DestroyOp
 // CHECK:STDOUT:   %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%i.var)
 // CHECK:STDOUT:   <elided>
@@ -214,21 +214,21 @@ fn Use() {
 // CHECK:STDOUT:   %Init.ref: %Init.type = name_ref Init, file.%Init.decl [concrete = constants.%Init]
 // CHECK:STDOUT:   %.loc12_3: ref %X = splice_block %i.var {}
 // CHECK:STDOUT:   %Init.call: init %const to %.loc12_3 = call %Init.ref()
-// CHECK:STDOUT:   %X.ref.loc12_24: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc12_21.1: init %X = as_compatible %Init.call
-// CHECK:STDOUT:   %.loc12_21.2: init %X = converted %Init.call, %.loc12_21.1
-// CHECK:STDOUT:   assign %i.var, %.loc12_21.2
-// CHECK:STDOUT:   %X.ref.loc12_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc12_31: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc12_28.1: init %X = as_compatible %Init.call
+// CHECK:STDOUT:   %.loc12_28.2: init %X = converted %Init.call, %.loc12_28.1
+// CHECK:STDOUT:   assign %i.var, %.loc12_28.2
+// CHECK:STDOUT:   %X.ref.loc12_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:   %i: ref %X = ref_binding i, %i.var
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %v.patt: %pattern_type.05f = value_binding_pattern v [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %value.ref: %const = name_ref value, file.%value
-// CHECK:STDOUT:   %X.ref.loc13_23: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc13_20.1: %X = as_compatible %value.ref
-// CHECK:STDOUT:   %.loc13_20.2: %X = converted %value.ref, %.loc13_20.1
-// CHECK:STDOUT:   %X.ref.loc13_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %v: %X = value_binding v, %.loc13_20.2
+// CHECK:STDOUT:   %X.ref.loc13_30: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc13_27.1: %X = as_compatible %value.ref
+// CHECK:STDOUT:   %.loc13_27.2: %X = converted %value.ref, %.loc13_27.1
+// CHECK:STDOUT:   %X.ref.loc13_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %v: %X = value_binding v, %.loc13_27.2
 // CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %i.var, constants.%DestroyOp
 // CHECK:STDOUT:   %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%i.var)
 // CHECK:STDOUT:   <elided>
@@ -262,28 +262,28 @@ fn Use() {
 // CHECK:STDOUT:     %a.patt: %pattern_type.37f = value_binding_pattern a [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %reference.ref: ref %const = name_ref reference, file.%reference [concrete = file.%reference.var]
-// CHECK:STDOUT:   %X.ref.loc11_37: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc11_34.1: ref %X = as_compatible %reference.ref [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %.loc11_34.2: ref %X = converted %reference.ref, %.loc11_34.1 [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %addr: %ptr.2a9 = addr_of %.loc11_34.2 [concrete = constants.%addr.806]
-// CHECK:STDOUT:   %.loc11_11: type = splice_block %ptr.loc11 [concrete = constants.%ptr.2a9] {
-// CHECK:STDOUT:     %X.ref.loc11_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %ptr.loc11: type = ptr_type %X.ref.loc11_10 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %X.ref.loc11_44: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc11_41.1: ref %X = as_compatible %reference.ref [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %.loc11_41.2: ref %X = converted %reference.ref, %.loc11_41.1 [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %addr: %ptr.2a9 = addr_of %.loc11_41.2 [concrete = constants.%addr.806]
+// CHECK:STDOUT:   %.loc11_18: type = splice_block %ptr.loc11 [concrete = constants.%ptr.2a9] {
+// CHECK:STDOUT:     %X.ref.loc11_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %ptr.loc11: type = ptr_type %X.ref.loc11_17 [concrete = constants.%ptr.2a9]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a: %ptr.2a9 = value_binding a, %addr
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %b.patt: %pattern_type.37f = value_binding_pattern b [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %ptr.ref: %ptr.d4c = name_ref ptr, file.%ptr.loc7_5
-// CHECK:STDOUT:   %X.ref.loc12_29: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %ptr.loc12_30: type = ptr_type %X.ref.loc12_29 [concrete = constants.%ptr.2a9]
-// CHECK:STDOUT:   %.loc12_26.1: %ptr.2a9 = as_compatible %ptr.ref
-// CHECK:STDOUT:   %.loc12_26.2: %ptr.2a9 = converted %ptr.ref, %.loc12_26.1
-// CHECK:STDOUT:   %.loc12_11: type = splice_block %ptr.loc12_11 [concrete = constants.%ptr.2a9] {
-// CHECK:STDOUT:     %X.ref.loc12_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %ptr.loc12_11: type = ptr_type %X.ref.loc12_10 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %X.ref.loc12_36: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %ptr.loc12_37: type = ptr_type %X.ref.loc12_36 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %.loc12_33.1: %ptr.2a9 = as_compatible %ptr.ref
+// CHECK:STDOUT:   %.loc12_33.2: %ptr.2a9 = converted %ptr.ref, %.loc12_33.1
+// CHECK:STDOUT:   %.loc12_18: type = splice_block %ptr.loc12_18 [concrete = constants.%ptr.2a9] {
+// CHECK:STDOUT:     %X.ref.loc12_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %ptr.loc12_18: type = ptr_type %X.ref.loc12_17 [concrete = constants.%ptr.2a9]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %b: %ptr.2a9 = value_binding b, %.loc12_26.2
+// CHECK:STDOUT:   %b: %ptr.2a9 = value_binding b, %.loc12_33.2
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 123 - 123
toolchain/check/testdata/as/maybe_unformed.carbon

@@ -22,8 +22,8 @@ let ptr: X* = &reference;
 fn Use() {
   // TODO: Should some of these be valid without the `as`?
   //@dump-sem-ir-begin
-  let a: Core.MaybeUnformed(X)* = &(reference as Core.MaybeUnformed(X));
-  let b: Core.MaybeUnformed(X)* = ptr as Core.MaybeUnformed(X)*;
+  let unused a: Core.MaybeUnformed(X)* = &(reference as Core.MaybeUnformed(X));
+  let unused b: Core.MaybeUnformed(X)* = ptr as Core.MaybeUnformed(X)*;
   //@dump-sem-ir-end
 }
 
@@ -39,22 +39,22 @@ let value: X = Init();
 fn Use() {
   // TODO: These should probably be valid.
   //@dump-sem-ir-begin
-  // CHECK:STDERR: fail_todo_add_unformed_nonref.carbon:[[@LINE+7]]:34: error: cannot convert expression of type `X` to `Core.MaybeUnformed(X)` with `as` [ConversionFailure]
-  // CHECK:STDERR:   var i: Core.MaybeUnformed(X) = Init() as Core.MaybeUnformed(X);
-  // CHECK:STDERR:                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_todo_add_unformed_nonref.carbon:[[@LINE+4]]:34: note: type `X` does not implement interface `Core.As(Core.MaybeUnformed(X))` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   var i: Core.MaybeUnformed(X) = Init() as Core.MaybeUnformed(X);
-  // CHECK:STDERR:                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_add_unformed_nonref.carbon:[[@LINE+7]]:41: error: cannot convert expression of type `X` to `Core.MaybeUnformed(X)` with `as` [ConversionFailure]
+  // CHECK:STDERR:   var unused i: Core.MaybeUnformed(X) = Init() as Core.MaybeUnformed(X);
+  // CHECK:STDERR:                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_add_unformed_nonref.carbon:[[@LINE+4]]:41: note: type `X` does not implement interface `Core.As(Core.MaybeUnformed(X))` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   var unused i: Core.MaybeUnformed(X) = Init() as Core.MaybeUnformed(X);
+  // CHECK:STDERR:                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var i: Core.MaybeUnformed(X) = Init() as Core.MaybeUnformed(X);
-  // CHECK:STDERR: fail_todo_add_unformed_nonref.carbon:[[@LINE+7]]:34: error: cannot convert expression of type `X` to `Core.MaybeUnformed(X)` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let v: Core.MaybeUnformed(X) = value as Core.MaybeUnformed(X);
-  // CHECK:STDERR:                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_todo_add_unformed_nonref.carbon:[[@LINE+4]]:34: note: type `X` does not implement interface `Core.As(Core.MaybeUnformed(X))` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let v: Core.MaybeUnformed(X) = value as Core.MaybeUnformed(X);
-  // CHECK:STDERR:                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  var unused i: Core.MaybeUnformed(X) = Init() as Core.MaybeUnformed(X);
+  // CHECK:STDERR: fail_todo_add_unformed_nonref.carbon:[[@LINE+7]]:41: error: cannot convert expression of type `X` to `Core.MaybeUnformed(X)` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused v: Core.MaybeUnformed(X) = value as Core.MaybeUnformed(X);
+  // CHECK:STDERR:                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_add_unformed_nonref.carbon:[[@LINE+4]]:41: note: type `X` does not implement interface `Core.As(Core.MaybeUnformed(X))` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused v: Core.MaybeUnformed(X) = value as Core.MaybeUnformed(X);
+  // CHECK:STDERR:                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let v: Core.MaybeUnformed(X) = value as Core.MaybeUnformed(X);
+  let unused v: Core.MaybeUnformed(X) = value as Core.MaybeUnformed(X);
   //@dump-sem-ir-end
 }
 
@@ -70,48 +70,48 @@ var reference: Core.MaybeUnformed(X);
 let ptr: Core.MaybeUnformed(X)* = &reference;
 
 fn Use() {
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:14: error: cannot convert expression of type `Core.MaybeUnformed(X)` to `X` with `as` [ConversionFailure]
-  // CHECK:STDERR:   var i: X = Init() as X;
-  // CHECK:STDERR:              ^~~~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:14: note: type `Core.MaybeUnformed(X)` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   var i: X = Init() as X;
-  // CHECK:STDERR:              ^~~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:21: error: cannot convert expression of type `Core.MaybeUnformed(X)` to `X` with `as` [ConversionFailure]
+  // CHECK:STDERR:   var unused i: X = Init() as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:21: note: type `Core.MaybeUnformed(X)` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   var unused i: X = Init() as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~~
   // CHECK:STDERR:
-  var i: X = Init() as X;
+  var unused i: X = Init() as X;
   // TODO: The diagnostic should explain that the reason we can't perform this
   // conversion is due to the expression category.
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:14: error: cannot convert expression of type `Core.MaybeUnformed(X)` to `X` with `unsafe as` [ConversionFailure]
-  // CHECK:STDERR:   var j: X = Init() unsafe as X;
-  // CHECK:STDERR:              ^~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:14: note: type `Core.MaybeUnformed(X)` does not implement interface `Core.UnsafeAs(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   var j: X = Init() unsafe as X;
-  // CHECK:STDERR:              ^~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:21: error: cannot convert expression of type `Core.MaybeUnformed(X)` to `X` with `unsafe as` [ConversionFailure]
+  // CHECK:STDERR:   var unused j: X = Init() unsafe as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:21: note: type `Core.MaybeUnformed(X)` does not implement interface `Core.UnsafeAs(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   var unused j: X = Init() unsafe as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var j: X = Init() unsafe as X;
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:14: error: cannot convert expression of type `Core.MaybeUnformed(X)` to `X` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let v: X = value as X;
-  // CHECK:STDERR:              ^~~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:14: note: type `Core.MaybeUnformed(X)` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let v: X = value as X;
-  // CHECK:STDERR:              ^~~~~~~~~~
+  var unused j: X = Init() unsafe as X;
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:21: error: cannot convert expression of type `Core.MaybeUnformed(X)` to `X` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused v: X = value as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:21: note: type `Core.MaybeUnformed(X)` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused v: X = value as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~
   // CHECK:STDERR:
-  let v: X = value as X;
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:17: error: cannot convert expression of type `Core.MaybeUnformed(X)` to `X` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let a: X* = &(reference as X);
-  // CHECK:STDERR:                 ^~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:17: note: type `Core.MaybeUnformed(X)` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let a: X* = &(reference as X);
-  // CHECK:STDERR:                 ^~~~~~~~~~~~~~
+  let unused v: X = value as X;
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:24: error: cannot convert expression of type `Core.MaybeUnformed(X)` to `X` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused a: X* = &(reference as X);
+  // CHECK:STDERR:                        ^~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:24: note: type `Core.MaybeUnformed(X)` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused a: X* = &(reference as X);
+  // CHECK:STDERR:                        ^~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let a: X* = &(reference as X);
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:15: error: cannot convert expression of type `Core.MaybeUnformed(X)*` to `X*` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let b: X* = ptr as X*;
-  // CHECK:STDERR:               ^~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:15: note: type `Core.MaybeUnformed(X)*` does not implement interface `Core.As(X*)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let b: X* = ptr as X*;
-  // CHECK:STDERR:               ^~~~~~~~~
+  let unused a: X* = &(reference as X);
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+7]]:22: error: cannot convert expression of type `Core.MaybeUnformed(X)*` to `X*` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused b: X* = ptr as X*;
+  // CHECK:STDERR:                      ^~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_unformed.carbon:[[@LINE+4]]:22: note: type `Core.MaybeUnformed(X)*` does not implement interface `Core.As(X*)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused b: X* = ptr as X*;
+  // CHECK:STDERR:                      ^~~~~~~~~
   // CHECK:STDERR:
-  let b: X* = ptr as X*;
+  let unused b: X* = ptr as X*;
 }
 
 // --- unsafe_remove_unformed.carbon
@@ -127,9 +127,9 @@ let ptr: Core.MaybeUnformed(X)* = &reference;
 
 fn Use() {
   //@dump-sem-ir-begin
-  let v: X = value unsafe as X;
-  let a: X* = &(reference unsafe as X);
-  let b: X* = ptr unsafe as X*;
+  let unused v: X = value unsafe as X;
+  let unused a: X* = &(reference unsafe as X);
+  let unused b: X* = ptr unsafe as X*;
   //@dump-sem-ir-end
 }
 
@@ -162,40 +162,40 @@ fn Use() {
 // CHECK:STDOUT:     %a.patt: %pattern_type.396 = value_binding_pattern a [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %reference.ref: ref %X = name_ref reference, file.%reference [concrete = file.%reference.var]
-// CHECK:STDOUT:   %Core.ref.loc12_50: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:   %MaybeUnformed.ref.loc12_54: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
-// CHECK:STDOUT:   %X.ref.loc12_69: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %MaybeUnformed.loc12_70: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
-// CHECK:STDOUT:   %.loc12_47.1: ref %MaybeUnformed.b49 = as_compatible %reference.ref [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %.loc12_47.2: ref %MaybeUnformed.b49 = converted %reference.ref, %.loc12_47.1 [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %addr: %ptr.045 = addr_of %.loc12_47.2 [concrete = constants.%addr.25c]
-// CHECK:STDOUT:   %.loc12_31: type = splice_block %ptr.loc12 [concrete = constants.%ptr.045] {
-// CHECK:STDOUT:     %Core.ref.loc12_10: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:     %MaybeUnformed.ref.loc12_14: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
-// CHECK:STDOUT:     %X.ref.loc12_29: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %MaybeUnformed.loc12_30: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
-// CHECK:STDOUT:     %ptr.loc12: type = ptr_type %MaybeUnformed.loc12_30 [concrete = constants.%ptr.045]
+// CHECK:STDOUT:   %Core.ref.loc12_57: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:   %MaybeUnformed.ref.loc12_61: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
+// CHECK:STDOUT:   %X.ref.loc12_76: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %MaybeUnformed.loc12_77: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
+// CHECK:STDOUT:   %.loc12_54.1: ref %MaybeUnformed.b49 = as_compatible %reference.ref [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %.loc12_54.2: ref %MaybeUnformed.b49 = converted %reference.ref, %.loc12_54.1 [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %addr: %ptr.045 = addr_of %.loc12_54.2 [concrete = constants.%addr.25c]
+// CHECK:STDOUT:   %.loc12_38: type = splice_block %ptr.loc12 [concrete = constants.%ptr.045] {
+// CHECK:STDOUT:     %Core.ref.loc12_17: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:     %MaybeUnformed.ref.loc12_21: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
+// CHECK:STDOUT:     %X.ref.loc12_36: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %MaybeUnformed.loc12_37: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
+// CHECK:STDOUT:     %ptr.loc12: type = ptr_type %MaybeUnformed.loc12_37 [concrete = constants.%ptr.045]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a: %ptr.045 = value_binding a, %addr
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %b.patt: %pattern_type.396 = value_binding_pattern b [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %ptr.ref: %ptr.2a9 = name_ref ptr, file.%ptr.loc7_5
-// CHECK:STDOUT:   %Core.ref.loc13_42: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:   %MaybeUnformed.ref.loc13_46: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
-// CHECK:STDOUT:   %X.ref.loc13_61: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %MaybeUnformed.loc13_62: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
-// CHECK:STDOUT:   %ptr.loc13_63: type = ptr_type %MaybeUnformed.loc13_62 [concrete = constants.%ptr.045]
-// CHECK:STDOUT:   %.loc13_39.1: %ptr.045 = as_compatible %ptr.ref
-// CHECK:STDOUT:   %.loc13_39.2: %ptr.045 = converted %ptr.ref, %.loc13_39.1
-// CHECK:STDOUT:   %.loc13_31: type = splice_block %ptr.loc13_31 [concrete = constants.%ptr.045] {
-// CHECK:STDOUT:     %Core.ref.loc13_10: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:     %MaybeUnformed.ref.loc13_14: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
-// CHECK:STDOUT:     %X.ref.loc13_29: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %MaybeUnformed.loc13_30: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
-// CHECK:STDOUT:     %ptr.loc13_31: type = ptr_type %MaybeUnformed.loc13_30 [concrete = constants.%ptr.045]
+// CHECK:STDOUT:   %Core.ref.loc13_49: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:   %MaybeUnformed.ref.loc13_53: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
+// CHECK:STDOUT:   %X.ref.loc13_68: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %MaybeUnformed.loc13_69: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
+// CHECK:STDOUT:   %ptr.loc13_70: type = ptr_type %MaybeUnformed.loc13_69 [concrete = constants.%ptr.045]
+// CHECK:STDOUT:   %.loc13_46.1: %ptr.045 = as_compatible %ptr.ref
+// CHECK:STDOUT:   %.loc13_46.2: %ptr.045 = converted %ptr.ref, %.loc13_46.1
+// CHECK:STDOUT:   %.loc13_38: type = splice_block %ptr.loc13_38 [concrete = constants.%ptr.045] {
+// CHECK:STDOUT:     %Core.ref.loc13_17: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:     %MaybeUnformed.ref.loc13_21: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
+// CHECK:STDOUT:     %X.ref.loc13_36: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %MaybeUnformed.loc13_37: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
+// CHECK:STDOUT:     %ptr.loc13_38: type = ptr_type %MaybeUnformed.loc13_37 [concrete = constants.%ptr.045]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %b: %ptr.045 = value_binding b, %.loc13_39.2
+// CHECK:STDOUT:   %b: %ptr.045 = value_binding b, %.loc13_46.2
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -243,35 +243,35 @@ fn Use() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %i.var: ref %MaybeUnformed.b49 = var %i.var_patt
 // CHECK:STDOUT:   %Init.ref: %Init.type = name_ref Init, file.%Init.decl [concrete = constants.%Init]
-// CHECK:STDOUT:   %.loc19_39: ref %X = temporary_storage
-// CHECK:STDOUT:   %Init.call: init %X to %.loc19_39 = call %Init.ref()
-// CHECK:STDOUT:   %Core.ref.loc19_44: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:   %MaybeUnformed.ref.loc19_48: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
-// CHECK:STDOUT:   %X.ref.loc19_63: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %MaybeUnformed.loc19_64: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
-// CHECK:STDOUT:   %.loc19_41: %MaybeUnformed.b49 = converted %Init.call, <error> [concrete = <error>]
+// CHECK:STDOUT:   %.loc19_46: ref %X = temporary_storage
+// CHECK:STDOUT:   %Init.call: init %X to %.loc19_46 = call %Init.ref()
+// CHECK:STDOUT:   %Core.ref.loc19_51: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:   %MaybeUnformed.ref.loc19_55: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
+// CHECK:STDOUT:   %X.ref.loc19_70: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %MaybeUnformed.loc19_71: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
+// CHECK:STDOUT:   %.loc19_48: %MaybeUnformed.b49 = converted %Init.call, <error> [concrete = <error>]
 // CHECK:STDOUT:   assign %i.var, <error>
-// CHECK:STDOUT:   %.loc19_30: type = splice_block %MaybeUnformed.loc19_30 [concrete = constants.%MaybeUnformed.b49] {
-// CHECK:STDOUT:     %Core.ref.loc19_10: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:     %MaybeUnformed.ref.loc19_14: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
-// CHECK:STDOUT:     %X.ref.loc19_29: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %MaybeUnformed.loc19_30: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
+// CHECK:STDOUT:   %.loc19_37: type = splice_block %MaybeUnformed.loc19_37 [concrete = constants.%MaybeUnformed.b49] {
+// CHECK:STDOUT:     %Core.ref.loc19_17: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:     %MaybeUnformed.ref.loc19_21: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
+// CHECK:STDOUT:     %X.ref.loc19_36: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %MaybeUnformed.loc19_37: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %i: ref %MaybeUnformed.b49 = ref_binding i, %i.var
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %v.patt: %pattern_type.de9 = value_binding_pattern v [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %value.ref: %X = name_ref value, file.%value
-// CHECK:STDOUT:   %Core.ref.loc27_43: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:   %MaybeUnformed.ref.loc27_47: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
-// CHECK:STDOUT:   %X.ref.loc27_62: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %MaybeUnformed.loc27_63: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
-// CHECK:STDOUT:   %.loc27_40: %MaybeUnformed.b49 = converted %value.ref, <error> [concrete = <error>]
-// CHECK:STDOUT:   %.loc27_30: type = splice_block %MaybeUnformed.loc27_30 [concrete = constants.%MaybeUnformed.b49] {
-// CHECK:STDOUT:     %Core.ref.loc27_10: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:     %MaybeUnformed.ref.loc27_14: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
-// CHECK:STDOUT:     %X.ref.loc27_29: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %MaybeUnformed.loc27_30: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
+// CHECK:STDOUT:   %Core.ref.loc27_50: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:   %MaybeUnformed.ref.loc27_54: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
+// CHECK:STDOUT:   %X.ref.loc27_69: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %MaybeUnformed.loc27_70: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
+// CHECK:STDOUT:   %.loc27_47: %MaybeUnformed.b49 = converted %value.ref, <error> [concrete = <error>]
+// CHECK:STDOUT:   %.loc27_37: type = splice_block %MaybeUnformed.loc27_37 [concrete = constants.%MaybeUnformed.b49] {
+// CHECK:STDOUT:     %Core.ref.loc27_17: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:     %MaybeUnformed.ref.loc27_21: %MaybeUnformed.type = name_ref MaybeUnformed, imports.%Core.MaybeUnformed [concrete = constants.%MaybeUnformed.generic]
+// CHECK:STDOUT:     %X.ref.loc27_36: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %MaybeUnformed.loc27_37: type = class_type @MaybeUnformed, @MaybeUnformed(constants.%X) [concrete = constants.%MaybeUnformed.b49]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v: %MaybeUnformed.b49 = value_binding v, <error> [concrete = <error>]
 // CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %i.var, constants.%DestroyOp
@@ -308,37 +308,37 @@ fn Use() {
 // CHECK:STDOUT:     %v.patt: %pattern_type.05f = value_binding_pattern v [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %value.ref: %MaybeUnformed.b49 = name_ref value, file.%value
-// CHECK:STDOUT:   %X.ref.loc13_30: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc13_27.1: %X = as_compatible %value.ref
-// CHECK:STDOUT:   %.loc13_27.2: %X = converted %value.ref, %.loc13_27.1
-// CHECK:STDOUT:   %X.ref.loc13_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %v: %X = value_binding v, %.loc13_27.2
+// CHECK:STDOUT:   %X.ref.loc13_37: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc13_34.1: %X = as_compatible %value.ref
+// CHECK:STDOUT:   %.loc13_34.2: %X = converted %value.ref, %.loc13_34.1
+// CHECK:STDOUT:   %X.ref.loc13_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %v: %X = value_binding v, %.loc13_34.2
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %a.patt: %pattern_type.37f = value_binding_pattern a [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %reference.ref: ref %MaybeUnformed.b49 = name_ref reference, file.%reference [concrete = file.%reference.var]
-// CHECK:STDOUT:   %X.ref.loc14_37: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc14_34.1: ref %X = as_compatible %reference.ref [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %.loc14_34.2: ref %X = converted %reference.ref, %.loc14_34.1 [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %addr: %ptr.2a9 = addr_of %.loc14_34.2 [concrete = constants.%addr.6f7]
-// CHECK:STDOUT:   %.loc14_11: type = splice_block %ptr.loc14 [concrete = constants.%ptr.2a9] {
-// CHECK:STDOUT:     %X.ref.loc14_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %ptr.loc14: type = ptr_type %X.ref.loc14_10 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %X.ref.loc14_44: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc14_41.1: ref %X = as_compatible %reference.ref [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %.loc14_41.2: ref %X = converted %reference.ref, %.loc14_41.1 [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %addr: %ptr.2a9 = addr_of %.loc14_41.2 [concrete = constants.%addr.6f7]
+// CHECK:STDOUT:   %.loc14_18: type = splice_block %ptr.loc14 [concrete = constants.%ptr.2a9] {
+// CHECK:STDOUT:     %X.ref.loc14_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %ptr.loc14: type = ptr_type %X.ref.loc14_17 [concrete = constants.%ptr.2a9]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a: %ptr.2a9 = value_binding a, %addr
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %b.patt: %pattern_type.37f = value_binding_pattern b [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %ptr.ref: %ptr.045 = name_ref ptr, file.%ptr.loc9_5
-// CHECK:STDOUT:   %X.ref.loc15_29: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %ptr.loc15_30: type = ptr_type %X.ref.loc15_29 [concrete = constants.%ptr.2a9]
-// CHECK:STDOUT:   %.loc15_26.1: %ptr.2a9 = as_compatible %ptr.ref
-// CHECK:STDOUT:   %.loc15_26.2: %ptr.2a9 = converted %ptr.ref, %.loc15_26.1
-// CHECK:STDOUT:   %.loc15_11: type = splice_block %ptr.loc15_11 [concrete = constants.%ptr.2a9] {
-// CHECK:STDOUT:     %X.ref.loc15_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %ptr.loc15_11: type = ptr_type %X.ref.loc15_10 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %X.ref.loc15_36: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %ptr.loc15_37: type = ptr_type %X.ref.loc15_36 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %.loc15_33.1: %ptr.2a9 = as_compatible %ptr.ref
+// CHECK:STDOUT:   %.loc15_33.2: %ptr.2a9 = converted %ptr.ref, %.loc15_33.1
+// CHECK:STDOUT:   %.loc15_18: type = splice_block %ptr.loc15_18 [concrete = constants.%ptr.2a9] {
+// CHECK:STDOUT:     %X.ref.loc15_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %ptr.loc15_18: type = ptr_type %X.ref.loc15_17 [concrete = constants.%ptr.2a9]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %b: %ptr.2a9 = value_binding b, %.loc15_26.2
+// CHECK:STDOUT:   %b: %ptr.2a9 = value_binding b, %.loc15_33.2
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 114 - 114
toolchain/check/testdata/as/partial.carbon

@@ -24,10 +24,10 @@ let ptr: X* = &reference;
 fn Use() {
   // TODO: Should some of these be valid without the `as`?
   //@dump-sem-ir-begin
-  var i: partial X = Init() as partial X;
-  let v: partial X = value as partial X;
-  let a: partial X* = &(reference as partial X);
-  let b: partial X* = ptr as partial X*;
+  var unused i: partial X = Init() as partial X;
+  let unused v: partial X = value as partial X;
+  let unused a: partial X* = &(reference as partial X);
+  let unused b: partial X* = ptr as partial X*;
   //@dump-sem-ir-end
 }
 
@@ -43,29 +43,29 @@ fn Use() {
   //@dump-sem-ir-begin
   // TODO: This should be valid, and should initialize the vptr. The explicit `as` should probably not be necessary.
   // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+7]]:3: error: cannot implicitly convert expression of type `partial X` to `X` [ConversionFailure]
-  // CHECK:STDERR:   var i: X = Init();
-  // CHECK:STDERR:   ^~~~~~~~
+  // CHECK:STDERR:   var unused i: X = Init();
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+4]]:3: note: type `partial X` does not implement interface `Core.ImplicitAs(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   var i: X = Init();
-  // CHECK:STDERR:   ^~~~~~~~
+  // CHECK:STDERR:   var unused i: X = Init();
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var i: X = Init();
-  // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+7]]:14: error: cannot convert expression of type `partial X` to `X` with `as` [ConversionFailure]
-  // CHECK:STDERR:   var j: X = Init() as X;
-  // CHECK:STDERR:              ^~~~~~~~~~~
-  // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+4]]:14: note: type `partial X` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   var j: X = Init() as X;
-  // CHECK:STDERR:              ^~~~~~~~~~~
+  var unused i: X = Init();
+  // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+7]]:21: error: cannot convert expression of type `partial X` to `X` with `as` [ConversionFailure]
+  // CHECK:STDERR:   var unused j: X = Init() as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+4]]:21: note: type `partial X` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   var unused j: X = Init() as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~~
   // CHECK:STDERR:
-  var j: X = Init() as X;
-  // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+7]]:14: error: cannot convert expression of type `partial X` to `X` with `unsafe as` [ConversionFailure]
-  // CHECK:STDERR:   var k: X = Init() unsafe as X;
-  // CHECK:STDERR:              ^~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+4]]:14: note: type `partial X` does not implement interface `Core.UnsafeAs(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   var k: X = Init() unsafe as X;
-  // CHECK:STDERR:              ^~~~~~~~~~~~~~~~~~
+  var unused j: X = Init() as X;
+  // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+7]]:21: error: cannot convert expression of type `partial X` to `X` with `unsafe as` [ConversionFailure]
+  // CHECK:STDERR:   var unused k: X = Init() unsafe as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_remove_partial_in_init.carbon:[[@LINE+4]]:21: note: type `partial X` does not implement interface `Core.UnsafeAs(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   var unused k: X = Init() unsafe as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var k: X = Init() unsafe as X;
+  var unused k: X = Init() unsafe as X;
   //@dump-sem-ir-end
 }
 
@@ -82,30 +82,30 @@ var reference: partial X;
 let ptr: partial X* = &reference;
 
 fn Use() {
-  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+7]]:14: error: cannot convert expression of type `partial X` to `X` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let v: X = value as X;
-  // CHECK:STDERR:              ^~~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+4]]:14: note: type `partial X` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let v: X = value as X;
-  // CHECK:STDERR:              ^~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+7]]:21: error: cannot convert expression of type `partial X` to `X` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused v: X = value as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+4]]:21: note: type `partial X` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused v: X = value as X;
+  // CHECK:STDERR:                     ^~~~~~~~~~
   // CHECK:STDERR:
-  let v: X = value as X;
-  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+7]]:17: error: cannot convert expression of type `partial X` to `X` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let a: X* = &(reference as X);
-  // CHECK:STDERR:                 ^~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+4]]:17: note: type `partial X` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let a: X* = &(reference as X);
-  // CHECK:STDERR:                 ^~~~~~~~~~~~~~
+  let unused v: X = value as X;
+  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+7]]:24: error: cannot convert expression of type `partial X` to `X` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused a: X* = &(reference as X);
+  // CHECK:STDERR:                        ^~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+4]]:24: note: type `partial X` does not implement interface `Core.As(X)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused a: X* = &(reference as X);
+  // CHECK:STDERR:                        ^~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let a: X* = &(reference as X);
-  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+7]]:15: error: cannot convert expression of type `partial X*` to `X*` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let b: X* = ptr as X*;
-  // CHECK:STDERR:               ^~~~~~~~~
-  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+4]]:15: note: type `partial X*` does not implement interface `Core.As(X*)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let b: X* = ptr as X*;
-  // CHECK:STDERR:               ^~~~~~~~~
+  let unused a: X* = &(reference as X);
+  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+7]]:22: error: cannot convert expression of type `partial X*` to `X*` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused b: X* = ptr as X*;
+  // CHECK:STDERR:                      ^~~~~~~~~
+  // CHECK:STDERR: fail_cannot_remove_partial.carbon:[[@LINE+4]]:22: note: type `partial X*` does not implement interface `Core.As(X*)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused b: X* = ptr as X*;
+  // CHECK:STDERR:                      ^~~~~~~~~
   // CHECK:STDERR:
-  let b: X* = ptr as X*;
+  let unused b: X* = ptr as X*;
 }
 
 // --- unsafe_remove_partial.carbon
@@ -122,9 +122,9 @@ let ptr: partial X* = &reference;
 
 fn Use() {
   //@dump-sem-ir-begin
-  let v: X = value unsafe as X;
-  let a: X* = &(reference unsafe as X);
-  let b: X* = ptr unsafe as X*;
+  let unused v: X = value unsafe as X;
+  let unused a: X* = &(reference unsafe as X);
+  let unused b: X* = ptr unsafe as X*;
   //@dump-sem-ir-end
 }
 
@@ -159,59 +159,59 @@ fn Use() {
 // CHECK:STDOUT:   %Init.ref: %Init.type = name_ref Init, file.%Init.decl [concrete = constants.%Init]
 // CHECK:STDOUT:   %.loc14_3: ref %.4b5 = splice_block %i.var {}
 // CHECK:STDOUT:   %Init.call: init %X to %.loc14_3 = call %Init.ref()
-// CHECK:STDOUT:   %X.ref.loc14_40: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc14_32: type = partial_type %X.ref.loc14_40 [concrete = constants.%.4b5]
-// CHECK:STDOUT:   %.loc14_29.1: init %.4b5 = as_compatible %Init.call
-// CHECK:STDOUT:   %.loc14_29.2: init %.4b5 = converted %Init.call, %.loc14_29.1
-// CHECK:STDOUT:   assign %i.var, %.loc14_29.2
-// CHECK:STDOUT:   %.loc14_10.1: type = splice_block %.loc14_10.2 [concrete = constants.%.4b5] {
-// CHECK:STDOUT:     %X.ref.loc14_18: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %.loc14_10.2: type = partial_type %X.ref.loc14_18 [concrete = constants.%.4b5]
+// CHECK:STDOUT:   %X.ref.loc14_47: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc14_39: type = partial_type %X.ref.loc14_47 [concrete = constants.%.4b5]
+// CHECK:STDOUT:   %.loc14_36.1: init %.4b5 = as_compatible %Init.call
+// CHECK:STDOUT:   %.loc14_36.2: init %.4b5 = converted %Init.call, %.loc14_36.1
+// CHECK:STDOUT:   assign %i.var, %.loc14_36.2
+// CHECK:STDOUT:   %.loc14_17.1: type = splice_block %.loc14_17.2 [concrete = constants.%.4b5] {
+// CHECK:STDOUT:     %X.ref.loc14_25: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %.loc14_17.2: type = partial_type %X.ref.loc14_25 [concrete = constants.%.4b5]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %i: ref %.4b5 = ref_binding i, %i.var
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %v.patt: %pattern_type.bc5 = value_binding_pattern v [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %value.ref: %X = name_ref value, file.%value
-// CHECK:STDOUT:   %X.ref.loc15_39: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc15_31: type = partial_type %X.ref.loc15_39 [concrete = constants.%.4b5]
-// CHECK:STDOUT:   %.loc15_28.1: %.4b5 = as_compatible %value.ref
-// CHECK:STDOUT:   %.loc15_28.2: %.4b5 = converted %value.ref, %.loc15_28.1
-// CHECK:STDOUT:   %.loc15_10.1: type = splice_block %.loc15_10.2 [concrete = constants.%.4b5] {
-// CHECK:STDOUT:     %X.ref.loc15_18: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %.loc15_10.2: type = partial_type %X.ref.loc15_18 [concrete = constants.%.4b5]
+// CHECK:STDOUT:   %X.ref.loc15_46: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc15_38: type = partial_type %X.ref.loc15_46 [concrete = constants.%.4b5]
+// CHECK:STDOUT:   %.loc15_35.1: %.4b5 = as_compatible %value.ref
+// CHECK:STDOUT:   %.loc15_35.2: %.4b5 = converted %value.ref, %.loc15_35.1
+// CHECK:STDOUT:   %.loc15_17.1: type = splice_block %.loc15_17.2 [concrete = constants.%.4b5] {
+// CHECK:STDOUT:     %X.ref.loc15_25: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %.loc15_17.2: type = partial_type %X.ref.loc15_25 [concrete = constants.%.4b5]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %v: %.4b5 = value_binding v, %.loc15_28.2
+// CHECK:STDOUT:   %v: %.4b5 = value_binding v, %.loc15_35.2
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %a.patt: %pattern_type.408 = value_binding_pattern a [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %reference.ref: ref %X = name_ref reference, file.%reference [concrete = file.%reference.var]
-// CHECK:STDOUT:   %X.ref.loc16_46: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc16_38: type = partial_type %X.ref.loc16_46 [concrete = constants.%.4b5]
-// CHECK:STDOUT:   %.loc16_35.1: ref %.4b5 = as_compatible %reference.ref [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %.loc16_35.2: ref %.4b5 = converted %reference.ref, %.loc16_35.1 [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %addr: %ptr.314 = addr_of %.loc16_35.2 [concrete = constants.%addr.315]
-// CHECK:STDOUT:   %.loc16_19: type = splice_block %ptr.loc16 [concrete = constants.%ptr.314] {
-// CHECK:STDOUT:     %X.ref.loc16_18: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %.loc16_10: type = partial_type %X.ref.loc16_18 [concrete = constants.%.4b5]
-// CHECK:STDOUT:     %ptr.loc16: type = ptr_type %.loc16_10 [concrete = constants.%ptr.314]
+// CHECK:STDOUT:   %X.ref.loc16_53: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc16_45: type = partial_type %X.ref.loc16_53 [concrete = constants.%.4b5]
+// CHECK:STDOUT:   %.loc16_42.1: ref %.4b5 = as_compatible %reference.ref [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %.loc16_42.2: ref %.4b5 = converted %reference.ref, %.loc16_42.1 [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %addr: %ptr.314 = addr_of %.loc16_42.2 [concrete = constants.%addr.315]
+// CHECK:STDOUT:   %.loc16_26: type = splice_block %ptr.loc16 [concrete = constants.%ptr.314] {
+// CHECK:STDOUT:     %X.ref.loc16_25: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %.loc16_17: type = partial_type %X.ref.loc16_25 [concrete = constants.%.4b5]
+// CHECK:STDOUT:     %ptr.loc16: type = ptr_type %.loc16_17 [concrete = constants.%ptr.314]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a: %ptr.314 = value_binding a, %addr
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %b.patt: %pattern_type.408 = value_binding_pattern b [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %ptr.ref: %ptr.2a9 = name_ref ptr, file.%ptr.loc9_5
-// CHECK:STDOUT:   %X.ref.loc17_38: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc17_30: type = partial_type %X.ref.loc17_38 [concrete = constants.%.4b5]
-// CHECK:STDOUT:   %ptr.loc17_39: type = ptr_type %.loc17_30 [concrete = constants.%ptr.314]
-// CHECK:STDOUT:   %.loc17_27.1: %ptr.314 = as_compatible %ptr.ref
-// CHECK:STDOUT:   %.loc17_27.2: %ptr.314 = converted %ptr.ref, %.loc17_27.1
-// CHECK:STDOUT:   %.loc17_19: type = splice_block %ptr.loc17_19 [concrete = constants.%ptr.314] {
-// CHECK:STDOUT:     %X.ref.loc17_18: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %.loc17_10: type = partial_type %X.ref.loc17_18 [concrete = constants.%.4b5]
-// CHECK:STDOUT:     %ptr.loc17_19: type = ptr_type %.loc17_10 [concrete = constants.%ptr.314]
+// CHECK:STDOUT:   %X.ref.loc17_45: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc17_37: type = partial_type %X.ref.loc17_45 [concrete = constants.%.4b5]
+// CHECK:STDOUT:   %ptr.loc17_46: type = ptr_type %.loc17_37 [concrete = constants.%ptr.314]
+// CHECK:STDOUT:   %.loc17_34.1: %ptr.314 = as_compatible %ptr.ref
+// CHECK:STDOUT:   %.loc17_34.2: %ptr.314 = converted %ptr.ref, %.loc17_34.1
+// CHECK:STDOUT:   %.loc17_26: type = splice_block %ptr.loc17_26 [concrete = constants.%ptr.314] {
+// CHECK:STDOUT:     %X.ref.loc17_25: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %.loc17_17: type = partial_type %X.ref.loc17_25 [concrete = constants.%.4b5]
+// CHECK:STDOUT:     %ptr.loc17_26: type = ptr_type %.loc17_17 [concrete = constants.%ptr.314]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %b: %ptr.314 = value_binding b, %.loc17_27.2
+// CHECK:STDOUT:   %b: %ptr.314 = value_binding b, %.loc17_34.2
 // CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %i.var, constants.%DestroyOp
 // CHECK:STDOUT:   %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%i.var)
 // CHECK:STDOUT:   <elided>
@@ -248,8 +248,8 @@ fn Use() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %i.var: ref %X = var %i.var_patt
 // CHECK:STDOUT:   %Init.ref.loc18: %Init.type = name_ref Init, file.%Init.decl [concrete = constants.%Init]
-// CHECK:STDOUT:   %.loc18_19: ref %.4b5 = temporary_storage
-// CHECK:STDOUT:   %Init.call.loc18: init %.4b5 to %.loc18_19 = call %Init.ref.loc18()
+// CHECK:STDOUT:   %.loc18_26: ref %.4b5 = temporary_storage
+// CHECK:STDOUT:   %Init.call.loc18: init %.4b5 to %.loc18_26 = call %Init.ref.loc18()
 // CHECK:STDOUT:   %.loc18_3: %X = converted %Init.call.loc18, <error> [concrete = <error>]
 // CHECK:STDOUT:   assign %i.var, <error>
 // CHECK:STDOUT:   %X.ref.loc18: type = name_ref X, file.%X.decl [concrete = constants.%X]
@@ -260,12 +260,12 @@ fn Use() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %j.var: ref %X = var %j.var_patt
 // CHECK:STDOUT:   %Init.ref.loc26: %Init.type = name_ref Init, file.%Init.decl [concrete = constants.%Init]
-// CHECK:STDOUT:   %.loc26_19: ref %.4b5 = temporary_storage
-// CHECK:STDOUT:   %Init.call.loc26: init %.4b5 to %.loc26_19 = call %Init.ref.loc26()
-// CHECK:STDOUT:   %X.ref.loc26_24: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc26_21: %X = converted %Init.call.loc26, <error> [concrete = <error>]
+// CHECK:STDOUT:   %.loc26_26: ref %.4b5 = temporary_storage
+// CHECK:STDOUT:   %Init.call.loc26: init %.4b5 to %.loc26_26 = call %Init.ref.loc26()
+// CHECK:STDOUT:   %X.ref.loc26_31: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc26_28: %X = converted %Init.call.loc26, <error> [concrete = <error>]
 // CHECK:STDOUT:   assign %j.var, <error>
-// CHECK:STDOUT:   %X.ref.loc26_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc26_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:   %j: ref %X = ref_binding j, %j.var
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %k.patt: %pattern_type.05f = ref_binding_pattern k [concrete]
@@ -273,12 +273,12 @@ fn Use() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %k.var: ref %X = var %k.var_patt
 // CHECK:STDOUT:   %Init.ref.loc34: %Init.type = name_ref Init, file.%Init.decl [concrete = constants.%Init]
-// CHECK:STDOUT:   %.loc34_19: ref %.4b5 = temporary_storage
-// CHECK:STDOUT:   %Init.call.loc34: init %.4b5 to %.loc34_19 = call %Init.ref.loc34()
-// CHECK:STDOUT:   %X.ref.loc34_31: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc34_28: %X = converted %Init.call.loc34, <error> [concrete = <error>]
+// CHECK:STDOUT:   %.loc34_26: ref %.4b5 = temporary_storage
+// CHECK:STDOUT:   %Init.call.loc34: init %.4b5 to %.loc34_26 = call %Init.ref.loc34()
+// CHECK:STDOUT:   %X.ref.loc34_38: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc34_35: %X = converted %Init.call.loc34, <error> [concrete = <error>]
 // CHECK:STDOUT:   assign %k.var, <error>
-// CHECK:STDOUT:   %X.ref.loc34_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %X.ref.loc34_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:   %k: ref %X = ref_binding k, %k.var
 // CHECK:STDOUT:   %DestroyOp.bound.loc34: <bound method> = bound_method %k.var, constants.%DestroyOp
 // CHECK:STDOUT:   %DestroyOp.call.loc34: init %empty_tuple.type = call %DestroyOp.bound.loc34(%k.var)
@@ -313,37 +313,37 @@ fn Use() {
 // CHECK:STDOUT:     %v.patt: %pattern_type.05f = value_binding_pattern v [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %value.ref: %.4b5 = name_ref value, file.%value
-// CHECK:STDOUT:   %X.ref.loc14_30: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc14_27.1: %X = as_compatible %value.ref
-// CHECK:STDOUT:   %.loc14_27.2: %X = converted %value.ref, %.loc14_27.1
-// CHECK:STDOUT:   %X.ref.loc14_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %v: %X = value_binding v, %.loc14_27.2
+// CHECK:STDOUT:   %X.ref.loc14_37: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc14_34.1: %X = as_compatible %value.ref
+// CHECK:STDOUT:   %.loc14_34.2: %X = converted %value.ref, %.loc14_34.1
+// CHECK:STDOUT:   %X.ref.loc14_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %v: %X = value_binding v, %.loc14_34.2
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %a.patt: %pattern_type.37f = value_binding_pattern a [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %reference.ref: ref %.4b5 = name_ref reference, file.%reference [concrete = file.%reference.var]
-// CHECK:STDOUT:   %X.ref.loc15_37: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %.loc15_34.1: ref %X = as_compatible %reference.ref [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %.loc15_34.2: ref %X = converted %reference.ref, %.loc15_34.1 [concrete = constants.%reference.var]
-// CHECK:STDOUT:   %addr: %ptr.2a9 = addr_of %.loc15_34.2 [concrete = constants.%addr.9cd]
-// CHECK:STDOUT:   %.loc15_11: type = splice_block %ptr.loc15 [concrete = constants.%ptr.2a9] {
-// CHECK:STDOUT:     %X.ref.loc15_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %ptr.loc15: type = ptr_type %X.ref.loc15_10 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %X.ref.loc15_44: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %.loc15_41.1: ref %X = as_compatible %reference.ref [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %.loc15_41.2: ref %X = converted %reference.ref, %.loc15_41.1 [concrete = constants.%reference.var]
+// CHECK:STDOUT:   %addr: %ptr.2a9 = addr_of %.loc15_41.2 [concrete = constants.%addr.9cd]
+// CHECK:STDOUT:   %.loc15_18: type = splice_block %ptr.loc15 [concrete = constants.%ptr.2a9] {
+// CHECK:STDOUT:     %X.ref.loc15_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %ptr.loc15: type = ptr_type %X.ref.loc15_17 [concrete = constants.%ptr.2a9]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a: %ptr.2a9 = value_binding a, %addr
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %b.patt: %pattern_type.37f = value_binding_pattern b [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %ptr.ref: %ptr.314 = name_ref ptr, file.%ptr.loc10_5
-// CHECK:STDOUT:   %X.ref.loc16_29: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:   %ptr.loc16_30: type = ptr_type %X.ref.loc16_29 [concrete = constants.%ptr.2a9]
-// CHECK:STDOUT:   %.loc16_26.1: %ptr.2a9 = as_compatible %ptr.ref
-// CHECK:STDOUT:   %.loc16_26.2: %ptr.2a9 = converted %ptr.ref, %.loc16_26.1
-// CHECK:STDOUT:   %.loc16_11: type = splice_block %ptr.loc16_11 [concrete = constants.%ptr.2a9] {
-// CHECK:STDOUT:     %X.ref.loc16_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
-// CHECK:STDOUT:     %ptr.loc16_11: type = ptr_type %X.ref.loc16_10 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %X.ref.loc16_36: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:   %ptr.loc16_37: type = ptr_type %X.ref.loc16_36 [concrete = constants.%ptr.2a9]
+// CHECK:STDOUT:   %.loc16_33.1: %ptr.2a9 = as_compatible %ptr.ref
+// CHECK:STDOUT:   %.loc16_33.2: %ptr.2a9 = converted %ptr.ref, %.loc16_33.1
+// CHECK:STDOUT:   %.loc16_18: type = splice_block %ptr.loc16_18 [concrete = constants.%ptr.2a9] {
+// CHECK:STDOUT:     %X.ref.loc16_17: type = name_ref X, file.%X.decl [concrete = constants.%X]
+// CHECK:STDOUT:     %ptr.loc16_18: type = ptr_type %X.ref.loc16_17 [concrete = constants.%ptr.2a9]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %b: %ptr.2a9 = value_binding b, %.loc16_26.2
+// CHECK:STDOUT:   %b: %ptr.2a9 = value_binding b, %.loc16_33.2
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 8 - 8
toolchain/check/testdata/as/var_init.carbon

@@ -16,13 +16,13 @@ library "[[@TEST_NAME]]";
 
 class X {
   impl () as Core.ImplicitAs(X) {
-    fn Convert[self: ()]() ->  X { return {}; }
+    fn Convert[unused self: ()]() ->  X { return {}; }
   }
 }
 
-fn Convert(t: ()) {
+fn Convert(unused t: ()) {
   //@dump-sem-ir-begin
-  var x: X = ();
+  var unused x: X = ();
   //@dump-sem-ir-end
 }
 
@@ -56,14 +56,14 @@ fn Convert(t: ()) {
 // CHECK:STDOUT:     %x.var_patt: %pattern_type.05f = var_pattern %x.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %x.var: ref %X = var %x.var_patt
-// CHECK:STDOUT:   %.loc12_15.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:   %.loc12_22.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
 // CHECK:STDOUT:   %impl.elem0: %.1bd = impl_witness_access constants.%ImplicitAs.impl_witness, element0 [concrete = constants.%empty_tuple.type.as.ImplicitAs.impl.Convert]
-// CHECK:STDOUT:   %bound_method: <bound method> = bound_method %.loc12_15.1, %impl.elem0 [concrete = constants.%empty_tuple.type.as.ImplicitAs.impl.Convert.bound]
+// CHECK:STDOUT:   %bound_method: <bound method> = bound_method %.loc12_22.1, %impl.elem0 [concrete = constants.%empty_tuple.type.as.ImplicitAs.impl.Convert.bound]
 // CHECK:STDOUT:   %.loc12_3.1: ref %X = splice_block %x.var {}
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc12_15.2: %empty_tuple.type = converted %.loc12_15.1, %empty_tuple [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:   %empty_tuple.type.as.ImplicitAs.impl.Convert.call: init %X to %.loc12_3.1 = call %bound_method(%.loc12_15.2)
-// CHECK:STDOUT:   %.loc12_3.2: init %X = converted %.loc12_15.1, %empty_tuple.type.as.ImplicitAs.impl.Convert.call
+// CHECK:STDOUT:   %.loc12_22.2: %empty_tuple.type = converted %.loc12_22.1, %empty_tuple [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:   %empty_tuple.type.as.ImplicitAs.impl.Convert.call: init %X to %.loc12_3.1 = call %bound_method(%.loc12_22.2)
+// CHECK:STDOUT:   %.loc12_3.2: init %X = converted %.loc12_22.1, %empty_tuple.type.as.ImplicitAs.impl.Convert.call
 // CHECK:STDOUT:   assign %x.var, %.loc12_3.2
 // CHECK:STDOUT:   %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:   %x: ref %X = ref_binding x, %x.var

+ 1 - 1
toolchain/check/testdata/basics/dump_sem_ir_ranges.carbon

@@ -20,7 +20,7 @@
 library "[[@TEST_NAME]]";
 
 fn A() {
-  var a: ();
+  var unused a: ();
 }
 
 fn B() -> () {

+ 16 - 16
toolchain/check/testdata/basics/duplicate_name_same_line.carbon

@@ -15,7 +15,7 @@ fn A() {
     // This declares `n` in two different scopes, it's just showing the IR
     // behavior of having both on the same line.
     //@dump-sem-ir-begin
-    var n: (); } else { var n: ();
+    var unused n: (); } else { var unused n: ();
     //@dump-sem-ir-end
   }
 }
@@ -39,33 +39,33 @@ fn A() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.then:
 // CHECK:STDOUT:   name_binding_decl {
-// CHECK:STDOUT:     %n.patt.loc18_9: %pattern_type.cb1 = ref_binding_pattern n [concrete]
-// CHECK:STDOUT:     %n.var_patt.loc18_5: %pattern_type.cb1 = var_pattern %n.patt.loc18_9 [concrete]
+// CHECK:STDOUT:     %n.patt.loc18_16: %pattern_type.cb1 = ref_binding_pattern n [concrete]
+// CHECK:STDOUT:     %n.var_patt.loc18_5: %pattern_type.cb1 = var_pattern %n.patt.loc18_16 [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %n.var.loc18_5: ref %empty_tuple.type = var %n.var_patt.loc18_5
-// CHECK:STDOUT:   %.loc18_13.1: type = splice_block %.loc18_13.3 [concrete = constants.%empty_tuple.type] {
-// CHECK:STDOUT:     %.loc18_13.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:     %.loc18_13.3: type = converted %.loc18_13.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
+// CHECK:STDOUT:   %.loc18_20.1: type = splice_block %.loc18_20.3 [concrete = constants.%empty_tuple.type] {
+// CHECK:STDOUT:     %.loc18_20.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:     %.loc18_20.3: type = converted %.loc18_20.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %n.loc18_9: ref %empty_tuple.type = ref_binding n, %n.var.loc18_5
+// CHECK:STDOUT:   %n.loc18_16: ref %empty_tuple.type = ref_binding n, %n.var.loc18_5
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.else:
 // CHECK:STDOUT:   name_binding_decl {
-// CHECK:STDOUT:     %n.patt.loc18_29: %pattern_type.cb1 = ref_binding_pattern n [concrete]
-// CHECK:STDOUT:     %n.var_patt.loc18_25: %pattern_type.cb1 = var_pattern %n.patt.loc18_29 [concrete]
+// CHECK:STDOUT:     %n.patt.loc18_43: %pattern_type.cb1 = ref_binding_pattern n [concrete]
+// CHECK:STDOUT:     %n.var_patt.loc18_32: %pattern_type.cb1 = var_pattern %n.patt.loc18_43 [concrete]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %n.var.loc18_25: ref %empty_tuple.type = var %n.var_patt.loc18_25
-// CHECK:STDOUT:   %.loc18_33.1: type = splice_block %.loc18_33.3 [concrete = constants.%empty_tuple.type] {
-// CHECK:STDOUT:     %.loc18_33.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:     %.loc18_33.3: type = converted %.loc18_33.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
+// CHECK:STDOUT:   %n.var.loc18_32: ref %empty_tuple.type = var %n.var_patt.loc18_32
+// CHECK:STDOUT:   %.loc18_47.1: type = splice_block %.loc18_47.3 [concrete = constants.%empty_tuple.type] {
+// CHECK:STDOUT:     %.loc18_47.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:     %.loc18_47.3: type = converted %.loc18_47.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %n.loc18_29: ref %empty_tuple.type = ref_binding n, %n.var.loc18_25
+// CHECK:STDOUT:   %n.loc18_43: ref %empty_tuple.type = ref_binding n, %n.var.loc18_32
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.done:
-// CHECK:STDOUT:   %DestroyOp.bound.loc18_25: <bound method> = bound_method %n.var.loc18_25, constants.%DestroyOp
-// CHECK:STDOUT:   %DestroyOp.call.loc18_25: init %empty_tuple.type = call %DestroyOp.bound.loc18_25(%n.var.loc18_25)
+// CHECK:STDOUT:   %DestroyOp.bound.loc18_32: <bound method> = bound_method %n.var.loc18_32, constants.%DestroyOp
+// CHECK:STDOUT:   %DestroyOp.call.loc18_32: init %empty_tuple.type = call %DestroyOp.bound.loc18_32(%n.var.loc18_32)
 // CHECK:STDOUT:   %DestroyOp.bound.loc18_5: <bound method> = bound_method %n.var.loc18_5, constants.%DestroyOp
 // CHECK:STDOUT:   %DestroyOp.call.loc18_5: init %empty_tuple.type = call %DestroyOp.bound.loc18_5(%n.var.loc18_5)
 // CHECK:STDOUT:   <elided>

+ 12 - 12
toolchain/check/testdata/basics/include_in_dumps.carbon

@@ -31,13 +31,13 @@ library "[[@TEST_NAME]]";
 
 //@dump-sem-ir-begin
 interface I {
-  fn Op[self: Self]();
+  fn Op[unused self: Self]();
 }
 //@dump-sem-ir-end
 
 class C {
   impl C as I {
-    fn Op[self: Self]() {}
+    fn Op[unused self: Self]() {}
   }
 }
 
@@ -61,13 +61,13 @@ library "[[@TEST_NAME]]";
 
 //@dump-sem-ir-begin
 interface I {
-  fn Op[self: Self]();
+  fn Op[unused self: Self]();
 }
 //@dump-sem-ir-end
 
 class C {
   impl C as I {
-    fn Op[self: Self]() {}
+    fn Op[unused self: Self]() {}
   }
 }
 
@@ -151,10 +151,10 @@ fn F(c: C) { c.(I.Op)(); }
 // CHECK:STDOUT:     %self.param_patt: @I.WithSelf.Op.%pattern_type (%pattern_type.fa0) = value_param_pattern %self.patt, call_param0 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %self.param: @I.WithSelf.Op.%Self.binding.as_type (%Self.binding.as_type) = value_param call_param0
-// CHECK:STDOUT:     %.loc8_15.1: type = splice_block %.loc8_15.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] {
+// CHECK:STDOUT:     %.loc8_22.1: type = splice_block %.loc8_22.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] {
 // CHECK:STDOUT:       %Self.ref: %I.type = name_ref Self, @I.%Self.loc7 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:       %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)]
-// CHECK:STDOUT:       %.loc8_15.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)]
+// CHECK:STDOUT:       %.loc8_22.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %self: @I.WithSelf.Op.%Self.binding.as_type (%Self.binding.as_type) = value_binding self, %self.param
 // CHECK:STDOUT:   }
@@ -238,15 +238,15 @@ fn F(c: C) { c.(I.Op)(); }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Main.import_ref.8f2: <witness> = import_ref Main//included_with_range, loc16_1, loaded [concrete = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.743 = import_ref Main//included_with_range, inst{{[0-9A-F]+}} [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.d09: %I.assoc_type = import_ref Main//included_with_range, loc8_22, loaded [concrete = constants.%assoc0]
+// CHECK:STDOUT:   %Main.import_ref.d09: %I.assoc_type = import_ref Main//included_with_range, loc8_29, loaded [concrete = constants.%assoc0]
 // CHECK:STDOUT:   %Main.Op = import_ref Main//included_with_range, Op, unloaded
 // CHECK:STDOUT:   %Main.import_ref.2362f8.2: %I.type = import_ref Main//included_with_range, loc7_13, loaded [symbolic = constants.%Self]
 // CHECK:STDOUT:   %Main.import_ref.c82 = import_ref Main//included_with_range, loc7_13, unloaded
-// CHECK:STDOUT:   %Main.import_ref.e26: @I.%I.WithSelf.Op.type (%I.WithSelf.Op.type.f73) = import_ref Main//included_with_range, loc8_22, loaded [symbolic = @I.%I.WithSelf.Op (constants.%I.WithSelf.Op.f53)]
+// CHECK:STDOUT:   %Main.import_ref.e26: @I.%I.WithSelf.Op.type (%I.WithSelf.Op.type.f73) = import_ref Main//included_with_range, loc8_29, loaded [symbolic = @I.%I.WithSelf.Op (constants.%I.WithSelf.Op.f53)]
 // CHECK:STDOUT:   %Main.import_ref.f72: <witness> = import_ref Main//included_with_range, loc13_15, loaded [concrete = constants.%I.impl_witness]
 // CHECK:STDOUT:   %Main.import_ref.61c: type = import_ref Main//included_with_range, loc13_8, loaded [concrete = constants.%C]
 // CHECK:STDOUT:   %Main.import_ref.72a: type = import_ref Main//included_with_range, loc13_13, loaded [concrete = constants.%I.type]
-// CHECK:STDOUT:   %Main.import_ref.4bc: %C.as.I.impl.Op.type = import_ref Main//included_with_range, loc14_25, loaded [concrete = constants.%C.as.I.impl.Op]
+// CHECK:STDOUT:   %Main.import_ref.4bc: %C.as.I.impl.Op.type = import_ref Main//included_with_range, loc14_32, loaded [concrete = constants.%C.as.I.impl.Op]
 // CHECK:STDOUT:   %I.impl_witness_table = impl_witness_table (%Main.import_ref.4bc), @C.as.I.impl [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -360,9 +360,9 @@ fn F(c: C) { c.(I.Op)(); }
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Main.import_ref.d09: %I.assoc_type = import_ref Main//excluded_with_range, loc6_22, loaded [concrete = constants.%assoc0]
-// CHECK:STDOUT:   %Main.import_ref.e26: @I.%I.WithSelf.Op.type (%I.WithSelf.Op.type.f73) = import_ref Main//excluded_with_range, loc6_22, loaded [symbolic = @I.%I.WithSelf.Op (constants.%I.WithSelf.Op.f53)]
-// CHECK:STDOUT:   %Main.import_ref.4bc: %C.as.I.impl.Op.type = import_ref Main//excluded_with_range, loc12_25, loaded [concrete = constants.%C.as.I.impl.Op]
+// CHECK:STDOUT:   %Main.import_ref.d09: %I.assoc_type = import_ref Main//excluded_with_range, loc6_29, loaded [concrete = constants.%assoc0]
+// CHECK:STDOUT:   %Main.import_ref.e26: @I.%I.WithSelf.Op.type (%I.WithSelf.Op.type.f73) = import_ref Main//excluded_with_range, loc6_29, loaded [symbolic = @I.%I.WithSelf.Op (constants.%I.WithSelf.Op.f53)]
+// CHECK:STDOUT:   %Main.import_ref.4bc: %C.as.I.impl.Op.type = import_ref Main//excluded_with_range, loc12_32, loaded [concrete = constants.%C.as.I.impl.Op]
 // CHECK:STDOUT:   %I.impl_witness_table = impl_witness_table (%Main.import_ref.4bc), @C.as.I.impl [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon

@@ -66,10 +66,10 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     name_scope60000001: {inst: inst60000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name2: inst60000014, name3: inst6000002A, name4: inst6000004E}}
 // CHECK:STDOUT:     name_scope60000002: {inst: inst60000014, parent_scope: name_scope60000001, has_error: false, extended_scopes: [], names: {}}
 // CHECK:STDOUT:   entity_names:
-// CHECK:STDOUT:     entity_name60000000: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000001: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000002: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000003: {name: name4, parent_scope: name_scope60000001, index: -1, is_template: 0}
+// CHECK:STDOUT:     entity_name60000000: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000001: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000002: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000003: {name: name4, parent_scope: name_scope60000001, index: -1, is_template: 0, is_unused: 0}
 // CHECK:STDOUT:   cpp_global_vars:
 // CHECK:STDOUT:     cpp_global_var60000000: {key: {entity_name_id: entity_name60000003}, clang_decl_id: clang_decl_id60000007}
 // CHECK:STDOUT:   functions:

+ 1 - 1
toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon

@@ -120,7 +120,7 @@ fn B() {
 // CHECK:STDOUT:     name_scope0:     {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name1: inst50000011, name0: inst50000012}}
 // CHECK:STDOUT:     name_scope50000001: {inst: inst50000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst50000017}}
 // CHECK:STDOUT:   entity_names:
-// CHECK:STDOUT:     entity_name50000000: {name: name1, parent_scope: name_scope50000001, index: -1, is_template: 0}
+// CHECK:STDOUT:     entity_name50000000: {name: name1, parent_scope: name_scope50000001, index: -1, is_template: 0, is_unused: 0}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
 // CHECK:STDOUT:     function50000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block_empty, call_params_id: inst_block_empty, body: [inst_block50000005]}

+ 1 - 1
toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon

@@ -139,7 +139,7 @@ fn B() {
 // CHECK:STDOUT:     name_scope0:     {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name1: inst50000011, name0: inst50000012}}
 // CHECK:STDOUT:     name_scope50000001: {inst: inst50000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst50000017}}
 // CHECK:STDOUT:   entity_names:
-// CHECK:STDOUT:     entity_name50000000: {name: name1, parent_scope: name_scope50000001, index: -1, is_template: 0}
+// CHECK:STDOUT:     entity_name50000000: {name: name1, parent_scope: name_scope50000001, index: -1, is_template: 0, is_unused: 0}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
 // CHECK:STDOUT:     function50000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block_empty, call_params_id: inst_block_empty, body: [inst_block50000005]}

+ 64 - 64
toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon

@@ -270,70 +270,70 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
 // CHECK:STDOUT:     name_scope6000000C: {inst: inst600000D9, parent_scope: name_scope60000001, has_error: false, extended_scopes: [], names: {}}
 // CHECK:STDOUT:     name_scope6000000D: {inst: inst6000011D, parent_scope: name_scope60000001, has_error: false, extended_scopes: [], names: {}}
 // CHECK:STDOUT:   entity_names:
-// CHECK:STDOUT:     entity_name60000000: {name: name(PeriodSelf), parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000001: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000002: {name: name2, parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000003: {name: name3, parent_scope: name_scope60000001, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000004: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000005: {name: name4, parent_scope: name_scope60000003, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000006: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000007: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000008: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000009: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000000A: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000000B: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000000C: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000000D: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000000E: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000000F: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000010: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000011: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000012: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000013: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000014: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000015: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000016: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000017: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000018: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000019: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000001A: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name6000001B: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000001C: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name6000001D: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name6000001E: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name6000001F: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000020: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000021: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000022: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000023: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000024: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000025: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000026: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000027: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000028: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000029: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name6000002A: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000002B: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0}
-// CHECK:STDOUT:     entity_name6000002C: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0}
-// CHECK:STDOUT:     entity_name6000002D: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0}
-// CHECK:STDOUT:     entity_name6000002E: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0}
-// CHECK:STDOUT:     entity_name6000002F: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0}
-// CHECK:STDOUT:     entity_name60000030: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000031: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000032: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000033: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000034: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0}
-// CHECK:STDOUT:     entity_name60000035: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000036: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name60000037: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0}
-// CHECK:STDOUT:     entity_name60000038: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name60000039: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000003A: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0}
-// CHECK:STDOUT:     entity_name6000003B: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name6000003C: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
-// CHECK:STDOUT:     entity_name6000003D: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0}
-// CHECK:STDOUT:     entity_name6000003E: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0}
-// CHECK:STDOUT:     entity_name6000003F: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0}
+// CHECK:STDOUT:     entity_name60000000: {name: name(PeriodSelf), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000001: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000002: {name: name2, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000003: {name: name3, parent_scope: name_scope60000001, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000004: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000005: {name: name4, parent_scope: name_scope60000003, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000006: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000007: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000008: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000009: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000000A: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000000B: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000000C: {name: name(SelfType), parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000000D: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000000E: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000000F: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000010: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000011: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000012: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000013: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000014: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000015: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000016: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000017: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000018: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000019: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000001A: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000001B: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000001C: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000001D: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000001E: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000001F: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000020: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000021: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000022: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000023: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000024: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000025: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000026: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000027: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000028: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000029: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000002A: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000002B: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000002C: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000002D: {name: name(SelfValue), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000002E: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000002F: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000030: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000031: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000032: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000033: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000034: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000035: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000036: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000037: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000038: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name60000039: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000003A: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000003B: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000003C: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000003D: {name: name6, parent_scope: name_scope<none>, index: 2, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000003E: {name: name5, parent_scope: name_scope<none>, index: 1, is_template: 0, is_unused: 0}
+// CHECK:STDOUT:     entity_name6000003F: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
 // CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block60000010, call_params_id: inst_block60000011, return_type_inst_id: inst6000002F, return_form_inst_id: inst60000031, return_patterns_id: inst_block6000000F, body: [inst_block60000018]}

+ 1 - 1
toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon

@@ -31,7 +31,7 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:   name_scopes:
 // CHECK:STDOUT:     name_scope0:     {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst6000002A}}
 // CHECK:STDOUT:   entity_names:
-// CHECK:STDOUT:     entity_name60000000: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0}
+// CHECK:STDOUT:     entity_name60000000: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
 // CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block6000000B, call_params_id: inst_block6000000C, return_type_inst_id: inst60000020, return_form_inst_id: inst60000021, return_patterns_id: inst_block6000000A, body: [inst_block6000000F]}

+ 1 - 1
toolchain/check/testdata/builtins/float/negate.carbon

@@ -16,7 +16,7 @@ library "[[@TEST_NAME]]";
 
 fn Negate(a: f64) -> f64 = "float.negate";
 
-fn RuntimeCallIsValid(a: f64, b: f64) -> f64 {
+fn RuntimeCallIsValid(a: f64, unused b: f64) -> f64 {
   //@dump-sem-ir-begin
   return Negate(a);
   //@dump-sem-ir-end

+ 1 - 1
toolchain/check/testdata/builtins/int/snegate.carbon

@@ -21,7 +21,7 @@ let arr_p: array(i32, 123)* = &arr;
 
 let n: i32 = Negate(1);
 
-fn RuntimeCallIsValid(a: i32, b: i32) -> i32 {
+fn RuntimeCallIsValid(a: i32, unused b: i32) -> i32 {
   //@dump-sem-ir-begin
   return Negate(a);
   //@dump-sem-ir-end

+ 1 - 1
toolchain/check/testdata/builtins/int/unegate.carbon

@@ -21,7 +21,7 @@ let arr_p: array(u32, 123)* = &arr;
 
 let n: u32 = Negate(1);
 
-fn RuntimeCallIsValid(a: u32, b: u32) -> u32 {
+fn RuntimeCallIsValid(a: u32, unused b: u32) -> u32 {
   //@dump-sem-ir-begin
   return Negate(a);
   //@dump-sem-ir-end

+ 10 - 10
toolchain/check/testdata/builtins/read/char.carbon

@@ -18,8 +18,8 @@ fn ReadChar() -> i32 = "read.char";
 
 fn Main() {
   //@dump-sem-ir-begin
-  let n: i32 = ReadChar();
-  let m: i32 = Core.ReadChar();
+  let unused n: i32 = ReadChar();
+  let unused m: i32 = Core.ReadChar();
   //@dump-sem-ir-end
 }
 
@@ -56,26 +56,26 @@ fn Main() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %ReadChar.ref.loc8: %ReadChar.type.c36 = name_ref ReadChar, file.%ReadChar.decl [concrete = constants.%ReadChar.6ad]
 // CHECK:STDOUT:   %ReadChar.call.loc8: init %i32 = call %ReadChar.ref.loc8()
-// CHECK:STDOUT:   %.loc8_10: type = splice_block %i32.loc8 [concrete = constants.%i32] {
+// CHECK:STDOUT:   %.loc8_17: type = splice_block %i32.loc8 [concrete = constants.%i32] {
 // CHECK:STDOUT:     %int_32.loc8: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32.loc8: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc8_25.1: %i32 = value_of_initializer %ReadChar.call.loc8
-// CHECK:STDOUT:   %.loc8_25.2: %i32 = converted %ReadChar.call.loc8, %.loc8_25.1
-// CHECK:STDOUT:   %n: %i32 = value_binding n, %.loc8_25.2
+// CHECK:STDOUT:   %.loc8_32.1: %i32 = value_of_initializer %ReadChar.call.loc8
+// CHECK:STDOUT:   %.loc8_32.2: %i32 = converted %ReadChar.call.loc8, %.loc8_32.1
+// CHECK:STDOUT:   %n: %i32 = value_binding n, %.loc8_32.2
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %m.patt: %pattern_type.7ce = value_binding_pattern m [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
 // CHECK:STDOUT:   %ReadChar.ref.loc9: %ReadChar.type.9f3 = name_ref ReadChar, imports.%Core.ReadChar [concrete = constants.%ReadChar.01f]
 // CHECK:STDOUT:   %ReadChar.call.loc9: init %i32 = call %ReadChar.ref.loc9()
-// CHECK:STDOUT:   %.loc9_10: type = splice_block %i32.loc9 [concrete = constants.%i32] {
+// CHECK:STDOUT:   %.loc9_17: type = splice_block %i32.loc9 [concrete = constants.%i32] {
 // CHECK:STDOUT:     %int_32.loc9: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32.loc9: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc9_30.1: %i32 = value_of_initializer %ReadChar.call.loc9
-// CHECK:STDOUT:   %.loc9_30.2: %i32 = converted %ReadChar.call.loc9, %.loc9_30.1
-// CHECK:STDOUT:   %m: %i32 = value_binding m, %.loc9_30.2
+// CHECK:STDOUT:   %.loc9_37.1: %i32 = value_of_initializer %ReadChar.call.loc9
+// CHECK:STDOUT:   %.loc9_37.2: %i32 = converted %ReadChar.call.loc9, %.loc9_37.1
+// CHECK:STDOUT:   %m: %i32 = value_binding m, %.loc9_37.2
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 8 - 8
toolchain/check/testdata/builtins/type/and.carbon

@@ -19,7 +19,7 @@ fn TypeAnd(a: type, b: type) -> type = "type.and";
 interface I {}
 interface J {}
 
-fn TakeIJ(T:! TypeAnd(I, J)) {}
+fn TakeIJ(unused T:! TypeAnd(I, J)) {}
 
 class IJ {
   impl as I {}
@@ -39,7 +39,7 @@ fn TypeAnd(a: type, b: type) -> type = "type.and";
 interface I {}
 interface J {}
 
-fn TakeIJ(T:! TypeAnd(I, J)) {}
+fn TakeIJ(unused T:! TypeAnd(I, J)) {}
 
 class JustI {
   impl as I {}
@@ -53,17 +53,17 @@ fn Call() {
   // CHECK:STDERR: fail_combine_facets_bad_call.carbon:[[@LINE+7]]:3: error: cannot convert type `JustI` into type implementing `I & J` [ConversionFailureTypeToFacet]
   // CHECK:STDERR:   TakeIJ(JustI);
   // CHECK:STDERR:   ^~~~~~~~~~~~~
-  // CHECK:STDERR: fail_combine_facets_bad_call.carbon:[[@LINE-14]]:11: note: initializing generic parameter `T` declared here [InitializingGenericParam]
-  // CHECK:STDERR: fn TakeIJ(T:! TypeAnd(I, J)) {}
-  // CHECK:STDERR:           ^
+  // CHECK:STDERR: fail_combine_facets_bad_call.carbon:[[@LINE-14]]:18: note: initializing generic parameter `T` declared here [InitializingGenericParam]
+  // CHECK:STDERR: fn TakeIJ(unused T:! TypeAnd(I, J)) {}
+  // CHECK:STDERR:                  ^
   // CHECK:STDERR:
   TakeIJ(JustI);
   // CHECK:STDERR: fail_combine_facets_bad_call.carbon:[[@LINE+7]]:3: error: cannot convert type `JustJ` into type implementing `I & J` [ConversionFailureTypeToFacet]
   // CHECK:STDERR:   TakeIJ(JustJ);
   // CHECK:STDERR:   ^~~~~~~~~~~~~
-  // CHECK:STDERR: fail_combine_facets_bad_call.carbon:[[@LINE-22]]:11: note: initializing generic parameter `T` declared here [InitializingGenericParam]
-  // CHECK:STDERR: fn TakeIJ(T:! TypeAnd(I, J)) {}
-  // CHECK:STDERR:           ^
+  // CHECK:STDERR: fail_combine_facets_bad_call.carbon:[[@LINE-22]]:18: note: initializing generic parameter `T` declared here [InitializingGenericParam]
+  // CHECK:STDERR: fn TakeIJ(unused T:! TypeAnd(I, J)) {}
+  // CHECK:STDERR:                  ^
   // CHECK:STDERR:
   TakeIJ(JustJ);
 }

+ 8 - 8
toolchain/check/testdata/class/access_modifers.carbon

@@ -31,14 +31,14 @@ class Circle {
 
 fn Run() {
   let circle: Circle = Circle.Make();
-  // CHECK:STDERR: fail_private_field_access.carbon:[[@LINE+7]]:21: error: cannot access private member `radius` of type `Circle` [ClassInvalidMemberAccess]
-  // CHECK:STDERR:   let radius: i32 = circle.radius;
-  // CHECK:STDERR:                     ^~~~~~~~~~~~~
+  // CHECK:STDERR: fail_private_field_access.carbon:[[@LINE+7]]:28: error: cannot access private member `radius` of type `Circle` [ClassInvalidMemberAccess]
+  // CHECK:STDERR:   let unused radius: i32 = circle.radius;
+  // CHECK:STDERR:                            ^~~~~~~~~~~~~
   // CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-17]]:15: note: declared here [ClassMemberDeclaration]
   // CHECK:STDERR:   private var radius: i32;
   // CHECK:STDERR:               ^~~~~~~~~~~
   // CHECK:STDERR:
-  let radius: i32 = circle.radius;
+  let unused radius: i32 = circle.radius;
   // CHECK:STDERR: fail_private_field_access.carbon:[[@LINE+7]]:3: error: cannot access private member `radius` of type `Circle` [ClassInvalidMemberAccess]
   // CHECK:STDERR:   circle.radius = 5;
   // CHECK:STDERR:   ^~~~~~~~~~~~~
@@ -75,14 +75,14 @@ class A {
 }
 
 fn Run() {
-  // CHECK:STDERR: fail_protected_field_access.carbon:[[@LINE+7]]:16: error: cannot access protected member `x` of type `A` [ClassInvalidMemberAccess]
-  // CHECK:STDERR:   let x: i32 = A.x;
-  // CHECK:STDERR:                ^~~
+  // CHECK:STDERR: fail_protected_field_access.carbon:[[@LINE+7]]:23: error: cannot access protected member `x` of type `A` [ClassInvalidMemberAccess]
+  // CHECK:STDERR:   let unused x: i32 = A.x;
+  // CHECK:STDERR:                       ^~~
   // CHECK:STDERR: fail_protected_field_access.carbon:[[@LINE-7]]:17: note: declared here [ClassMemberDeclaration]
   // CHECK:STDERR:   protected var x: i32;
   // CHECK:STDERR:                 ^~~~~~
   // CHECK:STDERR:
-  let x: i32 = A.x;
+  let unused x: i32 = A.x;
 }
 
 // --- instance_private_field_access_on_self.carbon

+ 9 - 9
toolchain/check/testdata/class/adapter/convert_incomplete.carbon

@@ -24,7 +24,7 @@ class X {}
 var x: Adapter(X);
 
 fn F(p: Adapter(X)*) {
-  let x: X* = *p as X*;
+  let unused x: X* = *p as X*;
 }
 
 // --- can_be_completed.carbon
@@ -40,7 +40,7 @@ class X {}
 fn F(p: Adapter(X)*) {
   // The conversion here triggers completion of Adapter(X)
   // so we can determine what it adapts.
-  let x: X* = *p as X*;
+  let unused x: X* = *p as X*;
 }
 
 // --- fail_incomplete.carbon
@@ -52,12 +52,12 @@ class Adapter(T:! type);
 class X {}
 
 fn F(p: Adapter(X)*) {
-  // CHECK:STDERR: fail_incomplete.carbon:[[@LINE+7]]:15: error: cannot convert expression of type `Adapter(X)` to `X*` with `as` [ConversionFailure]
-  // CHECK:STDERR:   let x: X* = *p as X*;
-  // CHECK:STDERR:               ^~~~~~~~
-  // CHECK:STDERR: fail_incomplete.carbon:[[@LINE+4]]:15: note: type `Adapter(X)` does not implement interface `Core.As(X*)` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   let x: X* = *p as X*;
-  // CHECK:STDERR:               ^~~~~~~~
+  // CHECK:STDERR: fail_incomplete.carbon:[[@LINE+7]]:22: error: cannot convert expression of type `Adapter(X)` to `X*` with `as` [ConversionFailure]
+  // CHECK:STDERR:   let unused x: X* = *p as X*;
+  // CHECK:STDERR:                      ^~~~~~~~
+  // CHECK:STDERR: fail_incomplete.carbon:[[@LINE+4]]:22: note: type `Adapter(X)` does not implement interface `Core.As(X*)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   let unused x: X* = *p as X*;
+  // CHECK:STDERR:                      ^~~~~~~~
   // CHECK:STDERR:
-  let x: X* = *p as X*;
+  let unused x: X* = *p as X*;
 }

+ 51 - 51
toolchain/check/testdata/class/derived_to_base.carbon

@@ -34,7 +34,7 @@ fn ConvertBToA(p: B*) -> A* { return p; }
 fn ConvertCToA(p: C*) -> A* { return p; }
 
 fn ConvertValue(c: C) {
-  let a: A = c;
+  let unused a: A = c;
 }
 
 fn ConvertRef(c: C*) -> A* {
@@ -42,7 +42,7 @@ fn ConvertRef(c: C*) -> A* {
 }
 
 fn ConvertInit() {
-  let a: A = {.base = {.base = {.a = 1}, .b = 2}, .c = 3} as C;
+  let unused a: A = {.base = {.base = {.a = 1}, .b = 2}, .c = 3} as C;
 }
 //@dump-sem-ir-end
 
@@ -345,11 +345,11 @@ fn PassConstB(p: const B) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A]
-// CHECK:STDOUT:   %.loc24_14.1: ref %B = class_element_access %c.ref, element0
-// CHECK:STDOUT:   %.loc24_14.2: ref %A = class_element_access %.loc24_14.1, element0
-// CHECK:STDOUT:   %.loc24_14.3: ref %A = converted %c.ref, %.loc24_14.2
-// CHECK:STDOUT:   %.loc24_14.4: %A = acquire_value %.loc24_14.3
-// CHECK:STDOUT:   %a: %A = value_binding a, %.loc24_14.4
+// CHECK:STDOUT:   %.loc24_21.1: ref %B = class_element_access %c.ref, element0
+// CHECK:STDOUT:   %.loc24_21.2: ref %A = class_element_access %.loc24_21.1, element0
+// CHECK:STDOUT:   %.loc24_21.3: ref %A = converted %c.ref, %.loc24_21.2
+// CHECK:STDOUT:   %.loc24_21.4: %A = acquire_value %.loc24_21.3
+// CHECK:STDOUT:   %a: %A = value_binding a, %.loc24_21.4
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -376,54 +376,54 @@ fn PassConstB(p: const B) {
 // CHECK:STDOUT:     %a.patt: %pattern_type.1ab = value_binding_pattern a [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
-// CHECK:STDOUT:   %.loc32_39.1: %struct_type.a.a6c = struct_literal (%int_1) [concrete = constants.%struct.48c]
+// CHECK:STDOUT:   %.loc32_46.1: %struct_type.a.a6c = struct_literal (%int_1) [concrete = constants.%struct.48c]
 // CHECK:STDOUT:   %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
-// CHECK:STDOUT:   %.loc32_48.1: %struct_type.base.b.bf0 = struct_literal (%.loc32_39.1, %int_2) [concrete = constants.%struct.ff9]
+// CHECK:STDOUT:   %.loc32_55.1: %struct_type.base.b.bf0 = struct_literal (%.loc32_46.1, %int_2) [concrete = constants.%struct.ff9]
 // CHECK:STDOUT:   %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba]
-// CHECK:STDOUT:   %.loc32_57.1: %struct_type.base.c.136 = struct_literal (%.loc32_48.1, %int_3) [concrete = constants.%struct.2aa]
+// CHECK:STDOUT:   %.loc32_64.1: %struct_type.base.c.136 = struct_literal (%.loc32_55.1, %int_3) [concrete = constants.%struct.2aa]
 // CHECK:STDOUT:   %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:   %impl.elem0.loc32_39: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:   %bound_method.loc32_39.1: <bound method> = bound_method %int_1, %impl.elem0.loc32_39 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215]
-// CHECK:STDOUT:   %specific_fn.loc32_39: <specific function> = specific_function %impl.elem0.loc32_39, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc32_39.2: <bound method> = bound_method %int_1, %specific_fn.loc32_39 [concrete = constants.%bound_method.38b]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_39: init %i32 = call %bound_method.loc32_39.2(%int_1) [concrete = constants.%int_1.5d2]
-// CHECK:STDOUT:   %.loc32_39.2: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_39 [concrete = constants.%int_1.5d2]
-// CHECK:STDOUT:   %.loc32_57.2: ref %C = temporary_storage
-// CHECK:STDOUT:   %.loc32_57.3: ref %B = class_element_access %.loc32_57.2, element0
-// CHECK:STDOUT:   %.loc32_48.2: ref %A = class_element_access %.loc32_57.3, element0
-// CHECK:STDOUT:   %.loc32_39.3: ref %i32 = class_element_access %.loc32_48.2, element0
-// CHECK:STDOUT:   %.loc32_39.4: init %i32 to %.loc32_39.3 = in_place_init %.loc32_39.2 [concrete = constants.%int_1.5d2]
-// CHECK:STDOUT:   %.loc32_39.5: init %A to %.loc32_48.2 = class_init (%.loc32_39.4) [concrete = constants.%A.val]
-// CHECK:STDOUT:   %.loc32_48.3: init %A = converted %.loc32_39.1, %.loc32_39.5 [concrete = constants.%A.val]
-// CHECK:STDOUT:   %impl.elem0.loc32_48: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:   %bound_method.loc32_48.1: <bound method> = bound_method %int_2, %impl.elem0.loc32_48 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5]
-// CHECK:STDOUT:   %specific_fn.loc32_48: <specific function> = specific_function %impl.elem0.loc32_48, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc32_48.2: <bound method> = bound_method %int_2, %specific_fn.loc32_48 [concrete = constants.%bound_method.646]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_48: init %i32 = call %bound_method.loc32_48.2(%int_2) [concrete = constants.%int_2.ef8]
-// CHECK:STDOUT:   %.loc32_48.4: init %i32 = converted %int_2, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_48 [concrete = constants.%int_2.ef8]
-// CHECK:STDOUT:   %.loc32_48.5: ref %i32 = class_element_access %.loc32_57.3, element1
-// CHECK:STDOUT:   %.loc32_48.6: init %i32 to %.loc32_48.5 = in_place_init %.loc32_48.4 [concrete = constants.%int_2.ef8]
-// CHECK:STDOUT:   %.loc32_48.7: init %B to %.loc32_57.3 = class_init (%.loc32_48.3, %.loc32_48.6) [concrete = constants.%B.val]
-// CHECK:STDOUT:   %.loc32_57.4: init %B = converted %.loc32_48.1, %.loc32_48.7 [concrete = constants.%B.val]
-// CHECK:STDOUT:   %impl.elem0.loc32_57: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:   %bound_method.loc32_57.1: <bound method> = bound_method %int_3, %impl.elem0.loc32_57 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.061]
-// CHECK:STDOUT:   %specific_fn.loc32_57: <specific function> = specific_function %impl.elem0.loc32_57, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc32_57.2: <bound method> = bound_method %int_3, %specific_fn.loc32_57 [concrete = constants.%bound_method.fa7]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_57: init %i32 = call %bound_method.loc32_57.2(%int_3) [concrete = constants.%int_3.822]
-// CHECK:STDOUT:   %.loc32_57.5: init %i32 = converted %int_3, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_57 [concrete = constants.%int_3.822]
-// CHECK:STDOUT:   %.loc32_57.6: ref %i32 = class_element_access %.loc32_57.2, element1
-// CHECK:STDOUT:   %.loc32_57.7: init %i32 to %.loc32_57.6 = in_place_init %.loc32_57.5 [concrete = constants.%int_3.822]
-// CHECK:STDOUT:   %.loc32_57.8: init %C to %.loc32_57.2 = class_init (%.loc32_57.4, %.loc32_57.7) [concrete = constants.%C.val]
-// CHECK:STDOUT:   %.loc32_57.9: ref %C = temporary %.loc32_57.2, %.loc32_57.8
-// CHECK:STDOUT:   %.loc32_59.1: ref %C = converted %.loc32_57.1, %.loc32_57.9
+// CHECK:STDOUT:   %impl.elem0.loc32_46: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
+// CHECK:STDOUT:   %bound_method.loc32_46.1: <bound method> = bound_method %int_1, %impl.elem0.loc32_46 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215]
+// CHECK:STDOUT:   %specific_fn.loc32_46: <specific function> = specific_function %impl.elem0.loc32_46, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
+// CHECK:STDOUT:   %bound_method.loc32_46.2: <bound method> = bound_method %int_1, %specific_fn.loc32_46 [concrete = constants.%bound_method.38b]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_46: init %i32 = call %bound_method.loc32_46.2(%int_1) [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %.loc32_46.2: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_46 [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %.loc32_64.2: ref %C = temporary_storage
+// CHECK:STDOUT:   %.loc32_64.3: ref %B = class_element_access %.loc32_64.2, element0
+// CHECK:STDOUT:   %.loc32_55.2: ref %A = class_element_access %.loc32_64.3, element0
+// CHECK:STDOUT:   %.loc32_46.3: ref %i32 = class_element_access %.loc32_55.2, element0
+// CHECK:STDOUT:   %.loc32_46.4: init %i32 to %.loc32_46.3 = in_place_init %.loc32_46.2 [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %.loc32_46.5: init %A to %.loc32_55.2 = class_init (%.loc32_46.4) [concrete = constants.%A.val]
+// CHECK:STDOUT:   %.loc32_55.3: init %A = converted %.loc32_46.1, %.loc32_46.5 [concrete = constants.%A.val]
+// CHECK:STDOUT:   %impl.elem0.loc32_55: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
+// CHECK:STDOUT:   %bound_method.loc32_55.1: <bound method> = bound_method %int_2, %impl.elem0.loc32_55 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5]
+// CHECK:STDOUT:   %specific_fn.loc32_55: <specific function> = specific_function %impl.elem0.loc32_55, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
+// CHECK:STDOUT:   %bound_method.loc32_55.2: <bound method> = bound_method %int_2, %specific_fn.loc32_55 [concrete = constants.%bound_method.646]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_55: init %i32 = call %bound_method.loc32_55.2(%int_2) [concrete = constants.%int_2.ef8]
+// CHECK:STDOUT:   %.loc32_55.4: init %i32 = converted %int_2, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_55 [concrete = constants.%int_2.ef8]
+// CHECK:STDOUT:   %.loc32_55.5: ref %i32 = class_element_access %.loc32_64.3, element1
+// CHECK:STDOUT:   %.loc32_55.6: init %i32 to %.loc32_55.5 = in_place_init %.loc32_55.4 [concrete = constants.%int_2.ef8]
+// CHECK:STDOUT:   %.loc32_55.7: init %B to %.loc32_64.3 = class_init (%.loc32_55.3, %.loc32_55.6) [concrete = constants.%B.val]
+// CHECK:STDOUT:   %.loc32_64.4: init %B = converted %.loc32_55.1, %.loc32_55.7 [concrete = constants.%B.val]
+// CHECK:STDOUT:   %impl.elem0.loc32_64: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
+// CHECK:STDOUT:   %bound_method.loc32_64.1: <bound method> = bound_method %int_3, %impl.elem0.loc32_64 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.061]
+// CHECK:STDOUT:   %specific_fn.loc32_64: <specific function> = specific_function %impl.elem0.loc32_64, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
+// CHECK:STDOUT:   %bound_method.loc32_64.2: <bound method> = bound_method %int_3, %specific_fn.loc32_64 [concrete = constants.%bound_method.fa7]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_64: init %i32 = call %bound_method.loc32_64.2(%int_3) [concrete = constants.%int_3.822]
+// CHECK:STDOUT:   %.loc32_64.5: init %i32 = converted %int_3, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32_64 [concrete = constants.%int_3.822]
+// CHECK:STDOUT:   %.loc32_64.6: ref %i32 = class_element_access %.loc32_64.2, element1
+// CHECK:STDOUT:   %.loc32_64.7: init %i32 to %.loc32_64.6 = in_place_init %.loc32_64.5 [concrete = constants.%int_3.822]
+// CHECK:STDOUT:   %.loc32_64.8: init %C to %.loc32_64.2 = class_init (%.loc32_64.4, %.loc32_64.7) [concrete = constants.%C.val]
+// CHECK:STDOUT:   %.loc32_64.9: ref %C = temporary %.loc32_64.2, %.loc32_64.8
+// CHECK:STDOUT:   %.loc32_66.1: ref %C = converted %.loc32_64.1, %.loc32_64.9
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A]
-// CHECK:STDOUT:   %.loc32_59.2: ref %B = class_element_access %.loc32_59.1, element0
-// CHECK:STDOUT:   %.loc32_59.3: ref %A = class_element_access %.loc32_59.2, element0
-// CHECK:STDOUT:   %.loc32_59.4: ref %A = converted %.loc32_59.1, %.loc32_59.3
-// CHECK:STDOUT:   %.loc32_59.5: %A = acquire_value %.loc32_59.4
-// CHECK:STDOUT:   %a: %A = value_binding a, %.loc32_59.5
-// CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %.loc32_57.9, constants.%DestroyOp
-// CHECK:STDOUT:   %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%.loc32_57.9)
+// CHECK:STDOUT:   %.loc32_66.2: ref %B = class_element_access %.loc32_66.1, element0
+// CHECK:STDOUT:   %.loc32_66.3: ref %A = class_element_access %.loc32_66.2, element0
+// CHECK:STDOUT:   %.loc32_66.4: ref %A = converted %.loc32_66.1, %.loc32_66.3
+// CHECK:STDOUT:   %.loc32_66.5: %A = acquire_value %.loc32_66.4
+// CHECK:STDOUT:   %a: %A = value_binding a, %.loc32_66.5
+// CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %.loc32_64.9, constants.%DestroyOp
+// CHECK:STDOUT:   %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%.loc32_64.9)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 18 - 18
toolchain/check/testdata/class/destroy_calls.carbon

@@ -20,9 +20,9 @@ class C {}
 
 //@dump-sem-ir-begin
 fn F() {
-  var a: A;
-  var b: B;
-  var c: C;
+  var unused a: A;
+  var unused b: B;
+  var unused c: C;
 }
 //@dump-sem-ir-end
 
@@ -36,10 +36,10 @@ class C {}
 
 //@dump-sem-ir-begin
 fn F() {
-  var a: A;
-  var b: B;
+  var unused a: A;
+  var unused b: B;
   if (true) {
-    var c: C;
+    var unused c: C;
   }
 }
 //@dump-sem-ir-end
@@ -71,7 +71,7 @@ class D(template T:! type) {}
 
 //@dump-sem-ir-begin
 fn F() {
-  var a: D(C);
+  var unused a: D(C);
 }
 //@dump-sem-ir-end
 
@@ -82,7 +82,7 @@ class C(template T:! type) {}
 
 //@dump-sem-ir-begin
 fn F(template T:! type) {
-  var v: C(T);
+  var unused v: C(T);
 }
 //@dump-sem-ir-end
 
@@ -378,11 +378,11 @@ fn G() { F({}); }
 // CHECK:STDOUT:   %T.loc6_15.1: type = symbolic_binding T, 0, template [template = %T.loc6_15.1 (constants.%T)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %C.loc7_13.2: type = class_type @C, @C(%T.loc6_15.1) [template = %C.loc7_13.2 (constants.%C.5a3)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %C.loc7_13.2 [template = %require_complete (constants.%require_complete)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %C.loc7_13.2 [template = %pattern_type (constants.%pattern_type.3d5)]
-// CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %C.loc7_13.2, @Destroy [template = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
-// CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %C.loc7_13.2, (%Destroy.lookup_impl_witness) [template = %Destroy.facet (constants.%Destroy.facet.472)]
+// CHECK:STDOUT:   %C.loc7_20.2: type = class_type @C, @C(%T.loc6_15.1) [template = %C.loc7_20.2 (constants.%C.5a3)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %C.loc7_20.2 [template = %require_complete (constants.%require_complete)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %C.loc7_20.2 [template = %pattern_type (constants.%pattern_type.3d5)]
+// CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %C.loc7_20.2, @Destroy [template = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
+// CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %C.loc7_20.2, (%Destroy.lookup_impl_witness) [template = %Destroy.facet (constants.%Destroy.facet.472)]
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type: type = fn_type @Destroy.WithSelf.Op, @Destroy(%Destroy.facet) [template = %Destroy.WithSelf.Op.type (constants.%Destroy.WithSelf.Op.type.7d1)]
 // CHECK:STDOUT:   %.loc7_3: type = fn_type_with_self_type %Destroy.WithSelf.Op.type, %Destroy.facet [template = %.loc7_3 (constants.%.306)]
 // CHECK:STDOUT:   %impl.elem0.loc7_3.2: @F.%.loc7_3 (%.306) = impl_witness_access %Destroy.lookup_impl_witness, element0 [template = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
@@ -394,13 +394,13 @@ fn G() { F({}); }
 // CHECK:STDOUT:       %v.patt: @F.%pattern_type (%pattern_type.3d5) = ref_binding_pattern v [concrete]
 // CHECK:STDOUT:       %v.var_patt: @F.%pattern_type (%pattern_type.3d5) = var_pattern %v.patt [concrete]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %v.var: ref @F.%C.loc7_13.2 (%C.5a3) = var %v.var_patt
-// CHECK:STDOUT:     %.loc7_13: type = splice_block %C.loc7_13.1 [template = %C.loc7_13.2 (constants.%C.5a3)] {
+// CHECK:STDOUT:     %v.var: ref @F.%C.loc7_20.2 (%C.5a3) = var %v.var_patt
+// CHECK:STDOUT:     %.loc7_20: type = splice_block %C.loc7_20.1 [template = %C.loc7_20.2 (constants.%C.5a3)] {
 // CHECK:STDOUT:       %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic]
 // CHECK:STDOUT:       %T.ref: type = name_ref T, %T.loc6_15.2 [template = %T.loc6_15.1 (constants.%T)]
-// CHECK:STDOUT:       %C.loc7_13.1: type = class_type @C, @C(constants.%T) [template = %C.loc7_13.2 (constants.%C.5a3)]
+// CHECK:STDOUT:       %C.loc7_20.1: type = class_type @C, @C(constants.%T) [template = %C.loc7_20.2 (constants.%C.5a3)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %v: ref @F.%C.loc7_13.2 (%C.5a3) = ref_binding v, %v.var
+// CHECK:STDOUT:     %v: ref @F.%C.loc7_20.2 (%C.5a3) = ref_binding v, %v.var
 // CHECK:STDOUT:     %impl.elem0.loc7_3.1: @F.%.loc7_3 (%.306) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [template = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
 // CHECK:STDOUT:     %bound_method.loc7_3.1: <bound method> = bound_method %v.var, %impl.elem0.loc7_3.1
 // CHECK:STDOUT:     %specific_impl_fn.loc7_3.1: <specific function> = specific_impl_function %impl.elem0.loc7_3.1, @Destroy.WithSelf.Op(constants.%Destroy.facet.472) [template = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn)]
@@ -420,7 +420,7 @@ fn G() { F({}); }
 // CHECK:STDOUT:   %T.loc6_15.1 => constants.%empty_struct_type
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %C.loc7_13.2 => constants.%C.850
+// CHECK:STDOUT:   %C.loc7_20.2 => constants.%C.850
 // CHECK:STDOUT:   %require_complete => constants.%complete_type
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.526
 // CHECK:STDOUT:   %Destroy.lookup_impl_witness => constants.%custom_witness.809

+ 36 - 40
toolchain/check/testdata/class/fail_abstract.carbon

@@ -36,14 +36,14 @@ abstract class Abstract {
 }
 
 fn Var() {
-  // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE+7]]:10: error: binding pattern has abstract type `Abstract` in `var` pattern [AbstractTypeInVarPattern]
-  // CHECK:STDERR:   var v: Abstract;
-  // CHECK:STDERR:          ^~~~~~~~
+  // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE+7]]:17: error: binding pattern has abstract type `Abstract` in `var` pattern [AbstractTypeInVarPattern]
+  // CHECK:STDERR:   var unused v: Abstract;
+  // CHECK:STDERR:                 ^~~~~~~~
   // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE-7]]:1: note: class was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var v: Abstract;
+  var unused v: Abstract;
 }
 
 // --- fail_abstract_var_function_param.carbon
@@ -53,13 +53,13 @@ abstract class Abstract {
 }
 
 // CHECK:STDERR: fail_abstract_var_function_param.carbon:[[@LINE+7]]:13: error: binding pattern has abstract type `Abstract` in `var` pattern [AbstractTypeInVarPattern]
-// CHECK:STDERR: fn F(var p: Abstract) {
+// CHECK:STDERR: fn F(var _: Abstract) {
 // CHECK:STDERR:             ^~~~~~~~
 // CHECK:STDERR: fail_abstract_var_function_param.carbon:[[@LINE-6]]:1: note: class was declared abstract here [ClassAbstractHere]
 // CHECK:STDERR: abstract class Abstract {
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
-fn F(var p: Abstract) {
+fn F(var _: Abstract) {
 }
 
 // --- fail_todo_abstract_let.carbon
@@ -69,14 +69,14 @@ abstract class Abstract {
 }
 
 fn F(a: Abstract) {
-  // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE+7]]:21: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
-  // CHECK:STDERR:   let l: Abstract = a;
-  // CHECK:STDERR:                     ^
+  // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE+7]]:28: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
+  // CHECK:STDERR:   let unused l: Abstract = a;
+  // CHECK:STDERR:                            ^
   // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE-7]]:1: note: class was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let l: Abstract = a;
+  let unused l: Abstract = a;
 }
 
 // --- fail_abstract_adapter.carbon
@@ -197,18 +197,14 @@ abstract class Abstract {
 }
 
 fn F() {
-  // An abstract value of a class type that has a pointer value representation
-  // is allowed, but it has to be initialized from some a value of some concrete
-  // class type.
-  //
-  // CHECK:STDERR: fail_abstract_let_temporary_struct_literal.carbon:[[@LINE+7]]:21: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
-  // CHECK:STDERR:   let l: Abstract = {};
-  // CHECK:STDERR:                     ^~
-  // CHECK:STDERR: fail_abstract_let_temporary_struct_literal.carbon:[[@LINE-11]]:1: note: class was declared abstract here [ClassAbstractHere]
+  // CHECK:STDERR: fail_abstract_let_temporary_struct_literal.carbon:[[@LINE+7]]:28: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
+  // CHECK:STDERR:   let unused l: Abstract = {};
+  // CHECK:STDERR:                            ^~
+  // CHECK:STDERR: fail_abstract_let_temporary_struct_literal.carbon:[[@LINE-7]]:1: note: class was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let l: Abstract = {};
+  let unused l: Abstract = {};
 }
 
 // --- fail_todo_abstract_let_temporary.carbon
@@ -226,21 +222,21 @@ fn F() {
   // to the `Abstract` value since `Abstract` and `Derived` have pointer value
   // representations.
   //
-  // CHECK:STDERR: fail_todo_abstract_let_temporary.carbon:[[@LINE+14]]:21: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
-  // CHECK:STDERR:   let l: Abstract = {.base = {}} as Derived;
-  // CHECK:STDERR:                     ^~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_abstract_let_temporary.carbon:[[@LINE+14]]:28: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
+  // CHECK:STDERR:   let unused l: Abstract = {.base = {}} as Derived;
+  // CHECK:STDERR:                            ^~~~~~~~~~~~
   // CHECK:STDERR: fail_todo_abstract_let_temporary.carbon:[[@LINE-15]]:1: note: class was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  // CHECK:STDERR: fail_todo_abstract_let_temporary.carbon:[[@LINE+7]]:21: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
-  // CHECK:STDERR:   let l: Abstract = {.base = {}} as Derived;
-  // CHECK:STDERR:                     ^~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_abstract_let_temporary.carbon:[[@LINE+7]]:28: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
+  // CHECK:STDERR:   let unused l: Abstract = {.base = {}} as Derived;
+  // CHECK:STDERR:                            ^~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_todo_abstract_let_temporary.carbon:[[@LINE-22]]:1: note: class was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let l: Abstract = {.base = {}} as Derived;
+  let unused l: Abstract = {.base = {}} as Derived;
 }
 
 // --- fail_call_abstract_return.carbon
@@ -389,13 +385,13 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Abstract.decl: type = class_decl @Abstract [concrete = constants.%Abstract] {} {}
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
-// CHECK:STDOUT:     %p.patt: <error> = ref_binding_pattern p [concrete]
-// CHECK:STDOUT:     %p.param_patt: <error> = var_param_pattern %p.patt, call_param0 [concrete]
-// CHECK:STDOUT:     %p.var_patt: <error> = var_pattern %p.param_patt [concrete]
+// CHECK:STDOUT:     %_.patt: <error> = ref_binding_pattern _ [concrete]
+// CHECK:STDOUT:     %_.param_patt: <error> = var_param_pattern %_.patt, call_param0 [concrete]
+// CHECK:STDOUT:     %_.var_patt: <error> = var_pattern %_.param_patt [concrete]
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %p.param: ref <error> = ref_param call_param0
+// CHECK:STDOUT:     %_.param: ref <error> = ref_param call_param0
 // CHECK:STDOUT:     %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract]
-// CHECK:STDOUT:     %p: ref <error> = ref_binding p, %p.param
+// CHECK:STDOUT:     %_: ref <error> = ref_binding _, %_.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -407,7 +403,7 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:   .Self = constants.%Abstract
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%p.param: ref <error>) {
+// CHECK:STDOUT: fn @F(%_.param: ref <error>) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -878,7 +874,7 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %l.patt: %pattern_type = value_binding_pattern l [concrete]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc18: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
+// CHECK:STDOUT:   %.loc14: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
 // CHECK:STDOUT:   %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract]
 // CHECK:STDOUT:   %l: %Abstract = value_binding l, <error> [concrete = <error>]
 // CHECK:STDOUT:   return
@@ -954,16 +950,16 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %l.patt: %pattern_type.a2e = value_binding_pattern l [concrete]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc29_31: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
-// CHECK:STDOUT:   %.loc29_32.1: %struct_type.base.f5e = struct_literal (%.loc29_31) [concrete = constants.%struct]
+// CHECK:STDOUT:   %.loc29_38: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
+// CHECK:STDOUT:   %.loc29_39.1: %struct_type.base.f5e = struct_literal (%.loc29_38) [concrete = constants.%struct]
 // CHECK:STDOUT:   %Derived.ref: type = name_ref Derived, file.%Derived.decl [concrete = constants.%Derived]
-// CHECK:STDOUT:   %.loc29_32.2: ref %Derived = temporary_storage
-// CHECK:STDOUT:   %.loc29_32.3: ref %Derived = temporary %.loc29_32.2, <error>
-// CHECK:STDOUT:   %.loc29_34: ref %Derived = converted %.loc29_32.1, %.loc29_32.3
+// CHECK:STDOUT:   %.loc29_39.2: ref %Derived = temporary_storage
+// CHECK:STDOUT:   %.loc29_39.3: ref %Derived = temporary %.loc29_39.2, <error>
+// CHECK:STDOUT:   %.loc29_41: ref %Derived = converted %.loc29_39.1, %.loc29_39.3
 // CHECK:STDOUT:   %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract]
 // CHECK:STDOUT:   %l: %Abstract = value_binding l, <error> [concrete = <error>]
-// CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %.loc29_32.3, constants.%DestroyOp
-// CHECK:STDOUT:   %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%.loc29_32.3)
+// CHECK:STDOUT:   %DestroyOp.bound: <bound method> = bound_method %.loc29_39.3, constants.%DestroyOp
+// CHECK:STDOUT:   %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%.loc29_39.3)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 6 - 6
toolchain/check/testdata/class/fail_abstract_in_struct.carbon

@@ -49,14 +49,14 @@ abstract class Abstract3 {
 }
 
 fn F(a: Abstract3) {
-  // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE+7]]:29: error: initialization of abstract type `{.m3: Abstract3}` [AbstractTypeInInit]
-  // CHECK:STDERR:   let l: {.m3: Abstract3} = {.m3 = a};
-  // CHECK:STDERR:                             ^~~~~~~~~
+  // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE+7]]:36: error: initialization of abstract type `{.m3: Abstract3}` [AbstractTypeInInit]
+  // CHECK:STDERR:   let unused l: {.m3: Abstract3} = {.m3 = a};
+  // CHECK:STDERR:                                    ^~~~~~~~~
   // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE-7]]:1: note: uses class that was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract3 {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let l: {.m3: Abstract3} = {.m3 = a};
+  let unused l: {.m3: Abstract3} = {.m3 = a};
 }
 
 // --- fail_abstract_twice.carbon
@@ -240,8 +240,8 @@ var v5: {.m: Abstract};
 // CHECK:STDOUT:     %l.patt: %pattern_type.816 = value_binding_pattern l [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.ref: %Abstract3 = name_ref a, %a
-// CHECK:STDOUT:   %.loc14_37: %struct_type.m3.b1b = struct_literal (%a.ref)
-// CHECK:STDOUT:   %.loc14_25: type = splice_block %struct_type.m3 [concrete = constants.%struct_type.m3.b1b] {
+// CHECK:STDOUT:   %.loc14_44: %struct_type.m3.b1b = struct_literal (%a.ref)
+// CHECK:STDOUT:   %.loc14_32: type = splice_block %struct_type.m3 [concrete = constants.%struct_type.m3.b1b] {
 // CHECK:STDOUT:     %Abstract3.ref.loc14: type = name_ref Abstract3, file.%Abstract3.decl [concrete = constants.%Abstract3]
 // CHECK:STDOUT:     %struct_type.m3: type = struct_type {.m3: %Abstract3} [concrete = constants.%struct_type.m3.b1b]
 // CHECK:STDOUT:   }

+ 47 - 47
toolchain/check/testdata/class/fail_abstract_in_tuple.carbon

@@ -34,14 +34,14 @@ library "[[@TEST_NAME]]";
 abstract class Abstract2 {}
 
 fn Var() {
-  // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE+7]]:10: error: binding pattern has abstract type `(Abstract2,)` in `var` pattern [AbstractTypeInVarPattern]
-  // CHECK:STDERR:   var v: (Abstract2,);
-  // CHECK:STDERR:          ^~~~~~~~~~~~
+  // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE+7]]:17: error: binding pattern has abstract type `(Abstract2,)` in `var` pattern [AbstractTypeInVarPattern]
+  // CHECK:STDERR:   var unused v: (Abstract2,);
+  // CHECK:STDERR:                 ^~~~~~~~~~~~
   // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract2 {}
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var v: (Abstract2,);
+  var unused v: (Abstract2,);
 }
 
 // --- fail_todo_abstract_let.carbon
@@ -51,14 +51,14 @@ abstract class Abstract3 {
 }
 
 fn F(a: Abstract3) {
-  // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE+7]]:25: error: initialization of abstract type `(Abstract3,)` [AbstractTypeInInit]
-  // CHECK:STDERR:   let l: (Abstract3,) = (a,);
-  // CHECK:STDERR:                         ^~~~
+  // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE+7]]:32: error: initialization of abstract type `(Abstract3,)` [AbstractTypeInInit]
+  // CHECK:STDERR:   let unused l: (Abstract3,) = (a,);
+  // CHECK:STDERR:                                ^~~~
   // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE-7]]:1: note: uses class that was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract3 {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  let l: (Abstract3,) = (a,);
+  let unused l: (Abstract3,) = (a,);
 }
 
 // --- fail_abstract_twice.carbon
@@ -68,14 +68,14 @@ abstract class Abstract4 {}
 abstract class Abstract5 {}
 
 fn Var2() {
-  // CHECK:STDERR: fail_abstract_twice.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `(Abstract4, Abstract5)` in `var` pattern [AbstractTypeInVarPattern]
-  // CHECK:STDERR:   var v2: (Abstract4, Abstract5);
-  // CHECK:STDERR:           ^~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_abstract_twice.carbon:[[@LINE+7]]:18: error: binding pattern has abstract type `(Abstract4, Abstract5)` in `var` pattern [AbstractTypeInVarPattern]
+  // CHECK:STDERR:   var unused v2: (Abstract4, Abstract5);
+  // CHECK:STDERR:                  ^~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_abstract_twice.carbon:[[@LINE-7]]:1: note: uses class that was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract4 {}
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var v2: (Abstract4, Abstract5);
+  var unused v2: (Abstract4, Abstract5);
 }
 
 // --- fail_abstract_first.carbon
@@ -84,14 +84,14 @@ library "[[@TEST_NAME]]";
 abstract class Abstract6 {}
 
 fn Var3() {
-  // CHECK:STDERR: fail_abstract_first.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `(Abstract6, {})` in `var` pattern [AbstractTypeInVarPattern]
-  // CHECK:STDERR:   var v3: (Abstract6, {});
-  // CHECK:STDERR:           ^~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_abstract_first.carbon:[[@LINE+7]]:18: error: binding pattern has abstract type `(Abstract6, {})` in `var` pattern [AbstractTypeInVarPattern]
+  // CHECK:STDERR:   var unused v3: (Abstract6, {});
+  // CHECK:STDERR:                  ^~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_abstract_first.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract6 {}
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var v3: (Abstract6, {});
+  var unused v3: (Abstract6, {});
 }
 
 // --- fail_abstract_second.carbon
@@ -100,14 +100,14 @@ library "[[@TEST_NAME]]";
 abstract class Abstract7 {}
 
 fn Var4() {
-  // CHECK:STDERR: fail_abstract_second.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `({}, Abstract7)` in `var` pattern [AbstractTypeInVarPattern]
-  // CHECK:STDERR:   var v4: ({}, Abstract7);
-  // CHECK:STDERR:           ^~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_abstract_second.carbon:[[@LINE+7]]:18: error: binding pattern has abstract type `({}, Abstract7)` in `var` pattern [AbstractTypeInVarPattern]
+  // CHECK:STDERR:   var unused v4: ({}, Abstract7);
+  // CHECK:STDERR:                  ^~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_abstract_second.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract7 {}
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var v4: ({}, Abstract7);
+  var unused v4: ({}, Abstract7);
 }
 
 // --- lib.carbon
@@ -121,15 +121,15 @@ library "[[@TEST_NAME]]";
 import library "lib";
 
 fn Var5() {
-  // CHECK:STDERR: fail_import.carbon:[[@LINE+8]]:11: error: binding pattern has abstract type `(Abstract,)` in `var` pattern [AbstractTypeInVarPattern]
-  // CHECK:STDERR:   var v5: (Abstract,);
-  // CHECK:STDERR:           ^~~~~~~~~~~
+  // CHECK:STDERR: fail_import.carbon:[[@LINE+8]]:18: error: binding pattern has abstract type `(Abstract,)` in `var` pattern [AbstractTypeInVarPattern]
+  // CHECK:STDERR:   var unused v5: (Abstract,);
+  // CHECK:STDERR:                  ^~~~~~~~~~~
   // CHECK:STDERR: fail_import.carbon:[[@LINE-6]]:1: in import [InImport]
   // CHECK:STDERR: lib.carbon:3:1: note: uses class that was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract {}
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var v5: (Abstract,);
+  var unused v5: (Abstract,);
 }
 
 // CHECK:STDOUT: --- fail_abstract_field.carbon
@@ -233,10 +233,10 @@ fn Var5() {
 // CHECK:STDOUT:     %v.var_patt: <error> = var_pattern %v.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v.var: ref <error> = var %v.var_patt [concrete = <error>]
-// CHECK:STDOUT:   %.loc13_21.1: type = splice_block %.loc13_21.3 [concrete = constants.%tuple.type.d46] {
+// CHECK:STDOUT:   %.loc13_28.1: type = splice_block %.loc13_28.3 [concrete = constants.%tuple.type.d46] {
 // CHECK:STDOUT:     %Abstract2.ref: type = name_ref Abstract2, file.%Abstract2.decl [concrete = constants.%Abstract2]
-// CHECK:STDOUT:     %.loc13_21.2: %tuple.type.85c = tuple_literal (%Abstract2.ref) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc13_21.3: type = converted %.loc13_21.2, constants.%tuple.type.d46 [concrete = constants.%tuple.type.d46]
+// CHECK:STDOUT:     %.loc13_28.2: %tuple.type.85c = tuple_literal (%Abstract2.ref) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc13_28.3: type = converted %.loc13_28.2, constants.%tuple.type.d46 [concrete = constants.%tuple.type.d46]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v: ref <error> = ref_binding v, <error> [concrete = <error>]
 // CHECK:STDOUT:   return
@@ -296,11 +296,11 @@ fn Var5() {
 // CHECK:STDOUT:     %l.patt: %pattern_type.016 = value_binding_pattern l [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.ref: %Abstract3 = name_ref a, %a
-// CHECK:STDOUT:   %.loc14_28: %tuple.type.c99 = tuple_literal (%a.ref)
-// CHECK:STDOUT:   %.loc14_21.1: type = splice_block %.loc14_21.3 [concrete = constants.%tuple.type.c99] {
+// CHECK:STDOUT:   %.loc14_35: %tuple.type.c99 = tuple_literal (%a.ref)
+// CHECK:STDOUT:   %.loc14_28.1: type = splice_block %.loc14_28.3 [concrete = constants.%tuple.type.c99] {
 // CHECK:STDOUT:     %Abstract3.ref.loc14: type = name_ref Abstract3, file.%Abstract3.decl [concrete = constants.%Abstract3]
-// CHECK:STDOUT:     %.loc14_21.2: %tuple.type.85c = tuple_literal (%Abstract3.ref.loc14) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc14_21.3: type = converted %.loc14_21.2, constants.%tuple.type.c99 [concrete = constants.%tuple.type.c99]
+// CHECK:STDOUT:     %.loc14_28.2: %tuple.type.85c = tuple_literal (%Abstract3.ref.loc14) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc14_28.3: type = converted %.loc14_28.2, constants.%tuple.type.c99 [concrete = constants.%tuple.type.c99]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %l: %tuple.type.c99 = value_binding l, <error> [concrete = <error>]
 // CHECK:STDOUT:   return
@@ -366,11 +366,11 @@ fn Var5() {
 // CHECK:STDOUT:     %v2.var_patt: <error> = var_pattern %v2.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v2.var: ref <error> = var %v2.var_patt [concrete = <error>]
-// CHECK:STDOUT:   %.loc14_32.1: type = splice_block %.loc14_32.3 [concrete = constants.%tuple.type.fa1] {
+// CHECK:STDOUT:   %.loc14_39.1: type = splice_block %.loc14_39.3 [concrete = constants.%tuple.type.fa1] {
 // CHECK:STDOUT:     %Abstract4.ref: type = name_ref Abstract4, file.%Abstract4.decl [concrete = constants.%Abstract4]
 // CHECK:STDOUT:     %Abstract5.ref: type = name_ref Abstract5, file.%Abstract5.decl [concrete = constants.%Abstract5]
-// CHECK:STDOUT:     %.loc14_32.2: %tuple.type.24b = tuple_literal (%Abstract4.ref, %Abstract5.ref) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc14_32.3: type = converted %.loc14_32.2, constants.%tuple.type.fa1 [concrete = constants.%tuple.type.fa1]
+// CHECK:STDOUT:     %.loc14_39.2: %tuple.type.24b = tuple_literal (%Abstract4.ref, %Abstract5.ref) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc14_39.3: type = converted %.loc14_39.2, constants.%tuple.type.fa1 [concrete = constants.%tuple.type.fa1]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v2: ref <error> = ref_binding v2, <error> [concrete = <error>]
 // CHECK:STDOUT:   return
@@ -426,12 +426,12 @@ fn Var5() {
 // CHECK:STDOUT:     %v3.var_patt: <error> = var_pattern %v3.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v3.var: ref <error> = var %v3.var_patt [concrete = <error>]
-// CHECK:STDOUT:   %.loc13_25.1: type = splice_block %.loc13_25.4 [concrete = constants.%tuple.type.a75] {
+// CHECK:STDOUT:   %.loc13_32.1: type = splice_block %.loc13_32.4 [concrete = constants.%tuple.type.a75] {
 // CHECK:STDOUT:     %Abstract6.ref: type = name_ref Abstract6, file.%Abstract6.decl [concrete = constants.%Abstract6]
-// CHECK:STDOUT:     %.loc13_24: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
-// CHECK:STDOUT:     %.loc13_25.2: %tuple.type.159 = tuple_literal (%Abstract6.ref, %.loc13_24) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc13_25.3: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
-// CHECK:STDOUT:     %.loc13_25.4: type = converted %.loc13_25.2, constants.%tuple.type.a75 [concrete = constants.%tuple.type.a75]
+// CHECK:STDOUT:     %.loc13_31: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
+// CHECK:STDOUT:     %.loc13_32.2: %tuple.type.159 = tuple_literal (%Abstract6.ref, %.loc13_31) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc13_32.3: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:     %.loc13_32.4: type = converted %.loc13_32.2, constants.%tuple.type.a75 [concrete = constants.%tuple.type.a75]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v3: ref <error> = ref_binding v3, <error> [concrete = <error>]
 // CHECK:STDOUT:   return
@@ -487,12 +487,12 @@ fn Var5() {
 // CHECK:STDOUT:     %v4.var_patt: <error> = var_pattern %v4.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v4.var: ref <error> = var %v4.var_patt [concrete = <error>]
-// CHECK:STDOUT:   %.loc13_25.1: type = splice_block %.loc13_25.4 [concrete = constants.%tuple.type.ff9] {
-// CHECK:STDOUT:     %.loc13_13: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
+// CHECK:STDOUT:   %.loc13_32.1: type = splice_block %.loc13_32.4 [concrete = constants.%tuple.type.ff9] {
+// CHECK:STDOUT:     %.loc13_20: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
 // CHECK:STDOUT:     %Abstract7.ref: type = name_ref Abstract7, file.%Abstract7.decl [concrete = constants.%Abstract7]
-// CHECK:STDOUT:     %.loc13_25.2: %tuple.type.c8c = tuple_literal (%.loc13_13, %Abstract7.ref) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc13_25.3: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
-// CHECK:STDOUT:     %.loc13_25.4: type = converted %.loc13_25.2, constants.%tuple.type.ff9 [concrete = constants.%tuple.type.ff9]
+// CHECK:STDOUT:     %.loc13_32.2: %tuple.type.c8c = tuple_literal (%.loc13_20, %Abstract7.ref) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc13_32.3: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:     %.loc13_32.4: type = converted %.loc13_32.2, constants.%tuple.type.ff9 [concrete = constants.%tuple.type.ff9]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v4: ref <error> = ref_binding v4, <error> [concrete = <error>]
 // CHECK:STDOUT:   return
@@ -581,10 +581,10 @@ fn Var5() {
 // CHECK:STDOUT:     %v5.var_patt: <error> = var_pattern %v5.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v5.var: ref <error> = var %v5.var_patt [concrete = <error>]
-// CHECK:STDOUT:   %.loc14_21.1: type = splice_block %.loc14_21.3 [concrete = constants.%tuple.type.e3a] {
+// CHECK:STDOUT:   %.loc14_28.1: type = splice_block %.loc14_28.3 [concrete = constants.%tuple.type.e3a] {
 // CHECK:STDOUT:     %Abstract.ref: type = name_ref Abstract, imports.%Main.Abstract [concrete = constants.%Abstract]
-// CHECK:STDOUT:     %.loc14_21.2: %tuple.type.85c = tuple_literal (%Abstract.ref) [concrete = constants.%tuple]
-// CHECK:STDOUT:     %.loc14_21.3: type = converted %.loc14_21.2, constants.%tuple.type.e3a [concrete = constants.%tuple.type.e3a]
+// CHECK:STDOUT:     %.loc14_28.2: %tuple.type.85c = tuple_literal (%Abstract.ref) [concrete = constants.%tuple]
+// CHECK:STDOUT:     %.loc14_28.3: type = converted %.loc14_28.2, constants.%tuple.type.e3a [concrete = constants.%tuple.type.e3a]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v5: ref <error> = ref_binding v5, <error> [concrete = <error>]
 // CHECK:STDOUT:   return

+ 5 - 5
toolchain/check/testdata/class/fail_error_recovery.carbon

@@ -12,13 +12,13 @@
 
 // --- fail_virtual_fn_in_invalid_context.carbon
 
-// CHECK:STDERR: fail_virtual_fn_in_invalid_context.carbon:[[@LINE+4]]:10: error: name `error_not_found` not found [NameNotFound]
-// CHECK:STDERR: fn F(N:! error_not_found) {
-// CHECK:STDERR:          ^~~~~~~~~~~~~~~
+// CHECK:STDERR: fail_virtual_fn_in_invalid_context.carbon:[[@LINE+4]]:17: error: name `error_not_found` not found [NameNotFound]
+// CHECK:STDERR: fn F(unused N:! error_not_found) {
+// CHECK:STDERR:                 ^~~~~~~~~~~~~~~
 // CHECK:STDERR:
-fn F(N:! error_not_found) {
+fn F(unused N:! error_not_found) {
   base class C {
-    virtual fn Foo[self: Self]() {}
+    virtual fn Foo[unused self: Self]() {}
   }
 
   base class D {

+ 10 - 10
toolchain/check/testdata/class/fail_generic_method.carbon

@@ -19,19 +19,19 @@ class Class(T:! type) {
 
 // TODO: The follow-on errors here aren't great. Investigate whether we can
 // enter the scope anyway if the parameters don't match.
-// CHECK:STDERR: fail_generic_method.carbon:[[@LINE+15]]:10: error: type `<pattern for I>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for type>` [RedeclParamDiffersType]
-// CHECK:STDERR: fn Class(N:! I).F[self: Self](n: T) {}
-// CHECK:STDERR:          ^
+// CHECK:STDERR: fail_generic_method.carbon:[[@LINE+15]]:17: error: type `<pattern for I>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for type>` [RedeclParamDiffersType]
+// CHECK:STDERR: fn Class(unused N:! I).F[unused self: Self](unused n: T) {}
+// CHECK:STDERR:                 ^
 // CHECK:STDERR: fail_generic_method.carbon:[[@LINE-10]]:13: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
 // CHECK:STDERR: class Class(T:! type) {
 // CHECK:STDERR:             ^
 // CHECK:STDERR:
-// CHECK:STDERR: fail_generic_method.carbon:[[@LINE+8]]:25: error: name `Self` not found [NameNotFound]
-// CHECK:STDERR: fn Class(N:! I).F[self: Self](n: T) {}
-// CHECK:STDERR:                         ^~~~
+// CHECK:STDERR: fail_generic_method.carbon:[[@LINE+8]]:39: error: name `Self` not found [NameNotFound]
+// CHECK:STDERR: fn Class(unused N:! I).F[unused self: Self](unused n: T) {}
+// CHECK:STDERR:                                       ^~~~
 // CHECK:STDERR:
-// CHECK:STDERR: fail_generic_method.carbon:[[@LINE+4]]:34: error: name `T` not found [NameNotFound]
-// CHECK:STDERR: fn Class(N:! I).F[self: Self](n: T) {}
-// CHECK:STDERR:                                  ^
+// CHECK:STDERR: fail_generic_method.carbon:[[@LINE+4]]:55: error: name `T` not found [NameNotFound]
+// CHECK:STDERR: fn Class(unused N:! I).F[unused self: Self](unused n: T) {}
+// CHECK:STDERR:                                                       ^
 // CHECK:STDERR:
-fn Class(N:! I).F[self: Self](n: T) {}
+fn Class(unused N:! I).F[unused self: Self](unused n: T) {}

+ 4 - 4
toolchain/check/testdata/class/fail_incomplete.carbon

@@ -88,14 +88,14 @@ fn Copy(p: Class*) -> Class {
 }
 
 fn Let(p: Class*) {
-  // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+7]]:10: error: binding pattern has incomplete type `Class` in name binding declaration [IncompleteTypeInBindingDecl]
-  // CHECK:STDERR:   let c: Class = *p;
-  // CHECK:STDERR:          ^~~~~
+  // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+7]]:17: error: binding pattern has incomplete type `Class` in name binding declaration [IncompleteTypeInBindingDecl]
+  // CHECK:STDERR:   let unused c: Class = *p;
+  // CHECK:STDERR:                 ^~~~~
   // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-77]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
   // CHECK:STDERR: class Class;
   // CHECK:STDERR: ^~~~~~~~~~~~
   // CHECK:STDERR:
-  let c: Class = *p;
+  let unused c: Class = *p;
 }
 
 fn TakeIncomplete(c: Class);

+ 9 - 9
toolchain/check/testdata/class/fail_modifiers.carbon

@@ -85,16 +85,16 @@ abstract protected class WrongOrder { }
 abstract base class AbstractAndBase {}
 
 abstract class AbstractWithDefinition {
-  // CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:31: error: definition of `abstract` function [DefinedAbstractFunction]
-  // CHECK:STDERR:   abstract fn F[self: Self]() {}
-  // CHECK:STDERR:                               ^
+  // CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:38: error: definition of `abstract` function [DefinedAbstractFunction]
+  // CHECK:STDERR:   abstract fn F[unused self: Self]() {}
+  // CHECK:STDERR:                                      ^
   // CHECK:STDERR:
-  abstract fn F[self: Self]() {}
-  abstract fn G[self: Self]();
+  abstract fn F[unused self: Self]() {}
+  abstract fn G[unused self: Self]();
 }
-// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:43: error: definition of `abstract` function [DefinedAbstractFunction]
-// CHECK:STDERR: fn AbstractWithDefinition.G[self: Self]() {
-// CHECK:STDERR:                                           ^
+// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:50: error: definition of `abstract` function [DefinedAbstractFunction]
+// CHECK:STDERR: fn AbstractWithDefinition.G[unused self: Self]() {
+// CHECK:STDERR:                                                  ^
 // CHECK:STDERR:
-fn AbstractWithDefinition.G[self: Self]() {
+fn AbstractWithDefinition.G[unused self: Self]() {
 }

+ 4 - 4
toolchain/check/testdata/class/fail_self.carbon

@@ -20,11 +20,11 @@ class Class {
   fn G() -> Self;
 }
 
-// CHECK:STDERR: fail_self.carbon:[[@LINE+4]]:12: error: `self` can only be declared in an implicit parameter list [SelfOutsideImplicitParamList]
-// CHECK:STDERR: fn Class.F(self: Self) {
-// CHECK:STDERR:            ^~~~~~~~~~
+// CHECK:STDERR: fail_self.carbon:[[@LINE+4]]:19: error: `self` can only be declared in an implicit parameter list [SelfOutsideImplicitParamList]
+// CHECK:STDERR: fn Class.F(unused self: Self) {
+// CHECK:STDERR:                   ^~~~~~~~~~
 // CHECK:STDERR:
-fn Class.F(self: Self) {
+fn Class.F(unused self: Self) {
 }
 
 fn Class.G() -> Self {

+ 14 - 14
toolchain/check/testdata/class/field_access.carbon

@@ -21,8 +21,8 @@ fn Run() {
   var c: Class;
   c.j = 1;
   c.k = 2;
-  var cj: i32 = c.j;
-  var ck: i32 = c.k;
+  var unused cj: i32 = c.j;
+  var unused ck: i32 = c.k;
 }
 
 // CHECK:STDOUT: --- field_access.carbon
@@ -164,15 +164,15 @@ fn Run() {
 // CHECK:STDOUT:   %cj.var: ref %i32 = var %cj.var_patt
 // CHECK:STDOUT:   %c.ref.loc24: ref %Class = name_ref c, %c
 // CHECK:STDOUT:   %j.ref.loc24: %Class.elem = name_ref j, @Class.%.loc16 [concrete = @Class.%.loc16]
-// CHECK:STDOUT:   %.loc24_18.1: ref %i32 = class_element_access %c.ref.loc24, element0
-// CHECK:STDOUT:   %.loc24_18.2: %i32 = acquire_value %.loc24_18.1
+// CHECK:STDOUT:   %.loc24_25.1: ref %i32 = class_element_access %c.ref.loc24, element0
+// CHECK:STDOUT:   %.loc24_25.2: %i32 = acquire_value %.loc24_25.1
 // CHECK:STDOUT:   %impl.elem0.loc24: %.8e2 = impl_witness_access constants.%Copy.impl_witness.f17, element0 [concrete = constants.%Int.as.Copy.impl.Op.664]
-// CHECK:STDOUT:   %bound_method.loc24_18.1: <bound method> = bound_method %.loc24_18.2, %impl.elem0.loc24
+// CHECK:STDOUT:   %bound_method.loc24_25.1: <bound method> = bound_method %.loc24_25.2, %impl.elem0.loc24
 // CHECK:STDOUT:   %specific_fn.loc24: <specific function> = specific_function %impl.elem0.loc24, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc24_18.2: <bound method> = bound_method %.loc24_18.2, %specific_fn.loc24
-// CHECK:STDOUT:   %Int.as.Copy.impl.Op.call.loc24: init %i32 = call %bound_method.loc24_18.2(%.loc24_18.2)
+// CHECK:STDOUT:   %bound_method.loc24_25.2: <bound method> = bound_method %.loc24_25.2, %specific_fn.loc24
+// CHECK:STDOUT:   %Int.as.Copy.impl.Op.call.loc24: init %i32 = call %bound_method.loc24_25.2(%.loc24_25.2)
 // CHECK:STDOUT:   assign %cj.var, %Int.as.Copy.impl.Op.call.loc24
-// CHECK:STDOUT:   %.loc24_11: type = splice_block %i32.loc24 [concrete = constants.%i32] {
+// CHECK:STDOUT:   %.loc24_18: type = splice_block %i32.loc24 [concrete = constants.%i32] {
 // CHECK:STDOUT:     %int_32.loc24: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32.loc24: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   }
@@ -184,15 +184,15 @@ fn Run() {
 // CHECK:STDOUT:   %ck.var: ref %i32 = var %ck.var_patt
 // CHECK:STDOUT:   %c.ref.loc25: ref %Class = name_ref c, %c
 // CHECK:STDOUT:   %k.ref.loc25: %Class.elem = name_ref k, @Class.%.loc17 [concrete = @Class.%.loc17]
-// CHECK:STDOUT:   %.loc25_18.1: ref %i32 = class_element_access %c.ref.loc25, element1
-// CHECK:STDOUT:   %.loc25_18.2: %i32 = acquire_value %.loc25_18.1
+// CHECK:STDOUT:   %.loc25_25.1: ref %i32 = class_element_access %c.ref.loc25, element1
+// CHECK:STDOUT:   %.loc25_25.2: %i32 = acquire_value %.loc25_25.1
 // CHECK:STDOUT:   %impl.elem0.loc25: %.8e2 = impl_witness_access constants.%Copy.impl_witness.f17, element0 [concrete = constants.%Int.as.Copy.impl.Op.664]
-// CHECK:STDOUT:   %bound_method.loc25_18.1: <bound method> = bound_method %.loc25_18.2, %impl.elem0.loc25
+// CHECK:STDOUT:   %bound_method.loc25_25.1: <bound method> = bound_method %.loc25_25.2, %impl.elem0.loc25
 // CHECK:STDOUT:   %specific_fn.loc25: <specific function> = specific_function %impl.elem0.loc25, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc25_18.2: <bound method> = bound_method %.loc25_18.2, %specific_fn.loc25
-// CHECK:STDOUT:   %Int.as.Copy.impl.Op.call.loc25: init %i32 = call %bound_method.loc25_18.2(%.loc25_18.2)
+// CHECK:STDOUT:   %bound_method.loc25_25.2: <bound method> = bound_method %.loc25_25.2, %specific_fn.loc25
+// CHECK:STDOUT:   %Int.as.Copy.impl.Op.call.loc25: init %i32 = call %bound_method.loc25_25.2(%.loc25_25.2)
 // CHECK:STDOUT:   assign %ck.var, %Int.as.Copy.impl.Op.call.loc25
-// CHECK:STDOUT:   %.loc25_11: type = splice_block %i32.loc25 [concrete = constants.%i32] {
+// CHECK:STDOUT:   %.loc25_18: type = splice_block %i32.loc25 [concrete = constants.%i32] {
 // CHECK:STDOUT:     %int_32.loc25: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32.loc25: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   }

+ 14 - 14
toolchain/check/testdata/class/field_access_in_value.carbon

@@ -22,8 +22,8 @@ fn Test() {
   cv.j = 1;
   cv.k = 2;
   let c: Class = cv;
-  var cj: i32 = c.j;
-  var ck: i32 = c.k;
+  var unused cj: i32 = c.j;
+  var unused ck: i32 = c.k;
 }
 
 // CHECK:STDOUT: --- field_access_in_value.carbon
@@ -172,15 +172,15 @@ fn Test() {
 // CHECK:STDOUT:   %cj.var: ref %i32 = var %cj.var_patt
 // CHECK:STDOUT:   %c.ref.loc25: %Class = name_ref c, %c
 // CHECK:STDOUT:   %j.ref.loc25: %Class.elem = name_ref j, @Class.%.loc16 [concrete = @Class.%.loc16]
-// CHECK:STDOUT:   %.loc25_18.1: ref %i32 = class_element_access %c.ref.loc25, element0
-// CHECK:STDOUT:   %.loc25_18.2: %i32 = acquire_value %.loc25_18.1
+// CHECK:STDOUT:   %.loc25_25.1: ref %i32 = class_element_access %c.ref.loc25, element0
+// CHECK:STDOUT:   %.loc25_25.2: %i32 = acquire_value %.loc25_25.1
 // CHECK:STDOUT:   %impl.elem0.loc25: %.8e2 = impl_witness_access constants.%Copy.impl_witness.f17, element0 [concrete = constants.%Int.as.Copy.impl.Op.664]
-// CHECK:STDOUT:   %bound_method.loc25_18.1: <bound method> = bound_method %.loc25_18.2, %impl.elem0.loc25
+// CHECK:STDOUT:   %bound_method.loc25_25.1: <bound method> = bound_method %.loc25_25.2, %impl.elem0.loc25
 // CHECK:STDOUT:   %specific_fn.loc25: <specific function> = specific_function %impl.elem0.loc25, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc25_18.2: <bound method> = bound_method %.loc25_18.2, %specific_fn.loc25
-// CHECK:STDOUT:   %Int.as.Copy.impl.Op.call.loc25: init %i32 = call %bound_method.loc25_18.2(%.loc25_18.2)
+// CHECK:STDOUT:   %bound_method.loc25_25.2: <bound method> = bound_method %.loc25_25.2, %specific_fn.loc25
+// CHECK:STDOUT:   %Int.as.Copy.impl.Op.call.loc25: init %i32 = call %bound_method.loc25_25.2(%.loc25_25.2)
 // CHECK:STDOUT:   assign %cj.var, %Int.as.Copy.impl.Op.call.loc25
-// CHECK:STDOUT:   %.loc25_11: type = splice_block %i32.loc25 [concrete = constants.%i32] {
+// CHECK:STDOUT:   %.loc25_18: type = splice_block %i32.loc25 [concrete = constants.%i32] {
 // CHECK:STDOUT:     %int_32.loc25: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32.loc25: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   }
@@ -192,15 +192,15 @@ fn Test() {
 // CHECK:STDOUT:   %ck.var: ref %i32 = var %ck.var_patt
 // CHECK:STDOUT:   %c.ref.loc26: %Class = name_ref c, %c
 // CHECK:STDOUT:   %k.ref.loc26: %Class.elem = name_ref k, @Class.%.loc17 [concrete = @Class.%.loc17]
-// CHECK:STDOUT:   %.loc26_18.1: ref %i32 = class_element_access %c.ref.loc26, element1
-// CHECK:STDOUT:   %.loc26_18.2: %i32 = acquire_value %.loc26_18.1
+// CHECK:STDOUT:   %.loc26_25.1: ref %i32 = class_element_access %c.ref.loc26, element1
+// CHECK:STDOUT:   %.loc26_25.2: %i32 = acquire_value %.loc26_25.1
 // CHECK:STDOUT:   %impl.elem0.loc26: %.8e2 = impl_witness_access constants.%Copy.impl_witness.f17, element0 [concrete = constants.%Int.as.Copy.impl.Op.664]
-// CHECK:STDOUT:   %bound_method.loc26_18.1: <bound method> = bound_method %.loc26_18.2, %impl.elem0.loc26
+// CHECK:STDOUT:   %bound_method.loc26_25.1: <bound method> = bound_method %.loc26_25.2, %impl.elem0.loc26
 // CHECK:STDOUT:   %specific_fn.loc26: <specific function> = specific_function %impl.elem0.loc26, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc26_18.2: <bound method> = bound_method %.loc26_18.2, %specific_fn.loc26
-// CHECK:STDOUT:   %Int.as.Copy.impl.Op.call.loc26: init %i32 = call %bound_method.loc26_18.2(%.loc26_18.2)
+// CHECK:STDOUT:   %bound_method.loc26_25.2: <bound method> = bound_method %.loc26_25.2, %specific_fn.loc26
+// CHECK:STDOUT:   %Int.as.Copy.impl.Op.call.loc26: init %i32 = call %bound_method.loc26_25.2(%.loc26_25.2)
 // CHECK:STDOUT:   assign %ck.var, %Int.as.Copy.impl.Op.call.loc26
-// CHECK:STDOUT:   %.loc26_11: type = splice_block %i32.loc26 [concrete = constants.%i32] {
+// CHECK:STDOUT:   %.loc26_18: type = splice_block %i32.loc26 [concrete = constants.%i32] {
 // CHECK:STDOUT:     %int_32.loc26: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32.loc26: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   }

+ 22 - 22
toolchain/check/testdata/class/generic/base_is_generic.carbon

@@ -75,7 +75,7 @@ class C(T:! type) {
 }
 
 fn F() {
-  let i: i32 = C(i32).G();
+  let unused i: i32 = C(i32).G();
 }
 
 
@@ -86,7 +86,7 @@ library "[[@TEST_NAME]]";
 import library "extend_generic_symbolic_base";
 
 fn H() {
-  let j: i32 = C(i32).G();
+  let unused j: i32 = C(i32).G();
 }
 
 // CHECK:STDOUT: --- extend_generic_base.carbon
@@ -706,20 +706,20 @@ fn H() {
 // CHECK:STDOUT:     %i.patt: %pattern_type.7ce = value_binding_pattern i [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic]
-// CHECK:STDOUT:   %int_32.loc13_18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
-// CHECK:STDOUT:   %i32.loc13_18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:   %int_32.loc13_25: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:   %i32.loc13_25: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   %C: type = class_type @C, @C(constants.%i32) [concrete = constants.%C.b13]
-// CHECK:STDOUT:   %.loc13_22: %X.G.type.f75 = specific_constant @X.%X.G.decl, @X(constants.%i32) [concrete = constants.%X.G.e2a]
-// CHECK:STDOUT:   %G.ref: %X.G.type.f75 = name_ref G, %.loc13_22 [concrete = constants.%X.G.e2a]
+// CHECK:STDOUT:   %.loc13_29: %X.G.type.f75 = specific_constant @X.%X.G.decl, @X(constants.%i32) [concrete = constants.%X.G.e2a]
+// CHECK:STDOUT:   %G.ref: %X.G.type.f75 = name_ref G, %.loc13_29 [concrete = constants.%X.G.e2a]
 // CHECK:STDOUT:   %X.G.specific_fn: <specific function> = specific_function %G.ref, @X.G(constants.%i32) [concrete = constants.%X.G.specific_fn.54d]
 // CHECK:STDOUT:   %X.G.call: init %i32 = call %X.G.specific_fn()
-// CHECK:STDOUT:   %.loc13_10: type = splice_block %i32.loc13_10 [concrete = constants.%i32] {
-// CHECK:STDOUT:     %int_32.loc13_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc13_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:   %.loc13_17: type = splice_block %i32.loc13_17 [concrete = constants.%i32] {
+// CHECK:STDOUT:     %int_32.loc13_17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc13_17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc13_25.1: %i32 = value_of_initializer %X.G.call
-// CHECK:STDOUT:   %.loc13_25.2: %i32 = converted %X.G.call, %.loc13_25.1
-// CHECK:STDOUT:   %i: %i32 = value_binding i, %.loc13_25.2
+// CHECK:STDOUT:   %.loc13_32.1: %i32 = value_of_initializer %X.G.call
+// CHECK:STDOUT:   %.loc13_32.2: %i32 = converted %X.G.call, %.loc13_32.1
+// CHECK:STDOUT:   %i: %i32 = value_binding i, %.loc13_32.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -909,20 +909,20 @@ fn H() {
 // CHECK:STDOUT:     %j.patt: %pattern_type.7ce = value_binding_pattern j [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.ref: %C.type = name_ref C, imports.%Main.C [concrete = constants.%C.generic]
-// CHECK:STDOUT:   %int_32.loc7_18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
-// CHECK:STDOUT:   %i32.loc7_18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:   %int_32.loc7_25: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:   %i32.loc7_25: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   %C: type = class_type @C, @C(constants.%i32) [concrete = constants.%C.b13]
-// CHECK:STDOUT:   %.loc7_22: %X.G.type.f75 = specific_constant imports.%Main.import_ref.940, @X(constants.%i32) [concrete = constants.%X.G.e2a]
-// CHECK:STDOUT:   %G.ref: %X.G.type.f75 = name_ref G, %.loc7_22 [concrete = constants.%X.G.e2a]
+// CHECK:STDOUT:   %.loc7_29: %X.G.type.f75 = specific_constant imports.%Main.import_ref.940, @X(constants.%i32) [concrete = constants.%X.G.e2a]
+// CHECK:STDOUT:   %G.ref: %X.G.type.f75 = name_ref G, %.loc7_29 [concrete = constants.%X.G.e2a]
 // CHECK:STDOUT:   %X.G.specific_fn: <specific function> = specific_function %G.ref, @X.G(constants.%i32) [concrete = constants.%X.G.specific_fn.54d]
 // CHECK:STDOUT:   %X.G.call: init %i32 = call %X.G.specific_fn()
-// CHECK:STDOUT:   %.loc7_10: type = splice_block %i32.loc7_10 [concrete = constants.%i32] {
-// CHECK:STDOUT:     %int_32.loc7_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc7_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:   %.loc7_17: type = splice_block %i32.loc7_17 [concrete = constants.%i32] {
+// CHECK:STDOUT:     %int_32.loc7_17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc7_17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc7_25.1: %i32 = value_of_initializer %X.G.call
-// CHECK:STDOUT:   %.loc7_25.2: %i32 = converted %X.G.call, %.loc7_25.1
-// CHECK:STDOUT:   %j: %i32 = value_binding j, %.loc7_25.2
+// CHECK:STDOUT:   %.loc7_32.1: %i32 = value_of_initializer %X.G.call
+// CHECK:STDOUT:   %.loc7_32.2: %i32 = converted %X.G.call, %.loc7_32.1
+// CHECK:STDOUT:   %j: %i32 = value_binding j, %.loc7_32.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 10 - 10
toolchain/check/testdata/class/generic/complete_in_conversion.carbon

@@ -28,11 +28,11 @@ class A(N:! i32) {
 }
 
 fn F(a: A(0)*) {
-  // CHECK:STDERR: fail_derived_to_base.carbon:[[@LINE+4]]:15: note: in `A(0)` used here [ResolvingSpecificHere]
-  // CHECK:STDERR:   let b: B* = a;
-  // CHECK:STDERR:               ^
+  // CHECK:STDERR: fail_derived_to_base.carbon:[[@LINE+4]]:22: note: in `A(0)` used here [ResolvingSpecificHere]
+  // CHECK:STDERR:   let unused b: B* = a;
+  // CHECK:STDERR:                      ^
   // CHECK:STDERR:
-  let b: B* = a;
+  let unused b: B* = a;
 }
 
 // CHECK:STDOUT: --- fail_derived_to_base.carbon
@@ -249,15 +249,15 @@ fn F(a: A(0)*) {
 // CHECK:STDOUT:     %b.patt: %pattern_type.191 = value_binding_pattern b [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.ref: %ptr.0e2 = name_ref a, %a
-// CHECK:STDOUT:   %.loc20_11: type = splice_block %ptr.loc20 [concrete = constants.%ptr.27c] {
+// CHECK:STDOUT:   %.loc20_18: type = splice_block %ptr.loc20 [concrete = constants.%ptr.27c] {
 // CHECK:STDOUT:     %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B]
 // CHECK:STDOUT:     %ptr.loc20: type = ptr_type %B.ref [concrete = constants.%ptr.27c]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc20_15.1: ref %A.dc6 = deref %a.ref
-// CHECK:STDOUT:   %.loc20_15.2: ref %B = class_element_access %.loc20_15.1, element0
-// CHECK:STDOUT:   %addr: %ptr.27c = addr_of %.loc20_15.2
-// CHECK:STDOUT:   %.loc20_15.3: %ptr.27c = converted %a.ref, %addr
-// CHECK:STDOUT:   %b: %ptr.27c = value_binding b, %.loc20_15.3
+// CHECK:STDOUT:   %.loc20_22.1: ref %A.dc6 = deref %a.ref
+// CHECK:STDOUT:   %.loc20_22.2: ref %B = class_element_access %.loc20_22.1, element0
+// CHECK:STDOUT:   %addr: %ptr.27c = addr_of %.loc20_22.2
+// CHECK:STDOUT:   %.loc20_22.3: %ptr.27c = converted %a.ref, %addr
+// CHECK:STDOUT:   %b: %ptr.27c = value_binding b, %.loc20_22.3
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 8 - 8
toolchain/check/testdata/class/generic/import.carbon

@@ -60,13 +60,13 @@ import library "foo";
 fn Use() {
   // TODO: Include the generic arguments in the formatted type name.
   // CHECK:STDERR: fail_generic_arg_mismatch.carbon:[[@LINE+7]]:3: error: cannot implicitly convert expression of type `CompleteClass(i32)` to `CompleteClass(i32*)` [ConversionFailure]
-  // CHECK:STDERR:   var v: CompleteClass(i32*) = F();
-  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR:   var unused v: CompleteClass(i32*) = F();
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_generic_arg_mismatch.carbon:[[@LINE+4]]:3: note: type `CompleteClass(i32)` does not implement interface `Core.ImplicitAs(CompleteClass(i32*))` [MissingImplInMemberAccessNote]
-  // CHECK:STDERR:   var v: CompleteClass(i32*) = F();
-  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR:   var unused v: CompleteClass(i32*) = F();
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var v: CompleteClass(i32*) = F();
+  var unused v: CompleteClass(i32*) = F();
 }
 
 // --- fail_foo.impl.carbon
@@ -778,11 +778,11 @@ class Class(U:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v.var: ref %CompleteClass.582 = var %v.var_patt
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, imports.%Main.F [concrete = constants.%F]
-// CHECK:STDOUT:   %.loc14_34: ref %CompleteClass.667 = temporary_storage
-// CHECK:STDOUT:   %F.call: init %CompleteClass.667 to %.loc14_34 = call %F.ref()
+// CHECK:STDOUT:   %.loc14_41: ref %CompleteClass.667 = temporary_storage
+// CHECK:STDOUT:   %F.call: init %CompleteClass.667 to %.loc14_41 = call %F.ref()
 // CHECK:STDOUT:   %.loc14_3: %CompleteClass.582 = converted %F.call, <error> [concrete = <error>]
 // CHECK:STDOUT:   assign %v.var, <error>
-// CHECK:STDOUT:   %.loc14_28: type = splice_block %CompleteClass [concrete = constants.%CompleteClass.582] {
+// CHECK:STDOUT:   %.loc14_35: type = splice_block %CompleteClass [concrete = constants.%CompleteClass.582] {
 // CHECK:STDOUT:     %CompleteClass.ref: %CompleteClass.type = name_ref CompleteClass, imports.%Main.CompleteClass [concrete = constants.%CompleteClass.generic]
 // CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]

+ 40 - 40
toolchain/check/testdata/class/generic/member_out_of_line.carbon

@@ -36,12 +36,12 @@ library "[[@TEST_NAME]]";
 
 //@dump-sem-ir-begin
 class A(T:! type) {
-  class B(N:! T) {
+  class B(_:! T) {
     fn F[self: Self](a: T);
   }
 }
 
-fn A(T:! type).B(N:! T).F[self: Self](a: T) {}
+fn A(T:! type).B(_:! T).F[unused self: Self](unused a: T) {}
 //@dump-sem-ir-end
 
 // --- fail_mismatched_not_generic_vs_generic.carbon
@@ -53,19 +53,19 @@ class NotGeneric {
 }
 
 // CHECK:STDERR: fail_mismatched_not_generic_vs_generic.carbon:[[@LINE+7]]:4: error: redeclaration differs because of parameter list [RedeclParamListDiffers]
-// CHECK:STDERR: fn NotGeneric(T:! type).F() {}
+// CHECK:STDERR: fn NotGeneric(unused T:! type).F() {}
 // CHECK:STDERR:    ^~~~~~~~~~
 // CHECK:STDERR: fail_mismatched_not_generic_vs_generic.carbon:[[@LINE-7]]:1: note: previously declared without parameter list [RedeclParamListPrevious]
 // CHECK:STDERR: class NotGeneric {
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
-fn NotGeneric(T:! type).F() {}
+fn NotGeneric(unused T:! type).F() {}
 
 // --- fail_mismatched_too_few_args.carbon
 
 library "[[@TEST_NAME]]";
 
-class Generic(T:! type) {
+class Generic(unused T:! type) {
   fn TooFew();
 }
 
@@ -73,8 +73,8 @@ class Generic(T:! type) {
 // CHECK:STDERR: fn Generic().TooFew() {}
 // CHECK:STDERR:    ^~~~~~~
 // CHECK:STDERR: fail_mismatched_too_few_args.carbon:[[@LINE-7]]:1: note: previously declared with parameter count of 1 [RedeclParamCountPrevious]
-// CHECK:STDERR: class Generic(T:! type) {
-// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
+// CHECK:STDERR: class Generic(unused T:! type) {
+// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 fn Generic().TooFew() {}
 
@@ -87,30 +87,30 @@ class Generic(T:! type) {
 }
 
 // CHECK:STDERR: fail_mismatched_too_many_args.carbon:[[@LINE+7]]:4: error: redeclaration differs because of parameter count of 2 [RedeclParamCountDiffers]
-// CHECK:STDERR: fn Generic(T:! type, U:! type).TooMany() {}
+// CHECK:STDERR: fn Generic(unused T:! type, unused U:! type).TooMany() {}
 // CHECK:STDERR:    ^~~~~~~
 // CHECK:STDERR: fail_mismatched_too_many_args.carbon:[[@LINE-7]]:1: note: previously declared with parameter count of 1 [RedeclParamCountPrevious]
 // CHECK:STDERR: class Generic(T:! type) {
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
-fn Generic(T:! type, U:! type).TooMany() {}
+fn Generic(unused T:! type, unused U:! type).TooMany() {}
 
 // --- fail_mismatched_wrong_arg_type.carbon
 
 library "[[@TEST_NAME]]";
 
-class Generic(T:! type) {
+class Generic(unused T:! type) {
   fn WrongType();
 }
 
-// CHECK:STDERR: fail_mismatched_wrong_arg_type.carbon:[[@LINE+7]]:12: error: type `<pattern for ()>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for type>` [RedeclParamDiffersType]
-// CHECK:STDERR: fn Generic(T:! ()).WrongType() {}
-// CHECK:STDERR:            ^
-// CHECK:STDERR: fail_mismatched_wrong_arg_type.carbon:[[@LINE-7]]:15: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
-// CHECK:STDERR: class Generic(T:! type) {
-// CHECK:STDERR:               ^
+// CHECK:STDERR: fail_mismatched_wrong_arg_type.carbon:[[@LINE+7]]:19: error: type `<pattern for ()>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for type>` [RedeclParamDiffersType]
+// CHECK:STDERR: fn Generic(unused T:! ()).WrongType() {}
+// CHECK:STDERR:                   ^
+// CHECK:STDERR: fail_mismatched_wrong_arg_type.carbon:[[@LINE-7]]:22: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
+// CHECK:STDERR: class Generic(unused T:! type) {
+// CHECK:STDERR:                      ^
 // CHECK:STDERR:
-fn Generic(T:! ()).WrongType() {}
+fn Generic(unused T:! ()).WrongType() {}
 
 // CHECK:STDOUT: --- basic.carbon
 // CHECK:STDOUT:
@@ -386,13 +386,13 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %A.type: type = generic_class_type @A [concrete]
 // CHECK:STDOUT:   %A.generic: %A.type = struct_value () [concrete]
 // CHECK:STDOUT:   %A: type = class_type @A, @A(%T) [symbolic]
-// CHECK:STDOUT:   %N: %T = symbolic_binding N, 1 [symbolic]
+// CHECK:STDOUT:   %_: %T = symbolic_binding _, 1 [symbolic]
 // CHECK:STDOUT:   %pattern_type.51d: type = pattern_type %T [symbolic]
 // CHECK:STDOUT:   %B.type: type = generic_class_type @B, @A(%T) [symbolic]
 // CHECK:STDOUT:   %B.generic: %B.type = struct_value () [symbolic]
-// CHECK:STDOUT:   %B: type = class_type @B, @B(%T, %N) [symbolic]
+// CHECK:STDOUT:   %B: type = class_type @B, @B(%T, %_) [symbolic]
 // CHECK:STDOUT:   %pattern_type.830: type = pattern_type %B [symbolic]
-// CHECK:STDOUT:   %B.F.type: type = fn_type @B.F, @B(%T, %N) [symbolic]
+// CHECK:STDOUT:   %B.F.type: type = fn_type @B.F, @B(%T, %_) [symbolic]
 // CHECK:STDOUT:   %B.F: %B.F.type = struct_value () [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -422,15 +422,15 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:       <elided>
 // CHECK:STDOUT:       %T.ref.loc11_22: type = name_ref T, %T.loc11 [symbolic = @B.%T (constants.%T)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %N.loc11: @B.%T (%T) = symbolic_binding N, 1 [symbolic = @B.%N.loc6_11.1 (constants.%N)]
+// CHECK:STDOUT:     %_.loc11: @B.%T (%T) = symbolic_binding _, 1 [symbolic = @B.%_.loc6_11.1 (constants.%_)]
 // CHECK:STDOUT:     %self.param.loc11: @B.F.%B (%B) = value_param call_param0
-// CHECK:STDOUT:     %.loc11_33.1: type = splice_block %Self.ref.loc11 [symbolic = %B (constants.%B)] {
-// CHECK:STDOUT:       %.loc11_33.2: type = specific_constant constants.%B, @B(constants.%T, constants.%N) [symbolic = %B (constants.%B)]
-// CHECK:STDOUT:       %Self.ref.loc11: type = name_ref Self, %.loc11_33.2 [symbolic = %B (constants.%B)]
+// CHECK:STDOUT:     %.loc11_40.1: type = splice_block %Self.ref.loc11 [symbolic = %B (constants.%B)] {
+// CHECK:STDOUT:       %.loc11_40.2: type = specific_constant constants.%B, @B(constants.%T, constants.%_) [symbolic = %B (constants.%B)]
+// CHECK:STDOUT:       %Self.ref.loc11: type = name_ref Self, %.loc11_40.2 [symbolic = %B (constants.%B)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %self.loc11: @B.F.%B (%B) = value_binding self, %self.param.loc11
 // CHECK:STDOUT:     %a.param.loc11: @B.F.%T.loc7 (%T) = value_param call_param1
-// CHECK:STDOUT:     %T.ref.loc11_42: type = name_ref T, %T.loc11 [symbolic = %T.loc7 (constants.%T)]
+// CHECK:STDOUT:     %T.ref.loc11_56: type = name_ref T, %T.loc11 [symbolic = %T.loc7 (constants.%T)]
 // CHECK:STDOUT:     %a.loc11: @B.F.%T.loc7 (%T) = value_binding a, %a.param.loc11
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -444,13 +444,13 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT:   class {
 // CHECK:STDOUT:     %B.decl: @A.%B.type (%B.type) = class_decl @B [symbolic = @A.%B.generic (constants.%B.generic)] {
-// CHECK:STDOUT:       %N.patt: @B.%pattern_type (%pattern_type.51d) = symbolic_binding_pattern N, 1 [concrete]
+// CHECK:STDOUT:       %_.patt: @B.%pattern_type (%pattern_type.51d) = symbolic_binding_pattern _, 1 [concrete]
 // CHECK:STDOUT:     } {
 // CHECK:STDOUT:       %.loc6: type = splice_block %T.ref [symbolic = %T (constants.%T)] {
 // CHECK:STDOUT:         <elided>
 // CHECK:STDOUT:         %T.ref: type = name_ref T, @A.%T.loc5_9.2 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:       }
-// CHECK:STDOUT:       %N.loc6_11.2: @B.%T (%T) = symbolic_binding N, 1 [symbolic = %N.loc6_11.1 (constants.%N)]
+// CHECK:STDOUT:       %_.loc6_11.2: @B.%T (%T) = symbolic_binding _, 1 [symbolic = %_.loc6_11.1 (constants.%_)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type]
 // CHECK:STDOUT:     complete_type_witness = %complete_type
@@ -462,13 +462,13 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic class @B(@A.%T.loc5_9.2: type, %N.loc6_11.2: @B.%T (%T)) {
+// CHECK:STDOUT: generic class @B(@A.%T.loc5_9.2: type, %_.loc6_11.2: @B.%T (%T)) {
 // CHECK:STDOUT:   %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %N.loc6_11.1: @B.%T (%T) = symbolic_binding N, 1 [symbolic = %N.loc6_11.1 (constants.%N)]
+// CHECK:STDOUT:   %_.loc6_11.1: @B.%T (%T) = symbolic_binding _, 1 [symbolic = %_.loc6_11.1 (constants.%_)]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %T [symbolic = %pattern_type (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %B.F.type: type = fn_type @B.F, @B(%T, %N.loc6_11.1) [symbolic = %B.F.type (constants.%B.F.type)]
+// CHECK:STDOUT:   %B.F.type: type = fn_type @B.F, @B(%T, %_.loc6_11.1) [symbolic = %B.F.type (constants.%B.F.type)]
 // CHECK:STDOUT:   %B.F: @B.%B.F.type (%B.F.type) = struct_value () [symbolic = %B.F (constants.%B.F)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   class {
@@ -480,7 +480,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:     } {
 // CHECK:STDOUT:       %self.param.loc7: @B.F.%B (%B) = value_param call_param0
 // CHECK:STDOUT:       %.loc7_16.1: type = splice_block %Self.ref.loc7 [symbolic = %B (constants.%B)] {
-// CHECK:STDOUT:         %.loc7_16.2: type = specific_constant constants.%B, @B(constants.%T, constants.%N) [symbolic = %B (constants.%B)]
+// CHECK:STDOUT:         %.loc7_16.2: type = specific_constant constants.%B, @B(constants.%T, constants.%_) [symbolic = %B (constants.%B)]
 // CHECK:STDOUT:         %Self.ref.loc7: type = name_ref Self, %.loc7_16.2 [symbolic = %B (constants.%B)]
 // CHECK:STDOUT:       }
 // CHECK:STDOUT:       %self.loc7: @B.F.%B (%B) = value_binding self, %self.param.loc7
@@ -498,16 +498,16 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @B.F(@A.%T.loc5_9.2: type, @B.%N.loc6_11.2: @B.%T (%T)) {
+// CHECK:STDOUT: generic fn @B.F(@A.%T.loc5_9.2: type, @B.%_.loc6_11.2: @B.%T (%T)) {
 // CHECK:STDOUT:   %T.loc7: type = symbolic_binding T, 0 [symbolic = %T.loc7 (constants.%T)]
-// CHECK:STDOUT:   %N.loc7: @B.F.%T.loc7 (%T) = symbolic_binding N, 1 [symbolic = %N.loc7 (constants.%N)]
-// CHECK:STDOUT:   %B: type = class_type @B, @B(%T.loc7, %N.loc7) [symbolic = %B (constants.%B)]
+// CHECK:STDOUT:   %_.loc7: @B.F.%T.loc7 (%T) = symbolic_binding _, 1 [symbolic = %_.loc7 (constants.%_)]
+// CHECK:STDOUT:   %B: type = class_type @B, @B(%T.loc7, %_.loc7) [symbolic = %B (constants.%B)]
 // CHECK:STDOUT:   %pattern_type.loc7_10: type = pattern_type %B [symbolic = %pattern_type.loc7_10 (constants.%pattern_type.830)]
 // CHECK:STDOUT:   %pattern_type.loc7_22: type = pattern_type %T.loc7 [symbolic = %pattern_type.loc7_22 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc11_31: <witness> = require_complete_type %B [symbolic = %require_complete.loc11_31 (constants.%require_complete.7cc)]
-// CHECK:STDOUT:   %require_complete.loc11_40: <witness> = require_complete_type %T.loc7 [symbolic = %require_complete.loc11_40 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc11_38: <witness> = require_complete_type %B [symbolic = %require_complete.loc11_38 (constants.%require_complete.7cc)]
+// CHECK:STDOUT:   %require_complete.loc11_54: <witness> = require_complete_type %T.loc7 [symbolic = %require_complete.loc11_54 (constants.%require_complete.944)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%self.param.loc11: @B.F.%B (%B), %a.param.loc11: @B.F.%T.loc7 (%T)) {
 // CHECK:STDOUT:   !entry:
@@ -523,9 +523,9 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %B.generic => constants.%B.generic
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @B(constants.%T, constants.%N) {
+// CHECK:STDOUT: specific @B(constants.%T, constants.%_) {
 // CHECK:STDOUT:   %T => constants.%T
-// CHECK:STDOUT:   %N.loc6_11.1 => constants.%N
+// CHECK:STDOUT:   %_.loc6_11.1 => constants.%_
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.51d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
@@ -533,9 +533,9 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %B.F => constants.%B.F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @B.F(constants.%T, constants.%N) {
+// CHECK:STDOUT: specific @B.F(constants.%T, constants.%_) {
 // CHECK:STDOUT:   %T.loc7 => constants.%T
-// CHECK:STDOUT:   %N.loc7 => constants.%N
+// CHECK:STDOUT:   %_.loc7 => constants.%_
 // CHECK:STDOUT:   %B => constants.%B
 // CHECK:STDOUT:   %pattern_type.loc7_10 => constants.%pattern_type.830
 // CHECK:STDOUT:   %pattern_type.loc7_22 => constants.%pattern_type.51d

+ 28 - 28
toolchain/check/testdata/class/generic/self.carbon

@@ -18,8 +18,8 @@ class Class(T:! type) {
   fn MakeSelf() -> Self { return {}; }
   fn MakeClass() -> Class(T) { return {}; }
   fn F() {
-    var c: Class(T) = MakeSelf();
-    var s: Self = MakeClass();
+    var unused c: Class(T) = MakeSelf();
+    var unused s: Self = MakeClass();
   }
 }
 
@@ -169,17 +169,17 @@ class Class(T:! type) {
 // CHECK:STDOUT: generic fn @Class.F(@Class.%T.loc15_13.2: type) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %Class.loc21_19.2: type = class_type @Class, @Class(%T) [symbolic = %Class.loc21_19.2 (constants.%Class)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %Class.loc21_19.2 [symbolic = %require_complete (constants.%require_complete)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %Class.loc21_19.2 [symbolic = %pattern_type (constants.%pattern_type.466)]
+// CHECK:STDOUT:   %Class.loc21_26.2: type = class_type @Class, @Class(%T) [symbolic = %Class.loc21_26.2 (constants.%Class)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %Class.loc21_26.2 [symbolic = %require_complete (constants.%require_complete)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %Class.loc21_26.2 [symbolic = %pattern_type (constants.%pattern_type.466)]
 // CHECK:STDOUT:   %Class.MakeSelf.type: type = fn_type @Class.MakeSelf, @Class(%T) [symbolic = %Class.MakeSelf.type (constants.%Class.MakeSelf.type)]
 // CHECK:STDOUT:   %Class.MakeSelf: @Class.F.%Class.MakeSelf.type (%Class.MakeSelf.type) = struct_value () [symbolic = %Class.MakeSelf (constants.%Class.MakeSelf)]
-// CHECK:STDOUT:   %Class.MakeSelf.specific_fn.loc21_23.2: <specific function> = specific_function %Class.MakeSelf, @Class.MakeSelf(%T) [symbolic = %Class.MakeSelf.specific_fn.loc21_23.2 (constants.%Class.MakeSelf.specific_fn)]
+// CHECK:STDOUT:   %Class.MakeSelf.specific_fn.loc21_30.2: <specific function> = specific_function %Class.MakeSelf, @Class.MakeSelf(%T) [symbolic = %Class.MakeSelf.specific_fn.loc21_30.2 (constants.%Class.MakeSelf.specific_fn)]
 // CHECK:STDOUT:   %Class.MakeClass.type: type = fn_type @Class.MakeClass, @Class(%T) [symbolic = %Class.MakeClass.type (constants.%Class.MakeClass.type)]
 // CHECK:STDOUT:   %Class.MakeClass: @Class.F.%Class.MakeClass.type (%Class.MakeClass.type) = struct_value () [symbolic = %Class.MakeClass (constants.%Class.MakeClass)]
-// CHECK:STDOUT:   %Class.MakeClass.specific_fn.loc22_19.2: <specific function> = specific_function %Class.MakeClass, @Class.MakeClass(%T) [symbolic = %Class.MakeClass.specific_fn.loc22_19.2 (constants.%Class.MakeClass.specific_fn)]
-// CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %Class.loc21_19.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
-// CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %Class.loc21_19.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet)]
+// CHECK:STDOUT:   %Class.MakeClass.specific_fn.loc22_26.2: <specific function> = specific_function %Class.MakeClass, @Class.MakeClass(%T) [symbolic = %Class.MakeClass.specific_fn.loc22_26.2 (constants.%Class.MakeClass.specific_fn)]
+// CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %Class.loc21_26.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
+// CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %Class.loc21_26.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet)]
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type: type = fn_type @Destroy.WithSelf.Op, @Destroy(%Destroy.facet) [symbolic = %Destroy.WithSelf.Op.type (constants.%Destroy.WithSelf.Op.type.609)]
 // CHECK:STDOUT:   %.loc22_5.2: type = fn_type_with_self_type %Destroy.WithSelf.Op.type, %Destroy.facet [symbolic = %.loc22_5.2 (constants.%.2f5)]
 // CHECK:STDOUT:   %impl.elem0.loc22_5.2: @Class.F.%.loc22_5.2 (%.2f5) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc22_5.2 (constants.%impl.elem0)]
@@ -191,35 +191,35 @@ class Class(T:! type) {
 // CHECK:STDOUT:       %c.patt: @Class.F.%pattern_type (%pattern_type.466) = ref_binding_pattern c [concrete]
 // CHECK:STDOUT:       %c.var_patt: @Class.F.%pattern_type (%pattern_type.466) = var_pattern %c.patt [concrete]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %c.var: ref @Class.F.%Class.loc21_19.2 (%Class) = var %c.var_patt
-// CHECK:STDOUT:     %.loc21_23: @Class.F.%Class.MakeSelf.type (%Class.MakeSelf.type) = specific_constant @Class.%Class.MakeSelf.decl, @Class(constants.%T) [symbolic = %Class.MakeSelf (constants.%Class.MakeSelf)]
-// CHECK:STDOUT:     %MakeSelf.ref: @Class.F.%Class.MakeSelf.type (%Class.MakeSelf.type) = name_ref MakeSelf, %.loc21_23 [symbolic = %Class.MakeSelf (constants.%Class.MakeSelf)]
-// CHECK:STDOUT:     %Class.MakeSelf.specific_fn.loc21_23.1: <specific function> = specific_function %MakeSelf.ref, @Class.MakeSelf(constants.%T) [symbolic = %Class.MakeSelf.specific_fn.loc21_23.2 (constants.%Class.MakeSelf.specific_fn)]
-// CHECK:STDOUT:     %.loc21_5: ref @Class.F.%Class.loc21_19.2 (%Class) = splice_block %c.var {}
-// CHECK:STDOUT:     %Class.MakeSelf.call: init @Class.F.%Class.loc21_19.2 (%Class) to %.loc21_5 = call %Class.MakeSelf.specific_fn.loc21_23.1()
+// CHECK:STDOUT:     %c.var: ref @Class.F.%Class.loc21_26.2 (%Class) = var %c.var_patt
+// CHECK:STDOUT:     %.loc21_30: @Class.F.%Class.MakeSelf.type (%Class.MakeSelf.type) = specific_constant @Class.%Class.MakeSelf.decl, @Class(constants.%T) [symbolic = %Class.MakeSelf (constants.%Class.MakeSelf)]
+// CHECK:STDOUT:     %MakeSelf.ref: @Class.F.%Class.MakeSelf.type (%Class.MakeSelf.type) = name_ref MakeSelf, %.loc21_30 [symbolic = %Class.MakeSelf (constants.%Class.MakeSelf)]
+// CHECK:STDOUT:     %Class.MakeSelf.specific_fn.loc21_30.1: <specific function> = specific_function %MakeSelf.ref, @Class.MakeSelf(constants.%T) [symbolic = %Class.MakeSelf.specific_fn.loc21_30.2 (constants.%Class.MakeSelf.specific_fn)]
+// CHECK:STDOUT:     %.loc21_5: ref @Class.F.%Class.loc21_26.2 (%Class) = splice_block %c.var {}
+// CHECK:STDOUT:     %Class.MakeSelf.call: init @Class.F.%Class.loc21_26.2 (%Class) to %.loc21_5 = call %Class.MakeSelf.specific_fn.loc21_30.1()
 // CHECK:STDOUT:     assign %c.var, %Class.MakeSelf.call
-// CHECK:STDOUT:     %.loc21_19: type = splice_block %Class.loc21_19.1 [symbolic = %Class.loc21_19.2 (constants.%Class)] {
+// CHECK:STDOUT:     %.loc21_26: type = splice_block %Class.loc21_26.1 [symbolic = %Class.loc21_26.2 (constants.%Class)] {
 // CHECK:STDOUT:       %Class.ref: %Class.type = name_ref Class, file.%Class.decl [concrete = constants.%Class.generic]
 // CHECK:STDOUT:       %T.ref: type = name_ref T, @Class.%T.loc15_13.2 [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:       %Class.loc21_19.1: type = class_type @Class, @Class(constants.%T) [symbolic = %Class.loc21_19.2 (constants.%Class)]
+// CHECK:STDOUT:       %Class.loc21_26.1: type = class_type @Class, @Class(constants.%T) [symbolic = %Class.loc21_26.2 (constants.%Class)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %c: ref @Class.F.%Class.loc21_19.2 (%Class) = ref_binding c, %c.var
+// CHECK:STDOUT:     %c: ref @Class.F.%Class.loc21_26.2 (%Class) = ref_binding c, %c.var
 // CHECK:STDOUT:     name_binding_decl {
 // CHECK:STDOUT:       %s.patt: @Class.F.%pattern_type (%pattern_type.466) = ref_binding_pattern s [concrete]
 // CHECK:STDOUT:       %s.var_patt: @Class.F.%pattern_type (%pattern_type.466) = var_pattern %s.patt [concrete]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %s.var: ref @Class.F.%Class.loc21_19.2 (%Class) = var %s.var_patt
-// CHECK:STDOUT:     %.loc22_19: @Class.F.%Class.MakeClass.type (%Class.MakeClass.type) = specific_constant @Class.%Class.MakeClass.decl, @Class(constants.%T) [symbolic = %Class.MakeClass (constants.%Class.MakeClass)]
-// CHECK:STDOUT:     %MakeClass.ref: @Class.F.%Class.MakeClass.type (%Class.MakeClass.type) = name_ref MakeClass, %.loc22_19 [symbolic = %Class.MakeClass (constants.%Class.MakeClass)]
-// CHECK:STDOUT:     %Class.MakeClass.specific_fn.loc22_19.1: <specific function> = specific_function %MakeClass.ref, @Class.MakeClass(constants.%T) [symbolic = %Class.MakeClass.specific_fn.loc22_19.2 (constants.%Class.MakeClass.specific_fn)]
-// CHECK:STDOUT:     %.loc22_5.1: ref @Class.F.%Class.loc21_19.2 (%Class) = splice_block %s.var {}
-// CHECK:STDOUT:     %Class.MakeClass.call: init @Class.F.%Class.loc21_19.2 (%Class) to %.loc22_5.1 = call %Class.MakeClass.specific_fn.loc22_19.1()
+// CHECK:STDOUT:     %s.var: ref @Class.F.%Class.loc21_26.2 (%Class) = var %s.var_patt
+// CHECK:STDOUT:     %.loc22_26: @Class.F.%Class.MakeClass.type (%Class.MakeClass.type) = specific_constant @Class.%Class.MakeClass.decl, @Class(constants.%T) [symbolic = %Class.MakeClass (constants.%Class.MakeClass)]
+// CHECK:STDOUT:     %MakeClass.ref: @Class.F.%Class.MakeClass.type (%Class.MakeClass.type) = name_ref MakeClass, %.loc22_26 [symbolic = %Class.MakeClass (constants.%Class.MakeClass)]
+// CHECK:STDOUT:     %Class.MakeClass.specific_fn.loc22_26.1: <specific function> = specific_function %MakeClass.ref, @Class.MakeClass(constants.%T) [symbolic = %Class.MakeClass.specific_fn.loc22_26.2 (constants.%Class.MakeClass.specific_fn)]
+// CHECK:STDOUT:     %.loc22_5.1: ref @Class.F.%Class.loc21_26.2 (%Class) = splice_block %s.var {}
+// CHECK:STDOUT:     %Class.MakeClass.call: init @Class.F.%Class.loc21_26.2 (%Class) to %.loc22_5.1 = call %Class.MakeClass.specific_fn.loc22_26.1()
 // CHECK:STDOUT:     assign %s.var, %Class.MakeClass.call
-// CHECK:STDOUT:     %.loc22_12.1: type = splice_block %Self.ref [symbolic = %Class.loc21_19.2 (constants.%Class)] {
-// CHECK:STDOUT:       %.loc22_12.2: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class.loc21_19.2 (constants.%Class)]
-// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc22_12.2 [symbolic = %Class.loc21_19.2 (constants.%Class)]
+// CHECK:STDOUT:     %.loc22_19.1: type = splice_block %Self.ref [symbolic = %Class.loc21_26.2 (constants.%Class)] {
+// CHECK:STDOUT:       %.loc22_19.2: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class.loc21_26.2 (constants.%Class)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc22_19.2 [symbolic = %Class.loc21_26.2 (constants.%Class)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %s: ref @Class.F.%Class.loc21_19.2 (%Class) = ref_binding s, %s.var
+// CHECK:STDOUT:     %s: ref @Class.F.%Class.loc21_26.2 (%Class) = ref_binding s, %s.var
 // CHECK:STDOUT:     %impl.elem0.loc22_5.1: @Class.F.%.loc22_5.2 (%.2f5) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc22_5.2 (constants.%impl.elem0)]
 // CHECK:STDOUT:     %bound_method.loc22_5.1: <bound method> = bound_method %s.var, %impl.elem0.loc22_5.1
 // CHECK:STDOUT:     %specific_impl_fn.loc22_5.1: <specific function> = specific_impl_function %impl.elem0.loc22_5.1, @Destroy.WithSelf.Op(constants.%Destroy.facet) [symbolic = %specific_impl_fn.loc22_5.2 (constants.%specific_impl_fn)]

+ 6 - 6
toolchain/check/testdata/class/generic_method.carbon

@@ -17,7 +17,7 @@ class Class(T:! type) {
   fn F[self: Self](n: T);
 }
 
-fn Class(T:! type).F[self: Self](n: T) {}
+fn Class(T:! type).F[unused self: Self](unused n: T) {}
 
 // CHECK:STDOUT: --- generic_method.carbon
 // CHECK:STDOUT:
@@ -68,9 +68,9 @@ fn Class(T:! type).F[self: Self](n: T) {}
 // CHECK:STDOUT:     %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:     %T.loc20: type = symbolic_binding T, 0 [symbolic = @Class.%T.loc15_13.1 (constants.%T)]
 // CHECK:STDOUT:     %self.param.loc20: @Class.F.%Class (%Class) = value_param call_param0
-// CHECK:STDOUT:     %.loc20_28.1: type = splice_block %Self.ref.loc20 [symbolic = %Class (constants.%Class)] {
-// CHECK:STDOUT:       %.loc20_28.2: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)]
-// CHECK:STDOUT:       %Self.ref.loc20: type = name_ref Self, %.loc20_28.2 [symbolic = %Class (constants.%Class)]
+// CHECK:STDOUT:     %.loc20_35.1: type = splice_block %Self.ref.loc20 [symbolic = %Class (constants.%Class)] {
+// CHECK:STDOUT:       %.loc20_35.2: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)]
+// CHECK:STDOUT:       %Self.ref.loc20: type = name_ref Self, %.loc20_35.2 [symbolic = %Class (constants.%Class)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %self.loc20: @Class.F.%Class (%Class) = value_binding self, %self.param.loc20
 // CHECK:STDOUT:     %n.param.loc20: @Class.F.%T.loc17 (%T) = value_param call_param1
@@ -128,8 +128,8 @@ fn Class(T:! type).F[self: Self](n: T) {}
 // CHECK:STDOUT:   %pattern_type.loc17_20: type = pattern_type %T.loc17 [symbolic = %pattern_type.loc17_20 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc20_26: <witness> = require_complete_type %Class [symbolic = %require_complete.loc20_26 (constants.%require_complete.43d)]
-// CHECK:STDOUT:   %require_complete.loc20_35: <witness> = require_complete_type %T.loc17 [symbolic = %require_complete.loc20_35 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc20_33: <witness> = require_complete_type %Class [symbolic = %require_complete.loc20_33 (constants.%require_complete.43d)]
+// CHECK:STDOUT:   %require_complete.loc20_49: <witness> = require_complete_type %T.loc17 [symbolic = %require_complete.loc20_49 (constants.%require_complete.944)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%self.param.loc20: @Class.F.%Class (%Class), %n.param.loc20: @Class.F.%T.loc17 (%T)) {
 // CHECK:STDOUT:   !entry:

+ 9 - 9
toolchain/check/testdata/class/import.carbon

@@ -39,7 +39,7 @@ library "[[@TEST_NAME]]";
 import library "a";
 
 fn Run() {
-  var a: Empty = {};
+  var unused a: Empty = {};
 
   var b: Field = {.x = 1};
   b.x = 2;
@@ -48,9 +48,9 @@ fn Run() {
   c.F();
   c.G();
 
-  var d: ForwardDeclared* = &c;
+  var unused d: ForwardDeclared* = &c;
 
-  var e: Incomplete*;
+  var unused e: Incomplete*;
 }
 
 // CHECK:STDOUT: --- a.carbon
@@ -323,9 +323,9 @@ fn Run() {
 // CHECK:STDOUT:     %a.var_patt: %pattern_type.37d = var_pattern %a.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.var: ref %Empty = var %a.var_patt
-// CHECK:STDOUT:   %.loc7_19.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
-// CHECK:STDOUT:   %.loc7_19.2: init %Empty to %a.var = class_init () [concrete = constants.%Empty.val]
-// CHECK:STDOUT:   %.loc7_3: init %Empty = converted %.loc7_19.1, %.loc7_19.2 [concrete = constants.%Empty.val]
+// CHECK:STDOUT:   %.loc7_26.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
+// CHECK:STDOUT:   %.loc7_26.2: init %Empty to %a.var = class_init () [concrete = constants.%Empty.val]
+// CHECK:STDOUT:   %.loc7_3: init %Empty = converted %.loc7_26.1, %.loc7_26.2 [concrete = constants.%Empty.val]
 // CHECK:STDOUT:   assign %a.var, %.loc7_3
 // CHECK:STDOUT:   %Empty.ref: type = name_ref Empty, imports.%Main.Empty [concrete = constants.%Empty]
 // CHECK:STDOUT:   %a: ref %Empty = ref_binding a, %a.var
@@ -388,10 +388,10 @@ fn Run() {
 // CHECK:STDOUT:   %c.ref.loc16: ref %ForwardDeclared.20f323.1 = name_ref c, %c
 // CHECK:STDOUT:   %addr: %ptr.006 = addr_of %c.ref.loc16
 // CHECK:STDOUT:   %impl.elem0.loc16: %.89b = impl_witness_access constants.%Copy.impl_witness.bef, element0 [concrete = constants.%ptr.as.Copy.impl.Op.d3c]
-// CHECK:STDOUT:   %bound_method.loc16_29.1: <bound method> = bound_method %addr, %impl.elem0.loc16
+// CHECK:STDOUT:   %bound_method.loc16_36.1: <bound method> = bound_method %addr, %impl.elem0.loc16
 // CHECK:STDOUT:   %specific_fn.loc16: <specific function> = specific_function %impl.elem0.loc16, @ptr.as.Copy.impl.Op(constants.%ForwardDeclared.20f323.1) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc16_29.2: <bound method> = bound_method %addr, %specific_fn.loc16
-// CHECK:STDOUT:   %ptr.as.Copy.impl.Op.call: init %ptr.006 = call %bound_method.loc16_29.2(%addr)
+// CHECK:STDOUT:   %bound_method.loc16_36.2: <bound method> = bound_method %addr, %specific_fn.loc16
+// CHECK:STDOUT:   %ptr.as.Copy.impl.Op.call: init %ptr.006 = call %bound_method.loc16_36.2(%addr)
 // CHECK:STDOUT:   assign %d.var, %ptr.as.Copy.impl.Op.call
 // CHECK:STDOUT:   %.loc16: type = splice_block %ptr.loc16 [concrete = constants.%ptr.006] {
 // CHECK:STDOUT:     %ForwardDeclared.ref.loc16: type = name_ref ForwardDeclared, imports.%Main.ForwardDeclared [concrete = constants.%ForwardDeclared.20f323.1]

+ 9 - 9
toolchain/check/testdata/class/import_access.carbon

@@ -104,7 +104,7 @@ var c: Test.ForwardWithDef = {};
 
 impl package Test library "[[@TEST_NAME]]";
 
-fn F(c: Forward*) {}
+fn F(unused c: Forward*) {}
 
 class Forward {}
 
@@ -114,11 +114,11 @@ package Test library "[[@TEST_NAME]]";
 
 import library "forward";
 
-// CHECK:STDERR: fail_local_forward.carbon:[[@LINE+4]]:9: error: name `Forward` not found [NameNotFound]
-// CHECK:STDERR: fn F(c: Forward*) {}
-// CHECK:STDERR:         ^~~~~~~
+// CHECK:STDERR: fail_local_forward.carbon:[[@LINE+4]]:16: error: name `Forward` not found [NameNotFound]
+// CHECK:STDERR: fn F(unused c: Forward*) {}
+// CHECK:STDERR:                ^~~~~~~
 // CHECK:STDERR:
-fn F(c: Forward*) {}
+fn F(unused c: Forward*) {}
 
 // --- fail_other_forward.carbon
 
@@ -126,11 +126,11 @@ package Other library "[[@TEST_NAME]]";
 
 import Test library "forward";
 
-// CHECK:STDERR: fail_other_forward.carbon:[[@LINE+4]]:9: error: member name `Forward` not found in `Test` [MemberNameNotFoundInInstScope]
-// CHECK:STDERR: fn F(c: Test.Forward*) {}
-// CHECK:STDERR:         ^~~~~~~~~~~~
+// CHECK:STDERR: fail_other_forward.carbon:[[@LINE+4]]:16: error: member name `Forward` not found in `Test` [MemberNameNotFoundInInstScope]
+// CHECK:STDERR: fn F(unused c: Test.Forward*) {}
+// CHECK:STDERR:                ^~~~~~~~~~~~
 // CHECK:STDERR:
-fn F(c: Test.Forward*) {}
+fn F(unused c: Test.Forward*) {}
 
 // --- todo_fail_private_on_redecl.carbon
 

+ 1 - 1
toolchain/check/testdata/class/import_member_cycle.carbon

@@ -27,7 +27,7 @@ library "[[@TEST_NAME]]";
 import library "a";
 
 fn Run() {
-  var a: Cycle*;
+  var unused a: Cycle*;
 }
 
 // CHECK:STDOUT: --- a.carbon

+ 6 - 6
toolchain/check/testdata/class/nested.carbon

@@ -15,8 +15,8 @@
 class Outer {
   fn F() {
     // Outer and Inner are both complete here.
-    var o: Outer;
-    var i: Inner;
+    var unused o: Outer;
+    var unused i: Inner;
   }
 
   class Inner {
@@ -26,15 +26,15 @@ class Outer {
 
     fn G() {
       // Outer and Inner are both complete here.
-      var o: Outer;
-      var i: Inner;
+      var unused o: Outer;
+      var unused i: Inner;
     }
   }
 
   fn H() {
     // Outer and Inner are both complete here.
-    var o: Outer;
-    var i: Inner;
+    var unused o: Outer;
+    var unused i: Inner;
   }
 
   var po: Self*;

+ 1 - 1
toolchain/check/testdata/class/nested_name.carbon

@@ -23,7 +23,7 @@ fn F(oi: Outer.Inner) -> i32 {
 }
 
 fn G(o: Outer) {
-  var i: o.Inner;
+  var unused i: o.Inner;
 }
 
 // CHECK:STDOUT: --- nested_name.carbon

+ 12 - 12
toolchain/check/testdata/class/raw_self_type.carbon

@@ -15,7 +15,7 @@
 class Class {
   fn F() {
     var r#Self: Self*;
-    var p: Self* = r#Self;
+    var unused p: Self* = r#Self;
   }
 }
 
@@ -25,7 +25,7 @@ class MemberNamedSelf {
   fn F(x: Self, y: r#Self);
 }
 
-fn MemberNamedSelf.F(x: Self, y: r#Self) {}
+fn MemberNamedSelf.F(unused x: Self, unused y: r#Self) {}
 
 // CHECK:STDOUT: --- raw_self_type.carbon
 // CHECK:STDOUT:
@@ -89,10 +89,10 @@ fn MemberNamedSelf.F(x: Self, y: r#Self) {}
 // CHECK:STDOUT:     %y.param_patt: %pattern_type.f56 = value_param_pattern %y.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %x.param.loc28: %MemberNamedSelf = value_param call_param0
-// CHECK:STDOUT:     %Self.ref.loc28_25: type = name_ref Self, constants.%MemberNamedSelf [concrete = constants.%MemberNamedSelf]
+// CHECK:STDOUT:     %Self.ref.loc28_32: type = name_ref Self, constants.%MemberNamedSelf [concrete = constants.%MemberNamedSelf]
 // CHECK:STDOUT:     %x.loc28: %MemberNamedSelf = value_binding x, %x.param.loc28
 // CHECK:STDOUT:     %y.param.loc28: %Self.0d4 = value_param call_param1
-// CHECK:STDOUT:     %Self.ref.loc28_34: type = name_ref r#Self, @MemberNamedSelf.%Self.decl [concrete = constants.%Self.0d4]
+// CHECK:STDOUT:     %Self.ref.loc28_48: type = name_ref r#Self, @MemberNamedSelf.%Self.decl [concrete = constants.%Self.0d4]
 // CHECK:STDOUT:     %y.loc28: %Self.0d4 = value_binding y, %y.param.loc28
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -156,17 +156,17 @@ fn MemberNamedSelf.F(x: Self, y: r#Self) {}
 // CHECK:STDOUT:     %p.var_patt: %pattern_type.018 = var_pattern %p.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %p.var: ref %ptr.8e5 = var %p.var_patt
-// CHECK:STDOUT:   %Self.ref.loc18_20: ref %ptr.8e5 = name_ref r#Self, %Self
-// CHECK:STDOUT:   %.loc18_20: %ptr.8e5 = acquire_value %Self.ref.loc18_20
+// CHECK:STDOUT:   %Self.ref.loc18_27: ref %ptr.8e5 = name_ref r#Self, %Self
+// CHECK:STDOUT:   %.loc18_27: %ptr.8e5 = acquire_value %Self.ref.loc18_27
 // CHECK:STDOUT:   %impl.elem0: %.370 = impl_witness_access constants.%Copy.impl_witness.9d3, element0 [concrete = constants.%ptr.as.Copy.impl.Op.120]
-// CHECK:STDOUT:   %bound_method.loc18_20.1: <bound method> = bound_method %.loc18_20, %impl.elem0
+// CHECK:STDOUT:   %bound_method.loc18_27.1: <bound method> = bound_method %.loc18_27, %impl.elem0
 // CHECK:STDOUT:   %specific_fn: <specific function> = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%Class) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc18_20.2: <bound method> = bound_method %.loc18_20, %specific_fn
-// CHECK:STDOUT:   %ptr.as.Copy.impl.Op.call: init %ptr.8e5 = call %bound_method.loc18_20.2(%.loc18_20)
+// CHECK:STDOUT:   %bound_method.loc18_27.2: <bound method> = bound_method %.loc18_27, %specific_fn
+// CHECK:STDOUT:   %ptr.as.Copy.impl.Op.call: init %ptr.8e5 = call %bound_method.loc18_27.2(%.loc18_27)
 // CHECK:STDOUT:   assign %p.var, %ptr.as.Copy.impl.Op.call
-// CHECK:STDOUT:   %.loc18_16: type = splice_block %ptr.loc18 [concrete = constants.%ptr.8e5] {
-// CHECK:STDOUT:     %Self.ref.loc18_12: type = name_ref Self, constants.%Class [concrete = constants.%Class]
-// CHECK:STDOUT:     %ptr.loc18: type = ptr_type %Self.ref.loc18_12 [concrete = constants.%ptr.8e5]
+// CHECK:STDOUT:   %.loc18_23: type = splice_block %ptr.loc18 [concrete = constants.%ptr.8e5] {
+// CHECK:STDOUT:     %Self.ref.loc18_19: type = name_ref Self, constants.%Class [concrete = constants.%Class]
+// CHECK:STDOUT:     %ptr.loc18: type = ptr_type %Self.ref.loc18_19 [concrete = constants.%ptr.8e5]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %p: ref %ptr.8e5 = ref_binding p, %p.var
 // CHECK:STDOUT:   %DestroyOp.bound.loc18: <bound method> = bound_method %p.var, constants.%DestroyOp

+ 4 - 4
toolchain/check/testdata/class/redeclaration.carbon

@@ -18,7 +18,7 @@ class Class {
   fn F[self: Self](b: ());
 }
 
-fn Class.F[self: Self](b: ()) {}
+fn Class.F[unused self: Self](unused b: ()) {}
 
 // CHECK:STDOUT: --- redeclaration.carbon
 // CHECK:STDOUT:
@@ -59,9 +59,9 @@ fn Class.F[self: Self](b: ()) {}
 // CHECK:STDOUT:     %Self.ref.loc21: type = name_ref Self, constants.%Class [concrete = constants.%Class]
 // CHECK:STDOUT:     %self.loc21: %Class = value_binding self, %self.param.loc21
 // CHECK:STDOUT:     %b.param.loc21: %empty_tuple.type = value_param call_param1
-// CHECK:STDOUT:     %.loc21_28.1: type = splice_block %.loc21_28.3 [concrete = constants.%empty_tuple.type] {
-// CHECK:STDOUT:       %.loc21_28.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:       %.loc21_28.3: type = converted %.loc21_28.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
+// CHECK:STDOUT:     %.loc21_42.1: type = splice_block %.loc21_42.3 [concrete = constants.%empty_tuple.type] {
+// CHECK:STDOUT:       %.loc21_42.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
+// CHECK:STDOUT:       %.loc21_42.3: type = converted %.loc21_42.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %b.loc21: %empty_tuple.type = value_binding b, %b.param.loc21
 // CHECK:STDOUT:   }

+ 40 - 40
toolchain/check/testdata/class/reorder_qualified.carbon

@@ -30,10 +30,10 @@ class A {
 
     fn D.DF() {
       // A, B, C, and D are complete here.
-      var a: A = {.a = 1};
-      var b: B = {.b = 2};
-      var c: C = {.c = 3};
-      var d: D = {.d = 4};
+      var unused a: A = {.a = 1};
+      var unused b: B = {.b = 2};
+      var unused c: C = {.c = 3};
+      var unused d: D = {.d = 4};
 
       // Unqualified lookup looks in all of them.
       AF();
@@ -258,17 +258,17 @@ class A {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.var: ref %A = var %a.var_patt
 // CHECK:STDOUT:   %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
-// CHECK:STDOUT:   %.loc33_25.1: %struct_type.a.a6c = struct_literal (%int_1) [concrete = constants.%struct.48c]
+// CHECK:STDOUT:   %.loc33_32.1: %struct_type.a.a6c = struct_literal (%int_1) [concrete = constants.%struct.48c]
 // CHECK:STDOUT:   %impl.elem0.loc33: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:   %bound_method.loc33_25.1: <bound method> = bound_method %int_1, %impl.elem0.loc33 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215]
+// CHECK:STDOUT:   %bound_method.loc33_32.1: <bound method> = bound_method %int_1, %impl.elem0.loc33 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215]
 // CHECK:STDOUT:   %specific_fn.loc33: <specific function> = specific_function %impl.elem0.loc33, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc33_25.2: <bound method> = bound_method %int_1, %specific_fn.loc33 [concrete = constants.%bound_method.38b]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc33: init %i32 = call %bound_method.loc33_25.2(%int_1) [concrete = constants.%int_1.5d2]
-// CHECK:STDOUT:   %.loc33_25.2: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc33 [concrete = constants.%int_1.5d2]
-// CHECK:STDOUT:   %.loc33_25.3: ref %i32 = class_element_access %a.var, element0
-// CHECK:STDOUT:   %.loc33_25.4: init %i32 to %.loc33_25.3 = in_place_init %.loc33_25.2 [concrete = constants.%int_1.5d2]
-// CHECK:STDOUT:   %.loc33_25.5: init %A to %a.var = class_init (%.loc33_25.4) [concrete = constants.%A.val]
-// CHECK:STDOUT:   %.loc33_7: init %A = converted %.loc33_25.1, %.loc33_25.5 [concrete = constants.%A.val]
+// CHECK:STDOUT:   %bound_method.loc33_32.2: <bound method> = bound_method %int_1, %specific_fn.loc33 [concrete = constants.%bound_method.38b]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc33: init %i32 = call %bound_method.loc33_32.2(%int_1) [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %.loc33_32.2: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc33 [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %.loc33_32.3: ref %i32 = class_element_access %a.var, element0
+// CHECK:STDOUT:   %.loc33_32.4: init %i32 to %.loc33_32.3 = in_place_init %.loc33_32.2 [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %.loc33_32.5: init %A to %a.var = class_init (%.loc33_32.4) [concrete = constants.%A.val]
+// CHECK:STDOUT:   %.loc33_7: init %A = converted %.loc33_32.1, %.loc33_32.5 [concrete = constants.%A.val]
 // CHECK:STDOUT:   assign %a.var, %.loc33_7
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A]
 // CHECK:STDOUT:   %a: ref %A = ref_binding a, %a.var
@@ -278,17 +278,17 @@ class A {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %b.var: ref %B = var %b.var_patt
 // CHECK:STDOUT:   %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
-// CHECK:STDOUT:   %.loc34_25.1: %struct_type.b.a15 = struct_literal (%int_2) [concrete = constants.%struct.26f]
+// CHECK:STDOUT:   %.loc34_32.1: %struct_type.b.a15 = struct_literal (%int_2) [concrete = constants.%struct.26f]
 // CHECK:STDOUT:   %impl.elem0.loc34: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:   %bound_method.loc34_25.1: <bound method> = bound_method %int_2, %impl.elem0.loc34 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5]
+// CHECK:STDOUT:   %bound_method.loc34_32.1: <bound method> = bound_method %int_2, %impl.elem0.loc34 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5]
 // CHECK:STDOUT:   %specific_fn.loc34: <specific function> = specific_function %impl.elem0.loc34, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc34_25.2: <bound method> = bound_method %int_2, %specific_fn.loc34 [concrete = constants.%bound_method.646]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc34: init %i32 = call %bound_method.loc34_25.2(%int_2) [concrete = constants.%int_2.ef8]
-// CHECK:STDOUT:   %.loc34_25.2: init %i32 = converted %int_2, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc34 [concrete = constants.%int_2.ef8]
-// CHECK:STDOUT:   %.loc34_25.3: ref %i32 = class_element_access %b.var, element0
-// CHECK:STDOUT:   %.loc34_25.4: init %i32 to %.loc34_25.3 = in_place_init %.loc34_25.2 [concrete = constants.%int_2.ef8]
-// CHECK:STDOUT:   %.loc34_25.5: init %B to %b.var = class_init (%.loc34_25.4) [concrete = constants.%B.val]
-// CHECK:STDOUT:   %.loc34_7: init %B = converted %.loc34_25.1, %.loc34_25.5 [concrete = constants.%B.val]
+// CHECK:STDOUT:   %bound_method.loc34_32.2: <bound method> = bound_method %int_2, %specific_fn.loc34 [concrete = constants.%bound_method.646]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc34: init %i32 = call %bound_method.loc34_32.2(%int_2) [concrete = constants.%int_2.ef8]
+// CHECK:STDOUT:   %.loc34_32.2: init %i32 = converted %int_2, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc34 [concrete = constants.%int_2.ef8]
+// CHECK:STDOUT:   %.loc34_32.3: ref %i32 = class_element_access %b.var, element0
+// CHECK:STDOUT:   %.loc34_32.4: init %i32 to %.loc34_32.3 = in_place_init %.loc34_32.2 [concrete = constants.%int_2.ef8]
+// CHECK:STDOUT:   %.loc34_32.5: init %B to %b.var = class_init (%.loc34_32.4) [concrete = constants.%B.val]
+// CHECK:STDOUT:   %.loc34_7: init %B = converted %.loc34_32.1, %.loc34_32.5 [concrete = constants.%B.val]
 // CHECK:STDOUT:   assign %b.var, %.loc34_7
 // CHECK:STDOUT:   %B.ref: type = name_ref B, @A.%B.decl [concrete = constants.%B]
 // CHECK:STDOUT:   %b: ref %B = ref_binding b, %b.var
@@ -298,17 +298,17 @@ class A {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %c.var: ref %C = var %c.var_patt
 // CHECK:STDOUT:   %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba]
-// CHECK:STDOUT:   %.loc35_25.1: %struct_type.c.5b8 = struct_literal (%int_3) [concrete = constants.%struct.d98]
+// CHECK:STDOUT:   %.loc35_32.1: %struct_type.c.5b8 = struct_literal (%int_3) [concrete = constants.%struct.d98]
 // CHECK:STDOUT:   %impl.elem0.loc35: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:   %bound_method.loc35_25.1: <bound method> = bound_method %int_3, %impl.elem0.loc35 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.061]
+// CHECK:STDOUT:   %bound_method.loc35_32.1: <bound method> = bound_method %int_3, %impl.elem0.loc35 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.061]
 // CHECK:STDOUT:   %specific_fn.loc35: <specific function> = specific_function %impl.elem0.loc35, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc35_25.2: <bound method> = bound_method %int_3, %specific_fn.loc35 [concrete = constants.%bound_method.fa7]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc35: init %i32 = call %bound_method.loc35_25.2(%int_3) [concrete = constants.%int_3.822]
-// CHECK:STDOUT:   %.loc35_25.2: init %i32 = converted %int_3, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc35 [concrete = constants.%int_3.822]
-// CHECK:STDOUT:   %.loc35_25.3: ref %i32 = class_element_access %c.var, element0
-// CHECK:STDOUT:   %.loc35_25.4: init %i32 to %.loc35_25.3 = in_place_init %.loc35_25.2 [concrete = constants.%int_3.822]
-// CHECK:STDOUT:   %.loc35_25.5: init %C to %c.var = class_init (%.loc35_25.4) [concrete = constants.%C.val]
-// CHECK:STDOUT:   %.loc35_7: init %C = converted %.loc35_25.1, %.loc35_25.5 [concrete = constants.%C.val]
+// CHECK:STDOUT:   %bound_method.loc35_32.2: <bound method> = bound_method %int_3, %specific_fn.loc35 [concrete = constants.%bound_method.fa7]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc35: init %i32 = call %bound_method.loc35_32.2(%int_3) [concrete = constants.%int_3.822]
+// CHECK:STDOUT:   %.loc35_32.2: init %i32 = converted %int_3, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc35 [concrete = constants.%int_3.822]
+// CHECK:STDOUT:   %.loc35_32.3: ref %i32 = class_element_access %c.var, element0
+// CHECK:STDOUT:   %.loc35_32.4: init %i32 to %.loc35_32.3 = in_place_init %.loc35_32.2 [concrete = constants.%int_3.822]
+// CHECK:STDOUT:   %.loc35_32.5: init %C to %c.var = class_init (%.loc35_32.4) [concrete = constants.%C.val]
+// CHECK:STDOUT:   %.loc35_7: init %C = converted %.loc35_32.1, %.loc35_32.5 [concrete = constants.%C.val]
 // CHECK:STDOUT:   assign %c.var, %.loc35_7
 // CHECK:STDOUT:   %C.ref: type = name_ref C, @B.%C.decl [concrete = constants.%C]
 // CHECK:STDOUT:   %c: ref %C = ref_binding c, %c.var
@@ -318,17 +318,17 @@ class A {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %d.var: ref %D = var %d.var_patt
 // CHECK:STDOUT:   %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1]
-// CHECK:STDOUT:   %.loc36_25.1: %struct_type.d.3ea = struct_literal (%int_4) [concrete = constants.%struct.5a9]
+// CHECK:STDOUT:   %.loc36_32.1: %struct_type.d.3ea = struct_literal (%int_4) [concrete = constants.%struct.5a9]
 // CHECK:STDOUT:   %impl.elem0.loc36: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:   %bound_method.loc36_25.1: <bound method> = bound_method %int_4, %impl.elem0.loc36 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.f0c]
+// CHECK:STDOUT:   %bound_method.loc36_32.1: <bound method> = bound_method %int_4, %impl.elem0.loc36 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.f0c]
 // CHECK:STDOUT:   %specific_fn.loc36: <specific function> = specific_function %impl.elem0.loc36, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:   %bound_method.loc36_25.2: <bound method> = bound_method %int_4, %specific_fn.loc36 [concrete = constants.%bound_method.6d7]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc36: init %i32 = call %bound_method.loc36_25.2(%int_4) [concrete = constants.%int_4.940]
-// CHECK:STDOUT:   %.loc36_25.2: init %i32 = converted %int_4, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc36 [concrete = constants.%int_4.940]
-// CHECK:STDOUT:   %.loc36_25.3: ref %i32 = class_element_access %d.var, element0
-// CHECK:STDOUT:   %.loc36_25.4: init %i32 to %.loc36_25.3 = in_place_init %.loc36_25.2 [concrete = constants.%int_4.940]
-// CHECK:STDOUT:   %.loc36_25.5: init %D to %d.var = class_init (%.loc36_25.4) [concrete = constants.%D.val]
-// CHECK:STDOUT:   %.loc36_7: init %D = converted %.loc36_25.1, %.loc36_25.5 [concrete = constants.%D.val]
+// CHECK:STDOUT:   %bound_method.loc36_32.2: <bound method> = bound_method %int_4, %specific_fn.loc36 [concrete = constants.%bound_method.6d7]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc36: init %i32 = call %bound_method.loc36_32.2(%int_4) [concrete = constants.%int_4.940]
+// CHECK:STDOUT:   %.loc36_32.2: init %i32 = converted %int_4, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc36 [concrete = constants.%int_4.940]
+// CHECK:STDOUT:   %.loc36_32.3: ref %i32 = class_element_access %d.var, element0
+// CHECK:STDOUT:   %.loc36_32.4: init %i32 to %.loc36_32.3 = in_place_init %.loc36_32.2 [concrete = constants.%int_4.940]
+// CHECK:STDOUT:   %.loc36_32.5: init %D to %d.var = class_init (%.loc36_32.4) [concrete = constants.%D.val]
+// CHECK:STDOUT:   %.loc36_7: init %D = converted %.loc36_32.1, %.loc36_32.5 [concrete = constants.%D.val]
 // CHECK:STDOUT:   assign %d.var, %.loc36_7
 // CHECK:STDOUT:   %D.ref: type = name_ref D, @C.%D.decl [concrete = constants.%D]
 // CHECK:STDOUT:   %d: ref %D = ref_binding d, %d.var

+ 2 - 2
toolchain/check/testdata/class/scope.carbon

@@ -27,8 +27,8 @@ fn F() -> i32 {
 }
 
 fn Run() {
-  var a: i32 = F();
-  var b: i32 = Class.F();
+  var unused a: i32 = F();
+  var unused b: i32 = Class.F();
 }
 
 // CHECK:STDOUT: --- scope.carbon

File diff suppressed because it is too large
+ 275 - 275
toolchain/check/testdata/class/virtual_modifiers.carbon


+ 2 - 2
toolchain/check/testdata/const/basics.carbon

@@ -66,8 +66,8 @@ library "[[@TEST_NAME]]";
 
 class X {}
 
-fn TakeValue(x: X) {}
-fn TakeConstValue(x: const X) {}
+fn TakeValue(unused x: X) {}
+fn TakeConstValue(unused x: const X) {}
 
 fn PassConstValueToValue(a: const X) {
   TakeValue(a);

+ 199 - 38
toolchain/check/testdata/dataflow/unused.carbon

@@ -17,134 +17,143 @@ fn ReturnVar() -> i32 {
   var x: i32 = 0;
   x = 1;
   return x;
-   // TODO: ensure no warning.
  }
 
 fn ReturnLet() -> i32 {
   let y: i32 = 1;
   return y;
-  // TODO: ensure no warning.
 }
 
 fn RefParam(ref x: i32) {
   x = 1;
-  // TODO: ensure no warning.
 }
 
 fn ReturnedVar() -> i32 {
   returned var x: i32 = 0;
   return var;
-  // TODO: ensure no warning.
 }
 
 fn ReturnVarExplicit() -> i32 {
   var x: i32 = 0;
   return x;
-  // TODO: ensure no warning.
 }
 
 fn FieldAccess() {
   var x: {.a: i32} = {.a = 0};
   // Accessing a field should count as a use of x.
-  var y: i32 = x.a;
-  // TODO: ensure no warning.
+  var _: i32 = x.a;
 }
 
 fn ParametersUsed(x: i32) -> i32 {
-  // TODO: ensure no warning.
   return x;
 }
 
-// --- fail_todo_unused_ref_param.carbon
+// --- unused_ref_param.carbon
 library "[[@TEST_NAME]]";
 
-// CHECK:STDERR: fail_todo_unused_ref_param.carbon:[[@LINE+4]]:19: error: semantics TODO: `unused` [SemanticsTodo]
-// CHECK:STDERR: fn RefParamUnused(unused ref y: i32) {
-// CHECK:STDERR:                   ^~~~~~~~~~~~~~~~~
-// CHECK:STDERR:
 fn RefParamUnused(unused ref y: i32) {
-  // TODO: ensure no warning
 }
 
-// --- todo_fail_local_let_named_not_used.carbon
+// --- local_let_named_not_used.carbon
 library "[[@TEST_NAME]]";
 
 fn F() {
+  // CHECK:STDERR: local_let_named_not_used.carbon:[[@LINE+4]]:7: warning: binding `x` unused [UnusedBinding]
+  // CHECK:STDERR:   let x: i32 = 0;
+  // CHECK:STDERR:       ^
+  // CHECK:STDERR:
   let x: i32 = 0;
-  // TODO: warning, x is unused.
 }
 
-// --- todo_fail_local_var_named_not_used.carbon
+// --- local_var_named_not_used.carbon
 library "[[@TEST_NAME]]";
 
 fn F() {
+  // CHECK:STDERR: local_var_named_not_used.carbon:[[@LINE+4]]:7: warning: binding `a` unused [UnusedBinding]
+  // CHECK:STDERR:   var a: i32 = 0;
+  // CHECK:STDERR:       ^
+  // CHECK:STDERR:
   var a: i32 = 0;
-  // TODO: warning, a is unused.
 }
 
-// --- todo_fail_local_var_shadowed_not_used.carbon
+// --- local_var_shadowed_not_used.carbon
 library "[[@TEST_NAME]]";
 
 fn F() {
   var x: i32 = 0;
   if (true) {
+    // CHECK:STDERR: local_var_shadowed_not_used.carbon:[[@LINE+4]]:9: warning: binding `x` unused [UnusedBinding]
+    // CHECK:STDERR:     var x: i32 = 1;
+    // CHECK:STDERR:         ^
+    // CHECK:STDERR:
     var x: i32 = 1;
-    // TODO: warning, x is unused.
   }
   x = 2;
-  // TODO: warning, x is unused.
 }
 
-// --- todo_fail_param_let_named_not_used.carbon
+// --- param_let_named_not_used.carbon
 library "[[@TEST_NAME]]";
 
+// CHECK:STDERR: param_let_named_not_used.carbon:[[@LINE+4]]:6: warning: binding `p` unused [UnusedBinding]
+// CHECK:STDERR: fn F(p: i32) {
+// CHECK:STDERR:      ^
+// CHECK:STDERR:
 fn F(p: i32) {
-  // TODO: warning, p is unused.
 }
 
-// --- todo_fail_param_ref_named_not_used.carbon
+// --- param_ref_named_not_used.carbon
 library "[[@TEST_NAME]]";
 
+// CHECK:STDERR: param_ref_named_not_used.carbon:[[@LINE+4]]:10: warning: binding `y` unused [UnusedBinding]
+// CHECK:STDERR: fn F(ref y: i32) {
+// CHECK:STDERR:          ^
+// CHECK:STDERR:
 fn F(ref y: i32) {
-  // TODO: warning, y is unused.
 }
 
-// --- fail_todo_read_from_param_unused_ref.carbon
+// --- fail_read_from_param_unused_ref.carbon
 library "[[@TEST_NAME]]";
 
-// CHECK:STDERR: fail_todo_read_from_param_unused_ref.carbon:[[@LINE+4]]:19: error: semantics TODO: `unused` [SemanticsTodo]
+// CHECK:STDERR: fail_read_from_param_unused_ref.carbon:[[@LINE+3]]:30: error: variable `y` marked `unused` but used [UnusedButUsed]
 // CHECK:STDERR: fn RefParamUnused(unused ref y: i32) {
-// CHECK:STDERR:                   ^~~~~~~~~~~~~~~~~
-// CHECK:STDERR:
+// CHECK:STDERR:                              ^
 fn RefParamUnused(unused ref y: i32) {
+  // CHECK:STDERR: fail_read_from_param_unused_ref.carbon:[[@LINE+4]]:16: note: usage here [UnusedButUsedHere]
+  // CHECK:STDERR:   var _: i32 = y;
+  // CHECK:STDERR:                ^
+  // CHECK:STDERR:
   var _: i32 = y;
-  // TODO: ensure error, marked "unused" but used.
 }
 
-// --- fail_todo_fail_unused_returned_var.carbon
+// --- fail_unused_returned_var.carbon
 library "[[@TEST_NAME]]";
 
 fn F() -> i32 {
-  // CHECK:STDERR: fail_todo_fail_unused_returned_var.carbon:[[@LINE+4]]:16: error: semantics TODO: `unused` [SemanticsTodo]
+  // CHECK:STDERR: fail_unused_returned_var.carbon:[[@LINE+7]]:23: error: variable `x` marked `unused` but used [UnusedButUsed]
+  // CHECK:STDERR:   returned var unused x: i32 = 0;
+  // CHECK:STDERR:                       ^
+  // CHECK:STDERR: fail_unused_returned_var.carbon:[[@LINE+4]]:23: note: usage here [UnusedButUsedHere]
   // CHECK:STDERR:   returned var unused x: i32 = 0;
-  // CHECK:STDERR:                ^~~~~~~~~~~~~
+  // CHECK:STDERR:                       ^
   // CHECK:STDERR:
   returned var unused x: i32 = 0;
-  // TODO: ensure error, marked "unused" but used.
   return var;
 }
 
-// --- fail_todo_fail_read_from_unused_local_var.carbon
+// --- fail_read_from_unused_local_var.carbon
 library "[[@TEST_NAME]]";
 
 fn F(x: i32) {
   var _: i32 = x;
-  // CHECK:STDERR: fail_todo_fail_read_from_unused_local_var.carbon:[[@LINE+4]]:7: error: semantics TODO: `unused` [SemanticsTodo]
+  // CHECK:STDERR: fail_read_from_unused_local_var.carbon:[[@LINE+3]]:14: error: variable `y` marked `unused` but used [UnusedButUsed]
   // CHECK:STDERR:   var unused y: i32 = x;
-  // CHECK:STDERR:       ^~~~~~~~~~~~~
-  // CHECK:STDERR:
+  // CHECK:STDERR:              ^
   var unused y: i32 = x;
   // TODO: error, marked "unused", but used
+  // CHECK:STDERR: fail_read_from_unused_local_var.carbon:[[@LINE+4]]:23: note: usage here [UnusedButUsedHere]
+  // CHECK:STDERR:   var unused z: i32 = y;
+  // CHECK:STDERR:                       ^
+  // CHECK:STDERR:
   var unused z: i32 = y;
 }
 
@@ -166,3 +175,155 @@ fn F() -> i32 {
   return 0;
   // TODO: ensure no warning (after match is implemented).
 }
+
+// --- fail_unused_decl.carbon
+library "[[@TEST_NAME]]";
+
+// CHECK:STDERR: fail_unused_decl.carbon:[[@LINE+4]]:13: error: `unused` modifier on declaration [UnusedModifierOnDeclaration]
+// CHECK:STDERR: fn F(unused x: i32);
+// CHECK:STDERR:             ^
+// CHECK:STDERR:
+fn F(unused x: i32);
+
+// --- fail_multiple_uses_of_unused.carbon
+library "[[@TEST_NAME]]";
+
+fn F() {
+  // CHECK:STDERR: fail_multiple_uses_of_unused.carbon:[[@LINE+3]]:14: error: variable `x` marked `unused` but used [UnusedButUsed]
+  // CHECK:STDERR:   var unused x: i32 = 0;
+  // CHECK:STDERR:              ^
+  var unused x: i32 = 0;
+  // CHECK:STDERR: fail_multiple_uses_of_unused.carbon:[[@LINE+4]]:3: note: usage here [UnusedButUsedHere]
+  // CHECK:STDERR:   x;
+  // CHECK:STDERR:   ^
+  // CHECK:STDERR:
+  x;
+  x;
+}
+
+// --- fail_unused_does_not_affect_redeclaration.carbon
+library "[[@TEST_NAME]]";
+
+fn F(x: i32);
+// CHECK:STDERR: fail_unused_does_not_affect_redeclaration.carbon:[[@LINE+7]]:13: error: redeclaration differs at parameter 1 [RedeclParamDiffers]
+// CHECK:STDERR: fn F(unused y: i32) {}
+// CHECK:STDERR:             ^~~~~~
+// CHECK:STDERR: fail_unused_does_not_affect_redeclaration.carbon:[[@LINE-4]]:6: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
+// CHECK:STDERR: fn F(x: i32);
+// CHECK:STDERR:      ^~~~~~
+// CHECK:STDERR:
+fn F(unused y: i32) {}
+
+// --- unreachable.carbon
+library "[[@TEST_NAME]]";
+
+fn F(x: i32) {
+  return;
+  // Unreachable use suppresses the UnusedBinding warning.
+  var y: i32 = x;
+}
+
+fn G(unused x: i32) {
+  return;
+  // Unreachable use is ignored, so no UnusedButUsed error.
+  var y: i32 = x;
+}
+
+fn H(ref x: i32) {
+  return;
+  // Unreachable assignment suppresses the UnusedBinding warning.
+  x = 0;
+}
+
+// --- fail_todo_unused_generic.carbon
+library "[[@TEST_NAME]]";
+
+fn F(T:! type);
+
+// CHECK:STDERR: fail_todo_unused_generic.carbon:[[@LINE+4]]:13: error: semantics TODO: `generic redeclaration differs from previous declaration` [SemanticsTodo]
+// CHECK:STDERR: fn F(unused T:! type) {}
+// CHECK:STDERR:             ^
+// CHECK:STDERR:
+fn F(unused T:! type) {}
+
+class C(T:! type);
+
+// CHECK:STDERR: fail_todo_unused_generic.carbon:[[@LINE+4]]:16: error: semantics TODO: `generic redeclaration differs from previous declaration` [SemanticsTodo]
+// CHECK:STDERR: class C(unused T:! type) {}
+// CHECK:STDERR:                ^
+// CHECK:STDERR:
+class C(unused T:! type) {}
+
+// TODO: Multiple diagnostics on same line has non-deterministic order.
+// Uncomment after adding second sort key in diagnostics sorting.
+//
+// // --- fail_unused_let_multiple_uses.carbon
+// library "[[@TEST_NAME]]";
+//
+// fn F() {
+//   // CHECK:STDERR: fail_unused_let_multiple_uses.carbon:[[@LINE+3]]:14: error: variable `x` marked `unused` but used [UnusedButUsed]
+//   // CHECK:STDERR:   let unused x: i32 = 0;
+//   // CHECK:STDERR:              ^
+//   let unused x: i32 = 0;
+//   // CHECK:STDERR: fail_unused_let_multiple_uses.carbon:[[@LINE+8]]:16: note: usage here [UnusedButUsedHere]
+//   // CHECK:STDERR:   var y: i32 = x;
+//   // CHECK:STDERR:                ^
+//   // CHECK:STDERR:
+//   // CHECK:STDERR: fail_unused_let_multiple_uses.carbon:[[@LINE+4]]:7: warning: binding `y` unused [UnusedBinding]
+//   // CHECK:STDERR:   var y: i32 = x;
+//   // CHECK:STDERR:       ^
+//   // CHECK:STDERR:
+//   var y: i32 = x;
+//   // CHECK:STDERR: fail_unused_let_multiple_uses.carbon:[[@LINE+4]]:7: warning: binding `z` unused [UnusedBinding]
+//   // CHECK:STDERR:   var z: i32 = x;
+//   // CHECK:STDERR:       ^
+//   // CHECK:STDERR:
+//   var z: i32 = x;
+// }
+
+// TODO: Multiple diagnostics on same line has non-deterministic order.
+// Uncomment after adding second sort key in diagnostics sorting.
+//
+// // --- multiple_unused_bindings.carbon
+// library "[[@TEST_NAME]]";
+//
+// fn F() {
+//   // CHECK:STDERR: multiple_unused_bindings.carbon:[[@LINE+4]]:7: warning: binding `x` unused [UnusedBinding]
+//   // CHECK:STDERR:   var x: i32 = 0;
+//   // CHECK:STDERR:       ^
+//   // CHECK:STDERR:
+//   var x: i32 = 0;
+//   // CHECK:STDERR: multiple_unused_bindings.carbon:[[@LINE+4]]:7: warning: binding `y` unused [UnusedBinding]
+//   // CHECK:STDERR:   var y: i32 = 0;
+//   // CHECK:STDERR:       ^
+//   // CHECK:STDERR:
+//   var y: i32 = 0;
+// }
+
+// TODO: Multiple diagnostics on same line has non-deterministic order.
+// Uncomment after adding second sort key in diagnostics sorting.
+//
+// // --- fail_unused_tuple.carbon
+// library "[[@TEST_NAME]]";
+//
+// fn F() -> i32 {
+//  // CHECK:STDERR: fail_unused_tuple.carbon:[[@LINE+3]]:15: error: variable `a` marked `unused` but used [UnusedButUsed]
+//  // CHECK:STDERR:   let unused (a: i32,
+//  // CHECK:STDERR:               ^
+//  let unused (a: i32,
+//              b: i32) = (1, 2);
+//  // CHECK:STDERR: fail_unused_tuple.carbon:[[@LINE+7]]:16: note: usage here [UnusedButUsedHere]
+//  // CHECK:STDERR:   let i: i32 = a;
+//  // CHECK:STDERR:                ^
+//  // CHECK:STDERR:
+//  // CHECK:STDERR: fail_unused_tuple.carbon:[[@LINE-5]]:15: error: variable `b` marked `unused` but used [UnusedButUsed]
+//  // CHECK:STDERR:               b: i32) = (1, 2);
+//  // CHECK:STDERR:               ^
+//  let i: i32 = a;
+//  // CHECK:STDERR: fail_unused_tuple.carbon:[[@LINE+4]]:23: note: usage here [UnusedButUsedHere]
+//  // CHECK:STDERR:   let unused j: i32 = b;
+//  // CHECK:STDERR:                       ^
+//  // CHECK:STDERR:
+//  let unused j: i32 = b;
+//  return i;
+// }

+ 115 - 115
toolchain/check/testdata/deduce/array.carbon

@@ -31,7 +31,7 @@ library "[[@TEST_NAME]]";
 
 class C {}
 
-fn F[N:! Core.IntLiteral()](a: array(C, N)) -> i32 { return N; }
+fn F[N:! Core.IntLiteral()](unused a: array(C, N)) -> i32 { return N; }
 
 fn G() -> i32 {
   var a: array(C, 3) = ({}, {}, {});
@@ -44,7 +44,7 @@ library "[[@TEST_NAME]]";
 
 class C {}
 
-fn F[T:! type, N:! Core.IntLiteral()](a: array(T, N)) {}
+fn F[T:! type, N:! Core.IntLiteral()](unused a: array(T, N)) {}
 
 fn G() {
   var a: array(C, 3) = ({}, {}, {});
@@ -82,7 +82,7 @@ library "[[@TEST_NAME]]";
 class C {}
 class D {}
 
-fn F[N:! Core.IntLiteral()](a: array(C, N)) -> i32 { return N; }
+fn F[N:! Core.IntLiteral()](unused a: array(C, N)) -> i32 { return N; }
 
 fn G() -> i32 {
   // TODO: We succeed at deducing N here but fail to convert. Is this the right behavior?
@@ -93,9 +93,9 @@ fn G() -> i32 {
   // CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+7]]:12: note: type `array(D, 3)` does not implement interface `Core.ImplicitAs(array(C, 3))` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   return F(a);
   // CHECK:STDERR:            ^
-  // CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE-11]]:29: note: initializing function parameter [InCallToFunctionParam]
-  // CHECK:STDERR: fn F[N:! Core.IntLiteral()](a: array(C, N)) -> i32 { return N; }
-  // CHECK:STDERR:                             ^~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE-11]]:36: note: initializing function parameter [InCallToFunctionParam]
+  // CHECK:STDERR: fn F[N:! Core.IntLiteral()](unused a: array(C, N)) -> i32 { return N; }
+  // CHECK:STDERR:                                    ^~~~~~~~~~~~~~
   // CHECK:STDERR:
   return F(a);
 }
@@ -106,7 +106,7 @@ library "[[@TEST_NAME]]";
 
 class C {}
 
-fn F[N:! i32](a: array(C, N)) -> i32 { return N; }
+fn F[N:! i32](unused a: array(C, N)) -> i32 { return N; }
 
 fn G() -> i32 {
   var a: array(C, 3) = ({}, {}, {});
@@ -119,8 +119,8 @@ fn G() -> i32 {
   // CHECK:STDERR:   return F(a);
   // CHECK:STDERR:          ^~~~
   // CHECK:STDERR: fail_bound_type_mismatch.carbon:[[@LINE-12]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn F[N:! i32](a: array(C, N)) -> i32 { return N; }
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn F[N:! i32](unused a: array(C, N)) -> i32 { return N; }
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   return F(a);
 }
@@ -130,7 +130,7 @@ library "[[@TEST_NAME]]";
 
 class C {}
 
-fn F[N:! i32](a: array(C, N)) {}
+fn F[N:! i32](unused a: array(C, N)) {}
 
 fn G() {
   // TODO: Deduce N as 3 from the tuple's size.
@@ -139,8 +139,8 @@ fn G() {
   // CHECK:STDERR:   F(({}, {}, {}));
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_todo_array_length_from_tuple.carbon:[[@LINE-8]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn F[N:! i32](a: array(C, N)) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn F[N:! i32](unused a: array(C, N)) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   F(({}, {}, {}));
 }
@@ -439,7 +439,7 @@ fn G() {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
-// CHECK:STDOUT:     %.loc6_48: Core.Form = init_form %i32, call_param1 [concrete = constants.%.e54]
+// CHECK:STDOUT:     %.loc6_55: Core.Form = init_form %i32, call_param1 [concrete = constants.%.e54]
 // CHECK:STDOUT:     %.loc6_26.1: type = splice_block %.loc6_26.3 [concrete = Core.IntLiteral] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
@@ -449,13 +449,13 @@ fn G() {
 // CHECK:STDOUT:       %.loc6_26.3: type = converted %IntLiteral.call, %.loc6_26.2 [concrete = Core.IntLiteral]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %N.loc6_6.2: Core.IntLiteral = symbolic_binding N, 0 [symbolic = %N.loc6_6.1 (constants.%N)]
-// CHECK:STDOUT:     %a.param: @F.%array_type.loc6_42.1 (%array_type.c79) = value_param call_param0
-// CHECK:STDOUT:     %.loc6_42: type = splice_block %array_type.loc6_42.2 [symbolic = %array_type.loc6_42.1 (constants.%array_type.c79)] {
+// CHECK:STDOUT:     %a.param: @F.%array_type.loc6_49.1 (%array_type.c79) = value_param call_param0
+// CHECK:STDOUT:     %.loc6_49: type = splice_block %array_type.loc6_49.2 [symbolic = %array_type.loc6_49.1 (constants.%array_type.c79)] {
 // CHECK:STDOUT:       %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:       %N.ref.loc6_41: Core.IntLiteral = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N)]
-// CHECK:STDOUT:       %array_type.loc6_42.2: type = array_type %N.ref.loc6_41, %C.ref [symbolic = %array_type.loc6_42.1 (constants.%array_type.c79)]
+// CHECK:STDOUT:       %N.ref.loc6_48: Core.IntLiteral = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N)]
+// CHECK:STDOUT:       %array_type.loc6_49.2: type = array_type %N.ref.loc6_48, %C.ref [symbolic = %array_type.loc6_49.1 (constants.%array_type.c79)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: @F.%array_type.loc6_42.1 (%array_type.c79) = value_binding a, %a.param
+// CHECK:STDOUT:     %a: @F.%array_type.loc6_49.1 (%array_type.c79) = value_binding a, %a.param
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param call_param1
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -481,25 +481,25 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%N.loc6_6.2: Core.IntLiteral) {
 // CHECK:STDOUT:   %N.loc6_6.1: Core.IntLiteral = symbolic_binding N, 0 [symbolic = %N.loc6_6.1 (constants.%N)]
-// CHECK:STDOUT:   %array_type.loc6_42.1: type = array_type %N.loc6_6.1, constants.%C [symbolic = %array_type.loc6_42.1 (constants.%array_type.c79)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc6_42.1 [symbolic = %pattern_type (constants.%pattern_type.cc9)]
+// CHECK:STDOUT:   %array_type.loc6_49.1: type = array_type %N.loc6_6.1, constants.%C [symbolic = %array_type.loc6_49.1 (constants.%array_type.c79)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc6_49.1 [symbolic = %pattern_type (constants.%pattern_type.cc9)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc6_42.1 [symbolic = %require_complete (constants.%require_complete.d0d)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc6_49.1 [symbolic = %require_complete (constants.%require_complete.d0d)]
 // CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %N.loc6_6.1, constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.d6e)]
-// CHECK:STDOUT:   %bound_method.loc6_62.3: <bound method> = bound_method %N.loc6_6.1, constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc6_62.3 (constants.%bound_method.7fa)]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_62.2: init %i32 = call %bound_method.loc6_62.3(%N.loc6_6.1) [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_62.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:   %bound_method.loc6_69.3: <bound method> = bound_method %N.loc6_6.1, constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc6_69.3 (constants.%bound_method.7fa)]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_69.2: init %i32 = call %bound_method.loc6_69.3(%N.loc6_6.1) [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_69.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc6_42.1 (%array_type.c79)) -> out %return.param: %i32 {
+// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc6_49.1 (%array_type.c79)) -> out %return.param: %i32 {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %N.ref.loc6_61: Core.IntLiteral = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N)]
+// CHECK:STDOUT:     %N.ref.loc6_68: Core.IntLiteral = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N)]
 // CHECK:STDOUT:     %impl.elem0: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:     %bound_method.loc6_62.1: <bound method> = bound_method %N.ref.loc6_61, %impl.elem0 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.d6e)]
+// CHECK:STDOUT:     %bound_method.loc6_69.1: <bound method> = bound_method %N.ref.loc6_68, %impl.elem0 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.d6e)]
 // CHECK:STDOUT:     %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:     %bound_method.loc6_62.2: <bound method> = bound_method %N.ref.loc6_61, %specific_fn [symbolic = %bound_method.loc6_62.3 (constants.%bound_method.7fa)]
-// CHECK:STDOUT:     %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_62.1: init %i32 = call %bound_method.loc6_62.2(%N.ref.loc6_61) [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_62.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:     %.loc6_62: init %i32 = converted %N.ref.loc6_61, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_62.1 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_62.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:     return %.loc6_62
+// CHECK:STDOUT:     %bound_method.loc6_69.2: <bound method> = bound_method %N.ref.loc6_68, %specific_fn [symbolic = %bound_method.loc6_69.3 (constants.%bound_method.7fa)]
+// CHECK:STDOUT:     %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_69.1: init %i32 = call %bound_method.loc6_69.2(%N.ref.loc6_68) [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_69.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:     %.loc6_69: init %i32 = converted %N.ref.loc6_68, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_69.1 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_69.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:     return %.loc6_69
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -549,20 +549,20 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%N) {
 // CHECK:STDOUT:   %N.loc6_6.1 => constants.%N
-// CHECK:STDOUT:   %array_type.loc6_42.1 => constants.%array_type.c79
+// CHECK:STDOUT:   %array_type.loc6_49.1 => constants.%array_type.c79
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.cc9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%int_3.1ba) {
 // CHECK:STDOUT:   %N.loc6_6.1 => constants.%int_3.1ba
-// CHECK:STDOUT:   %array_type.loc6_42.1 => constants.%array_type.931
+// CHECK:STDOUT:   %array_type.loc6_49.1 => constants.%array_type.931
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.f21
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete => constants.%complete_type.c7a
 // CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound => constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.061
-// CHECK:STDOUT:   %bound_method.loc6_62.3 => constants.%bound_method.fa7
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_62.2 => constants.%int_3.822
+// CHECK:STDOUT:   %bound_method.loc6_69.3 => constants.%bound_method.fa7
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6_69.2 => constants.%int_3.822
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- type_and_bound.carbon
@@ -642,13 +642,13 @@ fn G() {
 // CHECK:STDOUT:       %.loc6_36.3: type = converted %IntLiteral.call, %.loc6_36.2 [concrete = Core.IntLiteral]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %N.loc6_16.2: Core.IntLiteral = symbolic_binding N, 1 [symbolic = %N.loc6_16.1 (constants.%N)]
-// CHECK:STDOUT:     %a.param: @F.%array_type.loc6_52.1 (%array_type.6d2) = value_param call_param0
-// CHECK:STDOUT:     %.loc6_52: type = splice_block %array_type.loc6_52.2 [symbolic = %array_type.loc6_52.1 (constants.%array_type.6d2)] {
+// CHECK:STDOUT:     %a.param: @F.%array_type.loc6_59.1 (%array_type.6d2) = value_param call_param0
+// CHECK:STDOUT:     %.loc6_59: type = splice_block %array_type.loc6_59.2 [symbolic = %array_type.loc6_59.1 (constants.%array_type.6d2)] {
 // CHECK:STDOUT:       %T.ref: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
 // CHECK:STDOUT:       %N.ref: Core.IntLiteral = name_ref N, %N.loc6_16.2 [symbolic = %N.loc6_16.1 (constants.%N)]
-// CHECK:STDOUT:       %array_type.loc6_52.2: type = array_type %N.ref, %T.ref [symbolic = %array_type.loc6_52.1 (constants.%array_type.6d2)]
+// CHECK:STDOUT:       %array_type.loc6_59.2: type = array_type %N.ref, %T.ref [symbolic = %array_type.loc6_59.1 (constants.%array_type.6d2)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: @F.%array_type.loc6_52.1 (%array_type.6d2) = value_binding a, %a.param
+// CHECK:STDOUT:     %a: @F.%array_type.loc6_59.1 (%array_type.6d2) = value_binding a, %a.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
 // CHECK:STDOUT: }
@@ -664,13 +664,13 @@ fn G() {
 // CHECK:STDOUT: generic fn @F(%T.loc6_6.2: type, %N.loc6_16.2: Core.IntLiteral) {
 // CHECK:STDOUT:   %T.loc6_6.1: type = symbolic_binding T, 0 [symbolic = %T.loc6_6.1 (constants.%T)]
 // CHECK:STDOUT:   %N.loc6_16.1: Core.IntLiteral = symbolic_binding N, 1 [symbolic = %N.loc6_16.1 (constants.%N)]
-// CHECK:STDOUT:   %array_type.loc6_52.1: type = array_type %N.loc6_16.1, %T.loc6_6.1 [symbolic = %array_type.loc6_52.1 (constants.%array_type.6d2)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc6_52.1 [symbolic = %pattern_type (constants.%pattern_type.4d8)]
+// CHECK:STDOUT:   %array_type.loc6_59.1: type = array_type %N.loc6_16.1, %T.loc6_6.1 [symbolic = %array_type.loc6_59.1 (constants.%array_type.6d2)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc6_59.1 [symbolic = %pattern_type (constants.%pattern_type.4d8)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc6_52.1 [symbolic = %require_complete (constants.%require_complete)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc6_59.1 [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc6_52.1 (%array_type.6d2)) {
+// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc6_59.1 (%array_type.6d2)) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -723,14 +723,14 @@ fn G() {
 // CHECK:STDOUT: specific @F(constants.%T, constants.%N) {
 // CHECK:STDOUT:   %T.loc6_6.1 => constants.%T
 // CHECK:STDOUT:   %N.loc6_16.1 => constants.%N
-// CHECK:STDOUT:   %array_type.loc6_52.1 => constants.%array_type.6d2
+// CHECK:STDOUT:   %array_type.loc6_59.1 => constants.%array_type.6d2
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.4d8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%C, constants.%int_3) {
 // CHECK:STDOUT:   %T.loc6_6.1 => constants.%C
 // CHECK:STDOUT:   %N.loc6_16.1 => constants.%int_3
-// CHECK:STDOUT:   %array_type.loc6_52.1 => constants.%array_type.931
+// CHECK:STDOUT:   %array_type.loc6_59.1 => constants.%array_type.931
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.f21
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
@@ -1042,7 +1042,7 @@ fn G() {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
-// CHECK:STDOUT:     %.loc7_48: Core.Form = init_form %i32, call_param1 [concrete = constants.%.e54]
+// CHECK:STDOUT:     %.loc7_55: Core.Form = init_form %i32, call_param1 [concrete = constants.%.e54]
 // CHECK:STDOUT:     %.loc7_26.1: type = splice_block %.loc7_26.3 [concrete = Core.IntLiteral] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
@@ -1052,13 +1052,13 @@ fn G() {
 // CHECK:STDOUT:       %.loc7_26.3: type = converted %IntLiteral.call, %.loc7_26.2 [concrete = Core.IntLiteral]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %N.loc7_6.2: Core.IntLiteral = symbolic_binding N, 0 [symbolic = %N.loc7_6.1 (constants.%N)]
-// CHECK:STDOUT:     %a.param: @F.%array_type.loc7_42.1 (%array_type.c79) = value_param call_param0
-// CHECK:STDOUT:     %.loc7_42: type = splice_block %array_type.loc7_42.2 [symbolic = %array_type.loc7_42.1 (constants.%array_type.c79)] {
+// CHECK:STDOUT:     %a.param: @F.%array_type.loc7_49.1 (%array_type.c79) = value_param call_param0
+// CHECK:STDOUT:     %.loc7_49: type = splice_block %array_type.loc7_49.2 [symbolic = %array_type.loc7_49.1 (constants.%array_type.c79)] {
 // CHECK:STDOUT:       %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:       %N.ref.loc7_41: Core.IntLiteral = name_ref N, %N.loc7_6.2 [symbolic = %N.loc7_6.1 (constants.%N)]
-// CHECK:STDOUT:       %array_type.loc7_42.2: type = array_type %N.ref.loc7_41, %C.ref [symbolic = %array_type.loc7_42.1 (constants.%array_type.c79)]
+// CHECK:STDOUT:       %N.ref.loc7_48: Core.IntLiteral = name_ref N, %N.loc7_6.2 [symbolic = %N.loc7_6.1 (constants.%N)]
+// CHECK:STDOUT:       %array_type.loc7_49.2: type = array_type %N.ref.loc7_48, %C.ref [symbolic = %array_type.loc7_49.1 (constants.%array_type.c79)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: @F.%array_type.loc7_42.1 (%array_type.c79) = value_binding a, %a.param
+// CHECK:STDOUT:     %a: @F.%array_type.loc7_49.1 (%array_type.c79) = value_binding a, %a.param
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param call_param1
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -1092,25 +1092,25 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%N.loc7_6.2: Core.IntLiteral) {
 // CHECK:STDOUT:   %N.loc7_6.1: Core.IntLiteral = symbolic_binding N, 0 [symbolic = %N.loc7_6.1 (constants.%N)]
-// CHECK:STDOUT:   %array_type.loc7_42.1: type = array_type %N.loc7_6.1, constants.%C [symbolic = %array_type.loc7_42.1 (constants.%array_type.c79)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc7_42.1 [symbolic = %pattern_type (constants.%pattern_type.cc9)]
+// CHECK:STDOUT:   %array_type.loc7_49.1: type = array_type %N.loc7_6.1, constants.%C [symbolic = %array_type.loc7_49.1 (constants.%array_type.c79)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc7_49.1 [symbolic = %pattern_type (constants.%pattern_type.cc9)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc7_42.1 [symbolic = %require_complete (constants.%require_complete.d0d)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc7_49.1 [symbolic = %require_complete (constants.%require_complete.d0d)]
 // CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %N.loc7_6.1, constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.d6e)]
-// CHECK:STDOUT:   %bound_method.loc7_62.3: <bound method> = bound_method %N.loc7_6.1, constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc7_62.3 (constants.%bound_method.7fa)]
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_62.2: init %i32 = call %bound_method.loc7_62.3(%N.loc7_6.1) [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_62.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:   %bound_method.loc7_69.3: <bound method> = bound_method %N.loc7_6.1, constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc7_69.3 (constants.%bound_method.7fa)]
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_69.2: init %i32 = call %bound_method.loc7_69.3(%N.loc7_6.1) [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_69.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc7_42.1 (%array_type.c79)) -> out %return.param: %i32 {
+// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc7_49.1 (%array_type.c79)) -> out %return.param: %i32 {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %N.ref.loc7_61: Core.IntLiteral = name_ref N, %N.loc7_6.2 [symbolic = %N.loc7_6.1 (constants.%N)]
+// CHECK:STDOUT:     %N.ref.loc7_68: Core.IntLiteral = name_ref N, %N.loc7_6.2 [symbolic = %N.loc7_6.1 (constants.%N)]
 // CHECK:STDOUT:     %impl.elem0: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:     %bound_method.loc7_62.1: <bound method> = bound_method %N.ref.loc7_61, %impl.elem0 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.d6e)]
+// CHECK:STDOUT:     %bound_method.loc7_69.1: <bound method> = bound_method %N.ref.loc7_68, %impl.elem0 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.d6e)]
 // CHECK:STDOUT:     %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:     %bound_method.loc7_62.2: <bound method> = bound_method %N.ref.loc7_61, %specific_fn [symbolic = %bound_method.loc7_62.3 (constants.%bound_method.7fa)]
-// CHECK:STDOUT:     %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_62.1: init %i32 = call %bound_method.loc7_62.2(%N.ref.loc7_61) [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_62.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:     %.loc7_62: init %i32 = converted %N.ref.loc7_61, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_62.1 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_62.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:     return %.loc7_62
+// CHECK:STDOUT:     %bound_method.loc7_69.2: <bound method> = bound_method %N.ref.loc7_68, %specific_fn [symbolic = %bound_method.loc7_69.3 (constants.%bound_method.7fa)]
+// CHECK:STDOUT:     %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_69.1: init %i32 = call %bound_method.loc7_69.2(%N.ref.loc7_68) [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_69.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:     %.loc7_69: init %i32 = converted %N.ref.loc7_68, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_69.1 [symbolic = %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_69.2 (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:     return %.loc7_69
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1160,20 +1160,20 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%N) {
 // CHECK:STDOUT:   %N.loc7_6.1 => constants.%N
-// CHECK:STDOUT:   %array_type.loc7_42.1 => constants.%array_type.c79
+// CHECK:STDOUT:   %array_type.loc7_49.1 => constants.%array_type.c79
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.cc9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%int_3.1ba) {
 // CHECK:STDOUT:   %N.loc7_6.1 => constants.%int_3.1ba
-// CHECK:STDOUT:   %array_type.loc7_42.1 => constants.%array_type.931
+// CHECK:STDOUT:   %array_type.loc7_49.1 => constants.%array_type.931
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.f21
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete => constants.%complete_type.c7a
 // CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound => constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.061
-// CHECK:STDOUT:   %bound_method.loc7_62.3 => constants.%bound_method.fa7
-// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_62.2 => constants.%int_3.822
+// CHECK:STDOUT:   %bound_method.loc7_69.3 => constants.%bound_method.fa7
+// CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7_69.2 => constants.%int_3.822
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bound_type_mismatch.carbon
@@ -1280,29 +1280,29 @@ fn G() {
 // CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
 // CHECK:STDOUT:     %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %int_32.loc6_34: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc6_34: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
-// CHECK:STDOUT:     %.loc6_34: Core.Form = init_form %i32.loc6_34, call_param1 [concrete = constants.%.e54]
+// CHECK:STDOUT:     %int_32.loc6_41: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc6_41: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %.loc6_41: Core.Form = init_form %i32.loc6_41, call_param1 [concrete = constants.%.e54]
 // CHECK:STDOUT:     %.loc6_10: type = splice_block %i32.loc6_10 [concrete = constants.%i32] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %int_32.loc6_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:       %i32.loc6_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %N.loc6_6.2: %i32 = symbolic_binding N, 0 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
-// CHECK:STDOUT:     %a.param: @F.%array_type.loc6_28.1 (%array_type.8c3) = value_param call_param0
-// CHECK:STDOUT:     %.loc6_28: type = splice_block %array_type.loc6_28.2 [symbolic = %array_type.loc6_28.1 (constants.%array_type.8c3)] {
+// CHECK:STDOUT:     %a.param: @F.%array_type.loc6_35.1 (%array_type.8c3) = value_param call_param0
+// CHECK:STDOUT:     %.loc6_35: type = splice_block %array_type.loc6_35.2 [symbolic = %array_type.loc6_35.1 (constants.%array_type.8c3)] {
 // CHECK:STDOUT:       %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:       %N.ref.loc6_27: %i32 = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
-// CHECK:STDOUT:       %impl.elem0.loc6_27: %.0a7 = impl_witness_access constants.%ImplicitAs.impl_witness.640, element0 [concrete = constants.%Int.as.ImplicitAs.impl.Convert.dd4]
-// CHECK:STDOUT:       %bound_method.loc6_27.2: <bound method> = bound_method %N.ref.loc6_27, %impl.elem0.loc6_27 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
-// CHECK:STDOUT:       %specific_fn.loc6_27: <specific function> = specific_function %impl.elem0.loc6_27, @Int.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Int.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:       %bound_method.loc6_27.3: <bound method> = bound_method %N.ref.loc6_27, %specific_fn.loc6_27 [symbolic = %bound_method.loc6_27.1 (constants.%bound_method.d76)]
-// CHECK:STDOUT:       %Int.as.ImplicitAs.impl.Convert.call.loc6_27.2: init Core.IntLiteral = call %bound_method.loc6_27.3(%N.ref.loc6_27) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc6_27.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %.loc6_27.1: Core.IntLiteral = value_of_initializer %Int.as.ImplicitAs.impl.Convert.call.loc6_27.2 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc6_27.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %.loc6_27.2: Core.IntLiteral = converted %N.ref.loc6_27, %.loc6_27.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc6_27.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %array_type.loc6_28.2: type = array_type %.loc6_27.2, %C.ref [symbolic = %array_type.loc6_28.1 (constants.%array_type.8c3)]
+// CHECK:STDOUT:       %N.ref.loc6_34: %i32 = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
+// CHECK:STDOUT:       %impl.elem0.loc6_34: %.0a7 = impl_witness_access constants.%ImplicitAs.impl_witness.640, element0 [concrete = constants.%Int.as.ImplicitAs.impl.Convert.dd4]
+// CHECK:STDOUT:       %bound_method.loc6_34.2: <bound method> = bound_method %N.ref.loc6_34, %impl.elem0.loc6_34 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
+// CHECK:STDOUT:       %specific_fn.loc6_34: <specific function> = specific_function %impl.elem0.loc6_34, @Int.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Int.as.ImplicitAs.impl.Convert.specific_fn]
+// CHECK:STDOUT:       %bound_method.loc6_34.3: <bound method> = bound_method %N.ref.loc6_34, %specific_fn.loc6_34 [symbolic = %bound_method.loc6_34.1 (constants.%bound_method.d76)]
+// CHECK:STDOUT:       %Int.as.ImplicitAs.impl.Convert.call.loc6_34.2: init Core.IntLiteral = call %bound_method.loc6_34.3(%N.ref.loc6_34) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc6_34.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %.loc6_34.1: Core.IntLiteral = value_of_initializer %Int.as.ImplicitAs.impl.Convert.call.loc6_34.2 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc6_34.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %.loc6_34.2: Core.IntLiteral = converted %N.ref.loc6_34, %.loc6_34.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc6_34.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %array_type.loc6_35.2: type = array_type %.loc6_34.2, %C.ref [symbolic = %array_type.loc6_35.1 (constants.%array_type.8c3)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: @F.%array_type.loc6_28.1 (%array_type.8c3) = value_binding a, %a.param
+// CHECK:STDOUT:     %a: @F.%array_type.loc6_35.1 (%array_type.8c3) = value_binding a, %a.param
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param call_param1
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -1329,24 +1329,24 @@ fn G() {
 // CHECK:STDOUT: generic fn @F(%N.loc6_6.2: %i32) {
 // CHECK:STDOUT:   %N.loc6_6.1: %i32 = symbolic_binding N, 0 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
 // CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.ImplicitAs.impl.Convert.dd4 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
-// CHECK:STDOUT:   %bound_method.loc6_27.1: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc6_27.1 (constants.%bound_method.d76)]
-// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc6_27.1: init Core.IntLiteral = call %bound_method.loc6_27.1(%N.loc6_6.1) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc6_27.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:   %array_type.loc6_28.1: type = array_type %Int.as.ImplicitAs.impl.Convert.call.loc6_27.1, constants.%C [symbolic = %array_type.loc6_28.1 (constants.%array_type.8c3)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc6_28.1 [symbolic = %pattern_type (constants.%pattern_type.0fb)]
+// CHECK:STDOUT:   %bound_method.loc6_34.1: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc6_34.1 (constants.%bound_method.d76)]
+// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc6_34.1: init Core.IntLiteral = call %bound_method.loc6_34.1(%N.loc6_6.1) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc6_34.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:   %array_type.loc6_35.1: type = array_type %Int.as.ImplicitAs.impl.Convert.call.loc6_34.1, constants.%C [symbolic = %array_type.loc6_35.1 (constants.%array_type.8c3)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc6_35.1 [symbolic = %pattern_type (constants.%pattern_type.0fb)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc6_28.1 [symbolic = %require_complete (constants.%require_complete.a24)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc6_35.1 [symbolic = %require_complete (constants.%require_complete.a24)]
 // CHECK:STDOUT:   %Int.as.Copy.impl.Op.bound: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.Copy.impl.Op.664 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound)]
-// CHECK:STDOUT:   %bound_method.loc6_47.3: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.Copy.impl.Op.specific_fn [symbolic = %bound_method.loc6_47.3 (constants.%bound_method.207)]
+// CHECK:STDOUT:   %bound_method.loc6_54.3: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.Copy.impl.Op.specific_fn [symbolic = %bound_method.loc6_54.3 (constants.%bound_method.207)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc6_28.1 (%array_type.8c3)) -> out %return.param: %i32 {
+// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc6_35.1 (%array_type.8c3)) -> out %return.param: %i32 {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %N.ref.loc6_47: %i32 = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
-// CHECK:STDOUT:     %impl.elem0.loc6_47: %.8e2 = impl_witness_access constants.%Copy.impl_witness.f17, element0 [concrete = constants.%Int.as.Copy.impl.Op.664]
-// CHECK:STDOUT:     %bound_method.loc6_47.1: <bound method> = bound_method %N.ref.loc6_47, %impl.elem0.loc6_47 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound)]
-// CHECK:STDOUT:     %specific_fn.loc6_47: <specific function> = specific_function %impl.elem0.loc6_47, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:     %bound_method.loc6_47.2: <bound method> = bound_method %N.ref.loc6_47, %specific_fn.loc6_47 [symbolic = %bound_method.loc6_47.3 (constants.%bound_method.207)]
-// CHECK:STDOUT:     %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_47.2(%N.ref.loc6_47) [symbolic = %N.loc6_6.1 (constants.%N.5de)]
+// CHECK:STDOUT:     %N.ref.loc6_54: %i32 = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
+// CHECK:STDOUT:     %impl.elem0.loc6_54: %.8e2 = impl_witness_access constants.%Copy.impl_witness.f17, element0 [concrete = constants.%Int.as.Copy.impl.Op.664]
+// CHECK:STDOUT:     %bound_method.loc6_54.1: <bound method> = bound_method %N.ref.loc6_54, %impl.elem0.loc6_54 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound)]
+// CHECK:STDOUT:     %specific_fn.loc6_54: <specific function> = specific_function %impl.elem0.loc6_54, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
+// CHECK:STDOUT:     %bound_method.loc6_54.2: <bound method> = bound_method %N.ref.loc6_54, %specific_fn.loc6_54 [symbolic = %bound_method.loc6_54.3 (constants.%bound_method.207)]
+// CHECK:STDOUT:     %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_54.2(%N.ref.loc6_54) [symbolic = %N.loc6_6.1 (constants.%N.5de)]
 // CHECK:STDOUT:     return %Int.as.Copy.impl.Op.call
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -1395,9 +1395,9 @@ fn G() {
 // CHECK:STDOUT: specific @F(constants.%N.5de) {
 // CHECK:STDOUT:   %N.loc6_6.1 => constants.%N.5de
 // CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.bound => constants.%Int.as.ImplicitAs.impl.Convert.bound
-// CHECK:STDOUT:   %bound_method.loc6_27.1 => constants.%bound_method.d76
-// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc6_27.1 => constants.%Int.as.ImplicitAs.impl.Convert.call
-// CHECK:STDOUT:   %array_type.loc6_28.1 => constants.%array_type.8c3
+// CHECK:STDOUT:   %bound_method.loc6_34.1 => constants.%bound_method.d76
+// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc6_34.1 => constants.%Int.as.ImplicitAs.impl.Convert.call
+// CHECK:STDOUT:   %array_type.loc6_35.1 => constants.%array_type.8c3
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.0fb
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1476,20 +1476,20 @@ fn G() {
 // CHECK:STDOUT:       %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %N.loc5_6.2: %i32 = symbolic_binding N, 0 [symbolic = %N.loc5_6.1 (constants.%N.5de)]
-// CHECK:STDOUT:     %a.param: @F.%array_type.loc5_28.1 (%array_type) = value_param call_param0
-// CHECK:STDOUT:     %.loc5_28: type = splice_block %array_type.loc5_28.2 [symbolic = %array_type.loc5_28.1 (constants.%array_type)] {
+// CHECK:STDOUT:     %a.param: @F.%array_type.loc5_35.1 (%array_type) = value_param call_param0
+// CHECK:STDOUT:     %.loc5_35: type = splice_block %array_type.loc5_35.2 [symbolic = %array_type.loc5_35.1 (constants.%array_type)] {
 // CHECK:STDOUT:       %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
 // CHECK:STDOUT:       %N.ref: %i32 = name_ref N, %N.loc5_6.2 [symbolic = %N.loc5_6.1 (constants.%N.5de)]
 // CHECK:STDOUT:       %impl.elem0: %.0a7 = impl_witness_access constants.%ImplicitAs.impl_witness.640, element0 [concrete = constants.%Int.as.ImplicitAs.impl.Convert.dd4]
-// CHECK:STDOUT:       %bound_method.loc5_27.2: <bound method> = bound_method %N.ref, %impl.elem0 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
+// CHECK:STDOUT:       %bound_method.loc5_34.2: <bound method> = bound_method %N.ref, %impl.elem0 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
 // CHECK:STDOUT:       %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Int.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:       %bound_method.loc5_27.3: <bound method> = bound_method %N.ref, %specific_fn [symbolic = %bound_method.loc5_27.1 (constants.%bound_method)]
-// CHECK:STDOUT:       %Int.as.ImplicitAs.impl.Convert.call.loc5_27.2: init Core.IntLiteral = call %bound_method.loc5_27.3(%N.ref) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc5_27.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %.loc5_27.1: Core.IntLiteral = value_of_initializer %Int.as.ImplicitAs.impl.Convert.call.loc5_27.2 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc5_27.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %.loc5_27.2: Core.IntLiteral = converted %N.ref, %.loc5_27.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc5_27.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %array_type.loc5_28.2: type = array_type %.loc5_27.2, %C.ref [symbolic = %array_type.loc5_28.1 (constants.%array_type)]
+// CHECK:STDOUT:       %bound_method.loc5_34.3: <bound method> = bound_method %N.ref, %specific_fn [symbolic = %bound_method.loc5_34.1 (constants.%bound_method)]
+// CHECK:STDOUT:       %Int.as.ImplicitAs.impl.Convert.call.loc5_34.2: init Core.IntLiteral = call %bound_method.loc5_34.3(%N.ref) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc5_34.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %.loc5_34.1: Core.IntLiteral = value_of_initializer %Int.as.ImplicitAs.impl.Convert.call.loc5_34.2 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc5_34.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %.loc5_34.2: Core.IntLiteral = converted %N.ref, %.loc5_34.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc5_34.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %array_type.loc5_35.2: type = array_type %.loc5_34.2, %C.ref [symbolic = %array_type.loc5_35.1 (constants.%array_type)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: @F.%array_type.loc5_28.1 (%array_type) = value_binding a, %a.param
+// CHECK:STDOUT:     %a: @F.%array_type.loc5_35.1 (%array_type) = value_binding a, %a.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
 // CHECK:STDOUT: }
@@ -1505,15 +1505,15 @@ fn G() {
 // CHECK:STDOUT: generic fn @F(%N.loc5_6.2: %i32) {
 // CHECK:STDOUT:   %N.loc5_6.1: %i32 = symbolic_binding N, 0 [symbolic = %N.loc5_6.1 (constants.%N.5de)]
 // CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %N.loc5_6.1, constants.%Int.as.ImplicitAs.impl.Convert.dd4 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
-// CHECK:STDOUT:   %bound_method.loc5_27.1: <bound method> = bound_method %N.loc5_6.1, constants.%Int.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc5_27.1 (constants.%bound_method)]
-// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc5_27.1: init Core.IntLiteral = call %bound_method.loc5_27.1(%N.loc5_6.1) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc5_27.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:   %array_type.loc5_28.1: type = array_type %Int.as.ImplicitAs.impl.Convert.call.loc5_27.1, constants.%C [symbolic = %array_type.loc5_28.1 (constants.%array_type)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc5_28.1 [symbolic = %pattern_type (constants.%pattern_type.0fb)]
+// CHECK:STDOUT:   %bound_method.loc5_34.1: <bound method> = bound_method %N.loc5_6.1, constants.%Int.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc5_34.1 (constants.%bound_method)]
+// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc5_34.1: init Core.IntLiteral = call %bound_method.loc5_34.1(%N.loc5_6.1) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc5_34.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:   %array_type.loc5_35.1: type = array_type %Int.as.ImplicitAs.impl.Convert.call.loc5_34.1, constants.%C [symbolic = %array_type.loc5_35.1 (constants.%array_type)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc5_35.1 [symbolic = %pattern_type (constants.%pattern_type.0fb)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc5_28.1 [symbolic = %require_complete (constants.%require_complete.a24)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc5_35.1 [symbolic = %require_complete (constants.%require_complete.a24)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc5_28.1 (%array_type)) {
+// CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc5_35.1 (%array_type)) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -1532,9 +1532,9 @@ fn G() {
 // CHECK:STDOUT: specific @F(constants.%N.5de) {
 // CHECK:STDOUT:   %N.loc5_6.1 => constants.%N.5de
 // CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.bound => constants.%Int.as.ImplicitAs.impl.Convert.bound
-// CHECK:STDOUT:   %bound_method.loc5_27.1 => constants.%bound_method
-// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc5_27.1 => constants.%Int.as.ImplicitAs.impl.Convert.call
-// CHECK:STDOUT:   %array_type.loc5_28.1 => constants.%array_type
+// CHECK:STDOUT:   %bound_method.loc5_34.1 => constants.%bound_method
+// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc5_34.1 => constants.%Int.as.ImplicitAs.impl.Convert.call
+// CHECK:STDOUT:   %array_type.loc5_35.1 => constants.%array_type
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.0fb
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 39 - 39
toolchain/check/testdata/deduce/binding_pattern.carbon

@@ -17,19 +17,19 @@
 library "[[@TEST_NAME]]";
 
 class C(T:! type) {
-  fn Create(value: T) {}
+  fn Create(unused value: T) {}
 }
 
-fn F(U:! type, V:! type) {
+fn F(unused U:! type, V:! type) {
   // CHECK:STDERR: fail_incompatible_deduce.carbon:[[@LINE+10]]:15: error: cannot implicitly convert expression of type `{}` to `V` [ConversionFailure]
   // CHECK:STDERR:   C(V).Create({});
   // CHECK:STDERR:               ^~
   // CHECK:STDERR: fail_incompatible_deduce.carbon:[[@LINE+7]]:15: note: type `{}` does not implement interface `Core.ImplicitAs(V)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   C(V).Create({});
   // CHECK:STDERR:               ^~
-  // CHECK:STDERR: fail_incompatible_deduce.carbon:[[@LINE-10]]:13: note: initializing function parameter [InCallToFunctionParam]
-  // CHECK:STDERR:   fn Create(value: T) {}
-  // CHECK:STDERR:             ^~~~~~~~
+  // CHECK:STDERR: fail_incompatible_deduce.carbon:[[@LINE-10]]:20: note: initializing function parameter [InCallToFunctionParam]
+  // CHECK:STDERR:   fn Create(unused value: T) {}
+  // CHECK:STDERR:                    ^~~~~~~~
   // CHECK:STDERR:
   C(V).Create({});
 }
@@ -39,20 +39,20 @@ fn F(U:! type, V:! type) {
 library "[[@TEST_NAME]]";
 
 class C(T:! type) {
-  fn Create(value: T) {}
+  fn Create(unused value: T) {}
 }
 
 // TODO: This `where` should be sufficient to say that `{} as V` works.
-fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
+fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
   // CHECK:STDERR: fail_todo_compatible_deduce.carbon:[[@LINE+10]]:15: error: cannot implicitly convert expression of type `{}` to `V` [ConversionFailure]
   // CHECK:STDERR:   C(V).Create({});
   // CHECK:STDERR:               ^~
   // CHECK:STDERR: fail_todo_compatible_deduce.carbon:[[@LINE+7]]:15: note: type `{}` does not implement interface `Core.ImplicitAs(V)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   C(V).Create({});
   // CHECK:STDERR:               ^~
-  // CHECK:STDERR: fail_todo_compatible_deduce.carbon:[[@LINE-11]]:13: note: initializing function parameter [InCallToFunctionParam]
-  // CHECK:STDERR:   fn Create(value: T) {}
-  // CHECK:STDERR:             ^~~~~~~~
+  // CHECK:STDERR: fail_todo_compatible_deduce.carbon:[[@LINE-11]]:20: note: initializing function parameter [InCallToFunctionParam]
+  // CHECK:STDERR:   fn Create(unused value: T) {}
+  // CHECK:STDERR:                    ^~~~~~~~
   // CHECK:STDERR:
   C(V).Create({});
 }
@@ -131,9 +131,9 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
 // CHECK:STDOUT:     %V.patt: %pattern_type.98f = symbolic_binding_pattern V, 1 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
-// CHECK:STDOUT:     %U.loc8_6.2: type = symbolic_binding U, 0 [symbolic = %U.loc8_6.1 (constants.%U)]
+// CHECK:STDOUT:     %U.loc8_13.2: type = symbolic_binding U, 0 [symbolic = %U.loc8_13.1 (constants.%U)]
 // CHECK:STDOUT:     %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
-// CHECK:STDOUT:     %V.loc8_16.2: type = symbolic_binding V, 1 [symbolic = %V.loc8_16.1 (constants.%V)]
+// CHECK:STDOUT:     %V.loc8_23.2: type = symbolic_binding V, 1 [symbolic = %V.loc8_23.1 (constants.%V)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -176,26 +176,26 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F(%U.loc8_6.2: type, %V.loc8_16.2: type) {
-// CHECK:STDOUT:   %U.loc8_6.1: type = symbolic_binding U, 0 [symbolic = %U.loc8_6.1 (constants.%U)]
-// CHECK:STDOUT:   %V.loc8_16.1: type = symbolic_binding V, 1 [symbolic = %V.loc8_16.1 (constants.%V)]
+// CHECK:STDOUT: generic fn @F(%U.loc8_13.2: type, %V.loc8_23.2: type) {
+// CHECK:STDOUT:   %U.loc8_13.1: type = symbolic_binding U, 0 [symbolic = %U.loc8_13.1 (constants.%U)]
+// CHECK:STDOUT:   %V.loc8_23.1: type = symbolic_binding V, 1 [symbolic = %V.loc8_23.1 (constants.%V)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %C.loc19_6.2: type = class_type @C, @C(%V.loc8_16.1) [symbolic = %C.loc19_6.2 (constants.%C.ee9)]
+// CHECK:STDOUT:   %C.loc19_6.2: type = class_type @C, @C(%V.loc8_23.1) [symbolic = %C.loc19_6.2 (constants.%C.ee9)]
 // CHECK:STDOUT:   %require_complete.loc19_7: <witness> = require_complete_type %C.loc19_6.2 [symbolic = %require_complete.loc19_7 (constants.%require_complete.1fc)]
-// CHECK:STDOUT:   %C.Create.type: type = fn_type @C.Create, @C(%V.loc8_16.1) [symbolic = %C.Create.type (constants.%C.Create.type.c3d)]
+// CHECK:STDOUT:   %C.Create.type: type = fn_type @C.Create, @C(%V.loc8_23.1) [symbolic = %C.Create.type (constants.%C.Create.type.c3d)]
 // CHECK:STDOUT:   %C.Create: @F.%C.Create.type (%C.Create.type.c3d) = struct_value () [symbolic = %C.Create (constants.%C.Create.b40)]
-// CHECK:STDOUT:   %C.Create.specific_fn.loc19_7.2: <specific function> = specific_function %C.Create, @C.Create(%V.loc8_16.1) [symbolic = %C.Create.specific_fn.loc19_7.2 (constants.%C.Create.specific_fn)]
-// CHECK:STDOUT:   %require_complete.loc19_16.1: <witness> = require_complete_type %V.loc8_16.1 [symbolic = %require_complete.loc19_16.1 (constants.%require_complete.441)]
-// CHECK:STDOUT:   %ImplicitAs.type.loc19_16.2: type = facet_type <@ImplicitAs, @ImplicitAs(%V.loc8_16.1)> [symbolic = %ImplicitAs.type.loc19_16.2 (constants.%ImplicitAs.type.1e5)]
+// CHECK:STDOUT:   %C.Create.specific_fn.loc19_7.2: <specific function> = specific_function %C.Create, @C.Create(%V.loc8_23.1) [symbolic = %C.Create.specific_fn.loc19_7.2 (constants.%C.Create.specific_fn)]
+// CHECK:STDOUT:   %require_complete.loc19_16.1: <witness> = require_complete_type %V.loc8_23.1 [symbolic = %require_complete.loc19_16.1 (constants.%require_complete.441)]
+// CHECK:STDOUT:   %ImplicitAs.type.loc19_16.2: type = facet_type <@ImplicitAs, @ImplicitAs(%V.loc8_23.1)> [symbolic = %ImplicitAs.type.loc19_16.2 (constants.%ImplicitAs.type.1e5)]
 // CHECK:STDOUT:   %require_complete.loc19_16.2: <witness> = require_complete_type %ImplicitAs.type.loc19_16.2 [symbolic = %require_complete.loc19_16.2 (constants.%require_complete.cc6)]
-// CHECK:STDOUT:   %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%V.loc8_16.1) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.d88)]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%V.loc8_23.1) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.d88)]
 // CHECK:STDOUT:   %assoc0: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.d88) = assoc_entity element0, imports.%Core.import_ref.201 [symbolic = %assoc0 (constants.%assoc0.3d8)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic]
-// CHECK:STDOUT:     %V.ref: type = name_ref V, %V.loc8_16.2 [symbolic = %V.loc8_16.1 (constants.%V)]
+// CHECK:STDOUT:     %V.ref: type = name_ref V, %V.loc8_23.2 [symbolic = %V.loc8_23.1 (constants.%V)]
 // CHECK:STDOUT:     %C.loc19_6.1: type = class_type @C, @C(constants.%V) [symbolic = %C.loc19_6.2 (constants.%C.ee9)]
 // CHECK:STDOUT:     %.loc19_7: @F.%C.Create.type (%C.Create.type.c3d) = specific_constant @C.%C.Create.decl, @C(constants.%V) [symbolic = %C.Create (constants.%C.Create.b40)]
 // CHECK:STDOUT:     %Create.ref: @F.%C.Create.type (%C.Create.type.c3d) = name_ref Create, %.loc19_7 [symbolic = %C.Create (constants.%C.Create.b40)]
@@ -204,7 +204,7 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
 // CHECK:STDOUT:     %ImplicitAs.type.loc19_16.1: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%V)> [symbolic = %ImplicitAs.type.loc19_16.2 (constants.%ImplicitAs.type.1e5)]
 // CHECK:STDOUT:     %.loc19_16.2: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.d88) = specific_constant imports.%Core.import_ref.178, @ImplicitAs(constants.%V, constants.%Self.738) [symbolic = %assoc0 (constants.%assoc0.3d8)]
 // CHECK:STDOUT:     %Convert.ref: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.d88) = name_ref Convert, %.loc19_16.2 [symbolic = %assoc0 (constants.%assoc0.3d8)]
-// CHECK:STDOUT:     %.loc19_16.3: @F.%V.loc8_16.1 (%V) = converted %.loc19_16.1, <error> [concrete = <error>]
+// CHECK:STDOUT:     %.loc19_16.3: @F.%V.loc8_23.1 (%V) = converted %.loc19_16.1, <error> [concrete = <error>]
 // CHECK:STDOUT:     %C.Create.call: init %empty_tuple.type = call %C.Create.specific_fn.loc19_7.1(<error>)
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -224,8 +224,8 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%U, constants.%V) {
-// CHECK:STDOUT:   %U.loc8_6.1 => constants.%U
-// CHECK:STDOUT:   %V.loc8_16.1 => constants.%V
+// CHECK:STDOUT:   %U.loc8_13.1 => constants.%U
+// CHECK:STDOUT:   %V.loc8_23.1 => constants.%V
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(constants.%V) {
@@ -323,22 +323,22 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
 // CHECK:STDOUT:     %V.patt: %pattern_type.354 = symbolic_binding_pattern V, 1 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39]
-// CHECK:STDOUT:     %U.loc9_6.2: type = symbolic_binding U, 0 [symbolic = %U.loc9_6.1 (constants.%U)]
-// CHECK:STDOUT:     %.loc9_25.1: type = splice_block %.loc9_25.2 [concrete = constants.%type_where] {
+// CHECK:STDOUT:     %U.loc9_13.2: type = symbolic_binding U, 0 [symbolic = %U.loc9_13.1 (constants.%U)]
+// CHECK:STDOUT:     %.loc9_32.1: type = splice_block %.loc9_32.2 [concrete = constants.%type_where] {
 // CHECK:STDOUT:       %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39]
 // CHECK:STDOUT:       %.Self.3: type = symbolic_binding .Self [symbolic_self = constants.%.Self.16f]
-// CHECK:STDOUT:       %.loc9_32.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
+// CHECK:STDOUT:       %.loc9_39.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
 // CHECK:STDOUT:       %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
 // CHECK:STDOUT:       %ImplicitAs.ref: %ImplicitAs.type.cc7 = name_ref ImplicitAs, imports.%Core.ImplicitAs [concrete = constants.%ImplicitAs.generic]
 // CHECK:STDOUT:       %.Self.ref: type = name_ref .Self, %.Self.3 [symbolic_self = constants.%.Self.16f]
 // CHECK:STDOUT:       %ImplicitAs.type.loc9: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%.Self.16f)> [symbolic_self = constants.%ImplicitAs.type.f60]
-// CHECK:STDOUT:       %.loc9_32.2: type = converted %.loc9_32.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
-// CHECK:STDOUT:       %.loc9_25.2: type = where_expr %.Self.3 [concrete = constants.%type_where] {
+// CHECK:STDOUT:       %.loc9_39.2: type = converted %.loc9_39.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:       %.loc9_32.2: type = where_expr %.Self.3 [concrete = constants.%type_where] {
 // CHECK:STDOUT:         requirement_base_facet_type type
-// CHECK:STDOUT:         requirement_impls %.loc9_32.2, %ImplicitAs.type.loc9
+// CHECK:STDOUT:         requirement_impls %.loc9_39.2, %ImplicitAs.type.loc9
 // CHECK:STDOUT:       }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %V.loc9_16.2: %type_where = symbolic_binding V, 1 [symbolic = %V.loc9_16.1 (constants.%V)]
+// CHECK:STDOUT:     %V.loc9_23.2: %type_where = symbolic_binding V, 1 [symbolic = %V.loc9_23.1 (constants.%V)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -381,12 +381,12 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F(%U.loc9_6.2: type, %V.loc9_16.2: %type_where) {
-// CHECK:STDOUT:   %U.loc9_6.1: type = symbolic_binding U, 0 [symbolic = %U.loc9_6.1 (constants.%U)]
-// CHECK:STDOUT:   %V.loc9_16.1: %type_where = symbolic_binding V, 1 [symbolic = %V.loc9_16.1 (constants.%V)]
+// CHECK:STDOUT: generic fn @F(%U.loc9_13.2: type, %V.loc9_23.2: %type_where) {
+// CHECK:STDOUT:   %U.loc9_13.1: type = symbolic_binding U, 0 [symbolic = %U.loc9_13.1 (constants.%U)]
+// CHECK:STDOUT:   %V.loc9_23.1: %type_where = symbolic_binding V, 1 [symbolic = %V.loc9_23.1 (constants.%V)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %V.binding.as_type: type = symbolic_binding_type V, 1, %V.loc9_16.1 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)]
+// CHECK:STDOUT:   %V.binding.as_type: type = symbolic_binding_type V, 1, %V.loc9_23.1 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)]
 // CHECK:STDOUT:   %C.loc20_6.2: type = class_type @C, @C(%V.binding.as_type) [symbolic = %C.loc20_6.2 (constants.%C.bca)]
 // CHECK:STDOUT:   %require_complete.loc20_7: <witness> = require_complete_type %C.loc20_6.2 [symbolic = %require_complete.loc20_7 (constants.%require_complete.232)]
 // CHECK:STDOUT:   %C.Create.type: type = fn_type @C.Create, @C(%V.binding.as_type) [symbolic = %C.Create.type (constants.%C.Create.type.242)]
@@ -401,7 +401,7 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic]
-// CHECK:STDOUT:     %V.ref: %type_where = name_ref V, %V.loc9_16.2 [symbolic = %V.loc9_16.1 (constants.%V)]
+// CHECK:STDOUT:     %V.ref: %type_where = name_ref V, %V.loc9_23.2 [symbolic = %V.loc9_23.1 (constants.%V)]
 // CHECK:STDOUT:     %V.as_type: type = facet_access_type %V.ref [symbolic = %V.binding.as_type (constants.%V.binding.as_type)]
 // CHECK:STDOUT:     %.loc20_6: type = converted %V.ref, %V.as_type [symbolic = %V.binding.as_type (constants.%V.binding.as_type)]
 // CHECK:STDOUT:     %C.loc20_6.1: type = class_type @C, @C(constants.%V.binding.as_type) [symbolic = %C.loc20_6.2 (constants.%C.bca)]
@@ -432,8 +432,8 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%U, constants.%V) {
-// CHECK:STDOUT:   %U.loc9_6.1 => constants.%U
-// CHECK:STDOUT:   %V.loc9_16.1 => constants.%V
+// CHECK:STDOUT:   %U.loc9_13.1 => constants.%U
+// CHECK:STDOUT:   %V.loc9_23.1 => constants.%V
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(constants.%V.binding.as_type) {

+ 21 - 21
toolchain/check/testdata/deduce/generic_type.carbon

@@ -63,7 +63,7 @@ library "[[@TEST_NAME]]";
 
 class WithNontype(N:! i32) {}
 
-fn F[N:! i32](x: WithNontype(N)) -> i32 { return N; }
+fn F[N:! i32](unused x: WithNontype(N)) -> i32 { return N; }
 
 fn G() -> i32 {
   return F({} as WithNontype(0));
@@ -831,22 +831,22 @@ fn G() -> i32 {
 // CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
 // CHECK:STDOUT:     %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %int_32.loc6_37: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc6_37: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
-// CHECK:STDOUT:     %.loc6_37: Core.Form = init_form %i32.loc6_37, call_param1 [concrete = constants.%.e54]
+// CHECK:STDOUT:     %int_32.loc6_44: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc6_44: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %.loc6_44: Core.Form = init_form %i32.loc6_44, call_param1 [concrete = constants.%.e54]
 // CHECK:STDOUT:     %.loc6_10: type = splice_block %i32.loc6_10 [concrete = constants.%i32] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %int_32.loc6_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:       %i32.loc6_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %N.loc6_6.2: %i32 = symbolic_binding N, 0 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
-// CHECK:STDOUT:     %x.param: @F.%WithNontype.loc6_31.1 (%WithNontype.205) = value_param call_param0
-// CHECK:STDOUT:     %.loc6_31: type = splice_block %WithNontype.loc6_31.2 [symbolic = %WithNontype.loc6_31.1 (constants.%WithNontype.205)] {
+// CHECK:STDOUT:     %x.param: @F.%WithNontype.loc6_38.1 (%WithNontype.205) = value_param call_param0
+// CHECK:STDOUT:     %.loc6_38: type = splice_block %WithNontype.loc6_38.2 [symbolic = %WithNontype.loc6_38.1 (constants.%WithNontype.205)] {
 // CHECK:STDOUT:       %WithNontype.ref: %WithNontype.type = name_ref WithNontype, file.%WithNontype.decl [concrete = constants.%WithNontype.generic]
-// CHECK:STDOUT:       %N.ref.loc6_30: %i32 = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
-// CHECK:STDOUT:       %WithNontype.loc6_31.2: type = class_type @WithNontype, @WithNontype(constants.%N.5de) [symbolic = %WithNontype.loc6_31.1 (constants.%WithNontype.205)]
+// CHECK:STDOUT:       %N.ref.loc6_37: %i32 = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
+// CHECK:STDOUT:       %WithNontype.loc6_38.2: type = class_type @WithNontype, @WithNontype(constants.%N.5de) [symbolic = %WithNontype.loc6_38.1 (constants.%WithNontype.205)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: @F.%WithNontype.loc6_31.1 (%WithNontype.205) = value_binding x, %x.param
+// CHECK:STDOUT:     %x: @F.%WithNontype.loc6_38.1 (%WithNontype.205) = value_binding x, %x.param
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param call_param1
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -878,22 +878,22 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%N.loc6_6.2: %i32) {
 // CHECK:STDOUT:   %N.loc6_6.1: %i32 = symbolic_binding N, 0 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
-// CHECK:STDOUT:   %WithNontype.loc6_31.1: type = class_type @WithNontype, @WithNontype(%N.loc6_6.1) [symbolic = %WithNontype.loc6_31.1 (constants.%WithNontype.205)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %WithNontype.loc6_31.1 [symbolic = %pattern_type (constants.%pattern_type.43d)]
+// CHECK:STDOUT:   %WithNontype.loc6_38.1: type = class_type @WithNontype, @WithNontype(%N.loc6_6.1) [symbolic = %WithNontype.loc6_38.1 (constants.%WithNontype.205)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %WithNontype.loc6_38.1 [symbolic = %pattern_type (constants.%pattern_type.43d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %WithNontype.loc6_31.1 [symbolic = %require_complete (constants.%require_complete.643)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %WithNontype.loc6_38.1 [symbolic = %require_complete (constants.%require_complete.643)]
 // CHECK:STDOUT:   %Int.as.Copy.impl.Op.bound: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.Copy.impl.Op.664 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound.e78)]
-// CHECK:STDOUT:   %bound_method.loc6_50.3: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.Copy.impl.Op.specific_fn [symbolic = %bound_method.loc6_50.3 (constants.%bound_method.207)]
+// CHECK:STDOUT:   %bound_method.loc6_57.3: <bound method> = bound_method %N.loc6_6.1, constants.%Int.as.Copy.impl.Op.specific_fn [symbolic = %bound_method.loc6_57.3 (constants.%bound_method.207)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%x.param: @F.%WithNontype.loc6_31.1 (%WithNontype.205)) -> out %return.param: %i32 {
+// CHECK:STDOUT:   fn(%x.param: @F.%WithNontype.loc6_38.1 (%WithNontype.205)) -> out %return.param: %i32 {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %N.ref.loc6_50: %i32 = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
+// CHECK:STDOUT:     %N.ref.loc6_57: %i32 = name_ref N, %N.loc6_6.2 [symbolic = %N.loc6_6.1 (constants.%N.5de)]
 // CHECK:STDOUT:     %impl.elem0: %.8e2 = impl_witness_access constants.%Copy.impl_witness.f17, element0 [concrete = constants.%Int.as.Copy.impl.Op.664]
-// CHECK:STDOUT:     %bound_method.loc6_50.1: <bound method> = bound_method %N.ref.loc6_50, %impl.elem0 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound.e78)]
+// CHECK:STDOUT:     %bound_method.loc6_57.1: <bound method> = bound_method %N.ref.loc6_57, %impl.elem0 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound.e78)]
 // CHECK:STDOUT:     %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:     %bound_method.loc6_50.2: <bound method> = bound_method %N.ref.loc6_50, %specific_fn [symbolic = %bound_method.loc6_50.3 (constants.%bound_method.207)]
-// CHECK:STDOUT:     %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_50.2(%N.ref.loc6_50) [symbolic = %N.loc6_6.1 (constants.%N.5de)]
+// CHECK:STDOUT:     %bound_method.loc6_57.2: <bound method> = bound_method %N.ref.loc6_57, %specific_fn [symbolic = %bound_method.loc6_57.3 (constants.%bound_method.207)]
+// CHECK:STDOUT:     %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_57.2(%N.ref.loc6_57) [symbolic = %N.loc6_6.1 (constants.%N.5de)]
 // CHECK:STDOUT:     return %Int.as.Copy.impl.Op.call
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -934,7 +934,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%N.5de) {
 // CHECK:STDOUT:   %N.loc6_6.1 => constants.%N.5de
-// CHECK:STDOUT:   %WithNontype.loc6_31.1 => constants.%WithNontype.205
+// CHECK:STDOUT:   %WithNontype.loc6_38.1 => constants.%WithNontype.205
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.43d
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -946,12 +946,12 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%int_0.6a9) {
 // CHECK:STDOUT:   %N.loc6_6.1 => constants.%int_0.6a9
-// CHECK:STDOUT:   %WithNontype.loc6_31.1 => constants.%WithNontype.6bb
+// CHECK:STDOUT:   %WithNontype.loc6_38.1 => constants.%WithNontype.6bb
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.7a0
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete => constants.%complete_type.357
 // CHECK:STDOUT:   %Int.as.Copy.impl.Op.bound => constants.%Int.as.Copy.impl.Op.bound.06d
-// CHECK:STDOUT:   %bound_method.loc6_50.3 => constants.%bound_method.5f6
+// CHECK:STDOUT:   %bound_method.loc6_57.3 => constants.%bound_method.5f6
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 36 - 36
toolchain/check/testdata/deduce/int_float.carbon

@@ -16,7 +16,7 @@
 
 library "[[@TEST_NAME]]";
 
-fn F[N:! Core.IntLiteral()](n: Core.Int(N)) -> Core.IntLiteral() {
+fn F[N:! Core.IntLiteral()](unused n: Core.Int(N)) -> Core.IntLiteral() {
   return N;
 }
 
@@ -28,7 +28,7 @@ fn G(a: i64) -> Core.IntLiteral() {
 
 library "[[@TEST_NAME]]";
 
-fn F[N:! Core.IntLiteral()](n: Core.Float(N)) -> Core.IntLiteral() {
+fn F[N:! Core.IntLiteral()](unused n: Core.Float(N)) -> Core.IntLiteral() {
   return N;
 }
 
@@ -101,12 +101,12 @@ fn G(a: f64) -> Core.IntLiteral() {
 // CHECK:STDOUT:     %return.patt: %pattern_type.dc0 = return_slot_pattern [concrete]
 // CHECK:STDOUT:     %return.param_patt: %pattern_type.dc0 = out_param_pattern %return.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %Core.ref.loc4_48: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:     %IntLiteral.ref.loc4_52: %IntLiteral.type = name_ref IntLiteral, imports.%Core.IntLiteral [concrete = constants.%IntLiteral]
-// CHECK:STDOUT:     %IntLiteral.call.loc4_64: init type = call %IntLiteral.ref.loc4_52() [concrete = Core.IntLiteral]
-// CHECK:STDOUT:     %.loc4_64.1: type = value_of_initializer %IntLiteral.call.loc4_64 [concrete = Core.IntLiteral]
-// CHECK:STDOUT:     %.loc4_64.2: type = converted %IntLiteral.call.loc4_64, %.loc4_64.1 [concrete = Core.IntLiteral]
-// CHECK:STDOUT:     %.loc4_64.3: Core.Form = init_form %.loc4_64.2, call_param1 [concrete = constants.%.7dc]
+// CHECK:STDOUT:     %Core.ref.loc4_55: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:     %IntLiteral.ref.loc4_59: %IntLiteral.type = name_ref IntLiteral, imports.%Core.IntLiteral [concrete = constants.%IntLiteral]
+// CHECK:STDOUT:     %IntLiteral.call.loc4_71: init type = call %IntLiteral.ref.loc4_59() [concrete = Core.IntLiteral]
+// CHECK:STDOUT:     %.loc4_71.1: type = value_of_initializer %IntLiteral.call.loc4_71 [concrete = Core.IntLiteral]
+// CHECK:STDOUT:     %.loc4_71.2: type = converted %IntLiteral.call.loc4_71, %.loc4_71.1 [concrete = Core.IntLiteral]
+// CHECK:STDOUT:     %.loc4_71.3: Core.Form = init_form %.loc4_71.2, call_param1 [concrete = constants.%.7dc]
 // CHECK:STDOUT:     %.loc4_26.1: type = splice_block %.loc4_26.3 [concrete = Core.IntLiteral] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %Core.ref.loc4_10: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
@@ -116,14 +116,14 @@ fn G(a: f64) -> Core.IntLiteral() {
 // CHECK:STDOUT:       %.loc4_26.3: type = converted %IntLiteral.call.loc4_26, %.loc4_26.2 [concrete = Core.IntLiteral]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %N.loc4_6.2: Core.IntLiteral = symbolic_binding N, 0 [symbolic = %N.loc4_6.1 (constants.%N)]
-// CHECK:STDOUT:     %n.param: @F.%Int.loc4_42.1 (%Int) = value_param call_param0
-// CHECK:STDOUT:     %.loc4_42: type = splice_block %Int.loc4_42.2 [symbolic = %Int.loc4_42.1 (constants.%Int)] {
-// CHECK:STDOUT:       %Core.ref.loc4_32: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:     %n.param: @F.%Int.loc4_49.1 (%Int) = value_param call_param0
+// CHECK:STDOUT:     %.loc4_49: type = splice_block %Int.loc4_49.2 [symbolic = %Int.loc4_49.1 (constants.%Int)] {
+// CHECK:STDOUT:       %Core.ref.loc4_39: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
 // CHECK:STDOUT:       %Int.ref: %Int.type = name_ref Int, imports.%Core.Int [concrete = constants.%Int.generic]
 // CHECK:STDOUT:       %N.ref.loc4: Core.IntLiteral = name_ref N, %N.loc4_6.2 [symbolic = %N.loc4_6.1 (constants.%N)]
-// CHECK:STDOUT:       %Int.loc4_42.2: type = class_type @Int, @Int(constants.%N) [symbolic = %Int.loc4_42.1 (constants.%Int)]
+// CHECK:STDOUT:       %Int.loc4_49.2: type = class_type @Int, @Int(constants.%N) [symbolic = %Int.loc4_49.1 (constants.%Int)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %n: @F.%Int.loc4_42.1 (%Int) = value_binding n, %n.param
+// CHECK:STDOUT:     %n: @F.%Int.loc4_49.1 (%Int) = value_binding n, %n.param
 // CHECK:STDOUT:     %return.param: ref Core.IntLiteral = out_param call_param1
 // CHECK:STDOUT:     %return: ref Core.IntLiteral = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -152,14 +152,14 @@ fn G(a: f64) -> Core.IntLiteral() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%N.loc4_6.2: Core.IntLiteral) {
 // CHECK:STDOUT:   %N.loc4_6.1: Core.IntLiteral = symbolic_binding N, 0 [symbolic = %N.loc4_6.1 (constants.%N)]
-// CHECK:STDOUT:   %Int.loc4_42.1: type = class_type @Int, @Int(%N.loc4_6.1) [symbolic = %Int.loc4_42.1 (constants.%Int)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %Int.loc4_42.1 [symbolic = %pattern_type (constants.%pattern_type.764)]
+// CHECK:STDOUT:   %Int.loc4_49.1: type = class_type @Int, @Int(%N.loc4_6.1) [symbolic = %Int.loc4_49.1 (constants.%Int)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %Int.loc4_49.1 [symbolic = %pattern_type (constants.%pattern_type.764)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %Int.loc4_42.1 [symbolic = %require_complete (constants.%require_complete.901)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %Int.loc4_49.1 [symbolic = %require_complete (constants.%require_complete.901)]
 // CHECK:STDOUT:   %Core.IntLiteral.as.Copy.impl.Op.bound: <bound method> = bound_method %N.loc4_6.1, constants.%Core.IntLiteral.as.Copy.impl.Op [symbolic = %Core.IntLiteral.as.Copy.impl.Op.bound (constants.%Core.IntLiteral.as.Copy.impl.Op.bound.555)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%n.param: @F.%Int.loc4_42.1 (%Int)) -> out %return.param: Core.IntLiteral {
+// CHECK:STDOUT:   fn(%n.param: @F.%Int.loc4_49.1 (%Int)) -> out %return.param: Core.IntLiteral {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %N.ref.loc5: Core.IntLiteral = name_ref N, %N.loc4_6.2 [symbolic = %N.loc4_6.1 (constants.%N)]
 // CHECK:STDOUT:     %impl.elem0: %.5e6 = impl_witness_access constants.%Copy.impl_witness.98e, element0 [concrete = constants.%Core.IntLiteral.as.Copy.impl.Op]
@@ -180,13 +180,13 @@ fn G(a: f64) -> Core.IntLiteral() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%N) {
 // CHECK:STDOUT:   %N.loc4_6.1 => constants.%N
-// CHECK:STDOUT:   %Int.loc4_42.1 => constants.%Int
+// CHECK:STDOUT:   %Int.loc4_49.1 => constants.%Int
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.764
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%int_64) {
 // CHECK:STDOUT:   %N.loc4_6.1 => constants.%int_64
-// CHECK:STDOUT:   %Int.loc4_42.1 => constants.%i64
+// CHECK:STDOUT:   %Int.loc4_49.1 => constants.%i64
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.95b
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
@@ -259,12 +259,12 @@ fn G(a: f64) -> Core.IntLiteral() {
 // CHECK:STDOUT:     %return.patt: %pattern_type.dc0 = return_slot_pattern [concrete]
 // CHECK:STDOUT:     %return.param_patt: %pattern_type.dc0 = out_param_pattern %return.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %Core.ref.loc4_50: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
-// CHECK:STDOUT:     %IntLiteral.ref.loc4_54: %IntLiteral.type = name_ref IntLiteral, imports.%Core.IntLiteral [concrete = constants.%IntLiteral]
-// CHECK:STDOUT:     %IntLiteral.call.loc4_66: init type = call %IntLiteral.ref.loc4_54() [concrete = Core.IntLiteral]
-// CHECK:STDOUT:     %.loc4_66.1: type = value_of_initializer %IntLiteral.call.loc4_66 [concrete = Core.IntLiteral]
-// CHECK:STDOUT:     %.loc4_66.2: type = converted %IntLiteral.call.loc4_66, %.loc4_66.1 [concrete = Core.IntLiteral]
-// CHECK:STDOUT:     %.loc4_66.3: Core.Form = init_form %.loc4_66.2, call_param1 [concrete = constants.%.7dc]
+// CHECK:STDOUT:     %Core.ref.loc4_57: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:     %IntLiteral.ref.loc4_61: %IntLiteral.type = name_ref IntLiteral, imports.%Core.IntLiteral [concrete = constants.%IntLiteral]
+// CHECK:STDOUT:     %IntLiteral.call.loc4_73: init type = call %IntLiteral.ref.loc4_61() [concrete = Core.IntLiteral]
+// CHECK:STDOUT:     %.loc4_73.1: type = value_of_initializer %IntLiteral.call.loc4_73 [concrete = Core.IntLiteral]
+// CHECK:STDOUT:     %.loc4_73.2: type = converted %IntLiteral.call.loc4_73, %.loc4_73.1 [concrete = Core.IntLiteral]
+// CHECK:STDOUT:     %.loc4_73.3: Core.Form = init_form %.loc4_73.2, call_param1 [concrete = constants.%.7dc]
 // CHECK:STDOUT:     %.loc4_26.1: type = splice_block %.loc4_26.3 [concrete = Core.IntLiteral] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %Core.ref.loc4_10: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
@@ -274,14 +274,14 @@ fn G(a: f64) -> Core.IntLiteral() {
 // CHECK:STDOUT:       %.loc4_26.3: type = converted %IntLiteral.call.loc4_26, %.loc4_26.2 [concrete = Core.IntLiteral]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %N.loc4_6.2: Core.IntLiteral = symbolic_binding N, 0 [symbolic = %N.loc4_6.1 (constants.%N)]
-// CHECK:STDOUT:     %n.param: @F.%Float.loc4_44.1 (%Float) = value_param call_param0
-// CHECK:STDOUT:     %.loc4_44: type = splice_block %Float.loc4_44.2 [symbolic = %Float.loc4_44.1 (constants.%Float)] {
-// CHECK:STDOUT:       %Core.ref.loc4_32: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:     %n.param: @F.%Float.loc4_51.1 (%Float) = value_param call_param0
+// CHECK:STDOUT:     %.loc4_51: type = splice_block %Float.loc4_51.2 [symbolic = %Float.loc4_51.1 (constants.%Float)] {
+// CHECK:STDOUT:       %Core.ref.loc4_39: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
 // CHECK:STDOUT:       %Float.ref: %Float.type = name_ref Float, imports.%Core.Float [concrete = constants.%Float.generic]
 // CHECK:STDOUT:       %N.ref.loc4: Core.IntLiteral = name_ref N, %N.loc4_6.2 [symbolic = %N.loc4_6.1 (constants.%N)]
-// CHECK:STDOUT:       %Float.loc4_44.2: type = class_type @Float, @Float(constants.%N) [symbolic = %Float.loc4_44.1 (constants.%Float)]
+// CHECK:STDOUT:       %Float.loc4_51.2: type = class_type @Float, @Float(constants.%N) [symbolic = %Float.loc4_51.1 (constants.%Float)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %n: @F.%Float.loc4_44.1 (%Float) = value_binding n, %n.param
+// CHECK:STDOUT:     %n: @F.%Float.loc4_51.1 (%Float) = value_binding n, %n.param
 // CHECK:STDOUT:     %return.param: ref Core.IntLiteral = out_param call_param1
 // CHECK:STDOUT:     %return: ref Core.IntLiteral = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -310,14 +310,14 @@ fn G(a: f64) -> Core.IntLiteral() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%N.loc4_6.2: Core.IntLiteral) {
 // CHECK:STDOUT:   %N.loc4_6.1: Core.IntLiteral = symbolic_binding N, 0 [symbolic = %N.loc4_6.1 (constants.%N)]
-// CHECK:STDOUT:   %Float.loc4_44.1: type = class_type @Float, @Float(%N.loc4_6.1) [symbolic = %Float.loc4_44.1 (constants.%Float)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %Float.loc4_44.1 [symbolic = %pattern_type (constants.%pattern_type.7d0)]
+// CHECK:STDOUT:   %Float.loc4_51.1: type = class_type @Float, @Float(%N.loc4_6.1) [symbolic = %Float.loc4_51.1 (constants.%Float)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %Float.loc4_51.1 [symbolic = %pattern_type (constants.%pattern_type.7d0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %Float.loc4_44.1 [symbolic = %require_complete (constants.%require_complete.dc0)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %Float.loc4_51.1 [symbolic = %require_complete (constants.%require_complete.dc0)]
 // CHECK:STDOUT:   %Core.IntLiteral.as.Copy.impl.Op.bound: <bound method> = bound_method %N.loc4_6.1, constants.%Core.IntLiteral.as.Copy.impl.Op [symbolic = %Core.IntLiteral.as.Copy.impl.Op.bound (constants.%Core.IntLiteral.as.Copy.impl.Op.bound.555)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%n.param: @F.%Float.loc4_44.1 (%Float)) -> out %return.param: Core.IntLiteral {
+// CHECK:STDOUT:   fn(%n.param: @F.%Float.loc4_51.1 (%Float)) -> out %return.param: Core.IntLiteral {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %N.ref.loc5: Core.IntLiteral = name_ref N, %N.loc4_6.2 [symbolic = %N.loc4_6.1 (constants.%N)]
 // CHECK:STDOUT:     %impl.elem0: %.5e6 = impl_witness_access constants.%Copy.impl_witness.98e, element0 [concrete = constants.%Core.IntLiteral.as.Copy.impl.Op]
@@ -338,13 +338,13 @@ fn G(a: f64) -> Core.IntLiteral() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%N) {
 // CHECK:STDOUT:   %N.loc4_6.1 => constants.%N
-// CHECK:STDOUT:   %Float.loc4_44.1 => constants.%Float
+// CHECK:STDOUT:   %Float.loc4_51.1 => constants.%Float
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.7d0
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%int_64) {
 // CHECK:STDOUT:   %N.loc4_6.1 => constants.%int_64
-// CHECK:STDOUT:   %Float.loc4_44.1 => constants.%f64.d77
+// CHECK:STDOUT:   %Float.loc4_51.1 => constants.%f64.d77
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.0ae
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:

+ 7 - 7
toolchain/check/testdata/deduce/symbolic_facets.carbon

@@ -20,7 +20,7 @@ library "[[@TEST_NAME]]";
 
 class C(CC:! type) {
   interface A {}
-  fn F(T:! A) {}
+  fn F(unused T:! A) {}
 }
 
 class D(DD:! type) {
@@ -33,8 +33,8 @@ class D(DD:! type) {
     // CHECK:STDERR:     C(()).F(T);
     // CHECK:STDERR:     ^~~~~~~~~~
     // CHECK:STDERR: fail_missing_interface.carbon:[[@LINE-12]]:3: note: while deducing parameters of generic declared here [DeductionGenericHere]
-    // CHECK:STDERR:   fn F(T:! A) {}
-    // CHECK:STDERR:   ^~~~~~~~~~~~~
+    // CHECK:STDERR:   fn F(unused T:! A) {}
+    // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~
     // CHECK:STDERR:
     C(()).F(T);
   }
@@ -45,7 +45,7 @@ library "[[@TEST_NAME]]";
 
 class C(CC:! type) {
   interface A {}
-  fn F(T:! A) {}
+  fn F(unused T:! A) {}
 }
 
 class D(DD:! type) {
@@ -58,8 +58,8 @@ class D(DD:! type) {
     // CHECK:STDERR:     C(()).F(T);
     // CHECK:STDERR:     ^~~~~~~~~~
     // CHECK:STDERR: fail_interface_wrong_generic_param.carbon:[[@LINE-12]]:3: note: while deducing parameters of generic declared here [DeductionGenericHere]
-    // CHECK:STDERR:   fn F(T:! A) {}
-    // CHECK:STDERR:   ^~~~~~~~~~~~~
+    // CHECK:STDERR:   fn F(unused T:! A) {}
+    // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~
     // CHECK:STDERR:
     C(()).F(T);
   }
@@ -70,7 +70,7 @@ library "[[@TEST_NAME]]";
 
 class C(CC:! type) {
   interface A {}
-  fn F(T:! A) {}
+  fn F(unused T:! A) {}
 }
 
 class D(DD:! type) {

+ 27 - 27
toolchain/check/testdata/deduce/tuple.carbon

@@ -31,7 +31,7 @@ library "[[@TEST_NAME]]";
 
 class HasPair(Pair:! (i32, i32)) {}
 
-fn F[A:! i32, B:! i32](h: HasPair((A, B))) -> i32 { return B; }
+fn F[A:! i32, B:! i32](unused h: HasPair((A, B))) -> i32 { return B; }
 
 fn G(h: HasPair((1, 2))) -> i32 {
   return F(h);
@@ -358,9 +358,9 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
 // CHECK:STDOUT:     %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %int_32.loc6_47: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc6_47: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
-// CHECK:STDOUT:     %.loc6_47: Core.Form = init_form %i32.loc6_47, call_param1 [concrete = constants.%.e54]
+// CHECK:STDOUT:     %int_32.loc6_54: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc6_54: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %.loc6_54: Core.Form = init_form %i32.loc6_54, call_param1 [concrete = constants.%.e54]
 // CHECK:STDOUT:     %.loc6_10: type = splice_block %i32.loc6_10 [concrete = constants.%i32] {
 // CHECK:STDOUT:       %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %int_32.loc6_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
@@ -373,17 +373,17 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:       %i32.loc6_19: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %B.loc6_15.2: %i32 = symbolic_binding B, 1 [symbolic = %B.loc6_15.1 (constants.%B)]
-// CHECK:STDOUT:     %h.param: @F.%HasPair.loc6_41.1 (%HasPair.2e7) = value_param call_param0
-// CHECK:STDOUT:     %.loc6_41.1: type = splice_block %HasPair.loc6_41.2 [symbolic = %HasPair.loc6_41.1 (constants.%HasPair.2e7)] {
+// CHECK:STDOUT:     %h.param: @F.%HasPair.loc6_48.1 (%HasPair.2e7) = value_param call_param0
+// CHECK:STDOUT:     %.loc6_48.1: type = splice_block %HasPair.loc6_48.2 [symbolic = %HasPair.loc6_48.1 (constants.%HasPair.2e7)] {
 // CHECK:STDOUT:       %HasPair.ref: %HasPair.type = name_ref HasPair, file.%HasPair.decl [concrete = constants.%HasPair.generic]
 // CHECK:STDOUT:       %A.ref: %i32 = name_ref A, %A.loc6_6.2 [symbolic = %A.loc6_6.1 (constants.%A)]
-// CHECK:STDOUT:       %B.ref.loc6_39: %i32 = name_ref B, %B.loc6_15.2 [symbolic = %B.loc6_15.1 (constants.%B)]
-// CHECK:STDOUT:       %.loc6_40: %tuple.type.d07 = tuple_literal (%A.ref, %B.ref.loc6_39) [symbolic = %tuple.loc6_40.1 (constants.%tuple.9c9)]
-// CHECK:STDOUT:       %tuple.loc6_40.2: %tuple.type.d07 = tuple_value (%A.ref, %B.ref.loc6_39) [symbolic = %tuple.loc6_40.1 (constants.%tuple.9c9)]
-// CHECK:STDOUT:       %.loc6_41.2: %tuple.type.d07 = converted %.loc6_40, %tuple.loc6_40.2 [symbolic = %tuple.loc6_40.1 (constants.%tuple.9c9)]
-// CHECK:STDOUT:       %HasPair.loc6_41.2: type = class_type @HasPair, @HasPair(constants.%tuple.9c9) [symbolic = %HasPair.loc6_41.1 (constants.%HasPair.2e7)]
+// CHECK:STDOUT:       %B.ref.loc6_46: %i32 = name_ref B, %B.loc6_15.2 [symbolic = %B.loc6_15.1 (constants.%B)]
+// CHECK:STDOUT:       %.loc6_47: %tuple.type.d07 = tuple_literal (%A.ref, %B.ref.loc6_46) [symbolic = %tuple.loc6_47.1 (constants.%tuple.9c9)]
+// CHECK:STDOUT:       %tuple.loc6_47.2: %tuple.type.d07 = tuple_value (%A.ref, %B.ref.loc6_46) [symbolic = %tuple.loc6_47.1 (constants.%tuple.9c9)]
+// CHECK:STDOUT:       %.loc6_48.2: %tuple.type.d07 = converted %.loc6_47, %tuple.loc6_47.2 [symbolic = %tuple.loc6_47.1 (constants.%tuple.9c9)]
+// CHECK:STDOUT:       %HasPair.loc6_48.2: type = class_type @HasPair, @HasPair(constants.%tuple.9c9) [symbolic = %HasPair.loc6_48.1 (constants.%HasPair.2e7)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %h: @F.%HasPair.loc6_41.1 (%HasPair.2e7) = value_binding h, %h.param
+// CHECK:STDOUT:     %h: @F.%HasPair.loc6_48.1 (%HasPair.2e7) = value_binding h, %h.param
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param call_param1
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -443,23 +443,23 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT: generic fn @F(%A.loc6_6.2: %i32, %B.loc6_15.2: %i32) {
 // CHECK:STDOUT:   %A.loc6_6.1: %i32 = symbolic_binding A, 0 [symbolic = %A.loc6_6.1 (constants.%A)]
 // CHECK:STDOUT:   %B.loc6_15.1: %i32 = symbolic_binding B, 1 [symbolic = %B.loc6_15.1 (constants.%B)]
-// CHECK:STDOUT:   %tuple.loc6_40.1: %tuple.type.d07 = tuple_value (%A.loc6_6.1, %B.loc6_15.1) [symbolic = %tuple.loc6_40.1 (constants.%tuple.9c9)]
-// CHECK:STDOUT:   %HasPair.loc6_41.1: type = class_type @HasPair, @HasPair(%tuple.loc6_40.1) [symbolic = %HasPair.loc6_41.1 (constants.%HasPair.2e7)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %HasPair.loc6_41.1 [symbolic = %pattern_type (constants.%pattern_type.dc2)]
+// CHECK:STDOUT:   %tuple.loc6_47.1: %tuple.type.d07 = tuple_value (%A.loc6_6.1, %B.loc6_15.1) [symbolic = %tuple.loc6_47.1 (constants.%tuple.9c9)]
+// CHECK:STDOUT:   %HasPair.loc6_48.1: type = class_type @HasPair, @HasPair(%tuple.loc6_47.1) [symbolic = %HasPair.loc6_48.1 (constants.%HasPair.2e7)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %HasPair.loc6_48.1 [symbolic = %pattern_type (constants.%pattern_type.dc2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %HasPair.loc6_41.1 [symbolic = %require_complete (constants.%require_complete.76f)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %HasPair.loc6_48.1 [symbolic = %require_complete (constants.%require_complete.76f)]
 // CHECK:STDOUT:   %Int.as.Copy.impl.Op.bound: <bound method> = bound_method %B.loc6_15.1, constants.%Int.as.Copy.impl.Op.664 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound.5f8)]
-// CHECK:STDOUT:   %bound_method.loc6_60.3: <bound method> = bound_method %B.loc6_15.1, constants.%Int.as.Copy.impl.Op.specific_fn [symbolic = %bound_method.loc6_60.3 (constants.%bound_method.dfb)]
+// CHECK:STDOUT:   %bound_method.loc6_67.3: <bound method> = bound_method %B.loc6_15.1, constants.%Int.as.Copy.impl.Op.specific_fn [symbolic = %bound_method.loc6_67.3 (constants.%bound_method.dfb)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%h.param: @F.%HasPair.loc6_41.1 (%HasPair.2e7)) -> out %return.param: %i32 {
+// CHECK:STDOUT:   fn(%h.param: @F.%HasPair.loc6_48.1 (%HasPair.2e7)) -> out %return.param: %i32 {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %B.ref.loc6_60: %i32 = name_ref B, %B.loc6_15.2 [symbolic = %B.loc6_15.1 (constants.%B)]
+// CHECK:STDOUT:     %B.ref.loc6_67: %i32 = name_ref B, %B.loc6_15.2 [symbolic = %B.loc6_15.1 (constants.%B)]
 // CHECK:STDOUT:     %impl.elem0: %.8e2 = impl_witness_access constants.%Copy.impl_witness.f17, element0 [concrete = constants.%Int.as.Copy.impl.Op.664]
-// CHECK:STDOUT:     %bound_method.loc6_60.1: <bound method> = bound_method %B.ref.loc6_60, %impl.elem0 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound.5f8)]
+// CHECK:STDOUT:     %bound_method.loc6_67.1: <bound method> = bound_method %B.ref.loc6_67, %impl.elem0 [symbolic = %Int.as.Copy.impl.Op.bound (constants.%Int.as.Copy.impl.Op.bound.5f8)]
 // CHECK:STDOUT:     %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
-// CHECK:STDOUT:     %bound_method.loc6_60.2: <bound method> = bound_method %B.ref.loc6_60, %specific_fn [symbolic = %bound_method.loc6_60.3 (constants.%bound_method.dfb)]
-// CHECK:STDOUT:     %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_60.2(%B.ref.loc6_60) [symbolic = %B.loc6_15.1 (constants.%B)]
+// CHECK:STDOUT:     %bound_method.loc6_67.2: <bound method> = bound_method %B.ref.loc6_67, %specific_fn [symbolic = %bound_method.loc6_67.3 (constants.%bound_method.dfb)]
+// CHECK:STDOUT:     %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_67.2(%B.ref.loc6_67) [symbolic = %B.loc6_15.1 (constants.%B)]
 // CHECK:STDOUT:     return %Int.as.Copy.impl.Op.call
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -486,8 +486,8 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT: specific @F(constants.%A, constants.%B) {
 // CHECK:STDOUT:   %A.loc6_6.1 => constants.%A
 // CHECK:STDOUT:   %B.loc6_15.1 => constants.%B
-// CHECK:STDOUT:   %tuple.loc6_40.1 => constants.%tuple.9c9
-// CHECK:STDOUT:   %HasPair.loc6_41.1 => constants.%HasPair.2e7
+// CHECK:STDOUT:   %tuple.loc6_47.1 => constants.%tuple.9c9
+// CHECK:STDOUT:   %HasPair.loc6_48.1 => constants.%HasPair.2e7
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.dc2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -500,14 +500,14 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT: specific @F(constants.%int_1.5d2, constants.%int_2.ef8) {
 // CHECK:STDOUT:   %A.loc6_6.1 => constants.%int_1.5d2
 // CHECK:STDOUT:   %B.loc6_15.1 => constants.%int_2.ef8
-// CHECK:STDOUT:   %tuple.loc6_40.1 => constants.%tuple.21c
-// CHECK:STDOUT:   %HasPair.loc6_41.1 => constants.%HasPair.867
+// CHECK:STDOUT:   %tuple.loc6_47.1 => constants.%tuple.21c
+// CHECK:STDOUT:   %HasPair.loc6_48.1 => constants.%HasPair.867
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.530
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete => constants.%complete_type.357
 // CHECK:STDOUT:   %Int.as.Copy.impl.Op.bound => constants.%Int.as.Copy.impl.Op.bound.5e8
-// CHECK:STDOUT:   %bound_method.loc6_60.3 => constants.%bound_method.f15
+// CHECK:STDOUT:   %bound_method.loc6_67.3 => constants.%bound_method.f15
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_inconsistent.carbon

+ 106 - 106
toolchain/check/testdata/deduce/value_with_type_through_access.carbon

@@ -20,7 +20,7 @@ class HoldsType(T:! (type, )) {}
 
 // `a` is received as a value, and has a type that requires going through
 // TupleAccess. Building the value representation must handle this indirection.
-fn F[T:! (type, )](x: HoldsType(T), a: T.0) {}
+fn F[T:! (type, )](unused x: HoldsType(T), unused a: T.0) {}
 
 class C {}
 
@@ -36,7 +36,7 @@ class HoldsType(T:! {.t: type}) {}
 
 // `a` is received as a value, and has a type that requires going through
 // StructAccess. Building the value representation must handle this indirection.
-fn F[T:! {.t: type}](x: HoldsType(T), a: T.t) {}
+fn F[T:! {.t: type}](unused x: HoldsType(T), unused a: T.t) {}
 
 class C {}
 
@@ -61,11 +61,11 @@ class HoldsType(T:! Class) {}
 // should be able to eval to a type. We would expect the `.` in `T.t` to be a
 // ClassElementAccess but it is an AcquireValue, which has a runtime value.
 //
-// CHECK:STDERR: fail_todo_class_access.carbon:[[@LINE+4]]:37: error: cannot evaluate type expression [TypeExprEvaluationFailure]
-// CHECK:STDERR: fn F[T:! Class](x: HoldsType(T), a: T.t) {}
-// CHECK:STDERR:                                     ^~~
+// CHECK:STDERR: fail_todo_class_access.carbon:[[@LINE+4]]:51: error: cannot evaluate type expression [TypeExprEvaluationFailure]
+// CHECK:STDERR: fn F[T:! Class](unused x: HoldsType(T), unused a: T.t) {}
+// CHECK:STDERR:                                                   ^~~
 // CHECK:STDERR:
-fn F[T:! Class](x: HoldsType(T), a: T.t) {}
+fn F[T:! Class](unused x: HoldsType(T), unused a: T.t) {}
 
 class C {}
 
@@ -92,11 +92,11 @@ class HoldsType(T:! array(type, 1)) {}
 
 // `a` is received as a value, and has a type that requires going through
 // ArrayIndex. Building the value representation must handle this indirection.
-// CHECK:STDERR: fail_todo_array_index.carbon:[[@LINE+4]]:46: error: cannot evaluate type expression [TypeExprEvaluationFailure]
-// CHECK:STDERR: fn F[T:! array(type, 1)](x: HoldsType(T), a: T[0]) {}
-// CHECK:STDERR:                                              ^~~~
+// CHECK:STDERR: fail_todo_array_index.carbon:[[@LINE+4]]:60: error: cannot evaluate type expression [TypeExprEvaluationFailure]
+// CHECK:STDERR: fn F[T:! array(type, 1)](unused x: HoldsType(T), unused a: T[0]) {}
+// CHECK:STDERR:                                                            ^~~~
 // CHECK:STDERR:
-fn F[T:! array(type, 1)](x: HoldsType(T), a: T[0]) {}
+fn F[T:! array(type, 1)](unused x: HoldsType(T), unused a: T[0]) {}
 
 class C {}
 
@@ -183,10 +183,10 @@ fn G() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
 // CHECK:STDOUT:     %T.patt: %pattern_type.f1e = symbolic_binding_pattern T, 0 [concrete]
-// CHECK:STDOUT:     %x.patt: @F.%pattern_type.loc8_20 (%pattern_type.17d) = value_binding_pattern x [concrete]
-// CHECK:STDOUT:     %x.param_patt: @F.%pattern_type.loc8_20 (%pattern_type.17d) = value_param_pattern %x.patt, call_param0 [concrete]
-// CHECK:STDOUT:     %a.patt: @F.%pattern_type.loc8_37 (%pattern_type.e66) = value_binding_pattern a [concrete]
-// CHECK:STDOUT:     %a.param_patt: @F.%pattern_type.loc8_37 (%pattern_type.e66) = value_param_pattern %a.patt, call_param1 [concrete]
+// CHECK:STDOUT:     %x.patt: @F.%pattern_type.loc8_27 (%pattern_type.17d) = value_binding_pattern x [concrete]
+// CHECK:STDOUT:     %x.param_patt: @F.%pattern_type.loc8_27 (%pattern_type.17d) = value_param_pattern %x.patt, call_param0 [concrete]
+// CHECK:STDOUT:     %a.patt: @F.%pattern_type.loc8_51 (%pattern_type.e66) = value_binding_pattern a [concrete]
+// CHECK:STDOUT:     %a.param_patt: @F.%pattern_type.loc8_51 (%pattern_type.e66) = value_param_pattern %a.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %.loc8_17.1: type = splice_block %.loc8_17.3 [concrete = constants.%tuple.type] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
@@ -194,20 +194,20 @@ fn G() {
 // CHECK:STDOUT:       %.loc8_17.3: type = converted %.loc8_17.2, constants.%tuple.type [concrete = constants.%tuple.type]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %T.loc8_6.2: %tuple.type = symbolic_binding T, 0 [symbolic = %T.loc8_6.1 (constants.%T)]
-// CHECK:STDOUT:     %x.param: @F.%HoldsType.loc8_34.1 (%HoldsType.f6a) = value_param call_param0
-// CHECK:STDOUT:     %.loc8_34: type = splice_block %HoldsType.loc8_34.2 [symbolic = %HoldsType.loc8_34.1 (constants.%HoldsType.f6a)] {
+// CHECK:STDOUT:     %x.param: @F.%HoldsType.loc8_41.1 (%HoldsType.f6a) = value_param call_param0
+// CHECK:STDOUT:     %.loc8_41: type = splice_block %HoldsType.loc8_41.2 [symbolic = %HoldsType.loc8_41.1 (constants.%HoldsType.f6a)] {
 // CHECK:STDOUT:       %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic]
-// CHECK:STDOUT:       %T.ref.loc8_33: %tuple.type = name_ref T, %T.loc8_6.2 [symbolic = %T.loc8_6.1 (constants.%T)]
-// CHECK:STDOUT:       %HoldsType.loc8_34.2: type = class_type @HoldsType, @HoldsType(constants.%T) [symbolic = %HoldsType.loc8_34.1 (constants.%HoldsType.f6a)]
-// CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: @F.%HoldsType.loc8_34.1 (%HoldsType.f6a) = value_binding x, %x.param
-// CHECK:STDOUT:     %a.param: @F.%tuple.elem0.loc8_41.1 (%tuple.elem0) = value_param call_param1
-// CHECK:STDOUT:     %.loc8_41: type = splice_block %tuple.elem0.loc8_41.2 [symbolic = %tuple.elem0.loc8_41.1 (constants.%tuple.elem0)] {
 // CHECK:STDOUT:       %T.ref.loc8_40: %tuple.type = name_ref T, %T.loc8_6.2 [symbolic = %T.loc8_6.1 (constants.%T)]
+// CHECK:STDOUT:       %HoldsType.loc8_41.2: type = class_type @HoldsType, @HoldsType(constants.%T) [symbolic = %HoldsType.loc8_41.1 (constants.%HoldsType.f6a)]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %x: @F.%HoldsType.loc8_41.1 (%HoldsType.f6a) = value_binding x, %x.param
+// CHECK:STDOUT:     %a.param: @F.%tuple.elem0.loc8_55.1 (%tuple.elem0) = value_param call_param1
+// CHECK:STDOUT:     %.loc8_55: type = splice_block %tuple.elem0.loc8_55.2 [symbolic = %tuple.elem0.loc8_55.1 (constants.%tuple.elem0)] {
+// CHECK:STDOUT:       %T.ref.loc8_54: %tuple.type = name_ref T, %T.loc8_6.2 [symbolic = %T.loc8_6.1 (constants.%T)]
 // CHECK:STDOUT:       %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0]
-// CHECK:STDOUT:       %tuple.elem0.loc8_41.2: type = tuple_access %T.ref.loc8_40, element0 [symbolic = %tuple.elem0.loc8_41.1 (constants.%tuple.elem0)]
+// CHECK:STDOUT:       %tuple.elem0.loc8_55.2: type = tuple_access %T.ref.loc8_54, element0 [symbolic = %tuple.elem0.loc8_55.1 (constants.%tuple.elem0)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: @F.%tuple.elem0.loc8_41.1 (%tuple.elem0) = value_binding a, %a.param
+// CHECK:STDOUT:     %a: @F.%tuple.elem0.loc8_55.1 (%tuple.elem0) = value_binding a, %a.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
@@ -237,16 +237,16 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%T.loc8_6.2: %tuple.type) {
 // CHECK:STDOUT:   %T.loc8_6.1: %tuple.type = symbolic_binding T, 0 [symbolic = %T.loc8_6.1 (constants.%T)]
-// CHECK:STDOUT:   %HoldsType.loc8_34.1: type = class_type @HoldsType, @HoldsType(%T.loc8_6.1) [symbolic = %HoldsType.loc8_34.1 (constants.%HoldsType.f6a)]
-// CHECK:STDOUT:   %pattern_type.loc8_20: type = pattern_type %HoldsType.loc8_34.1 [symbolic = %pattern_type.loc8_20 (constants.%pattern_type.17d)]
-// CHECK:STDOUT:   %tuple.elem0.loc8_41.1: type = tuple_access %T.loc8_6.1, element0 [symbolic = %tuple.elem0.loc8_41.1 (constants.%tuple.elem0)]
-// CHECK:STDOUT:   %pattern_type.loc8_37: type = pattern_type %tuple.elem0.loc8_41.1 [symbolic = %pattern_type.loc8_37 (constants.%pattern_type.e66)]
+// CHECK:STDOUT:   %HoldsType.loc8_41.1: type = class_type @HoldsType, @HoldsType(%T.loc8_6.1) [symbolic = %HoldsType.loc8_41.1 (constants.%HoldsType.f6a)]
+// CHECK:STDOUT:   %pattern_type.loc8_27: type = pattern_type %HoldsType.loc8_41.1 [symbolic = %pattern_type.loc8_27 (constants.%pattern_type.17d)]
+// CHECK:STDOUT:   %tuple.elem0.loc8_55.1: type = tuple_access %T.loc8_6.1, element0 [symbolic = %tuple.elem0.loc8_55.1 (constants.%tuple.elem0)]
+// CHECK:STDOUT:   %pattern_type.loc8_51: type = pattern_type %tuple.elem0.loc8_55.1 [symbolic = %pattern_type.loc8_51 (constants.%pattern_type.e66)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc8_21: <witness> = require_complete_type %HoldsType.loc8_34.1 [symbolic = %require_complete.loc8_21 (constants.%require_complete.7bf)]
-// CHECK:STDOUT:   %require_complete.loc8_38: <witness> = require_complete_type %tuple.elem0.loc8_41.1 [symbolic = %require_complete.loc8_38 (constants.%require_complete.e7a)]
+// CHECK:STDOUT:   %require_complete.loc8_28: <witness> = require_complete_type %HoldsType.loc8_41.1 [symbolic = %require_complete.loc8_28 (constants.%require_complete.7bf)]
+// CHECK:STDOUT:   %require_complete.loc8_52: <witness> = require_complete_type %tuple.elem0.loc8_55.1 [symbolic = %require_complete.loc8_52 (constants.%require_complete.e7a)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%x.param: @F.%HoldsType.loc8_34.1 (%HoldsType.f6a), %a.param: @F.%tuple.elem0.loc8_41.1 (%tuple.elem0)) {
+// CHECK:STDOUT:   fn(%x.param: @F.%HoldsType.loc8_41.1 (%HoldsType.f6a), %a.param: @F.%tuple.elem0.loc8_55.1 (%tuple.elem0)) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -294,10 +294,10 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%T) {
 // CHECK:STDOUT:   %T.loc8_6.1 => constants.%T
-// CHECK:STDOUT:   %HoldsType.loc8_34.1 => constants.%HoldsType.f6a
-// CHECK:STDOUT:   %pattern_type.loc8_20 => constants.%pattern_type.17d
-// CHECK:STDOUT:   %tuple.elem0.loc8_41.1 => constants.%tuple.elem0
-// CHECK:STDOUT:   %pattern_type.loc8_37 => constants.%pattern_type.e66
+// CHECK:STDOUT:   %HoldsType.loc8_41.1 => constants.%HoldsType.f6a
+// CHECK:STDOUT:   %pattern_type.loc8_27 => constants.%pattern_type.17d
+// CHECK:STDOUT:   %tuple.elem0.loc8_55.1 => constants.%tuple.elem0
+// CHECK:STDOUT:   %pattern_type.loc8_51 => constants.%pattern_type.e66
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @HoldsType(constants.%tuple.1f1) {
@@ -308,14 +308,14 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%tuple.1f1) {
 // CHECK:STDOUT:   %T.loc8_6.1 => constants.%tuple.1f1
-// CHECK:STDOUT:   %HoldsType.loc8_34.1 => constants.%HoldsType.a31
-// CHECK:STDOUT:   %pattern_type.loc8_20 => constants.%pattern_type.a646
-// CHECK:STDOUT:   %tuple.elem0.loc8_41.1 => constants.%C
-// CHECK:STDOUT:   %pattern_type.loc8_37 => constants.%pattern_type.7c7
+// CHECK:STDOUT:   %HoldsType.loc8_41.1 => constants.%HoldsType.a31
+// CHECK:STDOUT:   %pattern_type.loc8_27 => constants.%pattern_type.a646
+// CHECK:STDOUT:   %tuple.elem0.loc8_55.1 => constants.%C
+// CHECK:STDOUT:   %pattern_type.loc8_51 => constants.%pattern_type.7c7
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc8_21 => constants.%complete_type
-// CHECK:STDOUT:   %require_complete.loc8_38 => constants.%complete_type
+// CHECK:STDOUT:   %require_complete.loc8_28 => constants.%complete_type
+// CHECK:STDOUT:   %require_complete.loc8_52 => constants.%complete_type
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- struct_access.carbon
@@ -386,29 +386,29 @@ fn G() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
 // CHECK:STDOUT:     %T.patt: %pattern_type.7f2 = symbolic_binding_pattern T, 0 [concrete]
-// CHECK:STDOUT:     %x.patt: @F.%pattern_type.loc8_22 (%pattern_type.2de) = value_binding_pattern x [concrete]
-// CHECK:STDOUT:     %x.param_patt: @F.%pattern_type.loc8_22 (%pattern_type.2de) = value_param_pattern %x.patt, call_param0 [concrete]
-// CHECK:STDOUT:     %a.patt: @F.%pattern_type.loc8_39 (%pattern_type.92c) = value_binding_pattern a [concrete]
-// CHECK:STDOUT:     %a.param_patt: @F.%pattern_type.loc8_39 (%pattern_type.92c) = value_param_pattern %a.patt, call_param1 [concrete]
+// CHECK:STDOUT:     %x.patt: @F.%pattern_type.loc8_29 (%pattern_type.2de) = value_binding_pattern x [concrete]
+// CHECK:STDOUT:     %x.param_patt: @F.%pattern_type.loc8_29 (%pattern_type.2de) = value_param_pattern %x.patt, call_param0 [concrete]
+// CHECK:STDOUT:     %a.patt: @F.%pattern_type.loc8_53 (%pattern_type.92c) = value_binding_pattern a [concrete]
+// CHECK:STDOUT:     %a.param_patt: @F.%pattern_type.loc8_53 (%pattern_type.92c) = value_param_pattern %a.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %.loc8_19: type = splice_block %struct_type.t [concrete = constants.%struct_type.t] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %struct_type.t: type = struct_type {.t: type} [concrete = constants.%struct_type.t]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %T.loc8_6.2: %struct_type.t = symbolic_binding T, 0 [symbolic = %T.loc8_6.1 (constants.%T)]
-// CHECK:STDOUT:     %x.param: @F.%HoldsType.loc8_36.1 (%HoldsType.cac) = value_param call_param0
-// CHECK:STDOUT:     %.loc8_36: type = splice_block %HoldsType.loc8_36.2 [symbolic = %HoldsType.loc8_36.1 (constants.%HoldsType.cac)] {
+// CHECK:STDOUT:     %x.param: @F.%HoldsType.loc8_43.1 (%HoldsType.cac) = value_param call_param0
+// CHECK:STDOUT:     %.loc8_43: type = splice_block %HoldsType.loc8_43.2 [symbolic = %HoldsType.loc8_43.1 (constants.%HoldsType.cac)] {
 // CHECK:STDOUT:       %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic]
-// CHECK:STDOUT:       %T.ref.loc8_35: %struct_type.t = name_ref T, %T.loc8_6.2 [symbolic = %T.loc8_6.1 (constants.%T)]
-// CHECK:STDOUT:       %HoldsType.loc8_36.2: type = class_type @HoldsType, @HoldsType(constants.%T) [symbolic = %HoldsType.loc8_36.1 (constants.%HoldsType.cac)]
-// CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: @F.%HoldsType.loc8_36.1 (%HoldsType.cac) = value_binding x, %x.param
-// CHECK:STDOUT:     %a.param: @F.%.loc8_43.1 (%.424) = value_param call_param1
-// CHECK:STDOUT:     %.loc8_43.2: type = splice_block %.loc8_43.3 [symbolic = %.loc8_43.1 (constants.%.424)] {
 // CHECK:STDOUT:       %T.ref.loc8_42: %struct_type.t = name_ref T, %T.loc8_6.2 [symbolic = %T.loc8_6.1 (constants.%T)]
-// CHECK:STDOUT:       %.loc8_43.3: type = struct_access %T.ref.loc8_42, element0 [symbolic = %.loc8_43.1 (constants.%.424)]
+// CHECK:STDOUT:       %HoldsType.loc8_43.2: type = class_type @HoldsType, @HoldsType(constants.%T) [symbolic = %HoldsType.loc8_43.1 (constants.%HoldsType.cac)]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %x: @F.%HoldsType.loc8_43.1 (%HoldsType.cac) = value_binding x, %x.param
+// CHECK:STDOUT:     %a.param: @F.%.loc8_57.1 (%.424) = value_param call_param1
+// CHECK:STDOUT:     %.loc8_57.2: type = splice_block %.loc8_57.3 [symbolic = %.loc8_57.1 (constants.%.424)] {
+// CHECK:STDOUT:       %T.ref.loc8_56: %struct_type.t = name_ref T, %T.loc8_6.2 [symbolic = %T.loc8_6.1 (constants.%T)]
+// CHECK:STDOUT:       %.loc8_57.3: type = struct_access %T.ref.loc8_56, element0 [symbolic = %.loc8_57.1 (constants.%.424)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: @F.%.loc8_43.1 (%.424) = value_binding a, %a.param
+// CHECK:STDOUT:     %a: @F.%.loc8_57.1 (%.424) = value_binding a, %a.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
@@ -438,16 +438,16 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%T.loc8_6.2: %struct_type.t) {
 // CHECK:STDOUT:   %T.loc8_6.1: %struct_type.t = symbolic_binding T, 0 [symbolic = %T.loc8_6.1 (constants.%T)]
-// CHECK:STDOUT:   %HoldsType.loc8_36.1: type = class_type @HoldsType, @HoldsType(%T.loc8_6.1) [symbolic = %HoldsType.loc8_36.1 (constants.%HoldsType.cac)]
-// CHECK:STDOUT:   %pattern_type.loc8_22: type = pattern_type %HoldsType.loc8_36.1 [symbolic = %pattern_type.loc8_22 (constants.%pattern_type.2de)]
-// CHECK:STDOUT:   %.loc8_43.1: type = struct_access %T.loc8_6.1, element0 [symbolic = %.loc8_43.1 (constants.%.424)]
-// CHECK:STDOUT:   %pattern_type.loc8_39: type = pattern_type %.loc8_43.1 [symbolic = %pattern_type.loc8_39 (constants.%pattern_type.92c)]
+// CHECK:STDOUT:   %HoldsType.loc8_43.1: type = class_type @HoldsType, @HoldsType(%T.loc8_6.1) [symbolic = %HoldsType.loc8_43.1 (constants.%HoldsType.cac)]
+// CHECK:STDOUT:   %pattern_type.loc8_29: type = pattern_type %HoldsType.loc8_43.1 [symbolic = %pattern_type.loc8_29 (constants.%pattern_type.2de)]
+// CHECK:STDOUT:   %.loc8_57.1: type = struct_access %T.loc8_6.1, element0 [symbolic = %.loc8_57.1 (constants.%.424)]
+// CHECK:STDOUT:   %pattern_type.loc8_53: type = pattern_type %.loc8_57.1 [symbolic = %pattern_type.loc8_53 (constants.%pattern_type.92c)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc8_23: <witness> = require_complete_type %HoldsType.loc8_36.1 [symbolic = %require_complete.loc8_23 (constants.%require_complete.276)]
-// CHECK:STDOUT:   %require_complete.loc8_40: <witness> = require_complete_type %.loc8_43.1 [symbolic = %require_complete.loc8_40 (constants.%require_complete.ba0)]
+// CHECK:STDOUT:   %require_complete.loc8_30: <witness> = require_complete_type %HoldsType.loc8_43.1 [symbolic = %require_complete.loc8_30 (constants.%require_complete.276)]
+// CHECK:STDOUT:   %require_complete.loc8_54: <witness> = require_complete_type %.loc8_57.1 [symbolic = %require_complete.loc8_54 (constants.%require_complete.ba0)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%x.param: @F.%HoldsType.loc8_36.1 (%HoldsType.cac), %a.param: @F.%.loc8_43.1 (%.424)) {
+// CHECK:STDOUT:   fn(%x.param: @F.%HoldsType.loc8_43.1 (%HoldsType.cac), %a.param: @F.%.loc8_57.1 (%.424)) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -495,10 +495,10 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%T) {
 // CHECK:STDOUT:   %T.loc8_6.1 => constants.%T
-// CHECK:STDOUT:   %HoldsType.loc8_36.1 => constants.%HoldsType.cac
-// CHECK:STDOUT:   %pattern_type.loc8_22 => constants.%pattern_type.2de
-// CHECK:STDOUT:   %.loc8_43.1 => constants.%.424
-// CHECK:STDOUT:   %pattern_type.loc8_39 => constants.%pattern_type.92c
+// CHECK:STDOUT:   %HoldsType.loc8_43.1 => constants.%HoldsType.cac
+// CHECK:STDOUT:   %pattern_type.loc8_29 => constants.%pattern_type.2de
+// CHECK:STDOUT:   %.loc8_57.1 => constants.%.424
+// CHECK:STDOUT:   %pattern_type.loc8_53 => constants.%pattern_type.92c
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @HoldsType(constants.%struct) {
@@ -509,14 +509,14 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%struct) {
 // CHECK:STDOUT:   %T.loc8_6.1 => constants.%struct
-// CHECK:STDOUT:   %HoldsType.loc8_36.1 => constants.%HoldsType.673
-// CHECK:STDOUT:   %pattern_type.loc8_22 => constants.%pattern_type.4e6
-// CHECK:STDOUT:   %.loc8_43.1 => constants.%C
-// CHECK:STDOUT:   %pattern_type.loc8_39 => constants.%pattern_type.7c7
+// CHECK:STDOUT:   %HoldsType.loc8_43.1 => constants.%HoldsType.673
+// CHECK:STDOUT:   %pattern_type.loc8_29 => constants.%pattern_type.4e6
+// CHECK:STDOUT:   %.loc8_57.1 => constants.%C
+// CHECK:STDOUT:   %pattern_type.loc8_53 => constants.%pattern_type.7c7
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc8_23 => constants.%complete_type
-// CHECK:STDOUT:   %require_complete.loc8_40 => constants.%complete_type
+// CHECK:STDOUT:   %require_complete.loc8_30 => constants.%complete_type
+// CHECK:STDOUT:   %require_complete.loc8_54 => constants.%complete_type
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_todo_class_access.carbon
@@ -618,19 +618,19 @@ fn G() {
 // CHECK:STDOUT:       %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %T.loc21_6.2: %Class = symbolic_binding T, 0 [symbolic = %T.loc21_6.1 (constants.%T.d7d)]
-// CHECK:STDOUT:     %x.param: @F.%HoldsType.loc21_31.1 (%HoldsType.47b504.1) = value_param call_param0
-// CHECK:STDOUT:     %.loc21_31: type = splice_block %HoldsType.loc21_31.2 [symbolic = %HoldsType.loc21_31.1 (constants.%HoldsType.47b504.1)] {
+// CHECK:STDOUT:     %x.param: @F.%HoldsType.loc21_38.1 (%HoldsType.47b504.1) = value_param call_param0
+// CHECK:STDOUT:     %.loc21_38: type = splice_block %HoldsType.loc21_38.2 [symbolic = %HoldsType.loc21_38.1 (constants.%HoldsType.47b504.1)] {
 // CHECK:STDOUT:       %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic]
-// CHECK:STDOUT:       %T.ref.loc21_30: %Class = name_ref T, %T.loc21_6.2 [symbolic = %T.loc21_6.1 (constants.%T.d7d)]
-// CHECK:STDOUT:       %HoldsType.loc21_31.2: type = class_type @HoldsType, @HoldsType(constants.%T.d7d) [symbolic = %HoldsType.loc21_31.1 (constants.%HoldsType.47b504.1)]
+// CHECK:STDOUT:       %T.ref.loc21_37: %Class = name_ref T, %T.loc21_6.2 [symbolic = %T.loc21_6.1 (constants.%T.d7d)]
+// CHECK:STDOUT:       %HoldsType.loc21_38.2: type = class_type @HoldsType, @HoldsType(constants.%T.d7d) [symbolic = %HoldsType.loc21_38.1 (constants.%HoldsType.47b504.1)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: @F.%HoldsType.loc21_31.1 (%HoldsType.47b504.1) = value_binding x, %x.param
+// CHECK:STDOUT:     %x: @F.%HoldsType.loc21_38.1 (%HoldsType.47b504.1) = value_binding x, %x.param
 // CHECK:STDOUT:     %a.param: <error> = value_param call_param1
 // CHECK:STDOUT:     %.1: <error> = splice_block <error> [concrete = <error>] {
-// CHECK:STDOUT:       %T.ref.loc21_37: %Class = name_ref T, %T.loc21_6.2 [symbolic = %T.loc21_6.1 (constants.%T.d7d)]
+// CHECK:STDOUT:       %T.ref.loc21_51: %Class = name_ref T, %T.loc21_6.2 [symbolic = %T.loc21_6.1 (constants.%T.d7d)]
 // CHECK:STDOUT:       %t.ref: %Class.elem = name_ref t, @Class.%.loc5 [concrete = @Class.%.loc5]
-// CHECK:STDOUT:       %.loc21_38.2: ref type = class_element_access %T.ref.loc21_37, element0 [symbolic = %.loc21_38.1 (constants.%.208)]
-// CHECK:STDOUT:       %.loc21_38.3: type = acquire_value %.loc21_38.2
+// CHECK:STDOUT:       %.loc21_52.2: ref type = class_element_access %T.ref.loc21_51, element0 [symbolic = %.loc21_52.1 (constants.%.208)]
+// CHECK:STDOUT:       %.loc21_52.3: type = acquire_value %.loc21_52.2
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %a: <error> = value_binding a, %a.param
 // CHECK:STDOUT:   }
@@ -681,14 +681,14 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%T.loc21_6.2: %Class) {
 // CHECK:STDOUT:   %T.loc21_6.1: %Class = symbolic_binding T, 0 [symbolic = %T.loc21_6.1 (constants.%T.d7d)]
-// CHECK:STDOUT:   %HoldsType.loc21_31.1: type = class_type @HoldsType, @HoldsType(%T.loc21_6.1) [symbolic = %HoldsType.loc21_31.1 (constants.%HoldsType.47b504.1)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %HoldsType.loc21_31.1 [symbolic = %pattern_type (constants.%pattern_type.3b8c03.1)]
-// CHECK:STDOUT:   %.loc21_38.1: ref type = class_element_access %T.loc21_6.1, element0 [symbolic = %.loc21_38.1 (constants.%.208)]
+// CHECK:STDOUT:   %HoldsType.loc21_38.1: type = class_type @HoldsType, @HoldsType(%T.loc21_6.1) [symbolic = %HoldsType.loc21_38.1 (constants.%HoldsType.47b504.1)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %HoldsType.loc21_38.1 [symbolic = %pattern_type (constants.%pattern_type.3b8c03.1)]
+// CHECK:STDOUT:   %.loc21_52.1: ref type = class_element_access %T.loc21_6.1, element0 [symbolic = %.loc21_52.1 (constants.%.208)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %HoldsType.loc21_31.1 [symbolic = %require_complete (constants.%require_complete.9b8c71.1)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %HoldsType.loc21_38.1 [symbolic = %require_complete (constants.%require_complete.9b8c71.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%x.param: @F.%HoldsType.loc21_31.1 (%HoldsType.47b504.1), %a.param: <error>) {
+// CHECK:STDOUT:   fn(%x.param: @F.%HoldsType.loc21_38.1 (%HoldsType.47b504.1), %a.param: <error>) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -759,9 +759,9 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%T.d7d) {
 // CHECK:STDOUT:   %T.loc21_6.1 => constants.%T.d7d
-// CHECK:STDOUT:   %HoldsType.loc21_31.1 => constants.%HoldsType.47b504.1
+// CHECK:STDOUT:   %HoldsType.loc21_38.1 => constants.%HoldsType.47b504.1
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.3b8c03.1
-// CHECK:STDOUT:   %.loc21_38.1 => constants.%.208
+// CHECK:STDOUT:   %.loc21_52.1 => constants.%.208
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @G(constants.%c) {
@@ -885,29 +885,29 @@ fn G() {
 // CHECK:STDOUT:       %array_type: type = array_type %int_1, type [concrete = constants.%array_type]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %T.loc12_6.2: %array_type = symbolic_binding T, 0 [symbolic = %T.loc12_6.1 (constants.%T.9b7)]
-// CHECK:STDOUT:     %x.param: @F.%HoldsType.loc12_40.1 (%HoldsType) = value_param call_param0
-// CHECK:STDOUT:     %.loc12_40: type = splice_block %HoldsType.loc12_40.2 [symbolic = %HoldsType.loc12_40.1 (constants.%HoldsType)] {
+// CHECK:STDOUT:     %x.param: @F.%HoldsType.loc12_47.1 (%HoldsType) = value_param call_param0
+// CHECK:STDOUT:     %.loc12_47: type = splice_block %HoldsType.loc12_47.2 [symbolic = %HoldsType.loc12_47.1 (constants.%HoldsType)] {
 // CHECK:STDOUT:       %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic]
-// CHECK:STDOUT:       %T.ref.loc12_39: %array_type = name_ref T, %T.loc12_6.2 [symbolic = %T.loc12_6.1 (constants.%T.9b7)]
-// CHECK:STDOUT:       %HoldsType.loc12_40.2: type = class_type @HoldsType, @HoldsType(constants.%T.9b7) [symbolic = %HoldsType.loc12_40.1 (constants.%HoldsType)]
+// CHECK:STDOUT:       %T.ref.loc12_46: %array_type = name_ref T, %T.loc12_6.2 [symbolic = %T.loc12_6.1 (constants.%T.9b7)]
+// CHECK:STDOUT:       %HoldsType.loc12_47.2: type = class_type @HoldsType, @HoldsType(constants.%T.9b7) [symbolic = %HoldsType.loc12_47.1 (constants.%HoldsType)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: @F.%HoldsType.loc12_40.1 (%HoldsType) = value_binding x, %x.param
+// CHECK:STDOUT:     %x: @F.%HoldsType.loc12_47.1 (%HoldsType) = value_binding x, %x.param
 // CHECK:STDOUT:     %a.param: <error> = value_param call_param1
 // CHECK:STDOUT:     %.1: <error> = splice_block <error> [concrete = <error>] {
-// CHECK:STDOUT:       %T.ref.loc12_46: %array_type = name_ref T, %T.loc12_6.2 [symbolic = %T.loc12_6.1 (constants.%T.9b7)]
+// CHECK:STDOUT:       %T.ref.loc12_60: %array_type = name_ref T, %T.loc12_6.2 [symbolic = %T.loc12_6.1 (constants.%T.9b7)]
 // CHECK:STDOUT:       %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
 // CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:       %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:       %impl.elem0: %.545 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5]
-// CHECK:STDOUT:       %bound_method.loc12_48.1: <bound method> = bound_method %int_0, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
+// CHECK:STDOUT:       %bound_method.loc12_62.1: <bound method> = bound_method %int_0, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
 // CHECK:STDOUT:       %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:       %bound_method.loc12_48.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
-// CHECK:STDOUT:       %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc12_48.2(%int_0) [concrete = constants.%int_0.6a9]
-// CHECK:STDOUT:       %.loc12_48.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.6a9]
-// CHECK:STDOUT:       %.loc12_48.2: %i32 = converted %int_0, %.loc12_48.1 [concrete = constants.%int_0.6a9]
-// CHECK:STDOUT:       %.loc12_49.1: ref %array_type = value_as_ref %T.ref.loc12_46
-// CHECK:STDOUT:       %.loc12_49.2: ref type = array_index %.loc12_49.1, %.loc12_48.2
-// CHECK:STDOUT:       %.loc12_49.3: type = acquire_value %.loc12_49.2
+// CHECK:STDOUT:       %bound_method.loc12_62.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
+// CHECK:STDOUT:       %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc12_62.2(%int_0) [concrete = constants.%int_0.6a9]
+// CHECK:STDOUT:       %.loc12_62.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.6a9]
+// CHECK:STDOUT:       %.loc12_62.2: %i32 = converted %int_0, %.loc12_62.1 [concrete = constants.%int_0.6a9]
+// CHECK:STDOUT:       %.loc12_63.1: ref %array_type = value_as_ref %T.ref.loc12_60
+// CHECK:STDOUT:       %.loc12_63.2: ref type = array_index %.loc12_63.1, %.loc12_62.2
+// CHECK:STDOUT:       %.loc12_63.3: type = acquire_value %.loc12_63.2
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %a: <error> = value_binding a, %a.param
 // CHECK:STDOUT:   }
@@ -939,13 +939,13 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%T.loc12_6.2: %array_type) {
 // CHECK:STDOUT:   %T.loc12_6.1: %array_type = symbolic_binding T, 0 [symbolic = %T.loc12_6.1 (constants.%T.9b7)]
-// CHECK:STDOUT:   %HoldsType.loc12_40.1: type = class_type @HoldsType, @HoldsType(%T.loc12_6.1) [symbolic = %HoldsType.loc12_40.1 (constants.%HoldsType)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %HoldsType.loc12_40.1 [symbolic = %pattern_type (constants.%pattern_type.342)]
+// CHECK:STDOUT:   %HoldsType.loc12_47.1: type = class_type @HoldsType, @HoldsType(%T.loc12_6.1) [symbolic = %HoldsType.loc12_47.1 (constants.%HoldsType)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %HoldsType.loc12_47.1 [symbolic = %pattern_type (constants.%pattern_type.342)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %HoldsType.loc12_40.1 [symbolic = %require_complete (constants.%require_complete.bd5)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %HoldsType.loc12_47.1 [symbolic = %require_complete (constants.%require_complete.bd5)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%x.param: @F.%HoldsType.loc12_40.1 (%HoldsType), %a.param: <error>) {
+// CHECK:STDOUT:   fn(%x.param: @F.%HoldsType.loc12_47.1 (%HoldsType), %a.param: <error>) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -987,7 +987,7 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%T.9b7) {
 // CHECK:STDOUT:   %T.loc12_6.1 => constants.%T.9b7
-// CHECK:STDOUT:   %HoldsType.loc12_40.1 => constants.%HoldsType
+// CHECK:STDOUT:   %HoldsType.loc12_47.1 => constants.%HoldsType
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.342
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/deduce/where.carbon

@@ -17,9 +17,9 @@ interface Z {
   let Z1:! type;
 }
 
-class C(T:! type) {}
+class C(unused T:! type) {}
 
-fn F[U:! type](T:! Z where .Z1 = C(U)) {}
+fn F[U:! type](unused T:! Z where .Z1 = C(U)) {}
 
 class D {}
 final impl () as Z where .Z1 = C(D) {}
@@ -32,8 +32,8 @@ fn G() {
   // CHECK:STDERR:   F(() as type);
   // CHECK:STDERR:   ^~~~~~~~~~~~~
   // CHECK:STDERR: fail_todo_where.carbon:[[@LINE-12]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn F[U:! type](T:! Z where .Z1 = C(U)) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn F[U:! type](unused T:! Z where .Z1 = C(U)) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   F(() as type);
 }

+ 51 - 51
toolchain/check/testdata/eval/aggregates.carbon

@@ -41,15 +41,15 @@ library "[[@TEST_NAME]]";
 // Check that we propagate the `symbolic` tag through evaluations.
 fn F(T:! type) {
   //@dump-sem-ir-begin
-  var u: (T*, const T);
-  var v: {.a: T};
-  var w: array(T, 5);
+  var unused u: (T*, const T);
+  var unused v: {.a: T};
+  var unused w: array(T, 5);
   //@dump-sem-ir-end
 }
 
 fn G(N:! i32) {
   //@dump-sem-ir-begin
-  var k: array(i32, N);
+  var unused k: array(i32, N);
   //@dump-sem-ir-end
 }
 
@@ -574,26 +574,26 @@ fn G(N:! i32) {
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %ptr.loc6_12.2: type = ptr_type %T.loc4_6.1 [symbolic = %ptr.loc6_12.2 (constants.%ptr.e8f)]
-// CHECK:STDOUT:   %const.loc6_15.2: type = const_type %T.loc4_6.1 [symbolic = %const.loc6_15.2 (constants.%const)]
-// CHECK:STDOUT:   %tuple: %tuple.type.24b = tuple_value (%ptr.loc6_12.2, %const.loc6_15.2) [symbolic = %tuple (constants.%tuple)]
-// CHECK:STDOUT:   %tuple.type: type = tuple_type (%ptr.loc6_12.2, %const.loc6_15.2) [symbolic = %tuple.type (constants.%tuple.type.3c8)]
+// CHECK:STDOUT:   %ptr.loc6_19.2: type = ptr_type %T.loc4_6.1 [symbolic = %ptr.loc6_19.2 (constants.%ptr.e8f)]
+// CHECK:STDOUT:   %const.loc6_22.2: type = const_type %T.loc4_6.1 [symbolic = %const.loc6_22.2 (constants.%const)]
+// CHECK:STDOUT:   %tuple: %tuple.type.24b = tuple_value (%ptr.loc6_19.2, %const.loc6_22.2) [symbolic = %tuple (constants.%tuple)]
+// CHECK:STDOUT:   %tuple.type: type = tuple_type (%ptr.loc6_19.2, %const.loc6_22.2) [symbolic = %tuple.type (constants.%tuple.type.3c8)]
 // CHECK:STDOUT:   %require_complete.loc6: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc6 (constants.%require_complete.666)]
 // CHECK:STDOUT:   %pattern_type.loc6: type = pattern_type %tuple.type [symbolic = %pattern_type.loc6 (constants.%pattern_type.4ac)]
-// CHECK:STDOUT:   %struct_type.a.loc7_16.2: type = struct_type {.a: @F.%T.loc4_6.1 (%T)} [symbolic = %struct_type.a.loc7_16.2 (constants.%struct_type.a)]
-// CHECK:STDOUT:   %require_complete.loc7: <witness> = require_complete_type %struct_type.a.loc7_16.2 [symbolic = %require_complete.loc7 (constants.%require_complete.5d6)]
-// CHECK:STDOUT:   %pattern_type.loc7: type = pattern_type %struct_type.a.loc7_16.2 [symbolic = %pattern_type.loc7 (constants.%pattern_type.7b9)]
-// CHECK:STDOUT:   %array_type.loc8_20.2: type = array_type constants.%int_5, %T.loc4_6.1 [symbolic = %array_type.loc8_20.2 (constants.%array_type.742)]
-// CHECK:STDOUT:   %require_complete.loc8: <witness> = require_complete_type %array_type.loc8_20.2 [symbolic = %require_complete.loc8 (constants.%require_complete.345)]
-// CHECK:STDOUT:   %pattern_type.loc8: type = pattern_type %array_type.loc8_20.2 [symbolic = %pattern_type.loc8 (constants.%pattern_type.d52)]
-// CHECK:STDOUT:   %Destroy.lookup_impl_witness.loc8: <witness> = lookup_impl_witness %array_type.loc8_20.2, @Destroy [symbolic = %Destroy.lookup_impl_witness.loc8 (constants.%Destroy.lookup_impl_witness.b29)]
-// CHECK:STDOUT:   %Destroy.facet.loc8: %Destroy.type = facet_value %array_type.loc8_20.2, (%Destroy.lookup_impl_witness.loc8) [symbolic = %Destroy.facet.loc8 (constants.%Destroy.facet.ddc)]
+// CHECK:STDOUT:   %struct_type.a.loc7_23.2: type = struct_type {.a: @F.%T.loc4_6.1 (%T)} [symbolic = %struct_type.a.loc7_23.2 (constants.%struct_type.a)]
+// CHECK:STDOUT:   %require_complete.loc7: <witness> = require_complete_type %struct_type.a.loc7_23.2 [symbolic = %require_complete.loc7 (constants.%require_complete.5d6)]
+// CHECK:STDOUT:   %pattern_type.loc7: type = pattern_type %struct_type.a.loc7_23.2 [symbolic = %pattern_type.loc7 (constants.%pattern_type.7b9)]
+// CHECK:STDOUT:   %array_type.loc8_27.2: type = array_type constants.%int_5, %T.loc4_6.1 [symbolic = %array_type.loc8_27.2 (constants.%array_type.742)]
+// CHECK:STDOUT:   %require_complete.loc8: <witness> = require_complete_type %array_type.loc8_27.2 [symbolic = %require_complete.loc8 (constants.%require_complete.345)]
+// CHECK:STDOUT:   %pattern_type.loc8: type = pattern_type %array_type.loc8_27.2 [symbolic = %pattern_type.loc8 (constants.%pattern_type.d52)]
+// CHECK:STDOUT:   %Destroy.lookup_impl_witness.loc8: <witness> = lookup_impl_witness %array_type.loc8_27.2, @Destroy [symbolic = %Destroy.lookup_impl_witness.loc8 (constants.%Destroy.lookup_impl_witness.b29)]
+// CHECK:STDOUT:   %Destroy.facet.loc8: %Destroy.type = facet_value %array_type.loc8_27.2, (%Destroy.lookup_impl_witness.loc8) [symbolic = %Destroy.facet.loc8 (constants.%Destroy.facet.ddc)]
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type.loc8: type = fn_type @Destroy.WithSelf.Op, @Destroy(%Destroy.facet.loc8) [symbolic = %Destroy.WithSelf.Op.type.loc8 (constants.%Destroy.WithSelf.Op.type.3c6)]
 // CHECK:STDOUT:   %.loc8_3: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.loc8, %Destroy.facet.loc8 [symbolic = %.loc8_3 (constants.%.950)]
 // CHECK:STDOUT:   %impl.elem0.loc8_3.2: @F.%.loc8_3 (%.950) = impl_witness_access %Destroy.lookup_impl_witness.loc8, element0 [symbolic = %impl.elem0.loc8_3.2 (constants.%impl.elem0.fa5)]
 // CHECK:STDOUT:   %specific_impl_fn.loc8_3.2: <specific function> = specific_impl_function %impl.elem0.loc8_3.2, @Destroy.WithSelf.Op(%Destroy.facet.loc8) [symbolic = %specific_impl_fn.loc8_3.2 (constants.%specific_impl_fn.ede)]
-// CHECK:STDOUT:   %Destroy.lookup_impl_witness.loc7: <witness> = lookup_impl_witness %struct_type.a.loc7_16.2, @Destroy [symbolic = %Destroy.lookup_impl_witness.loc7 (constants.%Destroy.lookup_impl_witness.bed)]
-// CHECK:STDOUT:   %Destroy.facet.loc7: %Destroy.type = facet_value %struct_type.a.loc7_16.2, (%Destroy.lookup_impl_witness.loc7) [symbolic = %Destroy.facet.loc7 (constants.%Destroy.facet.d21)]
+// CHECK:STDOUT:   %Destroy.lookup_impl_witness.loc7: <witness> = lookup_impl_witness %struct_type.a.loc7_23.2, @Destroy [symbolic = %Destroy.lookup_impl_witness.loc7 (constants.%Destroy.lookup_impl_witness.bed)]
+// CHECK:STDOUT:   %Destroy.facet.loc7: %Destroy.type = facet_value %struct_type.a.loc7_23.2, (%Destroy.lookup_impl_witness.loc7) [symbolic = %Destroy.facet.loc7 (constants.%Destroy.facet.d21)]
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type.loc7: type = fn_type @Destroy.WithSelf.Op, @Destroy(%Destroy.facet.loc7) [symbolic = %Destroy.WithSelf.Op.type.loc7 (constants.%Destroy.WithSelf.Op.type.873)]
 // CHECK:STDOUT:   %.loc7_3: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.loc7, %Destroy.facet.loc7 [symbolic = %.loc7_3 (constants.%.511)]
 // CHECK:STDOUT:   %impl.elem0.loc7_3.2: @F.%.loc7_3 (%.511) = impl_witness_access %Destroy.lookup_impl_witness.loc7, element0 [symbolic = %impl.elem0.loc7_3.2 (constants.%impl.elem0.12c)]
@@ -612,36 +612,36 @@ fn G(N:! i32) {
 // CHECK:STDOUT:       %u.var_patt: @F.%pattern_type.loc6 (%pattern_type.4ac) = var_pattern %u.patt [concrete]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %u.var: ref @F.%tuple.type (%tuple.type.3c8) = var %u.var_patt
-// CHECK:STDOUT:     %.loc6_22.1: type = splice_block %.loc6_22.3 [symbolic = %tuple.type (constants.%tuple.type.3c8)] {
-// CHECK:STDOUT:       %T.ref.loc6_11: type = name_ref T, %T.loc4_6.2 [symbolic = %T.loc4_6.1 (constants.%T)]
-// CHECK:STDOUT:       %ptr.loc6_12.1: type = ptr_type %T.ref.loc6_11 [symbolic = %ptr.loc6_12.2 (constants.%ptr.e8f)]
-// CHECK:STDOUT:       %T.ref.loc6_21: type = name_ref T, %T.loc4_6.2 [symbolic = %T.loc4_6.1 (constants.%T)]
-// CHECK:STDOUT:       %const.loc6_15.1: type = const_type %T.ref.loc6_21 [symbolic = %const.loc6_15.2 (constants.%const)]
-// CHECK:STDOUT:       %.loc6_22.2: %tuple.type.24b = tuple_literal (%ptr.loc6_12.1, %const.loc6_15.1) [symbolic = %tuple (constants.%tuple)]
-// CHECK:STDOUT:       %.loc6_22.3: type = converted %.loc6_22.2, constants.%tuple.type.3c8 [symbolic = %tuple.type (constants.%tuple.type.3c8)]
+// CHECK:STDOUT:     %.loc6_29.1: type = splice_block %.loc6_29.3 [symbolic = %tuple.type (constants.%tuple.type.3c8)] {
+// CHECK:STDOUT:       %T.ref.loc6_18: type = name_ref T, %T.loc4_6.2 [symbolic = %T.loc4_6.1 (constants.%T)]
+// CHECK:STDOUT:       %ptr.loc6_19.1: type = ptr_type %T.ref.loc6_18 [symbolic = %ptr.loc6_19.2 (constants.%ptr.e8f)]
+// CHECK:STDOUT:       %T.ref.loc6_28: type = name_ref T, %T.loc4_6.2 [symbolic = %T.loc4_6.1 (constants.%T)]
+// CHECK:STDOUT:       %const.loc6_22.1: type = const_type %T.ref.loc6_28 [symbolic = %const.loc6_22.2 (constants.%const)]
+// CHECK:STDOUT:       %.loc6_29.2: %tuple.type.24b = tuple_literal (%ptr.loc6_19.1, %const.loc6_22.1) [symbolic = %tuple (constants.%tuple)]
+// CHECK:STDOUT:       %.loc6_29.3: type = converted %.loc6_29.2, constants.%tuple.type.3c8 [symbolic = %tuple.type (constants.%tuple.type.3c8)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %u: ref @F.%tuple.type (%tuple.type.3c8) = ref_binding u, %u.var
 // CHECK:STDOUT:     name_binding_decl {
 // CHECK:STDOUT:       %v.patt: @F.%pattern_type.loc7 (%pattern_type.7b9) = ref_binding_pattern v [concrete]
 // CHECK:STDOUT:       %v.var_patt: @F.%pattern_type.loc7 (%pattern_type.7b9) = var_pattern %v.patt [concrete]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %v.var: ref @F.%struct_type.a.loc7_16.2 (%struct_type.a) = var %v.var_patt
-// CHECK:STDOUT:     %.loc7_16: type = splice_block %struct_type.a.loc7_16.1 [symbolic = %struct_type.a.loc7_16.2 (constants.%struct_type.a)] {
+// CHECK:STDOUT:     %v.var: ref @F.%struct_type.a.loc7_23.2 (%struct_type.a) = var %v.var_patt
+// CHECK:STDOUT:     %.loc7_23: type = splice_block %struct_type.a.loc7_23.1 [symbolic = %struct_type.a.loc7_23.2 (constants.%struct_type.a)] {
 // CHECK:STDOUT:       %T.ref.loc7: type = name_ref T, %T.loc4_6.2 [symbolic = %T.loc4_6.1 (constants.%T)]
-// CHECK:STDOUT:       %struct_type.a.loc7_16.1: type = struct_type {.a: @F.%T.loc4_6.1 (%T)} [symbolic = %struct_type.a.loc7_16.2 (constants.%struct_type.a)]
+// CHECK:STDOUT:       %struct_type.a.loc7_23.1: type = struct_type {.a: @F.%T.loc4_6.1 (%T)} [symbolic = %struct_type.a.loc7_23.2 (constants.%struct_type.a)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %v: ref @F.%struct_type.a.loc7_16.2 (%struct_type.a) = ref_binding v, %v.var
+// CHECK:STDOUT:     %v: ref @F.%struct_type.a.loc7_23.2 (%struct_type.a) = ref_binding v, %v.var
 // CHECK:STDOUT:     name_binding_decl {
 // CHECK:STDOUT:       %w.patt: @F.%pattern_type.loc8 (%pattern_type.d52) = ref_binding_pattern w [concrete]
 // CHECK:STDOUT:       %w.var_patt: @F.%pattern_type.loc8 (%pattern_type.d52) = var_pattern %w.patt [concrete]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %w.var: ref @F.%array_type.loc8_20.2 (%array_type.742) = var %w.var_patt
-// CHECK:STDOUT:     %.loc8_20: type = splice_block %array_type.loc8_20.1 [symbolic = %array_type.loc8_20.2 (constants.%array_type.742)] {
+// CHECK:STDOUT:     %w.var: ref @F.%array_type.loc8_27.2 (%array_type.742) = var %w.var_patt
+// CHECK:STDOUT:     %.loc8_27: type = splice_block %array_type.loc8_27.1 [symbolic = %array_type.loc8_27.2 (constants.%array_type.742)] {
 // CHECK:STDOUT:       %T.ref.loc8: type = name_ref T, %T.loc4_6.2 [symbolic = %T.loc4_6.1 (constants.%T)]
 // CHECK:STDOUT:       %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5]
-// CHECK:STDOUT:       %array_type.loc8_20.1: type = array_type %int_5, %T.ref.loc8 [symbolic = %array_type.loc8_20.2 (constants.%array_type.742)]
+// CHECK:STDOUT:       %array_type.loc8_27.1: type = array_type %int_5, %T.ref.loc8 [symbolic = %array_type.loc8_27.2 (constants.%array_type.742)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %w: ref @F.%array_type.loc8_20.2 (%array_type.742) = ref_binding w, %w.var
+// CHECK:STDOUT:     %w: ref @F.%array_type.loc8_27.2 (%array_type.742) = ref_binding w, %w.var
 // CHECK:STDOUT:     %impl.elem0.loc8_3.1: @F.%.loc8_3 (%.950) = impl_witness_access constants.%Destroy.lookup_impl_witness.b29, element0 [symbolic = %impl.elem0.loc8_3.2 (constants.%impl.elem0.fa5)]
 // CHECK:STDOUT:     %bound_method.loc8_3.1: <bound method> = bound_method %w.var, %impl.elem0.loc8_3.1
 // CHECK:STDOUT:     %specific_impl_fn.loc8_3.1: <specific function> = specific_impl_function %impl.elem0.loc8_3.1, @Destroy.WithSelf.Op(constants.%Destroy.facet.ddc) [symbolic = %specific_impl_fn.loc8_3.2 (constants.%specific_impl_fn.ede)]
@@ -666,13 +666,13 @@ fn G(N:! i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %N.loc12_6.1, constants.%Int.as.ImplicitAs.impl.Convert.dd4 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
-// CHECK:STDOUT:   %bound_method.loc14_21.3: <bound method> = bound_method %N.loc12_6.1, constants.%Int.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc14_21.3 (constants.%bound_method)]
-// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc14_21.2: init Core.IntLiteral = call %bound_method.loc14_21.3(%N.loc12_6.1) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc14_21.2 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:   %array_type.loc14_22.2: type = array_type %Int.as.ImplicitAs.impl.Convert.call.loc14_21.2, constants.%i32 [symbolic = %array_type.loc14_22.2 (constants.%array_type.2ec)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc14_22.2 [symbolic = %require_complete (constants.%require_complete.5d1)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc14_22.2 [symbolic = %pattern_type (constants.%pattern_type.99c)]
-// CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.loc14_22.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness.f5c)]
-// CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %array_type.loc14_22.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.d1e)]
+// CHECK:STDOUT:   %bound_method.loc14_28.3: <bound method> = bound_method %N.loc12_6.1, constants.%Int.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc14_28.3 (constants.%bound_method)]
+// CHECK:STDOUT:   %Int.as.ImplicitAs.impl.Convert.call.loc14_28.2: init Core.IntLiteral = call %bound_method.loc14_28.3(%N.loc12_6.1) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc14_28.2 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:   %array_type.loc14_29.2: type = array_type %Int.as.ImplicitAs.impl.Convert.call.loc14_28.2, constants.%i32 [symbolic = %array_type.loc14_29.2 (constants.%array_type.2ec)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc14_29.2 [symbolic = %require_complete (constants.%require_complete.5d1)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %array_type.loc14_29.2 [symbolic = %pattern_type (constants.%pattern_type.99c)]
+// CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.loc14_29.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness.f5c)]
+// CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %array_type.loc14_29.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.d1e)]
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type: type = fn_type @Destroy.WithSelf.Op, @Destroy(%Destroy.facet) [symbolic = %Destroy.WithSelf.Op.type (constants.%Destroy.WithSelf.Op.type.ff9)]
 // CHECK:STDOUT:   %.loc14_3: type = fn_type_with_self_type %Destroy.WithSelf.Op.type, %Destroy.facet [symbolic = %.loc14_3 (constants.%.63e)]
 // CHECK:STDOUT:   %impl.elem0.loc14_3.2: @G.%.loc14_3 (%.63e) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_3.2 (constants.%impl.elem0.2bf)]
@@ -684,21 +684,21 @@ fn G(N:! i32) {
 // CHECK:STDOUT:       %k.patt: @G.%pattern_type (%pattern_type.99c) = ref_binding_pattern k [concrete]
 // CHECK:STDOUT:       %k.var_patt: @G.%pattern_type (%pattern_type.99c) = var_pattern %k.patt [concrete]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %k.var: ref @G.%array_type.loc14_22.2 (%array_type.2ec) = var %k.var_patt
-// CHECK:STDOUT:     %.loc14_22: type = splice_block %array_type.loc14_22.1 [symbolic = %array_type.loc14_22.2 (constants.%array_type.2ec)] {
+// CHECK:STDOUT:     %k.var: ref @G.%array_type.loc14_29.2 (%array_type.2ec) = var %k.var_patt
+// CHECK:STDOUT:     %.loc14_29: type = splice_block %array_type.loc14_29.1 [symbolic = %array_type.loc14_29.2 (constants.%array_type.2ec)] {
 // CHECK:STDOUT:       %int_32.loc14: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
 // CHECK:STDOUT:       %i32.loc14: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:       %N.ref: %i32 = name_ref N, %N.loc12_6.2 [symbolic = %N.loc12_6.1 (constants.%N.5de)]
-// CHECK:STDOUT:       %impl.elem0.loc14_21: %.0a7 = impl_witness_access constants.%ImplicitAs.impl_witness.640, element0 [concrete = constants.%Int.as.ImplicitAs.impl.Convert.dd4]
-// CHECK:STDOUT:       %bound_method.loc14_21.1: <bound method> = bound_method %N.ref, %impl.elem0.loc14_21 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
-// CHECK:STDOUT:       %specific_fn: <specific function> = specific_function %impl.elem0.loc14_21, @Int.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Int.as.ImplicitAs.impl.Convert.specific_fn]
-// CHECK:STDOUT:       %bound_method.loc14_21.2: <bound method> = bound_method %N.ref, %specific_fn [symbolic = %bound_method.loc14_21.3 (constants.%bound_method)]
-// CHECK:STDOUT:       %Int.as.ImplicitAs.impl.Convert.call.loc14_21.1: init Core.IntLiteral = call %bound_method.loc14_21.2(%N.ref) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc14_21.2 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %.loc14_21.1: Core.IntLiteral = value_of_initializer %Int.as.ImplicitAs.impl.Convert.call.loc14_21.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc14_21.2 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %.loc14_21.2: Core.IntLiteral = converted %N.ref, %.loc14_21.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc14_21.2 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
-// CHECK:STDOUT:       %array_type.loc14_22.1: type = array_type %.loc14_21.2, %i32.loc14 [symbolic = %array_type.loc14_22.2 (constants.%array_type.2ec)]
+// CHECK:STDOUT:       %impl.elem0.loc14_28: %.0a7 = impl_witness_access constants.%ImplicitAs.impl_witness.640, element0 [concrete = constants.%Int.as.ImplicitAs.impl.Convert.dd4]
+// CHECK:STDOUT:       %bound_method.loc14_28.1: <bound method> = bound_method %N.ref, %impl.elem0.loc14_28 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)]
+// CHECK:STDOUT:       %specific_fn: <specific function> = specific_function %impl.elem0.loc14_28, @Int.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Int.as.ImplicitAs.impl.Convert.specific_fn]
+// CHECK:STDOUT:       %bound_method.loc14_28.2: <bound method> = bound_method %N.ref, %specific_fn [symbolic = %bound_method.loc14_28.3 (constants.%bound_method)]
+// CHECK:STDOUT:       %Int.as.ImplicitAs.impl.Convert.call.loc14_28.1: init Core.IntLiteral = call %bound_method.loc14_28.2(%N.ref) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc14_28.2 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %.loc14_28.1: Core.IntLiteral = value_of_initializer %Int.as.ImplicitAs.impl.Convert.call.loc14_28.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc14_28.2 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %.loc14_28.2: Core.IntLiteral = converted %N.ref, %.loc14_28.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc14_28.2 (constants.%Int.as.ImplicitAs.impl.Convert.call)]
+// CHECK:STDOUT:       %array_type.loc14_29.1: type = array_type %.loc14_28.2, %i32.loc14 [symbolic = %array_type.loc14_29.2 (constants.%array_type.2ec)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %k: ref @G.%array_type.loc14_22.2 (%array_type.2ec) = ref_binding k, %k.var
+// CHECK:STDOUT:     %k: ref @G.%array_type.loc14_29.2 (%array_type.2ec) = ref_binding k, %k.var
 // CHECK:STDOUT:     %impl.elem0.loc14_3.1: @G.%.loc14_3 (%.63e) = impl_witness_access constants.%Destroy.lookup_impl_witness.f5c, element0 [symbolic = %impl.elem0.loc14_3.2 (constants.%impl.elem0.2bf)]
 // CHECK:STDOUT:     %bound_method.loc14_3.1: <bound method> = bound_method %k.var, %impl.elem0.loc14_3.1
 // CHECK:STDOUT:     %specific_impl_fn.loc14_3.1: <specific function> = specific_impl_function %impl.elem0.loc14_3.1, @Destroy.WithSelf.Op(constants.%Destroy.facet.d1e) [symbolic = %specific_impl_fn.loc14_3.2 (constants.%specific_impl_fn.0a5)]

+ 11 - 11
toolchain/check/testdata/eval/call.carbon

@@ -72,11 +72,11 @@ library "[[@TEST_NAME]]";
 eval fn F(x: i32) -> i32 { return x; }
 
 fn G(N:! i32) {
-  // CHECK:STDERR: fail_todo_dependent_call.carbon:[[@LINE+4]]:10: error: cannot evaluate type expression [TypeExprEvaluationFailure]
-  // CHECK:STDERR:   var a: array(i32, F(N)) = (0, 1, 2);
-  // CHECK:STDERR:          ^~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_dependent_call.carbon:[[@LINE+4]]:17: error: cannot evaluate type expression [TypeExprEvaluationFailure]
+  // CHECK:STDERR:   var unused a: array(i32, F(N)) = (0, 1, 2);
+  // CHECK:STDERR:                 ^~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var a: array(i32, F(N)) = (0, 1, 2);
+  var unused a: array(i32, F(N)) = (0, 1, 2);
 }
 
 fn H() { G(3); }
@@ -92,18 +92,18 @@ eval fn F(_: i32) -> type {
 
 fn UseFGenerically(X:! i32) {
   // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE+12]]:3: error: member name of type `<dependent type>` in compound member access is not an instance member or an interface member [CompoundMemberAccessDoesNotUseBase]
-  // CHECK:STDERR:   var v: F(X) = {};
-  // CHECK:STDERR:   ^~~~~~~~~~~
+  // CHECK:STDERR:   var unused v: F(X) = {};
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE+8]]:3: error: value of type `<dependent type>` is not callable [CallToNonCallable]
-  // CHECK:STDERR:   var v: F(X) = {};
-  // CHECK:STDERR:   ^~~~~~~~~~~
+  // CHECK:STDERR:   var unused v: F(X) = {};
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE+4]]:3: error: cannot access member of interface `Core.Destroy` in type `<cannot stringify inst7800018D: {kind: Call, arg0: inst7800003F, arg1: inst_block78000090, type: type(TypeType)}>` that does not implement that interface [MissingImplInMemberAccess]
-  // CHECK:STDERR:   var v: F(X) = {};
-  // CHECK:STDERR:   ^~~~~~~~~~~
+  // CHECK:STDERR:   var unused v: F(X) = {};
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
-  var v: F(X) = {};
+  var unused v: F(X) = {};
 }
 
 fn UseFSpecifically() {

+ 2 - 2
toolchain/check/testdata/eval/symbolic.carbon

@@ -20,7 +20,7 @@ eval fn F(B:! bool) -> type {
 }
 
 fn G(B:! bool) {
-  let n: F(B) = ({}, {});
+  let unused n: F(B) = ({}, {});
 }
 
 fn H() {
@@ -40,7 +40,7 @@ eval fn F(B:! bool) -> type {
 }
 
 fn G(B:! bool) {
-  let n: F(B) = ({}, {});
+  let unused n: F(B) = ({}, {});
 }
 
 fn H() {

+ 8 - 8
toolchain/check/testdata/facet/access.carbon

@@ -123,9 +123,9 @@ interface I {
   fn G() -> X*;
 }
 
-fn F2[U:! I](V: U*) {}
+fn F2[U:! I](unused V: U*) {}
 
-fn F(U:! I where .X = .Self, V: U) {
+fn F(U:! I where .X = .Self, unused V: U) {
   // The returned value of `G` type `U` which has access to the methods of `I`.
   U.G()->G();
   (U as type).G()->G();
@@ -142,10 +142,10 @@ interface I {
   fn G() -> X*;
 }
 
-fn F2[U:! I](V: U*) {}
-fn F3[U:! I where .X = .Self](V: U*) {}
+fn F2[U:! I](unused V: U*) {}
+fn F3[U:! I where .X = .Self](unused V: U*) {}
 
-fn F(U:! I where .X = .Self, V: U*) {
+fn F(U:! I where .X = .Self, unused V: U*) {
   // The returned value of `G` type `U` which has access to the methods of `I`.
   //
   // TODO: These should work.
@@ -184,8 +184,8 @@ fn F(U:! I where .X = .Self, V: U*) {
   // CHECK:STDERR:   F3(U.G());
   // CHECK:STDERR:   ^~~~~~~~~
   // CHECK:STDERR: fail_todo_access_through_call.carbon:[[@LINE-40]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn F3[U:! I where .X = .Self](V: U*) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn F3[U:! I where .X = .Self](unused V: U*) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   F3(U.G());
   // CHECK:STDERR: fail_todo_access_through_call.carbon:[[@LINE+4]]:6: error: type `.(I.X)` does not support qualified expressions [QualifiedExprUnsupported]
@@ -404,7 +404,7 @@ interface Z {
 // This requires that `SymbolicBindingType` evaluation correctly handles
 // arbitrary facet value instructions. Not just the common case of `FacetValue`
 // or `SymbolicBinding`.
-fn F1(T:! Y, t: T*) {}
+fn F1(T:! Y, unused t: T*) {}
 
 fn F2(U:! Z) {
   F1(U.Y1, U.G());

+ 17 - 17
toolchain/check/testdata/facet/combine.carbon

@@ -49,10 +49,10 @@ interface B {
 class C {}
 impl C as A {}
 impl C as B {
-  fn BB[self: Self]() {}
+  fn BB[unused self: Self]() {}
 }
 
-fn G[T:! A & B](t: T) {}
+fn G[T:! A & B](unused t: T) {}
 
 fn F() {
   ({} as C).((A & B).BB)();
@@ -76,7 +76,7 @@ class C {}
 impl C as A(P1) {}
 impl C as B {}
 
-fn G[T:! A(P1) & B](t: T) {}
+fn G[T:! A(P1) & B](unused t: T) {}
 
 fn F() {
   G({} as C);
@@ -95,15 +95,15 @@ class C {}
 impl C as A(P1) {}
 impl C as B {}
 
-fn G[T:! A(P2) & B](t: T) {}
+fn G[T:! A(P2) & B](unused t: T) {}
 
 fn F() {
   // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE+7]]:3: error: cannot convert type `C` into type implementing `A(P2) & B` [ConversionFailureTypeToFacet]
   // CHECK:STDERR:   G({} as C);
   // CHECK:STDERR:   ^~~~~~~~~~
   // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE-6]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn G[T:! A(P2) & B](t: T) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn G[T:! A(P2) & B](unused t: T) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   G({} as C);
 }
@@ -124,7 +124,7 @@ impl C as Iface {}
 
 impl forall [IfaceType:! Iface] C as GenericIface(GenericClass(IfaceType)) {}
 
-fn G[T:! Iface & GenericIface(GenericClass(ImplIface))](t: T) {}
+fn G[T:! Iface & GenericIface(GenericClass(ImplIface))](unused t: T) {}
 
 fn F() {
   G({} as C);
@@ -134,7 +134,7 @@ fn F() {
 library "[[@TEST_NAME]]";
 
 class WrapType(T:! type) {}
-fn AssertSame[T:! type](a: WrapType(T), b: WrapType(T)) {}
+fn AssertSame[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
 fn Type(T:! type) -> WrapType(T) { return {}; }
 
 interface I;
@@ -171,7 +171,7 @@ fn TestComplete() {
 library "[[@TEST_NAME]]";
 
 class WrapType(T:! type) {}
-fn Same[T:! type](a: WrapType(T), b: WrapType(T)) {}
+fn Same[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
 fn Type(T:! type) -> WrapType(T) { return {}; }
 
 interface I {}
@@ -183,8 +183,8 @@ fn Test() {
   // CHECK:STDERR:   Same(Type(I & J), Type(K & I & J));
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_compare_not_equal.carbon:[[@LINE-11]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn Same[T:! type](a: WrapType(T), b: WrapType(T)) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn Same[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   Same(Type(I & J), Type(K & I & J));
 }
@@ -193,7 +193,7 @@ fn Test() {
 library "[[@TEST_NAME]]";
 
 class WrapType(T:! type) {}
-fn Same[T:! type](a: WrapType(T), b: WrapType(T)) {}
+fn Same[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
 fn Type(T:! type) -> WrapType(T) { return {}; }
 
 interface I {}
@@ -204,8 +204,8 @@ fn Test() {
   // CHECK:STDERR:   Same(Type(I & J(())), Type(J({}) & I));
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_compare_not_equal_parameterized.carbon:[[@LINE-10]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn Same[T:! type](a: WrapType(T), b: WrapType(T)) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn Same[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   Same(Type(I & J(())), Type(J({}) & I));
 }
@@ -214,7 +214,7 @@ fn Test() {
 library "[[@TEST_NAME]]";
 
 class WrapType(T:! type) {}
-fn Same[T:! type](a: WrapType(T), b: WrapType(T)) {}
+fn Same[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
 fn Type(T:! type) -> WrapType(T) { return {}; }
 
 interface I {}
@@ -225,8 +225,8 @@ fn Test() {
   // CHECK:STDERR:   Same(Type(I & J(())), Type(J(()) & J({}) & I));
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_compare_not_equal_parameterized_extra.carbon:[[@LINE-10]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn Same[T:! type](a: WrapType(T), b: WrapType(T)) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn Same[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   Same(Type(I & J(())), Type(J(()) & J({}) & I));
 }

+ 6 - 6
toolchain/check/testdata/facet/convert_class_type_to_facet_type.carbon

@@ -17,7 +17,7 @@ interface Animal {}
 class Goat {}
 impl Goat as Animal {}
 
-fn WalkAnimal(A:! Animal) {}
+fn WalkAnimal(unused A:! Animal) {}
 
 fn F() {
   WalkAnimal(Goat);
@@ -74,7 +74,7 @@ fn F() {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %A.loc20_15.2: %Animal.type = symbolic_binding A, 0 [symbolic = %A.loc20_15.1 (constants.%A)]
+// CHECK:STDOUT:     %A.loc20_22.2: %Animal.type = symbolic_binding A, 0 [symbolic = %A.loc20_22.1 (constants.%A)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {}
 // CHECK:STDOUT: }
@@ -106,8 +106,8 @@ fn F() {
 // CHECK:STDOUT:   .Self = constants.%Goat
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @WalkAnimal(%A.loc20_15.2: %Animal.type) {
-// CHECK:STDOUT:   %A.loc20_15.1: %Animal.type = symbolic_binding A, 0 [symbolic = %A.loc20_15.1 (constants.%A)]
+// CHECK:STDOUT: generic fn @WalkAnimal(%A.loc20_22.2: %Animal.type) {
+// CHECK:STDOUT:   %A.loc20_22.1: %Animal.type = symbolic_binding A, 0 [symbolic = %A.loc20_22.1 (constants.%A)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
@@ -137,11 +137,11 @@ fn F() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @WalkAnimal(constants.%A) {
-// CHECK:STDOUT:   %A.loc20_15.1 => constants.%A
+// CHECK:STDOUT:   %A.loc20_22.1 => constants.%A
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @WalkAnimal(constants.%Animal.facet) {
-// CHECK:STDOUT:   %A.loc20_15.1 => constants.%Animal.facet
+// CHECK:STDOUT:   %A.loc20_22.1 => constants.%Animal.facet
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }

+ 53 - 45
toolchain/check/testdata/facet/convert_class_type_to_generic_facet_value.carbon

@@ -27,7 +27,7 @@ impl ImplsGeneric as Generic(GenericParam) {
   fn F() {}
 }
 
-fn CallGenericMethod(T:! type, U:! Generic(T)) {}
+fn CallGenericMethod(T:! type, unused U:! Generic(T)) {}
 
 fn G() {
   CallGenericMethod(GenericParam, ImplsGeneric);
@@ -56,7 +56,7 @@ impl ImplsGeneric as Generic(GenericParam) {
   fn F() {}
 }
 
-fn CallGenericMethod[T:! type](U:! Generic(T), t: T) {}
+fn CallGenericMethod[T:! type](unused U:! Generic(T), unused t: T) {}
 
 fn G() {
   CallGenericMethod(ImplsGeneric, {} as GenericParam);
@@ -96,7 +96,7 @@ fn G() {
 // CHECK:STDOUT:   %Generic.WithSelf.F.1fd: %Generic.WithSelf.F.type.c86 = struct_value () [concrete]
 // CHECK:STDOUT:   %T: type = symbolic_binding T, 0 [symbolic]
 // CHECK:STDOUT:   %Generic.type.03dff7.2: type = facet_type <@Generic, @Generic(%T)> [symbolic]
-// CHECK:STDOUT:   %U: %Generic.type.03dff7.2 = symbolic_binding U, 1 [symbolic]
+// CHECK:STDOUT:   %U.0f2266.1: %Generic.type.03dff7.2 = symbolic_binding U, 1 [symbolic]
 // CHECK:STDOUT:   %pattern_type.c49: type = pattern_type %Generic.type.03dff7.2 [symbolic]
 // CHECK:STDOUT:   %CallGenericMethod.type: type = fn_type @CallGenericMethod [concrete]
 // CHECK:STDOUT:   %CallGenericMethod: %CallGenericMethod.type = struct_value () [concrete]
@@ -104,6 +104,7 @@ fn G() {
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
 // CHECK:STDOUT:   %pattern_type.cba: type = pattern_type %Generic.type.498 [concrete]
 // CHECK:STDOUT:   %CallGenericMethod.specific_fn.d64: <specific function> = specific_function %CallGenericMethod, @CallGenericMethod(%GenericParam, %Generic.facet) [concrete]
+// CHECK:STDOUT:   %U.0f2266.2: %Generic.type.03dff7.2 = symbolic_binding U, 1 [symbolic]
 // CHECK:STDOUT:   %PassThroughToGenericMethod.type: type = fn_type @PassThroughToGenericMethod [concrete]
 // CHECK:STDOUT:   %PassThroughToGenericMethod: %PassThroughToGenericMethod.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Self.15d2d5.2: %Generic.type.03dff7.2 = symbolic_binding Self, 1 [symbolic]
@@ -111,7 +112,7 @@ fn G() {
 // CHECK:STDOUT:   %Generic.WithSelf.F.baf95a.2: %Generic.WithSelf.F.type.74390a.2 = struct_value () [symbolic]
 // CHECK:STDOUT:   %Generic.assoc_type.22afda.2: type = assoc_entity_type @Generic, @Generic(%T) [symbolic]
 // CHECK:STDOUT:   %assoc0.e0dc00.2: %Generic.assoc_type.22afda.2 = assoc_entity element0, @Generic.%Generic.WithSelf.F.decl [symbolic]
-// CHECK:STDOUT:   %CallGenericMethod.specific_fn.6c1: <specific function> = specific_function %CallGenericMethod, @CallGenericMethod(%T, %U) [symbolic]
+// CHECK:STDOUT:   %CallGenericMethod.specific_fn.6c1: <specific function> = specific_function %CallGenericMethod, @CallGenericMethod(%T, %U.0f2266.2) [symbolic]
 // CHECK:STDOUT:   %H.type: type = fn_type @H [concrete]
 // CHECK:STDOUT:   %H: %H.type = struct_value () [concrete]
 // CHECK:STDOUT:   %PassThroughToGenericMethod.specific_fn: <specific function> = specific_function %PassThroughToGenericMethod, @PassThroughToGenericMethod(%GenericParam, %Generic.facet) [concrete]
@@ -156,13 +157,13 @@ fn G() {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:     %T.loc15_22.2: type = symbolic_binding T, 0 [symbolic = %T.loc15_22.1 (constants.%T)]
-// CHECK:STDOUT:     %.loc15: type = splice_block %Generic.type.loc15_45.2 [symbolic = %Generic.type.loc15_45.1 (constants.%Generic.type.03dff7.2)] {
+// CHECK:STDOUT:     %.loc15: type = splice_block %Generic.type.loc15_52.2 [symbolic = %Generic.type.loc15_52.1 (constants.%Generic.type.03dff7.2)] {
 // CHECK:STDOUT:       %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %Generic.ref: %Generic.type.835 = name_ref Generic, file.%Generic.decl [concrete = constants.%Generic.generic]
 // CHECK:STDOUT:       %T.ref: type = name_ref T, %T.loc15_22.2 [symbolic = %T.loc15_22.1 (constants.%T)]
-// CHECK:STDOUT:       %Generic.type.loc15_45.2: type = facet_type <@Generic, @Generic(constants.%T)> [symbolic = %Generic.type.loc15_45.1 (constants.%Generic.type.03dff7.2)]
+// CHECK:STDOUT:       %Generic.type.loc15_52.2: type = facet_type <@Generic, @Generic(constants.%T)> [symbolic = %Generic.type.loc15_52.1 (constants.%Generic.type.03dff7.2)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %U.loc15_32.2: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_32.1 (constants.%U)]
+// CHECK:STDOUT:     %U.loc15_39.2: @CallGenericMethod.%Generic.type.loc15_52.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_39.1 (constants.%U.0f2266.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
 // CHECK:STDOUT:   %PassThroughToGenericMethod.decl: %PassThroughToGenericMethod.type = fn_decl @PassThroughToGenericMethod [concrete = constants.%PassThroughToGenericMethod] {
@@ -177,7 +178,7 @@ fn G() {
 // CHECK:STDOUT:       %T.ref.loc21: type = name_ref T, %T.loc21_31.2 [symbolic = %T.loc21_31.1 (constants.%T)]
 // CHECK:STDOUT:       %Generic.type.loc21_54.2: type = facet_type <@Generic, @Generic(constants.%T)> [symbolic = %Generic.type.loc21_54.1 (constants.%Generic.type.03dff7.2)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %U.loc21_41.2: @PassThroughToGenericMethod.%Generic.type.loc21_54.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc21_41.1 (constants.%U)]
+// CHECK:STDOUT:     %U.loc21_41.2: @PassThroughToGenericMethod.%Generic.type.loc21_54.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc21_41.1 (constants.%U.0f2266.2)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %H.decl: %H.type = fn_decl @H [concrete = constants.%H] {} {}
 // CHECK:STDOUT: }
@@ -241,11 +242,11 @@ fn G() {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @CallGenericMethod(%T.loc15_22.2: type, %U.loc15_32.2: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2)) {
+// CHECK:STDOUT: generic fn @CallGenericMethod(%T.loc15_22.2: type, %U.loc15_39.2: @CallGenericMethod.%Generic.type.loc15_52.1 (%Generic.type.03dff7.2)) {
 // CHECK:STDOUT:   %T.loc15_22.1: type = symbolic_binding T, 0 [symbolic = %T.loc15_22.1 (constants.%T)]
-// CHECK:STDOUT:   %Generic.type.loc15_45.1: type = facet_type <@Generic, @Generic(%T.loc15_22.1)> [symbolic = %Generic.type.loc15_45.1 (constants.%Generic.type.03dff7.2)]
-// CHECK:STDOUT:   %U.loc15_32.1: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_32.1 (constants.%U)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %Generic.type.loc15_45.1 [symbolic = %pattern_type (constants.%pattern_type.c49)]
+// CHECK:STDOUT:   %Generic.type.loc15_52.1: type = facet_type <@Generic, @Generic(%T.loc15_22.1)> [symbolic = %Generic.type.loc15_52.1 (constants.%Generic.type.03dff7.2)]
+// CHECK:STDOUT:   %U.loc15_39.1: @CallGenericMethod.%Generic.type.loc15_52.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_39.1 (constants.%U.0f2266.1)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %Generic.type.loc15_52.1 [symbolic = %pattern_type (constants.%pattern_type.c49)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
@@ -270,7 +271,7 @@ fn G() {
 // CHECK:STDOUT: generic fn @PassThroughToGenericMethod(%T.loc21_31.2: type, %U.loc21_41.2: @PassThroughToGenericMethod.%Generic.type.loc21_54.1 (%Generic.type.03dff7.2)) {
 // CHECK:STDOUT:   %T.loc21_31.1: type = symbolic_binding T, 0 [symbolic = %T.loc21_31.1 (constants.%T)]
 // CHECK:STDOUT:   %Generic.type.loc21_54.1: type = facet_type <@Generic, @Generic(%T.loc21_31.1)> [symbolic = %Generic.type.loc21_54.1 (constants.%Generic.type.03dff7.2)]
-// CHECK:STDOUT:   %U.loc21_41.1: @PassThroughToGenericMethod.%Generic.type.loc21_54.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc21_41.1 (constants.%U)]
+// CHECK:STDOUT:   %U.loc21_41.1: @PassThroughToGenericMethod.%Generic.type.loc21_54.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc21_41.1 (constants.%U.0f2266.2)]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %Generic.type.loc21_54.1 [symbolic = %pattern_type (constants.%pattern_type.c49)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
@@ -280,8 +281,8 @@ fn G() {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %CallGenericMethod.ref: %CallGenericMethod.type = name_ref CallGenericMethod, file.%CallGenericMethod.decl [concrete = constants.%CallGenericMethod]
 // CHECK:STDOUT:     %T.ref.loc22: type = name_ref T, %T.loc21_31.2 [symbolic = %T.loc21_31.1 (constants.%T)]
-// CHECK:STDOUT:     %U.ref: @PassThroughToGenericMethod.%Generic.type.loc21_54.1 (%Generic.type.03dff7.2) = name_ref U, %U.loc21_41.2 [symbolic = %U.loc21_41.1 (constants.%U)]
-// CHECK:STDOUT:     %CallGenericMethod.specific_fn.loc22_3.1: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%T, constants.%U) [symbolic = %CallGenericMethod.specific_fn.loc22_3.2 (constants.%CallGenericMethod.specific_fn.6c1)]
+// CHECK:STDOUT:     %U.ref: @PassThroughToGenericMethod.%Generic.type.loc21_54.1 (%Generic.type.03dff7.2) = name_ref U, %U.loc21_41.2 [symbolic = %U.loc21_41.1 (constants.%U.0f2266.2)]
+// CHECK:STDOUT:     %CallGenericMethod.specific_fn.loc22_3.1: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%T, constants.%U.0f2266.2) [symbolic = %CallGenericMethod.specific_fn.loc22_3.2 (constants.%CallGenericMethod.specific_fn.6c1)]
 // CHECK:STDOUT:     %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn.loc22_3.1()
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -347,28 +348,26 @@ fn G() {
 // CHECK:STDOUT:   %Self.loc4_34.2 => constants.%Self.15d2d5.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%T, constants.%U) {
+// CHECK:STDOUT: specific @CallGenericMethod(constants.%T, constants.%U.0f2266.1) {
 // CHECK:STDOUT:   %T.loc15_22.1 => constants.%T
-// CHECK:STDOUT:   %Generic.type.loc15_45.1 => constants.%Generic.type.03dff7.2
-// CHECK:STDOUT:   %U.loc15_32.1 => constants.%U
+// CHECK:STDOUT:   %Generic.type.loc15_52.1 => constants.%Generic.type.03dff7.2
+// CHECK:STDOUT:   %U.loc15_39.1 => constants.%U.0f2266.1
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.c49
-// CHECK:STDOUT:
-// CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
 // CHECK:STDOUT:   %T.loc15_22.1 => constants.%GenericParam
-// CHECK:STDOUT:   %Generic.type.loc15_45.1 => constants.%Generic.type.498
-// CHECK:STDOUT:   %U.loc15_32.1 => constants.%Generic.facet
+// CHECK:STDOUT:   %Generic.type.loc15_52.1 => constants.%Generic.type.498
+// CHECK:STDOUT:   %U.loc15_39.1 => constants.%Generic.facet
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.cba
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @PassThroughToGenericMethod(constants.%T, constants.%U) {
+// CHECK:STDOUT: specific @PassThroughToGenericMethod(constants.%T, constants.%U.0f2266.2) {
 // CHECK:STDOUT:   %T.loc21_31.1 => constants.%T
 // CHECK:STDOUT:   %Generic.type.loc21_54.1 => constants.%Generic.type.03dff7.2
-// CHECK:STDOUT:   %U.loc21_41.1 => constants.%U
+// CHECK:STDOUT:   %U.loc21_41.1 => constants.%U.0f2266.2
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.c49
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -383,6 +382,15 @@ fn G() {
 // CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.e0dc00.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @CallGenericMethod(constants.%T, constants.%U.0f2266.2) {
+// CHECK:STDOUT:   %T.loc15_22.1 => constants.%T
+// CHECK:STDOUT:   %Generic.type.loc15_52.1 => constants.%Generic.type.03dff7.2
+// CHECK:STDOUT:   %U.loc15_39.1 => constants.%U.0f2266.2
+// CHECK:STDOUT:   %pattern_type => constants.%pattern_type.c49
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @PassThroughToGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
 // CHECK:STDOUT:   %T.loc21_31.1 => constants.%GenericParam
 // CHECK:STDOUT:   %Generic.type.loc21_54.1 => constants.%Generic.type.498
@@ -480,21 +488,21 @@ fn G() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %CallGenericMethod.decl: %CallGenericMethod.type = fn_decl @CallGenericMethod [concrete = constants.%CallGenericMethod] {
 // CHECK:STDOUT:     %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete]
-// CHECK:STDOUT:     %U.patt: @CallGenericMethod.%pattern_type.loc15_32 (%pattern_type.c49) = symbolic_binding_pattern U, 1 [concrete]
-// CHECK:STDOUT:     %t.patt: @CallGenericMethod.%pattern_type.loc15_48 (%pattern_type.51d) = value_binding_pattern t [concrete]
-// CHECK:STDOUT:     %t.param_patt: @CallGenericMethod.%pattern_type.loc15_48 (%pattern_type.51d) = value_param_pattern %t.patt, call_param0 [concrete]
+// CHECK:STDOUT:     %U.patt: @CallGenericMethod.%pattern_type.loc15_39 (%pattern_type.c49) = symbolic_binding_pattern U, 1 [concrete]
+// CHECK:STDOUT:     %t.patt: @CallGenericMethod.%pattern_type.loc15_62 (%pattern_type.51d) = value_binding_pattern t [concrete]
+// CHECK:STDOUT:     %t.param_patt: @CallGenericMethod.%pattern_type.loc15_62 (%pattern_type.51d) = value_param_pattern %t.patt, call_param0 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:     %T.loc15_22.2: type = symbolic_binding T, 0 [symbolic = %T.loc15_22.1 (constants.%T)]
-// CHECK:STDOUT:     %.loc15: type = splice_block %Generic.type.loc15_45.2 [symbolic = %Generic.type.loc15_45.1 (constants.%Generic.type.03dff7.2)] {
+// CHECK:STDOUT:     %.loc15: type = splice_block %Generic.type.loc15_52.2 [symbolic = %Generic.type.loc15_52.1 (constants.%Generic.type.03dff7.2)] {
 // CHECK:STDOUT:       %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %Generic.ref: %Generic.type.835 = name_ref Generic, file.%Generic.decl [concrete = constants.%Generic.generic]
-// CHECK:STDOUT:       %T.ref.loc15_44: type = name_ref T, %T.loc15_22.2 [symbolic = %T.loc15_22.1 (constants.%T)]
-// CHECK:STDOUT:       %Generic.type.loc15_45.2: type = facet_type <@Generic, @Generic(constants.%T)> [symbolic = %Generic.type.loc15_45.1 (constants.%Generic.type.03dff7.2)]
+// CHECK:STDOUT:       %T.ref.loc15_51: type = name_ref T, %T.loc15_22.2 [symbolic = %T.loc15_22.1 (constants.%T)]
+// CHECK:STDOUT:       %Generic.type.loc15_52.2: type = facet_type <@Generic, @Generic(constants.%T)> [symbolic = %Generic.type.loc15_52.1 (constants.%Generic.type.03dff7.2)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %U.loc15_32.2: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_32.1 (constants.%U)]
+// CHECK:STDOUT:     %U.loc15_39.2: @CallGenericMethod.%Generic.type.loc15_52.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_39.1 (constants.%U)]
 // CHECK:STDOUT:     %t.param: @CallGenericMethod.%T.loc15_22.1 (%T) = value_param call_param0
-// CHECK:STDOUT:     %T.ref.loc15_51: type = name_ref T, %T.loc15_22.2 [symbolic = %T.loc15_22.1 (constants.%T)]
+// CHECK:STDOUT:     %T.ref.loc15_65: type = name_ref T, %T.loc15_22.2 [symbolic = %T.loc15_22.1 (constants.%T)]
 // CHECK:STDOUT:     %t: @CallGenericMethod.%T.loc15_22.1 (%T) = value_binding t, %t.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
@@ -559,12 +567,12 @@ fn G() {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @CallGenericMethod(%T.loc15_22.2: type, %U.loc15_32.2: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2)) {
+// CHECK:STDOUT: generic fn @CallGenericMethod(%T.loc15_22.2: type, %U.loc15_39.2: @CallGenericMethod.%Generic.type.loc15_52.1 (%Generic.type.03dff7.2)) {
 // CHECK:STDOUT:   %T.loc15_22.1: type = symbolic_binding T, 0 [symbolic = %T.loc15_22.1 (constants.%T)]
-// CHECK:STDOUT:   %Generic.type.loc15_45.1: type = facet_type <@Generic, @Generic(%T.loc15_22.1)> [symbolic = %Generic.type.loc15_45.1 (constants.%Generic.type.03dff7.2)]
-// CHECK:STDOUT:   %U.loc15_32.1: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_32.1 (constants.%U)]
-// CHECK:STDOUT:   %pattern_type.loc15_32: type = pattern_type %Generic.type.loc15_45.1 [symbolic = %pattern_type.loc15_32 (constants.%pattern_type.c49)]
-// CHECK:STDOUT:   %pattern_type.loc15_48: type = pattern_type %T.loc15_22.1 [symbolic = %pattern_type.loc15_48 (constants.%pattern_type.51d)]
+// CHECK:STDOUT:   %Generic.type.loc15_52.1: type = facet_type <@Generic, @Generic(%T.loc15_22.1)> [symbolic = %Generic.type.loc15_52.1 (constants.%Generic.type.03dff7.2)]
+// CHECK:STDOUT:   %U.loc15_39.1: @CallGenericMethod.%Generic.type.loc15_52.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_39.1 (constants.%U)]
+// CHECK:STDOUT:   %pattern_type.loc15_39: type = pattern_type %Generic.type.loc15_52.1 [symbolic = %pattern_type.loc15_39 (constants.%pattern_type.c49)]
+// CHECK:STDOUT:   %pattern_type.loc15_62: type = pattern_type %T.loc15_22.1 [symbolic = %pattern_type.loc15_62 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %T.loc15_22.1 [symbolic = %require_complete (constants.%require_complete)]
@@ -643,18 +651,18 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @CallGenericMethod(constants.%T, constants.%U) {
 // CHECK:STDOUT:   %T.loc15_22.1 => constants.%T
-// CHECK:STDOUT:   %Generic.type.loc15_45.1 => constants.%Generic.type.03dff7.2
-// CHECK:STDOUT:   %U.loc15_32.1 => constants.%U
-// CHECK:STDOUT:   %pattern_type.loc15_32 => constants.%pattern_type.c49
-// CHECK:STDOUT:   %pattern_type.loc15_48 => constants.%pattern_type.51d
+// CHECK:STDOUT:   %Generic.type.loc15_52.1 => constants.%Generic.type.03dff7.2
+// CHECK:STDOUT:   %U.loc15_39.1 => constants.%U
+// CHECK:STDOUT:   %pattern_type.loc15_39 => constants.%pattern_type.c49
+// CHECK:STDOUT:   %pattern_type.loc15_62 => constants.%pattern_type.51d
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
 // CHECK:STDOUT:   %T.loc15_22.1 => constants.%GenericParam
-// CHECK:STDOUT:   %Generic.type.loc15_45.1 => constants.%Generic.type.498
-// CHECK:STDOUT:   %U.loc15_32.1 => constants.%Generic.facet
-// CHECK:STDOUT:   %pattern_type.loc15_32 => constants.%pattern_type.cba
-// CHECK:STDOUT:   %pattern_type.loc15_48 => constants.%pattern_type.27a
+// CHECK:STDOUT:   %Generic.type.loc15_52.1 => constants.%Generic.type.498
+// CHECK:STDOUT:   %U.loc15_39.1 => constants.%Generic.facet
+// CHECK:STDOUT:   %pattern_type.loc15_39 => constants.%pattern_type.cba
+// CHECK:STDOUT:   %pattern_type.loc15_62 => constants.%pattern_type.27a
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete => constants.%complete_type

+ 3 - 3
toolchain/check/testdata/facet/convert_class_value_to_facet_value_value.carbon

@@ -14,7 +14,7 @@
 
 interface Animal {}
 
-fn WalkAnimal[T:! Animal](a: T) {}
+fn WalkAnimal[T:! Animal](unused a: T) {}
 
 class Goat {}
 impl Goat as Animal {}
@@ -84,10 +84,10 @@ fn F() {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %T.loc17_15.2: %Animal.type = symbolic_binding T, 0 [symbolic = %T.loc17_15.1 (constants.%T)]
 // CHECK:STDOUT:     %a.param: @WalkAnimal.%T.binding.as_type (%T.binding.as_type) = value_param call_param0
-// CHECK:STDOUT:     %.loc17_30.1: type = splice_block %.loc17_30.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] {
+// CHECK:STDOUT:     %.loc17_37.1: type = splice_block %.loc17_37.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] {
 // CHECK:STDOUT:       %T.ref: %Animal.type = name_ref T, %T.loc17_15.2 [symbolic = %T.loc17_15.1 (constants.%T)]
 // CHECK:STDOUT:       %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
-// CHECK:STDOUT:       %.loc17_30.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
+// CHECK:STDOUT:       %.loc17_37.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %a: @WalkAnimal.%T.binding.as_type (%T.binding.as_type) = value_binding a, %a.param
 // CHECK:STDOUT:   }

+ 31 - 31
toolchain/check/testdata/facet/convert_class_value_to_generic_facet_value_value.carbon

@@ -27,7 +27,7 @@ impl ImplsGeneric as Generic(GenericParam) {
   fn F() {}
 }
 
-fn CallGenericMethod[T:! type, U:! Generic(T)](a: U, s: T) {
+fn CallGenericMethod[T:! type, U:! Generic(T)](unused a: U, unused s: T) {
   U.F();
 }
 
@@ -44,7 +44,7 @@ class C {}
 
 impl forall [T:! type] C as I(T, ()) {}
 
-fn A[T:! I({}, ())](t: T) {}
+fn A[T:! I({}, ())](unused t: T) {}
 
 fn B() {
   A({} as C);
@@ -59,15 +59,15 @@ class C {}
 
 impl forall [T:! type] C as I(T, ()) {}
 
-fn A[T:! I({}, {})](t: T) {}
+fn A[T:! I({}, {})](unused t: T) {}
 
 fn B() {
   // CHECK:STDERR: fail_mismatch_impl_constraint_with_fixed_specific.carbon:[[@LINE+7]]:3: error: cannot convert type `C` into type implementing `I({}, {})` [ConversionFailureTypeToFacet]
   // CHECK:STDERR:   A({} as C);
   // CHECK:STDERR:   ^~~~~~~~~~
   // CHECK:STDERR: fail_mismatch_impl_constraint_with_fixed_specific.carbon:[[@LINE-6]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn A[T:! I({}, {})](t: T) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn A[T:! I({}, {})](unused t: T) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   A({} as C);
 }
@@ -81,15 +81,15 @@ class C(V:! type, W:! type) {}
 
 impl forall [T:! type] C(T, ()) as I {}
 
-fn A[T:! I](t: T) {}
+fn A[T:! I](unused t: T) {}
 
 fn B() {
   // CHECK:STDERR: fail_mismatch_impl_self_with_fixed_specific.carbon:[[@LINE+7]]:3: error: cannot convert type `C({}, {})` into type implementing `I` [ConversionFailureTypeToFacet]
   // CHECK:STDERR:   A({} as C({}, {}));
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_mismatch_impl_self_with_fixed_specific.carbon:[[@LINE-6]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
-  // CHECK:STDERR: fn A[T:! I](t: T) {}
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fn A[T:! I](unused t: T) {}
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   A({} as C({}, {}));
 }
@@ -203,10 +203,10 @@ fn B() {
 // CHECK:STDOUT:   %CallGenericMethod.decl: %CallGenericMethod.type = fn_decl @CallGenericMethod [concrete = constants.%CallGenericMethod] {
 // CHECK:STDOUT:     %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:     %U.patt: @CallGenericMethod.%pattern_type.loc15_32 (%pattern_type.c49) = symbolic_binding_pattern U, 1 [concrete]
-// CHECK:STDOUT:     %a.patt: @CallGenericMethod.%pattern_type.loc15_48 (%pattern_type.46f) = value_binding_pattern a [concrete]
-// CHECK:STDOUT:     %a.param_patt: @CallGenericMethod.%pattern_type.loc15_48 (%pattern_type.46f) = value_param_pattern %a.patt, call_param0 [concrete]
-// CHECK:STDOUT:     %s.patt: @CallGenericMethod.%pattern_type.loc15_54 (%pattern_type.51d) = value_binding_pattern s [concrete]
-// CHECK:STDOUT:     %s.param_patt: @CallGenericMethod.%pattern_type.loc15_54 (%pattern_type.51d) = value_param_pattern %s.patt, call_param1 [concrete]
+// CHECK:STDOUT:     %a.patt: @CallGenericMethod.%pattern_type.loc15_55 (%pattern_type.46f) = value_binding_pattern a [concrete]
+// CHECK:STDOUT:     %a.param_patt: @CallGenericMethod.%pattern_type.loc15_55 (%pattern_type.46f) = value_param_pattern %a.patt, call_param0 [concrete]
+// CHECK:STDOUT:     %s.patt: @CallGenericMethod.%pattern_type.loc15_68 (%pattern_type.51d) = value_binding_pattern s [concrete]
+// CHECK:STDOUT:     %s.param_patt: @CallGenericMethod.%pattern_type.loc15_68 (%pattern_type.51d) = value_param_pattern %s.patt, call_param1 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:     %T.loc15_22.2: type = symbolic_binding T, 0 [symbolic = %T.loc15_22.1 (constants.%T)]
@@ -218,14 +218,14 @@ fn B() {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %U.loc15_32.2: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_32.1 (constants.%U)]
 // CHECK:STDOUT:     %a.param: @CallGenericMethod.%U.binding.as_type (%U.binding.as_type) = value_param call_param0
-// CHECK:STDOUT:     %.loc15_51.1: type = splice_block %.loc15_51.2 [symbolic = %U.binding.as_type (constants.%U.binding.as_type)] {
+// CHECK:STDOUT:     %.loc15_58.1: type = splice_block %.loc15_58.2 [symbolic = %U.binding.as_type (constants.%U.binding.as_type)] {
 // CHECK:STDOUT:       %U.ref.loc15: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2) = name_ref U, %U.loc15_32.2 [symbolic = %U.loc15_32.1 (constants.%U)]
 // CHECK:STDOUT:       %U.as_type.loc15: type = facet_access_type %U.ref.loc15 [symbolic = %U.binding.as_type (constants.%U.binding.as_type)]
-// CHECK:STDOUT:       %.loc15_51.2: type = converted %U.ref.loc15, %U.as_type.loc15 [symbolic = %U.binding.as_type (constants.%U.binding.as_type)]
+// CHECK:STDOUT:       %.loc15_58.2: type = converted %U.ref.loc15, %U.as_type.loc15 [symbolic = %U.binding.as_type (constants.%U.binding.as_type)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %a: @CallGenericMethod.%U.binding.as_type (%U.binding.as_type) = value_binding a, %a.param
 // CHECK:STDOUT:     %s.param: @CallGenericMethod.%T.loc15_22.1 (%T) = value_param call_param1
-// CHECK:STDOUT:     %T.ref.loc15_57: type = name_ref T, %T.loc15_22.2 [symbolic = %T.loc15_22.1 (constants.%T)]
+// CHECK:STDOUT:     %T.ref.loc15_71: type = name_ref T, %T.loc15_22.2 [symbolic = %T.loc15_22.1 (constants.%T)]
 // CHECK:STDOUT:     %s: @CallGenericMethod.%T.loc15_22.1 (%T) = value_binding s, %s.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
@@ -296,12 +296,12 @@ fn B() {
 // CHECK:STDOUT:   %U.loc15_32.1: @CallGenericMethod.%Generic.type.loc15_45.1 (%Generic.type.03dff7.2) = symbolic_binding U, 1 [symbolic = %U.loc15_32.1 (constants.%U)]
 // CHECK:STDOUT:   %pattern_type.loc15_32: type = pattern_type %Generic.type.loc15_45.1 [symbolic = %pattern_type.loc15_32 (constants.%pattern_type.c49)]
 // CHECK:STDOUT:   %U.binding.as_type: type = symbolic_binding_type U, 1, %U.loc15_32.1 [symbolic = %U.binding.as_type (constants.%U.binding.as_type)]
-// CHECK:STDOUT:   %pattern_type.loc15_48: type = pattern_type %U.binding.as_type [symbolic = %pattern_type.loc15_48 (constants.%pattern_type.46f)]
-// CHECK:STDOUT:   %pattern_type.loc15_54: type = pattern_type %T.loc15_22.1 [symbolic = %pattern_type.loc15_54 (constants.%pattern_type.51d)]
+// CHECK:STDOUT:   %pattern_type.loc15_55: type = pattern_type %U.binding.as_type [symbolic = %pattern_type.loc15_55 (constants.%pattern_type.46f)]
+// CHECK:STDOUT:   %pattern_type.loc15_68: type = pattern_type %T.loc15_22.1 [symbolic = %pattern_type.loc15_68 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc15_49: <witness> = require_complete_type %U.binding.as_type [symbolic = %require_complete.loc15_49 (constants.%require_complete.186)]
-// CHECK:STDOUT:   %require_complete.loc15_55: <witness> = require_complete_type %T.loc15_22.1 [symbolic = %require_complete.loc15_55 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc15_56: <witness> = require_complete_type %U.binding.as_type [symbolic = %require_complete.loc15_56 (constants.%require_complete.186)]
+// CHECK:STDOUT:   %require_complete.loc15_69: <witness> = require_complete_type %T.loc15_22.1 [symbolic = %require_complete.loc15_69 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %require_complete.loc16: <witness> = require_complete_type %Generic.type.loc15_45.1 [symbolic = %require_complete.loc16 (constants.%require_complete.7da)]
 // CHECK:STDOUT:   %Generic.assoc_type: type = assoc_entity_type @Generic, @Generic(%T.loc15_22.1) [symbolic = %Generic.assoc_type (constants.%Generic.assoc_type.22afda.2)]
 // CHECK:STDOUT:   %assoc0: @CallGenericMethod.%Generic.assoc_type (%Generic.assoc_type.22afda.2) = assoc_entity element0, @Generic.%Generic.WithSelf.F.decl [symbolic = %assoc0 (constants.%assoc0.e0dc00.2)]
@@ -422,8 +422,8 @@ fn B() {
 // CHECK:STDOUT:   %U.loc15_32.1 => constants.%U
 // CHECK:STDOUT:   %pattern_type.loc15_32 => constants.%pattern_type.c49
 // CHECK:STDOUT:   %U.binding.as_type => constants.%U.binding.as_type
-// CHECK:STDOUT:   %pattern_type.loc15_48 => constants.%pattern_type.46f
-// CHECK:STDOUT:   %pattern_type.loc15_54 => constants.%pattern_type.51d
+// CHECK:STDOUT:   %pattern_type.loc15_55 => constants.%pattern_type.46f
+// CHECK:STDOUT:   %pattern_type.loc15_68 => constants.%pattern_type.51d
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Generic(constants.%T, constants.%U) {
@@ -445,12 +445,12 @@ fn B() {
 // CHECK:STDOUT:   %U.loc15_32.1 => constants.%Generic.facet
 // CHECK:STDOUT:   %pattern_type.loc15_32 => constants.%pattern_type.cba
 // CHECK:STDOUT:   %U.binding.as_type => constants.%ImplsGeneric
-// CHECK:STDOUT:   %pattern_type.loc15_48 => constants.%pattern_type.4da
-// CHECK:STDOUT:   %pattern_type.loc15_54 => constants.%pattern_type.27a
+// CHECK:STDOUT:   %pattern_type.loc15_55 => constants.%pattern_type.4da
+// CHECK:STDOUT:   %pattern_type.loc15_68 => constants.%pattern_type.27a
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc15_49 => constants.%complete_type.357
-// CHECK:STDOUT:   %require_complete.loc15_55 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc15_56 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc15_69 => constants.%complete_type.357
 // CHECK:STDOUT:   %require_complete.loc16 => constants.%complete_type.57a
 // CHECK:STDOUT:   %Generic.assoc_type => constants.%Generic.assoc_type.6dc
 // CHECK:STDOUT:   %assoc0 => constants.%assoc0.717
@@ -563,10 +563,10 @@ fn B() {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %T.loc9_6.2: %I.type.5f7 = symbolic_binding T, 0 [symbolic = %T.loc9_6.1 (constants.%T.bc3)]
 // CHECK:STDOUT:     %t.param: @A.%T.binding.as_type (%T.binding.as_type) = value_param call_param0
-// CHECK:STDOUT:     %.loc9_24.1: type = splice_block %.loc9_24.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] {
+// CHECK:STDOUT:     %.loc9_31.1: type = splice_block %.loc9_31.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] {
 // CHECK:STDOUT:       %T.ref: %I.type.5f7 = name_ref T, %T.loc9_6.2 [symbolic = %T.loc9_6.1 (constants.%T.bc3)]
 // CHECK:STDOUT:       %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
-// CHECK:STDOUT:       %.loc9_24.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
+// CHECK:STDOUT:       %.loc9_31.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %t: @A.%T.binding.as_type (%T.binding.as_type) = value_binding t, %t.param
 // CHECK:STDOUT:   }
@@ -819,10 +819,10 @@ fn B() {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %T.loc9_6.2: %I.type.7b9 = symbolic_binding T, 0 [symbolic = %T.loc9_6.1 (constants.%T.274)]
 // CHECK:STDOUT:     %t.param: @A.%T.binding.as_type (%T.binding.as_type) = value_param call_param0
-// CHECK:STDOUT:     %.loc9_24.1: type = splice_block %.loc9_24.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] {
+// CHECK:STDOUT:     %.loc9_31.1: type = splice_block %.loc9_31.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] {
 // CHECK:STDOUT:       %T.ref: %I.type.7b9 = name_ref T, %T.loc9_6.2 [symbolic = %T.loc9_6.1 (constants.%T.274)]
 // CHECK:STDOUT:       %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
-// CHECK:STDOUT:       %.loc9_24.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
+// CHECK:STDOUT:       %.loc9_31.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %t: @A.%T.binding.as_type (%T.binding.as_type) = value_binding t, %t.param
 // CHECK:STDOUT:   }
@@ -1042,10 +1042,10 @@ fn B() {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %T.loc9_6.2: %I.type = symbolic_binding T, 0 [symbolic = %T.loc9_6.1 (constants.%T.651)]
 // CHECK:STDOUT:     %t.param: @A.%T.binding.as_type (%T.binding.as_type) = value_param call_param0
-// CHECK:STDOUT:     %.loc9_16.1: type = splice_block %.loc9_16.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] {
+// CHECK:STDOUT:     %.loc9_23.1: type = splice_block %.loc9_23.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] {
 // CHECK:STDOUT:       %T.ref: %I.type = name_ref T, %T.loc9_6.2 [symbolic = %T.loc9_6.1 (constants.%T.651)]
 // CHECK:STDOUT:       %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
-// CHECK:STDOUT:       %.loc9_16.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
+// CHECK:STDOUT:       %.loc9_23.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %t: @A.%T.binding.as_type (%T.binding.as_type) = value_binding t, %t.param
 // CHECK:STDOUT:   }

+ 12 - 15
toolchain/check/testdata/facet/convert_facet_type_to_facet_value.carbon

@@ -20,8 +20,7 @@ interface Animal {}
 // https://github.com/carbon-language/carbon-lang/issues/4853
 impl Animal as Eats {}
 
-fn Feed(e:! Eats) {}
-
+fn Feed(unused e:! Eats) {}
 fn F() {
   Feed(Animal);
 }
@@ -36,8 +35,7 @@ interface Animal {}
 // https://github.com/carbon-language/carbon-lang/issues/4853
 impl Animal as Eats {}
 
-fn Feed(e:! Eats) {}
-
+fn Feed(unused e:! Eats) {}
 class Goat {}
 impl Goat as Animal {}
 
@@ -45,9 +43,9 @@ fn F() {
   // CHECK:STDERR: fail_facet_value_to_facet_type.carbon:[[@LINE+7]]:3: error: cannot convert type `Goat as Animal` that implements `Animal` into type implementing `Eats` [ConversionFailureFacetToFacet]
   // CHECK:STDERR:   Feed(Goat as Animal);
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_facet_value_to_facet_type.carbon:[[@LINE-9]]:9: note: initializing generic parameter `e` declared here [InitializingGenericParam]
-  // CHECK:STDERR: fn Feed(e:! Eats) {}
-  // CHECK:STDERR:         ^
+  // CHECK:STDERR: fail_facet_value_to_facet_type.carbon:[[@LINE-8]]:16: note: initializing generic parameter `e` declared here [InitializingGenericParam]
+  // CHECK:STDERR: fn Feed(unused e:! Eats) {}
+  // CHECK:STDERR:                ^
   // CHECK:STDERR:
   Feed(Goat as Animal);
 }
@@ -63,8 +61,7 @@ interface Climbs {}
 // https://github.com/carbon-language/carbon-lang/issues/4853
 impl Animal as Eats {}
 
-fn Feed(e:! Eats) {}
-
+fn Feed(unused e:! Eats) {}
 class Goat {}
 impl Goat as Animal {}
 impl Goat as Climbs {}
@@ -75,18 +72,18 @@ fn F() {
   // CHECK:STDERR: fail_convert_multi_interface_facet_value_to_facet_value.carbon:[[@LINE+7]]:3: error: cannot convert type `Goat as Animal & Climbs` that implements `Animal & Climbs` into type implementing `Eats` [ConversionFailureFacetToFacet]
   // CHECK:STDERR:   Feed(Goat as (Animal & Climbs));
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_convert_multi_interface_facet_value_to_facet_value.carbon:[[@LINE-12]]:9: note: initializing generic parameter `e` declared here [InitializingGenericParam]
-  // CHECK:STDERR: fn Feed(e:! Eats) {}
-  // CHECK:STDERR:         ^
+  // CHECK:STDERR: fail_convert_multi_interface_facet_value_to_facet_value.carbon:[[@LINE-11]]:16: note: initializing generic parameter `e` declared here [InitializingGenericParam]
+  // CHECK:STDERR: fn Feed(unused e:! Eats) {}
+  // CHECK:STDERR:                ^
   // CHECK:STDERR:
   Feed(Goat as (Animal & Climbs));
 
   // CHECK:STDERR: fail_convert_multi_interface_facet_value_to_facet_value.carbon:[[@LINE+7]]:3: error: cannot convert type `Animal & Climbs` into type implementing `Eats` [ConversionFailureTypeToFacet]
   // CHECK:STDERR:   Feed(Animal & Climbs);
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_convert_multi_interface_facet_value_to_facet_value.carbon:[[@LINE-21]]:9: note: initializing generic parameter `e` declared here [InitializingGenericParam]
-  // CHECK:STDERR: fn Feed(e:! Eats) {}
-  // CHECK:STDERR:         ^
+  // CHECK:STDERR: fail_convert_multi_interface_facet_value_to_facet_value.carbon:[[@LINE-20]]:16: note: initializing generic parameter `e` declared here [InitializingGenericParam]
+  // CHECK:STDERR: fn Feed(unused e:! Eats) {}
+  // CHECK:STDERR:                ^
   // CHECK:STDERR:
   Feed(Animal & Climbs);
 }

+ 2 - 2
toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon

@@ -21,7 +21,7 @@ class Goat {}
 impl Goat as Animal {}
 impl Goat as Eats {}
 
-fn Feed(e:! Eats) {}
+fn Feed(unused e:! Eats) {}
 
 fn F() {
   //@dump-sem-ir-begin
@@ -83,7 +83,7 @@ class C(A:! J, B:! A) {}
 // referring to the same symbolic type and with the same facet type.
 // Essentially, it allows lossless round trips through a FacetAccessType when
 // converting back to the type of its original facet value.
-fn G[A:! J, B:! A](x: C(A, B)) {}
+fn G[A:! J, B:! A](unused x: C(A, B)) {}
 
 fn F[A:! J, B:! A](x: C(A, B)) {
   //@dump-sem-ir-begin

Some files were not shown because too many files changed in this diff