Просмотр исходного кода

Represent integer literals as `IntLiteral` not as `i32`. (#4532)

When an `IntLiteral` appears as an operand of an `if` expression,
convert it to `i32` for now, so that we don't reject things like `if
cond then 1 else 2` due to having a non-constant value of type
`IntLiteral`.

For tuple indexing expressions such as `(a, b).0`, convert the index to
type `IntLiteral`, not to type `i32`. This isn't strictly necessary to
do in this PR, but avoids the need to provide an `IntLiteral` -> `i32`
implicit conversion for `no_prelude` tests using this syntax.
Richard Smith 1 год назад
Родитель
Сommit
bc395eb889
100 измененных файлов с 7450 добавлено и 3797 удалено
  1. 1 1
      examples/sieve.carbon
  2. 16 0
      toolchain/check/handle_if_expr.cpp
  3. 2 30
      toolchain/check/handle_literal.cpp
  4. 15 6
      toolchain/check/member_access.cpp
  5. 13 25
      toolchain/check/testdata/array/array_in_place.carbon
  6. 72 48
      toolchain/check/testdata/array/array_vs_tuple.carbon
  7. 21 20
      toolchain/check/testdata/array/assign_return_value.carbon
  8. 47 35
      toolchain/check/testdata/array/assign_var.carbon
  9. 57 71
      toolchain/check/testdata/array/base.carbon
  10. 100 69
      toolchain/check/testdata/array/canonicalize_index.carbon
  11. 26 15
      toolchain/check/testdata/array/fail_bound_negative.carbon
  12. 13 17
      toolchain/check/testdata/array/fail_bound_overflow.carbon
  13. 10 22
      toolchain/check/testdata/array/fail_incomplete_element.carbon
  14. 6 17
      toolchain/check/testdata/array/fail_invalid_type.carbon
  15. 13 25
      toolchain/check/testdata/array/fail_out_of_bound.carbon
  16. 58 42
      toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon
  17. 56 70
      toolchain/check/testdata/array/fail_type_mismatch.carbon
  18. 62 46
      toolchain/check/testdata/array/function_param.carbon
  19. 11 23
      toolchain/check/testdata/array/generic_empty.carbon
  20. 58 42
      toolchain/check/testdata/array/index_not_literal.carbon
  21. 107 60
      toolchain/check/testdata/array/nine_elements.carbon
  22. 129 64
      toolchain/check/testdata/as/adapter_conversion.carbon
  23. 16 4
      toolchain/check/testdata/as/basic.carbon
  24. 4 4
      toolchain/check/testdata/as/fail_no_conversion.carbon
  25. 6 6
      toolchain/check/testdata/as/fail_not_type.carbon
  26. 16 6
      toolchain/check/testdata/as/overloaded.carbon
  27. 21 10
      toolchain/check/testdata/basics/builtin_types.carbon
  28. 4 4
      toolchain/check/testdata/basics/fail_non_type_as_type.carbon
  29. 42 13
      toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon
  30. 104 86
      toolchain/check/testdata/basics/numeric_literals.carbon
  31. 24 7
      toolchain/check/testdata/basics/parens.carbon
  32. 16 4
      toolchain/check/testdata/basics/run_i32.carbon
  33. 43 13
      toolchain/check/testdata/builtins/float/make_type.carbon
  34. 46 33
      toolchain/check/testdata/builtins/int/and.carbon
  35. 50 37
      toolchain/check/testdata/builtins/int/complement.carbon
  36. 510 300
      toolchain/check/testdata/builtins/int/convert_checked.carbon
  37. 43 14
      toolchain/check/testdata/builtins/int/eq.carbon
  38. 98 37
      toolchain/check/testdata/builtins/int/greater.carbon
  39. 98 37
      toolchain/check/testdata/builtins/int/greater_eq.carbon
  40. 185 75
      toolchain/check/testdata/builtins/int/left_shift.carbon
  41. 98 37
      toolchain/check/testdata/builtins/int/less.carbon
  42. 98 37
      toolchain/check/testdata/builtins/int/less_eq.carbon
  43. 17 6
      toolchain/check/testdata/builtins/int/make_type_32.carbon
  44. 294 183
      toolchain/check/testdata/builtins/int/make_type_signed.carbon
  45. 155 90
      toolchain/check/testdata/builtins/int/make_type_unsigned.carbon
  46. 43 14
      toolchain/check/testdata/builtins/int/neq.carbon
  47. 46 33
      toolchain/check/testdata/builtins/int/or.carbon
  48. 219 134
      toolchain/check/testdata/builtins/int/right_shift.carbon
  49. 148 63
      toolchain/check/testdata/builtins/int/sadd.carbon
  50. 177 86
      toolchain/check/testdata/builtins/int/sdiv.carbon
  51. 178 87
      toolchain/check/testdata/builtins/int/smod.carbon
  52. 93 49
      toolchain/check/testdata/builtins/int/smul.carbon
  53. 132 72
      toolchain/check/testdata/builtins/int/snegate.carbon
  54. 129 63
      toolchain/check/testdata/builtins/int/ssub.carbon
  55. 148 63
      toolchain/check/testdata/builtins/int/uadd.carbon
  56. 178 87
      toolchain/check/testdata/builtins/int/udiv.carbon
  57. 178 87
      toolchain/check/testdata/builtins/int/umod.carbon
  58. 93 49
      toolchain/check/testdata/builtins/int/umul.carbon
  59. 132 72
      toolchain/check/testdata/builtins/int/unegate.carbon
  60. 129 63
      toolchain/check/testdata/builtins/int/usub.carbon
  61. 46 33
      toolchain/check/testdata/builtins/int/xor.carbon
  62. 28 9
      toolchain/check/testdata/builtins/print.carbon
  63. 103 38
      toolchain/check/testdata/class/access_modifers.carbon
  64. 36 18
      toolchain/check/testdata/class/base.carbon
  65. 29 18
      toolchain/check/testdata/class/base_method.carbon
  66. 16 4
      toolchain/check/testdata/class/basic.carbon
  67. 52 28
      toolchain/check/testdata/class/derived_to_base.carbon
  68. 6 6
      toolchain/check/testdata/class/fail_abstract.carbon
  69. 8 8
      toolchain/check/testdata/class/fail_adapt_bad_decl.carbon
  70. 4 4
      toolchain/check/testdata/class/fail_base_bad_type.carbon
  71. 3 3
      toolchain/check/testdata/class/fail_convert_to_invalid.carbon
  72. 29 10
      toolchain/check/testdata/class/fail_field_modifiers.carbon
  73. 30 19
      toolchain/check/testdata/class/fail_init.carbon
  74. 33 15
      toolchain/check/testdata/class/fail_init_as_inplace.carbon
  75. 16 4
      toolchain/check/testdata/class/fail_scope.carbon
  76. 2 2
      toolchain/check/testdata/class/fail_self_param.carbon
  77. 24 7
      toolchain/check/testdata/class/field_access.carbon
  78. 24 7
      toolchain/check/testdata/class/field_access_in_value.carbon
  79. 54 35
      toolchain/check/testdata/class/generic/call.carbon
  80. 998 38
      toolchain/check/testdata/class/generic/import.carbon
  81. 57 40
      toolchain/check/testdata/class/import.carbon
  82. 44 21
      toolchain/check/testdata/class/import_base.carbon
  83. 71 32
      toolchain/check/testdata/class/inheritance_access.carbon
  84. 64 29
      toolchain/check/testdata/class/init_adapt.carbon
  85. 33 15
      toolchain/check/testdata/class/init_as.carbon
  86. 23 11
      toolchain/check/testdata/class/method.carbon
  87. 16 4
      toolchain/check/testdata/class/reorder.carbon
  88. 66 33
      toolchain/check/testdata/class/reorder_qualified.carbon
  89. 26 7
      toolchain/check/testdata/class/scope.carbon
  90. 25 14
      toolchain/check/testdata/class/self_conversion.carbon
  91. 58 24
      toolchain/check/testdata/class/syntactic_merge_literal.carbon
  92. 122 154
      toolchain/check/testdata/deduce/array.carbon
  93. 49 37
      toolchain/check/testdata/deduce/generic_type.carbon
  94. 36 16
      toolchain/check/testdata/deduce/tuple.carbon
  95. 136 112
      toolchain/check/testdata/eval/aggregate.carbon
  96. 76 58
      toolchain/check/testdata/eval/fail_aggregate.carbon
  97. 7 19
      toolchain/check/testdata/eval/symbolic.carbon
  98. 2 2
      toolchain/check/testdata/expr_category/in_place_tuple_init.carbon
  99. 39 21
      toolchain/check/testdata/function/builtin/call.carbon
  100. 55 29
      toolchain/check/testdata/function/builtin/method.carbon

+ 1 - 1
examples/sieve.carbon

@@ -98,7 +98,7 @@ class Sieve {
   }
 
   fn MarkMultiplesNotPrime[addr self: Self*](p: i32) {
-    var n: i32 = 2 * p;
+    var n: i32 = p * 2;
     while (n < 1000) {
       self->is_prime[n] = false;
       n += p;

+ 16 - 0
toolchain/check/handle_if_expr.cpp

@@ -5,6 +5,7 @@
 #include "toolchain/check/context.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/handle.h"
+#include "toolchain/sem_ir/builtin_inst_kind.h"
 
 namespace Carbon::Check {
 
@@ -30,12 +31,27 @@ auto HandleParseNode(Context& context, Parse::IfExprIfId node_id) -> bool {
   return true;
 }
 
+// If the operand is an `IntLiteral`, convert it to a suitably-sized `Int` type.
+// TODO: For now we always pick `i32`.
+static auto DecayIntLiteralToSizedInt(Context& context, Parse::NodeId node_id,
+                                      SemIR::InstId operand_id)
+    -> SemIR::InstId {
+  if (context.types().GetInstId(context.insts().Get(operand_id).type_id()) ==
+      SemIR::InstId::BuiltinIntLiteralType) {
+    operand_id = ConvertToValueOfType(
+        context, node_id, operand_id,
+        context.GetBuiltinType(SemIR::BuiltinInstKind::IntType));
+  }
+  return operand_id;
+}
+
 auto HandleParseNode(Context& context, Parse::IfExprThenId node_id) -> bool {
   auto then_value_id = context.node_stack().PopExpr();
   auto else_block_id = context.node_stack().Peek<Parse::NodeKind::IfExprIf>();
 
   // Convert the first operand to a value.
   then_value_id = ConvertToValueExpr(context, then_value_id);
+  then_value_id = DecayIntLiteralToSizedInt(context, node_id, then_value_id);
 
   // Start emitting the `else` block.
   context.inst_block_stack().Push(else_block_id);

+ 2 - 30
toolchain/check/handle_literal.cpp

@@ -28,37 +28,11 @@ auto HandleParseNode(Context& context, Parse::BoolLiteralTrueId node_id)
   return true;
 }
 
-// Forms an IntValue instruction with type `i32` for a given literal integer
-// value, which is assumed to be unsigned.
-static auto MakeI32Literal(Context& context, Parse::NodeId node_id,
-                           IntId int_id) -> SemIR::InstId {
-  auto val = context.ints().Get(int_id);
-  CARBON_CHECK(val.isNonNegative(),
-               "Unexpected negative literal from the lexer: {0}", val);
-
-  // Make sure the value fits in an `i32`.
-  if (val.getSignificantBits() > 32) {
-    CARBON_DIAGNOSTIC(IntLiteralTooLargeForI32, Error,
-                      "integer literal with value {0} does not fit in i32",
-                      llvm::APInt);
-    context.emitter().Emit(node_id, IntLiteralTooLargeForI32, val);
-    return SemIR::InstId::BuiltinError;
-  }
-
-  // We directly reuse the integer ID as it represents the canonical value.
-  return context.AddInst<SemIR::IntValue>(
-      node_id,
-      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::IntType),
-       .int_id = int_id});
-}
-
 // Forms an IntValue instruction with type `IntLiteral` for a given literal
 // integer value, which is assumed to be unsigned.
 static auto MakeIntLiteral(Context& context, Parse::NodeId node_id,
                            IntId int_id) -> SemIR::InstId {
-  // TODO: `IntId`s with different bit-widths are considered different values
-  // here. Decide how we want to canonicalize these. For now this is only used
-  // by type literals, so we rely on the lexer picking some consistent rule.
+  // We rely on the lexer having normalized the `int_id` to a canonical width.
   return context.AddInst<SemIR::IntValue>(
       node_id, {.type_id = context.GetBuiltinType(
                     SemIR::BuiltinInstKind::IntLiteralType),
@@ -66,9 +40,7 @@ static auto MakeIntLiteral(Context& context, Parse::NodeId node_id,
 }
 
 auto HandleParseNode(Context& context, Parse::IntLiteralId node_id) -> bool {
-  // Convert the literal to i32.
-  // TODO: Form an integer literal value and a corresponding type here instead.
-  auto int_literal_id = MakeI32Literal(
+  auto int_literal_id = MakeIntLiteral(
       context, node_id,
       context.tokens().GetIntLiteral(context.parse_tree().node_token(node_id)));
   context.node_stack().Push(node_id, int_literal_id);

+ 15 - 6
toolchain/check/member_access.cpp

@@ -464,20 +464,29 @@ auto PerformTupleAccess(Context& context, SemIR::LocId loc_id,
     return SemIR::InstId::BuiltinError;
   }
 
+  auto diag_non_constant_index = [&] {
+    // TODO: Decide what to do if the index is a symbolic constant.
+    CARBON_DIAGNOSTIC(TupleIndexNotConstant, Error,
+                      "tuple index must be a constant");
+    context.emitter().Emit(loc_id, TupleIndexNotConstant);
+    return SemIR::InstId::BuiltinError;
+  };
+  // Diagnose a non-constant index prior to conversion to IntLiteral, because
+  // the conversion will fail if the index is not constant.
+  if (!context.constant_values().Get(index_inst_id).is_template()) {
+    return diag_non_constant_index();
+  }
+
   SemIR::TypeId element_type_id = SemIR::TypeId::Error;
   auto index_node_id = context.insts().GetLocId(index_inst_id);
   index_inst_id = ConvertToValueOfType(
       context, index_node_id, index_inst_id,
-      context.GetBuiltinType(SemIR::BuiltinInstKind::IntType));
+      context.GetBuiltinType(SemIR::BuiltinInstKind::IntLiteralType));
   auto index_const_id = context.constant_values().Get(index_inst_id);
   if (index_const_id == SemIR::ConstantId::Error) {
     return SemIR::InstId::BuiltinError;
   } else if (!index_const_id.is_template()) {
-    // TODO: Decide what to do if the index is a symbolic constant.
-    CARBON_DIAGNOSTIC(TupleIndexNotConstant, Error,
-                      "tuple index must be a constant");
-    context.emitter().Emit(loc_id, TupleIndexNotConstant);
-    return SemIR::InstId::BuiltinError;
+    return diag_non_constant_index();
   }
 
   auto index_literal = context.insts().GetAs<SemIR::IntValue>(

+ 13 - 25
toolchain/check/testdata/array/array_in_place.carbon

@@ -25,23 +25,16 @@ fn G() {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 2 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, %tuple.type.2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, %tuple.type.2 [template]
 // CHECK:STDOUT:   %tuple.type.3: type = tuple_type (%tuple.type.2, %tuple.type.2) [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.6: i32 = int_value 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref.1
-// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Int32 = %import_ref
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -83,7 +76,7 @@ fn G() {
 // CHECK:STDOUT:   %int.make_type_32.loc14_17: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %int.make_type_32.loc14_22: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc14_25.1: %tuple.type.1 = tuple_literal (%int.make_type_32.loc14_12, %int.make_type_32.loc14_17, %int.make_type_32.loc14_22)
-// CHECK:STDOUT:   %.loc14_28.1: i32 = int_value 2 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc14_28: Core.IntLiteral = int_value 2 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc14_25.2: type = value_of_initializer %int.make_type_32.loc14_12 [template = i32]
 // CHECK:STDOUT:   %.loc14_25.3: type = converted %int.make_type_32.loc14_12, %.loc14_25.2 [template = i32]
 // CHECK:STDOUT:   %.loc14_25.4: type = value_of_initializer %int.make_type_32.loc14_17 [template = i32]
@@ -91,29 +84,24 @@ fn G() {
 // CHECK:STDOUT:   %.loc14_25.6: type = value_of_initializer %int.make_type_32.loc14_22 [template = i32]
 // CHECK:STDOUT:   %.loc14_25.7: type = converted %int.make_type_32.loc14_22, %.loc14_25.6 [template = i32]
 // CHECK:STDOUT:   %.loc14_25.8: type = converted %.loc14_25.1, constants.%tuple.type.2 [template = constants.%tuple.type.2]
-// CHECK:STDOUT:   %.loc14_28.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc14_28.3: <bound method> = bound_method %.loc14_28.1, %.loc14_28.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc14_28.3(%.loc14_28.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_28.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_28.5: Core.IntLiteral = converted %.loc14_28.1, %.loc14_28.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_29: type = array_type %.loc14_28.5, %tuple.type.2 [template = constants.%.28]
-// CHECK:STDOUT:   %v.var: ref %.28 = var v
-// CHECK:STDOUT:   %v: ref %.28 = bind_name v, %v.var
+// CHECK:STDOUT:   %.loc14_29: type = array_type %.loc14_28, %tuple.type.2 [template = constants.%.2]
+// CHECK:STDOUT:   %v.var: ref %.2 = var v
+// CHECK:STDOUT:   %v: ref %.2 = bind_name v, %v.var
 // CHECK:STDOUT:   %F.ref.loc14_34: %F.type = name_ref F, file.%F.decl [template = constants.%F]
 // CHECK:STDOUT:   %.loc14_42.3: ref %tuple.type.2 = splice_block %.loc14_42.2 {
-// CHECK:STDOUT:     %.loc14_42.1: i32 = int_value 0 [template = constants.%.31]
+// CHECK:STDOUT:     %.loc14_42.1: i32 = int_value 0 [template = constants.%.5]
 // CHECK:STDOUT:     %.loc14_42.2: ref %tuple.type.2 = array_index %v.var, %.loc14_42.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.call.loc14_35: init %tuple.type.2 = call %F.ref.loc14_34() to %.loc14_42.3
 // CHECK:STDOUT:   %F.ref.loc14_39: %F.type = name_ref F, file.%F.decl [template = constants.%F]
 // CHECK:STDOUT:   %.loc14_42.6: ref %tuple.type.2 = splice_block %.loc14_42.5 {
-// CHECK:STDOUT:     %.loc14_42.4: i32 = int_value 1 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc14_42.4: i32 = int_value 1 [template = constants.%.6]
 // CHECK:STDOUT:     %.loc14_42.5: ref %tuple.type.2 = array_index %v.var, %.loc14_42.4
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.call.loc14_40: init %tuple.type.2 = call %F.ref.loc14_39() to %.loc14_42.6
 // CHECK:STDOUT:   %.loc14_42.7: %tuple.type.3 = tuple_literal (%F.call.loc14_35, %F.call.loc14_40)
-// CHECK:STDOUT:   %.loc14_42.8: init %.28 = array_init (%F.call.loc14_35, %F.call.loc14_40) to %v.var
-// CHECK:STDOUT:   %.loc14_43: init %.28 = converted %.loc14_42.7, %.loc14_42.8
+// CHECK:STDOUT:   %.loc14_42.8: init %.2 = array_init (%F.call.loc14_35, %F.call.loc14_40) to %v.var
+// CHECK:STDOUT:   %.loc14_43: init %.2 = converted %.loc14_42.7, %.loc14_42.8
 // CHECK:STDOUT:   assign %v.var, %.loc14_43
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 72 - 48
toolchain/check/testdata/array/array_vs_tuple.carbon

@@ -21,21 +21,26 @@ fn G() {
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.6: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %array: %.28 = tuple_value (%.30, %.31, %.1) [template]
+// CHECK:STDOUT:   %.30: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %array: %.2 = tuple_value (%.32, %.34, %.36) [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (type, type, type) [template]
-// CHECK:STDOUT:   %tuple: %tuple.type.1 = tuple_value (%.30, %.31, %.1) [template]
+// CHECK:STDOUT:   %tuple.type.3: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %tuple: %tuple.type.3 = tuple_value (%.32, %.34, %.36) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -59,32 +64,39 @@ fn G() {
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %int.make_type_32.loc13: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc13_16.1: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc13_16: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc13_11.1: type = value_of_initializer %int.make_type_32.loc13 [template = i32]
 // CHECK:STDOUT:   %.loc13_11.2: type = converted %int.make_type_32.loc13, %.loc13_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc13_16.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc13_16.3: <bound method> = bound_method %.loc13_16.1, %.loc13_16.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc13_16.3(%.loc13_16.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc13_16.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:   %.loc13_16.5: Core.IntLiteral = converted %.loc13_16.1, %.loc13_16.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc13_17: type = array_type %.loc13_16.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %a.var: ref %.28 = var a
-// CHECK:STDOUT:   %a: ref %.28 = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc13_22: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc13_25: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_28: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc13_17: type = array_type %.loc13_16, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %a.var: ref %.2 = var a
+// CHECK:STDOUT:   %a: ref %.2 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc13_22: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc13_25: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc13_28: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc13_29.1: %tuple.type.1 = tuple_literal (%.loc13_22, %.loc13_25, %.loc13_28)
-// CHECK:STDOUT:   %.loc13_29.2: i32 = int_value 0 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc13_29.3: ref i32 = array_index %a.var, %.loc13_29.2
-// CHECK:STDOUT:   %.loc13_29.4: init i32 = initialize_from %.loc13_22 to %.loc13_29.3 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc13_29.5: i32 = int_value 1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc13_29.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_29.3: <bound method> = bound_method %.loc13_22, %.loc13_29.2 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc13_29.1: init i32 = call %.loc13_29.3(%.loc13_22) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc13_29.4: init i32 = converted %.loc13_22, %int.convert_checked.loc13_29.1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc13_29.5: i32 = int_value 0 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc13_29.6: ref i32 = array_index %a.var, %.loc13_29.5
-// CHECK:STDOUT:   %.loc13_29.7: init i32 = initialize_from %.loc13_25 to %.loc13_29.6 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_29.8: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_29.9: ref i32 = array_index %a.var, %.loc13_29.8
-// CHECK:STDOUT:   %.loc13_29.10: init i32 = initialize_from %.loc13_28 to %.loc13_29.9 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc13_29.11: init %.28 = array_init (%.loc13_29.4, %.loc13_29.7, %.loc13_29.10) to %a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc13_30: init %.28 = converted %.loc13_29.1, %.loc13_29.11 [template = constants.%array]
+// CHECK:STDOUT:   %.loc13_29.7: init i32 = initialize_from %.loc13_29.4 to %.loc13_29.6 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc13_29.8: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_29.9: <bound method> = bound_method %.loc13_25, %.loc13_29.8 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc13_29.2: init i32 = call %.loc13_29.9(%.loc13_25) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_29.10: init i32 = converted %.loc13_25, %int.convert_checked.loc13_29.2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_29.11: i32 = int_value 1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc13_29.12: ref i32 = array_index %a.var, %.loc13_29.11
+// CHECK:STDOUT:   %.loc13_29.13: init i32 = initialize_from %.loc13_29.10 to %.loc13_29.12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_29.14: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_29.15: <bound method> = bound_method %.loc13_28, %.loc13_29.14 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc13_29.3: init i32 = call %.loc13_29.15(%.loc13_28) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_29.16: init i32 = converted %.loc13_28, %int.convert_checked.loc13_29.3 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_29.17: i32 = int_value 2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_29.18: ref i32 = array_index %a.var, %.loc13_29.17
+// CHECK:STDOUT:   %.loc13_29.19: init i32 = initialize_from %.loc13_29.16 to %.loc13_29.18 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_29.20: init %.2 = array_init (%.loc13_29.7, %.loc13_29.13, %.loc13_29.19) to %a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc13_30: init %.2 = converted %.loc13_29.1, %.loc13_29.20 [template = constants.%array]
 // CHECK:STDOUT:   assign %a.var, %.loc13_30
 // CHECK:STDOUT:   %int.make_type_32.loc14_11: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %int.make_type_32.loc14_16: init type = call constants.%Int32() [template = i32]
@@ -96,21 +108,33 @@ fn G() {
 // CHECK:STDOUT:   %.loc14_24.5: type = converted %int.make_type_32.loc14_16, %.loc14_24.4 [template = i32]
 // CHECK:STDOUT:   %.loc14_24.6: type = value_of_initializer %int.make_type_32.loc14_21 [template = i32]
 // CHECK:STDOUT:   %.loc14_24.7: type = converted %int.make_type_32.loc14_21, %.loc14_24.6 [template = i32]
-// CHECK:STDOUT:   %.loc14_24.8: type = converted %.loc14_24.1, constants.%tuple.type.1 [template = constants.%tuple.type.1]
-// CHECK:STDOUT:   %b.var: ref %tuple.type.1 = var b
-// CHECK:STDOUT:   %b: ref %tuple.type.1 = bind_name b, %b.var
-// CHECK:STDOUT:   %.loc14_29: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc14_32: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc14_35: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc14_24.8: type = converted %.loc14_24.1, constants.%tuple.type.3 [template = constants.%tuple.type.3]
+// CHECK:STDOUT:   %b.var: ref %tuple.type.3 = var b
+// CHECK:STDOUT:   %b: ref %tuple.type.3 = bind_name b, %b.var
+// CHECK:STDOUT:   %.loc14_29: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc14_32: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14_35: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc14_36.1: %tuple.type.1 = tuple_literal (%.loc14_29, %.loc14_32, %.loc14_35)
-// CHECK:STDOUT:   %.loc14_36.2: ref i32 = tuple_access %b.var, element0
-// CHECK:STDOUT:   %.loc14_36.3: init i32 = initialize_from %.loc14_29 to %.loc14_36.2 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc14_36.4: ref i32 = tuple_access %b.var, element1
-// CHECK:STDOUT:   %.loc14_36.5: init i32 = initialize_from %.loc14_32 to %.loc14_36.4 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc14_36.6: ref i32 = tuple_access %b.var, element2
-// CHECK:STDOUT:   %.loc14_36.7: init i32 = initialize_from %.loc14_35 to %.loc14_36.6 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc14_36.8: init %tuple.type.1 = tuple_init (%.loc14_36.3, %.loc14_36.5, %.loc14_36.7) to %b.var [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc14_37: init %tuple.type.1 = converted %.loc14_36.1, %.loc14_36.8 [template = constants.%tuple]
+// CHECK:STDOUT:   %.loc14_36.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_36.3: <bound method> = bound_method %.loc14_29, %.loc14_36.2 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc14_36.1: init i32 = call %.loc14_36.3(%.loc14_29) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_36.4: init i32 = converted %.loc14_29, %int.convert_checked.loc14_36.1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_36.5: ref i32 = tuple_access %b.var, element0
+// CHECK:STDOUT:   %.loc14_36.6: init i32 = initialize_from %.loc14_36.4 to %.loc14_36.5 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_36.7: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_36.8: <bound method> = bound_method %.loc14_32, %.loc14_36.7 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc14_36.2: init i32 = call %.loc14_36.8(%.loc14_32) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc14_36.9: init i32 = converted %.loc14_32, %int.convert_checked.loc14_36.2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc14_36.10: ref i32 = tuple_access %b.var, element1
+// CHECK:STDOUT:   %.loc14_36.11: init i32 = initialize_from %.loc14_36.9 to %.loc14_36.10 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc14_36.12: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_36.13: <bound method> = bound_method %.loc14_35, %.loc14_36.12 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc14_36.3: init i32 = call %.loc14_36.13(%.loc14_35) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_36.14: init i32 = converted %.loc14_35, %int.convert_checked.loc14_36.3 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_36.15: ref i32 = tuple_access %b.var, element2
+// CHECK:STDOUT:   %.loc14_36.16: init i32 = initialize_from %.loc14_36.14 to %.loc14_36.15 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_36.17: init %tuple.type.3 = tuple_init (%.loc14_36.6, %.loc14_36.11, %.loc14_36.16) to %b.var [template = constants.%tuple]
+// CHECK:STDOUT:   %.loc14_37: init %tuple.type.3 = converted %.loc14_36.1, %.loc14_36.17 [template = constants.%tuple]
 // CHECK:STDOUT:   assign %b.var, %.loc14_37
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 21 - 20
toolchain/check/testdata/array/assign_return_value.carbon

@@ -23,16 +23,17 @@ fn Run() {
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (i32) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %tuple: %tuple.type.2 = tuple_value (%.1) [template]
-// CHECK:STDOUT:   %Run.type: type = fn_type @Run [template]
-// CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %tuple.type.3: type = tuple_type (Core.IntLiteral) [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.27: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %tuple: %tuple.type.2 = tuple_value (%.27) [template]
+// CHECK:STDOUT:   %Run.type: type = fn_type @Run [template]
+// CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
 // CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 1 [template]
 // CHECK:STDOUT:   %.29: type = array_type %.28, i32 [template]
 // CHECK:STDOUT: }
@@ -70,25 +71,25 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> %tuple.type.2 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_28: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_30: %tuple.type.2 = tuple_literal (%.loc11_28)
-// CHECK:STDOUT:   %tuple: %tuple.type.2 = tuple_value (%.loc11_28) [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc11_31: %tuple.type.2 = converted %.loc11_30, %tuple [template = constants.%tuple]
+// CHECK:STDOUT:   %.loc11_28: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_30.1: %tuple.type.3 = tuple_literal (%.loc11_28)
+// CHECK:STDOUT:   %.loc11_30.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_30.3: <bound method> = bound_method %.loc11_28, %.loc11_30.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc11_30.3(%.loc11_28) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc11_30.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc11_30.5: i32 = converted %.loc11_28, %.loc11_30.4 [template = constants.%.27]
+// CHECK:STDOUT:   %tuple: %tuple.type.2 = tuple_value (%.loc11_30.5) [template = constants.%tuple]
+// CHECK:STDOUT:   %.loc11_31: %tuple.type.2 = converted %.loc11_30.1, %tuple [template = constants.%tuple]
 // CHECK:STDOUT:   return %.loc11_31
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc14_16.1: i32 = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc14_16: Core.IntLiteral = int_value 1 [template = constants.%.28]
 // CHECK:STDOUT:   %.loc14_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc14_11.2: type = converted %int.make_type_32, %.loc14_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc14_16.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc14_16.3: <bound method> = bound_method %.loc14_16.1, %.loc14_16.2 [template = constants.%.27]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc14_16.3(%.loc14_16.1) [template = constants.%.28]
-// CHECK:STDOUT:   %.loc14_16.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.28]
-// CHECK:STDOUT:   %.loc14_16.5: Core.IntLiteral = converted %.loc14_16.1, %.loc14_16.4 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc14_17: type = array_type %.loc14_16.5, i32 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc14_17: type = array_type %.loc14_16, i32 [template = constants.%.29]
 // CHECK:STDOUT:   %t.var: ref %.29 = var t
 // CHECK:STDOUT:   %t: ref %.29 = bind_name t, %t.var
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
@@ -97,7 +98,7 @@ fn Run() {
 // CHECK:STDOUT:   %.loc14_22.2: ref %tuple.type.2 = temporary %.loc14_22.1, %F.call
 // CHECK:STDOUT:   %.loc14_22.3: ref i32 = tuple_access %.loc14_22.2, element0
 // CHECK:STDOUT:   %.loc14_22.4: i32 = bind_value %.loc14_22.3
-// CHECK:STDOUT:   %.loc14_22.5: i32 = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc14_22.5: i32 = int_value 0 [template = constants.%.27]
 // CHECK:STDOUT:   %.loc14_22.6: ref i32 = array_index %t.var, %.loc14_22.5
 // CHECK:STDOUT:   %.loc14_22.7: init i32 = initialize_from %.loc14_22.4 to %.loc14_22.6
 // CHECK:STDOUT:   %.loc14_22.8: init %.29 = array_init (%.loc14_22.7) to %t.var

+ 47 - 35
toolchain/check/testdata/array/assign_var.carbon

@@ -18,18 +18,23 @@ var b: [i32; 3] = a;
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %tuple.type.1: type = tuple_type (type, type, type) [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %tuple: %tuple.type.2 = tuple_value (%.2, %.3, %.4) [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %tuple.type.3: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
 // CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.29: <bound method> = bound_method %.4, %Convert.15 [template]
-// CHECK:STDOUT:   %.30: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.31: type = array_type %.30, i32 [template]
-// CHECK:STDOUT:   %.33: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.3, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %tuple: %tuple.type.2 = tuple_value (%.30, %.32, %.34) [template]
+// CHECK:STDOUT:   %.35: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -62,52 +67,59 @@ var b: [i32; 3] = a;
 // CHECK:STDOUT:   %a.var: ref %tuple.type.2 = var a
 // CHECK:STDOUT:   %a: ref %tuple.type.2 = bind_name a, %a.var
 // CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc12_14.1: i32 = int_value 3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_14: Core.IntLiteral = int_value 3 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc12_9.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
 // CHECK:STDOUT:   %.loc12_9.2: type = converted %int.make_type_32.loc12, %.loc12_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc12_14.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc12_14.3: <bound method> = bound_method %.loc12_14.1, %.loc12_14.2 [template = constants.%.29]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc12_14.3(%.loc12_14.1) [template = constants.%.30]
-// CHECK:STDOUT:   %.loc12_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.30]
-// CHECK:STDOUT:   %.loc12_14.5: Core.IntLiteral = converted %.loc12_14.1, %.loc12_14.4 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc12_15: type = array_type %.loc12_14.5, i32 [template = constants.%.31]
-// CHECK:STDOUT:   %b.var: ref %.31 = var b
-// CHECK:STDOUT:   %b: ref %.31 = bind_name b, %b.var
+// CHECK:STDOUT:   %.loc12_15: type = array_type %.loc12_14, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %b.var: ref %.35 = var b
+// CHECK:STDOUT:   %b: ref %.35 = bind_name b, %b.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_27: i32 = int_value 1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_30: i32 = int_value 2 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_33: i32 = int_value 3 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_34.1: %tuple.type.2 = tuple_literal (%.loc11_27, %.loc11_30, %.loc11_33)
-// CHECK:STDOUT:   %.loc11_34.2: ref i32 = tuple_access file.%a.var, element0
-// CHECK:STDOUT:   %.loc11_34.3: init i32 = initialize_from %.loc11_27 to %.loc11_34.2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_34.4: ref i32 = tuple_access file.%a.var, element1
-// CHECK:STDOUT:   %.loc11_34.5: init i32 = initialize_from %.loc11_30 to %.loc11_34.4 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_34.6: ref i32 = tuple_access file.%a.var, element2
-// CHECK:STDOUT:   %.loc11_34.7: init i32 = initialize_from %.loc11_33 to %.loc11_34.6 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_34.8: init %tuple.type.2 = tuple_init (%.loc11_34.3, %.loc11_34.5, %.loc11_34.7) to file.%a.var [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc11_35: init %tuple.type.2 = converted %.loc11_34.1, %.loc11_34.8 [template = constants.%tuple]
+// CHECK:STDOUT:   %.loc11_27: Core.IntLiteral = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc11_30: Core.IntLiteral = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc11_33: Core.IntLiteral = int_value 3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_34.1: %tuple.type.3 = tuple_literal (%.loc11_27, %.loc11_30, %.loc11_33)
+// CHECK:STDOUT:   %.loc11_34.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_34.3: <bound method> = bound_method %.loc11_27, %.loc11_34.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc11_34.1: init i32 = call %.loc11_34.3(%.loc11_27) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_34.4: init i32 = converted %.loc11_27, %int.convert_checked.loc11_34.1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_34.5: ref i32 = tuple_access file.%a.var, element0
+// CHECK:STDOUT:   %.loc11_34.6: init i32 = initialize_from %.loc11_34.4 to %.loc11_34.5 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_34.7: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_34.8: <bound method> = bound_method %.loc11_30, %.loc11_34.7 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc11_34.2: init i32 = call %.loc11_34.8(%.loc11_30) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_34.9: init i32 = converted %.loc11_30, %int.convert_checked.loc11_34.2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_34.10: ref i32 = tuple_access file.%a.var, element1
+// CHECK:STDOUT:   %.loc11_34.11: init i32 = initialize_from %.loc11_34.9 to %.loc11_34.10 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_34.12: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_34.13: <bound method> = bound_method %.loc11_33, %.loc11_34.12 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc11_34.3: init i32 = call %.loc11_34.13(%.loc11_33) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_34.14: init i32 = converted %.loc11_33, %int.convert_checked.loc11_34.3 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_34.15: ref i32 = tuple_access file.%a.var, element2
+// CHECK:STDOUT:   %.loc11_34.16: init i32 = initialize_from %.loc11_34.14 to %.loc11_34.15 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_34.17: init %tuple.type.2 = tuple_init (%.loc11_34.6, %.loc11_34.11, %.loc11_34.16) to file.%a.var [template = constants.%tuple]
+// CHECK:STDOUT:   %.loc11_35: init %tuple.type.2 = converted %.loc11_34.1, %.loc11_34.17 [template = constants.%tuple]
 // CHECK:STDOUT:   assign file.%a.var, %.loc11_35
 // CHECK:STDOUT:   %a.ref: ref %tuple.type.2 = name_ref a, file.%a
 // CHECK:STDOUT:   %.loc12_19.1: ref i32 = tuple_access %a.ref, element0
 // CHECK:STDOUT:   %.loc12_19.2: i32 = bind_value %.loc12_19.1
-// CHECK:STDOUT:   %.loc12_19.3: i32 = int_value 0 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_19.3: i32 = int_value 0 [template = constants.%.37]
 // CHECK:STDOUT:   %.loc12_19.4: ref i32 = array_index file.%b.var, %.loc12_19.3
 // CHECK:STDOUT:   %.loc12_19.5: init i32 = initialize_from %.loc12_19.2 to %.loc12_19.4
 // CHECK:STDOUT:   %.loc12_19.6: ref i32 = tuple_access %a.ref, element1
 // CHECK:STDOUT:   %.loc12_19.7: i32 = bind_value %.loc12_19.6
-// CHECK:STDOUT:   %.loc12_19.8: i32 = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12_19.8: i32 = int_value 1 [template = constants.%.30]
 // CHECK:STDOUT:   %.loc12_19.9: ref i32 = array_index file.%b.var, %.loc12_19.8
 // CHECK:STDOUT:   %.loc12_19.10: init i32 = initialize_from %.loc12_19.7 to %.loc12_19.9
 // CHECK:STDOUT:   %.loc12_19.11: ref i32 = tuple_access %a.ref, element2
 // CHECK:STDOUT:   %.loc12_19.12: i32 = bind_value %.loc12_19.11
-// CHECK:STDOUT:   %.loc12_19.13: i32 = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_19.13: i32 = int_value 2 [template = constants.%.32]
 // CHECK:STDOUT:   %.loc12_19.14: ref i32 = array_index file.%b.var, %.loc12_19.13
 // CHECK:STDOUT:   %.loc12_19.15: init i32 = initialize_from %.loc12_19.12 to %.loc12_19.14
-// CHECK:STDOUT:   %.loc12_19.16: init %.31 = array_init (%.loc12_19.5, %.loc12_19.10, %.loc12_19.15) to file.%b.var
-// CHECK:STDOUT:   %.loc12_20: init %.31 = converted %a.ref, %.loc12_19.16
+// CHECK:STDOUT:   %.loc12_19.16: init %.35 = array_init (%.loc12_19.5, %.loc12_19.10, %.loc12_19.15) to file.%b.var
+// CHECK:STDOUT:   %.loc12_20: init %.35 = converted %a.ref, %.loc12_19.16
 // CHECK:STDOUT:   assign file.%b.var, %.loc12_20
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 57 - 71
toolchain/check/testdata/array/base.carbon

@@ -18,37 +18,34 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.4: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (i32) [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %array.1: %.28 = tuple_value (%.1) [template]
+// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %array.1: %.2 = tuple_value (%.30) [template]
 // CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 64 [template]
 // CHECK:STDOUT:   %Float.type: type = fn_type @Float [template]
 // CHECK:STDOUT:   %Float: %Float.type = struct_value () [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
-// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 2 [template]
-// CHECK:STDOUT:   %.35: type = array_type %.34, f64 [template]
-// CHECK:STDOUT:   %.37: f64 = float_literal 11.100000000000001 [template]
-// CHECK:STDOUT:   %.38: f64 = float_literal 2.2000000000000002 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.33: type = array_type %.32, f64 [template]
+// CHECK:STDOUT:   %.35: f64 = float_literal 11.100000000000001 [template]
+// CHECK:STDOUT:   %.36: f64 = float_literal 2.2000000000000002 [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (f64, f64) [template]
-// CHECK:STDOUT:   %array.2: %.35 = tuple_value (%.37, %.38) [template]
-// CHECK:STDOUT:   %.39: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.40: <bound method> = bound_method %.39, %Convert.15 [template]
-// CHECK:STDOUT:   %.41: Core.IntLiteral = int_value 5 [template]
-// CHECK:STDOUT:   %.42: type = array_type %.41, %empty_tuple.type [template]
+// CHECK:STDOUT:   %array.2: %.33 = tuple_value (%.35, %.36) [template]
+// CHECK:STDOUT:   %.37: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.38: type = array_type %.37, %empty_tuple.type [template]
 // CHECK:STDOUT:   %tuple.type.3: type = tuple_type (%empty_tuple.type, %empty_tuple.type, %empty_tuple.type, %empty_tuple.type, %empty_tuple.type) [template]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [template]
-// CHECK:STDOUT:   %.44: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.45: i32 = int_value 4 [template]
-// CHECK:STDOUT:   %array.3: %.42 = tuple_value (%empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple) [template]
+// CHECK:STDOUT:   %.40: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.41: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.42: i32 = int_value 4 [template]
+// CHECK:STDOUT:   %array.3: %.38 = tuple_value (%empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -70,64 +67,53 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc11_14.1: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_14: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc11_9.2: type = converted %int.make_type_32, %.loc11_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc11_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc11_14.3: <bound method> = bound_method %.loc11_14.1, %.loc11_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked.loc11: init Core.IntLiteral = call %.loc11_14.3(%.loc11_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc11 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_14.5: Core.IntLiteral = converted %.loc11_14.1, %.loc11_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %a.var: ref %.28 = var a
-// CHECK:STDOUT:   %a: ref %.28 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %a.var: ref %.2 = var a
+// CHECK:STDOUT:   %a: ref %.2 = bind_name a, %a.var
 // CHECK:STDOUT:   %.loc12_9.1: Core.IntLiteral = int_value 64 [template = constants.%.31]
 // CHECK:STDOUT:   %float.make_type: init type = call constants.%Float(%.loc12_9.1) [template = f64]
-// CHECK:STDOUT:   %.loc12_14.1: i32 = int_value 2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc12_14: Core.IntLiteral = int_value 2 [template = constants.%.32]
 // CHECK:STDOUT:   %.loc12_9.2: type = value_of_initializer %float.make_type [template = f64]
 // CHECK:STDOUT:   %.loc12_9.3: type = converted %float.make_type, %.loc12_9.2 [template = f64]
-// CHECK:STDOUT:   %.loc12_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc12_14.3: <bound method> = bound_method %.loc12_14.1, %.loc12_14.2 [template = constants.%.33]
-// CHECK:STDOUT:   %int.convert_checked.loc12: init Core.IntLiteral = call %.loc12_14.3(%.loc12_14.1) [template = constants.%.34]
-// CHECK:STDOUT:   %.loc12_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc12 [template = constants.%.34]
-// CHECK:STDOUT:   %.loc12_14.5: Core.IntLiteral = converted %.loc12_14.1, %.loc12_14.4 [template = constants.%.34]
-// CHECK:STDOUT:   %.loc12_15: type = array_type %.loc12_14.5, f64 [template = constants.%.35]
-// CHECK:STDOUT:   %b.var: ref %.35 = var b
-// CHECK:STDOUT:   %b: ref %.35 = bind_name b, %b.var
+// CHECK:STDOUT:   %.loc12_15: type = array_type %.loc12_14, f64 [template = constants.%.33]
+// CHECK:STDOUT:   %b.var: ref %.33 = var b
+// CHECK:STDOUT:   %b: ref %.33 = bind_name b, %b.var
 // CHECK:STDOUT:   %.loc13_10.1: %empty_tuple.type = tuple_literal ()
-// CHECK:STDOUT:   %.loc13_13.1: i32 = int_value 5 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_13: Core.IntLiteral = int_value 5 [template = constants.%.37]
 // CHECK:STDOUT:   %.loc13_10.2: type = converted %.loc13_10.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
-// CHECK:STDOUT:   %.loc13_13.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc13_13.3: <bound method> = bound_method %.loc13_13.1, %.loc13_13.2 [template = constants.%.40]
-// CHECK:STDOUT:   %int.convert_checked.loc13: init Core.IntLiteral = call %.loc13_13.3(%.loc13_13.1) [template = constants.%.41]
-// CHECK:STDOUT:   %.loc13_13.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc13 [template = constants.%.41]
-// CHECK:STDOUT:   %.loc13_13.5: Core.IntLiteral = converted %.loc13_13.1, %.loc13_13.4 [template = constants.%.41]
-// CHECK:STDOUT:   %.loc13_14: type = array_type %.loc13_13.5, %empty_tuple.type [template = constants.%.42]
-// CHECK:STDOUT:   %c.var: ref %.42 = var c
-// CHECK:STDOUT:   %c: ref %.42 = bind_name c, %c.var
+// CHECK:STDOUT:   %.loc13_14: type = array_type %.loc13_13, %empty_tuple.type [template = constants.%.38]
+// CHECK:STDOUT:   %c.var: ref %.38 = var c
+// CHECK:STDOUT:   %c: ref %.38 = bind_name c, %c.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_20: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_20: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_22.1: %tuple.type.1 = tuple_literal (%.loc11_20)
-// CHECK:STDOUT:   %.loc11_22.2: i32 = int_value 0 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc11_22.3: ref i32 = array_index file.%a.var, %.loc11_22.2
-// CHECK:STDOUT:   %.loc11_22.4: init i32 = initialize_from %.loc11_20 to %.loc11_22.3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_22.5: init %.28 = array_init (%.loc11_22.4) to file.%a.var [template = constants.%array.1]
-// CHECK:STDOUT:   %.loc11_23: init %.28 = converted %.loc11_22.1, %.loc11_22.5 [template = constants.%array.1]
+// CHECK:STDOUT:   %.loc11_22.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_22.3: <bound method> = bound_method %.loc11_20, %.loc11_22.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc11_22.3(%.loc11_20) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_22.4: init i32 = converted %.loc11_20, %int.convert_checked [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_22.5: i32 = int_value 0 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_22.6: ref i32 = array_index file.%a.var, %.loc11_22.5
+// CHECK:STDOUT:   %.loc11_22.7: init i32 = initialize_from %.loc11_22.4 to %.loc11_22.6 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_22.8: init %.2 = array_init (%.loc11_22.7) to file.%a.var [template = constants.%array.1]
+// CHECK:STDOUT:   %.loc11_23: init %.2 = converted %.loc11_22.1, %.loc11_22.8 [template = constants.%array.1]
 // CHECK:STDOUT:   assign file.%a.var, %.loc11_23
-// CHECK:STDOUT:   %.loc12_20: f64 = float_literal 11.100000000000001 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc12_26: f64 = float_literal 2.2000000000000002 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc12_20: f64 = float_literal 11.100000000000001 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc12_26: f64 = float_literal 2.2000000000000002 [template = constants.%.36]
 // CHECK:STDOUT:   %.loc12_30.1: %tuple.type.2 = tuple_literal (%.loc12_20, %.loc12_26)
-// CHECK:STDOUT:   %.loc12_30.2: i32 = int_value 0 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc12_30.2: i32 = int_value 0 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc12_30.3: ref f64 = array_index file.%b.var, %.loc12_30.2
-// CHECK:STDOUT:   %.loc12_30.4: init f64 = initialize_from %.loc12_20 to %.loc12_30.3 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc12_30.5: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_30.4: init f64 = initialize_from %.loc12_20 to %.loc12_30.3 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc12_30.5: i32 = int_value 1 [template = constants.%.30]
 // CHECK:STDOUT:   %.loc12_30.6: ref f64 = array_index file.%b.var, %.loc12_30.5
-// CHECK:STDOUT:   %.loc12_30.7: init f64 = initialize_from %.loc12_26 to %.loc12_30.6 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc12_30.8: init %.35 = array_init (%.loc12_30.4, %.loc12_30.7) to file.%b.var [template = constants.%array.2]
-// CHECK:STDOUT:   %.loc12_31: init %.35 = converted %.loc12_30.1, %.loc12_30.8 [template = constants.%array.2]
+// CHECK:STDOUT:   %.loc12_30.7: init f64 = initialize_from %.loc12_26 to %.loc12_30.6 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc12_30.8: init %.33 = array_init (%.loc12_30.4, %.loc12_30.7) to file.%b.var [template = constants.%array.2]
+// CHECK:STDOUT:   %.loc12_31: init %.33 = converted %.loc12_30.1, %.loc12_30.8 [template = constants.%array.2]
 // CHECK:STDOUT:   assign file.%b.var, %.loc12_31
 // CHECK:STDOUT:   %.loc13_20.1: %empty_tuple.type = tuple_literal ()
 // CHECK:STDOUT:   %.loc13_24.1: %empty_tuple.type = tuple_literal ()
@@ -135,28 +121,28 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT:   %.loc13_32.1: %empty_tuple.type = tuple_literal ()
 // CHECK:STDOUT:   %.loc13_36.1: %empty_tuple.type = tuple_literal ()
 // CHECK:STDOUT:   %.loc13_38.1: %tuple.type.3 = tuple_literal (%.loc13_20.1, %.loc13_24.1, %.loc13_28.1, %.loc13_32.1, %.loc13_36.1)
-// CHECK:STDOUT:   %.loc13_38.2: i32 = int_value 0 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc13_38.2: i32 = int_value 0 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc13_38.3: ref %empty_tuple.type = array_index file.%c.var, %.loc13_38.2
 // CHECK:STDOUT:   %.loc13_20.2: init %empty_tuple.type = tuple_init () to %.loc13_38.3 [template = constants.%empty_tuple]
 // CHECK:STDOUT:   %.loc13_38.4: init %empty_tuple.type = converted %.loc13_20.1, %.loc13_20.2 [template = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc13_38.5: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc13_38.5: i32 = int_value 1 [template = constants.%.30]
 // CHECK:STDOUT:   %.loc13_38.6: ref %empty_tuple.type = array_index file.%c.var, %.loc13_38.5
 // CHECK:STDOUT:   %.loc13_24.2: init %empty_tuple.type = tuple_init () to %.loc13_38.6 [template = constants.%empty_tuple]
 // CHECK:STDOUT:   %.loc13_38.7: init %empty_tuple.type = converted %.loc13_24.1, %.loc13_24.2 [template = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc13_38.8: i32 = int_value 2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc13_38.8: i32 = int_value 2 [template = constants.%.40]
 // CHECK:STDOUT:   %.loc13_38.9: ref %empty_tuple.type = array_index file.%c.var, %.loc13_38.8
 // CHECK:STDOUT:   %.loc13_28.2: init %empty_tuple.type = tuple_init () to %.loc13_38.9 [template = constants.%empty_tuple]
 // CHECK:STDOUT:   %.loc13_38.10: init %empty_tuple.type = converted %.loc13_28.1, %.loc13_28.2 [template = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc13_38.11: i32 = int_value 3 [template = constants.%.44]
+// CHECK:STDOUT:   %.loc13_38.11: i32 = int_value 3 [template = constants.%.41]
 // CHECK:STDOUT:   %.loc13_38.12: ref %empty_tuple.type = array_index file.%c.var, %.loc13_38.11
 // CHECK:STDOUT:   %.loc13_32.2: init %empty_tuple.type = tuple_init () to %.loc13_38.12 [template = constants.%empty_tuple]
 // CHECK:STDOUT:   %.loc13_38.13: init %empty_tuple.type = converted %.loc13_32.1, %.loc13_32.2 [template = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc13_38.14: i32 = int_value 4 [template = constants.%.45]
+// CHECK:STDOUT:   %.loc13_38.14: i32 = int_value 4 [template = constants.%.42]
 // CHECK:STDOUT:   %.loc13_38.15: ref %empty_tuple.type = array_index file.%c.var, %.loc13_38.14
 // CHECK:STDOUT:   %.loc13_36.2: init %empty_tuple.type = tuple_init () to %.loc13_38.15 [template = constants.%empty_tuple]
 // CHECK:STDOUT:   %.loc13_38.16: init %empty_tuple.type = converted %.loc13_36.1, %.loc13_36.2 [template = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc13_38.17: init %.42 = array_init (%.loc13_38.4, %.loc13_38.7, %.loc13_38.10, %.loc13_38.13, %.loc13_38.16) to file.%c.var [template = constants.%array.3]
-// CHECK:STDOUT:   %.loc13_39: init %.42 = converted %.loc13_38.1, %.loc13_38.17 [template = constants.%array.3]
+// CHECK:STDOUT:   %.loc13_38.17: init %.38 = array_init (%.loc13_38.4, %.loc13_38.7, %.loc13_38.10, %.loc13_38.13, %.loc13_38.16) to file.%c.var [template = constants.%array.3]
+// CHECK:STDOUT:   %.loc13_39: init %.38 = converted %.loc13_38.1, %.loc13_38.17 [template = constants.%array.3]
 // CHECK:STDOUT:   assign file.%c.var, %.loc13_39
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 100 - 69
toolchain/check/testdata/array/canonicalize_index.carbon

@@ -28,26 +28,35 @@ let c: [i32; ConvertToU32(3)]* = &a;
 // CHECK:STDOUT:   %.2: type = int_type unsigned, %.1 [template]
 // CHECK:STDOUT:   %ConvertToU32.type: type = fn_type @ConvertToU32 [template]
 // CHECK:STDOUT:   %ConvertToU32: %ConvertToU32.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.30: <bound method> = bound_method %.5, %Convert.15 [template]
-// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.32: type = array_type %.31, i32 [template]
-// CHECK:STDOUT:   %.33: type = ptr_type %.32 [template]
-// CHECK:STDOUT:   %tuple.type: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.34: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %array: %.32 = tuple_value (%.3, %.4, %.5) [template]
-// CHECK:STDOUT:   %.35: %.2 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.5, @impl.6(%.1) [template]
+// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.3, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
 // CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
-// CHECK:STDOUT:   %.37: <witness> = interface_witness (%Convert.16) [template]
-// CHECK:STDOUT:   %.38: <bound method> = bound_method %.35, %Convert.16 [template]
-// CHECK:STDOUT:   %.39: <specific function> = specific_function %.38, @Convert.5(%.1) [template]
+// CHECK:STDOUT:   %.34: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.33, %Convert.16 [template]
+// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.37: type = array_type %.36, i32 [template]
+// CHECK:STDOUT:   %.38: type = ptr_type %.37 [template]
+// CHECK:STDOUT:   %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.39: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.40: <bound method> = bound_method %.36, %Convert.15 [template]
+// CHECK:STDOUT:   %array: %.37 = tuple_value (%.30, %.32, %.33) [template]
+// CHECK:STDOUT:   %.41: %.2 = int_value 3 [template]
+// CHECK:STDOUT:   %Convert.type.17: type = fn_type @Convert.5, @impl.6(%.1) [template]
+// CHECK:STDOUT:   %Convert.17: %Convert.type.17 = struct_value () [template]
+// CHECK:STDOUT:   %.43: <witness> = interface_witness (%Convert.17) [template]
+// CHECK:STDOUT:   %.44: <bound method> = bound_method %.41, %Convert.17 [template]
+// CHECK:STDOUT:   %.45: <specific function> = specific_function %.44, @Convert.5(%.1) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -114,48 +123,58 @@ let c: [i32; ConvertToU32(3)]* = &a;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc14: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Add.ref: %Add.type = name_ref Add, %Add.decl [template = constants.%Add]
-// CHECK:STDOUT:   %.loc14_18: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc14_21: i32 = int_value 2 [template = constants.%.4]
-// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc14_18, %.loc14_21) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14_18.1: Core.IntLiteral = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc14_21.1: Core.IntLiteral = int_value 2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc14_18.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_18.3: <bound method> = bound_method %.loc14_18.1, %.loc14_18.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc14_18: init i32 = call %.loc14_18.3(%.loc14_18.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc14_18.4: i32 = value_of_initializer %int.convert_checked.loc14_18 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc14_18.5: i32 = converted %.loc14_18.1, %.loc14_18.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc14_21.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_21.3: <bound method> = bound_method %.loc14_21.1, %.loc14_21.2 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc14_21: init i32 = call %.loc14_21.3(%.loc14_21.1) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_21.4: i32 = value_of_initializer %int.convert_checked.loc14_21 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_21.5: i32 = converted %.loc14_21.1, %.loc14_21.4 [template = constants.%.32]
+// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc14_18.5, %.loc14_21.5) [template = constants.%.33]
 // CHECK:STDOUT:   %.loc14_9.1: type = value_of_initializer %int.make_type_32.loc14 [template = i32]
 // CHECK:STDOUT:   %.loc14_9.2: type = converted %int.make_type_32.loc14, %.loc14_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc14_17.1: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc14_17.2: <bound method> = bound_method %int.sadd, %.loc14_17.1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc14_17.3: i32 = value_of_initializer %int.sadd [template = constants.%.5]
-// CHECK:STDOUT:   %.loc14_17.4: i32 = converted %int.sadd, %.loc14_17.3 [template = constants.%.5]
-// CHECK:STDOUT:   %int.convert_checked.loc14: init Core.IntLiteral = call %.loc14_17.2(%.loc14_17.4) [template = constants.%.31]
-// CHECK:STDOUT:   %.loc14_17.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc14 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc14_17.6: Core.IntLiteral = converted %int.sadd, %.loc14_17.5 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc14_23: type = array_type %.loc14_17.6, i32 [template = constants.%.32]
-// CHECK:STDOUT:   %a.var: ref %.32 = var a
-// CHECK:STDOUT:   %a: ref %.32 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc14_17.1: %Convert.type.5 = interface_witness_access constants.%.34, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc14_17.2: <bound method> = bound_method %int.sadd, %.loc14_17.1 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc14_17.3: i32 = value_of_initializer %int.sadd [template = constants.%.33]
+// CHECK:STDOUT:   %.loc14_17.4: i32 = converted %int.sadd, %.loc14_17.3 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc14_17: init Core.IntLiteral = call %.loc14_17.2(%.loc14_17.4) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_17.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc14_17 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_17.6: Core.IntLiteral = converted %int.sadd, %.loc14_17.5 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_23: type = array_type %.loc14_17.6, i32 [template = constants.%.37]
+// CHECK:STDOUT:   %a.var: ref %.37 = var a
+// CHECK:STDOUT:   %a: ref %.37 = bind_name a, %a.var
 // CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc15_14.1: i32 = int_value 3 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15_14: Core.IntLiteral = int_value 3 [template = constants.%.36]
 // CHECK:STDOUT:   %.loc15_9.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
 // CHECK:STDOUT:   %.loc15_9.2: type = converted %int.make_type_32.loc15, %.loc15_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc15_14.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc15_14.3: <bound method> = bound_method %.loc15_14.1, %.loc15_14.2 [template = constants.%.30]
-// CHECK:STDOUT:   %int.convert_checked.loc15: init Core.IntLiteral = call %.loc15_14.3(%.loc15_14.1) [template = constants.%.31]
-// CHECK:STDOUT:   %.loc15_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc15 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc15_14.5: Core.IntLiteral = converted %.loc15_14.1, %.loc15_14.4 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc15_15: type = array_type %.loc15_14.5, i32 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc15_16: type = ptr_type %.32 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc15_15: type = array_type %.loc15_14, i32 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc15_16: type = ptr_type %.37 [template = constants.%.38]
 // CHECK:STDOUT:   %int.make_type_32.loc16: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %ConvertToU32.ref: %ConvertToU32.type = name_ref ConvertToU32, %ConvertToU32.decl [template = constants.%ConvertToU32]
-// CHECK:STDOUT:   %.loc16_27: i32 = int_value 3 [template = constants.%.5]
-// CHECK:STDOUT:   %int.convert_checked.loc16_26.1: init %.2 = call %ConvertToU32.ref(%.loc16_27) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc16_27.1: Core.IntLiteral = int_value 3 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc16_27.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_27.3: <bound method> = bound_method %.loc16_27.1, %.loc16_27.2 [template = constants.%.40]
+// CHECK:STDOUT:   %int.convert_checked.loc16_27: init i32 = call %.loc16_27.3(%.loc16_27.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc16_27.4: i32 = value_of_initializer %int.convert_checked.loc16_27 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc16_27.5: i32 = converted %.loc16_27.1, %.loc16_27.4 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc16_26.1: init %.2 = call %ConvertToU32.ref(%.loc16_27.5) [template = constants.%.41]
 // CHECK:STDOUT:   %.loc16_9.1: type = value_of_initializer %int.make_type_32.loc16 [template = i32]
 // CHECK:STDOUT:   %.loc16_9.2: type = converted %int.make_type_32.loc16, %.loc16_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc16_26.1: %Convert.type.2 = interface_witness_access constants.%.37, element0 [template = constants.%Convert.16]
-// CHECK:STDOUT:   %.loc16_26.2: <bound method> = bound_method %int.convert_checked.loc16_26.1, %.loc16_26.1 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc16_26.3: <specific function> = specific_function %.loc16_26.2, @Convert.5(constants.%.1) [template = constants.%.39]
-// CHECK:STDOUT:   %.loc16_26.4: %.2 = value_of_initializer %int.convert_checked.loc16_26.1 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc16_26.5: %.2 = converted %int.convert_checked.loc16_26.1, %.loc16_26.4 [template = constants.%.35]
-// CHECK:STDOUT:   %int.convert_checked.loc16_26.2: init Core.IntLiteral = call %.loc16_26.3(%.loc16_26.5) [template = constants.%.31]
-// CHECK:STDOUT:   %.loc16_26.6: Core.IntLiteral = value_of_initializer %int.convert_checked.loc16_26.2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc16_26.7: Core.IntLiteral = converted %int.convert_checked.loc16_26.1, %.loc16_26.6 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc16_29: type = array_type %.loc16_26.7, i32 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc16_30: type = ptr_type %.32 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc16_26.1: %Convert.type.5 = interface_witness_access constants.%.43, element0 [template = constants.%Convert.17]
+// CHECK:STDOUT:   %.loc16_26.2: <bound method> = bound_method %int.convert_checked.loc16_26.1, %.loc16_26.1 [template = constants.%.44]
+// CHECK:STDOUT:   %.loc16_26.3: <specific function> = specific_function %.loc16_26.2, @Convert.5(constants.%.1) [template = constants.%.45]
+// CHECK:STDOUT:   %.loc16_26.4: %.2 = value_of_initializer %int.convert_checked.loc16_26.1 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc16_26.5: %.2 = converted %int.convert_checked.loc16_26.1, %.loc16_26.4 [template = constants.%.41]
+// CHECK:STDOUT:   %int.convert_checked.loc16_26.2: init Core.IntLiteral = call %.loc16_26.3(%.loc16_26.5) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc16_26.6: Core.IntLiteral = value_of_initializer %int.convert_checked.loc16_26.2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc16_26.7: Core.IntLiteral = converted %int.convert_checked.loc16_26.1, %.loc16_26.6 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc16_29: type = array_type %.loc16_26.7, i32 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc16_30: type = ptr_type %.37 [template = constants.%.38]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Add(%a.param_patt: i32, %b.param_patt: i32) -> i32 = "int.sadd";
@@ -164,28 +183,40 @@ let c: [i32; ConvertToU32(3)]* = &a;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc14_28: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc14_31: i32 = int_value 2 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_34: i32 = int_value 3 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14_28: Core.IntLiteral = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc14_31: Core.IntLiteral = int_value 2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc14_34: Core.IntLiteral = int_value 3 [template = constants.%.36]
 // CHECK:STDOUT:   %.loc14_35.1: %tuple.type = tuple_literal (%.loc14_28, %.loc14_31, %.loc14_34)
-// CHECK:STDOUT:   %.loc14_35.2: i32 = int_value 0 [template = constants.%.34]
-// CHECK:STDOUT:   %.loc14_35.3: ref i32 = array_index file.%a.var, %.loc14_35.2
-// CHECK:STDOUT:   %.loc14_35.4: init i32 = initialize_from %.loc14_28 to %.loc14_35.3 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc14_35.5: i32 = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc14_35.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_35.3: <bound method> = bound_method %.loc14_28, %.loc14_35.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc14_35.1: init i32 = call %.loc14_35.3(%.loc14_28) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc14_35.4: init i32 = converted %.loc14_28, %int.convert_checked.loc14_35.1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc14_35.5: i32 = int_value 0 [template = constants.%.39]
 // CHECK:STDOUT:   %.loc14_35.6: ref i32 = array_index file.%a.var, %.loc14_35.5
-// CHECK:STDOUT:   %.loc14_35.7: init i32 = initialize_from %.loc14_31 to %.loc14_35.6 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_35.8: i32 = int_value 2 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_35.9: ref i32 = array_index file.%a.var, %.loc14_35.8
-// CHECK:STDOUT:   %.loc14_35.10: init i32 = initialize_from %.loc14_34 to %.loc14_35.9 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc14_35.11: init %.32 = array_init (%.loc14_35.4, %.loc14_35.7, %.loc14_35.10) to file.%a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc14_36: init %.32 = converted %.loc14_35.1, %.loc14_35.11 [template = constants.%array]
+// CHECK:STDOUT:   %.loc14_35.7: init i32 = initialize_from %.loc14_35.4 to %.loc14_35.6 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc14_35.8: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_35.9: <bound method> = bound_method %.loc14_31, %.loc14_35.8 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc14_35.2: init i32 = call %.loc14_35.9(%.loc14_31) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_35.10: init i32 = converted %.loc14_31, %int.convert_checked.loc14_35.2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_35.11: i32 = int_value 1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc14_35.12: ref i32 = array_index file.%a.var, %.loc14_35.11
+// CHECK:STDOUT:   %.loc14_35.13: init i32 = initialize_from %.loc14_35.10 to %.loc14_35.12 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_35.14: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_35.15: <bound method> = bound_method %.loc14_34, %.loc14_35.14 [template = constants.%.40]
+// CHECK:STDOUT:   %int.convert_checked.loc14_35.3: init i32 = call %.loc14_35.15(%.loc14_34) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc14_35.16: init i32 = converted %.loc14_34, %int.convert_checked.loc14_35.3 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc14_35.17: i32 = int_value 2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_35.18: ref i32 = array_index file.%a.var, %.loc14_35.17
+// CHECK:STDOUT:   %.loc14_35.19: init i32 = initialize_from %.loc14_35.16 to %.loc14_35.18 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc14_35.20: init %.37 = array_init (%.loc14_35.7, %.loc14_35.13, %.loc14_35.19) to file.%a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc14_36: init %.37 = converted %.loc14_35.1, %.loc14_35.20 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%a.var, %.loc14_36
-// CHECK:STDOUT:   %a.ref.loc15: ref %.32 = name_ref a, file.%a
-// CHECK:STDOUT:   %.loc15: %.33 = addr_of %a.ref.loc15
-// CHECK:STDOUT:   %b: %.33 = bind_name b, %.loc15
-// CHECK:STDOUT:   %a.ref.loc16: ref %.32 = name_ref a, file.%a
-// CHECK:STDOUT:   %.loc16: %.33 = addr_of %a.ref.loc16
-// CHECK:STDOUT:   %c: %.33 = bind_name c, %.loc16
+// CHECK:STDOUT:   %a.ref.loc15: ref %.37 = name_ref a, file.%a
+// CHECK:STDOUT:   %.loc15: %.38 = addr_of %a.ref.loc15
+// CHECK:STDOUT:   %b: %.38 = bind_name b, %.loc15
+// CHECK:STDOUT:   %a.ref.loc16: ref %.37 = name_ref a, file.%a
+// CHECK:STDOUT:   %.loc16: %.38 = addr_of %a.ref.loc16
+// CHECK:STDOUT:   %c: %.38 = bind_name c, %.loc16
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 26 - 15
toolchain/check/testdata/array/fail_bound_negative.carbon

@@ -22,14 +22,20 @@ var a: [i32; Negate(1)];
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.27: <bound method> = bound_method %.2, %Convert.15 [template]
-// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value -1 [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.28, %Convert.16 [template]
+// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -67,17 +73,22 @@ var a: [i32; Negate(1)];
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Negate.ref: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc16_21: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc16_21) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc16_21.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc16_21.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_21.3: <bound method> = bound_method %.loc16_21.1, %.loc16_21.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc16_21: init i32 = call %.loc16_21.3(%.loc16_21.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc16_21.4: i32 = value_of_initializer %int.convert_checked.loc16_21 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc16_21.5: i32 = converted %.loc16_21.1, %.loc16_21.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc16_21.5) [template = constants.%.28]
 // CHECK:STDOUT:   %.loc16_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc16_9.2: type = converted %int.make_type_32, %.loc16_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc16_20.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc16_20.2: <bound method> = bound_method %int.snegate, %.loc16_20.1 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc16_20.3: i32 = value_of_initializer %int.snegate [template = constants.%.2]
-// CHECK:STDOUT:   %.loc16_20.4: i32 = converted %int.snegate, %.loc16_20.3 [template = constants.%.2]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc16_20.2(%.loc16_20.4) [template = constants.%.28]
-// CHECK:STDOUT:   %.loc16_20.5: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.28]
-// CHECK:STDOUT:   %.loc16_20.6: Core.IntLiteral = converted %int.snegate, %.loc16_20.5 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc16_20.1: %Convert.type.5 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc16_20.2: <bound method> = bound_method %int.snegate, %.loc16_20.1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc16_20.3: i32 = value_of_initializer %int.snegate [template = constants.%.28]
+// CHECK:STDOUT:   %.loc16_20.4: i32 = converted %int.snegate, %.loc16_20.3 [template = constants.%.28]
+// CHECK:STDOUT:   %int.convert_checked.loc16_20: init Core.IntLiteral = call %.loc16_20.2(%.loc16_20.4) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc16_20.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc16_20 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc16_20.6: Core.IntLiteral = converted %int.snegate, %.loc16_20.5 [template = constants.%.31]
 // CHECK:STDOUT:   %.loc16_23: type = array_type %.loc16_20.6, i32 [template = <error>]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var

+ 13 - 17
toolchain/check/testdata/array/fail_bound_overflow.carbon

@@ -8,25 +8,18 @@
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_bound_overflow.carbon
 
-// TODO: Once we preserve the full value of integer literals in SemIR, check
-// that we reject the array bound being too large.
-
-// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+4]]:14: error: integer literal with value 39999999999999999993 does not fit in i32 [IntLiteralTooLargeForI32]
+// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+4]]:14: error: array bound of 39999999999999999993 is too large [ArrayBoundTooLarge]
 // CHECK:STDERR: var a: [i32; 39999999999999999993];
 // CHECK:STDERR:              ^~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 var a: [i32; 39999999999999999993];
 
-// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+10]]:9: error: cannot implicitly convert from `i32` to `type` [ImplicitAsConversionFailure]
+// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+6]]:9: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
 // CHECK:STDERR: var b: [1; 39999999999999999993];
 // CHECK:STDERR:         ^
-// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+7]]:9: note: type `i32` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+3]]:9: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: var b: [1; 39999999999999999993];
 // CHECK:STDERR:         ^
-// CHECK:STDERR:
-// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+3]]:12: error: integer literal with value 39999999999999999993 does not fit in i32 [IntLiteralTooLargeForI32]
-// CHECK:STDERR: var b: [1; 39999999999999999993];
-// CHECK:STDERR:            ^~~~~~~~~~~~~~~~~~~~
 var b: [1; 39999999999999999993];
 
 // CHECK:STDOUT: --- fail_bound_overflow.carbon
@@ -34,7 +27,8 @@ var b: [1; 39999999999999999993];
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 39999999999999999993 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -54,14 +48,16 @@ var b: [1; 39999999999999999993];
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc18_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
-// CHECK:STDOUT:   %.loc18_9.2: type = converted %int.make_type_32, %.loc18_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc18_34: type = array_type <error>, i32 [template = <error>]
+// CHECK:STDOUT:   %.loc15_14: Core.IntLiteral = int_value 39999999999999999993 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc15_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc15_9.2: type = converted %int.make_type_32, %.loc15_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc15_34: type = array_type %.loc15_14, i32 [template = <error>]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc30_9.1: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_9.2: type = converted %.loc30_9.1, <error> [template = <error>]
-// CHECK:STDOUT:   %.loc30_32: type = array_type <error>, <error> [template = <error>]
+// CHECK:STDOUT:   %.loc23_9.1: Core.IntLiteral = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc23_12: Core.IntLiteral = int_value 39999999999999999993 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc23_9.2: type = converted %.loc23_9.1, <error> [template = <error>]
+// CHECK:STDOUT:   %.loc23_32: type = array_type %.loc23_12, <error> [template = <error>]
 // CHECK:STDOUT:   %b.var: ref <error> = var b
 // CHECK:STDOUT:   %b: ref <error> = bind_name b, %b.var
 // CHECK:STDOUT: }

+ 10 - 22
toolchain/check/testdata/array/fail_incomplete_element.carbon

@@ -24,21 +24,14 @@ var p: Incomplete* = &a[0];
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, %Incomplete [template]
-// CHECK:STDOUT:   %.29: type = ptr_type %Incomplete [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, %Incomplete [template]
+// CHECK:STDOUT:   %.3: type = ptr_type %Incomplete [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .ImplicitAs = %import_ref.1
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -54,19 +47,14 @@ var p: Incomplete* = &a[0];
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Incomplete.decl: type = class_decl @Incomplete [template = constants.%Incomplete] {} {}
 // CHECK:STDOUT:   %Incomplete.ref.loc19: type = name_ref Incomplete, %Incomplete.decl [template = constants.%Incomplete]
-// CHECK:STDOUT:   %.loc19_21.1: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc19_21.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc19_21.3: <bound method> = bound_method %.loc19_21.1, %.loc19_21.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc19_21.3(%.loc19_21.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc19_21.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:   %.loc19_21.5: Core.IntLiteral = converted %.loc19_21.1, %.loc19_21.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc19_22: type = array_type %.loc19_21.5, %Incomplete [template = constants.%.28]
+// CHECK:STDOUT:   %.loc19_21: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc19_22: type = array_type %.loc19_21, %Incomplete [template = constants.%.2]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
 // CHECK:STDOUT:   %Incomplete.ref.loc21: type = name_ref Incomplete, %Incomplete.decl [template = constants.%Incomplete]
-// CHECK:STDOUT:   %.loc21: type = ptr_type %Incomplete [template = constants.%.29]
-// CHECK:STDOUT:   %p.var: ref %.29 = var p
-// CHECK:STDOUT:   %p: ref %.29 = bind_name p, %p.var
+// CHECK:STDOUT:   %.loc21: type = ptr_type %Incomplete [template = constants.%.3]
+// CHECK:STDOUT:   %p.var: ref %.3 = var p
+// CHECK:STDOUT:   %p: ref %.3 = bind_name p, %p.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Incomplete;
@@ -74,7 +62,7 @@ var p: Incomplete* = &a[0];
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: ref <error> = name_ref a, file.%a
-// CHECK:STDOUT:   %.loc21_25: i32 = int_value 0 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc21_25: Core.IntLiteral = int_value 0 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc21_22: <error> = addr_of <error> [template = <error>]
 // CHECK:STDOUT:   assign file.%p.var, <error>
 // CHECK:STDOUT:   return

+ 6 - 17
toolchain/check/testdata/array/fail_invalid_type.carbon

@@ -8,10 +8,10 @@
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_invalid_type.carbon
 
-// CHECK:STDERR: fail_invalid_type.carbon:[[@LINE+6]]:9: error: cannot implicitly convert from `i32` to `type` [ImplicitAsConversionFailure]
+// CHECK:STDERR: fail_invalid_type.carbon:[[@LINE+6]]:9: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
 // CHECK:STDERR: var a: [1; 1];
 // CHECK:STDERR:         ^
-// CHECK:STDERR: fail_invalid_type.carbon:[[@LINE+3]]:9: note: type `i32` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fail_invalid_type.carbon:[[@LINE+3]]:9: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: var a: [1; 1];
 // CHECK:STDERR:         ^
 var a: [1; 1];
@@ -19,13 +19,7 @@ var a: [1; 1];
 // CHECK:STDOUT: --- fail_invalid_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.6: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.16) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.1, %Convert.16 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -42,15 +36,10 @@ var a: [1; 1];
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
-// CHECK:STDOUT:   %.loc17_9.1: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc17_12.1: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc17_9.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc17_12: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc17_9.2: type = converted %.loc17_9.1, <error> [template = <error>]
-// CHECK:STDOUT:   %.loc17_12.2: %Convert.type.6 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.16]
-// CHECK:STDOUT:   %.loc17_12.3: <bound method> = bound_method %.loc17_12.1, %.loc17_12.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc17_12.3(%.loc17_12.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc17_12.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.29]
-// CHECK:STDOUT:   %.loc17_12.5: Core.IntLiteral = converted %.loc17_12.1, %.loc17_12.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc17_13: type = array_type %.loc17_12.5, <error> [template = <error>]
+// CHECK:STDOUT:   %.loc17_13: type = array_type %.loc17_12, <error> [template = <error>]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
 // CHECK:STDOUT: }

+ 13 - 25
toolchain/check/testdata/array/fail_out_of_bound.carbon

@@ -18,23 +18,16 @@ var a: [i32; 1] = (1, 2, 3);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %tuple.type: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref.1
-// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Int32 = %import_ref
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -47,24 +40,19 @@ var a: [i32; 1] = (1, 2, 3);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc14_14.1: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc14_14: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc14_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc14_9.2: type = converted %int.make_type_32, %.loc14_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc14_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc14_14.3: <bound method> = bound_method %.loc14_14.1, %.loc14_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc14_14.3(%.loc14_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_14.5: Core.IntLiteral = converted %.loc14_14.1, %.loc14_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_15: type = array_type %.loc14_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %a.var: ref %.28 = var a
-// CHECK:STDOUT:   %a: ref %.28 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc14_15: type = array_type %.loc14_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %a.var: ref %.2 = var a
+// CHECK:STDOUT:   %a: ref %.2 = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc14_20: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc14_23: i32 = int_value 2 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc14_26: i32 = int_value 3 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc14_20: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc14_23: Core.IntLiteral = int_value 2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc14_26: Core.IntLiteral = int_value 3 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc14_27: %tuple.type = tuple_literal (%.loc14_20, %.loc14_23, %.loc14_26)
 // CHECK:STDOUT:   assign file.%a.var, <error>
 // CHECK:STDOUT:   return

+ 58 - 42
toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon

@@ -19,21 +19,25 @@ var b: i32 = a[{.index = 3}.index];
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.6: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %tuple.type: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %array: %.28 = tuple_value (%.30, %.31, %.1) [template]
-// CHECK:STDOUT:   %.33: type = struct_type {.index: i32} [template]
-// CHECK:STDOUT:   %struct: %.33 = struct_value (%.1) [template]
+// CHECK:STDOUT:   %.30: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %array: %.2 = tuple_value (%.32, %.34, %.36) [template]
+// CHECK:STDOUT:   %.37: type = struct_type {.index: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %struct: %.37 = struct_value (%.1) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -53,17 +57,12 @@ var b: i32 = a[{.index = 3}.index];
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc11_14.1: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_14: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_9.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
 // CHECK:STDOUT:   %.loc11_9.2: type = converted %int.make_type_32.loc11, %.loc11_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc11_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc11_14.3: <bound method> = bound_method %.loc11_14.1, %.loc11_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc11_14.3(%.loc11_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_14.5: Core.IntLiteral = converted %.loc11_14.1, %.loc11_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %a.var: ref %.28 = var a
-// CHECK:STDOUT:   %a: ref %.28 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %a.var: ref %.2 = var a
+// CHECK:STDOUT:   %a: ref %.2 = bind_name a, %a.var
 // CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc15_8.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
 // CHECK:STDOUT:   %.loc15_8.2: type = converted %int.make_type_32.loc15, %.loc15_8.1 [template = i32]
@@ -73,29 +72,46 @@ var b: i32 = a[{.index = 3}.index];
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_20: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc11_23: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_26: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_20: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_23: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_26: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_27.1: %tuple.type = tuple_literal (%.loc11_20, %.loc11_23, %.loc11_26)
-// CHECK:STDOUT:   %.loc11_27.2: i32 = int_value 0 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc11_27.3: ref i32 = array_index file.%a.var, %.loc11_27.2
-// CHECK:STDOUT:   %.loc11_27.4: init i32 = initialize_from %.loc11_20 to %.loc11_27.3 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc11_27.5: i32 = int_value 1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_27.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.3: <bound method> = bound_method %.loc11_20, %.loc11_27.2 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc11_27.1: init i32 = call %.loc11_27.3(%.loc11_20) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_27.4: init i32 = converted %.loc11_20, %int.convert_checked.loc11_27.1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_27.5: i32 = int_value 0 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc11_27.6: ref i32 = array_index file.%a.var, %.loc11_27.5
-// CHECK:STDOUT:   %.loc11_27.7: init i32 = initialize_from %.loc11_23 to %.loc11_27.6 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_27.8: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_27.9: ref i32 = array_index file.%a.var, %.loc11_27.8
-// CHECK:STDOUT:   %.loc11_27.10: init i32 = initialize_from %.loc11_26 to %.loc11_27.9 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_27.11: init %.28 = array_init (%.loc11_27.4, %.loc11_27.7, %.loc11_27.10) to file.%a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc11_28: init %.28 = converted %.loc11_27.1, %.loc11_27.11 [template = constants.%array]
+// CHECK:STDOUT:   %.loc11_27.7: init i32 = initialize_from %.loc11_27.4 to %.loc11_27.6 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_27.8: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.9: <bound method> = bound_method %.loc11_23, %.loc11_27.8 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc11_27.2: init i32 = call %.loc11_27.9(%.loc11_23) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_27.10: init i32 = converted %.loc11_23, %int.convert_checked.loc11_27.2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_27.11: i32 = int_value 1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_27.12: ref i32 = array_index file.%a.var, %.loc11_27.11
+// CHECK:STDOUT:   %.loc11_27.13: init i32 = initialize_from %.loc11_27.10 to %.loc11_27.12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_27.14: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.15: <bound method> = bound_method %.loc11_26, %.loc11_27.14 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc11_27.3: init i32 = call %.loc11_27.15(%.loc11_26) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_27.16: init i32 = converted %.loc11_26, %int.convert_checked.loc11_27.3 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_27.17: i32 = int_value 2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_27.18: ref i32 = array_index file.%a.var, %.loc11_27.17
+// CHECK:STDOUT:   %.loc11_27.19: init i32 = initialize_from %.loc11_27.16 to %.loc11_27.18 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_27.20: init %.2 = array_init (%.loc11_27.7, %.loc11_27.13, %.loc11_27.19) to file.%a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc11_28: init %.2 = converted %.loc11_27.1, %.loc11_27.20 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%a.var, %.loc11_28
-// CHECK:STDOUT:   %a.ref: ref %.28 = name_ref a, file.%a
-// CHECK:STDOUT:   %.loc15_26: i32 = int_value 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc15_27.1: %.33 = struct_literal (%.loc15_26)
-// CHECK:STDOUT:   %struct: %.33 = struct_value (%.loc15_26) [template = constants.%struct]
-// CHECK:STDOUT:   %.loc15_27.2: %.33 = converted %.loc15_27.1, %struct [template = constants.%struct]
-// CHECK:STDOUT:   %.loc15_28: i32 = struct_access %.loc15_27.2, element0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc15_34.1: ref i32 = array_index %a.ref, %.loc15_28 [template = <error>]
+// CHECK:STDOUT:   %a.ref: ref %.2 = name_ref a, file.%a
+// CHECK:STDOUT:   %.loc15_26: Core.IntLiteral = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc15_27.1: %.37 = struct_literal (%.loc15_26)
+// CHECK:STDOUT:   %struct: %.37 = struct_value (%.loc15_26) [template = constants.%struct]
+// CHECK:STDOUT:   %.loc15_27.2: %.37 = converted %.loc15_27.1, %struct [template = constants.%struct]
+// CHECK:STDOUT:   %.loc15_28.1: Core.IntLiteral = struct_access %.loc15_27.2, element0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc15_28.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_28.3: <bound method> = bound_method %.loc15_28.1, %.loc15_28.2 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc15: init i32 = call %.loc15_28.3(%.loc15_28.1) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc15_28.4: i32 = value_of_initializer %int.convert_checked.loc15 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc15_28.5: i32 = converted %.loc15_28.1, %.loc15_28.4 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc15_34.1: ref i32 = array_index %a.ref, %.loc15_28.5 [template = <error>]
 // CHECK:STDOUT:   %.loc15_34.2: i32 = bind_value %.loc15_34.1
 // CHECK:STDOUT:   assign file.%b.var, %.loc15_34.2
 // CHECK:STDOUT:   return

+ 56 - 70
toolchain/check/testdata/array/fail_type_mismatch.carbon

@@ -44,23 +44,25 @@ var d: [i32; 3] = t2;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.6: String = string_literal "Hello" [template]
+// CHECK:STDOUT:   %.7: String = string_literal "World" [template]
+// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (Core.IntLiteral, String, String) [template]
+// CHECK:STDOUT:   %.8: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.32: String = string_literal "Hello" [template]
-// CHECK:STDOUT:   %.33: String = string_literal "World" [template]
-// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (i32, String, String) [template]
-// CHECK:STDOUT:   %.34: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (type, type, type) [template]
-// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %tuple.type.4: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %tuple.type.5: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %tuple.type.3: type = tuple_type (i32, String, String) [template]
+// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.type.5: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %tuple.type.6: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %tuple.type.7: type = tuple_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -84,97 +86,81 @@ var d: [i32; 3] = t2;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %int.make_type_32.loc18: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc18_14.1: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc18_14: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc18_9.1: type = value_of_initializer %int.make_type_32.loc18 [template = i32]
 // CHECK:STDOUT:   %.loc18_9.2: type = converted %int.make_type_32.loc18, %.loc18_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc18_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc18_14.3: <bound method> = bound_method %.loc18_14.1, %.loc18_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked.loc18: init Core.IntLiteral = call %.loc18_14.3(%.loc18_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc18_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc18 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc18_14.5: Core.IntLiteral = converted %.loc18_14.1, %.loc18_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc18_15: type = array_type %.loc18_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %a.var: ref %.28 = var a
-// CHECK:STDOUT:   %a: ref %.28 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc18_15: type = array_type %.loc18_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %a.var: ref %.2 = var a
+// CHECK:STDOUT:   %a: ref %.2 = bind_name a, %a.var
 // CHECK:STDOUT:   %int.make_type_32.loc20: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc20_29.1: %tuple.type.2 = tuple_literal (%int.make_type_32.loc20, String, String)
 // CHECK:STDOUT:   %.loc20_29.2: type = value_of_initializer %int.make_type_32.loc20 [template = i32]
 // CHECK:STDOUT:   %.loc20_29.3: type = converted %int.make_type_32.loc20, %.loc20_29.2 [template = i32]
-// CHECK:STDOUT:   %.loc20_29.4: type = converted %.loc20_29.1, constants.%tuple.type.1 [template = constants.%tuple.type.1]
-// CHECK:STDOUT:   %t1.var: ref %tuple.type.1 = var t1
-// CHECK:STDOUT:   %t1: ref %tuple.type.1 = bind_name t1, %t1.var
+// CHECK:STDOUT:   %.loc20_29.4: type = converted %.loc20_29.1, constants.%tuple.type.3 [template = constants.%tuple.type.3]
+// CHECK:STDOUT:   %t1.var: ref %tuple.type.3 = var t1
+// CHECK:STDOUT:   %t1: ref %tuple.type.3 = bind_name t1, %t1.var
 // CHECK:STDOUT:   %int.make_type_32.loc28: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc28_14.1: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc28_14: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc28_9.1: type = value_of_initializer %int.make_type_32.loc28 [template = i32]
 // CHECK:STDOUT:   %.loc28_9.2: type = converted %int.make_type_32.loc28, %.loc28_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc28_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc28_14.3: <bound method> = bound_method %.loc28_14.1, %.loc28_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked.loc28: init Core.IntLiteral = call %.loc28_14.3(%.loc28_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc28_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc28 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc28_14.5: Core.IntLiteral = converted %.loc28_14.1, %.loc28_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc28_15: type = array_type %.loc28_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %b.var: ref %.28 = var b
-// CHECK:STDOUT:   %b: ref %.28 = bind_name b, %b.var
+// CHECK:STDOUT:   %.loc28_15: type = array_type %.loc28_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %b.var: ref %.2 = var b
+// CHECK:STDOUT:   %b: ref %.2 = bind_name b, %b.var
 // CHECK:STDOUT:   %int.make_type_32.loc34: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc34_14.1: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc34_14: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc34_9.1: type = value_of_initializer %int.make_type_32.loc34 [template = i32]
 // CHECK:STDOUT:   %.loc34_9.2: type = converted %int.make_type_32.loc34, %.loc34_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc34_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc34_14.3: <bound method> = bound_method %.loc34_14.1, %.loc34_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked.loc34: init Core.IntLiteral = call %.loc34_14.3(%.loc34_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc34_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc34 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc34_14.5: Core.IntLiteral = converted %.loc34_14.1, %.loc34_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc34_15: type = array_type %.loc34_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %c.var: ref %.28 = var c
-// CHECK:STDOUT:   %c: ref %.28 = bind_name c, %c.var
+// CHECK:STDOUT:   %.loc34_15: type = array_type %.loc34_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %c.var: ref %.2 = var c
+// CHECK:STDOUT:   %c: ref %.2 = bind_name c, %c.var
 // CHECK:STDOUT:   %int.make_type_32.loc36_10: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %int.make_type_32.loc36_15: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc36_18.1: %tuple.type.5 = tuple_literal (%int.make_type_32.loc36_10, %int.make_type_32.loc36_15)
+// CHECK:STDOUT:   %.loc36_18.1: %tuple.type.6 = tuple_literal (%int.make_type_32.loc36_10, %int.make_type_32.loc36_15)
 // CHECK:STDOUT:   %.loc36_18.2: type = value_of_initializer %int.make_type_32.loc36_10 [template = i32]
 // CHECK:STDOUT:   %.loc36_18.3: type = converted %int.make_type_32.loc36_10, %.loc36_18.2 [template = i32]
 // CHECK:STDOUT:   %.loc36_18.4: type = value_of_initializer %int.make_type_32.loc36_15 [template = i32]
 // CHECK:STDOUT:   %.loc36_18.5: type = converted %int.make_type_32.loc36_15, %.loc36_18.4 [template = i32]
-// CHECK:STDOUT:   %.loc36_18.6: type = converted %.loc36_18.1, constants.%tuple.type.4 [template = constants.%tuple.type.4]
-// CHECK:STDOUT:   %t2.var: ref %tuple.type.4 = var t2
-// CHECK:STDOUT:   %t2: ref %tuple.type.4 = bind_name t2, %t2.var
+// CHECK:STDOUT:   %.loc36_18.6: type = converted %.loc36_18.1, constants.%tuple.type.7 [template = constants.%tuple.type.7]
+// CHECK:STDOUT:   %t2.var: ref %tuple.type.7 = var t2
+// CHECK:STDOUT:   %t2: ref %tuple.type.7 = bind_name t2, %t2.var
 // CHECK:STDOUT:   %int.make_type_32.loc40: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc40_14.1: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc40_14: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc40_9.1: type = value_of_initializer %int.make_type_32.loc40 [template = i32]
 // CHECK:STDOUT:   %.loc40_9.2: type = converted %int.make_type_32.loc40, %.loc40_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc40_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc40_14.3: <bound method> = bound_method %.loc40_14.1, %.loc40_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked.loc40: init Core.IntLiteral = call %.loc40_14.3(%.loc40_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc40_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc40 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc40_14.5: Core.IntLiteral = converted %.loc40_14.1, %.loc40_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc40_15: type = array_type %.loc40_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %d.var: ref %.28 = var d
-// CHECK:STDOUT:   %d: ref %.28 = bind_name d, %d.var
+// CHECK:STDOUT:   %.loc40_15: type = array_type %.loc40_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %d.var: ref %.2 = var d
+// CHECK:STDOUT:   %d: ref %.2 = bind_name d, %d.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc18_20: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc18_23: String = string_literal "Hello" [template = constants.%.32]
-// CHECK:STDOUT:   %.loc18_32: String = string_literal "World" [template = constants.%.33]
+// CHECK:STDOUT:   %.loc18_20: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc18_23: String = string_literal "Hello" [template = constants.%.6]
+// CHECK:STDOUT:   %.loc18_32: String = string_literal "World" [template = constants.%.7]
 // CHECK:STDOUT:   %.loc18_39.1: %tuple.type.1 = tuple_literal (%.loc18_20, %.loc18_23, %.loc18_32)
-// CHECK:STDOUT:   %.loc18_39.2: i32 = int_value 0 [template = constants.%.34]
-// CHECK:STDOUT:   %.loc18_39.3: ref i32 = array_index file.%a.var, %.loc18_39.2
-// CHECK:STDOUT:   %.loc18_39.4: init i32 = initialize_from %.loc18_20 to %.loc18_39.3 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc18_39.5: i32 = converted %.loc18_23, <error> [template = <error>]
+// CHECK:STDOUT:   %.loc18_39.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc18_39.3: <bound method> = bound_method %.loc18_20, %.loc18_39.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc18_39.3(%.loc18_20) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc18_39.4: init i32 = converted %.loc18_20, %int.convert_checked [template = constants.%.34]
+// CHECK:STDOUT:   %.loc18_39.5: i32 = int_value 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc18_39.6: ref i32 = array_index file.%a.var, %.loc18_39.5
+// CHECK:STDOUT:   %.loc18_39.7: init i32 = initialize_from %.loc18_39.4 to %.loc18_39.6 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc18_39.8: i32 = converted %.loc18_23, <error> [template = <error>]
 // CHECK:STDOUT:   assign file.%a.var, <error>
-// CHECK:STDOUT:   %t1.ref: ref %tuple.type.1 = name_ref t1, file.%t1
+// CHECK:STDOUT:   %t1.ref: ref %tuple.type.3 = name_ref t1, file.%t1
 // CHECK:STDOUT:   %.loc28_19.1: ref i32 = tuple_access %t1.ref, element0
 // CHECK:STDOUT:   %.loc28_19.2: i32 = bind_value %.loc28_19.1
-// CHECK:STDOUT:   %.loc28_19.3: i32 = int_value 0 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc28_19.3: i32 = int_value 0 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc28_19.4: ref i32 = array_index file.%b.var, %.loc28_19.3
 // CHECK:STDOUT:   %.loc28_19.5: init i32 = initialize_from %.loc28_19.2 to %.loc28_19.4
 // CHECK:STDOUT:   %.loc28_19.6: ref String = tuple_access %t1.ref, element1
 // CHECK:STDOUT:   %.loc28_19.7: i32 = converted %.loc28_19.6, <error> [template = <error>]
 // CHECK:STDOUT:   assign file.%b.var, <error>
-// CHECK:STDOUT:   %.loc34_20: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc34_23: i32 = int_value 2 [template = constants.%.36]
-// CHECK:STDOUT:   %.loc34_24: %tuple.type.4 = tuple_literal (%.loc34_20, %.loc34_23)
+// CHECK:STDOUT:   %.loc34_20: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc34_23: Core.IntLiteral = int_value 2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc34_24: %tuple.type.5 = tuple_literal (%.loc34_20, %.loc34_23)
 // CHECK:STDOUT:   assign file.%c.var, <error>
-// CHECK:STDOUT:   %t2.ref: ref %tuple.type.4 = name_ref t2, file.%t2
+// CHECK:STDOUT:   %t2.ref: ref %tuple.type.7 = name_ref t2, file.%t2
 // CHECK:STDOUT:   assign file.%d.var, <error>
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 62 - 46
toolchain/check/testdata/array/function_param.carbon

@@ -21,23 +21,27 @@ fn G() -> i32 {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %tuple.type: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %array: %.28 = tuple_value (%.30, %.31, %.1) [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.6: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.30: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %array: %.2 = tuple_value (%.32, %.34, %.36) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -57,31 +61,26 @@ fn G() -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %arr.patt: %.28 = binding_pattern arr
-// CHECK:STDOUT:     %arr.param_patt: %.28 = value_param_pattern %arr.patt, runtime_param0
+// CHECK:STDOUT:     %arr.patt: %.2 = binding_pattern arr
+// CHECK:STDOUT:     %arr.param_patt: %.2 = value_param_pattern %arr.patt, runtime_param0
 // CHECK:STDOUT:     %i.patt: i32 = binding_pattern i
 // CHECK:STDOUT:     %i.param_patt: i32 = value_param_pattern %i.patt, runtime_param1
 // CHECK:STDOUT:     %return.patt: i32 = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: i32 = out_param_pattern %return.patt, runtime_param2
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int.make_type_32.loc11_12: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:     %.loc11_17.1: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:     %.loc11_17: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:     %.loc11_12.1: type = value_of_initializer %int.make_type_32.loc11_12 [template = i32]
 // CHECK:STDOUT:     %.loc11_12.2: type = converted %int.make_type_32.loc11_12, %.loc11_12.1 [template = i32]
-// CHECK:STDOUT:     %.loc11_17.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:     %.loc11_17.3: <bound method> = bound_method %.loc11_17.1, %.loc11_17.2 [template = constants.%.26]
-// CHECK:STDOUT:     %int.convert_checked: init Core.IntLiteral = call %.loc11_17.3(%.loc11_17.1) [template = constants.%.27]
-// CHECK:STDOUT:     %.loc11_17.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:     %.loc11_17.5: Core.IntLiteral = converted %.loc11_17.1, %.loc11_17.4 [template = constants.%.27]
-// CHECK:STDOUT:     %.loc11_18: type = array_type %.loc11_17.5, i32 [template = constants.%.28]
+// CHECK:STDOUT:     %.loc11_18: type = array_type %.loc11_17, i32 [template = constants.%.2]
 // CHECK:STDOUT:     %int.make_type_32.loc11_24: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc11_24.1: type = value_of_initializer %int.make_type_32.loc11_24 [template = i32]
 // CHECK:STDOUT:     %.loc11_24.2: type = converted %int.make_type_32.loc11_24, %.loc11_24.1 [template = i32]
 // CHECK:STDOUT:     %int.make_type_32.loc11_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc11_32.1: type = value_of_initializer %int.make_type_32.loc11_32 [template = i32]
 // CHECK:STDOUT:     %.loc11_32.2: type = converted %int.make_type_32.loc11_32, %.loc11_32.1 [template = i32]
-// CHECK:STDOUT:     %arr.param: %.28 = value_param runtime_param0
-// CHECK:STDOUT:     %arr: %.28 = bind_name arr, %arr.param
+// CHECK:STDOUT:     %arr.param: %.2 = value_param runtime_param0
+// CHECK:STDOUT:     %arr: %.2 = bind_name arr, %arr.param
 // CHECK:STDOUT:     %i.param: i32 = value_param runtime_param1
 // CHECK:STDOUT:     %i: i32 = bind_name i, %i.param
 // CHECK:STDOUT:     %return.param: ref i32 = out_param runtime_param2
@@ -99,11 +98,11 @@ fn G() -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%arr.param_patt: %.28, %i.param_patt: i32) -> i32 {
+// CHECK:STDOUT: fn @F(%arr.param_patt: %.2, %i.param_patt: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: %.28 = name_ref arr, %arr
+// CHECK:STDOUT:   %arr.ref: %.2 = name_ref arr, %arr
 // CHECK:STDOUT:   %i.ref: i32 = name_ref i, %i
-// CHECK:STDOUT:   %.loc12_15.1: ref %.28 = value_as_ref %arr.ref
+// CHECK:STDOUT:   %.loc12_15.1: ref %.2 = value_as_ref %arr.ref
 // CHECK:STDOUT:   %.loc12_15.2: ref i32 = array_index %.loc12_15.1, %i.ref
 // CHECK:STDOUT:   %.loc12_15.3: i32 = bind_value %.loc12_15.2
 // CHECK:STDOUT:   return %.loc12_15.3
@@ -112,26 +111,43 @@ fn G() -> i32 {
 // CHECK:STDOUT: fn @G() -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %.loc16_13: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc16_16: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc16_19: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc16_13: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc16_16: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc16_19: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc16_20.1: %tuple.type = tuple_literal (%.loc16_13, %.loc16_16, %.loc16_19)
-// CHECK:STDOUT:   %.loc16_23: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc16_20.2: ref %.28 = temporary_storage
-// CHECK:STDOUT:   %.loc16_20.3: i32 = int_value 0 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc16_20.4: ref i32 = array_index %.loc16_20.2, %.loc16_20.3
-// CHECK:STDOUT:   %.loc16_20.5: init i32 = initialize_from %.loc16_13 to %.loc16_20.4 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc16_20.6: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc16_20.7: ref i32 = array_index %.loc16_20.2, %.loc16_20.6
-// CHECK:STDOUT:   %.loc16_20.8: init i32 = initialize_from %.loc16_16 to %.loc16_20.7 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc16_20.9: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc16_20.10: ref i32 = array_index %.loc16_20.2, %.loc16_20.9
-// CHECK:STDOUT:   %.loc16_20.11: init i32 = initialize_from %.loc16_19 to %.loc16_20.10 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc16_20.12: init %.28 = array_init (%.loc16_20.5, %.loc16_20.8, %.loc16_20.11) to %.loc16_20.2 [template = constants.%array]
-// CHECK:STDOUT:   %.loc16_20.13: init %.28 = converted %.loc16_20.1, %.loc16_20.12 [template = constants.%array]
-// CHECK:STDOUT:   %.loc16_20.14: ref %.28 = temporary %.loc16_20.2, %.loc16_20.13
-// CHECK:STDOUT:   %.loc16_20.15: %.28 = bind_value %.loc16_20.14
-// CHECK:STDOUT:   %F.call: init i32 = call %F.ref(%.loc16_20.15, %.loc16_23)
+// CHECK:STDOUT:   %.loc16_23.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc16_20.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_20.3: <bound method> = bound_method %.loc16_13, %.loc16_20.2 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc16_20.1: init i32 = call %.loc16_20.3(%.loc16_13) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc16_20.4: init i32 = converted %.loc16_13, %int.convert_checked.loc16_20.1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc16_20.5: ref %.2 = temporary_storage
+// CHECK:STDOUT:   %.loc16_20.6: i32 = int_value 0 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc16_20.7: ref i32 = array_index %.loc16_20.5, %.loc16_20.6
+// CHECK:STDOUT:   %.loc16_20.8: init i32 = initialize_from %.loc16_20.4 to %.loc16_20.7 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc16_20.9: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_20.10: <bound method> = bound_method %.loc16_16, %.loc16_20.9 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc16_20.2: init i32 = call %.loc16_20.10(%.loc16_16) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc16_20.11: init i32 = converted %.loc16_16, %int.convert_checked.loc16_20.2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc16_20.12: i32 = int_value 1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc16_20.13: ref i32 = array_index %.loc16_20.5, %.loc16_20.12
+// CHECK:STDOUT:   %.loc16_20.14: init i32 = initialize_from %.loc16_20.11 to %.loc16_20.13 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc16_20.15: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_20.16: <bound method> = bound_method %.loc16_19, %.loc16_20.15 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc16_20.3: init i32 = call %.loc16_20.16(%.loc16_19) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc16_20.17: init i32 = converted %.loc16_19, %int.convert_checked.loc16_20.3 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc16_20.18: i32 = int_value 2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc16_20.19: ref i32 = array_index %.loc16_20.5, %.loc16_20.18
+// CHECK:STDOUT:   %.loc16_20.20: init i32 = initialize_from %.loc16_20.17 to %.loc16_20.19 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc16_20.21: init %.2 = array_init (%.loc16_20.8, %.loc16_20.14, %.loc16_20.20) to %.loc16_20.5 [template = constants.%array]
+// CHECK:STDOUT:   %.loc16_20.22: init %.2 = converted %.loc16_20.1, %.loc16_20.21 [template = constants.%array]
+// CHECK:STDOUT:   %.loc16_20.23: ref %.2 = temporary %.loc16_20.5, %.loc16_20.22
+// CHECK:STDOUT:   %.loc16_20.24: %.2 = bind_value %.loc16_20.23
+// CHECK:STDOUT:   %.loc16_23.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_23.3: <bound method> = bound_method %.loc16_23.1, %.loc16_23.2 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc16_23: init i32 = call %.loc16_23.3(%.loc16_23.1) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc16_23.4: i32 = value_of_initializer %int.convert_checked.loc16_23 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc16_23.5: i32 = converted %.loc16_23.1, %.loc16_23.4 [template = constants.%.32]
+// CHECK:STDOUT:   %F.call: init i32 = call %F.ref(%.loc16_20.24, %.loc16_23.5)
 // CHECK:STDOUT:   %.loc16_25.1: i32 = value_of_initializer %F.call
 // CHECK:STDOUT:   %.loc16_25.2: i32 = converted %F.call, %.loc16_25.1
 // CHECK:STDOUT:   return %.loc16_25.2

+ 11 - 23
toolchain/check/testdata/array/generic_empty.carbon

@@ -21,20 +21,13 @@ fn G(T:! type) {
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 0 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, %T [symbolic]
-// CHECK:STDOUT:   %array: %.28 = tuple_value () [symbolic]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, %T [symbolic]
+// CHECK:STDOUT:   %array: %.2 = tuple_value () [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .ImplicitAs = %import_ref.1
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -60,24 +53,19 @@ fn G(T:! type) {
 // CHECK:STDOUT:   %T.patt.loc11_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %.loc13_17.2: type = array_type constants.%.27, @G.%T.loc11_6.2 (%T) [symbolic = %.loc13_17.2 (constants.%.28)]
-// CHECK:STDOUT:   %array: @G.%.loc13_17.2 (%.28) = tuple_value () [symbolic = %array (constants.%array)]
+// CHECK:STDOUT:   %.loc13_17.2: type = array_type constants.%.1, @G.%T.loc11_6.2 (%T) [symbolic = %.loc13_17.2 (constants.%.2)]
+// CHECK:STDOUT:   %array: @G.%.loc13_17.2 (%.2) = tuple_value () [symbolic = %array (constants.%array)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%T.param_patt: type) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T)]
-// CHECK:STDOUT:     %.loc13_16.1: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:     %.loc13_16.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:     %.loc13_16.3: <bound method> = bound_method %.loc13_16.1, %.loc13_16.2 [template = constants.%.26]
-// CHECK:STDOUT:     %int.convert_checked: init Core.IntLiteral = call %.loc13_16.3(%.loc13_16.1) [template = constants.%.27]
-// CHECK:STDOUT:     %.loc13_16.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:     %.loc13_16.5: Core.IntLiteral = converted %.loc13_16.1, %.loc13_16.4 [template = constants.%.27]
-// CHECK:STDOUT:     %.loc13_17.1: type = array_type %.loc13_16.5, %T [symbolic = %.loc13_17.2 (constants.%.28)]
-// CHECK:STDOUT:     %arr.var: ref @G.%.loc13_17.2 (%.28) = var arr
-// CHECK:STDOUT:     %arr: ref @G.%.loc13_17.2 (%.28) = bind_name arr, %arr.var
+// CHECK:STDOUT:     %.loc13_16: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:     %.loc13_17.1: type = array_type %.loc13_16, %T [symbolic = %.loc13_17.2 (constants.%.2)]
+// CHECK:STDOUT:     %arr.var: ref @G.%.loc13_17.2 (%.2) = var arr
+// CHECK:STDOUT:     %arr: ref @G.%.loc13_17.2 (%.2) = bind_name arr, %arr.var
 // CHECK:STDOUT:     %.loc13_22.1: %empty_tuple.type = tuple_literal ()
-// CHECK:STDOUT:     %.loc13_22.2: init @G.%.loc13_17.2 (%.28) = array_init () to %arr.var [symbolic = %array (constants.%array)]
-// CHECK:STDOUT:     %.loc13_23: init @G.%.loc13_17.2 (%.28) = converted %.loc13_22.1, %.loc13_22.2 [symbolic = %array (constants.%array)]
+// CHECK:STDOUT:     %.loc13_22.2: init @G.%.loc13_17.2 (%.2) = array_init () to %arr.var [symbolic = %array (constants.%array)]
+// CHECK:STDOUT:     %.loc13_23: init @G.%.loc13_17.2 (%.2) = converted %.loc13_22.1, %.loc13_22.2 [symbolic = %array (constants.%array)]
 // CHECK:STDOUT:     assign %arr.var, %.loc13_23
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }

+ 58 - 42
toolchain/check/testdata/array/index_not_literal.carbon

@@ -16,21 +16,25 @@ var b: i32 = a[{.index = 2}.index];
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.6: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %tuple.type: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %array: %.28 = tuple_value (%.30, %.31, %.1) [template]
-// CHECK:STDOUT:   %.33: type = struct_type {.index: i32} [template]
-// CHECK:STDOUT:   %struct: %.33 = struct_value (%.31) [template]
+// CHECK:STDOUT:   %.30: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %array: %.2 = tuple_value (%.32, %.34, %.36) [template]
+// CHECK:STDOUT:   %.37: type = struct_type {.index: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %struct: %.37 = struct_value (%.5) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -50,17 +54,12 @@ var b: i32 = a[{.index = 2}.index];
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc11_14.1: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_14: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_9.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
 // CHECK:STDOUT:   %.loc11_9.2: type = converted %int.make_type_32.loc11, %.loc11_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc11_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc11_14.3: <bound method> = bound_method %.loc11_14.1, %.loc11_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc11_14.3(%.loc11_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_14.5: Core.IntLiteral = converted %.loc11_14.1, %.loc11_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %a.var: ref %.28 = var a
-// CHECK:STDOUT:   %a: ref %.28 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %a.var: ref %.2 = var a
+// CHECK:STDOUT:   %a: ref %.2 = bind_name a, %a.var
 // CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc12_8.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
 // CHECK:STDOUT:   %.loc12_8.2: type = converted %int.make_type_32.loc12, %.loc12_8.1 [template = i32]
@@ -70,29 +69,46 @@ var b: i32 = a[{.index = 2}.index];
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_20: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc11_23: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_26: i32 = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_20: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_23: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_26: Core.IntLiteral = int_value 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_27.1: %tuple.type = tuple_literal (%.loc11_20, %.loc11_23, %.loc11_26)
-// CHECK:STDOUT:   %.loc11_27.2: i32 = int_value 0 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc11_27.3: ref i32 = array_index file.%a.var, %.loc11_27.2
-// CHECK:STDOUT:   %.loc11_27.4: init i32 = initialize_from %.loc11_20 to %.loc11_27.3 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc11_27.5: i32 = int_value 1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_27.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.3: <bound method> = bound_method %.loc11_20, %.loc11_27.2 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc11_27.1: init i32 = call %.loc11_27.3(%.loc11_20) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_27.4: init i32 = converted %.loc11_20, %int.convert_checked.loc11_27.1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_27.5: i32 = int_value 0 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc11_27.6: ref i32 = array_index file.%a.var, %.loc11_27.5
-// CHECK:STDOUT:   %.loc11_27.7: init i32 = initialize_from %.loc11_23 to %.loc11_27.6 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_27.8: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_27.9: ref i32 = array_index file.%a.var, %.loc11_27.8
-// CHECK:STDOUT:   %.loc11_27.10: init i32 = initialize_from %.loc11_26 to %.loc11_27.9 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_27.11: init %.28 = array_init (%.loc11_27.4, %.loc11_27.7, %.loc11_27.10) to file.%a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc11_28: init %.28 = converted %.loc11_27.1, %.loc11_27.11 [template = constants.%array]
+// CHECK:STDOUT:   %.loc11_27.7: init i32 = initialize_from %.loc11_27.4 to %.loc11_27.6 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_27.8: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.9: <bound method> = bound_method %.loc11_23, %.loc11_27.8 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc11_27.2: init i32 = call %.loc11_27.9(%.loc11_23) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_27.10: init i32 = converted %.loc11_23, %int.convert_checked.loc11_27.2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_27.11: i32 = int_value 1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_27.12: ref i32 = array_index file.%a.var, %.loc11_27.11
+// CHECK:STDOUT:   %.loc11_27.13: init i32 = initialize_from %.loc11_27.10 to %.loc11_27.12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_27.14: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.15: <bound method> = bound_method %.loc11_26, %.loc11_27.14 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc11_27.3: init i32 = call %.loc11_27.15(%.loc11_26) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_27.16: init i32 = converted %.loc11_26, %int.convert_checked.loc11_27.3 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_27.17: i32 = int_value 2 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_27.18: ref i32 = array_index file.%a.var, %.loc11_27.17
+// CHECK:STDOUT:   %.loc11_27.19: init i32 = initialize_from %.loc11_27.16 to %.loc11_27.18 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_27.20: init %.2 = array_init (%.loc11_27.7, %.loc11_27.13, %.loc11_27.19) to file.%a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc11_28: init %.2 = converted %.loc11_27.1, %.loc11_27.20 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%a.var, %.loc11_28
-// CHECK:STDOUT:   %a.ref: ref %.28 = name_ref a, file.%a
-// CHECK:STDOUT:   %.loc12_26: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc12_27.1: %.33 = struct_literal (%.loc12_26)
-// CHECK:STDOUT:   %struct: %.33 = struct_value (%.loc12_26) [template = constants.%struct]
-// CHECK:STDOUT:   %.loc12_27.2: %.33 = converted %.loc12_27.1, %struct [template = constants.%struct]
-// CHECK:STDOUT:   %.loc12_28: i32 = struct_access %.loc12_27.2, element0 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc12_34.1: ref i32 = array_index %a.ref, %.loc12_28
+// CHECK:STDOUT:   %a.ref: ref %.2 = name_ref a, file.%a
+// CHECK:STDOUT:   %.loc12_26: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12_27.1: %.37 = struct_literal (%.loc12_26)
+// CHECK:STDOUT:   %struct: %.37 = struct_value (%.loc12_26) [template = constants.%struct]
+// CHECK:STDOUT:   %.loc12_27.2: %.37 = converted %.loc12_27.1, %struct [template = constants.%struct]
+// CHECK:STDOUT:   %.loc12_28.1: Core.IntLiteral = struct_access %.loc12_27.2, element0 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12_28.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_28.3: <bound method> = bound_method %.loc12_28.1, %.loc12_28.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc12: init i32 = call %.loc12_28.3(%.loc12_28.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_28.4: i32 = value_of_initializer %int.convert_checked.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_28.5: i32 = converted %.loc12_28.1, %.loc12_28.4 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_34.1: ref i32 = array_index %a.ref, %.loc12_28.5
 // CHECK:STDOUT:   %.loc12_34.2: i32 = bind_value %.loc12_34.1
 // CHECK:STDOUT:   assign file.%b.var, %.loc12_34.2
 // CHECK:STDOUT:   return

+ 107 - 60
toolchain/check/testdata/array/nine_elements.carbon

@@ -15,25 +15,41 @@ var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 9 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 9 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.7: Core.IntLiteral = int_value 4 [template]
+// CHECK:STDOUT:   %.8: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.9: Core.IntLiteral = int_value 6 [template]
+// CHECK:STDOUT:   %.10: Core.IntLiteral = int_value 7 [template]
+// CHECK:STDOUT:   %.11: Core.IntLiteral = int_value 8 [template]
+// CHECK:STDOUT:   %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.12: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 9 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.33: i32 = int_value 4 [template]
-// CHECK:STDOUT:   %.34: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.35: i32 = int_value 6 [template]
-// CHECK:STDOUT:   %.36: i32 = int_value 7 [template]
-// CHECK:STDOUT:   %.37: i32 = int_value 8 [template]
-// CHECK:STDOUT:   %tuple.type: type = tuple_type (i32, i32, i32, i32, i32, i32, i32, i32, i32) [template]
-// CHECK:STDOUT:   %.38: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %array: %.28 = tuple_value (%.30, %.31, %.32, %.33, %.34, %.35, %.36, %.37, %.1) [template]
+// CHECK:STDOUT:   %.36: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.37: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.39: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.40: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.41: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.42: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.43: <bound method> = bound_method %.7, %Convert.15 [template]
+// CHECK:STDOUT:   %.44: i32 = int_value 4 [template]
+// CHECK:STDOUT:   %.45: <bound method> = bound_method %.8, %Convert.15 [template]
+// CHECK:STDOUT:   %.46: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.47: <bound method> = bound_method %.9, %Convert.15 [template]
+// CHECK:STDOUT:   %.48: i32 = int_value 6 [template]
+// CHECK:STDOUT:   %.49: <bound method> = bound_method %.10, %Convert.15 [template]
+// CHECK:STDOUT:   %.50: i32 = int_value 7 [template]
+// CHECK:STDOUT:   %.51: <bound method> = bound_method %.11, %Convert.15 [template]
+// CHECK:STDOUT:   %.52: i32 = int_value 8 [template]
+// CHECK:STDOUT:   %.53: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.54: i32 = int_value 9 [template]
+// CHECK:STDOUT:   %array: %.2 = tuple_value (%.38, %.40, %.42, %.44, %.46, %.48, %.50, %.52, %.54) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -52,60 +68,91 @@ var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc11_14.1: i32 = int_value 9 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_14: Core.IntLiteral = int_value 9 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc11_9.2: type = converted %int.make_type_32, %.loc11_9.1 [template = i32]
-// CHECK:STDOUT:   %.loc11_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc11_14.3: <bound method> = bound_method %.loc11_14.1, %.loc11_14.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc11_14.3(%.loc11_14.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_14.5: Core.IntLiteral = converted %.loc11_14.1, %.loc11_14.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %a.var: ref %.28 = var a
-// CHECK:STDOUT:   %a: ref %.28 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %a.var: ref %.2 = var a
+// CHECK:STDOUT:   %a: ref %.2 = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_20: i32 = int_value 1 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc11_23: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_26: i32 = int_value 3 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc11_29: i32 = int_value 4 [template = constants.%.33]
-// CHECK:STDOUT:   %.loc11_32: i32 = int_value 5 [template = constants.%.34]
-// CHECK:STDOUT:   %.loc11_35: i32 = int_value 6 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc11_38: i32 = int_value 7 [template = constants.%.36]
-// CHECK:STDOUT:   %.loc11_41: i32 = int_value 8 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc11_44: i32 = int_value 9 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_20: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_23: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_26: Core.IntLiteral = int_value 3 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc11_29: Core.IntLiteral = int_value 4 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc11_32: Core.IntLiteral = int_value 5 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc11_35: Core.IntLiteral = int_value 6 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc11_38: Core.IntLiteral = int_value 7 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc11_41: Core.IntLiteral = int_value 8 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc11_44: Core.IntLiteral = int_value 9 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_45.1: %tuple.type = tuple_literal (%.loc11_20, %.loc11_23, %.loc11_26, %.loc11_29, %.loc11_32, %.loc11_35, %.loc11_38, %.loc11_41, %.loc11_44)
-// CHECK:STDOUT:   %.loc11_45.2: i32 = int_value 0 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc11_45.3: ref i32 = array_index file.%a.var, %.loc11_45.2
-// CHECK:STDOUT:   %.loc11_45.4: init i32 = initialize_from %.loc11_20 to %.loc11_45.3 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc11_45.5: i32 = int_value 1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_45.2: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.3: <bound method> = bound_method %.loc11_20, %.loc11_45.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.1: init i32 = call %.loc11_45.3(%.loc11_20) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_45.4: init i32 = converted %.loc11_20, %int.convert_checked.loc11_45.1 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_45.5: i32 = int_value 0 [template = constants.%.12]
 // CHECK:STDOUT:   %.loc11_45.6: ref i32 = array_index file.%a.var, %.loc11_45.5
-// CHECK:STDOUT:   %.loc11_45.7: init i32 = initialize_from %.loc11_23 to %.loc11_45.6 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_45.8: i32 = int_value 2 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc11_45.9: ref i32 = array_index file.%a.var, %.loc11_45.8
-// CHECK:STDOUT:   %.loc11_45.10: init i32 = initialize_from %.loc11_26 to %.loc11_45.9 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc11_45.11: i32 = int_value 3 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_45.7: init i32 = initialize_from %.loc11_45.4 to %.loc11_45.6 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_45.8: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.9: <bound method> = bound_method %.loc11_23, %.loc11_45.8 [template = constants.%.39]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.2: init i32 = call %.loc11_45.9(%.loc11_23) [template = constants.%.40]
+// CHECK:STDOUT:   %.loc11_45.10: init i32 = converted %.loc11_23, %int.convert_checked.loc11_45.2 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc11_45.11: i32 = int_value 1 [template = constants.%.38]
 // CHECK:STDOUT:   %.loc11_45.12: ref i32 = array_index file.%a.var, %.loc11_45.11
-// CHECK:STDOUT:   %.loc11_45.13: init i32 = initialize_from %.loc11_29 to %.loc11_45.12 [template = constants.%.33]
-// CHECK:STDOUT:   %.loc11_45.14: i32 = int_value 4 [template = constants.%.33]
-// CHECK:STDOUT:   %.loc11_45.15: ref i32 = array_index file.%a.var, %.loc11_45.14
-// CHECK:STDOUT:   %.loc11_45.16: init i32 = initialize_from %.loc11_32 to %.loc11_45.15 [template = constants.%.34]
-// CHECK:STDOUT:   %.loc11_45.17: i32 = int_value 5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc11_45.13: init i32 = initialize_from %.loc11_45.10 to %.loc11_45.12 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc11_45.14: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.15: <bound method> = bound_method %.loc11_26, %.loc11_45.14 [template = constants.%.41]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.3: init i32 = call %.loc11_45.15(%.loc11_26) [template = constants.%.42]
+// CHECK:STDOUT:   %.loc11_45.16: init i32 = converted %.loc11_26, %int.convert_checked.loc11_45.3 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc11_45.17: i32 = int_value 2 [template = constants.%.40]
 // CHECK:STDOUT:   %.loc11_45.18: ref i32 = array_index file.%a.var, %.loc11_45.17
-// CHECK:STDOUT:   %.loc11_45.19: init i32 = initialize_from %.loc11_35 to %.loc11_45.18 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc11_45.20: i32 = int_value 6 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc11_45.21: ref i32 = array_index file.%a.var, %.loc11_45.20
-// CHECK:STDOUT:   %.loc11_45.22: init i32 = initialize_from %.loc11_38 to %.loc11_45.21 [template = constants.%.36]
-// CHECK:STDOUT:   %.loc11_45.23: i32 = int_value 7 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_45.19: init i32 = initialize_from %.loc11_45.16 to %.loc11_45.18 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc11_45.20: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.21: <bound method> = bound_method %.loc11_29, %.loc11_45.20 [template = constants.%.43]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.4: init i32 = call %.loc11_45.21(%.loc11_29) [template = constants.%.44]
+// CHECK:STDOUT:   %.loc11_45.22: init i32 = converted %.loc11_29, %int.convert_checked.loc11_45.4 [template = constants.%.44]
+// CHECK:STDOUT:   %.loc11_45.23: i32 = int_value 3 [template = constants.%.42]
 // CHECK:STDOUT:   %.loc11_45.24: ref i32 = array_index file.%a.var, %.loc11_45.23
-// CHECK:STDOUT:   %.loc11_45.25: init i32 = initialize_from %.loc11_41 to %.loc11_45.24 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc11_45.26: i32 = int_value 8 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc11_45.27: ref i32 = array_index file.%a.var, %.loc11_45.26
-// CHECK:STDOUT:   %.loc11_45.28: init i32 = initialize_from %.loc11_44 to %.loc11_45.27 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_45.29: init %.28 = array_init (%.loc11_45.4, %.loc11_45.7, %.loc11_45.10, %.loc11_45.13, %.loc11_45.16, %.loc11_45.19, %.loc11_45.22, %.loc11_45.25, %.loc11_45.28) to file.%a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc11_46: init %.28 = converted %.loc11_45.1, %.loc11_45.29 [template = constants.%array]
+// CHECK:STDOUT:   %.loc11_45.25: init i32 = initialize_from %.loc11_45.22 to %.loc11_45.24 [template = constants.%.44]
+// CHECK:STDOUT:   %.loc11_45.26: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.27: <bound method> = bound_method %.loc11_32, %.loc11_45.26 [template = constants.%.45]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.5: init i32 = call %.loc11_45.27(%.loc11_32) [template = constants.%.46]
+// CHECK:STDOUT:   %.loc11_45.28: init i32 = converted %.loc11_32, %int.convert_checked.loc11_45.5 [template = constants.%.46]
+// CHECK:STDOUT:   %.loc11_45.29: i32 = int_value 4 [template = constants.%.44]
+// CHECK:STDOUT:   %.loc11_45.30: ref i32 = array_index file.%a.var, %.loc11_45.29
+// CHECK:STDOUT:   %.loc11_45.31: init i32 = initialize_from %.loc11_45.28 to %.loc11_45.30 [template = constants.%.46]
+// CHECK:STDOUT:   %.loc11_45.32: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.33: <bound method> = bound_method %.loc11_35, %.loc11_45.32 [template = constants.%.47]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.6: init i32 = call %.loc11_45.33(%.loc11_35) [template = constants.%.48]
+// CHECK:STDOUT:   %.loc11_45.34: init i32 = converted %.loc11_35, %int.convert_checked.loc11_45.6 [template = constants.%.48]
+// CHECK:STDOUT:   %.loc11_45.35: i32 = int_value 5 [template = constants.%.46]
+// CHECK:STDOUT:   %.loc11_45.36: ref i32 = array_index file.%a.var, %.loc11_45.35
+// CHECK:STDOUT:   %.loc11_45.37: init i32 = initialize_from %.loc11_45.34 to %.loc11_45.36 [template = constants.%.48]
+// CHECK:STDOUT:   %.loc11_45.38: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.39: <bound method> = bound_method %.loc11_38, %.loc11_45.38 [template = constants.%.49]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.7: init i32 = call %.loc11_45.39(%.loc11_38) [template = constants.%.50]
+// CHECK:STDOUT:   %.loc11_45.40: init i32 = converted %.loc11_38, %int.convert_checked.loc11_45.7 [template = constants.%.50]
+// CHECK:STDOUT:   %.loc11_45.41: i32 = int_value 6 [template = constants.%.48]
+// CHECK:STDOUT:   %.loc11_45.42: ref i32 = array_index file.%a.var, %.loc11_45.41
+// CHECK:STDOUT:   %.loc11_45.43: init i32 = initialize_from %.loc11_45.40 to %.loc11_45.42 [template = constants.%.50]
+// CHECK:STDOUT:   %.loc11_45.44: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.45: <bound method> = bound_method %.loc11_41, %.loc11_45.44 [template = constants.%.51]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.8: init i32 = call %.loc11_45.45(%.loc11_41) [template = constants.%.52]
+// CHECK:STDOUT:   %.loc11_45.46: init i32 = converted %.loc11_41, %int.convert_checked.loc11_45.8 [template = constants.%.52]
+// CHECK:STDOUT:   %.loc11_45.47: i32 = int_value 7 [template = constants.%.50]
+// CHECK:STDOUT:   %.loc11_45.48: ref i32 = array_index file.%a.var, %.loc11_45.47
+// CHECK:STDOUT:   %.loc11_45.49: init i32 = initialize_from %.loc11_45.46 to %.loc11_45.48 [template = constants.%.52]
+// CHECK:STDOUT:   %.loc11_45.50: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.51: <bound method> = bound_method %.loc11_44, %.loc11_45.50 [template = constants.%.53]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45.9: init i32 = call %.loc11_45.51(%.loc11_44) [template = constants.%.54]
+// CHECK:STDOUT:   %.loc11_45.52: init i32 = converted %.loc11_44, %int.convert_checked.loc11_45.9 [template = constants.%.54]
+// CHECK:STDOUT:   %.loc11_45.53: i32 = int_value 8 [template = constants.%.52]
+// CHECK:STDOUT:   %.loc11_45.54: ref i32 = array_index file.%a.var, %.loc11_45.53
+// CHECK:STDOUT:   %.loc11_45.55: init i32 = initialize_from %.loc11_45.52 to %.loc11_45.54 [template = constants.%.54]
+// CHECK:STDOUT:   %.loc11_45.56: init %.2 = array_init (%.loc11_45.7, %.loc11_45.13, %.loc11_45.19, %.loc11_45.25, %.loc11_45.31, %.loc11_45.37, %.loc11_45.43, %.loc11_45.49, %.loc11_45.55) to file.%a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc11_46: init %.2 = converted %.loc11_45.1, %.loc11_45.56 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%a.var, %.loc11_46
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 129 - 64
toolchain/check/testdata/as/adapter_conversion.carbon

@@ -97,10 +97,10 @@ class B {
 // We do not try to implicitly convert from the first operand of `as` to the
 // adapted type of the second operand.
 
-// CHECK:STDERR: fail_adapt_init_from_struct.carbon:[[@LINE+6]]:12: error: cannot convert from `{.x: i32}` to `B` with `as` [ExplicitAsConversionFailure]
+// CHECK:STDERR: fail_adapt_init_from_struct.carbon:[[@LINE+6]]:12: error: cannot convert from `{.x: Core.IntLiteral}` to `B` with `as` [ExplicitAsConversionFailure]
 // CHECK:STDERR: var b: B = {.x = 1} as B;
 // CHECK:STDERR:            ^~~~~~~~~~~~~
-// CHECK:STDERR: fail_adapt_init_from_struct.carbon:[[@LINE+3]]:12: note: type `{.x: i32}` does not implement interface `As(B)` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fail_adapt_init_from_struct.carbon:[[@LINE+3]]:12: note: type `{.x: Core.IntLiteral}` does not implement interface `As(B)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: var b: B = {.x = 1} as B;
 // CHECK:STDERR:            ^~~~~~~~~~~~~
 var b: B = {.x = 1} as B;
@@ -116,17 +116,27 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   %Make: %Make.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {.x: i32, .y: i32} [template]
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %struct: %A = struct_value (%.5, %.6) [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.7: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.31: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %struct: %A = struct_value (%.33, %.35) [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
-// CHECK:STDOUT:   %.7: <witness> = complete_type_witness %A [template]
-// CHECK:STDOUT:   %.8: type = ptr_type %B [template]
+// CHECK:STDOUT:   %.36: <witness> = complete_type_witness %A [template]
+// CHECK:STDOUT:   %.37: type = ptr_type %B [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -152,7 +162,7 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   %A.ref.loc18: type = name_ref A, %A.decl [template = constants.%A]
 // CHECK:STDOUT:   %B.ref.loc21: type = name_ref B, %B.decl [template = constants.%B]
 // CHECK:STDOUT:   %B.ref.loc22: type = name_ref B, %B.decl [template = constants.%B]
-// CHECK:STDOUT:   %.loc22: type = ptr_type %B [template = constants.%.8]
+// CHECK:STDOUT:   %.loc22: type = ptr_type %B [template = constants.%.37]
 // CHECK:STDOUT:   %B.ref.loc24: type = name_ref B, %B.decl [template = constants.%B]
 // CHECK:STDOUT:   %b_factory.var: ref %B = var b_factory
 // CHECK:STDOUT:   %b_factory: ref %B = bind_name b_factory, %b_factory.var
@@ -187,7 +197,7 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT: class @B {
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
 // CHECK:STDOUT:   adapt_decl %A
-// CHECK:STDOUT:   %.loc15: <witness> = complete_type_witness %A [template = constants.%.7]
+// CHECK:STDOUT:   %.loc15: <witness> = complete_type_witness %A [template = constants.%.36]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%B
@@ -195,29 +205,45 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: %A {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc9_18: i32 = int_value 1 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_26: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_27.1: %.2 = struct_literal (%.loc9_18, %.loc9_26)
-// CHECK:STDOUT:   %.loc9_27.2: ref i32 = class_element_access %return, element0
-// CHECK:STDOUT:   %.loc9_27.3: init i32 = initialize_from %.loc9_18 to %.loc9_27.2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_27.4: ref i32 = class_element_access %return, element1
-// CHECK:STDOUT:   %.loc9_27.5: init i32 = initialize_from %.loc9_26 to %.loc9_27.4 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_27.6: init %A = class_init (%.loc9_27.3, %.loc9_27.5), %return [template = constants.%struct]
-// CHECK:STDOUT:   %.loc9_28: init %A = converted %.loc9_27.1, %.loc9_27.6 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc9_18: Core.IntLiteral = int_value 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_26: Core.IntLiteral = int_value 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_27.1: %.7 = struct_literal (%.loc9_18, %.loc9_26)
+// CHECK:STDOUT:   %.loc9_27.2: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_27.3: <bound method> = bound_method %.loc9_18, %.loc9_27.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc9_27.1: init i32 = call %.loc9_27.3(%.loc9_18) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_27.4: init i32 = converted %.loc9_18, %int.convert_checked.loc9_27.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_27.5: ref i32 = class_element_access %return, element0
+// CHECK:STDOUT:   %.loc9_27.6: init i32 = initialize_from %.loc9_27.4 to %.loc9_27.5 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_27.7: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_27.8: <bound method> = bound_method %.loc9_26, %.loc9_27.7 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked.loc9_27.2: init i32 = call %.loc9_27.8(%.loc9_26) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc9_27.9: init i32 = converted %.loc9_26, %int.convert_checked.loc9_27.2 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc9_27.10: ref i32 = class_element_access %return, element1
+// CHECK:STDOUT:   %.loc9_27.11: init i32 = initialize_from %.loc9_27.9 to %.loc9_27.10 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc9_27.12: init %A = class_init (%.loc9_27.6, %.loc9_27.11), %return [template = constants.%struct]
+// CHECK:STDOUT:   %.loc9_28: init %A = converted %.loc9_27.1, %.loc9_27.12 [template = constants.%struct]
 // CHECK:STDOUT:   return %.loc9_28 to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc17_22: i32 = int_value 1 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc17_30: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc17_31.1: %.2 = struct_literal (%.loc17_22, %.loc17_30)
-// CHECK:STDOUT:   %.loc17_31.2: ref i32 = class_element_access file.%a_ref.var, element0
-// CHECK:STDOUT:   %.loc17_31.3: init i32 = initialize_from %.loc17_22 to %.loc17_31.2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc17_31.4: ref i32 = class_element_access file.%a_ref.var, element1
-// CHECK:STDOUT:   %.loc17_31.5: init i32 = initialize_from %.loc17_30 to %.loc17_31.4 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc17_31.6: init %A = class_init (%.loc17_31.3, %.loc17_31.5), file.%a_ref.var [template = constants.%struct]
-// CHECK:STDOUT:   %.loc17_32: init %A = converted %.loc17_31.1, %.loc17_31.6 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc17_22: Core.IntLiteral = int_value 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_30: Core.IntLiteral = int_value 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc17_31.1: %.7 = struct_literal (%.loc17_22, %.loc17_30)
+// CHECK:STDOUT:   %.loc17_31.2: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_31.3: <bound method> = bound_method %.loc17_22, %.loc17_31.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc17_31.1: init i32 = call %.loc17_31.3(%.loc17_22) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc17_31.4: init i32 = converted %.loc17_22, %int.convert_checked.loc17_31.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc17_31.5: ref i32 = class_element_access file.%a_ref.var, element0
+// CHECK:STDOUT:   %.loc17_31.6: init i32 = initialize_from %.loc17_31.4 to %.loc17_31.5 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc17_31.7: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_31.8: <bound method> = bound_method %.loc17_30, %.loc17_31.7 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked.loc17_31.2: init i32 = call %.loc17_31.8(%.loc17_30) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc17_31.9: init i32 = converted %.loc17_30, %int.convert_checked.loc17_31.2 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc17_31.10: ref i32 = class_element_access file.%a_ref.var, element1
+// CHECK:STDOUT:   %.loc17_31.11: init i32 = initialize_from %.loc17_31.9 to %.loc17_31.10 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc17_31.12: init %A = class_init (%.loc17_31.6, %.loc17_31.11), file.%a_ref.var [template = constants.%struct]
+// CHECK:STDOUT:   %.loc17_32: init %A = converted %.loc17_31.1, %.loc17_31.12 [template = constants.%struct]
 // CHECK:STDOUT:   assign file.%a_ref.var, %.loc17_32
 // CHECK:STDOUT:   %a_ref.ref.loc18: ref %A = name_ref a_ref, file.%a_ref
 // CHECK:STDOUT:   %.loc18: %A = bind_value %a_ref.ref.loc18
@@ -231,8 +257,8 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   %B.ref.loc22: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc22_25.1: ref %B = as_compatible %a_ref.ref.loc22
 // CHECK:STDOUT:   %.loc22_25.2: ref %B = converted %a_ref.ref.loc22, %.loc22_25.1
-// CHECK:STDOUT:   %.loc22_17: %.8 = addr_of %.loc22_25.2
-// CHECK:STDOUT:   %b_ptr: %.8 = bind_name b_ptr, %.loc22_17
+// CHECK:STDOUT:   %.loc22_17: %.37 = addr_of %.loc22_25.2
+// CHECK:STDOUT:   %b_ptr: %.37 = bind_name b_ptr, %.loc22_17
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
 // CHECK:STDOUT:   %Make.ref: %Make.type = name_ref Make, @A.%Make.decl [template = constants.%Make]
 // CHECK:STDOUT:   %.loc24_5: ref %B = splice_block file.%b_factory.var {}
@@ -251,12 +277,19 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %.1: <witness> = complete_type_witness i32 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @As(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .As = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -290,13 +323,18 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc8_13: i32 = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_13: Core.IntLiteral = int_value 1 [template = constants.%.2]
 // CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc8_18.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
 // CHECK:STDOUT:   %.loc8_18.2: type = converted %int.make_type_32.loc8, %.loc8_18.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_15.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_15.2: <bound method> = bound_method %.loc8_13, %.loc8_15.1 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc8_15.2(%.loc8_13) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_15.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_15.4: i32 = converted %.loc8_13, %.loc8_15.3 [template = constants.%.28]
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT:   %.loc8_23.1: %A = as_compatible %.loc8_13 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_23.2: %A = converted %.loc8_13, %.loc8_23.1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_23.1: %A = as_compatible %.loc8_15.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_23.2: %A = converted %.loc8_15.4, %.loc8_23.1 [template = constants.%.28]
 // CHECK:STDOUT:   %a: %A = bind_name a, %.loc8_23.2
 // CHECK:STDOUT:   %a.ref: %A = name_ref a, %a
 // CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%Int32() [template = i32]
@@ -400,14 +438,24 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %.5: <witness> = complete_type_witness %A [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %struct: %A = struct_value (%.6, %.7) [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.7: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.7, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %struct: %A = struct_value (%.34, %.36) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -458,35 +506,51 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc13_25: i32 = int_value 1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc13_33: i32 = int_value 2 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_34.1: %.2 = struct_literal (%.loc13_25, %.loc13_33)
+// CHECK:STDOUT:   %.loc13_25: Core.IntLiteral = int_value 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc13_33: Core.IntLiteral = int_value 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc13_34.1: %.8 = struct_literal (%.loc13_25, %.loc13_33)
 // CHECK:STDOUT:   %A.ref.loc13: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT:   %.loc13_34.2: ref %A = temporary_storage
-// CHECK:STDOUT:   %.loc13_34.3: ref i32 = class_element_access %.loc13_34.2, element0
-// CHECK:STDOUT:   %.loc13_34.4: init i32 = initialize_from %.loc13_25 to %.loc13_34.3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc13_34.5: ref i32 = class_element_access %.loc13_34.2, element1
-// CHECK:STDOUT:   %.loc13_34.6: init i32 = initialize_from %.loc13_33 to %.loc13_34.5 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_34.7: init %A = class_init (%.loc13_34.4, %.loc13_34.6), %.loc13_34.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_34.8: ref %A = temporary %.loc13_34.2, %.loc13_34.7
-// CHECK:STDOUT:   %.loc13_36: ref %A = converted %.loc13_34.1, %.loc13_34.8
+// CHECK:STDOUT:   %.loc13_34.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_34.3: <bound method> = bound_method %.loc13_25, %.loc13_34.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc13_34.1: init i32 = call %.loc13_34.3(%.loc13_25) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_34.4: init i32 = converted %.loc13_25, %int.convert_checked.loc13_34.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_34.5: ref %A = temporary_storage
+// CHECK:STDOUT:   %.loc13_34.6: ref i32 = class_element_access %.loc13_34.5, element0
+// CHECK:STDOUT:   %.loc13_34.7: init i32 = initialize_from %.loc13_34.4 to %.loc13_34.6 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_34.8: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_34.9: <bound method> = bound_method %.loc13_33, %.loc13_34.8 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc13_34.2: init i32 = call %.loc13_34.9(%.loc13_33) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_34.10: init i32 = converted %.loc13_33, %int.convert_checked.loc13_34.2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_34.11: ref i32 = class_element_access %.loc13_34.5, element1
+// CHECK:STDOUT:   %.loc13_34.12: init i32 = initialize_from %.loc13_34.10 to %.loc13_34.11 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_34.13: init %A = class_init (%.loc13_34.7, %.loc13_34.12), %.loc13_34.5 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc13_34.14: ref %A = temporary %.loc13_34.5, %.loc13_34.13
+// CHECK:STDOUT:   %.loc13_36: ref %A = converted %.loc13_34.1, %.loc13_34.14
 // CHECK:STDOUT:   %B.ref.loc13: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc13_42.1: ref %B = as_compatible %.loc13_36
 // CHECK:STDOUT:   %.loc13_42.2: ref %B = converted %.loc13_36, %.loc13_42.1
 // CHECK:STDOUT:   %.loc13_42.3: %B = bind_value %.loc13_42.2
 // CHECK:STDOUT:   %b_value: %B = bind_name b_value, %.loc13_42.3
-// CHECK:STDOUT:   %.loc24_24: i32 = int_value 1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc24_32: i32 = int_value 2 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc24_33.1: %.2 = struct_literal (%.loc24_24, %.loc24_32)
+// CHECK:STDOUT:   %.loc24_24: Core.IntLiteral = int_value 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc24_32: Core.IntLiteral = int_value 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc24_33.1: %.8 = struct_literal (%.loc24_24, %.loc24_32)
 // CHECK:STDOUT:   %A.ref.loc24: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT:   %.loc24_33.2: ref %A = temporary_storage
-// CHECK:STDOUT:   %.loc24_33.3: ref i32 = class_element_access %.loc24_33.2, element0
-// CHECK:STDOUT:   %.loc24_33.4: init i32 = initialize_from %.loc24_24 to %.loc24_33.3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc24_33.5: ref i32 = class_element_access %.loc24_33.2, element1
-// CHECK:STDOUT:   %.loc24_33.6: init i32 = initialize_from %.loc24_32 to %.loc24_33.5 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc24_33.7: init %A = class_init (%.loc24_33.4, %.loc24_33.6), %.loc24_33.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc24_33.8: ref %A = temporary %.loc24_33.2, %.loc24_33.7
-// CHECK:STDOUT:   %.loc24_35: ref %A = converted %.loc24_33.1, %.loc24_33.8
+// CHECK:STDOUT:   %.loc24_33.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc24_33.3: <bound method> = bound_method %.loc24_24, %.loc24_33.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc24_33.1: init i32 = call %.loc24_33.3(%.loc24_24) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc24_33.4: init i32 = converted %.loc24_24, %int.convert_checked.loc24_33.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc24_33.5: ref %A = temporary_storage
+// CHECK:STDOUT:   %.loc24_33.6: ref i32 = class_element_access %.loc24_33.5, element0
+// CHECK:STDOUT:   %.loc24_33.7: init i32 = initialize_from %.loc24_33.4 to %.loc24_33.6 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc24_33.8: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc24_33.9: <bound method> = bound_method %.loc24_32, %.loc24_33.8 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc24_33.2: init i32 = call %.loc24_33.9(%.loc24_32) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc24_33.10: init i32 = converted %.loc24_32, %int.convert_checked.loc24_33.2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc24_33.11: ref i32 = class_element_access %.loc24_33.5, element1
+// CHECK:STDOUT:   %.loc24_33.12: init i32 = initialize_from %.loc24_33.10 to %.loc24_33.11 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc24_33.13: init %A = class_init (%.loc24_33.7, %.loc24_33.12), %.loc24_33.5 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc24_33.14: ref %A = temporary %.loc24_33.5, %.loc24_33.13
+// CHECK:STDOUT:   %.loc24_35: ref %A = converted %.loc24_33.1, %.loc24_33.14
 // CHECK:STDOUT:   %B.ref.loc24: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc24_41.1: ref %B = as_compatible %.loc24_35
 // CHECK:STDOUT:   %.loc24_41.2: ref %B = converted %.loc24_35, %.loc24_41.1
@@ -506,7 +570,8 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %.5: <witness> = complete_type_witness %A [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.7: type = struct_type {.x: Core.IntLiteral} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -556,8 +621,8 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc21_18: i32 = int_value 1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc21_19: %.2 = struct_literal (%.loc21_18)
+// CHECK:STDOUT:   %.loc21_18: Core.IntLiteral = int_value 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc21_19: %.7 = struct_literal (%.loc21_18)
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc21_21: %B = converted %.loc21_19, <error> [template = <error>]
 // CHECK:STDOUT:   assign file.%b.var, <error>

+ 16 - 4
toolchain/check/testdata/as/basic.carbon

@@ -19,12 +19,19 @@ fn Main() -> i32 {
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Main.type: type = fn_type @Main [template]
 // CHECK:STDOUT:   %Main: %Main.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @As(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .As = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -50,10 +57,15 @@ fn Main() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc12_10: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_10: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc12_15.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
 // CHECK:STDOUT:   %.loc12_15.2: type = converted %int.make_type_32.loc12, %.loc12_15.1 [template = i32]
-// CHECK:STDOUT:   return %.loc12_10
+// CHECK:STDOUT:   %.loc12_12.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_12.2: <bound method> = bound_method %.loc12_10, %.loc12_12.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc12_12.2(%.loc12_10) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_12.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_12.4: i32 = converted %.loc12_10, %.loc12_12.3 [template = constants.%.27]
+// CHECK:STDOUT:   return %.loc12_12.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/as/fail_no_conversion.carbon

@@ -8,10 +8,10 @@
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/as/fail_no_conversion.carbon
 
-// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+6]]:21: error: cannot convert from `i32` to `(i32, i32)` with `as` [ExplicitAsConversionFailure]
+// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+6]]:21: error: cannot convert from `Core.IntLiteral` to `(i32, i32)` with `as` [ExplicitAsConversionFailure]
 // CHECK:STDERR: let n: (i32, i32) = 1 as (i32, i32);
 // CHECK:STDERR:                     ^~~~~~~~~~~~~~~
-// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+3]]:21: note: type `i32` does not implement interface `As((i32, i32))` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+3]]:21: note: type `Core.IntLiteral` does not implement interface `As((i32, i32))` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: let n: (i32, i32) = 1 as (i32, i32);
 // CHECK:STDERR:                     ^~~~~~~~~~~~~~~
 let n: (i32, i32) = 1 as (i32, i32);
@@ -23,7 +23,7 @@ let n: (i32, i32) = 1 as (i32, i32);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %tuple.type.1: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -53,7 +53,7 @@ let n: (i32, i32) = 1 as (i32, i32);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc17_21: i32 = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_21: Core.IntLiteral = int_value 1 [template = constants.%.2]
 // CHECK:STDOUT:   %int.make_type_32.loc17_27: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %int.make_type_32.loc17_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc17_35.1: %tuple.type.1 = tuple_literal (%int.make_type_32.loc17_27, %int.make_type_32.loc17_32)

+ 6 - 6
toolchain/check/testdata/as/fail_not_type.carbon

@@ -8,10 +8,10 @@
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/as/fail_not_type.carbon
 
-// CHECK:STDERR: fail_not_type.carbon:[[@LINE+6]]:19: error: cannot implicitly convert from `i32` to `type` [ImplicitAsConversionFailure]
+// CHECK:STDERR: fail_not_type.carbon:[[@LINE+6]]:19: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
 // CHECK:STDERR: let n: i32 = 1 as 2;
 // CHECK:STDERR:                   ^
-// CHECK:STDERR: fail_not_type.carbon:[[@LINE+3]]:19: note: type `i32` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fail_not_type.carbon:[[@LINE+3]]:19: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: let n: i32 = 1 as 2;
 // CHECK:STDERR:                   ^
 let n: i32 = 1 as 2;
@@ -21,8 +21,8 @@ let n: i32 = 1 as 2;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -47,8 +47,8 @@ let n: i32 = 1 as 2;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc17_14: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc17_19.1: i32 = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_14: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc17_19.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc17_19.2: type = converted %.loc17_19.1, <error> [template = <error>]
 // CHECK:STDOUT:   %n: i32 = bind_name n, <error>
 // CHECK:STDOUT:   return

+ 16 - 6
toolchain/check/testdata/as/overloaded.carbon

@@ -43,8 +43,13 @@ let n: i32 = ((4 as i32) as X) as i32;
 // CHECK:STDOUT:   %Convert.4: %Convert.type.4 = struct_value () [template]
 // CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @As(i32) [template]
 // CHECK:STDOUT:   %.12: <witness> = interface_witness (%Convert.4) [template]
-// CHECK:STDOUT:   %.13: i32 = int_value 4 [template]
-// CHECK:STDOUT:   %.33: <bound method> = bound_method %.13, %Convert.2 [template]
+// CHECK:STDOUT:   %.13: Core.IntLiteral = int_value 4 [template]
+// CHECK:STDOUT:   %Convert.type.18: type = fn_type @Convert.13 [template]
+// CHECK:STDOUT:   %Convert.18: %Convert.type.18 = struct_value () [template]
+// CHECK:STDOUT:   %.33: <witness> = interface_witness (%Convert.18) [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.13, %Convert.18 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value 4 [template]
+// CHECK:STDOUT:   %.36: <bound method> = bound_method %.35, %Convert.2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -168,16 +173,21 @@ let n: i32 = ((4 as i32) as X) as i32;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc23_16: i32 = int_value 4 [template = constants.%.13]
+// CHECK:STDOUT:   %.loc23_16: Core.IntLiteral = int_value 4 [template = constants.%.13]
 // CHECK:STDOUT:   %int.make_type_32.loc23_21: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc23_21.1: type = value_of_initializer %int.make_type_32.loc23_21 [template = i32]
 // CHECK:STDOUT:   %.loc23_21.2: type = converted %int.make_type_32.loc23_21, %.loc23_21.1 [template = i32]
+// CHECK:STDOUT:   %.loc23_18.1: %Convert.type.5 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.18]
+// CHECK:STDOUT:   %.loc23_18.2: <bound method> = bound_method %.loc23_16, %.loc23_18.1 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc23_18.2(%.loc23_16) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc23_18.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.35]
+// CHECK:STDOUT:   %.loc23_18.4: i32 = converted %.loc23_16, %.loc23_18.3 [template = constants.%.35]
 // CHECK:STDOUT:   %X.ref: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %.loc23_26.1: %Convert.type.3 = interface_witness_access constants.%.8, element0 [template = constants.%Convert.2]
-// CHECK:STDOUT:   %.loc23_26.2: <bound method> = bound_method %.loc23_16, %.loc23_26.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc23_26.2: <bound method> = bound_method %.loc23_18.4, %.loc23_26.1 [template = constants.%.36]
 // CHECK:STDOUT:   %.loc23_26.3: ref %X = temporary_storage
-// CHECK:STDOUT:   %Convert.call.loc23_26: init %X = call %.loc23_26.2(%.loc23_16) to %.loc23_26.3
-// CHECK:STDOUT:   %.loc23_26.4: init %X = converted %.loc23_16, %Convert.call.loc23_26
+// CHECK:STDOUT:   %Convert.call.loc23_26: init %X = call %.loc23_26.2(%.loc23_18.4) to %.loc23_26.3
+// CHECK:STDOUT:   %.loc23_26.4: init %X = converted %.loc23_18.4, %Convert.call.loc23_26
 // CHECK:STDOUT:   %int.make_type_32.loc23_35: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc23_35.1: type = value_of_initializer %int.make_type_32.loc23_35 [template = i32]
 // CHECK:STDOUT:   %.loc23_35.2: type = converted %int.make_type_32.loc23_35, %.loc23_35.1 [template = i32]

+ 21 - 10
toolchain/check/testdata/basics/builtin_types.carbon

@@ -18,18 +18,25 @@ var test_type: type = i32;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 64 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 64 [template]
 // CHECK:STDOUT:   %Float.type: type = fn_type @Float [template]
 // CHECK:STDOUT:   %Float: %Float.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: f64 = float_literal 0.10000000000000001 [template]
-// CHECK:STDOUT:   %.5: String = string_literal "Test" [template]
+// CHECK:STDOUT:   %.29: f64 = float_literal 0.10000000000000001 [template]
+// CHECK:STDOUT:   %.31: String = string_literal "Test" [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
-// CHECK:STDOUT:     .Float = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Float = %import_ref.51
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -49,7 +56,7 @@ var test_type: type = i32;
 // CHECK:STDOUT:   %.loc11_15.2: type = converted %int.make_type_32, %.loc11_15.1 [template = i32]
 // CHECK:STDOUT:   %test_i32.var: ref i32 = var test_i32
 // CHECK:STDOUT:   %test_i32: ref i32 = bind_name test_i32, %test_i32.var
-// CHECK:STDOUT:   %.loc12_15.1: Core.IntLiteral = int_value 64 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12_15.1: Core.IntLiteral = int_value 64 [template = constants.%.28]
 // CHECK:STDOUT:   %float.make_type: init type = call constants.%Float(%.loc12_15.1) [template = f64]
 // CHECK:STDOUT:   %.loc12_15.2: type = value_of_initializer %float.make_type [template = f64]
 // CHECK:STDOUT:   %.loc12_15.3: type = converted %float.make_type, %.loc12_15.2 [template = f64]
@@ -61,11 +68,15 @@ var test_type: type = i32;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   assign file.%test_i32.var, %.loc11
-// CHECK:STDOUT:   %.loc12: f64 = float_literal 0.10000000000000001 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc11_21: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_22.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_22.2: <bound method> = bound_method %.loc11_21, %.loc11_22.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc11_22.2(%.loc11_21) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc11_22.3: init i32 = converted %.loc11_21, %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   assign file.%test_i32.var, %.loc11_22.3
+// CHECK:STDOUT:   %.loc12: f64 = float_literal 0.10000000000000001 [template = constants.%.29]
 // CHECK:STDOUT:   assign file.%test_f64.var, %.loc12
-// CHECK:STDOUT:   %.loc13: String = string_literal "Test" [template = constants.%.5]
+// CHECK:STDOUT:   %.loc13: String = string_literal "Test" [template = constants.%.31]
 // CHECK:STDOUT:   %test_str: String = bind_name test_str, %.loc13
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   assign file.%test_type.var, %int.make_type_32

+ 4 - 4
toolchain/check/testdata/basics/fail_non_type_as_type.carbon

@@ -8,10 +8,10 @@
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/basics/fail_non_type_as_type.carbon
 
-// CHECK:STDERR: fail_non_type_as_type.carbon:[[@LINE+6]]:1: error: cannot implicitly convert from `i32` to `type` [ImplicitAsConversionFailure]
+// CHECK:STDERR: fail_non_type_as_type.carbon:[[@LINE+6]]:1: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
 // CHECK:STDERR: var x: type = 42;
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~
-// CHECK:STDERR: fail_non_type_as_type.carbon:[[@LINE+3]]:1: note: type `i32` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fail_non_type_as_type.carbon:[[@LINE+3]]:1: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: var x: type = 42;
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~
 var x: type = 42;
@@ -19,7 +19,7 @@ var x: type = 42;
 // CHECK:STDOUT: --- fail_non_type_as_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_value 42 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 42 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -42,7 +42,7 @@ var x: type = 42;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc17_15: i32 = int_value 42 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc17_15: Core.IntLiteral = int_value 42 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc17_17: type = converted %.loc17_15, <error> [template = <error>]
 // CHECK:STDOUT:   assign file.%x.var, <error>
 // CHECK:STDOUT:   return

+ 42 - 13
toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon

@@ -8,21 +8,21 @@
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon
 
-// CHECK:STDERR: fail_numeric_literal_overflow.carbon:[[@LINE+4]]:14: error: integer literal with value 39999999999999999993 does not fit in i32 [IntLiteralTooLargeForI32]
+// CHECK:STDERR: fail_numeric_literal_overflow.carbon:[[@LINE+4]]:1: error: integer value 39999999999999999993 too large for type `i32` [IntTooLargeForType]
 // CHECK:STDERR: let a: i32 = 39999999999999999993;
-// CHECK:STDERR:              ^~~~~~~~~~~~~~~~~~~~
+// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 let a: i32 = 39999999999999999993;
 
-// CHECK:STDERR: fail_numeric_literal_overflow.carbon:[[@LINE+4]]:14: error: integer literal with value 2147483648 does not fit in i32 [IntLiteralTooLargeForI32]
+// CHECK:STDERR: fail_numeric_literal_overflow.carbon:[[@LINE+4]]:1: error: integer value 2147483648 too large for type `i32` [IntTooLargeForType]
 // CHECK:STDERR: let b: i32 = 2_147_483_648;
-// CHECK:STDERR:              ^~~~~~~~~~~~~
+// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 let b: i32 = 2_147_483_648;
 
-// CHECK:STDERR: fail_numeric_literal_overflow.carbon:[[@LINE+4]]:14: error: integer literal with value 2147483648 does not fit in i32 [IntLiteralTooLargeForI32]
+// CHECK:STDERR: fail_numeric_literal_overflow.carbon:[[@LINE+4]]:1: error: integer value 2147483648 too large for type `i32` [IntTooLargeForType]
 // CHECK:STDERR: let c: i32 = 0x8000_0000;
-// CHECK:STDERR:              ^~~~~~~~~~~
+// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 let c: i32 = 0x8000_0000;
 
@@ -42,7 +42,17 @@ let e: f64 = 5.0e39999999999999999993;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 64 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 39999999999999999993 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 39999999999999999993 [template]
+// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 2147483648 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.28, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2147483648 [template]
+// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 64 [template]
 // CHECK:STDOUT:   %Float.type: type = fn_type @Float [template]
 // CHECK:STDOUT:   %Float: %Float.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -50,7 +60,8 @@ let e: f64 = 5.0e39999999999999999993;
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
-// CHECK:STDOUT:     .Float = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Float = %import_ref.51
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -75,11 +86,11 @@ let e: f64 = 5.0e39999999999999999993;
 // CHECK:STDOUT:   %int.make_type_32.loc27: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc27_8.1: type = value_of_initializer %int.make_type_32.loc27 [template = i32]
 // CHECK:STDOUT:   %.loc27_8.2: type = converted %int.make_type_32.loc27, %.loc27_8.1 [template = i32]
-// CHECK:STDOUT:   %.loc33_8.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc33_8.1: Core.IntLiteral = int_value 64 [template = constants.%.31]
 // CHECK:STDOUT:   %float.make_type.loc33: init type = call constants.%Float(%.loc33_8.1) [template = f64]
 // CHECK:STDOUT:   %.loc33_8.2: type = value_of_initializer %float.make_type.loc33 [template = f64]
 // CHECK:STDOUT:   %.loc33_8.3: type = converted %float.make_type.loc33, %.loc33_8.2 [template = f64]
-// CHECK:STDOUT:   %.loc38_8.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc38_8.1: Core.IntLiteral = int_value 64 [template = constants.%.31]
 // CHECK:STDOUT:   %float.make_type.loc38: init type = call constants.%Float(%.loc38_8.1) [template = f64]
 // CHECK:STDOUT:   %.loc38_8.2: type = value_of_initializer %float.make_type.loc38 [template = f64]
 // CHECK:STDOUT:   %.loc38_8.3: type = converted %float.make_type.loc38, %.loc38_8.2 [template = f64]
@@ -87,9 +98,27 @@ let e: f64 = 5.0e39999999999999999993;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %a: i32 = bind_name a, <error>
-// CHECK:STDOUT:   %b: i32 = bind_name b, <error>
-// CHECK:STDOUT:   %c: i32 = bind_name c, <error>
+// CHECK:STDOUT:   %.loc15_14: Core.IntLiteral = int_value 39999999999999999993 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc15_34.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_34.2: <bound method> = bound_method %.loc15_14, %.loc15_34.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc15: init i32 = call %.loc15_34.2(%.loc15_14) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc15_34.3: i32 = value_of_initializer %int.convert_checked.loc15 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc15_34.4: i32 = converted %.loc15_14, %.loc15_34.3 [template = constants.%.27]
+// CHECK:STDOUT:   %a: i32 = bind_name a, %.loc15_34.4
+// CHECK:STDOUT:   %.loc21_14: Core.IntLiteral = int_value 2147483648 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc21_27.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_27.2: <bound method> = bound_method %.loc21_14, %.loc21_27.1 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc21: init i32 = call %.loc21_27.2(%.loc21_14) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc21_27.3: i32 = value_of_initializer %int.convert_checked.loc21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc21_27.4: i32 = converted %.loc21_14, %.loc21_27.3 [template = constants.%.30]
+// CHECK:STDOUT:   %b: i32 = bind_name b, %.loc21_27.4
+// CHECK:STDOUT:   %.loc27_14: Core.IntLiteral = int_value 2147483648 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc27_25.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc27_25.2: <bound method> = bound_method %.loc27_14, %.loc27_25.1 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc27: init i32 = call %.loc27_25.2(%.loc27_14) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc27_25.3: i32 = value_of_initializer %int.convert_checked.loc27 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc27_25.4: i32 = converted %.loc27_14, %.loc27_25.3 [template = constants.%.30]
+// CHECK:STDOUT:   %c: i32 = bind_name c, %.loc27_25.4
 // CHECK:STDOUT:   %d: f64 = bind_name d, <error>
 // CHECK:STDOUT:   %e: f64 = bind_name e, <error>
 // CHECK:STDOUT:   return

+ 104 - 86
toolchain/check/testdata/basics/numeric_literals.carbon

@@ -36,37 +36,41 @@ fn F() {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 6 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 6 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 8 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 9 [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.7: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 6 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 8 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 9 [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (i32, i32, i32, i32, i32, i32) [template]
-// CHECK:STDOUT:   %.33: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.31: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 8 [template]
 // CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.35: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.36: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.37: i32 = int_value 4 [template]
-// CHECK:STDOUT:   %.38: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %array.1: %.28 = tuple_value (%.30, %.31, %.30, %.30, %.32, %.32) [template]
-// CHECK:STDOUT:   %.39: Core.IntLiteral = int_value 64 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 9 [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.39: i32 = int_value 4 [template]
+// CHECK:STDOUT:   %.40: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.41: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.42: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %array.1: %.2 = tuple_value (%.33, %.36, %.33, %.33, %.41, %.41) [template]
+// CHECK:STDOUT:   %.43: Core.IntLiteral = int_value 64 [template]
 // CHECK:STDOUT:   %Float.type: type = fn_type @Float [template]
 // CHECK:STDOUT:   %Float: %Float.type = struct_value () [template]
-// CHECK:STDOUT:   %.40: type = array_type %.27, f64 [template]
-// CHECK:STDOUT:   %.42: f64 = float_literal 0.90000000000000002 [template]
-// CHECK:STDOUT:   %.43: f64 = float_literal 8 [template]
-// CHECK:STDOUT:   %.44: f64 = float_literal 80 [template]
-// CHECK:STDOUT:   %.45: f64 = float_literal 1.0E+7 [template]
-// CHECK:STDOUT:   %.46: f64 = float_literal 1.0E+8 [template]
-// CHECK:STDOUT:   %.47: f64 = float_literal 1.0E-8 [template]
+// CHECK:STDOUT:   %.44: type = array_type %.1, f64 [template]
+// CHECK:STDOUT:   %.46: f64 = float_literal 0.90000000000000002 [template]
+// CHECK:STDOUT:   %.47: f64 = float_literal 8 [template]
+// CHECK:STDOUT:   %.48: f64 = float_literal 80 [template]
+// CHECK:STDOUT:   %.49: f64 = float_literal 1.0E+7 [template]
+// CHECK:STDOUT:   %.50: f64 = float_literal 1.0E+8 [template]
+// CHECK:STDOUT:   %.51: f64 = float_literal 1.0E-8 [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (f64, f64, f64, f64, f64, f64) [template]
-// CHECK:STDOUT:   %array.2: %.40 = tuple_value (%.42, %.43, %.44, %.45, %.46, %.47) [template]
+// CHECK:STDOUT:   %array.2: %.44 = tuple_value (%.46, %.47, %.48, %.49, %.50, %.51) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -91,85 +95,99 @@ fn F() {
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc14_19.1: i32 = int_value 6 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc14_19: Core.IntLiteral = int_value 6 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc14_14.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc14_14.2: type = converted %int.make_type_32, %.loc14_14.1 [template = i32]
-// CHECK:STDOUT:   %.loc14_19.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc14_19.3: <bound method> = bound_method %.loc14_19.1, %.loc14_19.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked.loc14: init Core.IntLiteral = call %.loc14_19.3(%.loc14_19.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_19.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc14 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_19.5: Core.IntLiteral = converted %.loc14_19.1, %.loc14_19.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc14_20: type = array_type %.loc14_19.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %ints.var: ref %.28 = var ints
-// CHECK:STDOUT:   %ints: ref %.28 = bind_name ints, %ints.var
-// CHECK:STDOUT:   %.loc15: i32 = int_value 8 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc16: i32 = int_value 9 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc17: i32 = int_value 8 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc18: i32 = int_value 8 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc19: i32 = int_value 2147483647 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc20: i32 = int_value 2147483647 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_20: type = array_type %.loc14_19, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %ints.var: ref %.2 = var ints
+// CHECK:STDOUT:   %ints: ref %.2 = bind_name ints, %ints.var
+// CHECK:STDOUT:   %.loc15: Core.IntLiteral = int_value 8 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc16: Core.IntLiteral = int_value 9 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17: Core.IntLiteral = int_value 8 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc18: Core.IntLiteral = int_value 8 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc19: Core.IntLiteral = int_value 2147483647 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc20: Core.IntLiteral = int_value 2147483647 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc21_3.1: %tuple.type.1 = tuple_literal (%.loc15, %.loc16, %.loc17, %.loc18, %.loc19, %.loc20)
-// CHECK:STDOUT:   %.loc21_3.2: i32 = int_value 0 [template = constants.%.33]
-// CHECK:STDOUT:   %.loc21_3.3: ref i32 = array_index %ints.var, %.loc21_3.2
-// CHECK:STDOUT:   %.loc21_3.4: init i32 = initialize_from %.loc15 to %.loc21_3.3 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc21_3.5: i32 = int_value 1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc21_3.2: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_3.3: <bound method> = bound_method %.loc15, %.loc21_3.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc21_3.1: init i32 = call %.loc21_3.3(%.loc15) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.4: init i32 = converted %.loc15, %int.convert_checked.loc21_3.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.5: i32 = int_value 0 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc21_3.6: ref i32 = array_index %ints.var, %.loc21_3.5
-// CHECK:STDOUT:   %.loc21_3.7: init i32 = initialize_from %.loc16 to %.loc21_3.6 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc21_3.8: i32 = int_value 2 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc21_3.9: ref i32 = array_index %ints.var, %.loc21_3.8
-// CHECK:STDOUT:   %.loc21_3.10: init i32 = initialize_from %.loc17 to %.loc21_3.9 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc21_3.11: i32 = int_value 3 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc21_3.7: init i32 = initialize_from %.loc21_3.4 to %.loc21_3.6 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.8: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_3.9: <bound method> = bound_method %.loc16, %.loc21_3.8 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc21_3.2: init i32 = call %.loc21_3.9(%.loc16) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc21_3.10: init i32 = converted %.loc16, %int.convert_checked.loc21_3.2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc21_3.11: i32 = int_value 1 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc21_3.12: ref i32 = array_index %ints.var, %.loc21_3.11
-// CHECK:STDOUT:   %.loc21_3.13: init i32 = initialize_from %.loc18 to %.loc21_3.12 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc21_3.14: i32 = int_value 4 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc21_3.15: ref i32 = array_index %ints.var, %.loc21_3.14
-// CHECK:STDOUT:   %.loc21_3.16: init i32 = initialize_from %.loc19 to %.loc21_3.15 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc21_3.17: i32 = int_value 5 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc21_3.13: init i32 = initialize_from %.loc21_3.10 to %.loc21_3.12 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc21_3.14: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_3.15: <bound method> = bound_method %.loc17, %.loc21_3.14 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc21_3.3: init i32 = call %.loc21_3.15(%.loc17) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.16: init i32 = converted %.loc17, %int.convert_checked.loc21_3.3 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.17: i32 = int_value 2 [template = constants.%.37]
 // CHECK:STDOUT:   %.loc21_3.18: ref i32 = array_index %ints.var, %.loc21_3.17
-// CHECK:STDOUT:   %.loc21_3.19: init i32 = initialize_from %.loc20 to %.loc21_3.18 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc21_3.20: init %.28 = array_init (%.loc21_3.4, %.loc21_3.7, %.loc21_3.10, %.loc21_3.13, %.loc21_3.16, %.loc21_3.19) to %ints.var [template = constants.%array.1]
-// CHECK:STDOUT:   %.loc21_4: init %.28 = converted %.loc21_3.1, %.loc21_3.20 [template = constants.%array.1]
+// CHECK:STDOUT:   %.loc21_3.19: init i32 = initialize_from %.loc21_3.16 to %.loc21_3.18 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.20: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_3.21: <bound method> = bound_method %.loc18, %.loc21_3.20 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc21_3.4: init i32 = call %.loc21_3.21(%.loc18) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.22: init i32 = converted %.loc18, %int.convert_checked.loc21_3.4 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.23: i32 = int_value 3 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc21_3.24: ref i32 = array_index %ints.var, %.loc21_3.23
+// CHECK:STDOUT:   %.loc21_3.25: init i32 = initialize_from %.loc21_3.22 to %.loc21_3.24 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc21_3.26: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_3.27: <bound method> = bound_method %.loc19, %.loc21_3.26 [template = constants.%.40]
+// CHECK:STDOUT:   %int.convert_checked.loc21_3.5: init i32 = call %.loc21_3.27(%.loc19) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc21_3.28: init i32 = converted %.loc19, %int.convert_checked.loc21_3.5 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc21_3.29: i32 = int_value 4 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc21_3.30: ref i32 = array_index %ints.var, %.loc21_3.29
+// CHECK:STDOUT:   %.loc21_3.31: init i32 = initialize_from %.loc21_3.28 to %.loc21_3.30 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc21_3.32: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_3.33: <bound method> = bound_method %.loc20, %.loc21_3.32 [template = constants.%.40]
+// CHECK:STDOUT:   %int.convert_checked.loc21_3.6: init i32 = call %.loc21_3.33(%.loc20) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc21_3.34: init i32 = converted %.loc20, %int.convert_checked.loc21_3.6 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc21_3.35: i32 = int_value 5 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc21_3.36: ref i32 = array_index %ints.var, %.loc21_3.35
+// CHECK:STDOUT:   %.loc21_3.37: init i32 = initialize_from %.loc21_3.34 to %.loc21_3.36 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc21_3.38: init %.2 = array_init (%.loc21_3.7, %.loc21_3.13, %.loc21_3.19, %.loc21_3.25, %.loc21_3.31, %.loc21_3.37) to %ints.var [template = constants.%array.1]
+// CHECK:STDOUT:   %.loc21_4: init %.2 = converted %.loc21_3.1, %.loc21_3.38 [template = constants.%array.1]
 // CHECK:STDOUT:   assign %ints.var, %.loc21_4
-// CHECK:STDOUT:   %.loc22_16.1: Core.IntLiteral = int_value 64 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc22_16.1: Core.IntLiteral = int_value 64 [template = constants.%.43]
 // CHECK:STDOUT:   %float.make_type: init type = call constants.%Float(%.loc22_16.1) [template = f64]
-// CHECK:STDOUT:   %.loc22_21.1: i32 = int_value 6 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc22_21: Core.IntLiteral = int_value 6 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc22_16.2: type = value_of_initializer %float.make_type [template = f64]
 // CHECK:STDOUT:   %.loc22_16.3: type = converted %float.make_type, %.loc22_16.2 [template = f64]
-// CHECK:STDOUT:   %.loc22_21.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc22_21.3: <bound method> = bound_method %.loc22_21.1, %.loc22_21.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked.loc22: init Core.IntLiteral = call %.loc22_21.3(%.loc22_21.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc22_21.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc22 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc22_21.5: Core.IntLiteral = converted %.loc22_21.1, %.loc22_21.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc22_22: type = array_type %.loc22_21.5, f64 [template = constants.%.40]
-// CHECK:STDOUT:   %floats.var: ref %.40 = var floats
-// CHECK:STDOUT:   %floats: ref %.40 = bind_name floats, %floats.var
-// CHECK:STDOUT:   %.loc23: f64 = float_literal 0.90000000000000002 [template = constants.%.42]
-// CHECK:STDOUT:   %.loc24: f64 = float_literal 8 [template = constants.%.43]
-// CHECK:STDOUT:   %.loc25: f64 = float_literal 80 [template = constants.%.44]
-// CHECK:STDOUT:   %.loc26: f64 = float_literal 1.0E+7 [template = constants.%.45]
-// CHECK:STDOUT:   %.loc27: f64 = float_literal 1.0E+8 [template = constants.%.46]
-// CHECK:STDOUT:   %.loc28: f64 = float_literal 1.0E-8 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc22_22: type = array_type %.loc22_21, f64 [template = constants.%.44]
+// CHECK:STDOUT:   %floats.var: ref %.44 = var floats
+// CHECK:STDOUT:   %floats: ref %.44 = bind_name floats, %floats.var
+// CHECK:STDOUT:   %.loc23: f64 = float_literal 0.90000000000000002 [template = constants.%.46]
+// CHECK:STDOUT:   %.loc24: f64 = float_literal 8 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc25: f64 = float_literal 80 [template = constants.%.48]
+// CHECK:STDOUT:   %.loc26: f64 = float_literal 1.0E+7 [template = constants.%.49]
+// CHECK:STDOUT:   %.loc27: f64 = float_literal 1.0E+8 [template = constants.%.50]
+// CHECK:STDOUT:   %.loc28: f64 = float_literal 1.0E-8 [template = constants.%.51]
 // CHECK:STDOUT:   %.loc29_3.1: %tuple.type.2 = tuple_literal (%.loc23, %.loc24, %.loc25, %.loc26, %.loc27, %.loc28)
-// CHECK:STDOUT:   %.loc29_3.2: i32 = int_value 0 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc29_3.2: i32 = int_value 0 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc29_3.3: ref f64 = array_index %floats.var, %.loc29_3.2
-// CHECK:STDOUT:   %.loc29_3.4: init f64 = initialize_from %.loc23 to %.loc29_3.3 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc29_3.4: init f64 = initialize_from %.loc23 to %.loc29_3.3 [template = constants.%.46]
 // CHECK:STDOUT:   %.loc29_3.5: i32 = int_value 1 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc29_3.6: ref f64 = array_index %floats.var, %.loc29_3.5
-// CHECK:STDOUT:   %.loc29_3.7: init f64 = initialize_from %.loc24 to %.loc29_3.6 [template = constants.%.43]
-// CHECK:STDOUT:   %.loc29_3.8: i32 = int_value 2 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc29_3.7: init f64 = initialize_from %.loc24 to %.loc29_3.6 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc29_3.8: i32 = int_value 2 [template = constants.%.37]
 // CHECK:STDOUT:   %.loc29_3.9: ref f64 = array_index %floats.var, %.loc29_3.8
-// CHECK:STDOUT:   %.loc29_3.10: init f64 = initialize_from %.loc25 to %.loc29_3.9 [template = constants.%.44]
-// CHECK:STDOUT:   %.loc29_3.11: i32 = int_value 3 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc29_3.10: init f64 = initialize_from %.loc25 to %.loc29_3.9 [template = constants.%.48]
+// CHECK:STDOUT:   %.loc29_3.11: i32 = int_value 3 [template = constants.%.38]
 // CHECK:STDOUT:   %.loc29_3.12: ref f64 = array_index %floats.var, %.loc29_3.11
-// CHECK:STDOUT:   %.loc29_3.13: init f64 = initialize_from %.loc26 to %.loc29_3.12 [template = constants.%.45]
-// CHECK:STDOUT:   %.loc29_3.14: i32 = int_value 4 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc29_3.13: init f64 = initialize_from %.loc26 to %.loc29_3.12 [template = constants.%.49]
+// CHECK:STDOUT:   %.loc29_3.14: i32 = int_value 4 [template = constants.%.39]
 // CHECK:STDOUT:   %.loc29_3.15: ref f64 = array_index %floats.var, %.loc29_3.14
-// CHECK:STDOUT:   %.loc29_3.16: init f64 = initialize_from %.loc27 to %.loc29_3.15 [template = constants.%.46]
-// CHECK:STDOUT:   %.loc29_3.17: i32 = int_value 5 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc29_3.16: init f64 = initialize_from %.loc27 to %.loc29_3.15 [template = constants.%.50]
+// CHECK:STDOUT:   %.loc29_3.17: i32 = int_value 5 [template = constants.%.42]
 // CHECK:STDOUT:   %.loc29_3.18: ref f64 = array_index %floats.var, %.loc29_3.17
-// CHECK:STDOUT:   %.loc29_3.19: init f64 = initialize_from %.loc28 to %.loc29_3.18 [template = constants.%.47]
-// CHECK:STDOUT:   %.loc29_3.20: init %.40 = array_init (%.loc29_3.4, %.loc29_3.7, %.loc29_3.10, %.loc29_3.13, %.loc29_3.16, %.loc29_3.19) to %floats.var [template = constants.%array.2]
-// CHECK:STDOUT:   %.loc29_4: init %.40 = converted %.loc29_3.1, %.loc29_3.20 [template = constants.%array.2]
+// CHECK:STDOUT:   %.loc29_3.19: init f64 = initialize_from %.loc28 to %.loc29_3.18 [template = constants.%.51]
+// CHECK:STDOUT:   %.loc29_3.20: init %.44 = array_init (%.loc29_3.4, %.loc29_3.7, %.loc29_3.10, %.loc29_3.13, %.loc29_3.16, %.loc29_3.19) to %floats.var [template = constants.%array.2]
+// CHECK:STDOUT:   %.loc29_4: init %.44 = converted %.loc29_3.1, %.loc29_3.20 [template = constants.%array.2]
 // CHECK:STDOUT:   assign %floats.var, %.loc29_4
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 24 - 7
toolchain/check/testdata/basics/parens.carbon

@@ -16,13 +16,22 @@ var b: i32 = ((2));
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.28, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -49,10 +58,18 @@ var b: i32 = ((2));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   assign file.%a.var, %.loc11
-// CHECK:STDOUT:   %.loc12: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   assign file.%b.var, %.loc12
+// CHECK:STDOUT:   %.loc11_15: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_17.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_17.2: <bound method> = bound_method %.loc11_15, %.loc11_17.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc11: init i32 = call %.loc11_17.2(%.loc11_15) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc11_17.3: init i32 = converted %.loc11_15, %int.convert_checked.loc11 [template = constants.%.27]
+// CHECK:STDOUT:   assign file.%a.var, %.loc11_17.3
+// CHECK:STDOUT:   %.loc12_16: Core.IntLiteral = int_value 2 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_19.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_19.2: <bound method> = bound_method %.loc12_16, %.loc12_19.1 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc12: init i32 = call %.loc12_19.2(%.loc12_16) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc12_19.3: init i32 = converted %.loc12_16, %int.convert_checked.loc12 [template = constants.%.30]
+// CHECK:STDOUT:   assign file.%b.var, %.loc12_19.3
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 16 - 4
toolchain/check/testdata/basics/run_i32.carbon

@@ -17,12 +17,19 @@ fn Run() -> i32 { return 0; }
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Run.type: type = fn_type @Run [template]
 // CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -48,7 +55,12 @@ fn Run() -> i32 { return 0; }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_26: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   return %.loc11_26
+// CHECK:STDOUT:   %.loc11_26: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_27.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.2: <bound method> = bound_method %.loc11_26, %.loc11_27.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc11_27.2(%.loc11_26) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc11_27.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc11_27.4: i32 = converted %.loc11_26, %.loc11_27.3 [template = constants.%.27]
+// CHECK:STDOUT:   return %.loc11_27.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 43 - 13
toolchain/check/testdata/builtins/float/make_type.carbon

@@ -90,8 +90,14 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Float.type: type = fn_type @Float [template]
 // CHECK:STDOUT:   %Float: %Float.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 64 [template]
-// CHECK:STDOUT:   %.2: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 64 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 64 [template]
+// CHECK:STDOUT:   %.28: f64 = float_literal 0 [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %GetFloat.type: type = fn_type @GetFloat [template]
@@ -101,7 +107,8 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %Float.type = import_ref Main//types, inst+22, loaded [template = constants.%Float]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Int32 = %import_ref.51
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -117,8 +124,13 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
 // CHECK:STDOUT:   %Float.ref: %Float.type = name_ref Float, imports.%import_ref.1 [template = constants.%Float]
-// CHECK:STDOUT:   %.loc6_14: i32 = int_value 64 [template = constants.%.1]
-// CHECK:STDOUT:   %float.make_type: init type = call %Float.ref(%.loc6_14) [template = f64]
+// CHECK:STDOUT:   %.loc6_14.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_14.3: <bound method> = bound_method %.loc6_14.1, %.loc6_14.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc6_14.3(%.loc6_14.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc6_14.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc6_14.5: i32 = converted %.loc6_14.1, %.loc6_14.4 [template = constants.%.27]
+// CHECK:STDOUT:   %float.make_type: init type = call %Float.ref(%.loc6_14.5) [template = f64]
 // CHECK:STDOUT:   %.loc6_16.1: type = value_of_initializer %float.make_type [template = f64]
 // CHECK:STDOUT:   %.loc6_16.2: type = converted %float.make_type, %.loc6_16.1 [template = f64]
 // CHECK:STDOUT:   %f.var: ref f64 = var f
@@ -153,7 +165,7 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc6: f64 = float_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6: f64 = float_literal 0 [template = constants.%.28]
 // CHECK:STDOUT:   assign file.%f.var, %.loc6
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -163,16 +175,25 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Float.type: type = fn_type @Float [template]
 // CHECK:STDOUT:   %Float: %Float.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 32 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 32 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 32 [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 64 [template]
+// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 64 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.28, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 64 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %Float.type = import_ref Main//types, inst+22, loaded [template = constants.%Float]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Int32 = %import_ref.51
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -189,8 +210,13 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
 // CHECK:STDOUT:   %Float.ref.loc10: %Float.type = name_ref Float, imports.%import_ref.1 [template = constants.%Float]
-// CHECK:STDOUT:   %.loc10_26: i32 = int_value 32 [template = constants.%.1]
-// CHECK:STDOUT:   %float.make_type.loc10: init type = call %Float.ref.loc10(%.loc10_26) [template = <error>]
+// CHECK:STDOUT:   %.loc10_26.1: Core.IntLiteral = int_value 32 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_26.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_26.3: <bound method> = bound_method %.loc10_26.1, %.loc10_26.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc10_26.3(%.loc10_26.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_26.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_26.5: i32 = converted %.loc10_26.1, %.loc10_26.4 [template = constants.%.27]
+// CHECK:STDOUT:   %float.make_type.loc10: init type = call %Float.ref.loc10(%.loc10_26.5) [template = <error>]
 // CHECK:STDOUT:   %.loc10_28.1: type = value_of_initializer %float.make_type.loc10 [template = <error>]
 // CHECK:STDOUT:   %.loc10_28.2: type = converted %float.make_type.loc10, %.loc10_28.1 [template = <error>]
 // CHECK:STDOUT:   %invalid_float.var: ref <error> = var invalid_float
@@ -214,8 +240,12 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc12: i32 = int_value 64 [template = constants.%.2]
-// CHECK:STDOUT:   assign file.%dyn_size.var, %.loc12
+// CHECK:STDOUT:   %.loc12_21: Core.IntLiteral = int_value 64 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_23.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_23.2: <bound method> = bound_method %.loc12_21, %.loc12_23.1 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc12_23.2(%.loc12_21) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc12_23.3: init i32 = converted %.loc12_21, %int.convert_checked [template = constants.%.30]
+// CHECK:STDOUT:   assign file.%dyn_size.var, %.loc12_23.3
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 46 - 33
toolchain/check/testdata/builtins/int/and.carbon

@@ -26,17 +26,25 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %And.type: type = fn_type @And [template]
 // CHECK:STDOUT:   %And: %And.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 12 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 10 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 8 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 12 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 10 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 8 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 12 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 10 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 8 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 8 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -85,32 +93,37 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %And.ref: %And.type = name_ref And, %And.decl [template = constants.%And]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 12 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_24: i32 = int_value 10 [template = constants.%.2]
-// CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%.loc4_20, %.loc4_24) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 12 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_24.1: Core.IntLiteral = int_value 10 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_24.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_24.3: <bound method> = bound_method %.loc4_24.1, %.loc4_24.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_24: init i32 = call %.loc4_24.3(%.loc4_24.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_24.4: i32 = value_of_initializer %int.convert_checked.loc4_24 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_24.5: i32 = converted %.loc4_24.1, %.loc4_24.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%.loc4_20.5, %.loc4_24.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.and, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.and [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.and, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.and, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_27: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.and, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.and [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.and, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.and, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_27: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 8 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 8 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -152,9 +165,9 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 50 - 37
toolchain/check/testdata/builtins/int/complement.carbon

@@ -29,18 +29,26 @@ fn RuntimeCall(a: i32) -> i32 {
 // CHECK:STDOUT:   %Complement: %Complement.type = struct_value () [template]
 // CHECK:STDOUT:   %And.type: type = fn_type @And [template]
 // CHECK:STDOUT:   %And: %And.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1193046 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -1193047 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 16777215 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 15584169 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1193046 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.29: <bound method> = bound_method %.4, %Convert.15 [template]
-// CHECK:STDOUT:   %.30: Core.IntLiteral = int_value 15584169 [template]
-// CHECK:STDOUT:   %.31: type = array_type %.30, i32 [template]
-// CHECK:STDOUT:   %.32: type = ptr_type %.31 [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1193046 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -1193047 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 16777215 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 16777215 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 15584169 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.33: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.32, %Convert.16 [template]
+// CHECK:STDOUT:   %.35: Core.IntLiteral = int_value 15584169 [template]
+// CHECK:STDOUT:   %.36: type = array_type %.35, i32 [template]
+// CHECK:STDOUT:   %.37: type = ptr_type %.36 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -108,35 +116,40 @@ fn RuntimeCall(a: i32) -> i32 {
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %And.ref: %And.type = name_ref And, %And.decl [template = constants.%And]
 // CHECK:STDOUT:   %Complement.ref: %Complement.type = name_ref Complement, %Complement.decl [template = constants.%Complement]
-// CHECK:STDOUT:   %.loc5_31: i32 = int_value 1193046 [template = constants.%.1]
-// CHECK:STDOUT:   %int.complement: init i32 = call %Complement.ref(%.loc5_31) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc5_42: i32 = int_value 16777215 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_30.1: i32 = value_of_initializer %int.complement [template = constants.%.2]
-// CHECK:STDOUT:   %.loc5_30.2: i32 = converted %int.complement, %.loc5_30.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%.loc5_30.2, %.loc5_42) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_31.1: Core.IntLiteral = int_value 1193046 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc5_31.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc5_31.3: <bound method> = bound_method %.loc5_31.1, %.loc5_31.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc5_31: init i32 = call %.loc5_31.3(%.loc5_31.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_31.4: i32 = value_of_initializer %int.convert_checked.loc5_31 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_31.5: i32 = converted %.loc5_31.1, %.loc5_31.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.complement: init i32 = call %Complement.ref(%.loc5_31.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc5_42.1: Core.IntLiteral = int_value 16777215 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc5_30.1: i32 = value_of_initializer %int.complement [template = constants.%.28]
+// CHECK:STDOUT:   %.loc5_30.2: i32 = converted %int.complement, %.loc5_30.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc5_42.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc5_42.3: <bound method> = bound_method %.loc5_42.1, %.loc5_42.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc5_42: init i32 = call %.loc5_42.3(%.loc5_42.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_42.4: i32 = value_of_initializer %int.convert_checked.loc5_42 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_42.5: i32 = converted %.loc5_42.1, %.loc5_42.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%.loc5_30.2, %.loc5_42.5) [template = constants.%.32]
 // CHECK:STDOUT:   %.loc5_11.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_11.2: type = converted %int.make_type_32.loc5, %.loc5_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_19.1: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_19.2: <bound method> = bound_method %int.and, %.loc5_19.1 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19.3: i32 = value_of_initializer %int.and [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_19.4: i32 = converted %int.and, %.loc5_19.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_19.2(%.loc5_19.4) [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_19.6: Core.IntLiteral = converted %int.and, %.loc5_19.5 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_51: type = array_type %.loc5_19.6, i32 [template = constants.%.31]
-// CHECK:STDOUT:   %arr.var: ref %.31 = var arr
-// CHECK:STDOUT:   %arr: ref %.31 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc5_19.1: %Convert.type.5 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc5_19.2: <bound method> = bound_method %int.and, %.loc5_19.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc5_19.3: i32 = value_of_initializer %int.and [template = constants.%.32]
+// CHECK:STDOUT:   %.loc5_19.4: i32 = converted %int.and, %.loc5_19.3 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc5_19: init Core.IntLiteral = call %.loc5_19.2(%.loc5_19.4) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5_19 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_19.6: Core.IntLiteral = converted %int.and, %.loc5_19.5 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_51: type = array_type %.loc5_19.6, i32 [template = constants.%.36]
+// CHECK:STDOUT:   %arr.var: ref %.36 = var arr
+// CHECK:STDOUT:   %arr: ref %.36 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc6_18.1: i32 = int_value 15584169 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_18: Core.IntLiteral = int_value 15584169 [template = constants.%.35]
 // CHECK:STDOUT:   %.loc6_13.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
 // CHECK:STDOUT:   %.loc6_13.2: type = converted %int.make_type_32.loc6, %.loc6_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc6_18.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc6_18.3: <bound method> = bound_method %.loc6_18.1, %.loc6_18.2 [template = constants.%.29]
-// CHECK:STDOUT:   %int.convert_checked.loc6: init Core.IntLiteral = call %.loc6_18.3(%.loc6_18.1) [template = constants.%.30]
-// CHECK:STDOUT:   %.loc6_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc6 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc6_18.5: Core.IntLiteral = converted %.loc6_18.1, %.loc6_18.4 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc6_26: type = array_type %.loc6_18.5, i32 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc6_27: type = ptr_type %.31 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc6_26: type = array_type %.loc6_18, i32 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc6_27: type = ptr_type %.36 [template = constants.%.37]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -172,9 +185,9 @@ fn RuntimeCall(a: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.31 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc6: %.32 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.32 = bind_name arr_p, %.loc6
+// CHECK:STDOUT:   %arr.ref: ref %.36 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc6: %.37 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.37 = bind_name arr_p, %.loc6
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

Разница между файлами не показана из-за своего большого размера
+ 510 - 300
toolchain/check/testdata/builtins/int/convert_checked.carbon


+ 43 - 14
toolchain/check/testdata/builtins/int/eq.carbon

@@ -48,10 +48,18 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.7: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.31: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.35: bool = bool_literal false [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -60,6 +68,7 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -160,11 +169,21 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %Eq.ref.loc8: %Eq.type = name_ref Eq, file.%Eq.decl [template = constants.%Eq]
-// CHECK:STDOUT:   %.loc8_19: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc8_22: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19, %.loc8_22) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc8_13.1: bool = value_of_initializer %int.eq.loc8 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc8_13.2: bool = converted %int.eq.loc8, %.loc8_13.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc8_19.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_22.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_19.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_19.3: <bound method> = bound_method %.loc8_19.1, %.loc8_19.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc8_19: init i32 = call %.loc8_19.3(%.loc8_19.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_19.4: i32 = value_of_initializer %int.convert_checked.loc8_19 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_19.5: i32 = converted %.loc8_19.1, %.loc8_19.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_22.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_22.3: <bound method> = bound_method %.loc8_22.1, %.loc8_22.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc8_22: init i32 = call %.loc8_22.3(%.loc8_22.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_22.4: i32 = value_of_initializer %int.convert_checked.loc8_22 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_22.5: i32 = converted %.loc8_22.1, %.loc8_22.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19.5, %.loc8_22.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_13.1: bool = value_of_initializer %int.eq.loc8 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_13.2: bool = converted %int.eq.loc8, %.loc8_13.1 [template = constants.%.31]
 // CHECK:STDOUT:   if %.loc8_13.2 br !if.expr.then.loc8 else br !if.expr.else.loc8
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc8:
@@ -179,11 +198,21 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:   %.loc8_13.3: type = block_arg !if.expr.result.loc8 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %Eq.ref.loc9: %Eq.type = name_ref Eq, file.%Eq.decl [template = constants.%Eq]
-// CHECK:STDOUT:   %.loc9_20: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_23: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   %int.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_23) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %int.eq.loc9 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_14.2: bool = converted %int.eq.loc9, %.loc9_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_20.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_23.1: Core.IntLiteral = int_value 2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_20.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_20.3: <bound method> = bound_method %.loc9_20.1, %.loc9_20.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc9_20: init i32 = call %.loc9_20.3(%.loc9_20.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc9_20.4: i32 = value_of_initializer %int.convert_checked.loc9_20 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc9_20.5: i32 = converted %.loc9_20.1, %.loc9_20.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc9_23.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_23.3: <bound method> = bound_method %.loc9_23.1, %.loc9_23.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc9_23: init i32 = call %.loc9_23.3(%.loc9_23.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_23.4: i32 = value_of_initializer %int.convert_checked.loc9_23 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_23.5: i32 = converted %.loc9_23.1, %.loc9_23.4 [template = constants.%.34]
+// CHECK:STDOUT:   %int.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20.5, %.loc9_23.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %int.eq.loc9 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc9_14.2: bool = converted %int.eq.loc9, %.loc9_14.1 [template = constants.%.35]
 // CHECK:STDOUT:   if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:

+ 98 - 37
toolchain/check/testdata/builtins/int/greater.carbon

@@ -45,12 +45,22 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.6: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.8: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.9: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.34: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.35: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.36: <bound method> = bound_method %.35, %Convert.15 [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.38: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.39: i32 = int_value -1 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -59,6 +69,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -179,11 +190,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %false_.ref.loc9: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %Greater.ref.loc9: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_28: i32 = int_value 2 [template = constants.%.5]
-// CHECK:STDOUT:   %int.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25, %.loc9_28) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %int.greater.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_14.2: bool = converted %int.greater.loc9, %.loc9_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_25.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_28.1: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_25.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_25.3: <bound method> = bound_method %.loc9_25.1, %.loc9_25.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc9_25: init i32 = call %.loc9_25.3(%.loc9_25.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_25.4: i32 = value_of_initializer %int.convert_checked.loc9_25 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_25.5: i32 = converted %.loc9_25.1, %.loc9_25.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_28.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_28.3: <bound method> = bound_method %.loc9_28.1, %.loc9_28.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc9_28: init i32 = call %.loc9_28.3(%.loc9_28.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_28.4: i32 = value_of_initializer %int.convert_checked.loc9_28 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_28.5: i32 = converted %.loc9_28.1, %.loc9_28.4 [template = constants.%.33]
+// CHECK:STDOUT:   %int.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25.5, %.loc9_28.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %int.greater.loc9 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_14.2: bool = converted %int.greater.loc9, %.loc9_14.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -198,11 +219,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
 // CHECK:STDOUT:   %false_.ref.loc10: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %Greater.ref.loc10: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT:   %.loc10_25: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_28: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_28) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc10_14.1: bool = value_of_initializer %int.greater.loc10 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc10_14.2: bool = converted %int.greater.loc10, %.loc10_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc10_25.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_28.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_25.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_25.3: <bound method> = bound_method %.loc10_25.1, %.loc10_25.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc10_25: init i32 = call %.loc10_25.3(%.loc10_25.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_25.4: i32 = value_of_initializer %int.convert_checked.loc10_25 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_25.5: i32 = converted %.loc10_25.1, %.loc10_25.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_28.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_28.3: <bound method> = bound_method %.loc10_28.1, %.loc10_28.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc10_28: init i32 = call %.loc10_28.3(%.loc10_28.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_28.4: i32 = value_of_initializer %int.convert_checked.loc10_28 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_28.5: i32 = converted %.loc10_28.1, %.loc10_28.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25.5, %.loc10_28.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_14.1: bool = value_of_initializer %int.greater.loc10 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_14.2: bool = converted %int.greater.loc10, %.loc10_14.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc10_14.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc10:
@@ -217,11 +248,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc11: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %Greater.ref.loc11: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT:   %.loc11_24: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_27: i32 = int_value 0 [template = constants.%.7]
-// CHECK:STDOUT:   %int.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_27) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc11_13.1: bool = value_of_initializer %int.greater.loc11 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc11_13.2: bool = converted %int.greater.loc11, %.loc11_13.1 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc11_24.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_27.1: Core.IntLiteral = int_value 0 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc11_24.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_24.3: <bound method> = bound_method %.loc11_24.1, %.loc11_24.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc11_24: init i32 = call %.loc11_24.3(%.loc11_24.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_24.4: i32 = value_of_initializer %int.convert_checked.loc11_24 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_24.5: i32 = converted %.loc11_24.1, %.loc11_24.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_27.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.3: <bound method> = bound_method %.loc11_27.1, %.loc11_27.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc11_27: init i32 = call %.loc11_27.3(%.loc11_27.1) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc11_27.4: i32 = value_of_initializer %int.convert_checked.loc11_27 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc11_27.5: i32 = converted %.loc11_27.1, %.loc11_27.4 [template = constants.%.37]
+// CHECK:STDOUT:   %int.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24.5, %.loc11_27.5) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_13.1: bool = value_of_initializer %int.greater.loc11 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_13.2: bool = converted %int.greater.loc11, %.loc11_13.1 [template = constants.%.38]
 // CHECK:STDOUT:   if %.loc11_13.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc11:
@@ -237,14 +278,24 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %false_.ref.loc12: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %Greater.ref.loc12: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
 // CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_32: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_36: i32 = int_value 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc12_31.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_31.2: i32 = converted %int.snegate.loc12, %.loc12_31.1 [template = constants.%.9]
-// CHECK:STDOUT:   %int.greater.loc12: init bool = call %Greater.ref.loc12(%.loc12_31.2, %.loc12_36) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_14.1: bool = value_of_initializer %int.greater.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_14.2: bool = converted %int.greater.loc12, %.loc12_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_32.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_32.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_32.3: <bound method> = bound_method %.loc12_32.1, %.loc12_32.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_32: init i32 = call %.loc12_32.3(%.loc12_32.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_32.4: i32 = value_of_initializer %int.convert_checked.loc12_32 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_32.5: i32 = converted %.loc12_32.1, %.loc12_32.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_32.5) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_36.1: Core.IntLiteral = int_value 0 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc12_31.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_31.2: i32 = converted %int.snegate.loc12, %.loc12_31.1 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_36.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_36.3: <bound method> = bound_method %.loc12_36.1, %.loc12_36.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc12_36: init i32 = call %.loc12_36.3(%.loc12_36.1) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc12_36.4: i32 = value_of_initializer %int.convert_checked.loc12_36 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc12_36.5: i32 = converted %.loc12_36.1, %.loc12_36.4 [template = constants.%.37]
+// CHECK:STDOUT:   %int.greater.loc12: init bool = call %Greater.ref.loc12(%.loc12_31.2, %.loc12_36.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_14.1: bool = value_of_initializer %int.greater.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_14.2: bool = converted %int.greater.loc12, %.loc12_14.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc12_14.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc12:
@@ -259,15 +310,25 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc13: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %Greater.ref.loc13: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT:   %.loc13_24: i32 = int_value 0 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc13_24.1: Core.IntLiteral = int_value 0 [template = constants.%.35]
 // CHECK:STDOUT:   %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc13_34: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_33.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_33.2: i32 = converted %int.snegate.loc13, %.loc13_33.1 [template = constants.%.9]
-// CHECK:STDOUT:   %int.greater.loc13: init bool = call %Greater.ref.loc13(%.loc13_24, %.loc13_33.2) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc13_13.1: bool = value_of_initializer %int.greater.loc13 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc13_13.2: bool = converted %int.greater.loc13, %.loc13_13.1 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc13_34.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc13_34.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_34.3: <bound method> = bound_method %.loc13_34.1, %.loc13_34.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc13_34: init i32 = call %.loc13_34.3(%.loc13_34.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_34.4: i32 = value_of_initializer %int.convert_checked.loc13_34 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_34.5: i32 = converted %.loc13_34.1, %.loc13_34.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34.5) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_24.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_24.3: <bound method> = bound_method %.loc13_24.1, %.loc13_24.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc13_24: init i32 = call %.loc13_24.3(%.loc13_24.1) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc13_24.4: i32 = value_of_initializer %int.convert_checked.loc13_24 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc13_24.5: i32 = converted %.loc13_24.1, %.loc13_24.4 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc13_33.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_33.2: i32 = converted %int.snegate.loc13, %.loc13_33.1 [template = constants.%.39]
+// CHECK:STDOUT:   %int.greater.loc13: init bool = call %Greater.ref.loc13(%.loc13_24.5, %.loc13_33.2) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_13.1: bool = value_of_initializer %int.greater.loc13 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_13.2: bool = converted %int.greater.loc13, %.loc13_13.1 [template = constants.%.38]
 // CHECK:STDOUT:   if %.loc13_13.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc13:

+ 98 - 37
toolchain/check/testdata/builtins/int/greater_eq.carbon

@@ -45,12 +45,22 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.6: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.7: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.8: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.9: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.34: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.35: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.37: <bound method> = bound_method %.36, %Convert.15 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.39: i32 = int_value -1 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -59,6 +69,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -179,11 +190,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %false_.ref.loc9: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %GreaterEq.ref.loc9: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT:   %.loc9_27: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_30: i32 = int_value 2 [template = constants.%.5]
-// CHECK:STDOUT:   %int.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27, %.loc9_30) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %int.greater_eq.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_14.2: bool = converted %int.greater_eq.loc9, %.loc9_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_27.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_30.1: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_27.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_27.3: <bound method> = bound_method %.loc9_27.1, %.loc9_27.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc9_27: init i32 = call %.loc9_27.3(%.loc9_27.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_27.4: i32 = value_of_initializer %int.convert_checked.loc9_27 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_27.5: i32 = converted %.loc9_27.1, %.loc9_27.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_30.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_30.3: <bound method> = bound_method %.loc9_30.1, %.loc9_30.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc9_30: init i32 = call %.loc9_30.3(%.loc9_30.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_30.4: i32 = value_of_initializer %int.convert_checked.loc9_30 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_30.5: i32 = converted %.loc9_30.1, %.loc9_30.4 [template = constants.%.33]
+// CHECK:STDOUT:   %int.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27.5, %.loc9_30.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %int.greater_eq.loc9 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_14.2: bool = converted %int.greater_eq.loc9, %.loc9_14.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -198,11 +219,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc10: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %GreaterEq.ref.loc10: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT:   %.loc10_26: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_29: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_29) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_13.1: bool = value_of_initializer %int.greater_eq.loc10 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_13.2: bool = converted %int.greater_eq.loc10, %.loc10_13.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc10_26.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_29.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_26.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_26.3: <bound method> = bound_method %.loc10_26.1, %.loc10_26.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc10_26: init i32 = call %.loc10_26.3(%.loc10_26.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_26.4: i32 = value_of_initializer %int.convert_checked.loc10_26 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_26.5: i32 = converted %.loc10_26.1, %.loc10_26.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_29.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_29.3: <bound method> = bound_method %.loc10_29.1, %.loc10_29.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc10_29: init i32 = call %.loc10_29.3(%.loc10_29.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_29.4: i32 = value_of_initializer %int.convert_checked.loc10_29 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_29.5: i32 = converted %.loc10_29.1, %.loc10_29.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26.5, %.loc10_29.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc10_13.1: bool = value_of_initializer %int.greater_eq.loc10 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc10_13.2: bool = converted %int.greater_eq.loc10, %.loc10_13.1 [template = constants.%.35]
 // CHECK:STDOUT:   if %.loc10_13.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc10:
@@ -217,11 +248,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
 // CHECK:STDOUT:   %true_.ref.loc11: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %GreaterEq.ref.loc11: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT:   %.loc11_26: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_29: i32 = int_value 0 [template = constants.%.8]
-// CHECK:STDOUT:   %int.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_29) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc11_13.1: bool = value_of_initializer %int.greater_eq.loc11 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc11_13.2: bool = converted %int.greater_eq.loc11, %.loc11_13.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc11_26.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_29.1: Core.IntLiteral = int_value 0 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_26.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_26.3: <bound method> = bound_method %.loc11_26.1, %.loc11_26.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc11_26: init i32 = call %.loc11_26.3(%.loc11_26.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_26.4: i32 = value_of_initializer %int.convert_checked.loc11_26 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_26.5: i32 = converted %.loc11_26.1, %.loc11_26.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_29.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_29.3: <bound method> = bound_method %.loc11_29.1, %.loc11_29.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc11_29: init i32 = call %.loc11_29.3(%.loc11_29.1) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_29.4: i32 = value_of_initializer %int.convert_checked.loc11_29 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_29.5: i32 = converted %.loc11_29.1, %.loc11_29.4 [template = constants.%.38]
+// CHECK:STDOUT:   %int.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26.5, %.loc11_29.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc11_13.1: bool = value_of_initializer %int.greater_eq.loc11 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc11_13.2: bool = converted %int.greater_eq.loc11, %.loc11_13.1 [template = constants.%.35]
 // CHECK:STDOUT:   if %.loc11_13.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc11:
@@ -237,14 +278,24 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %false_.ref.loc12: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %GreaterEq.ref.loc12: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
 // CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_34: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_38: i32 = int_value 0 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc12_33.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_33.2: i32 = converted %int.snegate.loc12, %.loc12_33.1 [template = constants.%.9]
-// CHECK:STDOUT:   %int.greater_eq.loc12: init bool = call %GreaterEq.ref.loc12(%.loc12_33.2, %.loc12_38) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_14.1: bool = value_of_initializer %int.greater_eq.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_14.2: bool = converted %int.greater_eq.loc12, %.loc12_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_34.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_34.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_34.3: <bound method> = bound_method %.loc12_34.1, %.loc12_34.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_34: init i32 = call %.loc12_34.3(%.loc12_34.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_34.4: i32 = value_of_initializer %int.convert_checked.loc12_34 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_34.5: i32 = converted %.loc12_34.1, %.loc12_34.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_34.5) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_38.1: Core.IntLiteral = int_value 0 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc12_33.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_33.2: i32 = converted %int.snegate.loc12, %.loc12_33.1 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_38.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_38.3: <bound method> = bound_method %.loc12_38.1, %.loc12_38.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc12_38: init i32 = call %.loc12_38.3(%.loc12_38.1) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc12_38.4: i32 = value_of_initializer %int.convert_checked.loc12_38 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc12_38.5: i32 = converted %.loc12_38.1, %.loc12_38.4 [template = constants.%.38]
+// CHECK:STDOUT:   %int.greater_eq.loc12: init bool = call %GreaterEq.ref.loc12(%.loc12_33.2, %.loc12_38.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_14.1: bool = value_of_initializer %int.greater_eq.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_14.2: bool = converted %int.greater_eq.loc12, %.loc12_14.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc12_14.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc12:
@@ -259,15 +310,25 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc13: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %GreaterEq.ref.loc13: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT:   %.loc13_26: i32 = int_value 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc13_26.1: Core.IntLiteral = int_value 0 [template = constants.%.36]
 // CHECK:STDOUT:   %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc13_36: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_35.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_35.2: i32 = converted %int.snegate.loc13, %.loc13_35.1 [template = constants.%.9]
-// CHECK:STDOUT:   %int.greater_eq.loc13: init bool = call %GreaterEq.ref.loc13(%.loc13_26, %.loc13_35.2) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_13.1: bool = value_of_initializer %int.greater_eq.loc13 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_13.2: bool = converted %int.greater_eq.loc13, %.loc13_13.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc13_36.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc13_36.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_36.3: <bound method> = bound_method %.loc13_36.1, %.loc13_36.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc13_36: init i32 = call %.loc13_36.3(%.loc13_36.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_36.4: i32 = value_of_initializer %int.convert_checked.loc13_36 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_36.5: i32 = converted %.loc13_36.1, %.loc13_36.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_36.5) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_26.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_26.3: <bound method> = bound_method %.loc13_26.1, %.loc13_26.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc13_26: init i32 = call %.loc13_26.3(%.loc13_26.1) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_26.4: i32 = value_of_initializer %int.convert_checked.loc13_26 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_26.5: i32 = converted %.loc13_26.1, %.loc13_26.4 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_35.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_35.2: i32 = converted %int.snegate.loc13, %.loc13_35.1 [template = constants.%.39]
+// CHECK:STDOUT:   %int.greater_eq.loc13: init bool = call %GreaterEq.ref.loc13(%.loc13_26.5, %.loc13_35.2) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc13_13.1: bool = value_of_initializer %int.greater_eq.loc13 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc13_13.2: bool = converted %int.greater_eq.loc13, %.loc13_13.1 [template = constants.%.35]
 // CHECK:STDOUT:   if %.loc13_13.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc13:

+ 185 - 75
toolchain/check/testdata/builtins/int/left_shift.carbon

@@ -70,17 +70,25 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %LeftShift.type: type = fn_type @LeftShift [template]
 // CHECK:STDOUT:   %LeftShift: %LeftShift.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 20 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 20 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 20 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 20 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -129,32 +137,37 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %LeftShift.ref: %LeftShift.type = name_ref LeftShift, %LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc4_26: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_29: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.left_shift: init i32 = call %LeftShift.ref(%.loc4_26, %.loc4_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_26.1: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_29.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_26.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_26.3: <bound method> = bound_method %.loc4_26.1, %.loc4_26.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_26: init i32 = call %.loc4_26.3(%.loc4_26.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_26.4: i32 = value_of_initializer %int.convert_checked.loc4_26 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_26.5: i32 = converted %.loc4_26.1, %.loc4_26.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_29.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_29.3: <bound method> = bound_method %.loc4_29.1, %.loc4_29.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_29: init i32 = call %.loc4_29.3(%.loc4_29.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_29.4: i32 = value_of_initializer %int.convert_checked.loc4_29 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_29.5: i32 = converted %.loc4_29.1, %.loc4_29.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.left_shift: init i32 = call %LeftShift.ref(%.loc4_26.5, %.loc4_29.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_25.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_25.2: <bound method> = bound_method %int.left_shift, %.loc4_25.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_25.3: i32 = value_of_initializer %int.left_shift [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25.4: i32 = converted %int.left_shift, %.loc4_25.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_25.2(%.loc4_25.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25.6: Core.IntLiteral = converted %int.left_shift, %.loc4_25.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_31: type = array_type %.loc4_25.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_25.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_25.2: <bound method> = bound_method %int.left_shift, %.loc4_25.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_25.3: i32 = value_of_initializer %int.left_shift [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_25.4: i32 = converted %int.left_shift, %.loc4_25.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_25: init Core.IntLiteral = call %.loc4_25.2(%.loc4_25.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_25 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25.6: Core.IntLiteral = converted %int.left_shift, %.loc4_25.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_31: type = array_type %.loc4_25.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 20 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 20 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_20: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_21: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_20: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_21: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -196,9 +209,9 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -211,19 +224,36 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT:   %LeftShift: %LeftShift.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 31 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value -2147483648 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 32 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 33 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 1000 [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.8: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 31 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 31 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 32 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 32 [template]
+// CHECK:STDOUT:   %.35: Core.IntLiteral = int_value 33 [template]
+// CHECK:STDOUT:   %.36: <bound method> = bound_method %.35, %Convert.15 [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 33 [template]
+// CHECK:STDOUT:   %.38: Core.IntLiteral = int_value 1000 [template]
+// CHECK:STDOUT:   %.39: <bound method> = bound_method %.38, %Convert.15 [template]
+// CHECK:STDOUT:   %.40: i32 = int_value 1000 [template]
+// CHECK:STDOUT:   %.41: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.42: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.43: <bound method> = bound_method %.42, %Convert.15 [template]
+// CHECK:STDOUT:   %.44: i32 = int_value -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -318,62 +348,142 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %LeftShift.ref.loc8: %LeftShift.type = name_ref LeftShift, file.%LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc8_29: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_32: i32 = int_value 31 [template = constants.%.2]
-// CHECK:STDOUT:   %int.left_shift.loc8: init i32 = call %LeftShift.ref.loc8(%.loc8_29, %.loc8_32) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_35.1: i32 = value_of_initializer %int.left_shift.loc8 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_35.2: i32 = converted %int.left_shift.loc8, %.loc8_35.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_29.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_32.1: Core.IntLiteral = int_value 31 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_29.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_29.3: <bound method> = bound_method %.loc8_29.1, %.loc8_29.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc8_29: init i32 = call %.loc8_29.3(%.loc8_29.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_29.4: i32 = value_of_initializer %int.convert_checked.loc8_29 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_29.5: i32 = converted %.loc8_29.1, %.loc8_29.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_32.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_32.3: <bound method> = bound_method %.loc8_32.1, %.loc8_32.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc8_32: init i32 = call %.loc8_32.3(%.loc8_32.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_32.4: i32 = value_of_initializer %int.convert_checked.loc8_32 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_32.5: i32 = converted %.loc8_32.1, %.loc8_32.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.left_shift.loc8: init i32 = call %LeftShift.ref.loc8(%.loc8_29.5, %.loc8_32.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_35.1: i32 = value_of_initializer %int.left_shift.loc8 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_35.2: i32 = converted %int.left_shift.loc8, %.loc8_35.1 [template = constants.%.31]
 // CHECK:STDOUT:   %size_1: i32 = bind_name size_1, %.loc8_35.2
 // CHECK:STDOUT:   %LeftShift.ref.loc13: %LeftShift.type = name_ref LeftShift, file.%LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc13_29: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc13_32: i32 = int_value 32 [template = constants.%.4]
-// CHECK:STDOUT:   %int.left_shift.loc13: init i32 = call %LeftShift.ref.loc13(%.loc13_29, %.loc13_32) [template = <error>]
+// CHECK:STDOUT:   %.loc13_29.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc13_32.1: Core.IntLiteral = int_value 32 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc13_29.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_29.3: <bound method> = bound_method %.loc13_29.1, %.loc13_29.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc13_29: init i32 = call %.loc13_29.3(%.loc13_29.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_29.4: i32 = value_of_initializer %int.convert_checked.loc13_29 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_29.5: i32 = converted %.loc13_29.1, %.loc13_29.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_32.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_32.3: <bound method> = bound_method %.loc13_32.1, %.loc13_32.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc13_32: init i32 = call %.loc13_32.3(%.loc13_32.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_32.4: i32 = value_of_initializer %int.convert_checked.loc13_32 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_32.5: i32 = converted %.loc13_32.1, %.loc13_32.4 [template = constants.%.34]
+// CHECK:STDOUT:   %int.left_shift.loc13: init i32 = call %LeftShift.ref.loc13(%.loc13_29.5, %.loc13_32.5) [template = <error>]
 // CHECK:STDOUT:   %.loc13_35.1: i32 = value_of_initializer %int.left_shift.loc13 [template = <error>]
 // CHECK:STDOUT:   %.loc13_35.2: i32 = converted %int.left_shift.loc13, %.loc13_35.1 [template = <error>]
 // CHECK:STDOUT:   %size_2: i32 = bind_name size_2, %.loc13_35.2
 // CHECK:STDOUT:   %LeftShift.ref.loc18: %LeftShift.type = name_ref LeftShift, file.%LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc18_29: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc18_32: i32 = int_value 33 [template = constants.%.5]
-// CHECK:STDOUT:   %int.left_shift.loc18: init i32 = call %LeftShift.ref.loc18(%.loc18_29, %.loc18_32) [template = <error>]
+// CHECK:STDOUT:   %.loc18_29.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc18_32.1: Core.IntLiteral = int_value 33 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc18_29.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc18_29.3: <bound method> = bound_method %.loc18_29.1, %.loc18_29.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc18_29: init i32 = call %.loc18_29.3(%.loc18_29.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc18_29.4: i32 = value_of_initializer %int.convert_checked.loc18_29 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc18_29.5: i32 = converted %.loc18_29.1, %.loc18_29.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc18_32.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc18_32.3: <bound method> = bound_method %.loc18_32.1, %.loc18_32.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc18_32: init i32 = call %.loc18_32.3(%.loc18_32.1) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc18_32.4: i32 = value_of_initializer %int.convert_checked.loc18_32 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc18_32.5: i32 = converted %.loc18_32.1, %.loc18_32.4 [template = constants.%.37]
+// CHECK:STDOUT:   %int.left_shift.loc18: init i32 = call %LeftShift.ref.loc18(%.loc18_29.5, %.loc18_32.5) [template = <error>]
 // CHECK:STDOUT:   %.loc18_35.1: i32 = value_of_initializer %int.left_shift.loc18 [template = <error>]
 // CHECK:STDOUT:   %.loc18_35.2: i32 = converted %int.left_shift.loc18, %.loc18_35.1 [template = <error>]
 // CHECK:STDOUT:   %size_3: i32 = bind_name size_3, %.loc18_35.2
 // CHECK:STDOUT:   %LeftShift.ref.loc21: %LeftShift.type = name_ref LeftShift, file.%LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc21_33: i32 = int_value 1000 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc21_39: i32 = int_value 31 [template = constants.%.2]
-// CHECK:STDOUT:   %int.left_shift.loc21: init i32 = call %LeftShift.ref.loc21(%.loc21_33, %.loc21_39) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc21_42.1: i32 = value_of_initializer %int.left_shift.loc21 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc21_42.2: i32 = converted %int.left_shift.loc21, %.loc21_42.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc21_33.1: Core.IntLiteral = int_value 1000 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc21_39.1: Core.IntLiteral = int_value 31 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc21_33.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_33.3: <bound method> = bound_method %.loc21_33.1, %.loc21_33.2 [template = constants.%.39]
+// CHECK:STDOUT:   %int.convert_checked.loc21_33: init i32 = call %.loc21_33.3(%.loc21_33.1) [template = constants.%.40]
+// CHECK:STDOUT:   %.loc21_33.4: i32 = value_of_initializer %int.convert_checked.loc21_33 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc21_33.5: i32 = converted %.loc21_33.1, %.loc21_33.4 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc21_39.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc21_39.3: <bound method> = bound_method %.loc21_39.1, %.loc21_39.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc21_39: init i32 = call %.loc21_39.3(%.loc21_39.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc21_39.4: i32 = value_of_initializer %int.convert_checked.loc21_39 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc21_39.5: i32 = converted %.loc21_39.1, %.loc21_39.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.left_shift.loc21: init i32 = call %LeftShift.ref.loc21(%.loc21_33.5, %.loc21_39.5) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc21_42.1: i32 = value_of_initializer %int.left_shift.loc21 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc21_42.2: i32 = converted %int.left_shift.loc21, %.loc21_42.1 [template = constants.%.41]
 // CHECK:STDOUT:   %overflow_1: i32 = bind_name overflow_1, %.loc21_42.2
 // CHECK:STDOUT:   %LeftShift.ref.loc26: %LeftShift.type = name_ref LeftShift, file.%LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc26_33: i32 = int_value 1000 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc26_39: i32 = int_value 32 [template = constants.%.4]
-// CHECK:STDOUT:   %int.left_shift.loc26: init i32 = call %LeftShift.ref.loc26(%.loc26_33, %.loc26_39) [template = <error>]
+// CHECK:STDOUT:   %.loc26_33.1: Core.IntLiteral = int_value 1000 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc26_39.1: Core.IntLiteral = int_value 32 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc26_33.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc26_33.3: <bound method> = bound_method %.loc26_33.1, %.loc26_33.2 [template = constants.%.39]
+// CHECK:STDOUT:   %int.convert_checked.loc26_33: init i32 = call %.loc26_33.3(%.loc26_33.1) [template = constants.%.40]
+// CHECK:STDOUT:   %.loc26_33.4: i32 = value_of_initializer %int.convert_checked.loc26_33 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc26_33.5: i32 = converted %.loc26_33.1, %.loc26_33.4 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc26_39.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc26_39.3: <bound method> = bound_method %.loc26_39.1, %.loc26_39.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc26_39: init i32 = call %.loc26_39.3(%.loc26_39.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc26_39.4: i32 = value_of_initializer %int.convert_checked.loc26_39 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc26_39.5: i32 = converted %.loc26_39.1, %.loc26_39.4 [template = constants.%.34]
+// CHECK:STDOUT:   %int.left_shift.loc26: init i32 = call %LeftShift.ref.loc26(%.loc26_33.5, %.loc26_39.5) [template = <error>]
 // CHECK:STDOUT:   %.loc26_42.1: i32 = value_of_initializer %int.left_shift.loc26 [template = <error>]
 // CHECK:STDOUT:   %.loc26_42.2: i32 = converted %int.left_shift.loc26, %.loc26_42.1 [template = <error>]
 // CHECK:STDOUT:   %overflow_2: i32 = bind_name overflow_2, %.loc26_42.2
 // CHECK:STDOUT:   %LeftShift.ref.loc29: %LeftShift.type = name_ref LeftShift, file.%LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc29_36: i32 = int_value 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc29_39: i32 = int_value 31 [template = constants.%.2]
-// CHECK:STDOUT:   %int.left_shift.loc29: init i32 = call %LeftShift.ref.loc29(%.loc29_36, %.loc29_39) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc29_42.1: i32 = value_of_initializer %int.left_shift.loc29 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc29_42.2: i32 = converted %int.left_shift.loc29, %.loc29_42.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc29_36.1: Core.IntLiteral = int_value 0 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc29_39.1: Core.IntLiteral = int_value 31 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc29_36.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc29_36.3: <bound method> = bound_method %.loc29_36.1, %.loc29_36.2 [template = constants.%.43]
+// CHECK:STDOUT:   %int.convert_checked.loc29_36: init i32 = call %.loc29_36.3(%.loc29_36.1) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc29_36.4: i32 = value_of_initializer %int.convert_checked.loc29_36 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc29_36.5: i32 = converted %.loc29_36.1, %.loc29_36.4 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc29_39.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc29_39.3: <bound method> = bound_method %.loc29_39.1, %.loc29_39.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc29_39: init i32 = call %.loc29_39.3(%.loc29_39.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc29_39.4: i32 = value_of_initializer %int.convert_checked.loc29_39 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc29_39.5: i32 = converted %.loc29_39.1, %.loc29_39.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.left_shift.loc29: init i32 = call %LeftShift.ref.loc29(%.loc29_36.5, %.loc29_39.5) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc29_42.1: i32 = value_of_initializer %int.left_shift.loc29 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc29_42.2: i32 = converted %int.left_shift.loc29, %.loc29_42.1 [template = constants.%.41]
 // CHECK:STDOUT:   %no_overflow_1: i32 = bind_name no_overflow_1, %.loc29_42.2
 // CHECK:STDOUT:   %LeftShift.ref.loc34: %LeftShift.type = name_ref LeftShift, file.%LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc34_36: i32 = int_value 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc34_39: i32 = int_value 32 [template = constants.%.4]
-// CHECK:STDOUT:   %int.left_shift.loc34: init i32 = call %LeftShift.ref.loc34(%.loc34_36, %.loc34_39) [template = <error>]
+// CHECK:STDOUT:   %.loc34_36.1: Core.IntLiteral = int_value 0 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc34_39.1: Core.IntLiteral = int_value 32 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc34_36.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc34_36.3: <bound method> = bound_method %.loc34_36.1, %.loc34_36.2 [template = constants.%.43]
+// CHECK:STDOUT:   %int.convert_checked.loc34_36: init i32 = call %.loc34_36.3(%.loc34_36.1) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc34_36.4: i32 = value_of_initializer %int.convert_checked.loc34_36 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc34_36.5: i32 = converted %.loc34_36.1, %.loc34_36.4 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc34_39.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc34_39.3: <bound method> = bound_method %.loc34_39.1, %.loc34_39.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc34_39: init i32 = call %.loc34_39.3(%.loc34_39.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc34_39.4: i32 = value_of_initializer %int.convert_checked.loc34_39 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc34_39.5: i32 = converted %.loc34_39.1, %.loc34_39.4 [template = constants.%.34]
+// CHECK:STDOUT:   %int.left_shift.loc34: init i32 = call %LeftShift.ref.loc34(%.loc34_36.5, %.loc34_39.5) [template = <error>]
 // CHECK:STDOUT:   %.loc34_42.1: i32 = value_of_initializer %int.left_shift.loc34 [template = <error>]
 // CHECK:STDOUT:   %.loc34_42.2: i32 = converted %int.left_shift.loc34, %.loc34_42.1 [template = <error>]
 // CHECK:STDOUT:   %no_overflow_2: i32 = bind_name no_overflow_2, %.loc34_42.2
 // CHECK:STDOUT:   %LeftShift.ref.loc40: %LeftShift.type = name_ref LeftShift, file.%LeftShift.decl [template = constants.%LeftShift]
-// CHECK:STDOUT:   %.loc40_31: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc40_31.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %Negate.ref: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc40_41: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc40_41) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc40_40.1: i32 = value_of_initializer %int.snegate [template = constants.%.8]
-// CHECK:STDOUT:   %.loc40_40.2: i32 = converted %int.snegate, %.loc40_40.1 [template = constants.%.8]
-// CHECK:STDOUT:   %int.left_shift.loc40: init i32 = call %LeftShift.ref.loc40(%.loc40_31, %.loc40_40.2) [template = <error>]
+// CHECK:STDOUT:   %.loc40_41.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc40_41.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc40_41.3: <bound method> = bound_method %.loc40_41.1, %.loc40_41.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc40_41: init i32 = call %.loc40_41.3(%.loc40_41.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc40_41.4: i32 = value_of_initializer %int.convert_checked.loc40_41 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc40_41.5: i32 = converted %.loc40_41.1, %.loc40_41.4 [template = constants.%.28]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc40_41.5) [template = constants.%.44]
+// CHECK:STDOUT:   %.loc40_31.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc40_31.3: <bound method> = bound_method %.loc40_31.1, %.loc40_31.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc40_31: init i32 = call %.loc40_31.3(%.loc40_31.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc40_31.4: i32 = value_of_initializer %int.convert_checked.loc40_31 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc40_31.5: i32 = converted %.loc40_31.1, %.loc40_31.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc40_40.1: i32 = value_of_initializer %int.snegate [template = constants.%.44]
+// CHECK:STDOUT:   %.loc40_40.2: i32 = converted %int.snegate, %.loc40_40.1 [template = constants.%.44]
+// CHECK:STDOUT:   %int.left_shift.loc40: init i32 = call %LeftShift.ref.loc40(%.loc40_31.5, %.loc40_40.2) [template = <error>]
 // CHECK:STDOUT:   %.loc40_44.1: i32 = value_of_initializer %int.left_shift.loc40 [template = <error>]
 // CHECK:STDOUT:   %.loc40_44.2: i32 = converted %int.left_shift.loc40, %.loc40_44.1 [template = <error>]
 // CHECK:STDOUT:   %negative: i32 = bind_name negative, %.loc40_44.2

+ 98 - 37
toolchain/check/testdata/builtins/int/less.carbon

@@ -45,12 +45,22 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.6: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.7: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.8: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.9: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.34: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.35: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.37: <bound method> = bound_method %.36, %Convert.15 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.39: i32 = int_value -1 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -59,6 +69,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -179,11 +190,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref.loc9: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %Less.ref.loc9: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT:   %.loc9_21: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_24: i32 = int_value 2 [template = constants.%.5]
-// CHECK:STDOUT:   %int.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21, %.loc9_24) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %int.less.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_13.2: bool = converted %int.less.loc9, %.loc9_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_21.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_24.1: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_21.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_21.3: <bound method> = bound_method %.loc9_21.1, %.loc9_21.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc9_21: init i32 = call %.loc9_21.3(%.loc9_21.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_21.4: i32 = value_of_initializer %int.convert_checked.loc9_21 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_21.5: i32 = converted %.loc9_21.1, %.loc9_21.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_24.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_24.3: <bound method> = bound_method %.loc9_24.1, %.loc9_24.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc9_24: init i32 = call %.loc9_24.3(%.loc9_24.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_24.4: i32 = value_of_initializer %int.convert_checked.loc9_24 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_24.5: i32 = converted %.loc9_24.1, %.loc9_24.4 [template = constants.%.33]
+// CHECK:STDOUT:   %int.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21.5, %.loc9_24.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %int.less.loc9 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_13.2: bool = converted %int.less.loc9, %.loc9_13.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -198,11 +219,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc10: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %Less.ref.loc10: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT:   %.loc10_22: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_25: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_25) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_14.1: bool = value_of_initializer %int.less.loc10 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_14.2: bool = converted %int.less.loc10, %.loc10_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc10_22.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_25.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_22.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_22.3: <bound method> = bound_method %.loc10_22.1, %.loc10_22.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc10_22: init i32 = call %.loc10_22.3(%.loc10_22.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_22.4: i32 = value_of_initializer %int.convert_checked.loc10_22 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_22.5: i32 = converted %.loc10_22.1, %.loc10_22.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_25.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_25.3: <bound method> = bound_method %.loc10_25.1, %.loc10_25.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc10_25: init i32 = call %.loc10_25.3(%.loc10_25.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_25.4: i32 = value_of_initializer %int.convert_checked.loc10_25 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_25.5: i32 = converted %.loc10_25.1, %.loc10_25.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22.5, %.loc10_25.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc10_14.1: bool = value_of_initializer %int.less.loc10 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc10_14.2: bool = converted %int.less.loc10, %.loc10_14.1 [template = constants.%.35]
 // CHECK:STDOUT:   if %.loc10_14.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc10:
@@ -217,11 +248,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
 // CHECK:STDOUT:   %false_.ref.loc11: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %Less.ref.loc11: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT:   %.loc11_22: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_25: i32 = int_value 0 [template = constants.%.8]
-// CHECK:STDOUT:   %int.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_25) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc11_14.1: bool = value_of_initializer %int.less.loc11 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc11_14.2: bool = converted %int.less.loc11, %.loc11_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc11_22.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_25.1: Core.IntLiteral = int_value 0 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_22.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_22.3: <bound method> = bound_method %.loc11_22.1, %.loc11_22.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc11_22: init i32 = call %.loc11_22.3(%.loc11_22.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_22.4: i32 = value_of_initializer %int.convert_checked.loc11_22 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_22.5: i32 = converted %.loc11_22.1, %.loc11_22.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_25.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_25.3: <bound method> = bound_method %.loc11_25.1, %.loc11_25.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc11_25: init i32 = call %.loc11_25.3(%.loc11_25.1) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_25.4: i32 = value_of_initializer %int.convert_checked.loc11_25 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_25.5: i32 = converted %.loc11_25.1, %.loc11_25.4 [template = constants.%.38]
+// CHECK:STDOUT:   %int.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22.5, %.loc11_25.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc11_14.1: bool = value_of_initializer %int.less.loc11 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc11_14.2: bool = converted %int.less.loc11, %.loc11_14.1 [template = constants.%.35]
 // CHECK:STDOUT:   if %.loc11_14.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc11:
@@ -237,14 +278,24 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %true_.ref.loc12: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %Less.ref.loc12: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
 // CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_28: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_32: i32 = int_value 0 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc12_27.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_27.2: i32 = converted %int.snegate.loc12, %.loc12_27.1 [template = constants.%.9]
-// CHECK:STDOUT:   %int.less.loc12: init bool = call %Less.ref.loc12(%.loc12_27.2, %.loc12_32) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_13.1: bool = value_of_initializer %int.less.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_13.2: bool = converted %int.less.loc12, %.loc12_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_28.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_28.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_28.3: <bound method> = bound_method %.loc12_28.1, %.loc12_28.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_28: init i32 = call %.loc12_28.3(%.loc12_28.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_28.4: i32 = value_of_initializer %int.convert_checked.loc12_28 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_28.5: i32 = converted %.loc12_28.1, %.loc12_28.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_28.5) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_32.1: Core.IntLiteral = int_value 0 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc12_27.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_27.2: i32 = converted %int.snegate.loc12, %.loc12_27.1 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_32.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_32.3: <bound method> = bound_method %.loc12_32.1, %.loc12_32.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc12_32: init i32 = call %.loc12_32.3(%.loc12_32.1) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc12_32.4: i32 = value_of_initializer %int.convert_checked.loc12_32 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc12_32.5: i32 = converted %.loc12_32.1, %.loc12_32.4 [template = constants.%.38]
+// CHECK:STDOUT:   %int.less.loc12: init bool = call %Less.ref.loc12(%.loc12_27.2, %.loc12_32.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_13.1: bool = value_of_initializer %int.less.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_13.2: bool = converted %int.less.loc12, %.loc12_13.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc12_13.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc12:
@@ -259,15 +310,25 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc13: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %Less.ref.loc13: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT:   %.loc13_22: i32 = int_value 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc13_22.1: Core.IntLiteral = int_value 0 [template = constants.%.36]
 // CHECK:STDOUT:   %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc13_32: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_32) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_31.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_31.2: i32 = converted %int.snegate.loc13, %.loc13_31.1 [template = constants.%.9]
-// CHECK:STDOUT:   %int.less.loc13: init bool = call %Less.ref.loc13(%.loc13_22, %.loc13_31.2) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_14.1: bool = value_of_initializer %int.less.loc13 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_14.2: bool = converted %int.less.loc13, %.loc13_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc13_32.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc13_32.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_32.3: <bound method> = bound_method %.loc13_32.1, %.loc13_32.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc13_32: init i32 = call %.loc13_32.3(%.loc13_32.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_32.4: i32 = value_of_initializer %int.convert_checked.loc13_32 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_32.5: i32 = converted %.loc13_32.1, %.loc13_32.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_32.5) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_22.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_22.3: <bound method> = bound_method %.loc13_22.1, %.loc13_22.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc13_22: init i32 = call %.loc13_22.3(%.loc13_22.1) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_22.4: i32 = value_of_initializer %int.convert_checked.loc13_22 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_22.5: i32 = converted %.loc13_22.1, %.loc13_22.4 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_31.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_31.2: i32 = converted %int.snegate.loc13, %.loc13_31.1 [template = constants.%.39]
+// CHECK:STDOUT:   %int.less.loc13: init bool = call %Less.ref.loc13(%.loc13_22.5, %.loc13_31.2) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc13_14.1: bool = value_of_initializer %int.less.loc13 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc13_14.2: bool = converted %int.less.loc13, %.loc13_14.1 [template = constants.%.35]
 // CHECK:STDOUT:   if %.loc13_14.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc13:

+ 98 - 37
toolchain/check/testdata/builtins/int/less_eq.carbon

@@ -45,12 +45,22 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.6: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.8: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.9: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.34: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.35: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.36: <bound method> = bound_method %.35, %Convert.15 [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.38: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.39: i32 = int_value -1 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -59,6 +69,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -179,11 +190,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref.loc9: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %LessEq.ref.loc9: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT:   %.loc9_23: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_26: i32 = int_value 2 [template = constants.%.5]
-// CHECK:STDOUT:   %int.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23, %.loc9_26) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %int.less_eq.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_13.2: bool = converted %int.less_eq.loc9, %.loc9_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_23.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_26.1: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_23.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_23.3: <bound method> = bound_method %.loc9_23.1, %.loc9_23.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc9_23: init i32 = call %.loc9_23.3(%.loc9_23.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_23.4: i32 = value_of_initializer %int.convert_checked.loc9_23 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_23.5: i32 = converted %.loc9_23.1, %.loc9_23.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_26.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_26.3: <bound method> = bound_method %.loc9_26.1, %.loc9_26.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc9_26: init i32 = call %.loc9_26.3(%.loc9_26.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_26.4: i32 = value_of_initializer %int.convert_checked.loc9_26 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_26.5: i32 = converted %.loc9_26.1, %.loc9_26.4 [template = constants.%.33]
+// CHECK:STDOUT:   %int.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23.5, %.loc9_26.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %int.less_eq.loc9 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_13.2: bool = converted %int.less_eq.loc9, %.loc9_13.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -198,11 +219,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
 // CHECK:STDOUT:   %true_.ref.loc10: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %LessEq.ref.loc10: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT:   %.loc10_23: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_26: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_26) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc10_13.1: bool = value_of_initializer %int.less_eq.loc10 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc10_13.2: bool = converted %int.less_eq.loc10, %.loc10_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc10_23.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_26.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_23.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_23.3: <bound method> = bound_method %.loc10_23.1, %.loc10_23.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc10_23: init i32 = call %.loc10_23.3(%.loc10_23.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_23.4: i32 = value_of_initializer %int.convert_checked.loc10_23 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_23.5: i32 = converted %.loc10_23.1, %.loc10_23.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_26.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_26.3: <bound method> = bound_method %.loc10_26.1, %.loc10_26.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc10_26: init i32 = call %.loc10_26.3(%.loc10_26.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_26.4: i32 = value_of_initializer %int.convert_checked.loc10_26 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_26.5: i32 = converted %.loc10_26.1, %.loc10_26.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23.5, %.loc10_26.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_13.1: bool = value_of_initializer %int.less_eq.loc10 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_13.2: bool = converted %int.less_eq.loc10, %.loc10_13.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc10_13.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc10:
@@ -217,11 +248,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc11: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %LessEq.ref.loc11: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT:   %.loc11_24: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_27: i32 = int_value 0 [template = constants.%.7]
-// CHECK:STDOUT:   %int.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_27) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc11_14.1: bool = value_of_initializer %int.less_eq.loc11 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc11_14.2: bool = converted %int.less_eq.loc11, %.loc11_14.1 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc11_24.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_27.1: Core.IntLiteral = int_value 0 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc11_24.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_24.3: <bound method> = bound_method %.loc11_24.1, %.loc11_24.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc11_24: init i32 = call %.loc11_24.3(%.loc11_24.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_24.4: i32 = value_of_initializer %int.convert_checked.loc11_24 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_24.5: i32 = converted %.loc11_24.1, %.loc11_24.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_27.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_27.3: <bound method> = bound_method %.loc11_27.1, %.loc11_27.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc11_27: init i32 = call %.loc11_27.3(%.loc11_27.1) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc11_27.4: i32 = value_of_initializer %int.convert_checked.loc11_27 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc11_27.5: i32 = converted %.loc11_27.1, %.loc11_27.4 [template = constants.%.37]
+// CHECK:STDOUT:   %int.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24.5, %.loc11_27.5) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_14.1: bool = value_of_initializer %int.less_eq.loc11 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_14.2: bool = converted %int.less_eq.loc11, %.loc11_14.1 [template = constants.%.38]
 // CHECK:STDOUT:   if %.loc11_14.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc11:
@@ -237,14 +278,24 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %true_.ref.loc12: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %LessEq.ref.loc12: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
 // CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_30: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_34: i32 = int_value 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc12_29.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_29.2: i32 = converted %int.snegate.loc12, %.loc12_29.1 [template = constants.%.9]
-// CHECK:STDOUT:   %int.less_eq.loc12: init bool = call %LessEq.ref.loc12(%.loc12_29.2, %.loc12_34) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_13.1: bool = value_of_initializer %int.less_eq.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_13.2: bool = converted %int.less_eq.loc12, %.loc12_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_30.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_30.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_30.3: <bound method> = bound_method %.loc12_30.1, %.loc12_30.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_30: init i32 = call %.loc12_30.3(%.loc12_30.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_30.4: i32 = value_of_initializer %int.convert_checked.loc12_30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_30.5: i32 = converted %.loc12_30.1, %.loc12_30.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_30.5) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_34.1: Core.IntLiteral = int_value 0 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc12_29.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_29.2: i32 = converted %int.snegate.loc12, %.loc12_29.1 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc12_34.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_34.3: <bound method> = bound_method %.loc12_34.1, %.loc12_34.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc12_34: init i32 = call %.loc12_34.3(%.loc12_34.1) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc12_34.4: i32 = value_of_initializer %int.convert_checked.loc12_34 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc12_34.5: i32 = converted %.loc12_34.1, %.loc12_34.4 [template = constants.%.37]
+// CHECK:STDOUT:   %int.less_eq.loc12: init bool = call %LessEq.ref.loc12(%.loc12_29.2, %.loc12_34.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_13.1: bool = value_of_initializer %int.less_eq.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_13.2: bool = converted %int.less_eq.loc12, %.loc12_13.1 [template = constants.%.34]
 // CHECK:STDOUT:   if %.loc12_13.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc12:
@@ -259,15 +310,25 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc13: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %LessEq.ref.loc13: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT:   %.loc13_24: i32 = int_value 0 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc13_24.1: Core.IntLiteral = int_value 0 [template = constants.%.35]
 // CHECK:STDOUT:   %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc13_34: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_33.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_33.2: i32 = converted %int.snegate.loc13, %.loc13_33.1 [template = constants.%.9]
-// CHECK:STDOUT:   %int.less_eq.loc13: init bool = call %LessEq.ref.loc13(%.loc13_24, %.loc13_33.2) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc13_14.1: bool = value_of_initializer %int.less_eq.loc13 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc13_14.2: bool = converted %int.less_eq.loc13, %.loc13_14.1 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc13_34.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc13_34.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_34.3: <bound method> = bound_method %.loc13_34.1, %.loc13_34.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc13_34: init i32 = call %.loc13_34.3(%.loc13_34.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_34.4: i32 = value_of_initializer %int.convert_checked.loc13_34 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_34.5: i32 = converted %.loc13_34.1, %.loc13_34.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34.5) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_24.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_24.3: <bound method> = bound_method %.loc13_24.1, %.loc13_24.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc13_24: init i32 = call %.loc13_24.3(%.loc13_24.1) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc13_24.4: i32 = value_of_initializer %int.convert_checked.loc13_24 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc13_24.5: i32 = converted %.loc13_24.1, %.loc13_24.4 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc13_33.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_33.2: i32 = converted %int.snegate.loc13, %.loc13_33.1 [template = constants.%.39]
+// CHECK:STDOUT:   %int.less_eq.loc13: init bool = call %LessEq.ref.loc13(%.loc13_24.5, %.loc13_33.2) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_14.1: bool = value_of_initializer %int.less_eq.loc13 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc13_14.2: bool = converted %int.less_eq.loc13, %.loc13_14.1 [template = constants.%.38]
 // CHECK:STDOUT:   if %.loc13_14.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc13:

+ 17 - 6
toolchain/check/testdata/builtins/int/make_type_32.carbon

@@ -58,12 +58,19 @@ var i: Int() = 0;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int.type: type = fn_type @Int [template]
 // CHECK:STDOUT:   %Int: %Int.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref: %Int.type = import_ref Main//types, inst+7, loaded [template = constants.%Int]
+// CHECK:STDOUT:   %import_ref.1: %Int.type = import_ref Main//types, inst+7, loaded [template = constants.%Int]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -71,13 +78,13 @@ var i: Int() = 0;
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Int = imports.%import_ref
+// CHECK:STDOUT:     .Int = imports.%import_ref.1
 // CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .i = %i
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
-// CHECK:STDOUT:   %Int.ref: %Int.type = name_ref Int, imports.%import_ref [template = constants.%Int]
+// CHECK:STDOUT:   %Int.ref: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
 // CHECK:STDOUT:   %int.make_type_32: init type = call %Int.ref() [template = i32]
 // CHECK:STDOUT:   %.loc6_12.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc6_12.2: type = converted %int.make_type_32, %.loc6_12.1 [template = i32]
@@ -89,8 +96,12 @@ var i: Int() = 0;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc6: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   assign file.%i.var, %.loc6
+// CHECK:STDOUT:   %.loc6_16: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_17.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_17.2: <bound method> = bound_method %.loc6_16, %.loc6_17.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc6_17.2(%.loc6_16) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc6_17.3: init i32 = converted %.loc6_16, %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   assign file.%i.var, %.loc6_17.3
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 294 - 183
toolchain/check/testdata/builtins/int/make_type_signed.carbon

@@ -134,19 +134,27 @@ var m: Int(1000000000);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int.type: type = fn_type @Int [template]
 // CHECK:STDOUT:   %Int: %Int.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 64 [template]
-// CHECK:STDOUT:   %.2: type = int_type signed, %.1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 64 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 64 [template]
+// CHECK:STDOUT:   %.28: type = int_type signed, %.27 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 13 [template]
-// CHECK:STDOUT:   %.4: type = int_type signed, %.3 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 13 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 13 [template]
+// CHECK:STDOUT:   %.32: type = int_type signed, %.31 [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N, 0 [symbolic]
-// CHECK:STDOUT:   %N.patt: i32 = symbolic_binding_pattern N, 0 [symbolic]
-// CHECK:STDOUT:   %.5: type = int_type signed, %N [symbolic]
+// CHECK:STDOUT:   %N.2: i32 = bind_symbolic_name N, 0 [symbolic]
+// CHECK:STDOUT:   %N.patt.2: i32 = symbolic_binding_pattern N, 0 [symbolic]
+// CHECK:STDOUT:   %.33: type = int_type signed, %N.2 [symbolic]
 // CHECK:STDOUT:   %Symbolic.type: type = fn_type @Symbolic [template]
 // CHECK:STDOUT:   %Symbolic: %Symbolic.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -154,7 +162,8 @@ var m: Int(1000000000);
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %Int.type = import_ref Main//types, inst+22, loaded [template = constants.%Int]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Int32 = %import_ref.51
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -171,109 +180,129 @@ var m: Int(1000000000);
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %n.patt: %.2 = binding_pattern n
-// CHECK:STDOUT:     %n.param_patt: %.2 = value_param_pattern %n.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %.2 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %.2 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %n.patt: %.28 = binding_pattern n
+// CHECK:STDOUT:     %n.param_patt: %.28 = value_param_pattern %n.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %.28 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %.28 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %Int.ref.loc6_9: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc6_13: i32 = int_value 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_signed.loc6_12: init type = call %Int.ref.loc6_9(%.loc6_13) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_15.1: type = value_of_initializer %int.make_type_signed.loc6_12 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_15.2: type = converted %int.make_type_signed.loc6_12, %.loc6_15.1 [template = constants.%.2]
+// CHECK:STDOUT:     %.loc6_13.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:     %.loc6_13.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc6_13.3: <bound method> = bound_method %.loc6_13.1, %.loc6_13.2 [template = constants.%.26]
+// CHECK:STDOUT:     %int.convert_checked.loc6_13: init i32 = call %.loc6_13.3(%.loc6_13.1) [template = constants.%.27]
+// CHECK:STDOUT:     %.loc6_13.4: i32 = value_of_initializer %int.convert_checked.loc6_13 [template = constants.%.27]
+// CHECK:STDOUT:     %.loc6_13.5: i32 = converted %.loc6_13.1, %.loc6_13.4 [template = constants.%.27]
+// CHECK:STDOUT:     %int.make_type_signed.loc6_12: init type = call %Int.ref.loc6_9(%.loc6_13.5) [template = constants.%.28]
+// CHECK:STDOUT:     %.loc6_15.1: type = value_of_initializer %int.make_type_signed.loc6_12 [template = constants.%.28]
+// CHECK:STDOUT:     %.loc6_15.2: type = converted %int.make_type_signed.loc6_12, %.loc6_15.1 [template = constants.%.28]
 // CHECK:STDOUT:     %Int.ref.loc6_21: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc6_25: i32 = int_value 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_signed.loc6_24: init type = call %Int.ref.loc6_21(%.loc6_25) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_27.1: type = value_of_initializer %int.make_type_signed.loc6_24 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_27.2: type = converted %int.make_type_signed.loc6_24, %.loc6_27.1 [template = constants.%.2]
-// CHECK:STDOUT:     %n.param: %.2 = value_param runtime_param0
-// CHECK:STDOUT:     %n: %.2 = bind_name n, %n.param
-// CHECK:STDOUT:     %return.param: ref %.2 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %.2 = return_slot %return.param
+// CHECK:STDOUT:     %.loc6_25.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:     %.loc6_25.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc6_25.3: <bound method> = bound_method %.loc6_25.1, %.loc6_25.2 [template = constants.%.26]
+// CHECK:STDOUT:     %int.convert_checked.loc6_25: init i32 = call %.loc6_25.3(%.loc6_25.1) [template = constants.%.27]
+// CHECK:STDOUT:     %.loc6_25.4: i32 = value_of_initializer %int.convert_checked.loc6_25 [template = constants.%.27]
+// CHECK:STDOUT:     %.loc6_25.5: i32 = converted %.loc6_25.1, %.loc6_25.4 [template = constants.%.27]
+// CHECK:STDOUT:     %int.make_type_signed.loc6_24: init type = call %Int.ref.loc6_21(%.loc6_25.5) [template = constants.%.28]
+// CHECK:STDOUT:     %.loc6_27.1: type = value_of_initializer %int.make_type_signed.loc6_24 [template = constants.%.28]
+// CHECK:STDOUT:     %.loc6_27.2: type = converted %int.make_type_signed.loc6_24, %.loc6_27.1 [template = constants.%.28]
+// CHECK:STDOUT:     %n.param: %.28 = value_param runtime_param0
+// CHECK:STDOUT:     %n: %.28 = bind_name n, %n.param
+// CHECK:STDOUT:     %return.param: ref %.28 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %.28 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
-// CHECK:STDOUT:     %n.patt: %.4 = binding_pattern n
-// CHECK:STDOUT:     %n.param_patt: %.4 = value_param_pattern %n.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %.4 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %.4 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %n.patt: %.32 = binding_pattern n
+// CHECK:STDOUT:     %n.param_patt: %.32 = value_param_pattern %n.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %.32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %.32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %Int.ref.loc10_9: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc10_13: i32 = int_value 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_signed.loc10_12: init type = call %Int.ref.loc10_9(%.loc10_13) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_15.1: type = value_of_initializer %int.make_type_signed.loc10_12 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_15.2: type = converted %int.make_type_signed.loc10_12, %.loc10_15.1 [template = constants.%.4]
+// CHECK:STDOUT:     %.loc10_13.1: Core.IntLiteral = int_value 13 [template = constants.%.29]
+// CHECK:STDOUT:     %.loc10_13.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc10_13.3: <bound method> = bound_method %.loc10_13.1, %.loc10_13.2 [template = constants.%.30]
+// CHECK:STDOUT:     %int.convert_checked.loc10_13: init i32 = call %.loc10_13.3(%.loc10_13.1) [template = constants.%.31]
+// CHECK:STDOUT:     %.loc10_13.4: i32 = value_of_initializer %int.convert_checked.loc10_13 [template = constants.%.31]
+// CHECK:STDOUT:     %.loc10_13.5: i32 = converted %.loc10_13.1, %.loc10_13.4 [template = constants.%.31]
+// CHECK:STDOUT:     %int.make_type_signed.loc10_12: init type = call %Int.ref.loc10_9(%.loc10_13.5) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc10_15.1: type = value_of_initializer %int.make_type_signed.loc10_12 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc10_15.2: type = converted %int.make_type_signed.loc10_12, %.loc10_15.1 [template = constants.%.32]
 // CHECK:STDOUT:     %Int.ref.loc10_21: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc10_25: i32 = int_value 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_signed.loc10_24: init type = call %Int.ref.loc10_21(%.loc10_25) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_27.1: type = value_of_initializer %int.make_type_signed.loc10_24 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_27.2: type = converted %int.make_type_signed.loc10_24, %.loc10_27.1 [template = constants.%.4]
-// CHECK:STDOUT:     %n.param: %.4 = value_param runtime_param0
-// CHECK:STDOUT:     %n: %.4 = bind_name n, %n.param
-// CHECK:STDOUT:     %return.param: ref %.4 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %.4 = return_slot %return.param
+// CHECK:STDOUT:     %.loc10_25.1: Core.IntLiteral = int_value 13 [template = constants.%.29]
+// CHECK:STDOUT:     %.loc10_25.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc10_25.3: <bound method> = bound_method %.loc10_25.1, %.loc10_25.2 [template = constants.%.30]
+// CHECK:STDOUT:     %int.convert_checked.loc10_25: init i32 = call %.loc10_25.3(%.loc10_25.1) [template = constants.%.31]
+// CHECK:STDOUT:     %.loc10_25.4: i32 = value_of_initializer %int.convert_checked.loc10_25 [template = constants.%.31]
+// CHECK:STDOUT:     %.loc10_25.5: i32 = converted %.loc10_25.1, %.loc10_25.4 [template = constants.%.31]
+// CHECK:STDOUT:     %int.make_type_signed.loc10_24: init type = call %Int.ref.loc10_21(%.loc10_25.5) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc10_27.1: type = value_of_initializer %int.make_type_signed.loc10_24 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc10_27.2: type = converted %int.make_type_signed.loc10_24, %.loc10_27.1 [template = constants.%.32]
+// CHECK:STDOUT:     %n.param: %.32 = value_param runtime_param0
+// CHECK:STDOUT:     %n: %.32 = bind_name n, %n.param
+// CHECK:STDOUT:     %return.param: ref %.32 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %.32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Symbolic.decl: %Symbolic.type = fn_decl @Symbolic [template = constants.%Symbolic] {
-// CHECK:STDOUT:     %N.patt.loc14_13.1: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc14_13.2 (constants.%N.patt)]
-// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc14_13.1, runtime_param<invalid> [symbolic = %N.patt.loc14_13.2 (constants.%N.patt)]
-// CHECK:STDOUT:     %x.patt: @Symbolic.%.loc14_28 (%.5) = binding_pattern x
-// CHECK:STDOUT:     %x.param_patt: @Symbolic.%.loc14_28 (%.5) = value_param_pattern %x.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: @Symbolic.%.loc14_28 (%.5) = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: @Symbolic.%.loc14_28 (%.5) = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %N.patt.loc14_13.1: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc14_13.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc14_13.1, runtime_param<invalid> [symbolic = %N.patt.loc14_13.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:     %x.patt: @Symbolic.%.loc14_28 (%.33) = binding_pattern x
+// CHECK:STDOUT:     %x.param_patt: @Symbolic.%.loc14_28 (%.33) = value_param_pattern %x.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: @Symbolic.%.loc14_28 (%.33) = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: @Symbolic.%.loc14_28 (%.33) = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc14_17.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc14_17.2: type = converted %int.make_type_32, %.loc14_17.1 [template = i32]
 // CHECK:STDOUT:     %Int.ref.loc14_25: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %N.ref.loc14_29: i32 = name_ref N, %N.loc14_13.1 [symbolic = %N.loc14_13.2 (constants.%N)]
-// CHECK:STDOUT:     %int.make_type_signed.loc14_28: init type = call %Int.ref.loc14_25(%N.ref.loc14_29) [symbolic = %.loc14_28 (constants.%.5)]
-// CHECK:STDOUT:     %.loc14_30.1: type = value_of_initializer %int.make_type_signed.loc14_28 [symbolic = %.loc14_28 (constants.%.5)]
-// CHECK:STDOUT:     %.loc14_30.2: type = converted %int.make_type_signed.loc14_28, %.loc14_30.1 [symbolic = %.loc14_28 (constants.%.5)]
+// CHECK:STDOUT:     %N.ref.loc14_29: i32 = name_ref N, %N.loc14_13.1 [symbolic = %N.loc14_13.2 (constants.%N.2)]
+// CHECK:STDOUT:     %int.make_type_signed.loc14_28: init type = call %Int.ref.loc14_25(%N.ref.loc14_29) [symbolic = %.loc14_28 (constants.%.33)]
+// CHECK:STDOUT:     %.loc14_30.1: type = value_of_initializer %int.make_type_signed.loc14_28 [symbolic = %.loc14_28 (constants.%.33)]
+// CHECK:STDOUT:     %.loc14_30.2: type = converted %int.make_type_signed.loc14_28, %.loc14_30.1 [symbolic = %.loc14_28 (constants.%.33)]
 // CHECK:STDOUT:     %Int.ref.loc14_36: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %N.ref.loc14_40: i32 = name_ref N, %N.loc14_13.1 [symbolic = %N.loc14_13.2 (constants.%N)]
-// CHECK:STDOUT:     %int.make_type_signed.loc14_39: init type = call %Int.ref.loc14_36(%N.ref.loc14_40) [symbolic = %.loc14_28 (constants.%.5)]
-// CHECK:STDOUT:     %.loc14_41.1: type = value_of_initializer %int.make_type_signed.loc14_39 [symbolic = %.loc14_28 (constants.%.5)]
-// CHECK:STDOUT:     %.loc14_41.2: type = converted %int.make_type_signed.loc14_39, %.loc14_41.1 [symbolic = %.loc14_28 (constants.%.5)]
+// CHECK:STDOUT:     %N.ref.loc14_40: i32 = name_ref N, %N.loc14_13.1 [symbolic = %N.loc14_13.2 (constants.%N.2)]
+// CHECK:STDOUT:     %int.make_type_signed.loc14_39: init type = call %Int.ref.loc14_36(%N.ref.loc14_40) [symbolic = %.loc14_28 (constants.%.33)]
+// CHECK:STDOUT:     %.loc14_41.1: type = value_of_initializer %int.make_type_signed.loc14_39 [symbolic = %.loc14_28 (constants.%.33)]
+// CHECK:STDOUT:     %.loc14_41.2: type = converted %int.make_type_signed.loc14_39, %.loc14_41.1 [symbolic = %.loc14_28 (constants.%.33)]
 // CHECK:STDOUT:     %N.param: i32 = value_param runtime_param<invalid>
-// CHECK:STDOUT:     %N.loc14_13.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc14_13.2 (constants.%N)]
-// CHECK:STDOUT:     %x.param: @Symbolic.%.loc14_28 (%.5) = value_param runtime_param0
-// CHECK:STDOUT:     %x: @Symbolic.%.loc14_28 (%.5) = bind_name x, %x.param
-// CHECK:STDOUT:     %return.param: ref @Symbolic.%.loc14_28 (%.5) = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref @Symbolic.%.loc14_28 (%.5) = return_slot %return.param
+// CHECK:STDOUT:     %N.loc14_13.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc14_13.2 (constants.%N.2)]
+// CHECK:STDOUT:     %x.param: @Symbolic.%.loc14_28 (%.33) = value_param runtime_param0
+// CHECK:STDOUT:     %x: @Symbolic.%.loc14_28 (%.33) = bind_name x, %x.param
+// CHECK:STDOUT:     %return.param: ref @Symbolic.%.loc14_28 (%.33) = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref @Symbolic.%.loc14_28 (%.33) = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int(%n.param_patt: i32) -> type = "int.make_type_signed";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%n.param_patt: %.2) -> %.2 {
+// CHECK:STDOUT: fn @F(%n.param_patt: %.28) -> %.28 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %n.ref: %.2 = name_ref n, %n
+// CHECK:STDOUT:   %n.ref: %.28 = name_ref n, %n
 // CHECK:STDOUT:   return %n.ref
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(%n.param_patt: %.4) -> %.4 {
+// CHECK:STDOUT: fn @G(%n.param_patt: %.32) -> %.32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %n.ref: %.4 = name_ref n, %n
+// CHECK:STDOUT:   %n.ref: %.32 = name_ref n, %n
 // CHECK:STDOUT:   return %n.ref
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @Symbolic(%N.loc14_13.1: i32) {
-// CHECK:STDOUT:   %N.loc14_13.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc14_13.2 (constants.%N)]
-// CHECK:STDOUT:   %N.patt.loc14_13.2: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc14_13.2 (constants.%N.patt)]
-// CHECK:STDOUT:   %.loc14_28: type = int_type signed, %N.loc14_13.2 [symbolic = %.loc14_28 (constants.%.5)]
+// CHECK:STDOUT:   %N.loc14_13.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc14_13.2 (constants.%N.2)]
+// CHECK:STDOUT:   %N.patt.loc14_13.2: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc14_13.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:   %.loc14_28: type = int_type signed, %N.loc14_13.2 [symbolic = %.loc14_28 (constants.%.33)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%N.param_patt: i32, %x.param_patt: @Symbolic.%.loc14_28 (%.5)) -> @Symbolic.%.loc14_28 (%.5) {
+// CHECK:STDOUT:   fn(%N.param_patt: i32, %x.param_patt: @Symbolic.%.loc14_28 (%.33)) -> @Symbolic.%.loc14_28 (%.33) {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %x.ref: @Symbolic.%.loc14_28 (%.5) = name_ref x, %x
+// CHECK:STDOUT:     %x.ref: @Symbolic.%.loc14_28 (%.33) = name_ref x, %x
 // CHECK:STDOUT:     return %x.ref
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Symbolic(constants.%N) {
-// CHECK:STDOUT:   %N.loc14_13.2 => constants.%N
-// CHECK:STDOUT:   %N.patt.loc14_13.2 => constants.%N
-// CHECK:STDOUT:   %.loc14_28 => constants.%.5
+// CHECK:STDOUT: specific @Symbolic(constants.%N.2) {
+// CHECK:STDOUT:   %N.loc14_13.2 => constants.%N.2
+// CHECK:STDOUT:   %N.patt.loc14_13.2 => constants.%N.2
+// CHECK:STDOUT:   %.loc14_28 => constants.%.33
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- import_types.carbon
@@ -281,36 +310,47 @@ var m: Int(1000000000);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int.type: type = fn_type @Int [template]
 // CHECK:STDOUT:   %Int: %Int.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 64 [template]
-// CHECK:STDOUT:   %.2: type = int_type signed, %.1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 64 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 64 [template]
+// CHECK:STDOUT:   %.28: type = int_type signed, %.27 [template]
 // CHECK:STDOUT:   %UseF.type: type = fn_type @UseF [template]
 // CHECK:STDOUT:   %UseF: %UseF.type = struct_value () [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 13 [template]
-// CHECK:STDOUT:   %.4: type = int_type signed, %.3 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 13 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 13 [template]
+// CHECK:STDOUT:   %.32: type = int_type signed, %.31 [template]
 // CHECK:STDOUT:   %UseG.type: type = fn_type @UseG [template]
 // CHECK:STDOUT:   %UseG: %UseG.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 24 [template]
-// CHECK:STDOUT:   %.6: type = int_type signed, %.5 [template]
+// CHECK:STDOUT:   %.33: Core.IntLiteral = int_value 24 [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.33, %Convert.15 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value 24 [template]
+// CHECK:STDOUT:   %.36: type = int_type signed, %.35 [template]
 // CHECK:STDOUT:   %UseSymbolic.type: type = fn_type @UseSymbolic [template]
 // CHECK:STDOUT:   %UseSymbolic: %UseSymbolic.type = struct_value () [template]
 // CHECK:STDOUT:   %Symbolic.type: type = fn_type @Symbolic [template]
 // CHECK:STDOUT:   %Symbolic: %Symbolic.type = struct_value () [template]
-// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N, 0 [symbolic]
-// CHECK:STDOUT:   %.7: type = int_type signed, %N [symbolic]
-// CHECK:STDOUT:   %N.patt: i32 = symbolic_binding_pattern N, 0 [symbolic]
-// CHECK:STDOUT:   %.8: <specific function> = specific_function %Symbolic, @Symbolic(%.5) [template]
+// CHECK:STDOUT:   %N.2: i32 = bind_symbolic_name N, 0 [symbolic]
+// CHECK:STDOUT:   %.37: type = int_type signed, %N.2 [symbolic]
+// CHECK:STDOUT:   %N.patt.2: i32 = symbolic_binding_pattern N, 0 [symbolic]
+// CHECK:STDOUT:   %.38: <specific function> = specific_function %Symbolic, @Symbolic(%.35) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %Int.type = import_ref Main//types, inst+22, loaded [template = constants.%Int]
-// CHECK:STDOUT:   %import_ref.2: %F.type = import_ref Main//use_types, inst+36, loaded [template = constants.%F]
-// CHECK:STDOUT:   %import_ref.3: %G.type = import_ref Main//use_types, inst+61, loaded [template = constants.%G]
-// CHECK:STDOUT:   %import_ref.4: %Symbolic.type = import_ref Main//use_types, inst+101, loaded [template = constants.%Symbolic]
+// CHECK:STDOUT:   %import_ref.2: %F.type = import_ref Main//use_types, inst+405, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.3: %G.type = import_ref Main//use_types, inst+442, loaded [template = constants.%G]
+// CHECK:STDOUT:   %import_ref.4: %Symbolic.type = import_ref Main//use_types, inst+482, loaded [template = constants.%Symbolic]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.5
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -330,128 +370,163 @@ var m: Int(1000000000);
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
 // CHECK:STDOUT:   %UseF.decl: %UseF.type = fn_decl @UseF [template = constants.%UseF] {
-// CHECK:STDOUT:     %n.patt: %.2 = binding_pattern n
-// CHECK:STDOUT:     %n.param_patt: %.2 = value_param_pattern %n.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %.2 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %.2 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %n.patt: %.28 = binding_pattern n
+// CHECK:STDOUT:     %n.param_patt: %.28 = value_param_pattern %n.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %.28 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %.28 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %Int.ref.loc7_12: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc7_16: i32 = int_value 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_signed.loc7_15: init type = call %Int.ref.loc7_12(%.loc7_16) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc7_18.1: type = value_of_initializer %int.make_type_signed.loc7_15 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc7_18.2: type = converted %int.make_type_signed.loc7_15, %.loc7_18.1 [template = constants.%.2]
+// CHECK:STDOUT:     %.loc7_16.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:     %.loc7_16.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc7_16.3: <bound method> = bound_method %.loc7_16.1, %.loc7_16.2 [template = constants.%.26]
+// CHECK:STDOUT:     %int.convert_checked.loc7_16: init i32 = call %.loc7_16.3(%.loc7_16.1) [template = constants.%.27]
+// CHECK:STDOUT:     %.loc7_16.4: i32 = value_of_initializer %int.convert_checked.loc7_16 [template = constants.%.27]
+// CHECK:STDOUT:     %.loc7_16.5: i32 = converted %.loc7_16.1, %.loc7_16.4 [template = constants.%.27]
+// CHECK:STDOUT:     %int.make_type_signed.loc7_15: init type = call %Int.ref.loc7_12(%.loc7_16.5) [template = constants.%.28]
+// CHECK:STDOUT:     %.loc7_18.1: type = value_of_initializer %int.make_type_signed.loc7_15 [template = constants.%.28]
+// CHECK:STDOUT:     %.loc7_18.2: type = converted %int.make_type_signed.loc7_15, %.loc7_18.1 [template = constants.%.28]
 // CHECK:STDOUT:     %Int.ref.loc7_24: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc7_28: i32 = int_value 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_signed.loc7_27: init type = call %Int.ref.loc7_24(%.loc7_28) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc7_30.1: type = value_of_initializer %int.make_type_signed.loc7_27 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc7_30.2: type = converted %int.make_type_signed.loc7_27, %.loc7_30.1 [template = constants.%.2]
-// CHECK:STDOUT:     %n.param: %.2 = value_param runtime_param0
-// CHECK:STDOUT:     %n: %.2 = bind_name n, %n.param
-// CHECK:STDOUT:     %return.param: ref %.2 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %.2 = return_slot %return.param
+// CHECK:STDOUT:     %.loc7_28.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:     %.loc7_28.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc7_28.3: <bound method> = bound_method %.loc7_28.1, %.loc7_28.2 [template = constants.%.26]
+// CHECK:STDOUT:     %int.convert_checked.loc7_28: init i32 = call %.loc7_28.3(%.loc7_28.1) [template = constants.%.27]
+// CHECK:STDOUT:     %.loc7_28.4: i32 = value_of_initializer %int.convert_checked.loc7_28 [template = constants.%.27]
+// CHECK:STDOUT:     %.loc7_28.5: i32 = converted %.loc7_28.1, %.loc7_28.4 [template = constants.%.27]
+// CHECK:STDOUT:     %int.make_type_signed.loc7_27: init type = call %Int.ref.loc7_24(%.loc7_28.5) [template = constants.%.28]
+// CHECK:STDOUT:     %.loc7_30.1: type = value_of_initializer %int.make_type_signed.loc7_27 [template = constants.%.28]
+// CHECK:STDOUT:     %.loc7_30.2: type = converted %int.make_type_signed.loc7_27, %.loc7_30.1 [template = constants.%.28]
+// CHECK:STDOUT:     %n.param: %.28 = value_param runtime_param0
+// CHECK:STDOUT:     %n: %.28 = bind_name n, %n.param
+// CHECK:STDOUT:     %return.param: ref %.28 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %.28 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %UseG.decl: %UseG.type = fn_decl @UseG [template = constants.%UseG] {
-// CHECK:STDOUT:     %n.patt: %.4 = binding_pattern n
-// CHECK:STDOUT:     %n.param_patt: %.4 = value_param_pattern %n.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %.4 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %.4 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %n.patt: %.32 = binding_pattern n
+// CHECK:STDOUT:     %n.param_patt: %.32 = value_param_pattern %n.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %.32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %.32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %Int.ref.loc11_12: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc11_16: i32 = int_value 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_signed.loc11_15: init type = call %Int.ref.loc11_12(%.loc11_16) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc11_18.1: type = value_of_initializer %int.make_type_signed.loc11_15 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc11_18.2: type = converted %int.make_type_signed.loc11_15, %.loc11_18.1 [template = constants.%.4]
+// CHECK:STDOUT:     %.loc11_16.1: Core.IntLiteral = int_value 13 [template = constants.%.29]
+// CHECK:STDOUT:     %.loc11_16.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc11_16.3: <bound method> = bound_method %.loc11_16.1, %.loc11_16.2 [template = constants.%.30]
+// CHECK:STDOUT:     %int.convert_checked.loc11_16: init i32 = call %.loc11_16.3(%.loc11_16.1) [template = constants.%.31]
+// CHECK:STDOUT:     %.loc11_16.4: i32 = value_of_initializer %int.convert_checked.loc11_16 [template = constants.%.31]
+// CHECK:STDOUT:     %.loc11_16.5: i32 = converted %.loc11_16.1, %.loc11_16.4 [template = constants.%.31]
+// CHECK:STDOUT:     %int.make_type_signed.loc11_15: init type = call %Int.ref.loc11_12(%.loc11_16.5) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc11_18.1: type = value_of_initializer %int.make_type_signed.loc11_15 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc11_18.2: type = converted %int.make_type_signed.loc11_15, %.loc11_18.1 [template = constants.%.32]
 // CHECK:STDOUT:     %Int.ref.loc11_24: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc11_28: i32 = int_value 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_signed.loc11_27: init type = call %Int.ref.loc11_24(%.loc11_28) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc11_30.1: type = value_of_initializer %int.make_type_signed.loc11_27 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc11_30.2: type = converted %int.make_type_signed.loc11_27, %.loc11_30.1 [template = constants.%.4]
-// CHECK:STDOUT:     %n.param: %.4 = value_param runtime_param0
-// CHECK:STDOUT:     %n: %.4 = bind_name n, %n.param
-// CHECK:STDOUT:     %return.param: ref %.4 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %.4 = return_slot %return.param
+// CHECK:STDOUT:     %.loc11_28.1: Core.IntLiteral = int_value 13 [template = constants.%.29]
+// CHECK:STDOUT:     %.loc11_28.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc11_28.3: <bound method> = bound_method %.loc11_28.1, %.loc11_28.2 [template = constants.%.30]
+// CHECK:STDOUT:     %int.convert_checked.loc11_28: init i32 = call %.loc11_28.3(%.loc11_28.1) [template = constants.%.31]
+// CHECK:STDOUT:     %.loc11_28.4: i32 = value_of_initializer %int.convert_checked.loc11_28 [template = constants.%.31]
+// CHECK:STDOUT:     %.loc11_28.5: i32 = converted %.loc11_28.1, %.loc11_28.4 [template = constants.%.31]
+// CHECK:STDOUT:     %int.make_type_signed.loc11_27: init type = call %Int.ref.loc11_24(%.loc11_28.5) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc11_30.1: type = value_of_initializer %int.make_type_signed.loc11_27 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc11_30.2: type = converted %int.make_type_signed.loc11_27, %.loc11_30.1 [template = constants.%.32]
+// CHECK:STDOUT:     %n.param: %.32 = value_param runtime_param0
+// CHECK:STDOUT:     %n: %.32 = bind_name n, %n.param
+// CHECK:STDOUT:     %return.param: ref %.32 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %.32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %UseSymbolic.decl: %UseSymbolic.type = fn_decl @UseSymbolic [template = constants.%UseSymbolic] {
-// CHECK:STDOUT:     %n.patt: %.6 = binding_pattern n
-// CHECK:STDOUT:     %n.param_patt: %.6 = value_param_pattern %n.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %.6 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %.6 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %n.patt: %.36 = binding_pattern n
+// CHECK:STDOUT:     %n.param_patt: %.36 = value_param_pattern %n.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %.36 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %.36 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %Int.ref.loc15_19: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc15_23: i32 = int_value 24 [template = constants.%.5]
-// CHECK:STDOUT:     %int.make_type_signed.loc15_22: init type = call %Int.ref.loc15_19(%.loc15_23) [template = constants.%.6]
-// CHECK:STDOUT:     %.loc15_25.1: type = value_of_initializer %int.make_type_signed.loc15_22 [template = constants.%.6]
-// CHECK:STDOUT:     %.loc15_25.2: type = converted %int.make_type_signed.loc15_22, %.loc15_25.1 [template = constants.%.6]
+// CHECK:STDOUT:     %.loc15_23.1: Core.IntLiteral = int_value 24 [template = constants.%.33]
+// CHECK:STDOUT:     %.loc15_23.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc15_23.3: <bound method> = bound_method %.loc15_23.1, %.loc15_23.2 [template = constants.%.34]
+// CHECK:STDOUT:     %int.convert_checked.loc15_23: init i32 = call %.loc15_23.3(%.loc15_23.1) [template = constants.%.35]
+// CHECK:STDOUT:     %.loc15_23.4: i32 = value_of_initializer %int.convert_checked.loc15_23 [template = constants.%.35]
+// CHECK:STDOUT:     %.loc15_23.5: i32 = converted %.loc15_23.1, %.loc15_23.4 [template = constants.%.35]
+// CHECK:STDOUT:     %int.make_type_signed.loc15_22: init type = call %Int.ref.loc15_19(%.loc15_23.5) [template = constants.%.36]
+// CHECK:STDOUT:     %.loc15_25.1: type = value_of_initializer %int.make_type_signed.loc15_22 [template = constants.%.36]
+// CHECK:STDOUT:     %.loc15_25.2: type = converted %int.make_type_signed.loc15_22, %.loc15_25.1 [template = constants.%.36]
 // CHECK:STDOUT:     %Int.ref.loc15_31: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %.loc15_35: i32 = int_value 24 [template = constants.%.5]
-// CHECK:STDOUT:     %int.make_type_signed.loc15_34: init type = call %Int.ref.loc15_31(%.loc15_35) [template = constants.%.6]
-// CHECK:STDOUT:     %.loc15_37.1: type = value_of_initializer %int.make_type_signed.loc15_34 [template = constants.%.6]
-// CHECK:STDOUT:     %.loc15_37.2: type = converted %int.make_type_signed.loc15_34, %.loc15_37.1 [template = constants.%.6]
-// CHECK:STDOUT:     %n.param: %.6 = value_param runtime_param0
-// CHECK:STDOUT:     %n: %.6 = bind_name n, %n.param
-// CHECK:STDOUT:     %return.param: ref %.6 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %.6 = return_slot %return.param
+// CHECK:STDOUT:     %.loc15_35.1: Core.IntLiteral = int_value 24 [template = constants.%.33]
+// CHECK:STDOUT:     %.loc15_35.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc15_35.3: <bound method> = bound_method %.loc15_35.1, %.loc15_35.2 [template = constants.%.34]
+// CHECK:STDOUT:     %int.convert_checked.loc15_35: init i32 = call %.loc15_35.3(%.loc15_35.1) [template = constants.%.35]
+// CHECK:STDOUT:     %.loc15_35.4: i32 = value_of_initializer %int.convert_checked.loc15_35 [template = constants.%.35]
+// CHECK:STDOUT:     %.loc15_35.5: i32 = converted %.loc15_35.1, %.loc15_35.4 [template = constants.%.35]
+// CHECK:STDOUT:     %int.make_type_signed.loc15_34: init type = call %Int.ref.loc15_31(%.loc15_35.5) [template = constants.%.36]
+// CHECK:STDOUT:     %.loc15_37.1: type = value_of_initializer %int.make_type_signed.loc15_34 [template = constants.%.36]
+// CHECK:STDOUT:     %.loc15_37.2: type = converted %int.make_type_signed.loc15_34, %.loc15_37.1 [template = constants.%.36]
+// CHECK:STDOUT:     %n.param: %.36 = value_param runtime_param0
+// CHECK:STDOUT:     %n: %.36 = bind_name n, %n.param
+// CHECK:STDOUT:     %return.param: ref %.36 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %.36 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int(%n.param_patt: i32) -> type = "int.make_type_signed";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @UseF(%n.param_patt: %.2) -> %.2 {
+// CHECK:STDOUT: fn @UseF(%n.param_patt: %.28) -> %.28 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, imports.%import_ref.2 [template = constants.%F]
-// CHECK:STDOUT:   %n.ref: %.2 = name_ref n, %n
-// CHECK:STDOUT:   %F.call: init %.2 = call %F.ref(%n.ref)
-// CHECK:STDOUT:   %.loc8_14.1: %.2 = value_of_initializer %F.call
-// CHECK:STDOUT:   %.loc8_14.2: %.2 = converted %F.call, %.loc8_14.1
+// CHECK:STDOUT:   %n.ref: %.28 = name_ref n, %n
+// CHECK:STDOUT:   %F.call: init %.28 = call %F.ref(%n.ref)
+// CHECK:STDOUT:   %.loc8_14.1: %.28 = value_of_initializer %F.call
+// CHECK:STDOUT:   %.loc8_14.2: %.28 = converted %F.call, %.loc8_14.1
 // CHECK:STDOUT:   return %.loc8_14.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%n.param_patt: %.2) -> %.2;
+// CHECK:STDOUT: fn @F(%n.param_patt: %.28) -> %.28;
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @UseG(%n.param_patt: %.4) -> %.4 {
+// CHECK:STDOUT: fn @UseG(%n.param_patt: %.32) -> %.32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %G.ref: %G.type = name_ref G, imports.%import_ref.3 [template = constants.%G]
-// CHECK:STDOUT:   %n.ref: %.4 = name_ref n, %n
-// CHECK:STDOUT:   %G.call: init %.4 = call %G.ref(%n.ref)
-// CHECK:STDOUT:   %.loc12_14.1: %.4 = value_of_initializer %G.call
-// CHECK:STDOUT:   %.loc12_14.2: %.4 = converted %G.call, %.loc12_14.1
+// CHECK:STDOUT:   %n.ref: %.32 = name_ref n, %n
+// CHECK:STDOUT:   %G.call: init %.32 = call %G.ref(%n.ref)
+// CHECK:STDOUT:   %.loc12_14.1: %.32 = value_of_initializer %G.call
+// CHECK:STDOUT:   %.loc12_14.2: %.32 = converted %G.call, %.loc12_14.1
 // CHECK:STDOUT:   return %.loc12_14.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(%n.param_patt: %.4) -> %.4;
+// CHECK:STDOUT: fn @G(%n.param_patt: %.32) -> %.32;
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @UseSymbolic(%n.param_patt: %.6) -> %.6 {
+// CHECK:STDOUT: fn @UseSymbolic(%n.param_patt: %.36) -> %.36 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Symbolic.ref: %Symbolic.type = name_ref Symbolic, imports.%import_ref.4 [template = constants.%Symbolic]
-// CHECK:STDOUT:   %.loc16_19: i32 = int_value 24 [template = constants.%.5]
-// CHECK:STDOUT:   %n.ref: %.6 = name_ref n, %n
-// CHECK:STDOUT:   %.loc16_10: <specific function> = specific_function %Symbolic.ref, @Symbolic(constants.%.5) [template = constants.%.8]
-// CHECK:STDOUT:   %Symbolic.call: init %.6 = call %.loc16_10(%n.ref)
-// CHECK:STDOUT:   %.loc16_25.1: %.6 = value_of_initializer %Symbolic.call
-// CHECK:STDOUT:   %.loc16_25.2: %.6 = converted %Symbolic.call, %.loc16_25.1
+// CHECK:STDOUT:   %.loc16_19: Core.IntLiteral = int_value 24 [template = constants.%.33]
+// CHECK:STDOUT:   %n.ref: %.36 = name_ref n, %n
+// CHECK:STDOUT:   %.loc16_18.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_18.2: <bound method> = bound_method %.loc16_19, %.loc16_18.1 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked.loc16: init i32 = call %.loc16_18.2(%.loc16_19) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc16_18.3: i32 = value_of_initializer %int.convert_checked.loc16 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc16_18.4: i32 = converted %.loc16_19, %.loc16_18.3 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc16_10: <specific function> = specific_function %Symbolic.ref, @Symbolic(constants.%.35) [template = constants.%.38]
+// CHECK:STDOUT:   %Symbolic.call: init %.36 = call %.loc16_10(%n.ref)
+// CHECK:STDOUT:   %.loc16_25.1: %.36 = value_of_initializer %Symbolic.call
+// CHECK:STDOUT:   %.loc16_25.2: %.36 = converted %Symbolic.call, %.loc16_25.1
 // CHECK:STDOUT:   return %.loc16_25.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @Symbolic(constants.%N: i32) {
-// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
-// CHECK:STDOUT:   %N.patt: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt (constants.%N.patt)]
-// CHECK:STDOUT:   %.1: type = int_type signed, %N [symbolic = %.1 (constants.%.7)]
+// CHECK:STDOUT: generic fn @Symbolic(constants.%N.2: i32) {
+// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.2)]
+// CHECK:STDOUT:   %N.patt: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt (constants.%N.patt.2)]
+// CHECK:STDOUT:   %.1: type = int_type signed, %N [symbolic = %.1 (constants.%.37)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%N.param_patt: i32, %x.param_patt: @Symbolic.%.1 (%.7)) -> @Symbolic.%.1 (%.7);
+// CHECK:STDOUT:   fn(%N.param_patt: i32, %x.param_patt: @Symbolic.%.1 (%.37)) -> @Symbolic.%.1 (%.37);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Symbolic(constants.%N) {
-// CHECK:STDOUT:   %N => constants.%N
-// CHECK:STDOUT:   %N.patt => constants.%N
-// CHECK:STDOUT:   %.1 => constants.%.7
+// CHECK:STDOUT: specific @Symbolic(constants.%N.2) {
+// CHECK:STDOUT:   %N => constants.%N.2
+// CHECK:STDOUT:   %N.patt => constants.%N.2
+// CHECK:STDOUT:   %.1 => constants.%.37
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Symbolic(constants.%.5) {
-// CHECK:STDOUT:   %N => constants.%.5
-// CHECK:STDOUT:   %N.patt => constants.%.5
-// CHECK:STDOUT:   %.1 => constants.%.6
+// CHECK:STDOUT: specific @Symbolic(constants.%.35) {
+// CHECK:STDOUT:   %N => constants.%.35
+// CHECK:STDOUT:   %N.patt => constants.%.35
+// CHECK:STDOUT:   %.1 => constants.%.36
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
@@ -461,12 +536,19 @@ var m: Int(1000000000);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int.type: type = fn_type @Int [template]
 // CHECK:STDOUT:   %Int: %Int.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref: %Int.type = import_ref Main//types, inst+22, loaded [template = constants.%Int]
+// CHECK:STDOUT:   %import_ref.1: %Int.type = import_ref Main//types, inst+22, loaded [template = constants.%Int]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -474,15 +556,20 @@ var m: Int(1000000000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Int = imports.%import_ref
+// CHECK:STDOUT:     .Int = imports.%import_ref.1
 // CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .n = %n
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
-// CHECK:STDOUT:   %Int.ref: %Int.type = name_ref Int, imports.%import_ref [template = constants.%Int]
-// CHECK:STDOUT:   %.loc10_12: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %int.make_type_signed: init type = call %Int.ref(%.loc10_12) [template = <error>]
+// CHECK:STDOUT:   %Int.ref: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
+// CHECK:STDOUT:   %.loc10_12.1: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_12.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_12.3: <bound method> = bound_method %.loc10_12.1, %.loc10_12.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc10_12.3(%.loc10_12.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_12.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_12.5: i32 = converted %.loc10_12.1, %.loc10_12.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.make_type_signed: init type = call %Int.ref(%.loc10_12.5) [template = <error>]
 // CHECK:STDOUT:   %.loc10_13.1: type = value_of_initializer %int.make_type_signed [template = <error>]
 // CHECK:STDOUT:   %.loc10_13.2: type = converted %int.make_type_signed, %.loc10_13.1 [template = <error>]
 // CHECK:STDOUT:   %n.var: ref <error> = var n
@@ -500,14 +587,21 @@ var m: Int(1000000000);
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
 // CHECK:STDOUT:   %Int.type: type = fn_type @Int [template]
 // CHECK:STDOUT:   %Int: %Int.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %Int.type = import_ref Main//types, inst+22, loaded [template = constants.%Int]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -541,10 +635,15 @@ var m: Int(1000000000);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Int.ref: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
 // CHECK:STDOUT:   %Negate.ref: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_19: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_19) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_18.1: i32 = value_of_initializer %int.snegate [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_18.2: i32 = converted %int.snegate, %.loc12_18.1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12_19.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_19.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_19.3: <bound method> = bound_method %.loc12_19.1, %.loc12_19.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc12_19.3(%.loc12_19.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_19.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_19.5: i32 = converted %.loc12_19.1, %.loc12_19.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_19.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_18.1: i32 = value_of_initializer %int.snegate [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_18.2: i32 = converted %int.snegate, %.loc12_18.1 [template = constants.%.28]
 // CHECK:STDOUT:   %int.make_type_signed: init type = call %Int.ref(%.loc12_18.2) [template = <error>]
 // CHECK:STDOUT:   %.loc12_21.1: type = value_of_initializer %int.make_type_signed [template = <error>]
 // CHECK:STDOUT:   %.loc12_21.2: type = converted %int.make_type_signed, %.loc12_21.1 [template = <error>]
@@ -561,12 +660,19 @@ var m: Int(1000000000);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int.type: type = fn_type @Int [template]
 // CHECK:STDOUT:   %Int: %Int.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1000000000 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1000000000 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1000000000 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref: %Int.type = import_ref Main//types, inst+22, loaded [template = constants.%Int]
+// CHECK:STDOUT:   %import_ref.1: %Int.type = import_ref Main//types, inst+22, loaded [template = constants.%Int]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -574,15 +680,20 @@ var m: Int(1000000000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Int = imports.%import_ref
+// CHECK:STDOUT:     .Int = imports.%import_ref.1
 // CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .m = %m
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
-// CHECK:STDOUT:   %Int.ref: %Int.type = name_ref Int, imports.%import_ref [template = constants.%Int]
-// CHECK:STDOUT:   %.loc9_12: i32 = int_value 1000000000 [template = constants.%.1]
-// CHECK:STDOUT:   %int.make_type_signed: init type = call %Int.ref(%.loc9_12) [template = <error>]
+// CHECK:STDOUT:   %Int.ref: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
+// CHECK:STDOUT:   %.loc9_12.1: Core.IntLiteral = int_value 1000000000 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_12.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_12.3: <bound method> = bound_method %.loc9_12.1, %.loc9_12.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc9_12.3(%.loc9_12.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_12.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_12.5: i32 = converted %.loc9_12.1, %.loc9_12.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.make_type_signed: init type = call %Int.ref(%.loc9_12.5) [template = <error>]
 // CHECK:STDOUT:   %.loc9_22.1: type = value_of_initializer %int.make_type_signed [template = <error>]
 // CHECK:STDOUT:   %.loc9_22.2: type = converted %int.make_type_signed, %.loc9_22.1 [template = <error>]
 // CHECK:STDOUT:   %m.var: ref <error> = var m

+ 155 - 90
toolchain/check/testdata/builtins/int/make_type_unsigned.carbon

@@ -115,19 +115,27 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %UInt.type: type = fn_type @UInt [template]
 // CHECK:STDOUT:   %UInt: %UInt.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 64 [template]
-// CHECK:STDOUT:   %.2: type = int_type unsigned, %.1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 64 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 64 [template]
+// CHECK:STDOUT:   %.28: type = int_type unsigned, %.27 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 13 [template]
-// CHECK:STDOUT:   %.4: type = int_type unsigned, %.3 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 13 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 13 [template]
+// CHECK:STDOUT:   %.32: type = int_type unsigned, %.31 [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N, 0 [symbolic]
-// CHECK:STDOUT:   %N.patt: i32 = symbolic_binding_pattern N, 0 [symbolic]
-// CHECK:STDOUT:   %.5: type = int_type unsigned, %N [symbolic]
+// CHECK:STDOUT:   %N.2: i32 = bind_symbolic_name N, 0 [symbolic]
+// CHECK:STDOUT:   %N.patt.2: i32 = symbolic_binding_pattern N, 0 [symbolic]
+// CHECK:STDOUT:   %.33: type = int_type unsigned, %N.2 [symbolic]
 // CHECK:STDOUT:   %Symbolic.type: type = fn_type @Symbolic [template]
 // CHECK:STDOUT:   %Symbolic: %Symbolic.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -135,7 +143,8 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %UInt.type = import_ref Main//types, inst+22, loaded [template = constants.%UInt]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Int32 = %import_ref.51
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -152,109 +161,129 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %n.patt: %.2 = binding_pattern n
-// CHECK:STDOUT:     %n.param_patt: %.2 = value_param_pattern %n.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %.2 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %.2 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %n.patt: %.28 = binding_pattern n
+// CHECK:STDOUT:     %n.param_patt: %.28 = value_param_pattern %n.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %.28 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %.28 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %UInt.ref.loc6_9: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
-// CHECK:STDOUT:     %.loc6_14: i32 = int_value 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc6_13: init type = call %UInt.ref.loc6_9(%.loc6_14) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_16.1: type = value_of_initializer %int.make_type_unsigned.loc6_13 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_16.2: type = converted %int.make_type_unsigned.loc6_13, %.loc6_16.1 [template = constants.%.2]
+// CHECK:STDOUT:     %.loc6_14.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:     %.loc6_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc6_14.3: <bound method> = bound_method %.loc6_14.1, %.loc6_14.2 [template = constants.%.26]
+// CHECK:STDOUT:     %int.convert_checked.loc6_14: init i32 = call %.loc6_14.3(%.loc6_14.1) [template = constants.%.27]
+// CHECK:STDOUT:     %.loc6_14.4: i32 = value_of_initializer %int.convert_checked.loc6_14 [template = constants.%.27]
+// CHECK:STDOUT:     %.loc6_14.5: i32 = converted %.loc6_14.1, %.loc6_14.4 [template = constants.%.27]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc6_13: init type = call %UInt.ref.loc6_9(%.loc6_14.5) [template = constants.%.28]
+// CHECK:STDOUT:     %.loc6_16.1: type = value_of_initializer %int.make_type_unsigned.loc6_13 [template = constants.%.28]
+// CHECK:STDOUT:     %.loc6_16.2: type = converted %int.make_type_unsigned.loc6_13, %.loc6_16.1 [template = constants.%.28]
 // CHECK:STDOUT:     %UInt.ref.loc6_22: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
-// CHECK:STDOUT:     %.loc6_27: i32 = int_value 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc6_26: init type = call %UInt.ref.loc6_22(%.loc6_27) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_29.1: type = value_of_initializer %int.make_type_unsigned.loc6_26 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_29.2: type = converted %int.make_type_unsigned.loc6_26, %.loc6_29.1 [template = constants.%.2]
-// CHECK:STDOUT:     %n.param: %.2 = value_param runtime_param0
-// CHECK:STDOUT:     %n: %.2 = bind_name n, %n.param
-// CHECK:STDOUT:     %return.param: ref %.2 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %.2 = return_slot %return.param
+// CHECK:STDOUT:     %.loc6_27.1: Core.IntLiteral = int_value 64 [template = constants.%.1]
+// CHECK:STDOUT:     %.loc6_27.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc6_27.3: <bound method> = bound_method %.loc6_27.1, %.loc6_27.2 [template = constants.%.26]
+// CHECK:STDOUT:     %int.convert_checked.loc6_27: init i32 = call %.loc6_27.3(%.loc6_27.1) [template = constants.%.27]
+// CHECK:STDOUT:     %.loc6_27.4: i32 = value_of_initializer %int.convert_checked.loc6_27 [template = constants.%.27]
+// CHECK:STDOUT:     %.loc6_27.5: i32 = converted %.loc6_27.1, %.loc6_27.4 [template = constants.%.27]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc6_26: init type = call %UInt.ref.loc6_22(%.loc6_27.5) [template = constants.%.28]
+// CHECK:STDOUT:     %.loc6_29.1: type = value_of_initializer %int.make_type_unsigned.loc6_26 [template = constants.%.28]
+// CHECK:STDOUT:     %.loc6_29.2: type = converted %int.make_type_unsigned.loc6_26, %.loc6_29.1 [template = constants.%.28]
+// CHECK:STDOUT:     %n.param: %.28 = value_param runtime_param0
+// CHECK:STDOUT:     %n: %.28 = bind_name n, %n.param
+// CHECK:STDOUT:     %return.param: ref %.28 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %.28 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
-// CHECK:STDOUT:     %n.patt: %.4 = binding_pattern n
-// CHECK:STDOUT:     %n.param_patt: %.4 = value_param_pattern %n.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %.4 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %.4 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %n.patt: %.32 = binding_pattern n
+// CHECK:STDOUT:     %n.param_patt: %.32 = value_param_pattern %n.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %.32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %.32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %UInt.ref.loc10_9: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
-// CHECK:STDOUT:     %.loc10_14: i32 = int_value 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc10_13: init type = call %UInt.ref.loc10_9(%.loc10_14) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_16.1: type = value_of_initializer %int.make_type_unsigned.loc10_13 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_16.2: type = converted %int.make_type_unsigned.loc10_13, %.loc10_16.1 [template = constants.%.4]
+// CHECK:STDOUT:     %.loc10_14.1: Core.IntLiteral = int_value 13 [template = constants.%.29]
+// CHECK:STDOUT:     %.loc10_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc10_14.3: <bound method> = bound_method %.loc10_14.1, %.loc10_14.2 [template = constants.%.30]
+// CHECK:STDOUT:     %int.convert_checked.loc10_14: init i32 = call %.loc10_14.3(%.loc10_14.1) [template = constants.%.31]
+// CHECK:STDOUT:     %.loc10_14.4: i32 = value_of_initializer %int.convert_checked.loc10_14 [template = constants.%.31]
+// CHECK:STDOUT:     %.loc10_14.5: i32 = converted %.loc10_14.1, %.loc10_14.4 [template = constants.%.31]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc10_13: init type = call %UInt.ref.loc10_9(%.loc10_14.5) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc10_16.1: type = value_of_initializer %int.make_type_unsigned.loc10_13 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc10_16.2: type = converted %int.make_type_unsigned.loc10_13, %.loc10_16.1 [template = constants.%.32]
 // CHECK:STDOUT:     %UInt.ref.loc10_22: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
-// CHECK:STDOUT:     %.loc10_27: i32 = int_value 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc10_26: init type = call %UInt.ref.loc10_22(%.loc10_27) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_29.1: type = value_of_initializer %int.make_type_unsigned.loc10_26 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_29.2: type = converted %int.make_type_unsigned.loc10_26, %.loc10_29.1 [template = constants.%.4]
-// CHECK:STDOUT:     %n.param: %.4 = value_param runtime_param0
-// CHECK:STDOUT:     %n: %.4 = bind_name n, %n.param
-// CHECK:STDOUT:     %return.param: ref %.4 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %.4 = return_slot %return.param
+// CHECK:STDOUT:     %.loc10_27.1: Core.IntLiteral = int_value 13 [template = constants.%.29]
+// CHECK:STDOUT:     %.loc10_27.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc10_27.3: <bound method> = bound_method %.loc10_27.1, %.loc10_27.2 [template = constants.%.30]
+// CHECK:STDOUT:     %int.convert_checked.loc10_27: init i32 = call %.loc10_27.3(%.loc10_27.1) [template = constants.%.31]
+// CHECK:STDOUT:     %.loc10_27.4: i32 = value_of_initializer %int.convert_checked.loc10_27 [template = constants.%.31]
+// CHECK:STDOUT:     %.loc10_27.5: i32 = converted %.loc10_27.1, %.loc10_27.4 [template = constants.%.31]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc10_26: init type = call %UInt.ref.loc10_22(%.loc10_27.5) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc10_29.1: type = value_of_initializer %int.make_type_unsigned.loc10_26 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc10_29.2: type = converted %int.make_type_unsigned.loc10_26, %.loc10_29.1 [template = constants.%.32]
+// CHECK:STDOUT:     %n.param: %.32 = value_param runtime_param0
+// CHECK:STDOUT:     %n: %.32 = bind_name n, %n.param
+// CHECK:STDOUT:     %return.param: ref %.32 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %.32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Symbolic.decl: %Symbolic.type = fn_decl @Symbolic [template = constants.%Symbolic] {
-// CHECK:STDOUT:     %N.patt.loc14_13.1: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc14_13.2 (constants.%N.patt)]
-// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc14_13.1, runtime_param<invalid> [symbolic = %N.patt.loc14_13.2 (constants.%N.patt)]
-// CHECK:STDOUT:     %x.patt: @Symbolic.%.loc14_29 (%.5) = binding_pattern x
-// CHECK:STDOUT:     %x.param_patt: @Symbolic.%.loc14_29 (%.5) = value_param_pattern %x.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: @Symbolic.%.loc14_29 (%.5) = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: @Symbolic.%.loc14_29 (%.5) = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %N.patt.loc14_13.1: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc14_13.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc14_13.1, runtime_param<invalid> [symbolic = %N.patt.loc14_13.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:     %x.patt: @Symbolic.%.loc14_29 (%.33) = binding_pattern x
+// CHECK:STDOUT:     %x.param_patt: @Symbolic.%.loc14_29 (%.33) = value_param_pattern %x.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: @Symbolic.%.loc14_29 (%.33) = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: @Symbolic.%.loc14_29 (%.33) = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc14_17.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc14_17.2: type = converted %int.make_type_32, %.loc14_17.1 [template = i32]
 // CHECK:STDOUT:     %UInt.ref.loc14_25: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
-// CHECK:STDOUT:     %N.ref.loc14_30: i32 = name_ref N, %N.loc14_13.1 [symbolic = %N.loc14_13.2 (constants.%N)]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc14_29: init type = call %UInt.ref.loc14_25(%N.ref.loc14_30) [symbolic = %.loc14_29 (constants.%.5)]
-// CHECK:STDOUT:     %.loc14_31.1: type = value_of_initializer %int.make_type_unsigned.loc14_29 [symbolic = %.loc14_29 (constants.%.5)]
-// CHECK:STDOUT:     %.loc14_31.2: type = converted %int.make_type_unsigned.loc14_29, %.loc14_31.1 [symbolic = %.loc14_29 (constants.%.5)]
+// CHECK:STDOUT:     %N.ref.loc14_30: i32 = name_ref N, %N.loc14_13.1 [symbolic = %N.loc14_13.2 (constants.%N.2)]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc14_29: init type = call %UInt.ref.loc14_25(%N.ref.loc14_30) [symbolic = %.loc14_29 (constants.%.33)]
+// CHECK:STDOUT:     %.loc14_31.1: type = value_of_initializer %int.make_type_unsigned.loc14_29 [symbolic = %.loc14_29 (constants.%.33)]
+// CHECK:STDOUT:     %.loc14_31.2: type = converted %int.make_type_unsigned.loc14_29, %.loc14_31.1 [symbolic = %.loc14_29 (constants.%.33)]
 // CHECK:STDOUT:     %UInt.ref.loc14_37: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
-// CHECK:STDOUT:     %N.ref.loc14_42: i32 = name_ref N, %N.loc14_13.1 [symbolic = %N.loc14_13.2 (constants.%N)]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc14_41: init type = call %UInt.ref.loc14_37(%N.ref.loc14_42) [symbolic = %.loc14_29 (constants.%.5)]
-// CHECK:STDOUT:     %.loc14_43.1: type = value_of_initializer %int.make_type_unsigned.loc14_41 [symbolic = %.loc14_29 (constants.%.5)]
-// CHECK:STDOUT:     %.loc14_43.2: type = converted %int.make_type_unsigned.loc14_41, %.loc14_43.1 [symbolic = %.loc14_29 (constants.%.5)]
+// CHECK:STDOUT:     %N.ref.loc14_42: i32 = name_ref N, %N.loc14_13.1 [symbolic = %N.loc14_13.2 (constants.%N.2)]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc14_41: init type = call %UInt.ref.loc14_37(%N.ref.loc14_42) [symbolic = %.loc14_29 (constants.%.33)]
+// CHECK:STDOUT:     %.loc14_43.1: type = value_of_initializer %int.make_type_unsigned.loc14_41 [symbolic = %.loc14_29 (constants.%.33)]
+// CHECK:STDOUT:     %.loc14_43.2: type = converted %int.make_type_unsigned.loc14_41, %.loc14_43.1 [symbolic = %.loc14_29 (constants.%.33)]
 // CHECK:STDOUT:     %N.param: i32 = value_param runtime_param<invalid>
-// CHECK:STDOUT:     %N.loc14_13.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc14_13.2 (constants.%N)]
-// CHECK:STDOUT:     %x.param: @Symbolic.%.loc14_29 (%.5) = value_param runtime_param0
-// CHECK:STDOUT:     %x: @Symbolic.%.loc14_29 (%.5) = bind_name x, %x.param
-// CHECK:STDOUT:     %return.param: ref @Symbolic.%.loc14_29 (%.5) = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref @Symbolic.%.loc14_29 (%.5) = return_slot %return.param
+// CHECK:STDOUT:     %N.loc14_13.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc14_13.2 (constants.%N.2)]
+// CHECK:STDOUT:     %x.param: @Symbolic.%.loc14_29 (%.33) = value_param runtime_param0
+// CHECK:STDOUT:     %x: @Symbolic.%.loc14_29 (%.33) = bind_name x, %x.param
+// CHECK:STDOUT:     %return.param: ref @Symbolic.%.loc14_29 (%.33) = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref @Symbolic.%.loc14_29 (%.33) = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @UInt(%n.param_patt: i32) -> type = "int.make_type_unsigned";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%n.param_patt: %.2) -> %.2 {
+// CHECK:STDOUT: fn @F(%n.param_patt: %.28) -> %.28 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %n.ref: %.2 = name_ref n, %n
+// CHECK:STDOUT:   %n.ref: %.28 = name_ref n, %n
 // CHECK:STDOUT:   return %n.ref
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(%n.param_patt: %.4) -> %.4 {
+// CHECK:STDOUT: fn @G(%n.param_patt: %.32) -> %.32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %n.ref: %.4 = name_ref n, %n
+// CHECK:STDOUT:   %n.ref: %.32 = name_ref n, %n
 // CHECK:STDOUT:   return %n.ref
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @Symbolic(%N.loc14_13.1: i32) {
-// CHECK:STDOUT:   %N.loc14_13.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc14_13.2 (constants.%N)]
-// CHECK:STDOUT:   %N.patt.loc14_13.2: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc14_13.2 (constants.%N.patt)]
-// CHECK:STDOUT:   %.loc14_29: type = int_type unsigned, %N.loc14_13.2 [symbolic = %.loc14_29 (constants.%.5)]
+// CHECK:STDOUT:   %N.loc14_13.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc14_13.2 (constants.%N.2)]
+// CHECK:STDOUT:   %N.patt.loc14_13.2: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc14_13.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:   %.loc14_29: type = int_type unsigned, %N.loc14_13.2 [symbolic = %.loc14_29 (constants.%.33)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn(%N.param_patt: i32, %x.param_patt: @Symbolic.%.loc14_29 (%.5)) -> @Symbolic.%.loc14_29 (%.5) {
+// CHECK:STDOUT:   fn(%N.param_patt: i32, %x.param_patt: @Symbolic.%.loc14_29 (%.33)) -> @Symbolic.%.loc14_29 (%.33) {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %x.ref: @Symbolic.%.loc14_29 (%.5) = name_ref x, %x
+// CHECK:STDOUT:     %x.ref: @Symbolic.%.loc14_29 (%.33) = name_ref x, %x
 // CHECK:STDOUT:     return %x.ref
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Symbolic(constants.%N) {
-// CHECK:STDOUT:   %N.loc14_13.2 => constants.%N
-// CHECK:STDOUT:   %N.patt.loc14_13.2 => constants.%N
-// CHECK:STDOUT:   %.loc14_29 => constants.%.5
+// CHECK:STDOUT: specific @Symbolic(constants.%N.2) {
+// CHECK:STDOUT:   %N.loc14_13.2 => constants.%N.2
+// CHECK:STDOUT:   %N.patt.loc14_13.2 => constants.%N.2
+// CHECK:STDOUT:   %.loc14_29 => constants.%.33
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_zero_size.carbon
@@ -262,12 +291,19 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %UInt.type: type = fn_type @UInt [template]
 // CHECK:STDOUT:   %UInt: %UInt.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref: %UInt.type = import_ref Main//types, inst+22, loaded [template = constants.%UInt]
+// CHECK:STDOUT:   %import_ref.1: %UInt.type = import_ref Main//types, inst+22, loaded [template = constants.%UInt]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -275,15 +311,20 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .UInt = imports.%import_ref
+// CHECK:STDOUT:     .UInt = imports.%import_ref.1
 // CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .n = %n
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
-// CHECK:STDOUT:   %UInt.ref: %UInt.type = name_ref UInt, imports.%import_ref [template = constants.%UInt]
-// CHECK:STDOUT:   %.loc10_13: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %int.make_type_unsigned: init type = call %UInt.ref(%.loc10_13) [template = <error>]
+// CHECK:STDOUT:   %UInt.ref: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
+// CHECK:STDOUT:   %.loc10_13.1: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_13.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_13.3: <bound method> = bound_method %.loc10_13.1, %.loc10_13.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc10_13.3(%.loc10_13.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_13.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_13.5: i32 = converted %.loc10_13.1, %.loc10_13.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.make_type_unsigned: init type = call %UInt.ref(%.loc10_13.5) [template = <error>]
 // CHECK:STDOUT:   %.loc10_14.1: type = value_of_initializer %int.make_type_unsigned [template = <error>]
 // CHECK:STDOUT:   %.loc10_14.2: type = converted %int.make_type_unsigned, %.loc10_14.1 [template = <error>]
 // CHECK:STDOUT:   %n.var: ref <error> = var n
@@ -301,14 +342,21 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
 // CHECK:STDOUT:   %UInt.type: type = fn_type @UInt [template]
 // CHECK:STDOUT:   %UInt: %UInt.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %UInt.type = import_ref Main//types, inst+22, loaded [template = constants.%UInt]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -342,10 +390,15 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %UInt.ref: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
 // CHECK:STDOUT:   %Negate.ref: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_20: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_20) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_19.1: i32 = value_of_initializer %int.snegate [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_19.2: i32 = converted %int.snegate, %.loc12_19.1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12_20.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_20.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_20.3: <bound method> = bound_method %.loc12_20.1, %.loc12_20.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc12_20.3(%.loc12_20.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_20.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_20.5: i32 = converted %.loc12_20.1, %.loc12_20.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_20.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_19.1: i32 = value_of_initializer %int.snegate [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_19.2: i32 = converted %int.snegate, %.loc12_19.1 [template = constants.%.28]
 // CHECK:STDOUT:   %int.make_type_unsigned: init type = call %UInt.ref(%.loc12_19.2) [template = <error>]
 // CHECK:STDOUT:   %.loc12_22.1: type = value_of_initializer %int.make_type_unsigned [template = <error>]
 // CHECK:STDOUT:   %.loc12_22.2: type = converted %int.make_type_unsigned, %.loc12_22.1 [template = <error>]
@@ -362,12 +415,19 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %UInt.type: type = fn_type @UInt [template]
 // CHECK:STDOUT:   %UInt: %UInt.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1000000000 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1000000000 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1000000000 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref: %UInt.type = import_ref Main//types, inst+22, loaded [template = constants.%UInt]
+// CHECK:STDOUT:   %import_ref.1: %UInt.type = import_ref Main//types, inst+22, loaded [template = constants.%UInt]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -375,15 +435,20 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .UInt = imports.%import_ref
+// CHECK:STDOUT:     .UInt = imports.%import_ref.1
 // CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .m = %m
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %default.import = import <invalid>
-// CHECK:STDOUT:   %UInt.ref: %UInt.type = name_ref UInt, imports.%import_ref [template = constants.%UInt]
-// CHECK:STDOUT:   %.loc9_13: i32 = int_value 1000000000 [template = constants.%.1]
-// CHECK:STDOUT:   %int.make_type_unsigned: init type = call %UInt.ref(%.loc9_13) [template = <error>]
+// CHECK:STDOUT:   %UInt.ref: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
+// CHECK:STDOUT:   %.loc9_13.1: Core.IntLiteral = int_value 1000000000 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_13.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_13.3: <bound method> = bound_method %.loc9_13.1, %.loc9_13.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc9_13.3(%.loc9_13.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_13.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_13.5: i32 = converted %.loc9_13.1, %.loc9_13.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.make_type_unsigned: init type = call %UInt.ref(%.loc9_13.5) [template = <error>]
 // CHECK:STDOUT:   %.loc9_23.1: type = value_of_initializer %int.make_type_unsigned [template = <error>]
 // CHECK:STDOUT:   %.loc9_23.2: type = converted %int.make_type_unsigned, %.loc9_23.1 [template = <error>]
 // CHECK:STDOUT:   %m.var: ref <error> = var m

+ 43 - 14
toolchain/check/testdata/builtins/int/neq.carbon

@@ -39,10 +39,18 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.7: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.31: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.35: bool = bool_literal true [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -51,6 +59,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -151,11 +160,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %false_.ref: %False = name_ref false_, %false_
 // CHECK:STDOUT:   %Neq.ref.loc8: %Neq.type = name_ref Neq, file.%Neq.decl [template = constants.%Neq]
-// CHECK:STDOUT:   %.loc8_21: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc8_24: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_21, %.loc8_24) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc8_14.1: bool = value_of_initializer %int.neq.loc8 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc8_14.2: bool = converted %int.neq.loc8, %.loc8_14.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc8_21.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_24.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_21.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_21.3: <bound method> = bound_method %.loc8_21.1, %.loc8_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc8_21: init i32 = call %.loc8_21.3(%.loc8_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_21.4: i32 = value_of_initializer %int.convert_checked.loc8_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_21.5: i32 = converted %.loc8_21.1, %.loc8_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_24.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_24.3: <bound method> = bound_method %.loc8_24.1, %.loc8_24.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc8_24: init i32 = call %.loc8_24.3(%.loc8_24.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_24.4: i32 = value_of_initializer %int.convert_checked.loc8_24 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_24.5: i32 = converted %.loc8_24.1, %.loc8_24.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_21.5, %.loc8_24.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_14.1: bool = value_of_initializer %int.neq.loc8 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_14.2: bool = converted %int.neq.loc8, %.loc8_14.1 [template = constants.%.31]
 // CHECK:STDOUT:   if %.loc8_14.2 br !if.expr.then.loc8 else br !if.expr.else.loc8
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc8:
@@ -170,11 +189,21 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.loc8_14.3: type = block_arg !if.expr.result.loc8 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref: %True = name_ref true_, %true_
 // CHECK:STDOUT:   %Neq.ref.loc9: %Neq.type = name_ref Neq, file.%Neq.decl [template = constants.%Neq]
-// CHECK:STDOUT:   %.loc9_20: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_23: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   %int.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_20, %.loc9_23) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %int.neq.loc9 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_13.2: bool = converted %int.neq.loc9, %.loc9_13.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_20.1: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_23.1: Core.IntLiteral = int_value 2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_20.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_20.3: <bound method> = bound_method %.loc9_20.1, %.loc9_20.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc9_20: init i32 = call %.loc9_20.3(%.loc9_20.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc9_20.4: i32 = value_of_initializer %int.convert_checked.loc9_20 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc9_20.5: i32 = converted %.loc9_20.1, %.loc9_20.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc9_23.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_23.3: <bound method> = bound_method %.loc9_23.1, %.loc9_23.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc9_23: init i32 = call %.loc9_23.3(%.loc9_23.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_23.4: i32 = value_of_initializer %int.convert_checked.loc9_23 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_23.5: i32 = converted %.loc9_23.1, %.loc9_23.4 [template = constants.%.34]
+// CHECK:STDOUT:   %int.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_20.5, %.loc9_23.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %int.neq.loc9 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc9_13.2: bool = converted %int.neq.loc9, %.loc9_13.1 [template = constants.%.35]
 // CHECK:STDOUT:   if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:

+ 46 - 33
toolchain/check/testdata/builtins/int/or.carbon

@@ -26,17 +26,25 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Or.type: type = fn_type @Or [template]
 // CHECK:STDOUT:   %Or: %Or.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 12 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 10 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 14 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 12 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 10 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 14 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 12 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 10 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 14 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 14 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -85,32 +93,37 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Or.ref: %Or.type = name_ref Or, %Or.decl [template = constants.%Or]
-// CHECK:STDOUT:   %.loc4_19: i32 = int_value 12 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 10 [template = constants.%.2]
-// CHECK:STDOUT:   %int.or: init i32 = call %Or.ref(%.loc4_19, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_19.1: Core.IntLiteral = int_value 12 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 10 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_19.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_19.3: <bound method> = bound_method %.loc4_19.1, %.loc4_19.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init i32 = call %.loc4_19.3(%.loc4_19.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_19.5: i32 = converted %.loc4_19.1, %.loc4_19.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.or: init i32 = call %Or.ref(%.loc4_19.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_18.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_18.2: <bound method> = bound_method %int.or, %.loc4_18.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_18.3: i32 = value_of_initializer %int.or [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_18.4: i32 = converted %int.or, %.loc4_18.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_18.2(%.loc4_18.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_18.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_18.6: Core.IntLiteral = converted %int.or, %.loc4_18.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_26: type = array_type %.loc4_18.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_18.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_18.2: <bound method> = bound_method %int.or, %.loc4_18.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_18.3: i32 = value_of_initializer %int.or [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_18.4: i32 = converted %int.or, %.loc4_18.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_18: init Core.IntLiteral = call %.loc4_18.2(%.loc4_18.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_18.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_18 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_18.6: Core.IntLiteral = converted %int.or, %.loc4_18.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_26: type = array_type %.loc4_18.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 14 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 14 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_20: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_21: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_20: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_21: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -152,9 +165,9 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 219 - 134
toolchain/check/testdata/builtins/int/right_shift.carbon

@@ -71,17 +71,25 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %RightShift.type: type = fn_type @RightShift [template]
 // CHECK:STDOUT:   %RightShift: %RightShift.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 22 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 22 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 5 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 22 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -130,32 +138,37 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %RightShift.ref: %RightShift.type = name_ref RightShift, %RightShift.decl [template = constants.%RightShift]
-// CHECK:STDOUT:   %.loc4_27: i32 = int_value 22 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_31: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.right_shift: init i32 = call %RightShift.ref(%.loc4_27, %.loc4_31) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_27.1: Core.IntLiteral = int_value 22 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_31.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_27.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_27.3: <bound method> = bound_method %.loc4_27.1, %.loc4_27.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_27: init i32 = call %.loc4_27.3(%.loc4_27.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_27.4: i32 = value_of_initializer %int.convert_checked.loc4_27 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_27.5: i32 = converted %.loc4_27.1, %.loc4_27.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_31.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_31.3: <bound method> = bound_method %.loc4_31.1, %.loc4_31.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_31: init i32 = call %.loc4_31.3(%.loc4_31.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_31.4: i32 = value_of_initializer %int.convert_checked.loc4_31 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_31.5: i32 = converted %.loc4_31.1, %.loc4_31.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.right_shift: init i32 = call %RightShift.ref(%.loc4_27.5, %.loc4_31.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_26.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_26.2: <bound method> = bound_method %int.right_shift, %.loc4_26.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_26.3: i32 = value_of_initializer %int.right_shift [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_26.4: i32 = converted %int.right_shift, %.loc4_26.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_26.2(%.loc4_26.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_26.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_26.6: Core.IntLiteral = converted %int.right_shift, %.loc4_26.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_33: type = array_type %.loc4_26.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_26.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_26.2: <bound method> = bound_method %int.right_shift, %.loc4_26.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_26.3: i32 = value_of_initializer %int.right_shift [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_26.4: i32 = converted %int.right_shift, %.loc4_26.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_26: init Core.IntLiteral = call %.loc4_26.2(%.loc4_26.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_26.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_26 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_26.6: Core.IntLiteral = converted %int.right_shift, %.loc4_26.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_33: type = array_type %.loc4_26.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 5 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 5 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -197,9 +210,9 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -212,25 +225,34 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:   %RightShift: %RightShift.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.29: type = array_type %.28, i32 [template]
-// CHECK:STDOUT:   %.30: type = ptr_type %.29 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 10 [template]
-// CHECK:STDOUT:   %.32: i32 = int_value -10 [template]
-// CHECK:STDOUT:   %.33: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.34: i32 = int_value -3 [template]
-// CHECK:STDOUT:   %.35: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.36: <bound method> = bound_method %.35, %Convert.15 [template]
-// CHECK:STDOUT:   %.37: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.38: type = array_type %.37, i32 [template]
-// CHECK:STDOUT:   %.39: type = ptr_type %.38 [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.27, %Convert.16 [template]
+// CHECK:STDOUT:   %.31: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.32: type = ptr_type %.31 [template]
+// CHECK:STDOUT:   %.33: Core.IntLiteral = int_value 10 [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.33, %Convert.15 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value 10 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value -10 [template]
+// CHECK:STDOUT:   %.37: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.38: <bound method> = bound_method %.37, %Convert.15 [template]
+// CHECK:STDOUT:   %.39: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.40: i32 = int_value -3 [template]
+// CHECK:STDOUT:   %.41: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.42: <bound method> = bound_method %.41, %Convert.16 [template]
+// CHECK:STDOUT:   %.43: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.44: type = array_type %.43, i32 [template]
+// CHECK:STDOUT:   %.45: type = ptr_type %.44 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -298,74 +320,84 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:   %Negate.ref.loc10_17: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %RightShift.ref.loc10: %RightShift.type = name_ref RightShift, %RightShift.decl [template = constants.%RightShift]
 // CHECK:STDOUT:   %Negate.ref.loc10_35: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc10_42: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc10_41: init i32 = call %Negate.ref.loc10_35(%.loc10_42) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_46: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_41.1: i32 = value_of_initializer %int.snegate.loc10_41 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_41.2: i32 = converted %int.snegate.loc10_41, %.loc10_41.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.right_shift.loc10: init i32 = call %RightShift.ref.loc10(%.loc10_41.2, %.loc10_46) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_34.1: i32 = value_of_initializer %int.right_shift.loc10 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_34.2: i32 = converted %int.right_shift.loc10, %.loc10_34.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.snegate.loc10_23: init i32 = call %Negate.ref.loc10_17(%.loc10_34.2) [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_42.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_42.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_42.3: <bound method> = bound_method %.loc10_42.1, %.loc10_42.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc10_42: init i32 = call %.loc10_42.3(%.loc10_42.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_42.4: i32 = value_of_initializer %int.convert_checked.loc10_42 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_42.5: i32 = converted %.loc10_42.1, %.loc10_42.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc10_41: init i32 = call %Negate.ref.loc10_35(%.loc10_42.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_46.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_41.1: i32 = value_of_initializer %int.snegate.loc10_41 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_41.2: i32 = converted %int.snegate.loc10_41, %.loc10_41.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_46.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_46.3: <bound method> = bound_method %.loc10_46.1, %.loc10_46.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc10_46: init i32 = call %.loc10_46.3(%.loc10_46.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_46.4: i32 = value_of_initializer %int.convert_checked.loc10_46 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_46.5: i32 = converted %.loc10_46.1, %.loc10_46.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.right_shift.loc10: init i32 = call %RightShift.ref.loc10(%.loc10_41.2, %.loc10_46.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_34.1: i32 = value_of_initializer %int.right_shift.loc10 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_34.2: i32 = converted %int.right_shift.loc10, %.loc10_34.1 [template = constants.%.28]
+// CHECK:STDOUT:   %int.snegate.loc10_23: init i32 = call %Negate.ref.loc10_17(%.loc10_34.2) [template = constants.%.27]
 // CHECK:STDOUT:   %.loc10_12.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
 // CHECK:STDOUT:   %.loc10_12.2: type = converted %int.make_type_32.loc10, %.loc10_12.1 [template = i32]
-// CHECK:STDOUT:   %.loc10_23.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc10_23.2: <bound method> = bound_method %int.snegate.loc10_23, %.loc10_23.1 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc10_23.3: i32 = value_of_initializer %int.snegate.loc10_23 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_23.4: i32 = converted %int.snegate.loc10_23, %.loc10_23.3 [template = constants.%.1]
-// CHECK:STDOUT:   %int.convert_checked.loc10: init Core.IntLiteral = call %.loc10_23.2(%.loc10_23.4) [template = constants.%.28]
-// CHECK:STDOUT:   %.loc10_23.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc10 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc10_23.6: Core.IntLiteral = converted %int.snegate.loc10_23, %.loc10_23.5 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc10_49: type = array_type %.loc10_23.6, i32 [template = constants.%.29]
-// CHECK:STDOUT:   %arr1.var: ref %.29 = var arr1
-// CHECK:STDOUT:   %arr1: ref %.29 = bind_name arr1, %arr1.var
+// CHECK:STDOUT:   %.loc10_23.1: %Convert.type.5 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc10_23.2: <bound method> = bound_method %int.snegate.loc10_23, %.loc10_23.1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc10_23.3: i32 = value_of_initializer %int.snegate.loc10_23 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_23.4: i32 = converted %int.snegate.loc10_23, %.loc10_23.3 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc10_23: init Core.IntLiteral = call %.loc10_23.2(%.loc10_23.4) [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_23.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc10_23 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_23.6: Core.IntLiteral = converted %int.snegate.loc10_23, %.loc10_23.5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_49: type = array_type %.loc10_23.6, i32 [template = constants.%.31]
+// CHECK:STDOUT:   %arr1.var: ref %.31 = var arr1
+// CHECK:STDOUT:   %arr1: ref %.31 = bind_name arr1, %arr1.var
 // CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc11_19.1: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_19: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc11_14.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
 // CHECK:STDOUT:   %.loc11_14.2: type = converted %int.make_type_32.loc11, %.loc11_14.1 [template = i32]
-// CHECK:STDOUT:   %.loc11_19.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc11_19.3: <bound method> = bound_method %.loc11_19.1, %.loc11_19.2 [template = constants.%.27]
-// CHECK:STDOUT:   %int.convert_checked.loc11: init Core.IntLiteral = call %.loc11_19.3(%.loc11_19.1) [template = constants.%.28]
-// CHECK:STDOUT:   %.loc11_19.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc11 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc11_19.5: Core.IntLiteral = converted %.loc11_19.1, %.loc11_19.4 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc11_20: type = array_type %.loc11_19.5, i32 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc11_21: type = ptr_type %.29 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_20: type = array_type %.loc11_19, i32 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_21: type = ptr_type %.31 [template = constants.%.32]
 // CHECK:STDOUT:   %int.make_type_32.loc14: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Negate.ref.loc14_17: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %RightShift.ref.loc14: %RightShift.type = name_ref RightShift, %RightShift.decl [template = constants.%RightShift]
 // CHECK:STDOUT:   %Negate.ref.loc14_35: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc14_42: i32 = int_value 10 [template = constants.%.31]
-// CHECK:STDOUT:   %int.snegate.loc14_41: init i32 = call %Negate.ref.loc14_35(%.loc14_42) [template = constants.%.32]
-// CHECK:STDOUT:   %.loc14_47: i32 = int_value 2 [template = constants.%.33]
-// CHECK:STDOUT:   %.loc14_41.1: i32 = value_of_initializer %int.snegate.loc14_41 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc14_41.2: i32 = converted %int.snegate.loc14_41, %.loc14_41.1 [template = constants.%.32]
-// CHECK:STDOUT:   %int.right_shift.loc14: init i32 = call %RightShift.ref.loc14(%.loc14_41.2, %.loc14_47) [template = constants.%.34]
-// CHECK:STDOUT:   %.loc14_34.1: i32 = value_of_initializer %int.right_shift.loc14 [template = constants.%.34]
-// CHECK:STDOUT:   %.loc14_34.2: i32 = converted %int.right_shift.loc14, %.loc14_34.1 [template = constants.%.34]
-// CHECK:STDOUT:   %int.snegate.loc14_23: init i32 = call %Negate.ref.loc14_17(%.loc14_34.2) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc14_42.1: Core.IntLiteral = int_value 10 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc14_42.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_42.3: <bound method> = bound_method %.loc14_42.1, %.loc14_42.2 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked.loc14_42: init i32 = call %.loc14_42.3(%.loc14_42.1) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc14_42.4: i32 = value_of_initializer %int.convert_checked.loc14_42 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc14_42.5: i32 = converted %.loc14_42.1, %.loc14_42.4 [template = constants.%.35]
+// CHECK:STDOUT:   %int.snegate.loc14_41: init i32 = call %Negate.ref.loc14_35(%.loc14_42.5) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_47.1: Core.IntLiteral = int_value 2 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc14_41.1: i32 = value_of_initializer %int.snegate.loc14_41 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_41.2: i32 = converted %int.snegate.loc14_41, %.loc14_41.1 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc14_47.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_47.3: <bound method> = bound_method %.loc14_47.1, %.loc14_47.2 [template = constants.%.38]
+// CHECK:STDOUT:   %int.convert_checked.loc14_47: init i32 = call %.loc14_47.3(%.loc14_47.1) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc14_47.4: i32 = value_of_initializer %int.convert_checked.loc14_47 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc14_47.5: i32 = converted %.loc14_47.1, %.loc14_47.4 [template = constants.%.39]
+// CHECK:STDOUT:   %int.right_shift.loc14: init i32 = call %RightShift.ref.loc14(%.loc14_41.2, %.loc14_47.5) [template = constants.%.40]
+// CHECK:STDOUT:   %.loc14_34.1: i32 = value_of_initializer %int.right_shift.loc14 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc14_34.2: i32 = converted %int.right_shift.loc14, %.loc14_34.1 [template = constants.%.40]
+// CHECK:STDOUT:   %int.snegate.loc14_23: init i32 = call %Negate.ref.loc14_17(%.loc14_34.2) [template = constants.%.41]
 // CHECK:STDOUT:   %.loc14_12.1: type = value_of_initializer %int.make_type_32.loc14 [template = i32]
 // CHECK:STDOUT:   %.loc14_12.2: type = converted %int.make_type_32.loc14, %.loc14_12.1 [template = i32]
-// CHECK:STDOUT:   %.loc14_23.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc14_23.2: <bound method> = bound_method %int.snegate.loc14_23, %.loc14_23.1 [template = constants.%.36]
-// CHECK:STDOUT:   %.loc14_23.3: i32 = value_of_initializer %int.snegate.loc14_23 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc14_23.4: i32 = converted %int.snegate.loc14_23, %.loc14_23.3 [template = constants.%.35]
-// CHECK:STDOUT:   %int.convert_checked.loc14: init Core.IntLiteral = call %.loc14_23.2(%.loc14_23.4) [template = constants.%.37]
-// CHECK:STDOUT:   %.loc14_23.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc14 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc14_23.6: Core.IntLiteral = converted %int.snegate.loc14_23, %.loc14_23.5 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc14_50: type = array_type %.loc14_23.6, i32 [template = constants.%.38]
-// CHECK:STDOUT:   %arr2.var: ref %.38 = var arr2
-// CHECK:STDOUT:   %arr2: ref %.38 = bind_name arr2, %arr2.var
+// CHECK:STDOUT:   %.loc14_23.1: %Convert.type.5 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc14_23.2: <bound method> = bound_method %int.snegate.loc14_23, %.loc14_23.1 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc14_23.3: i32 = value_of_initializer %int.snegate.loc14_23 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc14_23.4: i32 = converted %int.snegate.loc14_23, %.loc14_23.3 [template = constants.%.41]
+// CHECK:STDOUT:   %int.convert_checked.loc14_23: init Core.IntLiteral = call %.loc14_23.2(%.loc14_23.4) [template = constants.%.43]
+// CHECK:STDOUT:   %.loc14_23.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc14_23 [template = constants.%.43]
+// CHECK:STDOUT:   %.loc14_23.6: Core.IntLiteral = converted %int.snegate.loc14_23, %.loc14_23.5 [template = constants.%.43]
+// CHECK:STDOUT:   %.loc14_50: type = array_type %.loc14_23.6, i32 [template = constants.%.44]
+// CHECK:STDOUT:   %arr2.var: ref %.44 = var arr2
+// CHECK:STDOUT:   %arr2: ref %.44 = bind_name arr2, %arr2.var
 // CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc15_19.1: i32 = int_value 3 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc15_19: Core.IntLiteral = int_value 3 [template = constants.%.43]
 // CHECK:STDOUT:   %.loc15_14.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
 // CHECK:STDOUT:   %.loc15_14.2: type = converted %int.make_type_32.loc15, %.loc15_14.1 [template = i32]
-// CHECK:STDOUT:   %.loc15_19.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc15_19.3: <bound method> = bound_method %.loc15_19.1, %.loc15_19.2 [template = constants.%.36]
-// CHECK:STDOUT:   %int.convert_checked.loc15: init Core.IntLiteral = call %.loc15_19.3(%.loc15_19.1) [template = constants.%.37]
-// CHECK:STDOUT:   %.loc15_19.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc15 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc15_19.5: Core.IntLiteral = converted %.loc15_19.1, %.loc15_19.4 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc15_20: type = array_type %.loc15_19.5, i32 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc15_21: type = ptr_type %.38 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc15_20: type = array_type %.loc15_19, i32 [template = constants.%.44]
+// CHECK:STDOUT:   %.loc15_21: type = ptr_type %.44 [template = constants.%.45]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RightShift(%a.param_patt: i32, %b.param_patt: i32) -> i32 = "int.right_shift";
@@ -374,12 +406,12 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr1.ref: ref %.29 = name_ref arr1, file.%arr1
-// CHECK:STDOUT:   %.loc11: %.30 = addr_of %arr1.ref
-// CHECK:STDOUT:   %arr1_p: %.30 = bind_name arr1_p, %.loc11
-// CHECK:STDOUT:   %arr2.ref: ref %.38 = name_ref arr2, file.%arr2
-// CHECK:STDOUT:   %.loc15: %.39 = addr_of %arr2.ref
-// CHECK:STDOUT:   %arr2_p: %.39 = bind_name arr2_p, %.loc15
+// CHECK:STDOUT:   %arr1.ref: ref %.31 = name_ref arr1, file.%arr1
+// CHECK:STDOUT:   %.loc11: %.32 = addr_of %arr1.ref
+// CHECK:STDOUT:   %arr1_p: %.32 = bind_name arr1_p, %.loc11
+// CHECK:STDOUT:   %arr2.ref: ref %.44 = name_ref arr2, file.%arr2
+// CHECK:STDOUT:   %.loc15: %.45 = addr_of %arr2.ref
+// CHECK:STDOUT:   %arr2_p: %.45 = bind_name arr2_p, %.loc15
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -392,17 +424,30 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:   %RightShift: %RightShift.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 31 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 32 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 33 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 31 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 31 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 32 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 32 [template]
+// CHECK:STDOUT:   %.35: Core.IntLiteral = int_value 33 [template]
+// CHECK:STDOUT:   %.36: <bound method> = bound_method %.35, %Convert.15 [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 33 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -481,34 +526,74 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %RightShift.ref.loc8: %RightShift.type = name_ref RightShift, file.%RightShift.decl [template = constants.%RightShift]
-// CHECK:STDOUT:   %.loc8_30: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_33: i32 = int_value 31 [template = constants.%.2]
-// CHECK:STDOUT:   %int.right_shift.loc8: init i32 = call %RightShift.ref.loc8(%.loc8_30, %.loc8_33) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_36.1: i32 = value_of_initializer %int.right_shift.loc8 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_36.2: i32 = converted %int.right_shift.loc8, %.loc8_36.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_30.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_33.1: Core.IntLiteral = int_value 31 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_30.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_30.3: <bound method> = bound_method %.loc8_30.1, %.loc8_30.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc8_30: init i32 = call %.loc8_30.3(%.loc8_30.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_30.4: i32 = value_of_initializer %int.convert_checked.loc8_30 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_30.5: i32 = converted %.loc8_30.1, %.loc8_30.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_33.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_33.3: <bound method> = bound_method %.loc8_33.1, %.loc8_33.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc8_33: init i32 = call %.loc8_33.3(%.loc8_33.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_33.4: i32 = value_of_initializer %int.convert_checked.loc8_33 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_33.5: i32 = converted %.loc8_33.1, %.loc8_33.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.right_shift.loc8: init i32 = call %RightShift.ref.loc8(%.loc8_30.5, %.loc8_33.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_36.1: i32 = value_of_initializer %int.right_shift.loc8 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_36.2: i32 = converted %int.right_shift.loc8, %.loc8_36.1 [template = constants.%.31]
 // CHECK:STDOUT:   %size_1: i32 = bind_name size_1, %.loc8_36.2
 // CHECK:STDOUT:   %RightShift.ref.loc13: %RightShift.type = name_ref RightShift, file.%RightShift.decl [template = constants.%RightShift]
-// CHECK:STDOUT:   %.loc13_30: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc13_33: i32 = int_value 32 [template = constants.%.4]
-// CHECK:STDOUT:   %int.right_shift.loc13: init i32 = call %RightShift.ref.loc13(%.loc13_30, %.loc13_33) [template = <error>]
+// CHECK:STDOUT:   %.loc13_30.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc13_33.1: Core.IntLiteral = int_value 32 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc13_30.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_30.3: <bound method> = bound_method %.loc13_30.1, %.loc13_30.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc13_30: init i32 = call %.loc13_30.3(%.loc13_30.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_30.4: i32 = value_of_initializer %int.convert_checked.loc13_30 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_30.5: i32 = converted %.loc13_30.1, %.loc13_30.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_33.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_33.3: <bound method> = bound_method %.loc13_33.1, %.loc13_33.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc13_33: init i32 = call %.loc13_33.3(%.loc13_33.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_33.4: i32 = value_of_initializer %int.convert_checked.loc13_33 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_33.5: i32 = converted %.loc13_33.1, %.loc13_33.4 [template = constants.%.34]
+// CHECK:STDOUT:   %int.right_shift.loc13: init i32 = call %RightShift.ref.loc13(%.loc13_30.5, %.loc13_33.5) [template = <error>]
 // CHECK:STDOUT:   %.loc13_36.1: i32 = value_of_initializer %int.right_shift.loc13 [template = <error>]
 // CHECK:STDOUT:   %.loc13_36.2: i32 = converted %int.right_shift.loc13, %.loc13_36.1 [template = <error>]
 // CHECK:STDOUT:   %size_2: i32 = bind_name size_2, %.loc13_36.2
 // CHECK:STDOUT:   %RightShift.ref.loc18: %RightShift.type = name_ref RightShift, file.%RightShift.decl [template = constants.%RightShift]
-// CHECK:STDOUT:   %.loc18_30: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc18_33: i32 = int_value 33 [template = constants.%.5]
-// CHECK:STDOUT:   %int.right_shift.loc18: init i32 = call %RightShift.ref.loc18(%.loc18_30, %.loc18_33) [template = <error>]
+// CHECK:STDOUT:   %.loc18_30.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc18_33.1: Core.IntLiteral = int_value 33 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc18_30.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc18_30.3: <bound method> = bound_method %.loc18_30.1, %.loc18_30.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc18_30: init i32 = call %.loc18_30.3(%.loc18_30.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc18_30.4: i32 = value_of_initializer %int.convert_checked.loc18_30 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc18_30.5: i32 = converted %.loc18_30.1, %.loc18_30.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc18_33.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc18_33.3: <bound method> = bound_method %.loc18_33.1, %.loc18_33.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc18_33: init i32 = call %.loc18_33.3(%.loc18_33.1) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc18_33.4: i32 = value_of_initializer %int.convert_checked.loc18_33 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc18_33.5: i32 = converted %.loc18_33.1, %.loc18_33.4 [template = constants.%.37]
+// CHECK:STDOUT:   %int.right_shift.loc18: init i32 = call %RightShift.ref.loc18(%.loc18_30.5, %.loc18_33.5) [template = <error>]
 // CHECK:STDOUT:   %.loc18_36.1: i32 = value_of_initializer %int.right_shift.loc18 [template = <error>]
 // CHECK:STDOUT:   %.loc18_36.2: i32 = converted %int.right_shift.loc18, %.loc18_36.1 [template = <error>]
 // CHECK:STDOUT:   %size_3: i32 = bind_name size_3, %.loc18_36.2
 // CHECK:STDOUT:   %RightShift.ref.loc24: %RightShift.type = name_ref RightShift, file.%RightShift.decl [template = constants.%RightShift]
-// CHECK:STDOUT:   %.loc24_32: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc24_32.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %Negate.ref: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc24_42: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc24_42) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc24_41.1: i32 = value_of_initializer %int.snegate [template = constants.%.6]
-// CHECK:STDOUT:   %.loc24_41.2: i32 = converted %int.snegate, %.loc24_41.1 [template = constants.%.6]
-// CHECK:STDOUT:   %int.right_shift.loc24: init i32 = call %RightShift.ref.loc24(%.loc24_32, %.loc24_41.2) [template = <error>]
+// CHECK:STDOUT:   %.loc24_42.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc24_42.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc24_42.3: <bound method> = bound_method %.loc24_42.1, %.loc24_42.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc24_42: init i32 = call %.loc24_42.3(%.loc24_42.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc24_42.4: i32 = value_of_initializer %int.convert_checked.loc24_42 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc24_42.5: i32 = converted %.loc24_42.1, %.loc24_42.4 [template = constants.%.28]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc24_42.5) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc24_32.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc24_32.3: <bound method> = bound_method %.loc24_32.1, %.loc24_32.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc24_32: init i32 = call %.loc24_32.3(%.loc24_32.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc24_32.4: i32 = value_of_initializer %int.convert_checked.loc24_32 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc24_32.5: i32 = converted %.loc24_32.1, %.loc24_32.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc24_41.1: i32 = value_of_initializer %int.snegate [template = constants.%.38]
+// CHECK:STDOUT:   %.loc24_41.2: i32 = converted %int.snegate, %.loc24_41.1 [template = constants.%.38]
+// CHECK:STDOUT:   %int.right_shift.loc24: init i32 = call %RightShift.ref.loc24(%.loc24_32.5, %.loc24_41.2) [template = <error>]
 // CHECK:STDOUT:   %.loc24_45.1: i32 = value_of_initializer %int.right_shift.loc24 [template = <error>]
 // CHECK:STDOUT:   %.loc24_45.2: i32 = converted %int.right_shift.loc24, %.loc24_45.1 [template = <error>]
 // CHECK:STDOUT:   %negative: i32 = bind_name negative, %.loc24_45.2

+ 148 - 63
toolchain/check/testdata/builtins/int/sadd.carbon

@@ -96,17 +96,25 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Add.type: type = fn_type @Add [template]
 // CHECK:STDOUT:   %Add: %Add.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -155,32 +163,37 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Add.ref: %Add.type = name_ref Add, %Add.decl [template = constants.%Add]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.sadd, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.sadd [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.sadd, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.sadd, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.sadd, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.sadd [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.sadd, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.sadd, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 3 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -222,9 +235,9 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -243,9 +256,19 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %BadReturnType: %BadReturnType.type = struct_value () [template]
 // CHECK:STDOUT:   %JustRight.type: type = fn_type @JustRight [template]
 // CHECK:STDOUT:   %JustRight: %JustRight.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.28, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 3 [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew.type: type = fn_type @RuntimeCallTooFew [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: %RuntimeCallTooFew.type = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany.type: type = fn_type @RuntimeCallTooMany [template]
@@ -258,6 +281,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -377,36 +401,66 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %TooFew.ref: %TooFew.type = name_ref TooFew, %TooFew.decl [template = constants.%TooFew]
-// CHECK:STDOUT:   %.loc25_27: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(%.loc25_27)
+// CHECK:STDOUT:   %.loc25_27.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc25_27.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc25_27.3: <bound method> = bound_method %.loc25_27.1, %.loc25_27.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc25: init i32 = call %.loc25_27.3(%.loc25_27.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc25_27.4: i32 = value_of_initializer %int.convert_checked.loc25 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc25_27.5: i32 = converted %.loc25_27.1, %.loc25_27.4 [template = constants.%.27]
+// CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(%.loc25_27.5)
 // CHECK:STDOUT:   %.loc25_15.1: type = value_of_initializer %int.make_type_32.loc25 [template = i32]
 // CHECK:STDOUT:   %.loc25_15.2: type = converted %int.make_type_32.loc25, %.loc25_15.1 [template = i32]
 // CHECK:STDOUT:   %too_few.var: ref <error> = var too_few
 // CHECK:STDOUT:   %too_few: ref <error> = bind_name too_few, %too_few.var
 // CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %TooMany.ref: %TooMany.type = name_ref TooMany, %TooMany.decl [template = constants.%TooMany]
-// CHECK:STDOUT:   %.loc30_29: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_32: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc30_35: i32 = int_value 3 [template = constants.%.3]
-// CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29, %.loc30_32, %.loc30_35)
+// CHECK:STDOUT:   %.loc30_29.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc30_32.1: Core.IntLiteral = int_value 2 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc30_35.1: Core.IntLiteral = int_value 3 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc30_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_29.3: <bound method> = bound_method %.loc30_29.1, %.loc30_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc30_29: init i32 = call %.loc30_29.3(%.loc30_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc30_29.4: i32 = value_of_initializer %int.convert_checked.loc30_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc30_29.5: i32 = converted %.loc30_29.1, %.loc30_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc30_32.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_32.3: <bound method> = bound_method %.loc30_32.1, %.loc30_32.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc30_32: init i32 = call %.loc30_32.3(%.loc30_32.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc30_32.4: i32 = value_of_initializer %int.convert_checked.loc30_32 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc30_32.5: i32 = converted %.loc30_32.1, %.loc30_32.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc30_35.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_35.3: <bound method> = bound_method %.loc30_35.1, %.loc30_35.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc30_35: init i32 = call %.loc30_35.3(%.loc30_35.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc30_35.4: i32 = value_of_initializer %int.convert_checked.loc30_35 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc30_35.5: i32 = converted %.loc30_35.1, %.loc30_35.4 [template = constants.%.33]
+// CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29.5, %.loc30_32.5, %.loc30_35.5)
 // CHECK:STDOUT:   %.loc30_16.1: type = value_of_initializer %int.make_type_32.loc30 [template = i32]
 // CHECK:STDOUT:   %.loc30_16.2: type = converted %int.make_type_32.loc30, %.loc30_16.1 [template = i32]
 // CHECK:STDOUT:   %too_many.var: ref <error> = var too_many
 // CHECK:STDOUT:   %too_many: ref <error> = bind_name too_many, %too_many.var
 // CHECK:STDOUT:   %int.make_type_32.loc35: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %BadReturnType.ref: %BadReturnType.type = name_ref BadReturnType, %BadReturnType.decl [template = constants.%BadReturnType]
-// CHECK:STDOUT:   %.loc35_42: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc35_45: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42, %.loc35_45)
+// CHECK:STDOUT:   %.loc35_42.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc35_45.1: Core.IntLiteral = int_value 2 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc35_42.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc35_42.3: <bound method> = bound_method %.loc35_42.1, %.loc35_42.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc35_42: init i32 = call %.loc35_42.3(%.loc35_42.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc35_42.4: i32 = value_of_initializer %int.convert_checked.loc35_42 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc35_42.5: i32 = converted %.loc35_42.1, %.loc35_42.4 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc35_45.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc35_45.3: <bound method> = bound_method %.loc35_45.1, %.loc35_45.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc35_45: init i32 = call %.loc35_45.3(%.loc35_45.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc35_45.4: i32 = value_of_initializer %int.convert_checked.loc35_45 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc35_45.5: i32 = converted %.loc35_45.1, %.loc35_45.4 [template = constants.%.31]
+// CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42.5, %.loc35_45.5)
 // CHECK:STDOUT:   %.loc35_23.1: type = value_of_initializer %int.make_type_32.loc35 [template = i32]
 // CHECK:STDOUT:   %.loc35_23.2: type = converted %int.make_type_32.loc35, %.loc35_23.1 [template = i32]
 // CHECK:STDOUT:   %bad_return_type.var: ref <error> = var bad_return_type
 // CHECK:STDOUT:   %bad_return_type: ref <error> = bind_name bad_return_type, %bad_return_type.var
 // CHECK:STDOUT:   %int.make_type_32.loc44: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %JustRight.ref: %JustRight.type = name_ref JustRight, %JustRight.decl [template = constants.%JustRight]
-// CHECK:STDOUT:   %.loc44_31: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc44_34: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc44_37: i32 = int_value 3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc44_31: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc44_34: Core.IntLiteral = int_value 2 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc44_37: Core.IntLiteral = int_value 3 [template = constants.%.29]
 // CHECK:STDOUT:   %.loc44_16.1: type = value_of_initializer %int.make_type_32.loc44 [template = i32]
 // CHECK:STDOUT:   %.loc44_16.2: type = converted %int.make_type_32.loc44, %.loc44_16.1 [template = i32]
 // CHECK:STDOUT:   %.loc44_39: type = array_type <error>, i32 [template = <error>]
@@ -534,15 +588,26 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Add.type: type = fn_type @Add [template]
 // CHECK:STDOUT:   %Add: %Add.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.31, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -593,18 +658,38 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Add.ref.loc6: %Add.type = name_ref Add, file.%Add.decl [template = constants.%Add]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_30: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sadd.loc6: init i32 = call %Add.ref.loc6(%.loc6_18, %.loc6_30) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.sadd.loc6 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.sadd.loc6, %.loc6_32.1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_18.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_30.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_18.3: <bound method> = bound_method %.loc6_18.1, %.loc6_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc6_18: init i32 = call %.loc6_18.3(%.loc6_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.4: i32 = value_of_initializer %int.convert_checked.loc6_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.5: i32 = converted %.loc6_18.1, %.loc6_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_30.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_30.3: <bound method> = bound_method %.loc6_30.1, %.loc6_30.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc6_30: init i32 = call %.loc6_30.3(%.loc6_30.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_30.4: i32 = value_of_initializer %int.convert_checked.loc6_30 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_30.5: i32 = converted %.loc6_30.1, %.loc6_30.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.sadd.loc6: init i32 = call %Add.ref.loc6(%.loc6_18.5, %.loc6_30.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.sadd.loc6 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.sadd.loc6, %.loc6_32.1 [template = constants.%.28]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc6_32.2
 // CHECK:STDOUT:   %Add.ref.loc10: %Add.type = name_ref Add, file.%Add.decl [template = constants.%Add]
-// CHECK:STDOUT:   %.loc10_18: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_30: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.sadd.loc10: init i32 = call %Add.ref.loc10(%.loc10_18, %.loc10_30) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_32.1: i32 = value_of_initializer %int.sadd.loc10 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_32.2: i32 = converted %int.sadd.loc10, %.loc10_32.1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_18.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_30.1: Core.IntLiteral = int_value 1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc10_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_18.3: <bound method> = bound_method %.loc10_18.1, %.loc10_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc10_18: init i32 = call %.loc10_18.3(%.loc10_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_18.4: i32 = value_of_initializer %int.convert_checked.loc10_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_18.5: i32 = converted %.loc10_18.1, %.loc10_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_30.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_30.3: <bound method> = bound_method %.loc10_30.1, %.loc10_30.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc10_30: init i32 = call %.loc10_30.3(%.loc10_30.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc10_30.4: i32 = value_of_initializer %int.convert_checked.loc10_30 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc10_30.5: i32 = converted %.loc10_30.1, %.loc10_30.4 [template = constants.%.33]
+// CHECK:STDOUT:   %int.sadd.loc10: init i32 = call %Add.ref.loc10(%.loc10_18.5, %.loc10_30.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_32.1: i32 = value_of_initializer %int.sadd.loc10 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_32.2: i32 = converted %int.sadd.loc10, %.loc10_32.1 [template = constants.%.34]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc10_32.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 177 - 86
toolchain/check/testdata/builtins/int/sdiv.carbon

@@ -64,17 +64,25 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Div.type: type = fn_type @Div [template]
 // CHECK:STDOUT:   %Div: %Div.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -123,32 +131,37 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Div.ref: %Div.type = name_ref Div, %Div.decl [template = constants.%Div]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sdiv: init i32 = call %Div.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.sdiv: init i32 = call %Div.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.sdiv, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.sdiv [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.sdiv, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.sdiv, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.sdiv, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.sdiv [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.sdiv, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.sdiv, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 1 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -190,9 +203,9 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -207,16 +220,25 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value -1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -2147483647 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -319,54 +341,94 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Div.ref.loc9: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
 // CHECK:STDOUT:   %Negate.ref.loc9_18: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_25.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_25.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_25.3: <bound method> = bound_method %.loc9_25.1, %.loc9_25.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc9_25: init i32 = call %.loc9_25.3(%.loc9_25.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_25.4: i32 = value_of_initializer %int.convert_checked.loc9_25 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_25.5: i32 = converted %.loc9_25.1, %.loc9_25.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25.5) [template = constants.%.28]
 // CHECK:STDOUT:   %Negate.ref.loc9_39: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc9_46: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.snegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_24.1: i32 = value_of_initializer %int.snegate.loc9_24 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_24.2: i32 = converted %int.snegate.loc9_24, %.loc9_24.1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_45.1: i32 = value_of_initializer %int.snegate.loc9_45 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_45.2: i32 = converted %int.snegate.loc9_45, %.loc9_45.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.sdiv.loc9: init i32 = call %Div.ref.loc9(%.loc9_24.2, %.loc9_45.2) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.sdiv.loc9 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.sdiv.loc9, %.loc9_49.1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_46.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc9_46.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_46.3: <bound method> = bound_method %.loc9_46.1, %.loc9_46.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc9_46: init i32 = call %.loc9_46.3(%.loc9_46.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_46.4: i32 = value_of_initializer %int.convert_checked.loc9_46 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_46.5: i32 = converted %.loc9_46.1, %.loc9_46.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_24.1: i32 = value_of_initializer %int.snegate.loc9_24 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_24.2: i32 = converted %int.snegate.loc9_24, %.loc9_24.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_45.1: i32 = value_of_initializer %int.snegate.loc9_45 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_45.2: i32 = converted %int.snegate.loc9_45, %.loc9_45.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.sdiv.loc9: init i32 = call %Div.ref.loc9(%.loc9_24.2, %.loc9_45.2) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.sdiv.loc9 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.sdiv.loc9, %.loc9_49.1 [template = constants.%.27]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc9_49.2
 // CHECK:STDOUT:   %Div.ref.loc12: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
 // CHECK:STDOUT:   %Sub.ref.loc12: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_29: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_43: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_28.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_28.2: i32 = converted %int.snegate.loc12, %.loc12_28.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_28.2, %.loc12_43) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_47: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.ssub.loc12 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.ssub.loc12, %.loc12_21.1 [template = constants.%.5]
-// CHECK:STDOUT:   %int.sdiv.loc12: init i32 = call %Div.ref.loc12(%.loc12_21.2, %.loc12_47) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.sdiv.loc12 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.sdiv.loc12, %.loc12_49.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12_29.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_29.3: <bound method> = bound_method %.loc12_29.1, %.loc12_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc12_29: init i32 = call %.loc12_29.3(%.loc12_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_29.4: i32 = value_of_initializer %int.convert_checked.loc12_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_29.5: i32 = converted %.loc12_29.1, %.loc12_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_43.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc12_28.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_28.2: i32 = converted %int.snegate.loc12, %.loc12_28.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_43.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_43.3: <bound method> = bound_method %.loc12_43.1, %.loc12_43.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_43: init i32 = call %.loc12_43.3(%.loc12_43.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_43.4: i32 = value_of_initializer %int.convert_checked.loc12_43 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_43.5: i32 = converted %.loc12_43.1, %.loc12_43.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.ssub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_28.2, %.loc12_43.5) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_47.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.ssub.loc12 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.ssub.loc12, %.loc12_21.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_47.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_47.3: <bound method> = bound_method %.loc12_47.1, %.loc12_47.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_47: init i32 = call %.loc12_47.3(%.loc12_47.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_47.4: i32 = value_of_initializer %int.convert_checked.loc12_47 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_47.5: i32 = converted %.loc12_47.1, %.loc12_47.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.sdiv.loc12: init i32 = call %Div.ref.loc12(%.loc12_21.2, %.loc12_47.5) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.sdiv.loc12 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.sdiv.loc12, %.loc12_49.1 [template = constants.%.33]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc12_49.2
 // CHECK:STDOUT:   %Div.ref.loc19: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
 // CHECK:STDOUT:   %Sub.ref.loc19: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc19_22: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc19_29: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc19_28: init i32 = call %Negate.ref.loc19_22(%.loc19_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc19_43: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc19_28.1: i32 = value_of_initializer %int.snegate.loc19_28 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc19_28.2: i32 = converted %int.snegate.loc19_28, %.loc19_28.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc19: init i32 = call %Sub.ref.loc19(%.loc19_28.2, %.loc19_43) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc19_29.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc19_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc19_29.3: <bound method> = bound_method %.loc19_29.1, %.loc19_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc19_29: init i32 = call %.loc19_29.3(%.loc19_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc19_29.4: i32 = value_of_initializer %int.convert_checked.loc19_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc19_29.5: i32 = converted %.loc19_29.1, %.loc19_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc19_28: init i32 = call %Negate.ref.loc19_22(%.loc19_29.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc19_43.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc19_28.1: i32 = value_of_initializer %int.snegate.loc19_28 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc19_28.2: i32 = converted %int.snegate.loc19_28, %.loc19_28.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc19_43.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc19_43.3: <bound method> = bound_method %.loc19_43.1, %.loc19_43.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc19_43: init i32 = call %.loc19_43.3(%.loc19_43.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc19_43.4: i32 = value_of_initializer %int.convert_checked.loc19_43 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc19_43.5: i32 = converted %.loc19_43.1, %.loc19_43.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.ssub.loc19: init i32 = call %Sub.ref.loc19(%.loc19_28.2, %.loc19_43.5) [template = constants.%.33]
 // CHECK:STDOUT:   %Negate.ref.loc19_47: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc19_54: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.snegate.loc19_53: init i32 = call %Negate.ref.loc19_47(%.loc19_54) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc19_21.1: i32 = value_of_initializer %int.ssub.loc19 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_21.2: i32 = converted %int.ssub.loc19, %.loc19_21.1 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_53.1: i32 = value_of_initializer %int.snegate.loc19_53 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc19_53.2: i32 = converted %int.snegate.loc19_53, %.loc19_53.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.sdiv.loc19: init i32 = call %Div.ref.loc19(%.loc19_21.2, %.loc19_53.2) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_57.1: i32 = value_of_initializer %int.sdiv.loc19 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_57.2: i32 = converted %int.sdiv.loc19, %.loc19_57.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc19_54.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc19_54.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc19_54.3: <bound method> = bound_method %.loc19_54.1, %.loc19_54.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc19_54: init i32 = call %.loc19_54.3(%.loc19_54.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc19_54.4: i32 = value_of_initializer %int.convert_checked.loc19_54 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc19_54.5: i32 = converted %.loc19_54.1, %.loc19_54.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc19_53: init i32 = call %Negate.ref.loc19_47(%.loc19_54.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc19_21.1: i32 = value_of_initializer %int.ssub.loc19 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc19_21.2: i32 = converted %int.ssub.loc19, %.loc19_21.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc19_53.1: i32 = value_of_initializer %int.snegate.loc19_53 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc19_53.2: i32 = converted %int.snegate.loc19_53, %.loc19_53.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.sdiv.loc19: init i32 = call %Div.ref.loc19(%.loc19_21.2, %.loc19_53.2) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc19_57.1: i32 = value_of_initializer %int.sdiv.loc19 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc19_57.2: i32 = converted %int.sdiv.loc19, %.loc19_57.1 [template = constants.%.33]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc19_57.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -378,13 +440,22 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Div.type: type = fn_type @Div [template]
 // CHECK:STDOUT:   %Div: %Div.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -435,16 +506,36 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Div.ref.loc10: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
-// CHECK:STDOUT:   %.loc10_18: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_21: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sdiv.loc10: init i32 = call %Div.ref.loc10(%.loc10_18, %.loc10_21) [template = <error>]
+// CHECK:STDOUT:   %.loc10_18.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_21.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_18.3: <bound method> = bound_method %.loc10_18.1, %.loc10_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc10_18: init i32 = call %.loc10_18.3(%.loc10_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_18.4: i32 = value_of_initializer %int.convert_checked.loc10_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_18.5: i32 = converted %.loc10_18.1, %.loc10_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_21.3: <bound method> = bound_method %.loc10_21.1, %.loc10_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc10_21: init i32 = call %.loc10_21.3(%.loc10_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc10_21.4: i32 = value_of_initializer %int.convert_checked.loc10_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc10_21.5: i32 = converted %.loc10_21.1, %.loc10_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.sdiv.loc10: init i32 = call %Div.ref.loc10(%.loc10_18.5, %.loc10_21.5) [template = <error>]
 // CHECK:STDOUT:   %.loc10_23.1: i32 = value_of_initializer %int.sdiv.loc10 [template = <error>]
 // CHECK:STDOUT:   %.loc10_23.2: i32 = converted %int.sdiv.loc10, %.loc10_23.1 [template = <error>]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc10_23.2
 // CHECK:STDOUT:   %Div.ref.loc15: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
-// CHECK:STDOUT:   %.loc15_18: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_21: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sdiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_18, %.loc15_21) [template = <error>]
+// CHECK:STDOUT:   %.loc15_18.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc15_21.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc15_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_18.3: <bound method> = bound_method %.loc15_18.1, %.loc15_18.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc15_18: init i32 = call %.loc15_18.3(%.loc15_18.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_18.4: i32 = value_of_initializer %int.convert_checked.loc15_18 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_18.5: i32 = converted %.loc15_18.1, %.loc15_18.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_21.3: <bound method> = bound_method %.loc15_21.1, %.loc15_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc15_21: init i32 = call %.loc15_21.3(%.loc15_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_21.4: i32 = value_of_initializer %int.convert_checked.loc15_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_21.5: i32 = converted %.loc15_21.1, %.loc15_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.sdiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_18.5, %.loc15_21.5) [template = <error>]
 // CHECK:STDOUT:   %.loc15_23.1: i32 = value_of_initializer %int.sdiv.loc15 [template = <error>]
 // CHECK:STDOUT:   %.loc15_23.2: i32 = converted %int.sdiv.loc15, %.loc15_23.1 [template = <error>]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc15_23.2

+ 178 - 87
toolchain/check/testdata/builtins/int/smod.carbon

@@ -67,17 +67,25 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Mod.type: type = fn_type @Mod [template]
 // CHECK:STDOUT:   %Mod: %Mod.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 2 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -126,32 +134,37 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Mod.ref: %Mod.type = name_ref Mod, %Mod.decl [template = constants.%Mod]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 3 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smod: init i32 = call %Mod.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.smod: init i32 = call %Mod.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.smod, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.smod [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.smod, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.smod, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.smod, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.smod [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.smod, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.smod, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 2 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -193,9 +206,9 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -210,17 +223,26 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value -1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -2147483647 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -323,54 +345,94 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Mod.ref.loc9: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
 // CHECK:STDOUT:   %Negate.ref.loc9_18: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_25.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_25.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_25.3: <bound method> = bound_method %.loc9_25.1, %.loc9_25.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc9_25: init i32 = call %.loc9_25.3(%.loc9_25.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_25.4: i32 = value_of_initializer %int.convert_checked.loc9_25 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_25.5: i32 = converted %.loc9_25.1, %.loc9_25.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25.5) [template = constants.%.28]
 // CHECK:STDOUT:   %Negate.ref.loc9_39: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc9_46: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.snegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_24.1: i32 = value_of_initializer %int.snegate.loc9_24 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_24.2: i32 = converted %int.snegate.loc9_24, %.loc9_24.1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_45.1: i32 = value_of_initializer %int.snegate.loc9_45 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_45.2: i32 = converted %int.snegate.loc9_45, %.loc9_45.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.smod.loc9: init i32 = call %Mod.ref.loc9(%.loc9_24.2, %.loc9_45.2) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.smod.loc9 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.smod.loc9, %.loc9_49.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_46.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc9_46.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_46.3: <bound method> = bound_method %.loc9_46.1, %.loc9_46.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc9_46: init i32 = call %.loc9_46.3(%.loc9_46.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_46.4: i32 = value_of_initializer %int.convert_checked.loc9_46 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_46.5: i32 = converted %.loc9_46.1, %.loc9_46.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_24.1: i32 = value_of_initializer %int.snegate.loc9_24 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_24.2: i32 = converted %int.snegate.loc9_24, %.loc9_24.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_45.1: i32 = value_of_initializer %int.snegate.loc9_45 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_45.2: i32 = converted %int.snegate.loc9_45, %.loc9_45.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.smod.loc9: init i32 = call %Mod.ref.loc9(%.loc9_24.2, %.loc9_45.2) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.smod.loc9 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.smod.loc9, %.loc9_49.1 [template = constants.%.33]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc9_49.2
 // CHECK:STDOUT:   %Mod.ref.loc12: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
 // CHECK:STDOUT:   %Sub.ref.loc12: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_29: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_43: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_28.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_28.2: i32 = converted %int.snegate.loc12, %.loc12_28.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_28.2, %.loc12_43) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_47: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.ssub.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.ssub.loc12, %.loc12_21.1 [template = constants.%.6]
-// CHECK:STDOUT:   %int.smod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_21.2, %.loc12_47) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.smod.loc12 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.smod.loc12, %.loc12_49.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12_29.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_29.3: <bound method> = bound_method %.loc12_29.1, %.loc12_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc12_29: init i32 = call %.loc12_29.3(%.loc12_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_29.4: i32 = value_of_initializer %int.convert_checked.loc12_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_29.5: i32 = converted %.loc12_29.1, %.loc12_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_43.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc12_28.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_28.2: i32 = converted %int.snegate.loc12, %.loc12_28.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_43.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_43.3: <bound method> = bound_method %.loc12_43.1, %.loc12_43.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_43: init i32 = call %.loc12_43.3(%.loc12_43.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_43.4: i32 = value_of_initializer %int.convert_checked.loc12_43 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_43.5: i32 = converted %.loc12_43.1, %.loc12_43.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.ssub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_28.2, %.loc12_43.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_47.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.ssub.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.ssub.loc12, %.loc12_21.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_47.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_47.3: <bound method> = bound_method %.loc12_47.1, %.loc12_47.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_47: init i32 = call %.loc12_47.3(%.loc12_47.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_47.4: i32 = value_of_initializer %int.convert_checked.loc12_47 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_47.5: i32 = converted %.loc12_47.1, %.loc12_47.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.smod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_21.2, %.loc12_47.5) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.smod.loc12 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.smod.loc12, %.loc12_49.1 [template = constants.%.33]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc12_49.2
 // CHECK:STDOUT:   %Mod.ref.loc20: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
 // CHECK:STDOUT:   %Sub.ref.loc20: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc20_22: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc20_29: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc20_28: init i32 = call %Negate.ref.loc20_22(%.loc20_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc20_43: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc20_28.1: i32 = value_of_initializer %int.snegate.loc20_28 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc20_28.2: i32 = converted %int.snegate.loc20_28, %.loc20_28.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc20: init i32 = call %Sub.ref.loc20(%.loc20_28.2, %.loc20_43) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc20_29.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc20_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc20_29.3: <bound method> = bound_method %.loc20_29.1, %.loc20_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc20_29: init i32 = call %.loc20_29.3(%.loc20_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc20_29.4: i32 = value_of_initializer %int.convert_checked.loc20_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc20_29.5: i32 = converted %.loc20_29.1, %.loc20_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc20_28: init i32 = call %Negate.ref.loc20_22(%.loc20_29.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc20_43.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc20_28.1: i32 = value_of_initializer %int.snegate.loc20_28 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc20_28.2: i32 = converted %int.snegate.loc20_28, %.loc20_28.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc20_43.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc20_43.3: <bound method> = bound_method %.loc20_43.1, %.loc20_43.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc20_43: init i32 = call %.loc20_43.3(%.loc20_43.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc20_43.4: i32 = value_of_initializer %int.convert_checked.loc20_43 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc20_43.5: i32 = converted %.loc20_43.1, %.loc20_43.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.ssub.loc20: init i32 = call %Sub.ref.loc20(%.loc20_28.2, %.loc20_43.5) [template = constants.%.34]
 // CHECK:STDOUT:   %Negate.ref.loc20_47: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc20_54: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.snegate.loc20_53: init i32 = call %Negate.ref.loc20_47(%.loc20_54) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc20_21.1: i32 = value_of_initializer %int.ssub.loc20 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc20_21.2: i32 = converted %int.ssub.loc20, %.loc20_21.1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc20_53.1: i32 = value_of_initializer %int.snegate.loc20_53 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc20_53.2: i32 = converted %int.snegate.loc20_53, %.loc20_53.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.smod.loc20: init i32 = call %Mod.ref.loc20(%.loc20_21.2, %.loc20_53.2) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc20_57.1: i32 = value_of_initializer %int.smod.loc20 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc20_57.2: i32 = converted %int.smod.loc20, %.loc20_57.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc20_54.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc20_54.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc20_54.3: <bound method> = bound_method %.loc20_54.1, %.loc20_54.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc20_54: init i32 = call %.loc20_54.3(%.loc20_54.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc20_54.4: i32 = value_of_initializer %int.convert_checked.loc20_54 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc20_54.5: i32 = converted %.loc20_54.1, %.loc20_54.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.snegate.loc20_53: init i32 = call %Negate.ref.loc20_47(%.loc20_54.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc20_21.1: i32 = value_of_initializer %int.ssub.loc20 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc20_21.2: i32 = converted %int.ssub.loc20, %.loc20_21.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc20_53.1: i32 = value_of_initializer %int.snegate.loc20_53 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc20_53.2: i32 = converted %int.snegate.loc20_53, %.loc20_53.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.smod.loc20: init i32 = call %Mod.ref.loc20(%.loc20_21.2, %.loc20_53.2) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc20_57.1: i32 = value_of_initializer %int.smod.loc20 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc20_57.2: i32 = converted %int.smod.loc20, %.loc20_57.1 [template = constants.%.33]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc20_57.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -382,13 +444,22 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Mod.type: type = fn_type @Mod [template]
 // CHECK:STDOUT:   %Mod: %Mod.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -439,16 +510,36 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Mod.ref.loc12: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
-// CHECK:STDOUT:   %.loc12_18: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc12_21: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_18, %.loc12_21) [template = <error>]
+// CHECK:STDOUT:   %.loc12_18.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_21.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_18.3: <bound method> = bound_method %.loc12_18.1, %.loc12_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc12_18: init i32 = call %.loc12_18.3(%.loc12_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_18.4: i32 = value_of_initializer %int.convert_checked.loc12_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_18.5: i32 = converted %.loc12_18.1, %.loc12_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_21.3: <bound method> = bound_method %.loc12_21.1, %.loc12_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc12_21: init i32 = call %.loc12_21.3(%.loc12_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc12_21.4: i32 = value_of_initializer %int.convert_checked.loc12_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc12_21.5: i32 = converted %.loc12_21.1, %.loc12_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.smod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_18.5, %.loc12_21.5) [template = <error>]
 // CHECK:STDOUT:   %.loc12_23.1: i32 = value_of_initializer %int.smod.loc12 [template = <error>]
 // CHECK:STDOUT:   %.loc12_23.2: i32 = converted %int.smod.loc12, %.loc12_23.1 [template = <error>]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc12_23.2
 // CHECK:STDOUT:   %Mod.ref.loc17: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
-// CHECK:STDOUT:   %.loc17_18: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc17_21: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smod.loc17: init i32 = call %Mod.ref.loc17(%.loc17_18, %.loc17_21) [template = <error>]
+// CHECK:STDOUT:   %.loc17_18.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_21.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_18.3: <bound method> = bound_method %.loc17_18.1, %.loc17_18.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc17_18: init i32 = call %.loc17_18.3(%.loc17_18.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_18.4: i32 = value_of_initializer %int.convert_checked.loc17_18 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_18.5: i32 = converted %.loc17_18.1, %.loc17_18.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_21.3: <bound method> = bound_method %.loc17_21.1, %.loc17_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc17_21: init i32 = call %.loc17_21.3(%.loc17_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_21.4: i32 = value_of_initializer %int.convert_checked.loc17_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_21.5: i32 = converted %.loc17_21.1, %.loc17_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.smod.loc17: init i32 = call %Mod.ref.loc17(%.loc17_18.5, %.loc17_21.5) [template = <error>]
 // CHECK:STDOUT:   %.loc17_23.1: i32 = value_of_initializer %int.smod.loc17 [template = <error>]
 // CHECK:STDOUT:   %.loc17_23.2: i32 = converted %int.smod.loc17, %.loc17_23.1 [template = <error>]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc17_23.2

+ 93 - 49
toolchain/check/testdata/builtins/int/smul.carbon

@@ -38,17 +38,25 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Mul.type: type = fn_type @Mul [template]
 // CHECK:STDOUT:   %Mul: %Mul.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 6 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 6 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 6 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 6 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -97,32 +105,37 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Mul.ref: %Mul.type = name_ref Mul, %Mul.decl [template = constants.%Mul]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smul: init i32 = call %Mul.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.smul: init i32 = call %Mul.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.smul, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.smul [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.smul, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.smul, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.smul, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.smul [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.smul, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.smul, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 6 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 6 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -164,9 +177,9 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -177,16 +190,27 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Mul.type: type = fn_type @Mul [template]
 // CHECK:STDOUT:   %Mul: %Mul.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 32767 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 65536 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 2147418112 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 32768 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 32767 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 65536 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 32767 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 65536 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 2147418112 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 32768 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 32768 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -237,18 +261,38 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Mul.ref.loc6: %Mul.type = name_ref Mul, file.%Mul.decl [template = constants.%Mul]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_value 32767 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_26: i32 = int_value 65536 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smul.loc6: init i32 = call %Mul.ref.loc6(%.loc6_18, %.loc6_26) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_34.1: i32 = value_of_initializer %int.smul.loc6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_34.2: i32 = converted %int.smul.loc6, %.loc6_34.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc6_18.1: Core.IntLiteral = int_value 32767 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_26.1: Core.IntLiteral = int_value 65536 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_18.3: <bound method> = bound_method %.loc6_18.1, %.loc6_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc6_18: init i32 = call %.loc6_18.3(%.loc6_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.4: i32 = value_of_initializer %int.convert_checked.loc6_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.5: i32 = converted %.loc6_18.1, %.loc6_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_26.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_26.3: <bound method> = bound_method %.loc6_26.1, %.loc6_26.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc6_26: init i32 = call %.loc6_26.3(%.loc6_26.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_26.4: i32 = value_of_initializer %int.convert_checked.loc6_26 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_26.5: i32 = converted %.loc6_26.1, %.loc6_26.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.smul.loc6: init i32 = call %Mul.ref.loc6(%.loc6_18.5, %.loc6_26.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc6_34.1: i32 = value_of_initializer %int.smul.loc6 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc6_34.2: i32 = converted %int.smul.loc6, %.loc6_34.1 [template = constants.%.31]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc6_34.2
 // CHECK:STDOUT:   %Mul.ref.loc10: %Mul.type = name_ref Mul, file.%Mul.decl [template = constants.%Mul]
-// CHECK:STDOUT:   %.loc10_18: i32 = int_value 32768 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_26: i32 = int_value 65536 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smul.loc10: init i32 = call %Mul.ref.loc10(%.loc10_18, %.loc10_26) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc10_34.1: i32 = value_of_initializer %int.smul.loc10 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc10_34.2: i32 = converted %int.smul.loc10, %.loc10_34.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_18.1: Core.IntLiteral = int_value 32768 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc10_26.1: Core.IntLiteral = int_value 65536 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_18.3: <bound method> = bound_method %.loc10_18.1, %.loc10_18.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc10_18: init i32 = call %.loc10_18.3(%.loc10_18.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_18.4: i32 = value_of_initializer %int.convert_checked.loc10_18 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_18.5: i32 = converted %.loc10_18.1, %.loc10_18.4 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_26.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_26.3: <bound method> = bound_method %.loc10_26.1, %.loc10_26.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc10_26: init i32 = call %.loc10_26.3(%.loc10_26.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc10_26.4: i32 = value_of_initializer %int.convert_checked.loc10_26 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc10_26.5: i32 = converted %.loc10_26.1, %.loc10_26.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.smul.loc10: init i32 = call %Mul.ref.loc10(%.loc10_18.5, %.loc10_26.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc10_34.1: i32 = value_of_initializer %int.smul.loc10 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc10_34.2: i32 = converted %int.smul.loc10, %.loc10_34.1 [template = constants.%.35]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc10_34.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 132 - 72
toolchain/check/testdata/builtins/int/snegate.carbon

@@ -123,18 +123,25 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 123 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -123 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 123 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 123 [template]
-// CHECK:STDOUT:   %.29: type = array_type %.28, i32 [template]
-// CHECK:STDOUT:   %.30: type = ptr_type %.29 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.32: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 123 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -123 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.27, %Convert.16 [template]
+// CHECK:STDOUT:   %.31: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.32: type = ptr_type %.31 [template]
+// CHECK:STDOUT:   %.33: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.33, %Convert.15 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value -1 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -178,34 +185,34 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Negate.ref.loc4_16: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %Negate.ref.loc4_23: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc4_30: i32 = int_value 123 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc4_29: init i32 = call %Negate.ref.loc4_23(%.loc4_30) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc4_29.1: i32 = value_of_initializer %int.snegate.loc4_29 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc4_29.2: i32 = converted %int.snegate.loc4_29, %.loc4_29.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.snegate.loc4_22: init i32 = call %Negate.ref.loc4_16(%.loc4_29.2) [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_30.1: Core.IntLiteral = int_value 123 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_30.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_30.3: <bound method> = bound_method %.loc4_30.1, %.loc4_30.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc4_30: init i32 = call %.loc4_30.3(%.loc4_30.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc4_30.4: i32 = value_of_initializer %int.convert_checked.loc4_30 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc4_30.5: i32 = converted %.loc4_30.1, %.loc4_30.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc4_29: init i32 = call %Negate.ref.loc4_23(%.loc4_30.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_29.1: i32 = value_of_initializer %int.snegate.loc4_29 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_29.2: i32 = converted %int.snegate.loc4_29, %.loc4_29.1 [template = constants.%.28]
+// CHECK:STDOUT:   %int.snegate.loc4_22: init i32 = call %Negate.ref.loc4_16(%.loc4_29.2) [template = constants.%.27]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_22.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_22.2: <bound method> = bound_method %int.snegate.loc4_22, %.loc4_22.1 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc4_22.3: i32 = value_of_initializer %int.snegate.loc4_22 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_22.4: i32 = converted %int.snegate.loc4_22, %.loc4_22.3 [template = constants.%.1]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_22.2(%.loc4_22.4) [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_22.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_22.6: Core.IntLiteral = converted %int.snegate.loc4_22, %.loc4_22.5 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_35: type = array_type %.loc4_22.6, i32 [template = constants.%.29]
-// CHECK:STDOUT:   %arr.var: ref %.29 = var arr
-// CHECK:STDOUT:   %arr: ref %.29 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_22.1: %Convert.type.5 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_22.2: <bound method> = bound_method %int.snegate.loc4_22, %.loc4_22.1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_22.3: i32 = value_of_initializer %int.snegate.loc4_22 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc4_22.4: i32 = converted %int.snegate.loc4_22, %.loc4_22.3 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_22: init Core.IntLiteral = call %.loc4_22.2(%.loc4_22.4) [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_22.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_22 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_22.6: Core.IntLiteral = converted %int.snegate.loc4_22, %.loc4_22.5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_35: type = array_type %.loc4_22.6, i32 [template = constants.%.31]
+// CHECK:STDOUT:   %arr.var: ref %.31 = var arr
+// CHECK:STDOUT:   %arr: ref %.31 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 123 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 123 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.27]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.28]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc5_21: type = array_type %.loc5_18.5, i32 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_22: type = ptr_type %.29 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc5_21: type = array_type %.loc5_18, i32 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_22: type = ptr_type %.31 [template = constants.%.32]
 // CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
 // CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
@@ -249,14 +256,19 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.29 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.30 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.30 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.31 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.32 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.32 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   %Negate.ref: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc7_21: i32 = int_value 1 [template = constants.%.31]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc7_21) [template = constants.%.32]
-// CHECK:STDOUT:   %.loc7_23.1: i32 = value_of_initializer %int.snegate [template = constants.%.32]
-// CHECK:STDOUT:   %.loc7_23.2: i32 = converted %int.snegate, %.loc7_23.1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc7_21.1: Core.IntLiteral = int_value 1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc7_21.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_21.3: <bound method> = bound_method %.loc7_21.1, %.loc7_21.2 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc7_21.3(%.loc7_21.1) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_21.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_21.5: i32 = converted %.loc7_21.1, %.loc7_21.4 [template = constants.%.35]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc7_21.5) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc7_23.1: i32 = value_of_initializer %int.snegate [template = constants.%.36]
+// CHECK:STDOUT:   %.loc7_23.2: i32 = converted %int.snegate, %.loc7_23.1 [template = constants.%.36]
 // CHECK:STDOUT:   %n: i32 = bind_name n, %.loc7_23.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -276,8 +288,16 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %BadReturnType: %BadReturnType.type = struct_value () [template]
 // CHECK:STDOUT:   %JustRight.type: type = fn_type @JustRight [template]
 // CHECK:STDOUT:   %JustRight: %JustRight.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew.type: type = fn_type @RuntimeCallTooFew [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: %RuntimeCallTooFew.type = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany.type: type = fn_type @RuntimeCallTooMany [template]
@@ -290,6 +310,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -388,25 +409,40 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %too_few: ref <error> = bind_name too_few, %too_few.var
 // CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %TooMany.ref: %TooMany.type = name_ref TooMany, %TooMany.decl [template = constants.%TooMany]
-// CHECK:STDOUT:   %.loc30_29: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_32: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29, %.loc30_32)
+// CHECK:STDOUT:   %.loc30_29.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc30_32.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc30_29.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_29.3: <bound method> = bound_method %.loc30_29.1, %.loc30_29.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc30_29: init i32 = call %.loc30_29.3(%.loc30_29.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc30_29.4: i32 = value_of_initializer %int.convert_checked.loc30_29 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc30_29.5: i32 = converted %.loc30_29.1, %.loc30_29.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc30_32.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_32.3: <bound method> = bound_method %.loc30_32.1, %.loc30_32.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc30_32: init i32 = call %.loc30_32.3(%.loc30_32.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc30_32.4: i32 = value_of_initializer %int.convert_checked.loc30_32 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc30_32.5: i32 = converted %.loc30_32.1, %.loc30_32.4 [template = constants.%.30]
+// CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29.5, %.loc30_32.5)
 // CHECK:STDOUT:   %.loc30_16.1: type = value_of_initializer %int.make_type_32.loc30 [template = i32]
 // CHECK:STDOUT:   %.loc30_16.2: type = converted %int.make_type_32.loc30, %.loc30_16.1 [template = i32]
 // CHECK:STDOUT:   %too_many.var: ref <error> = var too_many
 // CHECK:STDOUT:   %too_many: ref <error> = bind_name too_many, %too_many.var
 // CHECK:STDOUT:   %int.make_type_32.loc35: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %BadReturnType.ref: %BadReturnType.type = name_ref BadReturnType, %BadReturnType.decl [template = constants.%BadReturnType]
-// CHECK:STDOUT:   %.loc35_42: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42)
+// CHECK:STDOUT:   %.loc35_42.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc35_42.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc35_42.3: <bound method> = bound_method %.loc35_42.1, %.loc35_42.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc35: init i32 = call %.loc35_42.3(%.loc35_42.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc35_42.4: i32 = value_of_initializer %int.convert_checked.loc35 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc35_42.5: i32 = converted %.loc35_42.1, %.loc35_42.4 [template = constants.%.28]
+// CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42.5)
 // CHECK:STDOUT:   %.loc35_23.1: type = value_of_initializer %int.make_type_32.loc35 [template = i32]
 // CHECK:STDOUT:   %.loc35_23.2: type = converted %int.make_type_32.loc35, %.loc35_23.1 [template = i32]
 // CHECK:STDOUT:   %bad_return_type.var: ref <error> = var bad_return_type
 // CHECK:STDOUT:   %bad_return_type: ref <error> = bind_name bad_return_type, %bad_return_type.var
 // CHECK:STDOUT:   %int.make_type_32.loc44: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %JustRight.ref: %JustRight.type = name_ref JustRight, %JustRight.decl [template = constants.%JustRight]
-// CHECK:STDOUT:   %.loc44_31: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc44_34: i32 = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc44_31: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc44_34: Core.IntLiteral = int_value 2 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc44_16.1: type = value_of_initializer %int.make_type_32.loc44 [template = i32]
 // CHECK:STDOUT:   %.loc44_16.2: type = converted %int.make_type_32.loc44, %.loc44_16.1 [template = i32]
 // CHECK:STDOUT:   %.loc44_36: type = array_type <error>, i32 [template = <error>]
@@ -527,15 +563,24 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
 // CHECK:STDOUT:   %Sub.type: type = fn_type @Sub [template]
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -2147483647 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -607,28 +652,43 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Negate.ref.loc8_14: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %Negate.ref.loc8_21: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc8_28: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc8_27: init i32 = call %Negate.ref.loc8_21(%.loc8_28) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_27.1: i32 = value_of_initializer %int.snegate.loc8_27 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_27.2: i32 = converted %int.snegate.loc8_27, %.loc8_27.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.snegate.loc8_20: init i32 = call %Negate.ref.loc8_14(%.loc8_27.2) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.snegate.loc8_20 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.snegate.loc8_20, %.loc8_40.1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_28.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_28.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_28.3: <bound method> = bound_method %.loc8_28.1, %.loc8_28.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc8: init i32 = call %.loc8_28.3(%.loc8_28.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc8_28.4: i32 = value_of_initializer %int.convert_checked.loc8 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc8_28.5: i32 = converted %.loc8_28.1, %.loc8_28.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc8_27: init i32 = call %Negate.ref.loc8_21(%.loc8_28.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_27.1: i32 = value_of_initializer %int.snegate.loc8_27 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_27.2: i32 = converted %int.snegate.loc8_27, %.loc8_27.1 [template = constants.%.28]
+// CHECK:STDOUT:   %int.snegate.loc8_20: init i32 = call %Negate.ref.loc8_14(%.loc8_27.2) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.snegate.loc8_20 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.snegate.loc8_20, %.loc8_40.1 [template = constants.%.27]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc8_40.2
 // CHECK:STDOUT:   %Negate.ref.loc14_14: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %Sub.ref: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc14_25: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc14_32: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc14_31: init i32 = call %Negate.ref.loc14_25(%.loc14_32) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc14_45: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc14_31.1: i32 = value_of_initializer %int.snegate.loc14_31 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc14_31.2: i32 = converted %int.snegate.loc14_31, %.loc14_31.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%.loc14_31.2, %.loc14_45) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_24.1: i32 = value_of_initializer %int.ssub [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_24.2: i32 = converted %int.ssub, %.loc14_24.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc14_20: init i32 = call %Negate.ref.loc14_14(%.loc14_24.2) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_48.1: i32 = value_of_initializer %int.snegate.loc14_20 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_48.2: i32 = converted %int.snegate.loc14_20, %.loc14_48.1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc14_32.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc14_32.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_32.3: <bound method> = bound_method %.loc14_32.1, %.loc14_32.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc14_32: init i32 = call %.loc14_32.3(%.loc14_32.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc14_32.4: i32 = value_of_initializer %int.convert_checked.loc14_32 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc14_32.5: i32 = converted %.loc14_32.1, %.loc14_32.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.snegate.loc14_31: init i32 = call %Negate.ref.loc14_25(%.loc14_32.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc14_45.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc14_31.1: i32 = value_of_initializer %int.snegate.loc14_31 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc14_31.2: i32 = converted %int.snegate.loc14_31, %.loc14_31.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc14_45.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_45.3: <bound method> = bound_method %.loc14_45.1, %.loc14_45.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc14_45: init i32 = call %.loc14_45.3(%.loc14_45.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc14_45.4: i32 = value_of_initializer %int.convert_checked.loc14_45 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc14_45.5: i32 = converted %.loc14_45.1, %.loc14_45.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%.loc14_31.2, %.loc14_45.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_24.1: i32 = value_of_initializer %int.ssub [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_24.2: i32 = converted %int.ssub, %.loc14_24.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.snegate.loc14_20: init i32 = call %Negate.ref.loc14_14(%.loc14_24.2) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_48.1: i32 = value_of_initializer %int.snegate.loc14_20 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc14_48.2: i32 = converted %int.snegate.loc14_20, %.loc14_48.1 [template = constants.%.32]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc14_48.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 129 - 63
toolchain/check/testdata/builtins/int/ssub.carbon

@@ -39,17 +39,25 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Sub.type: type = fn_type @Sub [template]
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -98,32 +106,37 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Sub.ref: %Sub.type = name_ref Sub, %Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.ssub, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.ssub [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.ssub, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.ssub, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.ssub, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.ssub [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.ssub, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.ssub, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 1 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -165,9 +178,9 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -178,17 +191,30 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Sub.type: type = fn_type @Sub [template]
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value -2147483648 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value -2147483647 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.37: <bound method> = bound_method %.36, %Convert.15 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -243,35 +269,75 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Sub.ref.loc6: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_21: i32 = int_value 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc6: init i32 = call %Sub.ref.loc6(%.loc6_18, %.loc6_21) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.ssub.loc6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.ssub.loc6, %.loc6_32.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc6_18.1: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_21.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_18.3: <bound method> = bound_method %.loc6_18.1, %.loc6_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc6_18: init i32 = call %.loc6_18.3(%.loc6_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.4: i32 = value_of_initializer %int.convert_checked.loc6_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.5: i32 = converted %.loc6_18.1, %.loc6_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_21.3: <bound method> = bound_method %.loc6_21.1, %.loc6_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc6_21: init i32 = call %.loc6_21.3(%.loc6_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_21.4: i32 = value_of_initializer %int.convert_checked.loc6_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_21.5: i32 = converted %.loc6_21.1, %.loc6_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.ssub.loc6: init i32 = call %Sub.ref.loc6(%.loc6_18.5, %.loc6_21.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.ssub.loc6 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.ssub.loc6, %.loc6_32.1 [template = constants.%.31]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc6_32.2
 // CHECK:STDOUT:   %Sub.ref.loc7_14: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Sub.ref.loc7_18: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %.loc7_22: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_25: i32 = int_value 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc7_21: init i32 = call %Sub.ref.loc7_18(%.loc7_22, %.loc7_25) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc7_38: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_21.1: i32 = value_of_initializer %int.ssub.loc7_21 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc7_21.2: i32 = converted %int.ssub.loc7_21, %.loc7_21.1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.ssub.loc7_17: init i32 = call %Sub.ref.loc7_14(%.loc7_21.2, %.loc7_38) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_40.1: i32 = value_of_initializer %int.ssub.loc7_17 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_40.2: i32 = converted %int.ssub.loc7_17, %.loc7_40.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_22.1: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_25.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_22.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_22.3: <bound method> = bound_method %.loc7_22.1, %.loc7_22.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc7_22: init i32 = call %.loc7_22.3(%.loc7_22.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_22.4: i32 = value_of_initializer %int.convert_checked.loc7_22 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_22.5: i32 = converted %.loc7_22.1, %.loc7_22.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_25.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_25.3: <bound method> = bound_method %.loc7_25.1, %.loc7_25.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc7_25: init i32 = call %.loc7_25.3(%.loc7_25.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc7_25.4: i32 = value_of_initializer %int.convert_checked.loc7_25 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc7_25.5: i32 = converted %.loc7_25.1, %.loc7_25.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.ssub.loc7_21: init i32 = call %Sub.ref.loc7_18(%.loc7_22.5, %.loc7_25.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc7_38.1: Core.IntLiteral = int_value 1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc7_21.1: i32 = value_of_initializer %int.ssub.loc7_21 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc7_21.2: i32 = converted %int.ssub.loc7_21, %.loc7_21.1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc7_38.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_38.3: <bound method> = bound_method %.loc7_38.1, %.loc7_38.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc7_38: init i32 = call %.loc7_38.3(%.loc7_38.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc7_38.4: i32 = value_of_initializer %int.convert_checked.loc7_38 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc7_38.5: i32 = converted %.loc7_38.1, %.loc7_38.4 [template = constants.%.34]
+// CHECK:STDOUT:   %int.ssub.loc7_17: init i32 = call %Sub.ref.loc7_14(%.loc7_21.2, %.loc7_38.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_40.1: i32 = value_of_initializer %int.ssub.loc7_17 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_40.2: i32 = converted %int.ssub.loc7_17, %.loc7_40.1 [template = constants.%.35]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc7_40.2
 // CHECK:STDOUT:   %Sub.ref.loc11_14: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Sub.ref.loc11_18: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %.loc11_22: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_25: i32 = int_value 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc11_21: init i32 = call %Sub.ref.loc11_18(%.loc11_22, %.loc11_25) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_38: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc11_21.1: i32 = value_of_initializer %int.ssub.loc11_21 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_21.2: i32 = converted %int.ssub.loc11_21, %.loc11_21.1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.ssub.loc11_17: init i32 = call %Sub.ref.loc11_14(%.loc11_21.2, %.loc11_38) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_40.1: i32 = value_of_initializer %int.ssub.loc11_17 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_40.2: i32 = converted %int.ssub.loc11_17, %.loc11_40.1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc11_22.1: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_25.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc11_22.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_22.3: <bound method> = bound_method %.loc11_22.1, %.loc11_22.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc11_22: init i32 = call %.loc11_22.3(%.loc11_22.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc11_22.4: i32 = value_of_initializer %int.convert_checked.loc11_22 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc11_22.5: i32 = converted %.loc11_22.1, %.loc11_22.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc11_25.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_25.3: <bound method> = bound_method %.loc11_25.1, %.loc11_25.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc11_25: init i32 = call %.loc11_25.3(%.loc11_25.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_25.4: i32 = value_of_initializer %int.convert_checked.loc11_25 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_25.5: i32 = converted %.loc11_25.1, %.loc11_25.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.ssub.loc11_21: init i32 = call %Sub.ref.loc11_18(%.loc11_22.5, %.loc11_25.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_38.1: Core.IntLiteral = int_value 2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc11_21.1: i32 = value_of_initializer %int.ssub.loc11_21 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_21.2: i32 = converted %int.ssub.loc11_21, %.loc11_21.1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_38.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_38.3: <bound method> = bound_method %.loc11_38.1, %.loc11_38.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc11_38: init i32 = call %.loc11_38.3(%.loc11_38.1) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_38.4: i32 = value_of_initializer %int.convert_checked.loc11_38 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc11_38.5: i32 = converted %.loc11_38.1, %.loc11_38.4 [template = constants.%.38]
+// CHECK:STDOUT:   %int.ssub.loc11_17: init i32 = call %Sub.ref.loc11_14(%.loc11_21.2, %.loc11_38.5) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_40.1: i32 = value_of_initializer %int.ssub.loc11_17 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc11_40.2: i32 = converted %int.ssub.loc11_17, %.loc11_40.1 [template = constants.%.30]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc11_40.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 148 - 63
toolchain/check/testdata/builtins/int/uadd.carbon

@@ -93,17 +93,25 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Add.type: type = fn_type @Add [template]
 // CHECK:STDOUT:   %Add: %Add.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -152,32 +160,37 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Add.ref: %Add.type = name_ref Add, %Add.decl [template = constants.%Add]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.uadd: init i32 = call %Add.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.uadd: init i32 = call %Add.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.uadd, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.uadd [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.uadd, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.uadd, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.uadd, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.uadd [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.uadd, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.uadd, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 3 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -219,9 +232,9 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -240,9 +253,19 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %BadReturnType: %BadReturnType.type = struct_value () [template]
 // CHECK:STDOUT:   %JustRight.type: type = fn_type @JustRight [template]
 // CHECK:STDOUT:   %JustRight: %JustRight.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.28, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 3 [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew.type: type = fn_type @RuntimeCallTooFew [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: %RuntimeCallTooFew.type = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany.type: type = fn_type @RuntimeCallTooMany [template]
@@ -255,6 +278,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -374,36 +398,66 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %TooFew.ref: %TooFew.type = name_ref TooFew, %TooFew.decl [template = constants.%TooFew]
-// CHECK:STDOUT:   %.loc25_27: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(%.loc25_27)
+// CHECK:STDOUT:   %.loc25_27.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc25_27.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc25_27.3: <bound method> = bound_method %.loc25_27.1, %.loc25_27.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc25: init i32 = call %.loc25_27.3(%.loc25_27.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc25_27.4: i32 = value_of_initializer %int.convert_checked.loc25 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc25_27.5: i32 = converted %.loc25_27.1, %.loc25_27.4 [template = constants.%.27]
+// CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(%.loc25_27.5)
 // CHECK:STDOUT:   %.loc25_15.1: type = value_of_initializer %int.make_type_32.loc25 [template = i32]
 // CHECK:STDOUT:   %.loc25_15.2: type = converted %int.make_type_32.loc25, %.loc25_15.1 [template = i32]
 // CHECK:STDOUT:   %too_few.var: ref <error> = var too_few
 // CHECK:STDOUT:   %too_few: ref <error> = bind_name too_few, %too_few.var
 // CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %TooMany.ref: %TooMany.type = name_ref TooMany, %TooMany.decl [template = constants.%TooMany]
-// CHECK:STDOUT:   %.loc30_29: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_32: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc30_35: i32 = int_value 3 [template = constants.%.3]
-// CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29, %.loc30_32, %.loc30_35)
+// CHECK:STDOUT:   %.loc30_29.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc30_32.1: Core.IntLiteral = int_value 2 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc30_35.1: Core.IntLiteral = int_value 3 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc30_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_29.3: <bound method> = bound_method %.loc30_29.1, %.loc30_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc30_29: init i32 = call %.loc30_29.3(%.loc30_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc30_29.4: i32 = value_of_initializer %int.convert_checked.loc30_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc30_29.5: i32 = converted %.loc30_29.1, %.loc30_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc30_32.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_32.3: <bound method> = bound_method %.loc30_32.1, %.loc30_32.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc30_32: init i32 = call %.loc30_32.3(%.loc30_32.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc30_32.4: i32 = value_of_initializer %int.convert_checked.loc30_32 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc30_32.5: i32 = converted %.loc30_32.1, %.loc30_32.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc30_35.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_35.3: <bound method> = bound_method %.loc30_35.1, %.loc30_35.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc30_35: init i32 = call %.loc30_35.3(%.loc30_35.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc30_35.4: i32 = value_of_initializer %int.convert_checked.loc30_35 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc30_35.5: i32 = converted %.loc30_35.1, %.loc30_35.4 [template = constants.%.33]
+// CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29.5, %.loc30_32.5, %.loc30_35.5)
 // CHECK:STDOUT:   %.loc30_16.1: type = value_of_initializer %int.make_type_32.loc30 [template = i32]
 // CHECK:STDOUT:   %.loc30_16.2: type = converted %int.make_type_32.loc30, %.loc30_16.1 [template = i32]
 // CHECK:STDOUT:   %too_many.var: ref <error> = var too_many
 // CHECK:STDOUT:   %too_many: ref <error> = bind_name too_many, %too_many.var
 // CHECK:STDOUT:   %int.make_type_32.loc35: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %BadReturnType.ref: %BadReturnType.type = name_ref BadReturnType, %BadReturnType.decl [template = constants.%BadReturnType]
-// CHECK:STDOUT:   %.loc35_42: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc35_45: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42, %.loc35_45)
+// CHECK:STDOUT:   %.loc35_42.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc35_45.1: Core.IntLiteral = int_value 2 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc35_42.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc35_42.3: <bound method> = bound_method %.loc35_42.1, %.loc35_42.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc35_42: init i32 = call %.loc35_42.3(%.loc35_42.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc35_42.4: i32 = value_of_initializer %int.convert_checked.loc35_42 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc35_42.5: i32 = converted %.loc35_42.1, %.loc35_42.4 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc35_45.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc35_45.3: <bound method> = bound_method %.loc35_45.1, %.loc35_45.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc35_45: init i32 = call %.loc35_45.3(%.loc35_45.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc35_45.4: i32 = value_of_initializer %int.convert_checked.loc35_45 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc35_45.5: i32 = converted %.loc35_45.1, %.loc35_45.4 [template = constants.%.31]
+// CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42.5, %.loc35_45.5)
 // CHECK:STDOUT:   %.loc35_23.1: type = value_of_initializer %int.make_type_32.loc35 [template = i32]
 // CHECK:STDOUT:   %.loc35_23.2: type = converted %int.make_type_32.loc35, %.loc35_23.1 [template = i32]
 // CHECK:STDOUT:   %bad_return_type.var: ref <error> = var bad_return_type
 // CHECK:STDOUT:   %bad_return_type: ref <error> = bind_name bad_return_type, %bad_return_type.var
 // CHECK:STDOUT:   %int.make_type_32.loc43: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %JustRight.ref: %JustRight.type = name_ref JustRight, %JustRight.decl [template = constants.%JustRight]
-// CHECK:STDOUT:   %.loc43_31: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc43_34: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc43_37: i32 = int_value 3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc43_31: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc43_34: Core.IntLiteral = int_value 2 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc43_37: Core.IntLiteral = int_value 3 [template = constants.%.29]
 // CHECK:STDOUT:   %.loc43_16.1: type = value_of_initializer %int.make_type_32.loc43 [template = i32]
 // CHECK:STDOUT:   %.loc43_16.2: type = converted %int.make_type_32.loc43, %.loc43_16.1 [template = i32]
 // CHECK:STDOUT:   %.loc43_39: type = array_type <error>, i32 [template = <error>]
@@ -531,15 +585,26 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Add.type: type = fn_type @Add [template]
 // CHECK:STDOUT:   %Add: %Add.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.31, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -590,18 +655,38 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Add.ref.loc7: %Add.type = name_ref Add, file.%Add.decl [template = constants.%Add]
-// CHECK:STDOUT:   %.loc7_18: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_30: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.uadd.loc7: init i32 = call %Add.ref.loc7(%.loc7_18, %.loc7_30) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_32.1: i32 = value_of_initializer %int.uadd.loc7 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_32.2: i32 = converted %int.uadd.loc7, %.loc7_32.1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_18.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_30.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_18.3: <bound method> = bound_method %.loc7_18.1, %.loc7_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc7_18: init i32 = call %.loc7_18.3(%.loc7_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_18.4: i32 = value_of_initializer %int.convert_checked.loc7_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_18.5: i32 = converted %.loc7_18.1, %.loc7_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_30.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_30.3: <bound method> = bound_method %.loc7_30.1, %.loc7_30.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc7_30: init i32 = call %.loc7_30.3(%.loc7_30.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc7_30.4: i32 = value_of_initializer %int.convert_checked.loc7_30 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc7_30.5: i32 = converted %.loc7_30.1, %.loc7_30.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.uadd.loc7: init i32 = call %Add.ref.loc7(%.loc7_18.5, %.loc7_30.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_32.1: i32 = value_of_initializer %int.uadd.loc7 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_32.2: i32 = converted %int.uadd.loc7, %.loc7_32.1 [template = constants.%.28]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc7_32.2
 // CHECK:STDOUT:   %Add.ref.loc8: %Add.type = name_ref Add, file.%Add.decl [template = constants.%Add]
-// CHECK:STDOUT:   %.loc8_18: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_30: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.uadd.loc8: init i32 = call %Add.ref.loc8(%.loc8_18, %.loc8_30) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc8_32.1: i32 = value_of_initializer %int.uadd.loc8 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc8_32.2: i32 = converted %int.uadd.loc8, %.loc8_32.1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_18.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_30.1: Core.IntLiteral = int_value 1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_18.3: <bound method> = bound_method %.loc8_18.1, %.loc8_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc8_18: init i32 = call %.loc8_18.3(%.loc8_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_18.4: i32 = value_of_initializer %int.convert_checked.loc8_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_18.5: i32 = converted %.loc8_18.1, %.loc8_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_30.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_30.3: <bound method> = bound_method %.loc8_30.1, %.loc8_30.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc8_30: init i32 = call %.loc8_30.3(%.loc8_30.1) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc8_30.4: i32 = value_of_initializer %int.convert_checked.loc8_30 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc8_30.5: i32 = converted %.loc8_30.1, %.loc8_30.4 [template = constants.%.33]
+// CHECK:STDOUT:   %int.uadd.loc8: init i32 = call %Add.ref.loc8(%.loc8_18.5, %.loc8_30.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc8_32.1: i32 = value_of_initializer %int.uadd.loc8 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc8_32.2: i32 = converted %int.uadd.loc8, %.loc8_32.1 [template = constants.%.34]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc8_32.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 178 - 87
toolchain/check/testdata/builtins/int/udiv.carbon

@@ -60,17 +60,25 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Div.type: type = fn_type @Div [template]
 // CHECK:STDOUT:   %Div: %Div.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -119,32 +127,37 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Div.ref: %Div.type = name_ref Div, %Div.decl [template = constants.%Div]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.udiv: init i32 = call %Div.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.udiv: init i32 = call %Div.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.udiv, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.udiv [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.udiv, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.udiv, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.udiv, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.udiv [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.udiv, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.udiv, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 1 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -186,9 +199,9 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -203,17 +216,26 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value -1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -2147483647 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -316,54 +338,94 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Div.ref.loc9: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
 // CHECK:STDOUT:   %Negate.ref.loc9_18: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_25.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_25.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_25.3: <bound method> = bound_method %.loc9_25.1, %.loc9_25.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc9_25: init i32 = call %.loc9_25.3(%.loc9_25.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_25.4: i32 = value_of_initializer %int.convert_checked.loc9_25 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_25.5: i32 = converted %.loc9_25.1, %.loc9_25.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25.5) [template = constants.%.28]
 // CHECK:STDOUT:   %Negate.ref.loc9_39: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc9_46: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.unegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_24.1: i32 = value_of_initializer %int.unegate.loc9_24 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_24.2: i32 = converted %int.unegate.loc9_24, %.loc9_24.1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_45.1: i32 = value_of_initializer %int.unegate.loc9_45 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_45.2: i32 = converted %int.unegate.loc9_45, %.loc9_45.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.udiv.loc9: init i32 = call %Div.ref.loc9(%.loc9_24.2, %.loc9_45.2) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.udiv.loc9 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.udiv.loc9, %.loc9_49.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_46.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc9_46.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_46.3: <bound method> = bound_method %.loc9_46.1, %.loc9_46.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc9_46: init i32 = call %.loc9_46.3(%.loc9_46.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_46.4: i32 = value_of_initializer %int.convert_checked.loc9_46 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_46.5: i32 = converted %.loc9_46.1, %.loc9_46.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.unegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_24.1: i32 = value_of_initializer %int.unegate.loc9_24 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_24.2: i32 = converted %int.unegate.loc9_24, %.loc9_24.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_45.1: i32 = value_of_initializer %int.unegate.loc9_45 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_45.2: i32 = converted %int.unegate.loc9_45, %.loc9_45.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.udiv.loc9: init i32 = call %Div.ref.loc9(%.loc9_24.2, %.loc9_45.2) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.udiv.loc9 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.udiv.loc9, %.loc9_49.1 [template = constants.%.33]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc9_49.2
 // CHECK:STDOUT:   %Div.ref.loc12: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
 // CHECK:STDOUT:   %Sub.ref.loc12: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_29: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_43: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_28.1: i32 = value_of_initializer %int.unegate.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_28.2: i32 = converted %int.unegate.loc12, %.loc12_28.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_28.2, %.loc12_43) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_47: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.usub.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.usub.loc12, %.loc12_21.1 [template = constants.%.6]
-// CHECK:STDOUT:   %int.udiv.loc12: init i32 = call %Div.ref.loc12(%.loc12_21.2, %.loc12_47) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.udiv.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.udiv.loc12, %.loc12_49.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_29.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_29.3: <bound method> = bound_method %.loc12_29.1, %.loc12_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc12_29: init i32 = call %.loc12_29.3(%.loc12_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_29.4: i32 = value_of_initializer %int.convert_checked.loc12_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_29.5: i32 = converted %.loc12_29.1, %.loc12_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_43.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc12_28.1: i32 = value_of_initializer %int.unegate.loc12 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_28.2: i32 = converted %int.unegate.loc12, %.loc12_28.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_43.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_43.3: <bound method> = bound_method %.loc12_43.1, %.loc12_43.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_43: init i32 = call %.loc12_43.3(%.loc12_43.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_43.4: i32 = value_of_initializer %int.convert_checked.loc12_43 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_43.5: i32 = converted %.loc12_43.1, %.loc12_43.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.usub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_28.2, %.loc12_43.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_47.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.usub.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.usub.loc12, %.loc12_21.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_47.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_47.3: <bound method> = bound_method %.loc12_47.1, %.loc12_47.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_47: init i32 = call %.loc12_47.3(%.loc12_47.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_47.4: i32 = value_of_initializer %int.convert_checked.loc12_47 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_47.5: i32 = converted %.loc12_47.1, %.loc12_47.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.udiv.loc12: init i32 = call %Div.ref.loc12(%.loc12_21.2, %.loc12_47.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.udiv.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.udiv.loc12, %.loc12_49.1 [template = constants.%.34]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc12_49.2
 // CHECK:STDOUT:   %Div.ref.loc15: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
 // CHECK:STDOUT:   %Sub.ref.loc15: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc15_22: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc15_29: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc15_28: init i32 = call %Negate.ref.loc15_22(%.loc15_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_43: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc15_28.1: i32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_28.2: i32 = converted %int.unegate.loc15_28, %.loc15_28.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc15: init i32 = call %Sub.ref.loc15(%.loc15_28.2, %.loc15_43) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc15_29.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc15_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_29.3: <bound method> = bound_method %.loc15_29.1, %.loc15_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc15_29: init i32 = call %.loc15_29.3(%.loc15_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc15_29.4: i32 = value_of_initializer %int.convert_checked.loc15_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc15_29.5: i32 = converted %.loc15_29.1, %.loc15_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc15_28: init i32 = call %Negate.ref.loc15_22(%.loc15_29.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc15_43.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc15_28.1: i32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc15_28.2: i32 = converted %int.unegate.loc15_28, %.loc15_28.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc15_43.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_43.3: <bound method> = bound_method %.loc15_43.1, %.loc15_43.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc15_43: init i32 = call %.loc15_43.3(%.loc15_43.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc15_43.4: i32 = value_of_initializer %int.convert_checked.loc15_43 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc15_43.5: i32 = converted %.loc15_43.1, %.loc15_43.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.usub.loc15: init i32 = call %Sub.ref.loc15(%.loc15_28.2, %.loc15_43.5) [template = constants.%.34]
 // CHECK:STDOUT:   %Negate.ref.loc15_47: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc15_54: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.unegate.loc15_53: init i32 = call %Negate.ref.loc15_47(%.loc15_54) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15_21.1: i32 = value_of_initializer %int.usub.loc15 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc15_21.2: i32 = converted %int.usub.loc15, %.loc15_21.1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc15_53.1: i32 = value_of_initializer %int.unegate.loc15_53 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15_53.2: i32 = converted %int.unegate.loc15_53, %.loc15_53.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.udiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_21.2, %.loc15_53.2) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_57.1: i32 = value_of_initializer %int.udiv.loc15 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_57.2: i32 = converted %int.udiv.loc15, %.loc15_57.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15_54.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc15_54.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_54.3: <bound method> = bound_method %.loc15_54.1, %.loc15_54.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc15_54: init i32 = call %.loc15_54.3(%.loc15_54.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc15_54.4: i32 = value_of_initializer %int.convert_checked.loc15_54 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc15_54.5: i32 = converted %.loc15_54.1, %.loc15_54.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.unegate.loc15_53: init i32 = call %Negate.ref.loc15_47(%.loc15_54.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc15_21.1: i32 = value_of_initializer %int.usub.loc15 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc15_21.2: i32 = converted %int.usub.loc15, %.loc15_21.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc15_53.1: i32 = value_of_initializer %int.unegate.loc15_53 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc15_53.2: i32 = converted %int.unegate.loc15_53, %.loc15_53.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.udiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_21.2, %.loc15_53.2) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc15_57.1: i32 = value_of_initializer %int.udiv.loc15 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc15_57.2: i32 = converted %int.udiv.loc15, %.loc15_57.1 [template = constants.%.33]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc15_57.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -375,13 +437,22 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Div.type: type = fn_type @Div [template]
 // CHECK:STDOUT:   %Div: %Div.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -432,16 +503,36 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Div.ref.loc10: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
-// CHECK:STDOUT:   %.loc10_18: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_21: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.udiv.loc10: init i32 = call %Div.ref.loc10(%.loc10_18, %.loc10_21) [template = <error>]
+// CHECK:STDOUT:   %.loc10_18.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_21.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_18.3: <bound method> = bound_method %.loc10_18.1, %.loc10_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc10_18: init i32 = call %.loc10_18.3(%.loc10_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_18.4: i32 = value_of_initializer %int.convert_checked.loc10_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_18.5: i32 = converted %.loc10_18.1, %.loc10_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc10_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_21.3: <bound method> = bound_method %.loc10_21.1, %.loc10_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc10_21: init i32 = call %.loc10_21.3(%.loc10_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc10_21.4: i32 = value_of_initializer %int.convert_checked.loc10_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc10_21.5: i32 = converted %.loc10_21.1, %.loc10_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.udiv.loc10: init i32 = call %Div.ref.loc10(%.loc10_18.5, %.loc10_21.5) [template = <error>]
 // CHECK:STDOUT:   %.loc10_23.1: i32 = value_of_initializer %int.udiv.loc10 [template = <error>]
 // CHECK:STDOUT:   %.loc10_23.2: i32 = converted %int.udiv.loc10, %.loc10_23.1 [template = <error>]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc10_23.2
 // CHECK:STDOUT:   %Div.ref.loc15: %Div.type = name_ref Div, file.%Div.decl [template = constants.%Div]
-// CHECK:STDOUT:   %.loc15_18: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_21: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.udiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_18, %.loc15_21) [template = <error>]
+// CHECK:STDOUT:   %.loc15_18.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc15_21.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc15_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_18.3: <bound method> = bound_method %.loc15_18.1, %.loc15_18.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc15_18: init i32 = call %.loc15_18.3(%.loc15_18.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_18.4: i32 = value_of_initializer %int.convert_checked.loc15_18 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_18.5: i32 = converted %.loc15_18.1, %.loc15_18.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_21.3: <bound method> = bound_method %.loc15_21.1, %.loc15_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc15_21: init i32 = call %.loc15_21.3(%.loc15_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_21.4: i32 = value_of_initializer %int.convert_checked.loc15_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc15_21.5: i32 = converted %.loc15_21.1, %.loc15_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.udiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_18.5, %.loc15_21.5) [template = <error>]
 // CHECK:STDOUT:   %.loc15_23.1: i32 = value_of_initializer %int.udiv.loc15 [template = <error>]
 // CHECK:STDOUT:   %.loc15_23.2: i32 = converted %int.udiv.loc15, %.loc15_23.1 [template = <error>]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc15_23.2

+ 178 - 87
toolchain/check/testdata/builtins/int/umod.carbon

@@ -62,17 +62,25 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Mod.type: type = fn_type @Mod [template]
 // CHECK:STDOUT:   %Mod: %Mod.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 2 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -121,32 +129,37 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Mod.ref: %Mod.type = name_ref Mod, %Mod.decl [template = constants.%Mod]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 3 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umod: init i32 = call %Mod.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.umod: init i32 = call %Mod.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.umod, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.umod [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.umod, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.umod, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.umod, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.umod [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.umod, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.umod, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 2 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -188,9 +201,9 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -205,17 +218,26 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value -1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value -2147483648 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -2147483647 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -318,54 +340,94 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Mod.ref.loc9: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
 // CHECK:STDOUT:   %Negate.ref.loc9_18: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_25.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_25.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_25.3: <bound method> = bound_method %.loc9_25.1, %.loc9_25.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc9_25: init i32 = call %.loc9_25.3(%.loc9_25.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_25.4: i32 = value_of_initializer %int.convert_checked.loc9_25 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc9_25.5: i32 = converted %.loc9_25.1, %.loc9_25.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25.5) [template = constants.%.28]
 // CHECK:STDOUT:   %Negate.ref.loc9_39: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc9_46: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.unegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_24.1: i32 = value_of_initializer %int.unegate.loc9_24 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_24.2: i32 = converted %int.unegate.loc9_24, %.loc9_24.1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_45.1: i32 = value_of_initializer %int.unegate.loc9_45 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_45.2: i32 = converted %int.unegate.loc9_45, %.loc9_45.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.umod.loc9: init i32 = call %Mod.ref.loc9(%.loc9_24.2, %.loc9_45.2) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.umod.loc9 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.umod.loc9, %.loc9_49.1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_46.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc9_46.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_46.3: <bound method> = bound_method %.loc9_46.1, %.loc9_46.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc9_46: init i32 = call %.loc9_46.3(%.loc9_46.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_46.4: i32 = value_of_initializer %int.convert_checked.loc9_46 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_46.5: i32 = converted %.loc9_46.1, %.loc9_46.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.unegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_24.1: i32 = value_of_initializer %int.unegate.loc9_24 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_24.2: i32 = converted %int.unegate.loc9_24, %.loc9_24.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_45.1: i32 = value_of_initializer %int.unegate.loc9_45 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_45.2: i32 = converted %int.unegate.loc9_45, %.loc9_45.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.umod.loc9: init i32 = call %Mod.ref.loc9(%.loc9_24.2, %.loc9_45.2) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.umod.loc9 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.umod.loc9, %.loc9_49.1 [template = constants.%.28]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc9_49.2
 // CHECK:STDOUT:   %Mod.ref.loc12: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
 // CHECK:STDOUT:   %Sub.ref.loc12: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc12_29: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_43: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_28.1: i32 = value_of_initializer %int.unegate.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_28.2: i32 = converted %int.unegate.loc12, %.loc12_28.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_28.2, %.loc12_43) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_47: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.usub.loc12 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.usub.loc12, %.loc12_21.1 [template = constants.%.5]
-// CHECK:STDOUT:   %int.umod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_21.2, %.loc12_47) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.umod.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.umod.loc12, %.loc12_49.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_29.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_29.3: <bound method> = bound_method %.loc12_29.1, %.loc12_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc12_29: init i32 = call %.loc12_29.3(%.loc12_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_29.4: i32 = value_of_initializer %int.convert_checked.loc12_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc12_29.5: i32 = converted %.loc12_29.1, %.loc12_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_43.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc12_28.1: i32 = value_of_initializer %int.unegate.loc12 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_28.2: i32 = converted %int.unegate.loc12, %.loc12_28.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_43.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_43.3: <bound method> = bound_method %.loc12_43.1, %.loc12_43.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_43: init i32 = call %.loc12_43.3(%.loc12_43.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_43.4: i32 = value_of_initializer %int.convert_checked.loc12_43 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_43.5: i32 = converted %.loc12_43.1, %.loc12_43.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.usub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_28.2, %.loc12_43.5) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_47.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.usub.loc12 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.usub.loc12, %.loc12_21.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc12_47.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_47.3: <bound method> = bound_method %.loc12_47.1, %.loc12_47.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc12_47: init i32 = call %.loc12_47.3(%.loc12_47.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_47.4: i32 = value_of_initializer %int.convert_checked.loc12_47 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_47.5: i32 = converted %.loc12_47.1, %.loc12_47.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.umod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_21.2, %.loc12_47.5) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.umod.loc12 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.umod.loc12, %.loc12_49.1 [template = constants.%.34]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc12_49.2
 // CHECK:STDOUT:   %Mod.ref.loc15: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
 // CHECK:STDOUT:   %Sub.ref.loc15: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc15_22: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc15_29: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc15_28: init i32 = call %Negate.ref.loc15_22(%.loc15_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_43: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc15_28.1: i32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_28.2: i32 = converted %int.unegate.loc15_28, %.loc15_28.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc15: init i32 = call %Sub.ref.loc15(%.loc15_28.2, %.loc15_43) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15_29.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc15_29.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_29.3: <bound method> = bound_method %.loc15_29.1, %.loc15_29.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc15_29: init i32 = call %.loc15_29.3(%.loc15_29.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc15_29.4: i32 = value_of_initializer %int.convert_checked.loc15_29 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc15_29.5: i32 = converted %.loc15_29.1, %.loc15_29.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc15_28: init i32 = call %Negate.ref.loc15_22(%.loc15_29.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc15_43.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc15_28.1: i32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc15_28.2: i32 = converted %int.unegate.loc15_28, %.loc15_28.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc15_43.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_43.3: <bound method> = bound_method %.loc15_43.1, %.loc15_43.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc15_43: init i32 = call %.loc15_43.3(%.loc15_43.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc15_43.4: i32 = value_of_initializer %int.convert_checked.loc15_43 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc15_43.5: i32 = converted %.loc15_43.1, %.loc15_43.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.usub.loc15: init i32 = call %Sub.ref.loc15(%.loc15_28.2, %.loc15_43.5) [template = constants.%.33]
 // CHECK:STDOUT:   %Negate.ref.loc15_47: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc15_54: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.unegate.loc15_53: init i32 = call %Negate.ref.loc15_47(%.loc15_54) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15_21.1: i32 = value_of_initializer %int.usub.loc15 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_21.2: i32 = converted %int.usub.loc15, %.loc15_21.1 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_53.1: i32 = value_of_initializer %int.unegate.loc15_53 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15_53.2: i32 = converted %int.unegate.loc15_53, %.loc15_53.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.umod.loc15: init i32 = call %Mod.ref.loc15(%.loc15_21.2, %.loc15_53.2) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_57.1: i32 = value_of_initializer %int.umod.loc15 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_57.2: i32 = converted %int.umod.loc15, %.loc15_57.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15_54.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc15_54.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_54.3: <bound method> = bound_method %.loc15_54.1, %.loc15_54.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc15_54: init i32 = call %.loc15_54.3(%.loc15_54.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc15_54.4: i32 = value_of_initializer %int.convert_checked.loc15_54 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc15_54.5: i32 = converted %.loc15_54.1, %.loc15_54.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.unegate.loc15_53: init i32 = call %Negate.ref.loc15_47(%.loc15_54.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc15_21.1: i32 = value_of_initializer %int.usub.loc15 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc15_21.2: i32 = converted %int.usub.loc15, %.loc15_21.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc15_53.1: i32 = value_of_initializer %int.unegate.loc15_53 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc15_53.2: i32 = converted %int.unegate.loc15_53, %.loc15_53.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.umod.loc15: init i32 = call %Mod.ref.loc15(%.loc15_21.2, %.loc15_53.2) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc15_57.1: i32 = value_of_initializer %int.umod.loc15 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc15_57.2: i32 = converted %int.umod.loc15, %.loc15_57.1 [template = constants.%.33]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc15_57.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -377,13 +439,22 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Mod.type: type = fn_type @Mod [template]
 // CHECK:STDOUT:   %Mod: %Mod.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -434,16 +505,36 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Mod.ref.loc12: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
-// CHECK:STDOUT:   %.loc12_18: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc12_21: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_18, %.loc12_21) [template = <error>]
+// CHECK:STDOUT:   %.loc12_18.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_21.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_18.3: <bound method> = bound_method %.loc12_18.1, %.loc12_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc12_18: init i32 = call %.loc12_18.3(%.loc12_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_18.4: i32 = value_of_initializer %int.convert_checked.loc12_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_18.5: i32 = converted %.loc12_18.1, %.loc12_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc12_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_21.3: <bound method> = bound_method %.loc12_21.1, %.loc12_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc12_21: init i32 = call %.loc12_21.3(%.loc12_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc12_21.4: i32 = value_of_initializer %int.convert_checked.loc12_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc12_21.5: i32 = converted %.loc12_21.1, %.loc12_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.umod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_18.5, %.loc12_21.5) [template = <error>]
 // CHECK:STDOUT:   %.loc12_23.1: i32 = value_of_initializer %int.umod.loc12 [template = <error>]
 // CHECK:STDOUT:   %.loc12_23.2: i32 = converted %int.umod.loc12, %.loc12_23.1 [template = <error>]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc12_23.2
 // CHECK:STDOUT:   %Mod.ref.loc17: %Mod.type = name_ref Mod, file.%Mod.decl [template = constants.%Mod]
-// CHECK:STDOUT:   %.loc17_18: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc17_21: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umod.loc17: init i32 = call %Mod.ref.loc17(%.loc17_18, %.loc17_21) [template = <error>]
+// CHECK:STDOUT:   %.loc17_18.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_21.1: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_18.3: <bound method> = bound_method %.loc17_18.1, %.loc17_18.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc17_18: init i32 = call %.loc17_18.3(%.loc17_18.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_18.4: i32 = value_of_initializer %int.convert_checked.loc17_18 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_18.5: i32 = converted %.loc17_18.1, %.loc17_18.4 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_21.3: <bound method> = bound_method %.loc17_21.1, %.loc17_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc17_21: init i32 = call %.loc17_21.3(%.loc17_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_21.4: i32 = value_of_initializer %int.convert_checked.loc17_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_21.5: i32 = converted %.loc17_21.1, %.loc17_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.umod.loc17: init i32 = call %Mod.ref.loc17(%.loc17_18.5, %.loc17_21.5) [template = <error>]
 // CHECK:STDOUT:   %.loc17_23.1: i32 = value_of_initializer %int.umod.loc17 [template = <error>]
 // CHECK:STDOUT:   %.loc17_23.2: i32 = converted %int.umod.loc17, %.loc17_23.1 [template = <error>]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc17_23.2

+ 93 - 49
toolchain/check/testdata/builtins/int/umul.carbon

@@ -35,17 +35,25 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Mul.type: type = fn_type @Mul [template]
 // CHECK:STDOUT:   %Mul: %Mul.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 6 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 6 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 6 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 6 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -94,32 +102,37 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Mul.ref: %Mul.type = name_ref Mul, %Mul.decl [template = constants.%Mul]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umul: init i32 = call %Mul.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.umul: init i32 = call %Mul.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.umul, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.umul [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.umul, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.umul, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.umul, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.umul [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.umul, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.umul, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 6 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 6 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -161,9 +174,9 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -174,16 +187,27 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Mul.type: type = fn_type @Mul [template]
 // CHECK:STDOUT:   %Mul: %Mul.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 32767 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 65536 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 2147418112 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 32768 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 32767 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 65536 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 32767 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 65536 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 2147418112 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 32768 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 32768 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -234,18 +258,38 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Mul.ref.loc6: %Mul.type = name_ref Mul, file.%Mul.decl [template = constants.%Mul]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_value 32767 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_26: i32 = int_value 65536 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umul.loc6: init i32 = call %Mul.ref.loc6(%.loc6_18, %.loc6_26) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_34.1: i32 = value_of_initializer %int.umul.loc6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_34.2: i32 = converted %int.umul.loc6, %.loc6_34.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc6_18.1: Core.IntLiteral = int_value 32767 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_26.1: Core.IntLiteral = int_value 65536 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_18.3: <bound method> = bound_method %.loc6_18.1, %.loc6_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc6_18: init i32 = call %.loc6_18.3(%.loc6_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.4: i32 = value_of_initializer %int.convert_checked.loc6_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.5: i32 = converted %.loc6_18.1, %.loc6_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_26.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_26.3: <bound method> = bound_method %.loc6_26.1, %.loc6_26.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc6_26: init i32 = call %.loc6_26.3(%.loc6_26.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_26.4: i32 = value_of_initializer %int.convert_checked.loc6_26 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_26.5: i32 = converted %.loc6_26.1, %.loc6_26.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.umul.loc6: init i32 = call %Mul.ref.loc6(%.loc6_18.5, %.loc6_26.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc6_34.1: i32 = value_of_initializer %int.umul.loc6 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc6_34.2: i32 = converted %int.umul.loc6, %.loc6_34.1 [template = constants.%.31]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc6_34.2
 // CHECK:STDOUT:   %Mul.ref.loc7: %Mul.type = name_ref Mul, file.%Mul.decl [template = constants.%Mul]
-// CHECK:STDOUT:   %.loc7_18: i32 = int_value 32768 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_26: i32 = int_value 65536 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umul.loc7: init i32 = call %Mul.ref.loc7(%.loc7_18, %.loc7_26) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_34.1: i32 = value_of_initializer %int.umul.loc7 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_34.2: i32 = converted %int.umul.loc7, %.loc7_34.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_18.1: Core.IntLiteral = int_value 32768 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc7_26.1: Core.IntLiteral = int_value 65536 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_18.3: <bound method> = bound_method %.loc7_18.1, %.loc7_18.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc7_18: init i32 = call %.loc7_18.3(%.loc7_18.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc7_18.4: i32 = value_of_initializer %int.convert_checked.loc7_18 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc7_18.5: i32 = converted %.loc7_18.1, %.loc7_18.4 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc7_26.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_26.3: <bound method> = bound_method %.loc7_26.1, %.loc7_26.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc7_26: init i32 = call %.loc7_26.3(%.loc7_26.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc7_26.4: i32 = value_of_initializer %int.convert_checked.loc7_26 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc7_26.5: i32 = converted %.loc7_26.1, %.loc7_26.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.umul.loc7: init i32 = call %Mul.ref.loc7(%.loc7_18.5, %.loc7_26.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_34.1: i32 = value_of_initializer %int.umul.loc7 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_34.2: i32 = converted %int.umul.loc7, %.loc7_34.1 [template = constants.%.35]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc7_34.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 132 - 72
toolchain/check/testdata/builtins/int/unegate.carbon

@@ -119,18 +119,25 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Negate.type: type = fn_type @Negate [template]
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 123 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -123 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 123 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 123 [template]
-// CHECK:STDOUT:   %.29: type = array_type %.28, i32 [template]
-// CHECK:STDOUT:   %.30: type = ptr_type %.29 [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.32: i32 = int_value -1 [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 123 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -123 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.27, %Convert.16 [template]
+// CHECK:STDOUT:   %.31: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.32: type = ptr_type %.31 [template]
+// CHECK:STDOUT:   %.33: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.33, %Convert.15 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value -1 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -174,34 +181,34 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Negate.ref.loc4_16: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %Negate.ref.loc4_23: %Negate.type = name_ref Negate, %Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc4_30: i32 = int_value 123 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc4_29: init i32 = call %Negate.ref.loc4_23(%.loc4_30) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc4_29.1: i32 = value_of_initializer %int.unegate.loc4_29 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc4_29.2: i32 = converted %int.unegate.loc4_29, %.loc4_29.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.unegate.loc4_22: init i32 = call %Negate.ref.loc4_16(%.loc4_29.2) [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_30.1: Core.IntLiteral = int_value 123 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_30.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_30.3: <bound method> = bound_method %.loc4_30.1, %.loc4_30.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc4_30: init i32 = call %.loc4_30.3(%.loc4_30.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc4_30.4: i32 = value_of_initializer %int.convert_checked.loc4_30 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc4_30.5: i32 = converted %.loc4_30.1, %.loc4_30.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc4_29: init i32 = call %Negate.ref.loc4_23(%.loc4_30.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_29.1: i32 = value_of_initializer %int.unegate.loc4_29 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_29.2: i32 = converted %int.unegate.loc4_29, %.loc4_29.1 [template = constants.%.28]
+// CHECK:STDOUT:   %int.unegate.loc4_22: init i32 = call %Negate.ref.loc4_16(%.loc4_29.2) [template = constants.%.27]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_22.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_22.2: <bound method> = bound_method %int.unegate.loc4_22, %.loc4_22.1 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc4_22.3: i32 = value_of_initializer %int.unegate.loc4_22 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_22.4: i32 = converted %int.unegate.loc4_22, %.loc4_22.3 [template = constants.%.1]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_22.2(%.loc4_22.4) [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_22.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_22.6: Core.IntLiteral = converted %int.unegate.loc4_22, %.loc4_22.5 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_35: type = array_type %.loc4_22.6, i32 [template = constants.%.29]
-// CHECK:STDOUT:   %arr.var: ref %.29 = var arr
-// CHECK:STDOUT:   %arr: ref %.29 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_22.1: %Convert.type.5 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_22.2: <bound method> = bound_method %int.unegate.loc4_22, %.loc4_22.1 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_22.3: i32 = value_of_initializer %int.unegate.loc4_22 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc4_22.4: i32 = converted %int.unegate.loc4_22, %.loc4_22.3 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_22: init Core.IntLiteral = call %.loc4_22.2(%.loc4_22.4) [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_22.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_22 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_22.6: Core.IntLiteral = converted %int.unegate.loc4_22, %.loc4_22.5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_35: type = array_type %.loc4_22.6, i32 [template = constants.%.31]
+// CHECK:STDOUT:   %arr.var: ref %.31 = var arr
+// CHECK:STDOUT:   %arr: ref %.31 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 123 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 123 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.27]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.28]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc5_21: type = array_type %.loc5_18.5, i32 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_22: type = ptr_type %.29 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc5_21: type = array_type %.loc5_18, i32 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_22: type = ptr_type %.31 [template = constants.%.32]
 // CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
 // CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
@@ -245,14 +252,19 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.29 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.30 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.30 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.31 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.32 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.32 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   %Negate.ref: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc7_21: i32 = int_value 1 [template = constants.%.31]
-// CHECK:STDOUT:   %int.unegate: init i32 = call %Negate.ref(%.loc7_21) [template = constants.%.32]
-// CHECK:STDOUT:   %.loc7_23.1: i32 = value_of_initializer %int.unegate [template = constants.%.32]
-// CHECK:STDOUT:   %.loc7_23.2: i32 = converted %int.unegate, %.loc7_23.1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc7_21.1: Core.IntLiteral = int_value 1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc7_21.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_21.3: <bound method> = bound_method %.loc7_21.1, %.loc7_21.2 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc7_21.3(%.loc7_21.1) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_21.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_21.5: i32 = converted %.loc7_21.1, %.loc7_21.4 [template = constants.%.35]
+// CHECK:STDOUT:   %int.unegate: init i32 = call %Negate.ref(%.loc7_21.5) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc7_23.1: i32 = value_of_initializer %int.unegate [template = constants.%.36]
+// CHECK:STDOUT:   %.loc7_23.2: i32 = converted %int.unegate, %.loc7_23.1 [template = constants.%.36]
 // CHECK:STDOUT:   %n: i32 = bind_name n, %.loc7_23.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -272,8 +284,16 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %BadReturnType: %BadReturnType.type = struct_value () [template]
 // CHECK:STDOUT:   %JustRight.type: type = fn_type @JustRight [template]
 // CHECK:STDOUT:   %JustRight: %JustRight.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew.type: type = fn_type @RuntimeCallTooFew [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: %RuntimeCallTooFew.type = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany.type: type = fn_type @RuntimeCallTooMany [template]
@@ -286,6 +306,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.3
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -384,25 +405,40 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %too_few: ref <error> = bind_name too_few, %too_few.var
 // CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %TooMany.ref: %TooMany.type = name_ref TooMany, %TooMany.decl [template = constants.%TooMany]
-// CHECK:STDOUT:   %.loc30_29: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_32: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29, %.loc30_32)
+// CHECK:STDOUT:   %.loc30_29.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc30_32.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc30_29.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_29.3: <bound method> = bound_method %.loc30_29.1, %.loc30_29.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc30_29: init i32 = call %.loc30_29.3(%.loc30_29.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc30_29.4: i32 = value_of_initializer %int.convert_checked.loc30_29 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc30_29.5: i32 = converted %.loc30_29.1, %.loc30_29.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc30_32.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_32.3: <bound method> = bound_method %.loc30_32.1, %.loc30_32.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc30_32: init i32 = call %.loc30_32.3(%.loc30_32.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc30_32.4: i32 = value_of_initializer %int.convert_checked.loc30_32 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc30_32.5: i32 = converted %.loc30_32.1, %.loc30_32.4 [template = constants.%.30]
+// CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29.5, %.loc30_32.5)
 // CHECK:STDOUT:   %.loc30_16.1: type = value_of_initializer %int.make_type_32.loc30 [template = i32]
 // CHECK:STDOUT:   %.loc30_16.2: type = converted %int.make_type_32.loc30, %.loc30_16.1 [template = i32]
 // CHECK:STDOUT:   %too_many.var: ref <error> = var too_many
 // CHECK:STDOUT:   %too_many: ref <error> = bind_name too_many, %too_many.var
 // CHECK:STDOUT:   %int.make_type_32.loc35: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %BadReturnType.ref: %BadReturnType.type = name_ref BadReturnType, %BadReturnType.decl [template = constants.%BadReturnType]
-// CHECK:STDOUT:   %.loc35_42: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42)
+// CHECK:STDOUT:   %.loc35_42.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc35_42.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc35_42.3: <bound method> = bound_method %.loc35_42.1, %.loc35_42.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc35: init i32 = call %.loc35_42.3(%.loc35_42.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc35_42.4: i32 = value_of_initializer %int.convert_checked.loc35 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc35_42.5: i32 = converted %.loc35_42.1, %.loc35_42.4 [template = constants.%.28]
+// CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42.5)
 // CHECK:STDOUT:   %.loc35_23.1: type = value_of_initializer %int.make_type_32.loc35 [template = i32]
 // CHECK:STDOUT:   %.loc35_23.2: type = converted %int.make_type_32.loc35, %.loc35_23.1 [template = i32]
 // CHECK:STDOUT:   %bad_return_type.var: ref <error> = var bad_return_type
 // CHECK:STDOUT:   %bad_return_type: ref <error> = bind_name bad_return_type, %bad_return_type.var
 // CHECK:STDOUT:   %int.make_type_32.loc44: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %JustRight.ref: %JustRight.type = name_ref JustRight, %JustRight.decl [template = constants.%JustRight]
-// CHECK:STDOUT:   %.loc44_31: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc44_34: i32 = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc44_31: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc44_34: Core.IntLiteral = int_value 2 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc44_16.1: type = value_of_initializer %int.make_type_32.loc44 [template = i32]
 // CHECK:STDOUT:   %.loc44_16.2: type = converted %int.make_type_32.loc44, %.loc44_16.1 [template = i32]
 // CHECK:STDOUT:   %.loc44_36: type = array_type <error>, i32 [template = <error>]
@@ -523,15 +559,24 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %Negate: %Negate.type = struct_value () [template]
 // CHECK:STDOUT:   %Sub.type: type = fn_type @Sub [template]
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value -2147483647 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -603,28 +648,43 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Negate.ref.loc8_14: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %Negate.ref.loc8_21: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc8_28: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc8_27: init i32 = call %Negate.ref.loc8_21(%.loc8_28) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_27.1: i32 = value_of_initializer %int.unegate.loc8_27 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_27.2: i32 = converted %int.unegate.loc8_27, %.loc8_27.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.unegate.loc8_20: init i32 = call %Negate.ref.loc8_14(%.loc8_27.2) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.unegate.loc8_20 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.unegate.loc8_20, %.loc8_40.1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_28.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_28.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_28.3: <bound method> = bound_method %.loc8_28.1, %.loc8_28.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc8: init i32 = call %.loc8_28.3(%.loc8_28.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc8_28.4: i32 = value_of_initializer %int.convert_checked.loc8 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc8_28.5: i32 = converted %.loc8_28.1, %.loc8_28.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc8_27: init i32 = call %Negate.ref.loc8_21(%.loc8_28.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_27.1: i32 = value_of_initializer %int.unegate.loc8_27 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_27.2: i32 = converted %int.unegate.loc8_27, %.loc8_27.1 [template = constants.%.28]
+// CHECK:STDOUT:   %int.unegate.loc8_20: init i32 = call %Negate.ref.loc8_14(%.loc8_27.2) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.unegate.loc8_20 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.unegate.loc8_20, %.loc8_40.1 [template = constants.%.27]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc8_40.2
 // CHECK:STDOUT:   %Negate.ref.loc11_14: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %Sub.ref: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Negate.ref.loc11_25: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %.loc11_32: i32 = int_value 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc11_31: init i32 = call %Negate.ref.loc11_25(%.loc11_32) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_45: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_31.1: i32 = value_of_initializer %int.unegate.loc11_31 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_31.2: i32 = converted %int.unegate.loc11_31, %.loc11_31.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%.loc11_31.2, %.loc11_45) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_24.1: i32 = value_of_initializer %int.usub [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_24.2: i32 = converted %int.usub, %.loc11_24.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.unegate.loc11_20: init i32 = call %Negate.ref.loc11_14(%.loc11_24.2) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_48.1: i32 = value_of_initializer %int.unegate.loc11_20 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_48.2: i32 = converted %int.unegate.loc11_20, %.loc11_48.1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_32.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_32.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_32.3: <bound method> = bound_method %.loc11_32.1, %.loc11_32.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc11_32: init i32 = call %.loc11_32.3(%.loc11_32.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc11_32.4: i32 = value_of_initializer %int.convert_checked.loc11_32 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc11_32.5: i32 = converted %.loc11_32.1, %.loc11_32.4 [template = constants.%.27]
+// CHECK:STDOUT:   %int.unegate.loc11_31: init i32 = call %Negate.ref.loc11_25(%.loc11_32.5) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc11_45.1: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc11_31.1: i32 = value_of_initializer %int.unegate.loc11_31 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc11_31.2: i32 = converted %int.unegate.loc11_31, %.loc11_31.1 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc11_45.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_45.3: <bound method> = bound_method %.loc11_45.1, %.loc11_45.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc11_45: init i32 = call %.loc11_45.3(%.loc11_45.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_45.4: i32 = value_of_initializer %int.convert_checked.loc11_45 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_45.5: i32 = converted %.loc11_45.1, %.loc11_45.4 [template = constants.%.31]
+// CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%.loc11_31.2, %.loc11_45.5) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_24.1: i32 = value_of_initializer %int.usub [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_24.2: i32 = converted %int.usub, %.loc11_24.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.unegate.loc11_20: init i32 = call %Negate.ref.loc11_14(%.loc11_24.2) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_48.1: i32 = value_of_initializer %int.unegate.loc11_20 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc11_48.2: i32 = converted %int.unegate.loc11_20, %.loc11_48.1 [template = constants.%.32]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc11_48.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 129 - 63
toolchain/check/testdata/builtins/int/usub.carbon

@@ -36,17 +36,25 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Sub.type: type = fn_type @Sub [template]
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -95,32 +103,37 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Sub.ref: %Sub.type = name_ref Sub, %Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_23.3: <bound method> = bound_method %.loc4_23.1, %.loc4_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_23: init i32 = call %.loc4_23.3(%.loc4_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.4: i32 = value_of_initializer %int.convert_checked.loc4_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_23.5: i32 = converted %.loc4_23.1, %.loc4_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%.loc4_20.5, %.loc4_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.usub, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.usub [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.usub, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.usub, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.usub, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.usub [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.usub, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.usub, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 1 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -162,9 +175,9 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -175,17 +188,30 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Sub.type: type = fn_type @Sub [template]
 // CHECK:STDOUT:   %Sub: %Sub.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value -2147483648 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2147483647 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value -2147483647 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.37: <bound method> = bound_method %.36, %Convert.15 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -240,35 +266,75 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Sub.ref.loc6: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_21: i32 = int_value 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc6: init i32 = call %Sub.ref.loc6(%.loc6_18, %.loc6_21) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.usub.loc6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.usub.loc6, %.loc6_32.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc6_18.1: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_21.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_18.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_18.3: <bound method> = bound_method %.loc6_18.1, %.loc6_18.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc6_18: init i32 = call %.loc6_18.3(%.loc6_18.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.4: i32 = value_of_initializer %int.convert_checked.loc6_18 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_18.5: i32 = converted %.loc6_18.1, %.loc6_18.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_21.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_21.3: <bound method> = bound_method %.loc6_21.1, %.loc6_21.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc6_21: init i32 = call %.loc6_21.3(%.loc6_21.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_21.4: i32 = value_of_initializer %int.convert_checked.loc6_21 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_21.5: i32 = converted %.loc6_21.1, %.loc6_21.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.usub.loc6: init i32 = call %Sub.ref.loc6(%.loc6_18.5, %.loc6_21.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.usub.loc6 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.usub.loc6, %.loc6_32.1 [template = constants.%.31]
 // CHECK:STDOUT:   %a: i32 = bind_name a, %.loc6_32.2
 // CHECK:STDOUT:   %Sub.ref.loc7_14: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Sub.ref.loc7_18: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %.loc7_22: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_25: i32 = int_value 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc7_21: init i32 = call %Sub.ref.loc7_18(%.loc7_22, %.loc7_25) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc7_38: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_21.1: i32 = value_of_initializer %int.usub.loc7_21 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc7_21.2: i32 = converted %int.usub.loc7_21, %.loc7_21.1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.usub.loc7_17: init i32 = call %Sub.ref.loc7_14(%.loc7_21.2, %.loc7_38) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_40.1: i32 = value_of_initializer %int.usub.loc7_17 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_40.2: i32 = converted %int.usub.loc7_17, %.loc7_40.1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_22.1: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_25.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_22.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_22.3: <bound method> = bound_method %.loc7_22.1, %.loc7_22.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc7_22: init i32 = call %.loc7_22.3(%.loc7_22.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_22.4: i32 = value_of_initializer %int.convert_checked.loc7_22 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_22.5: i32 = converted %.loc7_22.1, %.loc7_22.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc7_25.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_25.3: <bound method> = bound_method %.loc7_25.1, %.loc7_25.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc7_25: init i32 = call %.loc7_25.3(%.loc7_25.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc7_25.4: i32 = value_of_initializer %int.convert_checked.loc7_25 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc7_25.5: i32 = converted %.loc7_25.1, %.loc7_25.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.usub.loc7_21: init i32 = call %Sub.ref.loc7_18(%.loc7_22.5, %.loc7_25.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc7_38.1: Core.IntLiteral = int_value 1 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc7_21.1: i32 = value_of_initializer %int.usub.loc7_21 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc7_21.2: i32 = converted %int.usub.loc7_21, %.loc7_21.1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc7_38.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_38.3: <bound method> = bound_method %.loc7_38.1, %.loc7_38.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc7_38: init i32 = call %.loc7_38.3(%.loc7_38.1) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc7_38.4: i32 = value_of_initializer %int.convert_checked.loc7_38 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc7_38.5: i32 = converted %.loc7_38.1, %.loc7_38.4 [template = constants.%.34]
+// CHECK:STDOUT:   %int.usub.loc7_17: init i32 = call %Sub.ref.loc7_14(%.loc7_21.2, %.loc7_38.5) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_40.1: i32 = value_of_initializer %int.usub.loc7_17 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc7_40.2: i32 = converted %int.usub.loc7_17, %.loc7_40.1 [template = constants.%.35]
 // CHECK:STDOUT:   %b: i32 = bind_name b, %.loc7_40.2
 // CHECK:STDOUT:   %Sub.ref.loc8_14: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
 // CHECK:STDOUT:   %Sub.ref.loc8_18: %Sub.type = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %.loc8_22: i32 = int_value 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_25: i32 = int_value 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc8_21: init i32 = call %Sub.ref.loc8_18(%.loc8_22, %.loc8_25) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_38: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc8_21.1: i32 = value_of_initializer %int.usub.loc8_21 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_21.2: i32 = converted %int.usub.loc8_21, %.loc8_21.1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.usub.loc8_17: init i32 = call %Sub.ref.loc8_14(%.loc8_21.2, %.loc8_38) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.usub.loc8_17 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.usub.loc8_17, %.loc8_40.1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_22.1: Core.IntLiteral = int_value 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_25.1: Core.IntLiteral = int_value 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_22.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_22.3: <bound method> = bound_method %.loc8_22.1, %.loc8_22.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc8_22: init i32 = call %.loc8_22.3(%.loc8_22.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_22.4: i32 = value_of_initializer %int.convert_checked.loc8_22 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_22.5: i32 = converted %.loc8_22.1, %.loc8_22.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc8_25.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_25.3: <bound method> = bound_method %.loc8_25.1, %.loc8_25.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc8_25: init i32 = call %.loc8_25.3(%.loc8_25.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_25.4: i32 = value_of_initializer %int.convert_checked.loc8_25 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_25.5: i32 = converted %.loc8_25.1, %.loc8_25.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.usub.loc8_21: init i32 = call %Sub.ref.loc8_18(%.loc8_22.5, %.loc8_25.5) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_38.1: Core.IntLiteral = int_value 2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc8_21.1: i32 = value_of_initializer %int.usub.loc8_21 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_21.2: i32 = converted %int.usub.loc8_21, %.loc8_21.1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc8_38.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_38.3: <bound method> = bound_method %.loc8_38.1, %.loc8_38.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc8_38: init i32 = call %.loc8_38.3(%.loc8_38.1) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc8_38.4: i32 = value_of_initializer %int.convert_checked.loc8_38 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc8_38.5: i32 = converted %.loc8_38.1, %.loc8_38.4 [template = constants.%.38]
+// CHECK:STDOUT:   %int.usub.loc8_17: init i32 = call %Sub.ref.loc8_14(%.loc8_21.2, %.loc8_38.5) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.usub.loc8_17 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.usub.loc8_17, %.loc8_40.1 [template = constants.%.30]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc8_40.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 46 - 33
toolchain/check/testdata/builtins/int/xor.carbon

@@ -26,17 +26,25 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Xor.type: type = fn_type @Xor [template]
 // CHECK:STDOUT:   %Xor: %Xor.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 12 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 10 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 6 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 12 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 10 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 6 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
-// CHECK:STDOUT:   %.31: type = ptr_type %.30 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 12 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 10 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 6 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 6 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %.35 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -85,32 +93,37 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Xor.ref: %Xor.type = name_ref Xor, %Xor.decl [template = constants.%Xor]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_value 12 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_24: i32 = int_value 10 [template = constants.%.2]
-// CHECK:STDOUT:   %int.xor: init i32 = call %Xor.ref(%.loc4_20, %.loc4_24) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_20.1: Core.IntLiteral = int_value 12 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc4_24.1: Core.IntLiteral = int_value 10 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_20.3: <bound method> = bound_method %.loc4_20.1, %.loc4_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc4_20: init i32 = call %.loc4_20.3(%.loc4_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.4: i32 = value_of_initializer %int.convert_checked.loc4_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_20.5: i32 = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc4_24.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc4_24.3: <bound method> = bound_method %.loc4_24.1, %.loc4_24.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc4_24: init i32 = call %.loc4_24.3(%.loc4_24.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_24.4: i32 = value_of_initializer %int.convert_checked.loc4_24 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc4_24.5: i32 = converted %.loc4_24.1, %.loc4_24.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.xor: init i32 = call %Xor.ref(%.loc4_20.5, %.loc4_24.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.xor, %.loc4_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.xor [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.xor, %.loc4_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked.loc4: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.xor, %.loc4_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc4_27: type = array_type %.loc4_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc4_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc4_19.2: <bound method> = bound_method %int.xor, %.loc4_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc4_19.3: i32 = value_of_initializer %int.xor [template = constants.%.31]
+// CHECK:STDOUT:   %.loc4_19.4: i32 = converted %int.xor, %.loc4_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc4_19: init Core.IntLiteral = call %.loc4_19.2(%.loc4_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_19.6: Core.IntLiteral = converted %int.xor, %.loc4_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc4_27: type = array_type %.loc4_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc5_18.1: i32 = int_value 6 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_18: Core.IntLiteral = int_value 6 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_18.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc5_18.3: <bound method> = bound_method %.loc5_18.1, %.loc5_18.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked.loc5: init Core.IntLiteral = call %.loc5_18.3(%.loc5_18.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_18.5: Core.IntLiteral = converted %.loc5_18.1, %.loc5_18.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18.5, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.30 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type %.35 [template = constants.%.36]
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:     %a.patt: i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: i32 = value_param_pattern %a.patt, runtime_param0
@@ -152,9 +165,9 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %arr.ref: ref %.30 = name_ref arr, file.%arr
-// CHECK:STDOUT:   %.loc5: %.31 = addr_of %arr.ref
-// CHECK:STDOUT:   %arr_p: %.31 = bind_name arr_p, %.loc5
+// CHECK:STDOUT:   %arr.ref: ref %.35 = name_ref arr, file.%arr
+// CHECK:STDOUT:   %.loc5: %.36 = addr_of %arr.ref
+// CHECK:STDOUT:   %arr_p: %.36 = bind_name arr_p, %.loc5
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 28 - 9
toolchain/check/testdata/builtins/print.carbon

@@ -26,20 +26,29 @@ fn Main() {
 // CHECK:STDOUT:   %Print.1: %Print.type.1 = struct_value () [template]
 // CHECK:STDOUT:   %Main.type: type = fn_type @Main [template]
 // CHECK:STDOUT:   %Main: %Main.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 1 [template]
 // CHECK:STDOUT:   %Print.type.2: type = fn_type @Print.2 [template]
 // CHECK:STDOUT:   %Print.2: %Print.type.2 = struct_value () [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.28: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.28, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
-// CHECK:STDOUT:     .Print = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .Print = %import_ref.51
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.2: %Print.type.2 = import_ref Core//prelude, inst+51, loaded [template = constants.%Print.2]
+// CHECK:STDOUT:   %import_ref.51: %Print.type.2 = import_ref Core//prelude, inst+51, loaded [template = constants.%Print.2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -67,12 +76,22 @@ fn Main() {
 // CHECK:STDOUT: fn @Main() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Print.ref.loc14: %Print.type.1 = name_ref Print, file.%Print.decl [template = constants.%Print.1]
-// CHECK:STDOUT:   %.loc14: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %print.int.loc14: init %empty_tuple.type = call %Print.ref.loc14(%.loc14)
+// CHECK:STDOUT:   %.loc14_9.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc14_9.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc14_9.3: <bound method> = bound_method %.loc14_9.1, %.loc14_9.2 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc14: init i32 = call %.loc14_9.3(%.loc14_9.1) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc14_9.4: i32 = value_of_initializer %int.convert_checked.loc14 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc14_9.5: i32 = converted %.loc14_9.1, %.loc14_9.4 [template = constants.%.27]
+// CHECK:STDOUT:   %print.int.loc14: init %empty_tuple.type = call %Print.ref.loc14(%.loc14_9.5)
 // CHECK:STDOUT:   %Core.ref: <namespace> = name_ref Core, imports.%Core [template = imports.%Core]
-// CHECK:STDOUT:   %Print.ref.loc16: %Print.type.2 = name_ref Print, imports.%import_ref.2 [template = constants.%Print.2]
-// CHECK:STDOUT:   %.loc16: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %print.int.loc16: init %empty_tuple.type = call %Print.ref.loc16(%.loc16)
+// CHECK:STDOUT:   %Print.ref.loc16: %Print.type.2 = name_ref Print, imports.%import_ref.51 [template = constants.%Print.2]
+// CHECK:STDOUT:   %.loc16_14.1: Core.IntLiteral = int_value 2 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc16_14.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_14.3: <bound method> = bound_method %.loc16_14.1, %.loc16_14.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc16: init i32 = call %.loc16_14.3(%.loc16_14.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc16_14.4: i32 = value_of_initializer %int.convert_checked.loc16 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc16_14.5: i32 = converted %.loc16_14.1, %.loc16_14.4 [template = constants.%.30]
+// CHECK:STDOUT:   %print.int.loc16: init %empty_tuple.type = call %Print.ref.loc16(%.loc16_14.5)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 103 - 38
toolchain/check/testdata/class/access_modifers.carbon

@@ -152,22 +152,32 @@ class A {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %.1: type = unbound_element_type %Circle, i32 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 5 [template]
 // CHECK:STDOUT:   %SomeInternalFunction.type: type = fn_type @SomeInternalFunction [template]
 // CHECK:STDOUT:   %SomeInternalFunction: %SomeInternalFunction.type = struct_value () [template]
 // CHECK:STDOUT:   %Make.type: type = fn_type @Make [template]
 // CHECK:STDOUT:   %Make: %Make.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = struct_type {.radius: i32} [template]
-// CHECK:STDOUT:   %.4: <witness> = complete_type_witness %.3 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %struct: %Circle = struct_value (%.2) [template]
+// CHECK:STDOUT:   %.29: type = struct_type {.radius: i32} [template]
+// CHECK:STDOUT:   %.30: <witness> = complete_type_witness %.29 [template]
+// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.31, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.35: type = struct_type {.radius: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %struct: %Circle = struct_value (%.28) [template]
 // CHECK:STDOUT:   %Run.type: type = fn_type @Run [template]
 // CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -192,8 +202,13 @@ class A {
 // CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc6_39.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
 // CHECK:STDOUT:   %.loc6_39.2: type = converted %int.make_type_32.loc6, %.loc6_39.1 [template = i32]
-// CHECK:STDOUT:   %.loc6_45: i32 = int_value 5 [template = constants.%.2]
-// CHECK:STDOUT:   %SOME_INTERNAL_CONSTANT: i32 = bind_name SOME_INTERNAL_CONSTANT, %.loc6_45
+// CHECK:STDOUT:   %.loc6_45: Core.IntLiteral = int_value 5 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_46.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_46.2: <bound method> = bound_method %.loc6_45, %.loc6_46.1 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc6_46.2(%.loc6_45) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_46.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.28]
+// CHECK:STDOUT:   %.loc6_46.4: i32 = converted %.loc6_45, %.loc6_46.3 [template = constants.%.28]
+// CHECK:STDOUT:   %SOME_INTERNAL_CONSTANT: i32 = bind_name SOME_INTERNAL_CONSTANT, %.loc6_46.4
 // CHECK:STDOUT:   %SomeInternalFunction.decl: %SomeInternalFunction.type = fn_decl @SomeInternalFunction [template = constants.%SomeInternalFunction] {
 // CHECK:STDOUT:     %return.patt: i32 = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: i32 = out_param_pattern %return.patt, runtime_param0
@@ -212,7 +227,7 @@ class A {
 // CHECK:STDOUT:     %return.param: ref %Circle = out_param runtime_param0
 // CHECK:STDOUT:     %return: ref %Circle = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc15: <witness> = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc15: <witness> = complete_type_witness %.29 [template = constants.%.30]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Circle
@@ -224,18 +239,27 @@ class A {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @SomeInternalFunction() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc9: i32 = int_value 0 [template = constants.%.5]
-// CHECK:STDOUT:   return %.loc9
+// CHECK:STDOUT:   %.loc9_12: Core.IntLiteral = int_value 0 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc9_13.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_13.2: <bound method> = bound_method %.loc9_12, %.loc9_13.1 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc9_13.2(%.loc9_12) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_13.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.33]
+// CHECK:STDOUT:   %.loc9_13.4: i32 = converted %.loc9_12, %.loc9_13.3 [template = constants.%.33]
+// CHECK:STDOUT:   return %.loc9_13.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: %Circle {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc13_23: i32 = int_value 5 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc13_24.1: %.3 = struct_literal (%.loc13_23)
-// CHECK:STDOUT:   %.loc13_24.2: ref i32 = class_element_access %return, element0
-// CHECK:STDOUT:   %.loc13_24.3: init i32 = initialize_from %.loc13_23 to %.loc13_24.2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc13_24.4: init %Circle = class_init (%.loc13_24.3), %return [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_25: init %Circle = converted %.loc13_24.1, %.loc13_24.4 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc13_23: Core.IntLiteral = int_value 5 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc13_24.1: %.35 = struct_literal (%.loc13_23)
+// CHECK:STDOUT:   %.loc13_24.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_24.3: <bound method> = bound_method %.loc13_23, %.loc13_24.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc13_24.3(%.loc13_23) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_24.4: init i32 = converted %.loc13_23, %int.convert_checked [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_24.5: ref i32 = class_element_access %return, element0
+// CHECK:STDOUT:   %.loc13_24.6: init i32 = initialize_from %.loc13_24.4 to %.loc13_24.5 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_24.7: init %Circle = class_init (%.loc13_24.6), %return [template = constants.%struct]
+// CHECK:STDOUT:   %.loc13_25: init %Circle = converted %.loc13_24.1, %.loc13_24.7 [template = constants.%struct]
 // CHECK:STDOUT:   return %.loc13_25 to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -257,7 +281,7 @@ class A {
 // CHECK:STDOUT:   %radius: i32 = bind_name radius, <error>
 // CHECK:STDOUT:   %circle.ref.loc34: %Circle = name_ref circle, %circle
 // CHECK:STDOUT:   %radius.ref.loc34: <error> = name_ref radius, <error> [template = <error>]
-// CHECK:STDOUT:   %.loc34: i32 = int_value 5 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc34: Core.IntLiteral = int_value 5 [template = constants.%.2]
 // CHECK:STDOUT:   assign %radius.ref.loc34, <error>
 // CHECK:STDOUT:   %circle.ref.loc42: %Circle = name_ref circle, %circle
 // CHECK:STDOUT:   %SOME_INTERNAL_CONSTANT.ref: <error> = name_ref SOME_INTERNAL_CONSTANT, <error> [template = <error>]
@@ -336,12 +360,19 @@ class A {
 // CHECK:STDOUT:   %Compute: %Compute.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {.radius: i32} [template]
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -422,8 +453,13 @@ class A {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @SomeInternalFunction() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc12: i32 = int_value 0 [template = constants.%.5]
-// CHECK:STDOUT:   return %.loc12
+// CHECK:STDOUT:   %.loc12_12: Core.IntLiteral = int_value 0 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12_13.1: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc12_13.2: <bound method> = bound_method %.loc12_12, %.loc12_13.1 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc12_13.2(%.loc12_12) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_13.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.31]
+// CHECK:STDOUT:   %.loc12_13.4: i32 = converted %.loc12_12, %.loc12_13.3 [template = constants.%.31]
+// CHECK:STDOUT:   return %.loc12_13.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Compute[%self.param_patt: %Circle]() -> i32 {
@@ -442,14 +478,21 @@ class A {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
-// CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.28: type = struct_type {} [template]
+// CHECK:STDOUT:   %.29: <witness> = complete_type_witness %.28 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -472,9 +515,14 @@ class A {
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc5_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc5_10.2: type = converted %int.make_type_32, %.loc5_10.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_16: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %x: i32 = bind_name x, %.loc5_16
-// CHECK:STDOUT:   %.loc6: <witness> = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_16: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc5_17.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc5_17.2: <bound method> = bound_method %.loc5_16, %.loc5_17.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc5_17.2(%.loc5_16) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_17.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_17.4: i32 = converted %.loc5_16, %.loc5_17.3 [template = constants.%.27]
+// CHECK:STDOUT:   %x: i32 = bind_name x, %.loc5_17.4
+// CHECK:STDOUT:   %.loc6: <witness> = complete_type_witness %.28 [template = constants.%.29]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
@@ -495,14 +543,21 @@ class A {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
-// CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.28: type = struct_type {} [template]
+// CHECK:STDOUT:   %.29: <witness> = complete_type_witness %.28 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -529,14 +584,24 @@ class A {
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc5_20.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_20.2: type = converted %int.make_type_32.loc5, %.loc5_20.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_26: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %x: i32 = bind_name x, %.loc5_26
+// CHECK:STDOUT:   %.loc5_26: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc5_27.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc5_27.2: <bound method> = bound_method %.loc5_26, %.loc5_27.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc5: init i32 = call %.loc5_27.2(%.loc5_26) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_27.3: i32 = value_of_initializer %int.convert_checked.loc5 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_27.4: i32 = converted %.loc5_26, %.loc5_27.3 [template = constants.%.27]
+// CHECK:STDOUT:   %x: i32 = bind_name x, %.loc5_27.4
 // CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc6_18.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
 // CHECK:STDOUT:   %.loc6_18.2: type = converted %int.make_type_32.loc6, %.loc6_18.1 [template = i32]
-// CHECK:STDOUT:   %.loc6_24: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %y: i32 = bind_name y, %.loc6_24
-// CHECK:STDOUT:   %.loc7: <witness> = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc6_24: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_25.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_25.2: <bound method> = bound_method %.loc6_24, %.loc6_25.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc6: init i32 = call %.loc6_25.2(%.loc6_24) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc6_25.3: i32 = value_of_initializer %int.convert_checked.loc6 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc6_25.4: i32 = converted %.loc6_24, %.loc6_25.3 [template = constants.%.27]
+// CHECK:STDOUT:   %y: i32 = bind_name y, %.loc6_25.4
+// CHECK:STDOUT:   %.loc7: <witness> = complete_type_witness %.28 [template = constants.%.29]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A

+ 36 - 18
toolchain/check/testdata/class/base.carbon

@@ -42,11 +42,20 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   %.8: <witness> = complete_type_witness %.7 [template]
 // CHECK:STDOUT:   %Make.type: type = fn_type @Make [template]
 // CHECK:STDOUT:   %Make: %Make.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: i32 = int_value 4 [template]
-// CHECK:STDOUT:   %.13: i32 = int_value 7 [template]
-// CHECK:STDOUT:   %.14: type = struct_type {.base: %.2, .d: i32} [template]
-// CHECK:STDOUT:   %struct.1: %Base = struct_value (%.12) [template]
-// CHECK:STDOUT:   %struct.2: %Derived = struct_value (%struct.1, %.13) [template]
+// CHECK:STDOUT:   %.12: Core.IntLiteral = int_value 4 [template]
+// CHECK:STDOUT:   %.13: type = struct_type {.b: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.14: Core.IntLiteral = int_value 7 [template]
+// CHECK:STDOUT:   %.15: type = struct_type {.base: %.13, .d: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.39: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.40: <bound method> = bound_method %.12, %Convert.15 [template]
+// CHECK:STDOUT:   %.41: i32 = int_value 4 [template]
+// CHECK:STDOUT:   %struct.1: %Base = struct_value (%.41) [template]
+// CHECK:STDOUT:   %.42: <bound method> = bound_method %.14, %Convert.15 [template]
+// CHECK:STDOUT:   %.43: i32 = int_value 7 [template]
+// CHECK:STDOUT:   %struct.2: %Derived = struct_value (%struct.1, %.43) [template]
 // CHECK:STDOUT:   %tuple.type.1: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (i32, i32) [template]
 // CHECK:STDOUT:   %Access.type: type = fn_type @Access [template]
@@ -55,7 +64,8 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -132,19 +142,27 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: %Derived {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc22_25: i32 = int_value 4 [template = constants.%.12]
-// CHECK:STDOUT:   %.loc22_26.1: %.2 = struct_literal (%.loc22_25)
-// CHECK:STDOUT:   %.loc22_34: i32 = int_value 7 [template = constants.%.13]
-// CHECK:STDOUT:   %.loc22_35.1: %.14 = struct_literal (%.loc22_26.1, %.loc22_34)
+// CHECK:STDOUT:   %.loc22_25: Core.IntLiteral = int_value 4 [template = constants.%.12]
+// CHECK:STDOUT:   %.loc22_26.1: %.13 = struct_literal (%.loc22_25)
+// CHECK:STDOUT:   %.loc22_34: Core.IntLiteral = int_value 7 [template = constants.%.14]
+// CHECK:STDOUT:   %.loc22_35.1: %.15 = struct_literal (%.loc22_26.1, %.loc22_34)
+// CHECK:STDOUT:   %.loc22_26.2: %Convert.type.2 = interface_witness_access constants.%.39, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc22_26.3: <bound method> = bound_method %.loc22_25, %.loc22_26.2 [template = constants.%.40]
+// CHECK:STDOUT:   %int.convert_checked.loc22_26: init i32 = call %.loc22_26.3(%.loc22_25) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc22_26.4: init i32 = converted %.loc22_25, %int.convert_checked.loc22_26 [template = constants.%.41]
 // CHECK:STDOUT:   %.loc22_35.2: ref %Base = class_element_access %return, element0
-// CHECK:STDOUT:   %.loc22_26.2: ref i32 = class_element_access %.loc22_35.2, element0
-// CHECK:STDOUT:   %.loc22_26.3: init i32 = initialize_from %.loc22_25 to %.loc22_26.2 [template = constants.%.12]
-// CHECK:STDOUT:   %.loc22_26.4: init %Base = class_init (%.loc22_26.3), %.loc22_35.2 [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc22_35.3: init %Base = converted %.loc22_26.1, %.loc22_26.4 [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc22_35.4: ref i32 = class_element_access %return, element1
-// CHECK:STDOUT:   %.loc22_35.5: init i32 = initialize_from %.loc22_34 to %.loc22_35.4 [template = constants.%.13]
-// CHECK:STDOUT:   %.loc22_35.6: init %Derived = class_init (%.loc22_35.3, %.loc22_35.5), %return [template = constants.%struct.2]
-// CHECK:STDOUT:   %.loc22_36: init %Derived = converted %.loc22_35.1, %.loc22_35.6 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc22_26.5: ref i32 = class_element_access %.loc22_35.2, element0
+// CHECK:STDOUT:   %.loc22_26.6: init i32 = initialize_from %.loc22_26.4 to %.loc22_26.5 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc22_26.7: init %Base = class_init (%.loc22_26.6), %.loc22_35.2 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc22_35.3: init %Base = converted %.loc22_26.1, %.loc22_26.7 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc22_35.4: %Convert.type.2 = interface_witness_access constants.%.39, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc22_35.5: <bound method> = bound_method %.loc22_34, %.loc22_35.4 [template = constants.%.42]
+// CHECK:STDOUT:   %int.convert_checked.loc22_35: init i32 = call %.loc22_35.5(%.loc22_34) [template = constants.%.43]
+// CHECK:STDOUT:   %.loc22_35.6: init i32 = converted %.loc22_34, %int.convert_checked.loc22_35 [template = constants.%.43]
+// CHECK:STDOUT:   %.loc22_35.7: ref i32 = class_element_access %return, element1
+// CHECK:STDOUT:   %.loc22_35.8: init i32 = initialize_from %.loc22_35.6 to %.loc22_35.7 [template = constants.%.43]
+// CHECK:STDOUT:   %.loc22_35.9: init %Derived = class_init (%.loc22_35.3, %.loc22_35.8), %return [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc22_36: init %Derived = converted %.loc22_35.1, %.loc22_35.9 [template = constants.%struct.2]
 // CHECK:STDOUT:   return %.loc22_36 to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 29 - 18
toolchain/check/testdata/class/base_method.carbon

@@ -39,19 +39,26 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
 // CHECK:STDOUT:   %.4: <witness> = complete_type_witness %.3 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.30: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 1 [template]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT:   %.7: type = unbound_element_type %Derived, %Base [template]
-// CHECK:STDOUT:   %.8: type = struct_type {.base: %Base} [template]
-// CHECK:STDOUT:   %.9: <witness> = complete_type_witness %.8 [template]
-// CHECK:STDOUT:   %.10: type = ptr_type %Derived [template]
+// CHECK:STDOUT:   %.33: type = unbound_element_type %Derived, %Base [template]
+// CHECK:STDOUT:   %.34: type = struct_type {.base: %Base} [template]
+// CHECK:STDOUT:   %.35: <witness> = complete_type_witness %.34 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %Derived [template]
 // CHECK:STDOUT:   %Call.type: type = fn_type @Call [template]
 // CHECK:STDOUT:   %Call: %Call.type = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -78,13 +85,13 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {} {}
 // CHECK:STDOUT:   %Call.decl: %Call.type = fn_decl @Call [template = constants.%Call] {
-// CHECK:STDOUT:     %p.patt: %.10 = binding_pattern p
-// CHECK:STDOUT:     %p.param_patt: %.10 = value_param_pattern %p.patt, runtime_param0
+// CHECK:STDOUT:     %p.patt: %.36 = binding_pattern p
+// CHECK:STDOUT:     %p.param_patt: %.36 = value_param_pattern %p.patt, runtime_param0
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %Derived.ref: type = name_ref Derived, file.%Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT:     %.loc25: type = ptr_type %Derived [template = constants.%.10]
-// CHECK:STDOUT:     %p.param: %.10 = value_param runtime_param0
-// CHECK:STDOUT:     %p: %.10 = bind_name p, %p.param
+// CHECK:STDOUT:     %.loc25: type = ptr_type %Derived [template = constants.%.36]
+// CHECK:STDOUT:     %p.param: %.36 = value_param runtime_param0
+// CHECK:STDOUT:     %p: %.36 = bind_name p, %p.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -113,8 +120,8 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT:   %.loc22: %.7 = base_decl %Base, element0 [template]
-// CHECK:STDOUT:   %.loc23: <witness> = complete_type_witness %.8 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc22: %.33 = base_decl %Base, element0 [template]
+// CHECK:STDOUT:   %.loc23: <witness> = complete_type_witness %.34 [template = constants.%.35]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Derived
@@ -128,18 +135,22 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   %.loc18_4: ref %Base = deref %self.ref
 // CHECK:STDOUT:   %a.ref: %.1 = name_ref a, @Base.%.loc12_8 [template = @Base.%.loc12_8]
 // CHECK:STDOUT:   %.loc18_10: ref i32 = class_element_access %.loc18_4, element0
-// CHECK:STDOUT:   %.loc18_15: i32 = int_value 1 [template = constants.%.6]
-// CHECK:STDOUT:   assign %.loc18_10, %.loc18_15
+// CHECK:STDOUT:   %.loc18_15: Core.IntLiteral = int_value 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc18_13.1: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc18_13.2: <bound method> = bound_method %.loc18_15, %.loc18_13.1 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc18_13.2(%.loc18_15) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc18_13.3: init i32 = converted %.loc18_15, %int.convert_checked [template = constants.%.32]
+// CHECK:STDOUT:   assign %.loc18_10, %.loc18_13.3
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Call(%p.param_patt: %.10) {
+// CHECK:STDOUT: fn @Call(%p.param_patt: %.36) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %p.ref: %.10 = name_ref p, %p
+// CHECK:STDOUT:   %p.ref: %.36 = name_ref p, %p
 // CHECK:STDOUT:   %.loc26_4.1: ref %Derived = deref %p.ref
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, @Base.%F.decl [template = constants.%F]
 // CHECK:STDOUT:   %.loc26_7: <bound method> = bound_method %.loc26_4.1, %F.ref
-// CHECK:STDOUT:   %.loc26_4.2: %.10 = addr_of %.loc26_4.1
+// CHECK:STDOUT:   %.loc26_4.2: %.36 = addr_of %.loc26_4.1
 // CHECK:STDOUT:   %.loc26_4.3: ref %Derived = deref %.loc26_4.2
 // CHECK:STDOUT:   %.loc26_4.4: ref %Base = class_element_access %.loc26_4.3, element0
 // CHECK:STDOUT:   %.loc26_4.5: %.2 = addr_of %.loc26_4.4

+ 16 - 4
toolchain/check/testdata/class/basic.carbon

@@ -41,12 +41,19 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %Run.type: type = fn_type @Run [template]
 // CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 4 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 4 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 4 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -153,8 +160,13 @@ fn Run() -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, @Class.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %.loc26_18: i32 = int_value 4 [template = constants.%.5]
-// CHECK:STDOUT:   %F.call: init i32 = call %F.ref(%.loc26_18)
+// CHECK:STDOUT:   %.loc26_18.1: Core.IntLiteral = int_value 4 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc26_18.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc26_18.3: <bound method> = bound_method %.loc26_18.1, %.loc26_18.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc26_18.3(%.loc26_18.1) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc26_18.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.31]
+// CHECK:STDOUT:   %.loc26_18.5: i32 = converted %.loc26_18.1, %.loc26_18.4 [template = constants.%.31]
+// CHECK:STDOUT:   %F.call: init i32 = call %F.ref(%.loc26_18.5)
 // CHECK:STDOUT:   %.loc26_20.1: i32 = value_of_initializer %F.call
 // CHECK:STDOUT:   %.loc26_20.2: i32 = converted %F.call, %.loc26_20.1
 // CHECK:STDOUT:   return %.loc26_20.2

+ 52 - 28
toolchain/check/testdata/class/derived_to_base.carbon

@@ -72,19 +72,31 @@ fn ConvertInit() {
 // CHECK:STDOUT:   %ConvertRef: %ConvertRef.type = struct_value () [template]
 // CHECK:STDOUT:   %ConvertInit.type: type = fn_type @ConvertInit [template]
 // CHECK:STDOUT:   %ConvertInit: %ConvertInit.type = struct_value () [template]
-// CHECK:STDOUT:   %.22: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.23: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.24: type = struct_type {.base: %.2, .b: i32} [template]
-// CHECK:STDOUT:   %.25: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.26: type = struct_type {.base: %.24, .c: i32} [template]
-// CHECK:STDOUT:   %struct.1: %A = struct_value (%.22) [template]
-// CHECK:STDOUT:   %struct.2: %B = struct_value (%struct.1, %.23) [template]
-// CHECK:STDOUT:   %struct.3: %C = struct_value (%struct.2, %.25) [template]
+// CHECK:STDOUT:   %.22: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.23: type = struct_type {.a: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.24: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.25: type = struct_type {.base: %.23, .b: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.26: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.27: type = struct_type {.base: %.25, .c: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.51: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.52: <bound method> = bound_method %.22, %Convert.15 [template]
+// CHECK:STDOUT:   %.53: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %struct.1: %A = struct_value (%.53) [template]
+// CHECK:STDOUT:   %.54: <bound method> = bound_method %.24, %Convert.15 [template]
+// CHECK:STDOUT:   %.55: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %struct.2: %B = struct_value (%struct.1, %.55) [template]
+// CHECK:STDOUT:   %.56: <bound method> = bound_method %.26, %Convert.15 [template]
+// CHECK:STDOUT:   %.57: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %struct.3: %C = struct_value (%struct.2, %.57) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -280,29 +292,41 @@ fn ConvertInit() {
 // CHECK:STDOUT: fn @ConvertInit() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT:   %.loc38_38: i32 = int_value 1 [template = constants.%.22]
-// CHECK:STDOUT:   %.loc38_39.1: %.2 = struct_literal (%.loc38_38)
-// CHECK:STDOUT:   %.loc38_47: i32 = int_value 2 [template = constants.%.23]
-// CHECK:STDOUT:   %.loc38_48.1: %.24 = struct_literal (%.loc38_39.1, %.loc38_47)
-// CHECK:STDOUT:   %.loc38_56: i32 = int_value 3 [template = constants.%.25]
-// CHECK:STDOUT:   %.loc38_57.1: %.26 = struct_literal (%.loc38_48.1, %.loc38_56)
+// CHECK:STDOUT:   %.loc38_38: Core.IntLiteral = int_value 1 [template = constants.%.22]
+// CHECK:STDOUT:   %.loc38_39.1: %.23 = struct_literal (%.loc38_38)
+// CHECK:STDOUT:   %.loc38_47: Core.IntLiteral = int_value 2 [template = constants.%.24]
+// CHECK:STDOUT:   %.loc38_48.1: %.25 = struct_literal (%.loc38_39.1, %.loc38_47)
+// CHECK:STDOUT:   %.loc38_56: Core.IntLiteral = int_value 3 [template = constants.%.26]
+// CHECK:STDOUT:   %.loc38_57.1: %.27 = struct_literal (%.loc38_48.1, %.loc38_56)
 // CHECK:STDOUT:   %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
+// CHECK:STDOUT:   %.loc38_39.2: %Convert.type.2 = interface_witness_access constants.%.51, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc38_39.3: <bound method> = bound_method %.loc38_38, %.loc38_39.2 [template = constants.%.52]
+// CHECK:STDOUT:   %int.convert_checked.loc38_39: init i32 = call %.loc38_39.3(%.loc38_38) [template = constants.%.53]
+// CHECK:STDOUT:   %.loc38_39.4: init i32 = converted %.loc38_38, %int.convert_checked.loc38_39 [template = constants.%.53]
 // CHECK:STDOUT:   %.loc38_57.2: ref %C = temporary_storage
 // CHECK:STDOUT:   %.loc38_57.3: ref %B = class_element_access %.loc38_57.2, element0
 // CHECK:STDOUT:   %.loc38_48.2: ref %A = class_element_access %.loc38_57.3, element0
-// CHECK:STDOUT:   %.loc38_39.2: ref i32 = class_element_access %.loc38_48.2, element0
-// CHECK:STDOUT:   %.loc38_39.3: init i32 = initialize_from %.loc38_38 to %.loc38_39.2 [template = constants.%.22]
-// CHECK:STDOUT:   %.loc38_39.4: init %A = class_init (%.loc38_39.3), %.loc38_48.2 [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc38_48.3: init %A = converted %.loc38_39.1, %.loc38_39.4 [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc38_48.4: ref i32 = class_element_access %.loc38_57.3, element1
-// CHECK:STDOUT:   %.loc38_48.5: init i32 = initialize_from %.loc38_47 to %.loc38_48.4 [template = constants.%.23]
-// CHECK:STDOUT:   %.loc38_48.6: init %B = class_init (%.loc38_48.3, %.loc38_48.5), %.loc38_57.3 [template = constants.%struct.2]
-// CHECK:STDOUT:   %.loc38_57.4: init %B = converted %.loc38_48.1, %.loc38_48.6 [template = constants.%struct.2]
-// CHECK:STDOUT:   %.loc38_57.5: ref i32 = class_element_access %.loc38_57.2, element1
-// CHECK:STDOUT:   %.loc38_57.6: init i32 = initialize_from %.loc38_56 to %.loc38_57.5 [template = constants.%.25]
-// CHECK:STDOUT:   %.loc38_57.7: init %C = class_init (%.loc38_57.4, %.loc38_57.6), %.loc38_57.2 [template = constants.%struct.3]
-// CHECK:STDOUT:   %.loc38_57.8: ref %C = temporary %.loc38_57.2, %.loc38_57.7
-// CHECK:STDOUT:   %.loc38_59: ref %C = converted %.loc38_57.1, %.loc38_57.8
+// CHECK:STDOUT:   %.loc38_39.5: ref i32 = class_element_access %.loc38_48.2, element0
+// CHECK:STDOUT:   %.loc38_39.6: init i32 = initialize_from %.loc38_39.4 to %.loc38_39.5 [template = constants.%.53]
+// CHECK:STDOUT:   %.loc38_39.7: init %A = class_init (%.loc38_39.6), %.loc38_48.2 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc38_48.3: init %A = converted %.loc38_39.1, %.loc38_39.7 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc38_48.4: %Convert.type.2 = interface_witness_access constants.%.51, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc38_48.5: <bound method> = bound_method %.loc38_47, %.loc38_48.4 [template = constants.%.54]
+// CHECK:STDOUT:   %int.convert_checked.loc38_48: init i32 = call %.loc38_48.5(%.loc38_47) [template = constants.%.55]
+// CHECK:STDOUT:   %.loc38_48.6: init i32 = converted %.loc38_47, %int.convert_checked.loc38_48 [template = constants.%.55]
+// CHECK:STDOUT:   %.loc38_48.7: ref i32 = class_element_access %.loc38_57.3, element1
+// CHECK:STDOUT:   %.loc38_48.8: init i32 = initialize_from %.loc38_48.6 to %.loc38_48.7 [template = constants.%.55]
+// CHECK:STDOUT:   %.loc38_48.9: init %B = class_init (%.loc38_48.3, %.loc38_48.8), %.loc38_57.3 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc38_57.4: init %B = converted %.loc38_48.1, %.loc38_48.9 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc38_57.5: %Convert.type.2 = interface_witness_access constants.%.51, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc38_57.6: <bound method> = bound_method %.loc38_56, %.loc38_57.5 [template = constants.%.56]
+// CHECK:STDOUT:   %int.convert_checked.loc38_57: init i32 = call %.loc38_57.6(%.loc38_56) [template = constants.%.57]
+// CHECK:STDOUT:   %.loc38_57.7: init i32 = converted %.loc38_56, %int.convert_checked.loc38_57 [template = constants.%.57]
+// CHECK:STDOUT:   %.loc38_57.8: ref i32 = class_element_access %.loc38_57.2, element1
+// CHECK:STDOUT:   %.loc38_57.9: init i32 = initialize_from %.loc38_57.7 to %.loc38_57.8 [template = constants.%.57]
+// CHECK:STDOUT:   %.loc38_57.10: init %C = class_init (%.loc38_57.4, %.loc38_57.9), %.loc38_57.2 [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc38_57.11: ref %C = temporary %.loc38_57.2, %.loc38_57.10
+// CHECK:STDOUT:   %.loc38_59: ref %C = converted %.loc38_57.1, %.loc38_57.11
 // CHECK:STDOUT:   %.loc38_63.1: ref %B = class_element_access %.loc38_59, element0
 // CHECK:STDOUT:   %.loc38_63.2: ref %A = class_element_access %.loc38_63.1, element0
 // CHECK:STDOUT:   %.loc38_63.3: ref %A = converted %.loc38_59, %.loc38_63.2

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

@@ -447,10 +447,10 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:   %.7: <witness> = complete_type_witness %.6 [template]
 // CHECK:STDOUT:   %Make.type: type = fn_type @Make [template]
 // CHECK:STDOUT:   %Make: %Make.type = struct_value () [template]
-// CHECK:STDOUT:   %.11: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.12: type = struct_type {.a: i32} [template]
-// CHECK:STDOUT:   %.13: i32 = int_value 7 [template]
-// CHECK:STDOUT:   %.14: type = struct_type {.base: %.12, .d: i32} [template]
+// CHECK:STDOUT:   %.11: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.12: type = struct_type {.a: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.13: Core.IntLiteral = int_value 7 [template]
+// CHECK:STDOUT:   %.14: type = struct_type {.base: %.12, .d: Core.IntLiteral} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -506,9 +506,9 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: %Derived {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc22_25: i32 = int_value 1 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc22_25: Core.IntLiteral = int_value 1 [template = constants.%.11]
 // CHECK:STDOUT:   %.loc22_26: %.12 = struct_literal (%.loc22_25)
-// CHECK:STDOUT:   %.loc22_34: i32 = int_value 7 [template = constants.%.13]
+// CHECK:STDOUT:   %.loc22_34: Core.IntLiteral = int_value 7 [template = constants.%.13]
 // CHECK:STDOUT:   %.loc22_35: %.14 = struct_literal (%.loc22_26, %.loc22_34)
 // CHECK:STDOUT:   return <error> to %return
 // CHECK:STDOUT: }

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

@@ -13,10 +13,10 @@
 library "[[@TEST_NAME]]";
 
 class Bad {
-  // CHECK:STDERR: fail_not_type.carbon:[[@LINE+7]]:3: error: cannot implicitly convert from `i32` to `type` [ImplicitAsConversionFailure]
+  // CHECK:STDERR: fail_not_type.carbon:[[@LINE+7]]:3: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
   // CHECK:STDERR:   adapt 100;
   // CHECK:STDERR:   ^~~~~~~~~~
-  // CHECK:STDERR: fail_not_type.carbon:[[@LINE+4]]:3: note: type `i32` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR: fail_not_type.carbon:[[@LINE+4]]:3: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   adapt 100;
   // CHECK:STDERR:   ^~~~~~~~~~
   // CHECK:STDERR:
@@ -34,10 +34,10 @@ fn Use(b: Bad) { b.F(); }
 library "[[@TEST_NAME]]";
 
 class Bad {
-  // CHECK:STDERR: fail_extend_not_type.carbon:[[@LINE+7]]:3: error: cannot implicitly convert from `i32` to `type` [ImplicitAsConversionFailure]
+  // CHECK:STDERR: fail_extend_not_type.carbon:[[@LINE+7]]:3: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
   // CHECK:STDERR:   extend adapt 100;
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_extend_not_type.carbon:[[@LINE+4]]:3: note: type `i32` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR: fail_extend_not_type.carbon:[[@LINE+4]]:3: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   extend adapt 100;
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
@@ -106,7 +106,7 @@ class C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Bad: type = class_type @Bad [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 100 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 100 [template]
 // CHECK:STDOUT:   %Use.type: type = fn_type @Use [template]
 // CHECK:STDOUT:   %Use: %Use.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -138,7 +138,7 @@ class C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Bad {
-// CHECK:STDOUT:   %.loc12_9: i32 = int_value 100 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_9: Core.IntLiteral = int_value 100 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc12_12: type = converted %.loc12_9, <error> [template = <error>]
 // CHECK:STDOUT:   adapt_decl <error>
 // CHECK:STDOUT:   %.loc13: <witness> = complete_type_witness <error> [template = <error>]
@@ -158,7 +158,7 @@ class C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Bad: type = class_type @Bad [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 100 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 100 [template]
 // CHECK:STDOUT:   %Use.type: type = fn_type @Use [template]
 // CHECK:STDOUT:   %Use: %Use.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -190,7 +190,7 @@ class C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Bad {
-// CHECK:STDOUT:   %.loc12_16: i32 = int_value 100 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_16: Core.IntLiteral = int_value 100 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc12_19: type = converted %.loc12_16, <error> [template = <error>]
 // CHECK:STDOUT:   adapt_decl <error>
 // CHECK:STDOUT:   %.loc13: <witness> = complete_type_witness <error> [template = <error>]

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

@@ -26,10 +26,10 @@ fn AccessMemberWithInvalidBaseError(p: DeriveFromError*) -> i32 { return (*p).n;
 // --- fail_derive_from_non_type.carbon
 
 class DeriveFromNonType {
-  // CHECK:STDERR: fail_derive_from_non_type.carbon:[[@LINE+9]]:16: error: cannot implicitly convert from `i32` to `type` [ImplicitAsConversionFailure]
+  // CHECK:STDERR: fail_derive_from_non_type.carbon:[[@LINE+9]]:16: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
   // CHECK:STDERR:   extend base: 32;
   // CHECK:STDERR:                ^~
-  // CHECK:STDERR: fail_derive_from_non_type.carbon:[[@LINE+6]]:16: note: type `i32` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR: fail_derive_from_non_type.carbon:[[@LINE+6]]:16: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   extend base: 32;
   // CHECK:STDERR:                ^~
   // CHECK:STDERR:
@@ -246,7 +246,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %DeriveFromNonType: type = class_type @DeriveFromNonType [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 32 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %.27: type = ptr_type %DeriveFromNonType [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
@@ -290,7 +290,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromNonType {
-// CHECK:STDOUT:   %.loc12_16.1: i32 = int_value 32 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc12_16.1: Core.IntLiteral = int_value 32 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc12_16.2: type = converted %.loc12_16.1, <error> [template = <error>]
 // CHECK:STDOUT:   %.loc12_18: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:   %.loc13: <witness> = complete_type_witness <error> [template = <error>]

+ 3 - 3
toolchain/check/testdata/class/fail_convert_to_invalid.carbon

@@ -25,8 +25,8 @@ fn Make() -> C {
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %Make.type: type = fn_type @Make [template]
 // CHECK:STDOUT:   %Make: %Make.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 123 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 123 [template]
+// CHECK:STDOUT:   %.2: type = struct_type {.a: Core.IntLiteral} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -66,7 +66,7 @@ fn Make() -> C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: %C {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc19_16: i32 = int_value 123 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc19_16: Core.IntLiteral = int_value 123 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc19_19: %.2 = struct_literal (%.loc19_16)
 // CHECK:STDOUT:   return <error> to %return
 // CHECK:STDOUT: }

+ 29 - 10
toolchain/check/testdata/class/fail_field_modifiers.carbon

@@ -41,15 +41,24 @@ class Class {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %.1: type = unbound_element_type %Class, i32 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.4: type = struct_type {.j: i32, .k: i32} [template]
-// CHECK:STDOUT:   %.5: <witness> = complete_type_witness %.4 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: type = struct_type {.j: i32, .k: i32} [template]
+// CHECK:STDOUT:   %.33: <witness> = complete_type_witness %.32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -76,14 +85,24 @@ class Class {
 // CHECK:STDOUT:   %int.make_type_32.loc29: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc29_18.1: type = value_of_initializer %int.make_type_32.loc29 [template = i32]
 // CHECK:STDOUT:   %.loc29_18.2: type = converted %int.make_type_32.loc29, %.loc29_18.1 [template = i32]
-// CHECK:STDOUT:   %.loc29_24: i32 = int_value 0 [template = constants.%.2]
-// CHECK:STDOUT:   %l: i32 = bind_name l, %.loc29_24
+// CHECK:STDOUT:   %.loc29_24: Core.IntLiteral = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc29_25.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc29_25.2: <bound method> = bound_method %.loc29_24, %.loc29_25.1 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc29: init i32 = call %.loc29_25.2(%.loc29_24) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc29_25.3: i32 = value_of_initializer %int.convert_checked.loc29 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc29_25.4: i32 = converted %.loc29_24, %.loc29_25.3 [template = constants.%.28]
+// CHECK:STDOUT:   %l: i32 = bind_name l, %.loc29_25.4
 // CHECK:STDOUT:   %int.make_type_32.loc34: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc34_16.1: type = value_of_initializer %int.make_type_32.loc34 [template = i32]
 // CHECK:STDOUT:   %.loc34_16.2: type = converted %int.make_type_32.loc34, %.loc34_16.1 [template = i32]
-// CHECK:STDOUT:   %.loc34_22: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   %m: i32 = bind_name m, %.loc34_22
-// CHECK:STDOUT:   %.loc35: <witness> = complete_type_witness %.4 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc34_22: Core.IntLiteral = int_value 1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc34_23.1: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc34_23.2: <bound method> = bound_method %.loc34_22, %.loc34_23.1 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc34: init i32 = call %.loc34_23.2(%.loc34_22) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc34_23.3: i32 = value_of_initializer %int.convert_checked.loc34 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc34_23.4: i32 = converted %.loc34_22, %.loc34_23.3 [template = constants.%.31]
+// CHECK:STDOUT:   %m: i32 = bind_name m, %.loc34_23.4
+// CHECK:STDOUT:   %.loc35: <witness> = complete_type_witness %.32 [template = constants.%.33]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class

+ 30 - 19
toolchain/check/testdata/class/fail_init.carbon

@@ -41,17 +41,24 @@ fn F() {
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: type = struct_type {.a: i32} [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.8: type = struct_type {.a: i32, .c: i32} [template]
-// CHECK:STDOUT:   %.9: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.10: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: type = struct_type {.a: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.7: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.a: Core.IntLiteral, .c: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.35: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.36: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral, .c: Core.IntLiteral} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -87,25 +94,29 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc21_9: i32 = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc21_9: Core.IntLiteral = int_value 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc21_10.1: %.5 = struct_literal (%.loc21_9)
 // CHECK:STDOUT:   %Class.ref.loc21: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:   %.loc21_10.2: ref %Class = temporary_storage
 // CHECK:STDOUT:   %.loc21_10.3: ref %Class = temporary %.loc21_10.2, <error>
 // CHECK:STDOUT:   %.loc21_12: ref %Class = converted %.loc21_10.1, %.loc21_10.3
-// CHECK:STDOUT:   %.loc26_9: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc26_17: i32 = int_value 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc26_9: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc26_17: Core.IntLiteral = int_value 2 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc26_18.1: %.8 = struct_literal (%.loc26_9, %.loc26_17)
 // CHECK:STDOUT:   %Class.ref.loc26: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:   %.loc26_18.2: ref %Class = temporary_storage
-// CHECK:STDOUT:   %.loc26_18.3: ref i32 = class_element_access %.loc26_18.2, element0
-// CHECK:STDOUT:   %.loc26_18.4: init i32 = initialize_from %.loc26_9 to %.loc26_18.3 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc26_18.5: ref %Class = temporary %.loc26_18.2, <error>
-// CHECK:STDOUT:   %.loc26_20: ref %Class = converted %.loc26_18.1, %.loc26_18.5
-// CHECK:STDOUT:   %.loc30_9: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc30_17: i32 = int_value 2 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc30_25: i32 = int_value 3 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc30_26.1: %.10 = struct_literal (%.loc30_9, %.loc30_17, %.loc30_25)
+// CHECK:STDOUT:   %.loc26_18.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc26_18.3: <bound method> = bound_method %.loc26_9, %.loc26_18.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc26_18.3(%.loc26_9) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc26_18.4: init i32 = converted %.loc26_9, %int.convert_checked [template = constants.%.34]
+// CHECK:STDOUT:   %.loc26_18.5: ref %Class = temporary_storage
+// CHECK:STDOUT:   %.loc26_18.6: ref i32 = class_element_access %.loc26_18.5, element0
+// CHECK:STDOUT:   %.loc26_18.7: init i32 = initialize_from %.loc26_18.4 to %.loc26_18.6 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc26_18.8: ref %Class = temporary %.loc26_18.5, <error>
+// CHECK:STDOUT:   %.loc26_20: ref %Class = converted %.loc26_18.1, %.loc26_18.8
+// CHECK:STDOUT:   %.loc30_9: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc30_17: Core.IntLiteral = int_value 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc30_25: Core.IntLiteral = int_value 3 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc30_26.1: %.36 = struct_literal (%.loc30_9, %.loc30_17, %.loc30_25)
 // CHECK:STDOUT:   %Class.ref.loc30: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:   %.loc30_26.2: ref %Class = temporary_storage
 // CHECK:STDOUT:   %.loc30_26.3: ref %Class = temporary %.loc30_26.2, <error>

+ 33 - 15
toolchain/check/testdata/class/fail_init_as_inplace.carbon

@@ -41,14 +41,24 @@ fn F() {
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %struct: %Class = struct_value (%.6, %.7) [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.7: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.7, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %struct: %Class = struct_value (%.34, %.36) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -99,18 +109,26 @@ fn F() {
 // CHECK:STDOUT:   %Class.ref.loc25_10: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:   %c.var: ref %Class = var c
 // CHECK:STDOUT:   %c: ref %Class = bind_name c, %c.var
-// CHECK:STDOUT:   %.loc25_24: i32 = int_value 1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc25_32: i32 = int_value 2 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc25_33.1: %.2 = struct_literal (%.loc25_24, %.loc25_32)
+// CHECK:STDOUT:   %.loc25_24: Core.IntLiteral = int_value 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc25_32: Core.IntLiteral = int_value 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc25_33.1: %.8 = struct_literal (%.loc25_24, %.loc25_32)
 // CHECK:STDOUT:   %Class.ref.loc25_38: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:   %.loc25_33.2: ref %Class = temporary_storage
-// CHECK:STDOUT:   %.loc25_33.3: ref i32 = class_element_access %.loc25_33.2, element0
-// CHECK:STDOUT:   %.loc25_33.4: init i32 = initialize_from %.loc25_24 to %.loc25_33.3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc25_33.5: ref i32 = class_element_access %.loc25_33.2, element1
-// CHECK:STDOUT:   %.loc25_33.6: init i32 = initialize_from %.loc25_32 to %.loc25_33.5 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc25_33.7: init %Class = class_init (%.loc25_33.4, %.loc25_33.6), %.loc25_33.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc25_33.8: ref %Class = temporary %.loc25_33.2, %.loc25_33.7
-// CHECK:STDOUT:   %.loc25_35.1: ref %Class = converted %.loc25_33.1, %.loc25_33.8
+// CHECK:STDOUT:   %.loc25_33.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc25_33.3: <bound method> = bound_method %.loc25_24, %.loc25_33.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc25_33.1: init i32 = call %.loc25_33.3(%.loc25_24) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc25_33.4: init i32 = converted %.loc25_24, %int.convert_checked.loc25_33.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc25_33.5: ref %Class = temporary_storage
+// CHECK:STDOUT:   %.loc25_33.6: ref i32 = class_element_access %.loc25_33.5, element0
+// CHECK:STDOUT:   %.loc25_33.7: init i32 = initialize_from %.loc25_33.4 to %.loc25_33.6 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc25_33.8: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc25_33.9: <bound method> = bound_method %.loc25_32, %.loc25_33.8 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc25_33.2: init i32 = call %.loc25_33.9(%.loc25_32) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc25_33.10: init i32 = converted %.loc25_32, %int.convert_checked.loc25_33.2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc25_33.11: ref i32 = class_element_access %.loc25_33.5, element1
+// CHECK:STDOUT:   %.loc25_33.12: init i32 = initialize_from %.loc25_33.10 to %.loc25_33.11 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc25_33.13: init %Class = class_init (%.loc25_33.7, %.loc25_33.12), %.loc25_33.5 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc25_33.14: ref %Class = temporary %.loc25_33.5, %.loc25_33.13
+// CHECK:STDOUT:   %.loc25_35.1: ref %Class = converted %.loc25_33.1, %.loc25_33.14
 // CHECK:STDOUT:   %.loc25_35.2: %Class = bind_value %.loc25_35.1
 // CHECK:STDOUT:   assign %c.var, <error>
 // CHECK:STDOUT:   %G.ref: %G.type = name_ref G, file.%G.decl [template = constants.%G]

+ 16 - 4
toolchain/check/testdata/class/fail_scope.carbon

@@ -31,14 +31,21 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
+// CHECK:STDOUT:   %.29: i32 = int_value 1 [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -84,8 +91,13 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc13: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   return %.loc13
+// CHECK:STDOUT:   %.loc13_12: Core.IntLiteral = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc13_13.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_13.2: <bound method> = bound_method %.loc13_12, %.loc13_13.1 [template = constants.%.28]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc13_13.2(%.loc13_12) [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_13.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_13.4: i32 = converted %.loc13_12, %.loc13_13.3 [template = constants.%.29]
+// CHECK:STDOUT:   return %.loc13_13.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {

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

@@ -24,7 +24,7 @@ var v: C(0);
 // CHECK:STDOUT:   %C.2: type = class_type @C, @C(%x) [symbolic]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -50,7 +50,7 @@ var v: C(0);
 // CHECK:STDOUT:     %x.loc14_22.1: <error> = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc14_22.2 (constants.%x)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.ref: %C.type = name_ref C, %C.decl [template = constants.%C.1]
-// CHECK:STDOUT:   %.loc15: i32 = int_value 0 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15: Core.IntLiteral = int_value 0 [template = constants.%.3]
 // CHECK:STDOUT:   %v.var: ref <error> = var v
 // CHECK:STDOUT:   %v: ref <error> = bind_name v, %v.var
 // CHECK:STDOUT: }

+ 24 - 7
toolchain/check/testdata/class/field_access.carbon

@@ -32,13 +32,22 @@ fn Run() {
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %Run.type: type = fn_type @Run [template]
 // CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -80,13 +89,21 @@ fn Run() {
 // CHECK:STDOUT:   %c.ref.loc18: ref %Class = name_ref c, %c
 // CHECK:STDOUT:   %j.ref.loc18: %.1 = name_ref j, @Class.%.loc12_8 [template = @Class.%.loc12_8]
 // CHECK:STDOUT:   %.loc18_4: ref i32 = class_element_access %c.ref.loc18, element0
-// CHECK:STDOUT:   %.loc18_9: i32 = int_value 1 [template = constants.%.5]
-// CHECK:STDOUT:   assign %.loc18_4, %.loc18_9
+// CHECK:STDOUT:   %.loc18_9: Core.IntLiteral = int_value 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc18_7.1: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc18_7.2: <bound method> = bound_method %.loc18_9, %.loc18_7.1 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc18: init i32 = call %.loc18_7.2(%.loc18_9) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc18_7.3: init i32 = converted %.loc18_9, %int.convert_checked.loc18 [template = constants.%.31]
+// CHECK:STDOUT:   assign %.loc18_4, %.loc18_7.3
 // CHECK:STDOUT:   %c.ref.loc19: ref %Class = name_ref c, %c
 // CHECK:STDOUT:   %k.ref.loc19: %.1 = name_ref k, @Class.%.loc13_8 [template = @Class.%.loc13_8]
 // CHECK:STDOUT:   %.loc19_4: ref i32 = class_element_access %c.ref.loc19, element1
-// CHECK:STDOUT:   %.loc19_9: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   assign %.loc19_4, %.loc19_9
+// CHECK:STDOUT:   %.loc19_9: Core.IntLiteral = int_value 2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc19_7.1: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc19_7.2: <bound method> = bound_method %.loc19_9, %.loc19_7.1 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc19: init i32 = call %.loc19_7.2(%.loc19_9) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc19_7.3: init i32 = converted %.loc19_9, %int.convert_checked.loc19 [template = constants.%.34]
+// CHECK:STDOUT:   assign %.loc19_4, %.loc19_7.3
 // CHECK:STDOUT:   %int.make_type_32.loc20: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc20_11.1: type = value_of_initializer %int.make_type_32.loc20 [template = i32]
 // CHECK:STDOUT:   %.loc20_11.2: type = converted %int.make_type_32.loc20, %.loc20_11.1 [template = i32]

+ 24 - 7
toolchain/check/testdata/class/field_access_in_value.carbon

@@ -33,13 +33,22 @@ fn Test() {
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %Test.type: type = fn_type @Test [template]
 // CHECK:STDOUT:   %Test: %Test.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -81,13 +90,21 @@ fn Test() {
 // CHECK:STDOUT:   %cv.ref.loc18: ref %Class = name_ref cv, %cv
 // CHECK:STDOUT:   %j.ref.loc18: %.1 = name_ref j, @Class.%.loc12_8 [template = @Class.%.loc12_8]
 // CHECK:STDOUT:   %.loc18_5: ref i32 = class_element_access %cv.ref.loc18, element0
-// CHECK:STDOUT:   %.loc18_10: i32 = int_value 1 [template = constants.%.5]
-// CHECK:STDOUT:   assign %.loc18_5, %.loc18_10
+// CHECK:STDOUT:   %.loc18_10: Core.IntLiteral = int_value 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc18_8.1: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc18_8.2: <bound method> = bound_method %.loc18_10, %.loc18_8.1 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc18: init i32 = call %.loc18_8.2(%.loc18_10) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc18_8.3: init i32 = converted %.loc18_10, %int.convert_checked.loc18 [template = constants.%.31]
+// CHECK:STDOUT:   assign %.loc18_5, %.loc18_8.3
 // CHECK:STDOUT:   %cv.ref.loc19: ref %Class = name_ref cv, %cv
 // CHECK:STDOUT:   %k.ref.loc19: %.1 = name_ref k, @Class.%.loc13_8 [template = @Class.%.loc13_8]
 // CHECK:STDOUT:   %.loc19_5: ref i32 = class_element_access %cv.ref.loc19, element1
-// CHECK:STDOUT:   %.loc19_10: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   assign %.loc19_5, %.loc19_10
+// CHECK:STDOUT:   %.loc19_10: Core.IntLiteral = int_value 2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc19_8.1: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc19_8.2: <bound method> = bound_method %.loc19_10, %.loc19_8.1 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc19: init i32 = call %.loc19_8.2(%.loc19_10) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc19_8.3: init i32 = converted %.loc19_10, %int.convert_checked.loc19 [template = constants.%.34]
+// CHECK:STDOUT:   assign %.loc19_5, %.loc19_8.3
 // CHECK:STDOUT:   %Class.ref.loc20: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:   %cv.ref.loc20: ref %Class = name_ref cv, %cv
 // CHECK:STDOUT:   %.loc20: %Class = bind_value %cv.ref.loc20

+ 54 - 35
toolchain/check/testdata/class/generic/call.carbon

@@ -55,10 +55,10 @@ library "[[@TEST_NAME]]";
 
 class Class(T:! type, N:! i32) {}
 
-// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+9]]:8: error: cannot implicitly convert from `i32` to `type` [ImplicitAsConversionFailure]
+// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+9]]:8: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure]
 // CHECK:STDERR: var a: Class(5, i32*);
 // CHECK:STDERR:        ^~~~~~
-// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+6]]:8: note: type `i32` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+6]]:8: note: type `Core.IntLiteral` does not implement interface `ImplicitAs(type)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: var a: Class(5, i32*);
 // CHECK:STDERR:        ^~~~~~
 // CHECK:STDERR: fail_no_conversion.carbon:[[@LINE-8]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
@@ -93,23 +93,32 @@ class Outer(T:! type) {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N, 1 [symbolic]
-// CHECK:STDOUT:   %N.patt: i32 = symbolic_binding_pattern N, 1 [symbolic]
+// CHECK:STDOUT:   %N.1: i32 = bind_symbolic_name N, 1 [symbolic]
+// CHECK:STDOUT:   %N.patt.1: i32 = symbolic_binding_pattern N, 1 [symbolic]
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T, %N) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T, %N.1) [symbolic]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
 // CHECK:STDOUT:   %.3: type = ptr_type i32 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %Class.3: type = class_type @Class, @Class(%.3, %.4) [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %Class.4: type = class_type @Class, @Class(%empty_tuple.type, %.6) [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %Class.3: type = class_type @Class, @Class(%.3, %.30) [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.32, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Class.4: type = class_type @Class, @Class(%empty_tuple.type, %.34) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -126,8 +135,8 @@ class Outer(T:! type) {
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.patt.loc4_13.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_13.2 (constants.%T.patt)]
 // CHECK:STDOUT:     %T.param_patt: type = value_param_pattern %T.patt.loc4_13.1, runtime_param<invalid> [symbolic = %T.patt.loc4_13.2 (constants.%T.patt)]
-// CHECK:STDOUT:     %N.patt.loc4_23.1: i32 = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc4_23.2 (constants.%N.patt)]
-// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc4_23.1, runtime_param<invalid> [symbolic = %N.patt.loc4_23.2 (constants.%N.patt)]
+// CHECK:STDOUT:     %N.patt.loc4_23.1: i32 = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc4_23.2 (constants.%N.patt.1)]
+// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc4_23.1, runtime_param<invalid> [symbolic = %N.patt.loc4_23.2 (constants.%N.patt.1)]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32 [template = i32]
@@ -135,22 +144,32 @@ class Outer(T:! type) {
 // CHECK:STDOUT:     %T.param: type = value_param runtime_param<invalid>
 // CHECK:STDOUT:     %T.loc4_13.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_13.2 (constants.%T)]
 // CHECK:STDOUT:     %N.param: i32 = value_param runtime_param<invalid>
-// CHECK:STDOUT:     %N.loc4_23.1: i32 = bind_symbolic_name N, 1, %N.param [symbolic = %N.loc4_23.2 (constants.%N)]
+// CHECK:STDOUT:     %N.loc4_23.1: i32 = bind_symbolic_name N, 1, %N.param [symbolic = %N.loc4_23.2 (constants.%N.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.ref.loc6: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc6_17.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc6_17.2: type = converted %int.make_type_32, %.loc6_17.1 [template = i32]
 // CHECK:STDOUT:   %.loc6_17.3: type = ptr_type i32 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_20: i32 = int_value 5 [template = constants.%.4]
-// CHECK:STDOUT:   %Class.loc6: type = class_type @Class, @Class(constants.%.3, constants.%.4) [template = constants.%Class.3]
+// CHECK:STDOUT:   %.loc6_20: Core.IntLiteral = int_value 5 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_13.1: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_13.2: <bound method> = bound_method %.loc6_20, %.loc6_13.1 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc6: init i32 = call %.loc6_13.2(%.loc6_20) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_13.3: i32 = value_of_initializer %int.convert_checked.loc6 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc6_13.4: i32 = converted %.loc6_20, %.loc6_13.3 [template = constants.%.30]
+// CHECK:STDOUT:   %Class.loc6: type = class_type @Class, @Class(constants.%.3, constants.%.30) [template = constants.%Class.3]
 // CHECK:STDOUT:   %a.var: ref %Class.3 = var a
 // CHECK:STDOUT:   %a: ref %Class.3 = bind_name a, %a.var
 // CHECK:STDOUT:   %Class.ref.loc9: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
 // CHECK:STDOUT:   %.loc9_15: %empty_tuple.type = tuple_literal ()
-// CHECK:STDOUT:   %.loc9_18: i32 = int_value 0 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_13: type = converted %.loc9_15, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
-// CHECK:STDOUT:   %Class.loc9: type = class_type @Class, @Class(constants.%empty_tuple.type, constants.%.6) [template = constants.%Class.4]
+// CHECK:STDOUT:   %.loc9_18: Core.IntLiteral = int_value 0 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc9_13.1: type = converted %.loc9_15, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
+// CHECK:STDOUT:   %.loc9_13.2: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_13.3: <bound method> = bound_method %.loc9_18, %.loc9_13.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc9: init i32 = call %.loc9_13.3(%.loc9_18) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_13.4: i32 = value_of_initializer %int.convert_checked.loc9 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_13.5: i32 = converted %.loc9_18, %.loc9_13.4 [template = constants.%.34]
+// CHECK:STDOUT:   %Class.loc9: type = class_type @Class, @Class(constants.%empty_tuple.type, constants.%.34) [template = constants.%Class.4]
 // CHECK:STDOUT:   %b.var: ref %Class.4 = var b
 // CHECK:STDOUT:   %b: ref %Class.4 = bind_name b, %b.var
 // CHECK:STDOUT: }
@@ -158,8 +177,8 @@ class Outer(T:! type) {
 // CHECK:STDOUT: generic class @Class(%T.loc4_13.1: type, %N.loc4_23.1: i32) {
 // CHECK:STDOUT:   %T.loc4_13.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.2 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc4_13.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_13.2 (constants.%T.patt)]
-// CHECK:STDOUT:   %N.loc4_23.2: i32 = bind_symbolic_name N, 1 [symbolic = %N.loc4_23.2 (constants.%N)]
-// CHECK:STDOUT:   %N.patt.loc4_23.2: i32 = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc4_23.2 (constants.%N.patt)]
+// CHECK:STDOUT:   %N.loc4_23.2: i32 = bind_symbolic_name N, 1 [symbolic = %N.loc4_23.2 (constants.%N.1)]
+// CHECK:STDOUT:   %N.patt.loc4_23.2: i32 = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc4_23.2 (constants.%N.patt.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
@@ -171,27 +190,27 @@ class Outer(T:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class(constants.%T, constants.%N) {
+// CHECK:STDOUT: specific @Class(constants.%T, constants.%N.1) {
 // CHECK:STDOUT:   %T.loc4_13.2 => constants.%T
 // CHECK:STDOUT:   %T.patt.loc4_13.2 => constants.%T
-// CHECK:STDOUT:   %N.loc4_23.2 => constants.%N
-// CHECK:STDOUT:   %N.patt.loc4_23.2 => constants.%N
+// CHECK:STDOUT:   %N.loc4_23.2 => constants.%N.1
+// CHECK:STDOUT:   %N.patt.loc4_23.2 => constants.%N.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class(constants.%.3, constants.%.4) {
+// CHECK:STDOUT: specific @Class(constants.%.3, constants.%.30) {
 // CHECK:STDOUT:   %T.loc4_13.2 => constants.%.3
 // CHECK:STDOUT:   %T.patt.loc4_13.2 => constants.%.3
-// CHECK:STDOUT:   %N.loc4_23.2 => constants.%.4
-// CHECK:STDOUT:   %N.patt.loc4_23.2 => constants.%.4
+// CHECK:STDOUT:   %N.loc4_23.2 => constants.%.30
+// CHECK:STDOUT:   %N.patt.loc4_23.2 => constants.%.30
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class(constants.%empty_tuple.type, constants.%.6) {
+// CHECK:STDOUT: specific @Class(constants.%empty_tuple.type, constants.%.34) {
 // CHECK:STDOUT:   %T.loc4_13.2 => constants.%empty_tuple.type
 // CHECK:STDOUT:   %T.patt.loc4_13.2 => constants.%empty_tuple.type
-// CHECK:STDOUT:   %N.loc4_23.2 => constants.%.6
-// CHECK:STDOUT:   %N.patt.loc4_23.2 => constants.%.6
+// CHECK:STDOUT:   %N.loc4_23.2 => constants.%.34
+// CHECK:STDOUT:   %N.patt.loc4_23.2 => constants.%.34
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
@@ -289,8 +308,8 @@ class Outer(T:! type) {
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
 // CHECK:STDOUT:   %.3: type = ptr_type i32 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -327,8 +346,8 @@ class Outer(T:! type) {
 // CHECK:STDOUT:   %.loc13_17.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc13_17.2: type = converted %int.make_type_32, %.loc13_17.1 [template = i32]
 // CHECK:STDOUT:   %.loc13_17.3: type = ptr_type i32 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc13_20: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc13_23: i32 = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc13_20: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc13_23: Core.IntLiteral = int_value 2 [template = constants.%.5]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
 // CHECK:STDOUT: }
@@ -370,7 +389,7 @@ class Outer(T:! type) {
 // CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T, %N.1) [symbolic]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 5 [template]
 // CHECK:STDOUT:   %.4: type = ptr_type i32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -405,7 +424,7 @@ class Outer(T:! type) {
 // CHECK:STDOUT:     %N.loc4_23.1: i32 = bind_symbolic_name N, 1, %N.param [symbolic = %N.loc4_23.2 (constants.%N.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.ref: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
-// CHECK:STDOUT:   %.loc15_14: i32 = int_value 5 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15_14: Core.IntLiteral = int_value 5 [template = constants.%.3]
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc15_20.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc15_20.2: type = converted %int.make_type_32, %.loc15_20.1 [template = i32]

Разница между файлами не показана из-за своего большого размера
+ 998 - 38
toolchain/check/testdata/class/generic/import.carbon


+ 57 - 40
toolchain/check/testdata/class/import.carbon

@@ -156,20 +156,28 @@ fn Run() {
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %struct.1: %Empty = struct_value () [template]
 // CHECK:STDOUT:   %Field: type = class_type @Field [template]
-// CHECK:STDOUT:   %.4: type = struct_type {.x: i32} [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %struct.2: %Field = struct_value (%.7) [template]
-// CHECK:STDOUT:   %.8: type = unbound_element_type %Field, i32 [template]
-// CHECK:STDOUT:   %.9: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.7: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.x: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.7, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %struct.2: %Field = struct_value (%.34) [template]
+// CHECK:STDOUT:   %.35: type = unbound_element_type %Field, i32 [template]
+// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.37: <bound method> = bound_method %.36, %Convert.15 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 2 [template]
 // CHECK:STDOUT:   %ForwardDeclared.1: type = class_type @ForwardDeclared.1 [template]
 // CHECK:STDOUT:   %struct.3: %ForwardDeclared.1 = struct_value () [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = ptr_type %ForwardDeclared.1 [template]
+// CHECK:STDOUT:   %.39: type = ptr_type %ForwardDeclared.1 [template]
 // CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete [template]
-// CHECK:STDOUT:   %.11: type = ptr_type %Incomplete [template]
+// CHECK:STDOUT:   %.40: type = ptr_type %Incomplete [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -178,18 +186,19 @@ fn Run() {
 // CHECK:STDOUT:   %import_ref.3: type = import_ref Main//a, inst+26, loaded [template = constants.%ForwardDeclared.1]
 // CHECK:STDOUT:   %import_ref.4: type = import_ref Main//a, inst+49, loaded [template = constants.%Incomplete]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.8
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %import_ref.5 = import_ref Main//a, inst+4, unloaded
 // CHECK:STDOUT:   %import_ref.6 = import_ref Main//a, inst+9, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.8 = import_ref Main//a, inst+22, loaded [template = %.1]
-// CHECK:STDOUT:   %import_ref.8 = import_ref Main//a, inst+27, unloaded
-// CHECK:STDOUT:   %import_ref.9: %F.type = import_ref Main//a, inst+34, loaded [template = constants.%F]
-// CHECK:STDOUT:   %import_ref.10: %G.type = import_ref Main//a, inst+45, loaded [template = constants.%G]
-// CHECK:STDOUT:   %import_ref.11 = import_ref Main//a, inst+27, unloaded
-// CHECK:STDOUT:   %import_ref.12 = import_ref Main//a, inst+34, unloaded
-// CHECK:STDOUT:   %import_ref.13 = import_ref Main//a, inst+45, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.35 = import_ref Main//a, inst+22, loaded [template = %.1]
+// CHECK:STDOUT:   %import_ref.57 = import_ref Main//a, inst+27, unloaded
+// CHECK:STDOUT:   %import_ref.58: %F.type = import_ref Main//a, inst+34, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.59: %G.type = import_ref Main//a, inst+45, loaded [template = constants.%G]
+// CHECK:STDOUT:   %import_ref.60 = import_ref Main//a, inst+27, unloaded
+// CHECK:STDOUT:   %import_ref.61 = import_ref Main//a, inst+34, unloaded
+// CHECK:STDOUT:   %import_ref.62 = import_ref Main//a, inst+45, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -219,16 +228,16 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @ForwardDeclared.1 {
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = imports.%import_ref.8
-// CHECK:STDOUT:   .F = imports.%import_ref.9
-// CHECK:STDOUT:   .G = imports.%import_ref.10
+// CHECK:STDOUT:   .Self = imports.%import_ref.57
+// CHECK:STDOUT:   .F = imports.%import_ref.58
+// CHECK:STDOUT:   .G = imports.%import_ref.59
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @ForwardDeclared.2 {
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = imports.%import_ref.11
-// CHECK:STDOUT:   .F = imports.%import_ref.12
-// CHECK:STDOUT:   .G = imports.%import_ref.13
+// CHECK:STDOUT:   .Self = imports.%import_ref.60
+// CHECK:STDOUT:   .F = imports.%import_ref.61
+// CHECK:STDOUT:   .G = imports.%import_ref.62
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Incomplete;
@@ -245,18 +254,26 @@ fn Run() {
 // CHECK:STDOUT:   %Field.ref: type = name_ref Field, imports.%import_ref.2 [template = constants.%Field]
 // CHECK:STDOUT:   %b.var: ref %Field = var b
 // CHECK:STDOUT:   %b: ref %Field = bind_name b, %b.var
-// CHECK:STDOUT:   %.loc9_24: i32 = int_value 1 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_25.1: %.4 = struct_literal (%.loc9_24)
-// CHECK:STDOUT:   %.loc9_25.2: ref i32 = class_element_access %b.var, element0
-// CHECK:STDOUT:   %.loc9_25.3: init i32 = initialize_from %.loc9_24 to %.loc9_25.2 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_25.4: init %Field = class_init (%.loc9_25.3), %b.var [template = constants.%struct.2]
-// CHECK:STDOUT:   %.loc9_26: init %Field = converted %.loc9_25.1, %.loc9_25.4 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc9_24: Core.IntLiteral = int_value 1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_25.1: %.8 = struct_literal (%.loc9_24)
+// CHECK:STDOUT:   %.loc9_25.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_25.3: <bound method> = bound_method %.loc9_24, %.loc9_25.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc9: init i32 = call %.loc9_25.3(%.loc9_24) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_25.4: init i32 = converted %.loc9_24, %int.convert_checked.loc9 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_25.5: ref i32 = class_element_access %b.var, element0
+// CHECK:STDOUT:   %.loc9_25.6: init i32 = initialize_from %.loc9_25.4 to %.loc9_25.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_25.7: init %Field = class_init (%.loc9_25.6), %b.var [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc9_26: init %Field = converted %.loc9_25.1, %.loc9_25.7 [template = constants.%struct.2]
 // CHECK:STDOUT:   assign %b.var, %.loc9_26
 // CHECK:STDOUT:   %b.ref: ref %Field = name_ref b, %b
-// CHECK:STDOUT:   %x.ref: %.8 = name_ref x, imports.%import_ref.7 [template = imports.%.1]
+// CHECK:STDOUT:   %x.ref: %.35 = name_ref x, imports.%import_ref.7 [template = imports.%.1]
 // CHECK:STDOUT:   %.loc10_4: ref i32 = class_element_access %b.ref, element0
-// CHECK:STDOUT:   %.loc10_9: i32 = int_value 2 [template = constants.%.9]
-// CHECK:STDOUT:   assign %.loc10_4, %.loc10_9
+// CHECK:STDOUT:   %.loc10_9: Core.IntLiteral = int_value 2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc10_7.1: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_7.2: <bound method> = bound_method %.loc10_9, %.loc10_7.1 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc10: init i32 = call %.loc10_7.2(%.loc10_9) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc10_7.3: init i32 = converted %.loc10_9, %int.convert_checked.loc10 [template = constants.%.38]
+// CHECK:STDOUT:   assign %.loc10_4, %.loc10_7.3
 // CHECK:STDOUT:   %ForwardDeclared.ref.loc12: type = name_ref ForwardDeclared, imports.%import_ref.3 [template = constants.%ForwardDeclared.1]
 // CHECK:STDOUT:   %c.var: ref %ForwardDeclared.1 = var c
 // CHECK:STDOUT:   %c: ref %ForwardDeclared.1 = bind_name c, %c.var
@@ -265,30 +282,30 @@ fn Run() {
 // CHECK:STDOUT:   %.loc12_30: init %ForwardDeclared.1 = converted %.loc12_29.1, %.loc12_29.2 [template = constants.%struct.3]
 // CHECK:STDOUT:   assign %c.var, %.loc12_30
 // CHECK:STDOUT:   %c.ref.loc13: ref %ForwardDeclared.1 = name_ref c, %c
-// CHECK:STDOUT:   %F.ref: %F.type = name_ref F, imports.%import_ref.9 [template = constants.%F]
+// CHECK:STDOUT:   %F.ref: %F.type = name_ref F, imports.%import_ref.58 [template = constants.%F]
 // CHECK:STDOUT:   %.loc13_4: <bound method> = bound_method %c.ref.loc13, %F.ref
 // CHECK:STDOUT:   %.loc13_3: %ForwardDeclared.1 = bind_value %c.ref.loc13
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %.loc13_4(%.loc13_3)
 // CHECK:STDOUT:   %c.ref.loc14: ref %ForwardDeclared.1 = name_ref c, %c
-// CHECK:STDOUT:   %G.ref: %G.type = name_ref G, imports.%import_ref.10 [template = constants.%G]
+// CHECK:STDOUT:   %G.ref: %G.type = name_ref G, imports.%import_ref.59 [template = constants.%G]
 // CHECK:STDOUT:   %.loc14_4: <bound method> = bound_method %c.ref.loc14, %G.ref
-// CHECK:STDOUT:   %.loc14_3: %.10 = addr_of %c.ref.loc14
+// CHECK:STDOUT:   %.loc14_3: %.39 = addr_of %c.ref.loc14
 // CHECK:STDOUT:   %G.call: init %empty_tuple.type = call %.loc14_4(%.loc14_3)
 // CHECK:STDOUT:   %ForwardDeclared.ref.loc16: type = name_ref ForwardDeclared, imports.%import_ref.3 [template = constants.%ForwardDeclared.1]
-// CHECK:STDOUT:   %.loc16_25: type = ptr_type %ForwardDeclared.1 [template = constants.%.10]
-// CHECK:STDOUT:   %d.var: ref %.10 = var d
-// CHECK:STDOUT:   %d: ref %.10 = bind_name d, %d.var
+// CHECK:STDOUT:   %.loc16_25: type = ptr_type %ForwardDeclared.1 [template = constants.%.39]
+// CHECK:STDOUT:   %d.var: ref %.39 = var d
+// CHECK:STDOUT:   %d: ref %.39 = bind_name d, %d.var
 // CHECK:STDOUT:   %c.ref.loc16: ref %ForwardDeclared.1 = name_ref c, %c
-// CHECK:STDOUT:   %.loc16_29: %.10 = addr_of %c.ref.loc16
+// CHECK:STDOUT:   %.loc16_29: %.39 = addr_of %c.ref.loc16
 // CHECK:STDOUT:   assign %d.var, %.loc16_29
 // CHECK:STDOUT:   %Incomplete.ref: type = name_ref Incomplete, imports.%import_ref.4 [template = constants.%Incomplete]
-// CHECK:STDOUT:   %.loc18: type = ptr_type %Incomplete [template = constants.%.11]
-// CHECK:STDOUT:   %e.var: ref %.11 = var e
-// CHECK:STDOUT:   %e: ref %.11 = bind_name e, %e.var
+// CHECK:STDOUT:   %.loc18: type = ptr_type %Incomplete [template = constants.%.40]
+// CHECK:STDOUT:   %e.var: ref %.40 = var e
+// CHECK:STDOUT:   %e: ref %.40 = bind_name e, %e.var
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F[%self.param_patt: %ForwardDeclared.1]();
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G[addr <unexpected>.inst+91: %.10]();
+// CHECK:STDOUT: fn @G[addr <unexpected>.inst+461: %.39]();
 // CHECK:STDOUT:

+ 44 - 21
toolchain/check/testdata/class/import_base.carbon

@@ -132,14 +132,24 @@ fn Run() {
 // CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
 // CHECK:STDOUT:   %Child: type = class_type @Child [template]
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
-// CHECK:STDOUT:   %.1: type = struct_type {.x: i32, .unused: i32} [template]
-// CHECK:STDOUT:   %.9: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %.10: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.11: type = struct_type {.base: %.1} [template]
-// CHECK:STDOUT:   %struct.1: %Base = struct_value (%.9, %.10) [template]
+// CHECK:STDOUT:   %.9: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %.10: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.11: type = struct_type {.x: Core.IntLiteral, .unused: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.12: type = struct_type {.base: %.11} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.36: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.37: <bound method> = bound_method %.9, %Convert.15 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.39: <bound method> = bound_method %.10, %Convert.15 [template]
+// CHECK:STDOUT:   %.40: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %struct.1: %Base = struct_value (%.38, %.40) [template]
 // CHECK:STDOUT:   %struct.2: %Child = struct_value (%struct.1) [template]
-// CHECK:STDOUT:   %.12: type = unbound_element_type %Base, i32 [template]
-// CHECK:STDOUT:   %.13: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.41: type = unbound_element_type %Base, i32 [template]
+// CHECK:STDOUT:   %.42: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.43: <bound method> = bound_method %.42, %Convert.15 [template]
+// CHECK:STDOUT:   %.44: i32 = int_value 2 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -148,13 +158,14 @@ fn Run() {
 // CHECK:STDOUT:   %import_ref.1 = import_ref Main//a, inst+3, unloaded
 // CHECK:STDOUT:   %import_ref.2: type = import_ref Main//a, inst+41, loaded [template = constants.%Child]
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.10
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %import_ref.3 = import_ref Main//a, inst+4, unloaded
 // CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Main//a, inst+10, loaded [template = constants.%F]
 // CHECK:STDOUT:   %import_ref.5 = import_ref Main//a, inst+19, unloaded
-// CHECK:STDOUT:   %import_ref.6: %.12 = import_ref Main//a, inst+33, loaded [template = %.1]
+// CHECK:STDOUT:   %import_ref.6: %.41 = import_ref Main//a, inst+33, loaded [template = %.1]
 // CHECK:STDOUT:   %import_ref.7 = import_ref Main//a, inst+37, unloaded
 // CHECK:STDOUT:   %import_ref.8 = import_ref Main//a, inst+42, unloaded
 // CHECK:STDOUT:   %import_ref.9 = import_ref Main//a, inst+46, unloaded
@@ -193,27 +204,39 @@ fn Run() {
 // CHECK:STDOUT:   %Child.ref: type = name_ref Child, imports.%import_ref.2 [template = constants.%Child]
 // CHECK:STDOUT:   %a.var: ref %Child = var a
 // CHECK:STDOUT:   %a: ref %Child = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc7_33: i32 = int_value 0 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc7_46: i32 = int_value 1 [template = constants.%.10]
-// CHECK:STDOUT:   %.loc7_47.1: %.1 = struct_literal (%.loc7_33, %.loc7_46)
-// CHECK:STDOUT:   %.loc7_48.1: %.11 = struct_literal (%.loc7_47.1)
+// CHECK:STDOUT:   %.loc7_33: Core.IntLiteral = int_value 0 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc7_46: Core.IntLiteral = int_value 1 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc7_47.1: %.11 = struct_literal (%.loc7_33, %.loc7_46)
+// CHECK:STDOUT:   %.loc7_48.1: %.12 = struct_literal (%.loc7_47.1)
+// CHECK:STDOUT:   %.loc7_47.2: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_47.3: <bound method> = bound_method %.loc7_33, %.loc7_47.2 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc7_47.1: init i32 = call %.loc7_47.3(%.loc7_33) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc7_47.4: init i32 = converted %.loc7_33, %int.convert_checked.loc7_47.1 [template = constants.%.38]
 // CHECK:STDOUT:   %.loc7_48.2: ref %Base = class_element_access %a.var, element0
-// CHECK:STDOUT:   %.loc7_47.2: ref i32 = class_element_access %.loc7_48.2, element0
-// CHECK:STDOUT:   %.loc7_47.3: init i32 = initialize_from %.loc7_33 to %.loc7_47.2 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc7_47.4: ref i32 = class_element_access %.loc7_48.2, element1
-// CHECK:STDOUT:   %.loc7_47.5: init i32 = initialize_from %.loc7_46 to %.loc7_47.4 [template = constants.%.10]
-// CHECK:STDOUT:   %.loc7_47.6: init %Base = class_init (%.loc7_47.3, %.loc7_47.5), %.loc7_48.2 [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc7_48.3: init %Base = converted %.loc7_47.1, %.loc7_47.6 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc7_47.5: ref i32 = class_element_access %.loc7_48.2, element0
+// CHECK:STDOUT:   %.loc7_47.6: init i32 = initialize_from %.loc7_47.4 to %.loc7_47.5 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc7_47.7: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_47.8: <bound method> = bound_method %.loc7_46, %.loc7_47.7 [template = constants.%.39]
+// CHECK:STDOUT:   %int.convert_checked.loc7_47.2: init i32 = call %.loc7_47.8(%.loc7_46) [template = constants.%.40]
+// CHECK:STDOUT:   %.loc7_47.9: init i32 = converted %.loc7_46, %int.convert_checked.loc7_47.2 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc7_47.10: ref i32 = class_element_access %.loc7_48.2, element1
+// CHECK:STDOUT:   %.loc7_47.11: init i32 = initialize_from %.loc7_47.9 to %.loc7_47.10 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc7_47.12: init %Base = class_init (%.loc7_47.6, %.loc7_47.11), %.loc7_48.2 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc7_48.3: init %Base = converted %.loc7_47.1, %.loc7_47.12 [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc7_48.4: init %Child = class_init (%.loc7_48.3), %a.var [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc7_49: init %Child = converted %.loc7_48.1, %.loc7_48.4 [template = constants.%struct.2]
 // CHECK:STDOUT:   assign %a.var, %.loc7_49
 // CHECK:STDOUT:   %a.ref.loc8: ref %Child = name_ref a, %a
-// CHECK:STDOUT:   %x.ref: %.12 = name_ref x, imports.%import_ref.6 [template = imports.%.1]
+// CHECK:STDOUT:   %x.ref: %.41 = name_ref x, imports.%import_ref.6 [template = imports.%.1]
 // CHECK:STDOUT:   %.loc8_4.1: ref %Base = class_element_access %a.ref.loc8, element0
 // CHECK:STDOUT:   %.loc8_4.2: ref %Base = converted %a.ref.loc8, %.loc8_4.1
 // CHECK:STDOUT:   %.loc8_4.3: ref i32 = class_element_access %.loc8_4.2, element0
-// CHECK:STDOUT:   %.loc8_9: i32 = int_value 2 [template = constants.%.13]
-// CHECK:STDOUT:   assign %.loc8_4.3, %.loc8_9
+// CHECK:STDOUT:   %.loc8_9: Core.IntLiteral = int_value 2 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc8_7.1: %Convert.type.2 = interface_witness_access constants.%.36, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc8_7.2: <bound method> = bound_method %.loc8_9, %.loc8_7.1 [template = constants.%.43]
+// CHECK:STDOUT:   %int.convert_checked.loc8: init i32 = call %.loc8_7.2(%.loc8_9) [template = constants.%.44]
+// CHECK:STDOUT:   %.loc8_7.3: init i32 = converted %.loc8_9, %int.convert_checked.loc8 [template = constants.%.44]
+// CHECK:STDOUT:   assign %.loc8_4.3, %.loc8_7.3
 // CHECK:STDOUT:   %a.ref.loc9: ref %Child = name_ref a, %a
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, imports.%import_ref.4 [template = constants.%F]
 // CHECK:STDOUT:   %.loc9_4: <bound method> = bound_method %a.ref.loc9, %F.ref

+ 71 - 32
toolchain/check/testdata/class/inheritance_access.carbon

@@ -463,24 +463,31 @@ class B {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 5 [template]
 // CHECK:STDOUT:   %SomeProtectedFunction.type: type = fn_type @SomeProtectedFunction [template]
 // CHECK:STDOUT:   %SomeProtectedFunction: %SomeProtectedFunction.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
-// CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
+// CHECK:STDOUT:   %.28: type = struct_type {} [template]
+// CHECK:STDOUT:   %.29: <witness> = complete_type_witness %.28 [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
-// CHECK:STDOUT:   %.5: type = unbound_element_type %B, %A [template]
+// CHECK:STDOUT:   %.31: type = unbound_element_type %B, %A [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %H.type: type = fn_type @H [template]
 // CHECK:STDOUT:   %H: %H.type = struct_value () [template]
-// CHECK:STDOUT:   %.6: type = struct_type {.base: %A} [template]
-// CHECK:STDOUT:   %.7: <witness> = complete_type_witness %.6 [template]
+// CHECK:STDOUT:   %.32: type = struct_type {.base: %A} [template]
+// CHECK:STDOUT:   %.33: <witness> = complete_type_witness %.32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -501,8 +508,13 @@ class B {
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc5_32.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc5_32.2: type = converted %int.make_type_32, %.loc5_32.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_38: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %SOME_CONSTANT: i32 = bind_name SOME_CONSTANT, %.loc5_38
+// CHECK:STDOUT:   %.loc5_38: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc5_39.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc5_39.2: <bound method> = bound_method %.loc5_38, %.loc5_39.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc5_39.2(%.loc5_38) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_39.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_39.4: i32 = converted %.loc5_38, %.loc5_39.3 [template = constants.%.27]
+// CHECK:STDOUT:   %SOME_CONSTANT: i32 = bind_name SOME_CONSTANT, %.loc5_39.4
 // CHECK:STDOUT:   %SomeProtectedFunction.decl: %SomeProtectedFunction.type = fn_decl @SomeProtectedFunction [template = constants.%SomeProtectedFunction] {
 // CHECK:STDOUT:     %return.patt: i32 = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: i32 = out_param_pattern %return.patt, runtime_param0
@@ -513,7 +525,7 @@ class B {
 // CHECK:STDOUT:     %return.param: ref i32 = out_param runtime_param0
 // CHECK:STDOUT:     %return: ref i32 = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc9: <witness> = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9: <witness> = complete_type_witness %.28 [template = constants.%.29]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
@@ -523,7 +535,7 @@ class B {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT:   %.loc12: %.5 = base_decl %A, element0 [template]
+// CHECK:STDOUT:   %.loc12: %.31 = base_decl %A, element0 [template]
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %return.patt: i32 = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: i32 = out_param_pattern %return.patt, runtime_param0
@@ -544,7 +556,7 @@ class B {
 // CHECK:STDOUT:     %return.param: ref i32 = out_param runtime_param0
 // CHECK:STDOUT:     %return: ref i32 = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc21: <witness> = complete_type_witness %.6 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc21: <witness> = complete_type_witness %.32 [template = constants.%.33]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%B
@@ -556,8 +568,13 @@ class B {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @SomeProtectedFunction() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   return %.loc7
+// CHECK:STDOUT:   %.loc7_12: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_13.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc7_13.2: <bound method> = bound_method %.loc7_12, %.loc7_13.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc7_13.2(%.loc7_12) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc7_13.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc7_13.4: i32 = converted %.loc7_12, %.loc7_13.3 [template = constants.%.27]
+// CHECK:STDOUT:   return %.loc7_13.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
@@ -909,23 +926,30 @@ class B {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
-// CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.27: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.28: type = struct_type {} [template]
+// CHECK:STDOUT:   %.29: <witness> = complete_type_witness %.28 [template]
 // CHECK:STDOUT:   %Internal: type = class_type @Internal [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
-// CHECK:STDOUT:   %.5: type = unbound_element_type %B, %Internal [template]
+// CHECK:STDOUT:   %.31: type = unbound_element_type %B, %Internal [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %SomeFunc.type: type = fn_type @SomeFunc [template]
 // CHECK:STDOUT:   %SomeFunc: %SomeFunc.type = struct_value () [template]
-// CHECK:STDOUT:   %.6: type = struct_type {.internal: %Internal} [template]
-// CHECK:STDOUT:   %.7: <witness> = complete_type_witness %.6 [template]
+// CHECK:STDOUT:   %.32: type = struct_type {.internal: %Internal} [template]
+// CHECK:STDOUT:   %.33: <witness> = complete_type_witness %.32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -948,14 +972,24 @@ class B {
 // CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc5_42.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
 // CHECK:STDOUT:   %.loc5_42.2: type = converted %int.make_type_32.loc5, %.loc5_42.1 [template = i32]
-// CHECK:STDOUT:   %.loc5_48: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %SOME_PROTECTED_CONSTANT: i32 = bind_name SOME_PROTECTED_CONSTANT, %.loc5_48
+// CHECK:STDOUT:   %.loc5_48: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc5_49.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc5_49.2: <bound method> = bound_method %.loc5_48, %.loc5_49.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc5: init i32 = call %.loc5_49.2(%.loc5_48) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_49.3: i32 = value_of_initializer %int.convert_checked.loc5 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc5_49.4: i32 = converted %.loc5_48, %.loc5_49.3 [template = constants.%.27]
+// CHECK:STDOUT:   %SOME_PROTECTED_CONSTANT: i32 = bind_name SOME_PROTECTED_CONSTANT, %.loc5_49.4
 // CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc6_38.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
 // CHECK:STDOUT:   %.loc6_38.2: type = converted %int.make_type_32.loc6, %.loc6_38.1 [template = i32]
-// CHECK:STDOUT:   %.loc6_44: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %SOME_PRIVATE_CONSTANT: i32 = bind_name SOME_PRIVATE_CONSTANT, %.loc6_44
-// CHECK:STDOUT:   %.loc7: <witness> = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc6_44: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6_45.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc6_45.2: <bound method> = bound_method %.loc6_44, %.loc6_45.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked.loc6: init i32 = call %.loc6_45.2(%.loc6_44) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc6_45.3: i32 = value_of_initializer %int.convert_checked.loc6 [template = constants.%.27]
+// CHECK:STDOUT:   %.loc6_45.4: i32 = converted %.loc6_44, %.loc6_45.3 [template = constants.%.27]
+// CHECK:STDOUT:   %SOME_PRIVATE_CONSTANT: i32 = bind_name SOME_PRIVATE_CONSTANT, %.loc6_45.4
+// CHECK:STDOUT:   %.loc7: <witness> = complete_type_witness %.28 [template = constants.%.29]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
@@ -967,9 +1001,14 @@ class B {
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc10_36.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc10_36.2: type = converted %int.make_type_32, %.loc10_36.1 [template = i32]
-// CHECK:STDOUT:   %.loc10_42: i32 = int_value 5 [template = constants.%.1]
-// CHECK:STDOUT:   %INTERNAL_CONSTANT: i32 = bind_name INTERNAL_CONSTANT, %.loc10_42
-// CHECK:STDOUT:   %.loc11: <witness> = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_42: Core.IntLiteral = int_value 5 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_43.1: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc10_43.2: <bound method> = bound_method %.loc10_42, %.loc10_43.1 [template = constants.%.26]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc10_43.2(%.loc10_42) [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_43.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.27]
+// CHECK:STDOUT:   %.loc10_43.4: i32 = converted %.loc10_42, %.loc10_43.3 [template = constants.%.27]
+// CHECK:STDOUT:   %INTERNAL_CONSTANT: i32 = bind_name INTERNAL_CONSTANT, %.loc10_43.4
+// CHECK:STDOUT:   %.loc11: <witness> = complete_type_witness %.28 [template = constants.%.29]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Internal
@@ -978,7 +1017,7 @@ class B {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
 // CHECK:STDOUT:   %Internal.ref: type = name_ref Internal, file.%Internal.decl [template = constants.%Internal]
-// CHECK:STDOUT:   %.loc14: %.5 = field_decl internal, element0 [template]
+// CHECK:STDOUT:   %.loc14: %.31 = field_decl internal, element0 [template]
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %return.patt: i32 = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: i32 = out_param_pattern %return.patt, runtime_param0
@@ -1004,7 +1043,7 @@ class B {
 // CHECK:STDOUT:     %return.param: ref i32 = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref i32 = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc46: <witness> = complete_type_witness %.6 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc46: <witness> = complete_type_witness %.32 [template = constants.%.33]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%B
@@ -1025,7 +1064,7 @@ class B {
 // CHECK:STDOUT: fn @SomeFunc[%self.param_patt: %B]() -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %self.ref: %B = name_ref self, %self
-// CHECK:STDOUT:   %internal.ref: %.5 = name_ref internal, @B.%.loc14 [template = @B.%.loc14]
+// CHECK:STDOUT:   %internal.ref: %.31 = name_ref internal, @B.%.loc14 [template = @B.%.loc14]
 // CHECK:STDOUT:   %.loc44_16.1: ref %Internal = class_element_access %self.ref, element0
 // CHECK:STDOUT:   %.loc44_16.2: %Internal = bind_value %.loc44_16.1
 // CHECK:STDOUT:   %INTERNAL_CONSTANT.ref: <error> = name_ref INTERNAL_CONSTANT, <error> [template = <error>]

+ 64 - 29
toolchain/check/testdata/class/init_adapt.carbon

@@ -102,9 +102,18 @@ var e: C = MakeAdaptC();
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %AdaptC: type = class_type @AdaptC [template]
 // CHECK:STDOUT:   %.5: <witness> = complete_type_witness %C [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %struct: %C = struct_value (%.6, %.7) [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.7: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.7, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %struct: %C = struct_value (%.34, %.36) [template]
 // CHECK:STDOUT:   %MakeC.type: type = fn_type @MakeC [template]
 // CHECK:STDOUT:   %MakeC: %MakeC.type = struct_value () [template]
 // CHECK:STDOUT:   %MakeAdaptC.type: type = fn_type @MakeAdaptC [template]
@@ -113,7 +122,8 @@ var e: C = MakeAdaptC();
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -194,17 +204,25 @@ var e: C = MakeAdaptC();
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc13_18: i32 = int_value 1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc13_26: i32 = int_value 2 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_27.1: %.2 = struct_literal (%.loc13_18, %.loc13_26)
-// CHECK:STDOUT:   %.loc13_27.2: ref %C = temporary_storage
-// CHECK:STDOUT:   %.loc13_27.3: ref i32 = class_element_access %.loc13_27.2, element0
-// CHECK:STDOUT:   %.loc13_27.4: init i32 = initialize_from %.loc13_18 to %.loc13_27.3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc13_27.5: ref i32 = class_element_access %.loc13_27.2, element1
-// CHECK:STDOUT:   %.loc13_27.6: init i32 = initialize_from %.loc13_26 to %.loc13_27.5 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_27.7: init %C = class_init (%.loc13_27.4, %.loc13_27.6), %.loc13_27.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_27.8: ref %C = temporary %.loc13_27.2, %.loc13_27.7
-// CHECK:STDOUT:   %.loc13_28.1: ref %C = converted %.loc13_27.1, %.loc13_27.8
+// CHECK:STDOUT:   %.loc13_18: Core.IntLiteral = int_value 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc13_26: Core.IntLiteral = int_value 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc13_27.1: %.8 = struct_literal (%.loc13_18, %.loc13_26)
+// CHECK:STDOUT:   %.loc13_27.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_27.3: <bound method> = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc13_27.1: init i32 = call %.loc13_27.3(%.loc13_18) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_27.4: init i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_27.5: ref %C = temporary_storage
+// CHECK:STDOUT:   %.loc13_27.6: ref i32 = class_element_access %.loc13_27.5, element0
+// CHECK:STDOUT:   %.loc13_27.7: init i32 = initialize_from %.loc13_27.4 to %.loc13_27.6 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_27.8: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_27.9: <bound method> = bound_method %.loc13_26, %.loc13_27.8 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc13_27.2: init i32 = call %.loc13_27.9(%.loc13_26) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_27.10: init i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_27.11: ref i32 = class_element_access %.loc13_27.5, element1
+// CHECK:STDOUT:   %.loc13_27.12: init i32 = initialize_from %.loc13_27.10 to %.loc13_27.11 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_27.13: init %C = class_init (%.loc13_27.7, %.loc13_27.12), %.loc13_27.5 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc13_27.14: ref %C = temporary %.loc13_27.5, %.loc13_27.13
+// CHECK:STDOUT:   %.loc13_28.1: ref %C = converted %.loc13_27.1, %.loc13_27.14
 // CHECK:STDOUT:   %.loc13_28.2: %C = bind_value %.loc13_28.1
 // CHECK:STDOUT:   %a: %C = bind_name a, %.loc13_28.2
 // CHECK:STDOUT:   %a.ref: %C = name_ref a, %a
@@ -245,9 +263,18 @@ var e: C = MakeAdaptC();
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %AdaptC: type = class_type @AdaptC [template]
 // CHECK:STDOUT:   %.5: <witness> = complete_type_witness %C [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %struct: %C = struct_value (%.6, %.7) [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.7: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.7, %Convert.15 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %struct: %C = struct_value (%.34, %.36) [template]
 // CHECK:STDOUT:   %MakeC.type: type = fn_type @MakeC [template]
 // CHECK:STDOUT:   %MakeC: %MakeC.type = struct_value () [template]
 // CHECK:STDOUT:   %MakeAdaptC.type: type = fn_type @MakeAdaptC [template]
@@ -338,17 +365,25 @@ var e: C = MakeAdaptC();
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc13_18: i32 = int_value 1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc13_26: i32 = int_value 2 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_27.1: %.2 = struct_literal (%.loc13_18, %.loc13_26)
-// CHECK:STDOUT:   %.loc13_27.2: ref %C = temporary_storage
-// CHECK:STDOUT:   %.loc13_27.3: ref i32 = class_element_access %.loc13_27.2, element0
-// CHECK:STDOUT:   %.loc13_27.4: init i32 = initialize_from %.loc13_18 to %.loc13_27.3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc13_27.5: ref i32 = class_element_access %.loc13_27.2, element1
-// CHECK:STDOUT:   %.loc13_27.6: init i32 = initialize_from %.loc13_26 to %.loc13_27.5 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_27.7: init %C = class_init (%.loc13_27.4, %.loc13_27.6), %.loc13_27.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_27.8: ref %C = temporary %.loc13_27.2, %.loc13_27.7
-// CHECK:STDOUT:   %.loc13_28.1: ref %C = converted %.loc13_27.1, %.loc13_27.8
+// CHECK:STDOUT:   %.loc13_18: Core.IntLiteral = int_value 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc13_26: Core.IntLiteral = int_value 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc13_27.1: %.8 = struct_literal (%.loc13_18, %.loc13_26)
+// CHECK:STDOUT:   %.loc13_27.2: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_27.3: <bound method> = bound_method %.loc13_18, %.loc13_27.2 [template = constants.%.33]
+// CHECK:STDOUT:   %int.convert_checked.loc13_27.1: init i32 = call %.loc13_27.3(%.loc13_18) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_27.4: init i32 = converted %.loc13_18, %int.convert_checked.loc13_27.1 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_27.5: ref %C = temporary_storage
+// CHECK:STDOUT:   %.loc13_27.6: ref i32 = class_element_access %.loc13_27.5, element0
+// CHECK:STDOUT:   %.loc13_27.7: init i32 = initialize_from %.loc13_27.4 to %.loc13_27.6 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_27.8: %Convert.type.2 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_27.9: <bound method> = bound_method %.loc13_26, %.loc13_27.8 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc13_27.2: init i32 = call %.loc13_27.9(%.loc13_26) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_27.10: init i32 = converted %.loc13_26, %int.convert_checked.loc13_27.2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_27.11: ref i32 = class_element_access %.loc13_27.5, element1
+// CHECK:STDOUT:   %.loc13_27.12: init i32 = initialize_from %.loc13_27.10 to %.loc13_27.11 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_27.13: init %C = class_init (%.loc13_27.7, %.loc13_27.12), %.loc13_27.5 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc13_27.14: ref %C = temporary %.loc13_27.5, %.loc13_27.13
+// CHECK:STDOUT:   %.loc13_28.1: ref %C = converted %.loc13_27.1, %.loc13_27.14
 // CHECK:STDOUT:   %.loc13_28.2: %C = bind_value %.loc13_28.1
 // CHECK:STDOUT:   %a: %C = bind_name a, %.loc13_28.2
 // CHECK:STDOUT:   %a.ref: %C = name_ref a, %a

+ 33 - 15
toolchain/check/testdata/class/init_as.carbon

@@ -28,14 +28,24 @@ fn F() -> i32 {
 // CHECK:STDOUT:   %.3: <witness> = complete_type_witness %.2 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %struct: %Class = struct_value (%.4, %.5) [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.6: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.31: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %struct: %Class = struct_value (%.33, %.35) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -80,18 +90,26 @@ fn F() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc17_17: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc17_25: i32 = int_value 2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc17_26.1: %.2 = struct_literal (%.loc17_17, %.loc17_25)
+// CHECK:STDOUT:   %.loc17_17: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc17_25: Core.IntLiteral = int_value 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_26.1: %.6 = struct_literal (%.loc17_17, %.loc17_25)
 // CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:   %.loc17_26.2: ref %Class = temporary_storage
-// CHECK:STDOUT:   %.loc17_26.3: ref i32 = class_element_access %.loc17_26.2, element0
-// CHECK:STDOUT:   %.loc17_26.4: init i32 = initialize_from %.loc17_17 to %.loc17_26.3 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc17_26.5: ref i32 = class_element_access %.loc17_26.2, element1
-// CHECK:STDOUT:   %.loc17_26.6: init i32 = initialize_from %.loc17_25 to %.loc17_26.5 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc17_26.7: init %Class = class_init (%.loc17_26.4, %.loc17_26.6), %.loc17_26.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc17_26.8: ref %Class = temporary %.loc17_26.2, %.loc17_26.7
-// CHECK:STDOUT:   %.loc17_28: ref %Class = converted %.loc17_26.1, %.loc17_26.8
+// CHECK:STDOUT:   %.loc17_26.2: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_26.3: <bound method> = bound_method %.loc17_17, %.loc17_26.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked.loc17_26.1: init i32 = call %.loc17_26.3(%.loc17_17) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc17_26.4: init i32 = converted %.loc17_17, %int.convert_checked.loc17_26.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc17_26.5: ref %Class = temporary_storage
+// CHECK:STDOUT:   %.loc17_26.6: ref i32 = class_element_access %.loc17_26.5, element0
+// CHECK:STDOUT:   %.loc17_26.7: init i32 = initialize_from %.loc17_26.4 to %.loc17_26.6 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc17_26.8: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_26.9: <bound method> = bound_method %.loc17_25, %.loc17_26.8 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked.loc17_26.2: init i32 = call %.loc17_26.9(%.loc17_25) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc17_26.10: init i32 = converted %.loc17_25, %int.convert_checked.loc17_26.2 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc17_26.11: ref i32 = class_element_access %.loc17_26.5, element1
+// CHECK:STDOUT:   %.loc17_26.12: init i32 = initialize_from %.loc17_26.10 to %.loc17_26.11 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc17_26.13: init %Class = class_init (%.loc17_26.7, %.loc17_26.12), %.loc17_26.5 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc17_26.14: ref %Class = temporary %.loc17_26.5, %.loc17_26.13
+// CHECK:STDOUT:   %.loc17_28: ref %Class = converted %.loc17_26.1, %.loc17_26.14
 // CHECK:STDOUT:   %a.ref: %.1 = name_ref a, @Class.%.loc12_8 [template = @Class.%.loc12_8]
 // CHECK:STDOUT:   %.loc17_37.1: ref i32 = class_element_access %.loc17_28, element0
 // CHECK:STDOUT:   %.loc17_37.2: i32 = bind_value %.loc17_37.1

+ 23 - 11
toolchain/check/testdata/class/method.carbon

@@ -78,8 +78,15 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:   %CallAlias: %CallAlias.type = struct_value () [template]
 // CHECK:STDOUT:   %CallOnConstBoundMethod.type: type = fn_type @CallOnConstBoundMethod [template]
 // CHECK:STDOUT:   %CallOnConstBoundMethod: %CallOnConstBoundMethod.type = struct_value () [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %struct: %Class = struct_value (%.6) [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.7: type = struct_type {.k: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.31: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.32: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %struct: %Class = struct_value (%.33) [template]
 // CHECK:STDOUT:   %CallWithAddr.type: type = fn_type @CallWithAddr [template]
 // CHECK:STDOUT:   %CallWithAddr: %CallWithAddr.type = struct_value () [template]
 // CHECK:STDOUT:   %CallFThroughPointer.type: type = fn_type @CallFThroughPointer [template]
@@ -96,7 +103,8 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -329,15 +337,19 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallOnConstBoundMethod() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc35_17: i32 = int_value 1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc35_18.1: %.3 = struct_literal (%.loc35_17)
+// CHECK:STDOUT:   %.loc35_17: Core.IntLiteral = int_value 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc35_18.1: %.7 = struct_literal (%.loc35_17)
 // CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:   %.loc35_18.2: ref %Class = temporary_storage
-// CHECK:STDOUT:   %.loc35_18.3: ref i32 = class_element_access %.loc35_18.2, element0
-// CHECK:STDOUT:   %.loc35_18.4: init i32 = initialize_from %.loc35_17 to %.loc35_18.3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc35_18.5: init %Class = class_init (%.loc35_18.4), %.loc35_18.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc35_18.6: ref %Class = temporary %.loc35_18.2, %.loc35_18.5
-// CHECK:STDOUT:   %.loc35_20.1: ref %Class = converted %.loc35_18.1, %.loc35_18.6
+// CHECK:STDOUT:   %.loc35_18.2: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc35_18.3: <bound method> = bound_method %.loc35_17, %.loc35_18.2 [template = constants.%.32]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc35_18.3(%.loc35_17) [template = constants.%.33]
+// CHECK:STDOUT:   %.loc35_18.4: init i32 = converted %.loc35_17, %int.convert_checked [template = constants.%.33]
+// CHECK:STDOUT:   %.loc35_18.5: ref %Class = temporary_storage
+// CHECK:STDOUT:   %.loc35_18.6: ref i32 = class_element_access %.loc35_18.5, element0
+// CHECK:STDOUT:   %.loc35_18.7: init i32 = initialize_from %.loc35_18.4 to %.loc35_18.6 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc35_18.8: init %Class = class_init (%.loc35_18.7), %.loc35_18.5 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc35_18.9: ref %Class = temporary %.loc35_18.5, %.loc35_18.8
+// CHECK:STDOUT:   %.loc35_20.1: ref %Class = converted %.loc35_18.1, %.loc35_18.9
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, @Class.%F.decl [template = constants.%F]
 // CHECK:STDOUT:   %.loc35_29: <bound method> = bound_method %.loc35_20.1, %F.ref
 // CHECK:STDOUT:   %.loc35_20.2: %Class = bind_value %.loc35_20.1

+ 16 - 4
toolchain/check/testdata/class/reorder.carbon

@@ -30,12 +30,19 @@ class Class {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -91,7 +98,12 @@ class Class {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc17: i32 = int_value 1 [template = constants.%.4]
-// CHECK:STDOUT:   return %.loc17
+// CHECK:STDOUT:   %.loc17_12: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc17_13.1: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_13.2: <bound method> = bound_method %.loc17_12, %.loc17_13.1 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc17_13.2(%.loc17_12) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_13.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.30]
+// CHECK:STDOUT:   %.loc17_13.4: i32 = converted %.loc17_12, %.loc17_13.3 [template = constants.%.30]
+// CHECK:STDOUT:   return %.loc17_13.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 66 - 33
toolchain/check/testdata/class/reorder_qualified.carbon

@@ -78,19 +78,36 @@ class A {
 // CHECK:STDOUT:   %.10: type = unbound_element_type %A, i32 [template]
 // CHECK:STDOUT:   %.11: type = struct_type {.a: i32} [template]
 // CHECK:STDOUT:   %.12: <witness> = complete_type_witness %.11 [template]
-// CHECK:STDOUT:   %.14: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %struct.1: %A = struct_value (%.14) [template]
-// CHECK:STDOUT:   %.16: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %struct.2: %B = struct_value (%.16) [template]
-// CHECK:STDOUT:   %.18: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %struct.3: %C = struct_value (%.18) [template]
-// CHECK:STDOUT:   %.20: i32 = int_value 4 [template]
-// CHECK:STDOUT:   %struct.4: %D = struct_value (%.20) [template]
+// CHECK:STDOUT:   %.14: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.15: type = struct_type {.a: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.39: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.40: <bound method> = bound_method %.14, %Convert.15 [template]
+// CHECK:STDOUT:   %.41: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %struct.1: %A = struct_value (%.41) [template]
+// CHECK:STDOUT:   %.43: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.44: type = struct_type {.b: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.45: <bound method> = bound_method %.43, %Convert.15 [template]
+// CHECK:STDOUT:   %.46: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %struct.2: %B = struct_value (%.46) [template]
+// CHECK:STDOUT:   %.48: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.49: type = struct_type {.c: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.50: <bound method> = bound_method %.48, %Convert.15 [template]
+// CHECK:STDOUT:   %.51: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %struct.3: %C = struct_value (%.51) [template]
+// CHECK:STDOUT:   %.53: Core.IntLiteral = int_value 4 [template]
+// CHECK:STDOUT:   %.54: type = struct_type {.d: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.55: <bound method> = bound_method %.53, %Convert.15 [template]
+// CHECK:STDOUT:   %.56: i32 = int_value 4 [template]
+// CHECK:STDOUT:   %struct.4: %D = struct_value (%.56) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -180,42 +197,58 @@ class A {
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
 // CHECK:STDOUT:   %a.var: ref %A = var a
 // CHECK:STDOUT:   %a: ref %A = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc29_24: i32 = int_value 1 [template = constants.%.14]
-// CHECK:STDOUT:   %.loc29_25.1: %.11 = struct_literal (%.loc29_24)
-// CHECK:STDOUT:   %.loc29_25.2: ref i32 = class_element_access %a.var, element0
-// CHECK:STDOUT:   %.loc29_25.3: init i32 = initialize_from %.loc29_24 to %.loc29_25.2 [template = constants.%.14]
-// CHECK:STDOUT:   %.loc29_25.4: init %A = class_init (%.loc29_25.3), %a.var [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc29_26: init %A = converted %.loc29_25.1, %.loc29_25.4 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc29_24: Core.IntLiteral = int_value 1 [template = constants.%.14]
+// CHECK:STDOUT:   %.loc29_25.1: %.15 = struct_literal (%.loc29_24)
+// CHECK:STDOUT:   %.loc29_25.2: %Convert.type.2 = interface_witness_access constants.%.39, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc29_25.3: <bound method> = bound_method %.loc29_24, %.loc29_25.2 [template = constants.%.40]
+// CHECK:STDOUT:   %int.convert_checked.loc29: init i32 = call %.loc29_25.3(%.loc29_24) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc29_25.4: init i32 = converted %.loc29_24, %int.convert_checked.loc29 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc29_25.5: ref i32 = class_element_access %a.var, element0
+// CHECK:STDOUT:   %.loc29_25.6: init i32 = initialize_from %.loc29_25.4 to %.loc29_25.5 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc29_25.7: init %A = class_init (%.loc29_25.6), %a.var [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc29_26: init %A = converted %.loc29_25.1, %.loc29_25.7 [template = constants.%struct.1]
 // CHECK:STDOUT:   assign %a.var, %.loc29_26
 // CHECK:STDOUT:   %B.ref: type = name_ref B, @A.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %b.var: ref %B = var b
 // CHECK:STDOUT:   %b: ref %B = bind_name b, %b.var
-// CHECK:STDOUT:   %.loc30_24: i32 = int_value 2 [template = constants.%.16]
-// CHECK:STDOUT:   %.loc30_25.1: %.2 = struct_literal (%.loc30_24)
-// CHECK:STDOUT:   %.loc30_25.2: ref i32 = class_element_access %b.var, element0
-// CHECK:STDOUT:   %.loc30_25.3: init i32 = initialize_from %.loc30_24 to %.loc30_25.2 [template = constants.%.16]
-// CHECK:STDOUT:   %.loc30_25.4: init %B = class_init (%.loc30_25.3), %b.var [template = constants.%struct.2]
-// CHECK:STDOUT:   %.loc30_26: init %B = converted %.loc30_25.1, %.loc30_25.4 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc30_24: Core.IntLiteral = int_value 2 [template = constants.%.43]
+// CHECK:STDOUT:   %.loc30_25.1: %.44 = struct_literal (%.loc30_24)
+// CHECK:STDOUT:   %.loc30_25.2: %Convert.type.2 = interface_witness_access constants.%.39, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc30_25.3: <bound method> = bound_method %.loc30_24, %.loc30_25.2 [template = constants.%.45]
+// CHECK:STDOUT:   %int.convert_checked.loc30: init i32 = call %.loc30_25.3(%.loc30_24) [template = constants.%.46]
+// CHECK:STDOUT:   %.loc30_25.4: init i32 = converted %.loc30_24, %int.convert_checked.loc30 [template = constants.%.46]
+// CHECK:STDOUT:   %.loc30_25.5: ref i32 = class_element_access %b.var, element0
+// CHECK:STDOUT:   %.loc30_25.6: init i32 = initialize_from %.loc30_25.4 to %.loc30_25.5 [template = constants.%.46]
+// CHECK:STDOUT:   %.loc30_25.7: init %B = class_init (%.loc30_25.6), %b.var [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc30_26: init %B = converted %.loc30_25.1, %.loc30_25.7 [template = constants.%struct.2]
 // CHECK:STDOUT:   assign %b.var, %.loc30_26
 // CHECK:STDOUT:   %C.ref: type = name_ref C, @B.%C.decl [template = constants.%C]
 // CHECK:STDOUT:   %c.var: ref %C = var c
 // CHECK:STDOUT:   %c: ref %C = bind_name c, %c.var
-// CHECK:STDOUT:   %.loc31_24: i32 = int_value 3 [template = constants.%.18]
-// CHECK:STDOUT:   %.loc31_25.1: %.8 = struct_literal (%.loc31_24)
-// CHECK:STDOUT:   %.loc31_25.2: ref i32 = class_element_access %c.var, element0
-// CHECK:STDOUT:   %.loc31_25.3: init i32 = initialize_from %.loc31_24 to %.loc31_25.2 [template = constants.%.18]
-// CHECK:STDOUT:   %.loc31_25.4: init %C = class_init (%.loc31_25.3), %c.var [template = constants.%struct.3]
-// CHECK:STDOUT:   %.loc31_26: init %C = converted %.loc31_25.1, %.loc31_25.4 [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc31_24: Core.IntLiteral = int_value 3 [template = constants.%.48]
+// CHECK:STDOUT:   %.loc31_25.1: %.49 = struct_literal (%.loc31_24)
+// CHECK:STDOUT:   %.loc31_25.2: %Convert.type.2 = interface_witness_access constants.%.39, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc31_25.3: <bound method> = bound_method %.loc31_24, %.loc31_25.2 [template = constants.%.50]
+// CHECK:STDOUT:   %int.convert_checked.loc31: init i32 = call %.loc31_25.3(%.loc31_24) [template = constants.%.51]
+// CHECK:STDOUT:   %.loc31_25.4: init i32 = converted %.loc31_24, %int.convert_checked.loc31 [template = constants.%.51]
+// CHECK:STDOUT:   %.loc31_25.5: ref i32 = class_element_access %c.var, element0
+// CHECK:STDOUT:   %.loc31_25.6: init i32 = initialize_from %.loc31_25.4 to %.loc31_25.5 [template = constants.%.51]
+// CHECK:STDOUT:   %.loc31_25.7: init %C = class_init (%.loc31_25.6), %c.var [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc31_26: init %C = converted %.loc31_25.1, %.loc31_25.7 [template = constants.%struct.3]
 // CHECK:STDOUT:   assign %c.var, %.loc31_26
 // CHECK:STDOUT:   %D.ref: type = name_ref D, @C.%D.decl [template = constants.%D]
 // CHECK:STDOUT:   %d.var: ref %D = var d
 // CHECK:STDOUT:   %d: ref %D = bind_name d, %d.var
-// CHECK:STDOUT:   %.loc32_24: i32 = int_value 4 [template = constants.%.20]
-// CHECK:STDOUT:   %.loc32_25.1: %.5 = struct_literal (%.loc32_24)
-// CHECK:STDOUT:   %.loc32_25.2: ref i32 = class_element_access %d.var, element0
-// CHECK:STDOUT:   %.loc32_25.3: init i32 = initialize_from %.loc32_24 to %.loc32_25.2 [template = constants.%.20]
-// CHECK:STDOUT:   %.loc32_25.4: init %D = class_init (%.loc32_25.3), %d.var [template = constants.%struct.4]
-// CHECK:STDOUT:   %.loc32_26: init %D = converted %.loc32_25.1, %.loc32_25.4 [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc32_24: Core.IntLiteral = int_value 4 [template = constants.%.53]
+// CHECK:STDOUT:   %.loc32_25.1: %.54 = struct_literal (%.loc32_24)
+// CHECK:STDOUT:   %.loc32_25.2: %Convert.type.2 = interface_witness_access constants.%.39, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc32_25.3: <bound method> = bound_method %.loc32_24, %.loc32_25.2 [template = constants.%.55]
+// CHECK:STDOUT:   %int.convert_checked.loc32: init i32 = call %.loc32_25.3(%.loc32_24) [template = constants.%.56]
+// CHECK:STDOUT:   %.loc32_25.4: init i32 = converted %.loc32_24, %int.convert_checked.loc32 [template = constants.%.56]
+// CHECK:STDOUT:   %.loc32_25.5: ref i32 = class_element_access %d.var, element0
+// CHECK:STDOUT:   %.loc32_25.6: init i32 = initialize_from %.loc32_25.4 to %.loc32_25.5 [template = constants.%.56]
+// CHECK:STDOUT:   %.loc32_25.7: init %D = class_init (%.loc32_25.6), %d.var [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc32_26: init %D = converted %.loc32_25.1, %.loc32_25.7 [template = constants.%struct.4]
 // CHECK:STDOUT:   assign %d.var, %.loc32_26
 // CHECK:STDOUT:   %AF.ref: %AF.type = name_ref AF, @A.%AF.decl [template = constants.%AF]
 // CHECK:STDOUT:   %AF.call: init %empty_tuple.type = call %AF.ref()

+ 26 - 7
toolchain/check/testdata/class/scope.carbon

@@ -39,17 +39,26 @@ fn Run() {
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
+// CHECK:STDOUT:   %.29: i32 = int_value 1 [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.30: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.30, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 2 [template]
 // CHECK:STDOUT:   %Run.type: type = fn_type @Run [template]
 // CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -108,8 +117,13 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.1() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc13: i32 = int_value 1 [template = constants.%.3]
-// CHECK:STDOUT:   return %.loc13
+// CHECK:STDOUT:   %.loc13_12: Core.IntLiteral = int_value 1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc13_13.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_13.2: <bound method> = bound_method %.loc13_12, %.loc13_13.1 [template = constants.%.28]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc13_13.2(%.loc13_12) [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_13.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_13.4: i32 = converted %.loc13_12, %.loc13_13.3 [template = constants.%.29]
+// CHECK:STDOUT:   return %.loc13_13.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
@@ -123,8 +137,13 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc22: i32 = int_value 2 [template = constants.%.4]
-// CHECK:STDOUT:   return %.loc22
+// CHECK:STDOUT:   %.loc22_10: Core.IntLiteral = int_value 2 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc22_11.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc22_11.2: <bound method> = bound_method %.loc22_10, %.loc22_11.1 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc22_11.2(%.loc22_10) [template = constants.%.32]
+// CHECK:STDOUT:   %.loc22_11.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.32]
+// CHECK:STDOUT:   %.loc22_11.4: i32 = converted %.loc22_10, %.loc22_11.3 [template = constants.%.32]
+// CHECK:STDOUT:   return %.loc22_11.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {

+ 25 - 14
toolchain/check/testdata/class/self_conversion.carbon

@@ -51,15 +51,22 @@ fn Call(p: Derived*) -> i32 {
 // CHECK:STDOUT:   %AddrSelfBase: %AddrSelfBase.type = struct_value () [template]
 // CHECK:STDOUT:   %.7: type = struct_type {.base: %Base} [template]
 // CHECK:STDOUT:   %.8: <witness> = complete_type_witness %.7 [template]
-// CHECK:STDOUT:   %.9: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.10: type = ptr_type %Derived [template]
+// CHECK:STDOUT:   %.9: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.33: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.34: <bound method> = bound_method %.9, %Convert.15 [template]
+// CHECK:STDOUT:   %.35: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.36: type = ptr_type %Derived [template]
 // CHECK:STDOUT:   %Call.type: type = fn_type @Call [template]
 // CHECK:STDOUT:   %Call: %Call.type = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -101,18 +108,18 @@ fn Call(p: Derived*) -> i32 {
 // CHECK:STDOUT:     %self.loc26: %.6 = bind_name self, %self.param.loc26
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Call.decl: %Call.type = fn_decl @Call [template = constants.%Call] {
-// CHECK:STDOUT:     %p.patt: %.10 = binding_pattern p
-// CHECK:STDOUT:     %p.param_patt: %.10 = value_param_pattern %p.patt, runtime_param0
+// CHECK:STDOUT:     %p.patt: %.36 = binding_pattern p
+// CHECK:STDOUT:     %p.param_patt: %.36 = value_param_pattern %p.patt, runtime_param0
 // CHECK:STDOUT:     %return.patt: i32 = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: i32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %Derived.ref: type = name_ref Derived, file.%Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT:     %.loc30_19: type = ptr_type %Derived [template = constants.%.10]
+// CHECK:STDOUT:     %.loc30_19: type = ptr_type %Derived [template = constants.%.36]
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc30_25.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc30_25.2: type = converted %int.make_type_32, %.loc30_25.1 [template = i32]
-// CHECK:STDOUT:     %p.param: %.10 = value_param runtime_param0
-// CHECK:STDOUT:     %p: %.10 = bind_name p, %p.param
+// CHECK:STDOUT:     %p.param: %.36 = value_param runtime_param0
+// CHECK:STDOUT:     %p: %.36 = bind_name p, %p.param
 // CHECK:STDOUT:     %return.param: ref i32 = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref i32 = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -183,24 +190,28 @@ fn Call(p: Derived*) -> i32 {
 // CHECK:STDOUT:   %.loc27_4: ref %Base = deref %self.ref
 // CHECK:STDOUT:   %a.ref: %.1 = name_ref a, @Base.%.loc12_8 [template = @Base.%.loc12_8]
 // CHECK:STDOUT:   %.loc27_10: ref i32 = class_element_access %.loc27_4, element0
-// CHECK:STDOUT:   %.loc27_15: i32 = int_value 1 [template = constants.%.9]
-// CHECK:STDOUT:   assign %.loc27_10, %.loc27_15
+// CHECK:STDOUT:   %.loc27_15: Core.IntLiteral = int_value 1 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc27_13.1: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc27_13.2: <bound method> = bound_method %.loc27_15, %.loc27_13.1 [template = constants.%.34]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc27_13.2(%.loc27_15) [template = constants.%.35]
+// CHECK:STDOUT:   %.loc27_13.3: init i32 = converted %.loc27_15, %int.convert_checked [template = constants.%.35]
+// CHECK:STDOUT:   assign %.loc27_10, %.loc27_13.3
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Call(%p.param_patt: %.10) -> i32 {
+// CHECK:STDOUT: fn @Call(%p.param_patt: %.36) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %p.ref.loc31: %.10 = name_ref p, %p
+// CHECK:STDOUT:   %p.ref.loc31: %.36 = name_ref p, %p
 // CHECK:STDOUT:   %.loc31_4.1: ref %Derived = deref %p.ref.loc31
 // CHECK:STDOUT:   %AddrSelfBase.ref: %AddrSelfBase.type = name_ref AddrSelfBase, @Derived.%AddrSelfBase.decl [template = constants.%AddrSelfBase]
 // CHECK:STDOUT:   %.loc31_7: <bound method> = bound_method %.loc31_4.1, %AddrSelfBase.ref
-// CHECK:STDOUT:   %.loc31_4.2: %.10 = addr_of %.loc31_4.1
+// CHECK:STDOUT:   %.loc31_4.2: %.36 = addr_of %.loc31_4.1
 // CHECK:STDOUT:   %.loc31_4.3: ref %Derived = deref %.loc31_4.2
 // CHECK:STDOUT:   %.loc31_4.4: ref %Base = class_element_access %.loc31_4.3, element0
 // CHECK:STDOUT:   %.loc31_4.5: %.6 = addr_of %.loc31_4.4
 // CHECK:STDOUT:   %.loc31_4.6: %.6 = converted %.loc31_4.2, %.loc31_4.5
 // CHECK:STDOUT:   %AddrSelfBase.call: init %empty_tuple.type = call %.loc31_7(%.loc31_4.6)
-// CHECK:STDOUT:   %p.ref.loc32: %.10 = name_ref p, %p
+// CHECK:STDOUT:   %p.ref.loc32: %.36 = name_ref p, %p
 // CHECK:STDOUT:   %.loc32_11.1: ref %Derived = deref %p.ref.loc32
 // CHECK:STDOUT:   %SelfBase.ref: %SelfBase.type = name_ref SelfBase, @Derived.%SelfBase.decl [template = constants.%SelfBase]
 // CHECK:STDOUT:   %.loc32_14: <bound method> = bound_method %.loc32_11.1, %SelfBase.ref

+ 58 - 24
toolchain/check/testdata/class/syntactic_merge_literal.carbon

@@ -40,8 +40,14 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:   %C.2: type = class_type @C, @C(%a) [symbolic]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1000 [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, @C(%.3) [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 1000 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
+// CHECK:STDOUT:   %.29: i32 = int_value 1000 [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, @C(%.29) [template]
 // CHECK:STDOUT:   %b: %C.3 = bind_symbolic_name b, 0 [symbolic]
 // CHECK:STDOUT:   %b.patt: %C.3 = symbolic_binding_pattern b, 0 [symbolic]
 // CHECK:STDOUT:   %D.type: type = generic_class_type @D [template]
@@ -51,7 +57,8 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -79,8 +86,13 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:     %b.param_patt: %C.3 = value_param_pattern %b.patt.loc4, runtime_param<invalid> [symbolic = constants.%b.patt]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %C.ref.loc3: %C.type = name_ref C, file.%C.decl [template = constants.%C.1]
-// CHECK:STDOUT:     %.loc3: i32 = int_value 1000 [template = constants.%.3]
-// CHECK:STDOUT:     %C.loc3: type = class_type @C, @C(constants.%.3) [template = constants.%C.3]
+// CHECK:STDOUT:     %.loc3_15: Core.IntLiteral = int_value 1000 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc3_14.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc3_14.2: <bound method> = bound_method %.loc3_15, %.loc3_14.1 [template = constants.%.28]
+// CHECK:STDOUT:     %int.convert_checked.loc3: init i32 = call %.loc3_14.2(%.loc3_15) [template = constants.%.29]
+// CHECK:STDOUT:     %.loc3_14.3: i32 = value_of_initializer %int.convert_checked.loc3 [template = constants.%.29]
+// CHECK:STDOUT:     %.loc3_14.4: i32 = converted %.loc3_15, %.loc3_14.3 [template = constants.%.29]
+// CHECK:STDOUT:     %C.loc3: type = class_type @C, @C(constants.%.29) [template = constants.%C.3]
 // CHECK:STDOUT:     %b.param.loc3: %C.3 = value_param runtime_param<invalid>
 // CHECK:STDOUT:     %b.loc3_9.1: %C.3 = bind_symbolic_name b, 0, %b.param.loc3 [symbolic = %b.loc3_9.2 (constants.%b)]
 // CHECK:STDOUT:   }
@@ -89,8 +101,13 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:     %b.param_patt: %C.3 = value_param_pattern %b.patt.loc4, runtime_param<invalid> [symbolic = constants.%b.patt]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %C.ref.loc4: %C.type = name_ref C, file.%C.decl [template = constants.%C.1]
-// CHECK:STDOUT:     %.loc4_15: i32 = int_value 1000 [template = constants.%.3]
-// CHECK:STDOUT:     %C.loc4: type = class_type @C, @C(constants.%.3) [template = constants.%C.3]
+// CHECK:STDOUT:     %.loc4_15: Core.IntLiteral = int_value 1000 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc4_14.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc4_14.2: <bound method> = bound_method %.loc4_15, %.loc4_14.1 [template = constants.%.28]
+// CHECK:STDOUT:     %int.convert_checked.loc4: init i32 = call %.loc4_14.2(%.loc4_15) [template = constants.%.29]
+// CHECK:STDOUT:     %.loc4_14.3: i32 = value_of_initializer %int.convert_checked.loc4 [template = constants.%.29]
+// CHECK:STDOUT:     %.loc4_14.4: i32 = converted %.loc4_15, %.loc4_14.3 [template = constants.%.29]
+// CHECK:STDOUT:     %C.loc4: type = class_type @C, @C(constants.%.29) [template = constants.%C.3]
 // CHECK:STDOUT:     %b.param.loc4: %C.3 = value_param runtime_param<invalid>
 // CHECK:STDOUT:     %b.loc4: %C.3 = bind_symbolic_name b, 0, %b.param.loc4 [symbolic = constants.%b]
 // CHECK:STDOUT:   }
@@ -129,9 +146,9 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:   %a.patt.loc2_9.2 => constants.%a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @C(constants.%.3) {
-// CHECK:STDOUT:   %a.loc2_9.2 => constants.%.3
-// CHECK:STDOUT:   %a.patt.loc2_9.2 => constants.%.3
+// CHECK:STDOUT: specific @C(constants.%.29) {
+// CHECK:STDOUT:   %a.loc2_9.2 => constants.%.29
+// CHECK:STDOUT:   %a.patt.loc2_9.2 => constants.%.29
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @D(constants.%b) {
@@ -151,20 +168,27 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:   %C.2: type = class_type @C, @C(%a) [symbolic]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 1000 [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, @C(%.3) [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 1000 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
+// CHECK:STDOUT:   %.29: i32 = int_value 1000 [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, @C(%.29) [template]
 // CHECK:STDOUT:   %b: %C.3 = bind_symbolic_name b, 0 [symbolic]
 // CHECK:STDOUT:   %b.patt: %C.3 = symbolic_binding_pattern b, 0 [symbolic]
 // CHECK:STDOUT:   %D.type: type = generic_class_type @D [template]
 // CHECK:STDOUT:   %D.1: %D.type = struct_value () [template]
 // CHECK:STDOUT:   %.type: type = generic_class_type @.1 [template]
-// CHECK:STDOUT:   %.4: %.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = class_type @.1, @.1(%b) [symbolic]
+// CHECK:STDOUT:   %.30: %.type = struct_value () [template]
+// CHECK:STDOUT:   %.31: type = class_type @.1, @.1(%b) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -192,18 +216,28 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:     %b.param_patt: %C.3 = value_param_pattern %b.patt.loc3_9.1, runtime_param<invalid> [symbolic = %b.patt.loc3_9.2 (constants.%b.patt)]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1]
-// CHECK:STDOUT:     %.loc3: i32 = int_value 1000 [template = constants.%.3]
-// CHECK:STDOUT:     %C: type = class_type @C, @C(constants.%.3) [template = constants.%C.3]
+// CHECK:STDOUT:     %.loc3_15: Core.IntLiteral = int_value 1000 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc3_14.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc3_14.2: <bound method> = bound_method %.loc3_15, %.loc3_14.1 [template = constants.%.28]
+// CHECK:STDOUT:     %int.convert_checked: init i32 = call %.loc3_14.2(%.loc3_15) [template = constants.%.29]
+// CHECK:STDOUT:     %.loc3_14.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.29]
+// CHECK:STDOUT:     %.loc3_14.4: i32 = converted %.loc3_15, %.loc3_14.3 [template = constants.%.29]
+// CHECK:STDOUT:     %C: type = class_type @C, @C(constants.%.29) [template = constants.%C.3]
 // CHECK:STDOUT:     %b.param: %C.3 = value_param runtime_param<invalid>
 // CHECK:STDOUT:     %b.loc3_9.1: %C.3 = bind_symbolic_name b, 0, %b.param [symbolic = %b.loc3_9.2 (constants.%b)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.decl: %.type = class_decl @.1 [template = constants.%.4] {
+// CHECK:STDOUT:   %.decl: %.type = class_decl @.1 [template = constants.%.30] {
 // CHECK:STDOUT:     %b.patt.loc10_9.1: %C.3 = symbolic_binding_pattern b, 0 [symbolic = %b.patt.loc10_9.2 (constants.%b.patt)]
 // CHECK:STDOUT:     %b.param_patt: %C.3 = value_param_pattern %b.patt.loc10_9.1, runtime_param<invalid> [symbolic = %b.patt.loc10_9.2 (constants.%b.patt)]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %C.ref: %C.type = name_ref C, file.%C.decl [template = constants.%C.1]
-// CHECK:STDOUT:     %.loc10_15: i32 = int_value 1000 [template = constants.%.3]
-// CHECK:STDOUT:     %C: type = class_type @C, @C(constants.%.3) [template = constants.%C.3]
+// CHECK:STDOUT:     %.loc10_15: Core.IntLiteral = int_value 1000 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc10_14.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc10_14.2: <bound method> = bound_method %.loc10_15, %.loc10_14.1 [template = constants.%.28]
+// CHECK:STDOUT:     %int.convert_checked: init i32 = call %.loc10_14.2(%.loc10_15) [template = constants.%.29]
+// CHECK:STDOUT:     %.loc10_14.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.29]
+// CHECK:STDOUT:     %.loc10_14.4: i32 = converted %.loc10_15, %.loc10_14.3 [template = constants.%.29]
+// CHECK:STDOUT:     %C: type = class_type @C, @C(constants.%.29) [template = constants.%C.3]
 // CHECK:STDOUT:     %b.param: %C.3 = value_param runtime_param<invalid>
 // CHECK:STDOUT:     %b.loc10_9.1: %C.3 = bind_symbolic_name b, 0, %b.param [symbolic = %b.loc10_9.2 (constants.%b)]
 // CHECK:STDOUT:   }
@@ -240,7 +274,7 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:     %.loc10_24: <witness> = complete_type_witness %.1 [template = constants.%.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     .Self = constants.%.5
+// CHECK:STDOUT:     .Self = constants.%.31
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -249,9 +283,9 @@ class D(b:! C(1_000)) {}
 // CHECK:STDOUT:   %a.patt.loc2_9.2 => constants.%a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @C(constants.%.3) {
-// CHECK:STDOUT:   %a.loc2_9.2 => constants.%.3
-// CHECK:STDOUT:   %a.patt.loc2_9.2 => constants.%.3
+// CHECK:STDOUT: specific @C(constants.%.29) {
+// CHECK:STDOUT:   %a.loc2_9.2 => constants.%.29
+// CHECK:STDOUT:   %a.patt.loc2_9.2 => constants.%.29
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @D(constants.%b) {

+ 122 - 154
toolchain/check/testdata/deduce/array.carbon

@@ -105,20 +105,20 @@ fn G() -> C {
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
-// CHECK:STDOUT:   %.3: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, %T [symbolic]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.4: type = array_type %.3, %T [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.30: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.6, %Convert.15 [template]
 // CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.34: type = array_type %.29, %C [template]
+// CHECK:STDOUT:   %.34: type = array_type %.3, %C [template]
 // CHECK:STDOUT:   %tuple.type: type = tuple_type (%.1, %.1, %.1) [template]
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
 // CHECK:STDOUT:   %.36: i32 = int_value 1 [template]
@@ -147,24 +147,19 @@ fn G() -> C {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.patt.loc6_6.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)]
 // CHECK:STDOUT:     %T.param_patt: type = value_param_pattern %T.patt.loc6_6.1, runtime_param<invalid> [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)]
-// CHECK:STDOUT:     %a.patt: @F.%.loc6_24.2 (%.30) = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: @F.%.loc6_24.2 (%.30) = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %a.patt: @F.%.loc6_24.2 (%.4) = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: @F.%.loc6_24.2 (%.4) = value_param_pattern %a.patt, runtime_param0
 // CHECK:STDOUT:     %return.patt: @F.%T.loc6_6.2 (%T) = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: @F.%T.loc6_6.2 (%T) = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %T.ref.loc6_20: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
-// CHECK:STDOUT:     %.loc6_23.1: i32 = int_value 3 [template = constants.%.3]
-// CHECK:STDOUT:     %.loc6_23.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:     %.loc6_23.3: <bound method> = bound_method %.loc6_23.1, %.loc6_23.2 [template = constants.%.28]
-// CHECK:STDOUT:     %int.convert_checked: init Core.IntLiteral = call %.loc6_23.3(%.loc6_23.1) [template = constants.%.29]
-// CHECK:STDOUT:     %.loc6_23.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.29]
-// CHECK:STDOUT:     %.loc6_23.5: Core.IntLiteral = converted %.loc6_23.1, %.loc6_23.4 [template = constants.%.29]
-// CHECK:STDOUT:     %.loc6_24.1: type = array_type %.loc6_23.5, %T [symbolic = %.loc6_24.2 (constants.%.30)]
+// CHECK:STDOUT:     %.loc6_23: Core.IntLiteral = int_value 3 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_24.1: type = array_type %.loc6_23, %T [symbolic = %.loc6_24.2 (constants.%.4)]
 // CHECK:STDOUT:     %T.ref.loc6_30: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
 // CHECK:STDOUT:     %T.param: type = value_param runtime_param<invalid>
 // CHECK:STDOUT:     %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)]
-// CHECK:STDOUT:     %a.param: @F.%.loc6_24.2 (%.30) = value_param runtime_param0
-// CHECK:STDOUT:     %a: @F.%.loc6_24.2 (%.30) = bind_name a, %a.param
+// CHECK:STDOUT:     %a.param: @F.%.loc6_24.2 (%.4) = value_param runtime_param0
+// CHECK:STDOUT:     %a: @F.%.loc6_24.2 (%.4) = bind_name a, %a.param
 // CHECK:STDOUT:     %return.param: ref @F.%T.loc6_6.2 (%T) = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref @F.%T.loc6_6.2 (%T) = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -188,16 +183,21 @@ fn G() -> C {
 // CHECK:STDOUT: generic fn @F(%T.loc6_6.1: type) {
 // CHECK:STDOUT:   %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc6_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)]
-// CHECK:STDOUT:   %.loc6_24.2: type = array_type constants.%.29, @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_24.2 (constants.%.30)]
+// CHECK:STDOUT:   %.loc6_24.2: type = array_type constants.%.3, @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_24.2 (constants.%.4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn[%T.param_patt: type](%a.param_patt: @F.%.loc6_24.2 (%.30)) -> @F.%T.loc6_6.2 (%T) {
+// CHECK:STDOUT:   fn[%T.param_patt: type](%a.param_patt: @F.%.loc6_24.2 (%.4)) -> @F.%T.loc6_6.2 (%T) {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %a.ref: @F.%.loc6_24.2 (%.30) = name_ref a, %a
-// CHECK:STDOUT:     %.loc6_43: i32 = int_value 0 [template = constants.%.32]
-// CHECK:STDOUT:     %.loc6_44.1: ref @F.%.loc6_24.2 (%.30) = value_as_ref %a.ref
-// CHECK:STDOUT:     %.loc6_44.2: ref @F.%T.loc6_6.2 (%T) = array_index %.loc6_44.1, %.loc6_43
+// CHECK:STDOUT:     %a.ref: @F.%.loc6_24.2 (%.4) = name_ref a, %a
+// CHECK:STDOUT:     %.loc6_43.1: Core.IntLiteral = int_value 0 [template = constants.%.6]
+// CHECK:STDOUT:     %.loc6_43.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc6_43.3: <bound method> = bound_method %.loc6_43.1, %.loc6_43.2 [template = constants.%.31]
+// CHECK:STDOUT:     %int.convert_checked: init i32 = call %.loc6_43.3(%.loc6_43.1) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc6_43.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.32]
+// CHECK:STDOUT:     %.loc6_43.5: i32 = converted %.loc6_43.1, %.loc6_43.4 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc6_44.1: ref @F.%.loc6_24.2 (%.4) = value_as_ref %a.ref
+// CHECK:STDOUT:     %.loc6_44.2: ref @F.%T.loc6_6.2 (%T) = array_index %.loc6_44.1, %.loc6_43.5
 // CHECK:STDOUT:     %.loc6_44.3: @F.%T.loc6_6.2 (%T) = bind_value %.loc6_44.2
 // CHECK:STDOUT:     return %.loc6_44.3
 // CHECK:STDOUT:   }
@@ -206,13 +206,8 @@ fn G() -> C {
 // CHECK:STDOUT: fn @G() -> %return: %C {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc9: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %.loc9_14.1: i32 = int_value 3 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc9_14.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc9_14.3: <bound method> = bound_method %.loc9_14.1, %.loc9_14.2 [template = constants.%.28]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc9_14.3(%.loc9_14.1) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc9_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.29]
-// CHECK:STDOUT:   %.loc9_14.5: Core.IntLiteral = converted %.loc9_14.1, %.loc9_14.4 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc9_15: type = array_type %.loc9_14.5, %C [template = constants.%.34]
+// CHECK:STDOUT:   %.loc9_14: Core.IntLiteral = int_value 3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_15: type = array_type %.loc9_14, %C [template = constants.%.34]
 // CHECK:STDOUT:   %a.var: ref %.34 = var a
 // CHECK:STDOUT:   %a: ref %.34 = bind_name a, %a.var
 // CHECK:STDOUT:   %.loc9_21.1: %.1 = struct_literal ()
@@ -246,7 +241,7 @@ fn G() -> C {
 // CHECK:STDOUT: specific @F(constants.%T) {
 // CHECK:STDOUT:   %T.loc6_6.2 => constants.%T
 // CHECK:STDOUT:   %T.patt.loc6_6.2 => constants.%T
-// CHECK:STDOUT:   %.loc6_24.2 => constants.%.30
+// CHECK:STDOUT:   %.loc6_24.2 => constants.%.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%C) {
@@ -277,16 +272,14 @@ fn G() -> C {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.29: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
-// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.32: type = array_type %.31, %C [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.30: type = array_type %.29, %C [template]
 // CHECK:STDOUT:   %tuple.type: type = tuple_type (%.1, %.1, %.1) [template]
-// CHECK:STDOUT:   %.34: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
-// CHECK:STDOUT:   %.35: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %array: %.32 = tuple_value (%struct, %struct, %struct) [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %array: %.30 = tuple_value (%struct, %struct, %struct) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -371,36 +364,31 @@ fn G() -> C {
 // CHECK:STDOUT: fn @G() -> %return: %C {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc13: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %.loc13_14.1: i32 = int_value 3 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc13_14.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc13_14.3: <bound method> = bound_method %.loc13_14.1, %.loc13_14.2 [template = constants.%.30]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc13_14.3(%.loc13_14.1) [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_14.5: Core.IntLiteral = converted %.loc13_14.1, %.loc13_14.4 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_15: type = array_type %.loc13_14.5, %C [template = constants.%.32]
-// CHECK:STDOUT:   %a.var: ref %.32 = var a
-// CHECK:STDOUT:   %a: ref %.32 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc13_14: Core.IntLiteral = int_value 3 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_15: type = array_type %.loc13_14, %C [template = constants.%.30]
+// CHECK:STDOUT:   %a.var: ref %.30 = var a
+// CHECK:STDOUT:   %a: ref %.30 = bind_name a, %a.var
 // CHECK:STDOUT:   %.loc13_21.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_25.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_29.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_30.1: %tuple.type = tuple_literal (%.loc13_21.1, %.loc13_25.1, %.loc13_29.1)
-// CHECK:STDOUT:   %.loc13_30.2: i32 = int_value 0 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_30.2: i32 = int_value 0 [template = constants.%.32]
 // CHECK:STDOUT:   %.loc13_30.3: ref %C = array_index %a.var, %.loc13_30.2
 // CHECK:STDOUT:   %.loc13_21.2: init %C = class_init (), %.loc13_30.3 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.4: init %C = converted %.loc13_21.1, %.loc13_21.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.5: i32 = int_value 1 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc13_30.5: i32 = int_value 1 [template = constants.%.33]
 // CHECK:STDOUT:   %.loc13_30.6: ref %C = array_index %a.var, %.loc13_30.5
 // CHECK:STDOUT:   %.loc13_25.2: init %C = class_init (), %.loc13_30.6 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.7: init %C = converted %.loc13_25.1, %.loc13_25.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.8: i32 = int_value 2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_30.8: i32 = int_value 2 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc13_30.9: ref %C = array_index %a.var, %.loc13_30.8
 // CHECK:STDOUT:   %.loc13_29.2: init %C = class_init (), %.loc13_30.9 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.10: init %C = converted %.loc13_29.1, %.loc13_29.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.11: init %.32 = array_init (%.loc13_30.4, %.loc13_30.7, %.loc13_30.10) to %a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc13_31: init %.32 = converted %.loc13_30.1, %.loc13_30.11 [template = constants.%array]
+// CHECK:STDOUT:   %.loc13_30.11: init %.30 = array_init (%.loc13_30.4, %.loc13_30.7, %.loc13_30.10) to %a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc13_31: init %.30 = converted %.loc13_30.1, %.loc13_30.11 [template = constants.%array]
 // CHECK:STDOUT:   assign %a.var, %.loc13_31
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %a.ref: ref %.32 = name_ref a, %a
+// CHECK:STDOUT:   %a.ref: ref %.30 = name_ref a, %a
 // CHECK:STDOUT:   return <error> to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -433,16 +421,14 @@ fn G() -> C {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.29: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
-// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.32: type = array_type %.31, %C [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.30: type = array_type %.29, %C [template]
 // CHECK:STDOUT:   %tuple.type: type = tuple_type (%.1, %.1, %.1) [template]
-// CHECK:STDOUT:   %.34: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
-// CHECK:STDOUT:   %.35: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %array: %.32 = tuple_value (%struct, %struct, %struct) [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %array: %.30 = tuple_value (%struct, %struct, %struct) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -525,36 +511,31 @@ fn G() -> C {
 // CHECK:STDOUT: fn @G() -> %return: %C {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc13: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %.loc13_14.1: i32 = int_value 3 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc13_14.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc13_14.3: <bound method> = bound_method %.loc13_14.1, %.loc13_14.2 [template = constants.%.30]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc13_14.3(%.loc13_14.1) [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_14.5: Core.IntLiteral = converted %.loc13_14.1, %.loc13_14.4 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_15: type = array_type %.loc13_14.5, %C [template = constants.%.32]
-// CHECK:STDOUT:   %a.var: ref %.32 = var a
-// CHECK:STDOUT:   %a: ref %.32 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc13_14: Core.IntLiteral = int_value 3 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_15: type = array_type %.loc13_14, %C [template = constants.%.30]
+// CHECK:STDOUT:   %a.var: ref %.30 = var a
+// CHECK:STDOUT:   %a: ref %.30 = bind_name a, %a.var
 // CHECK:STDOUT:   %.loc13_21.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_25.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_29.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_30.1: %tuple.type = tuple_literal (%.loc13_21.1, %.loc13_25.1, %.loc13_29.1)
-// CHECK:STDOUT:   %.loc13_30.2: i32 = int_value 0 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_30.2: i32 = int_value 0 [template = constants.%.32]
 // CHECK:STDOUT:   %.loc13_30.3: ref %C = array_index %a.var, %.loc13_30.2
 // CHECK:STDOUT:   %.loc13_21.2: init %C = class_init (), %.loc13_30.3 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.4: init %C = converted %.loc13_21.1, %.loc13_21.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.5: i32 = int_value 1 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc13_30.5: i32 = int_value 1 [template = constants.%.33]
 // CHECK:STDOUT:   %.loc13_30.6: ref %C = array_index %a.var, %.loc13_30.5
 // CHECK:STDOUT:   %.loc13_25.2: init %C = class_init (), %.loc13_30.6 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.7: init %C = converted %.loc13_25.1, %.loc13_25.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.8: i32 = int_value 2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_30.8: i32 = int_value 2 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc13_30.9: ref %C = array_index %a.var, %.loc13_30.8
 // CHECK:STDOUT:   %.loc13_29.2: init %C = class_init (), %.loc13_30.9 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.10: init %C = converted %.loc13_29.1, %.loc13_29.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.11: init %.32 = array_init (%.loc13_30.4, %.loc13_30.7, %.loc13_30.10) to %a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc13_31: init %.32 = converted %.loc13_30.1, %.loc13_30.11 [template = constants.%array]
+// CHECK:STDOUT:   %.loc13_30.11: init %.30 = array_init (%.loc13_30.4, %.loc13_30.7, %.loc13_30.10) to %a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc13_31: init %.30 = converted %.loc13_30.1, %.loc13_30.11 [template = constants.%array]
 // CHECK:STDOUT:   assign %a.var, %.loc13_31
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %a.ref: ref %.32 = name_ref a, %a
+// CHECK:STDOUT:   %a.ref: ref %.30 = name_ref a, %a
 // CHECK:STDOUT:   return <error> to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -575,29 +556,28 @@ fn G() -> C {
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
-// CHECK:STDOUT:   %.3: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 2 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, %T [symbolic]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.4: type = array_type %.3, %T [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.30: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.6, %Convert.15 [template]
 // CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.34: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.35: <bound method> = bound_method %.34, %Convert.15 [template]
-// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.37: type = array_type %.36, %C [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, %C [template]
 // CHECK:STDOUT:   %tuple.type: type = tuple_type (%.1, %.1, %.1) [template]
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
-// CHECK:STDOUT:   %.39: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %array: %.37 = tuple_value (%struct, %struct, %struct) [template]
-// CHECK:STDOUT:   %.40: type = array_type %.29, %C [template]
-// CHECK:STDOUT:   %.41: <specific function> = specific_function %F, @F(%C) [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %array: %.35 = tuple_value (%struct, %struct, %struct) [template]
+// CHECK:STDOUT:   %.39: type = array_type %.3, %C [template]
+// CHECK:STDOUT:   %.40: <specific function> = specific_function %F, @F(%C) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -620,24 +600,19 @@ fn G() -> C {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.patt.loc6_6.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)]
 // CHECK:STDOUT:     %T.param_patt: type = value_param_pattern %T.patt.loc6_6.1, runtime_param<invalid> [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)]
-// CHECK:STDOUT:     %a.patt: @F.%.loc6_24.2 (%.30) = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: @F.%.loc6_24.2 (%.30) = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %a.patt: @F.%.loc6_24.2 (%.4) = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: @F.%.loc6_24.2 (%.4) = value_param_pattern %a.patt, runtime_param0
 // CHECK:STDOUT:     %return.patt: @F.%T.loc6_6.2 (%T) = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: @F.%T.loc6_6.2 (%T) = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %T.ref.loc6_20: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
-// CHECK:STDOUT:     %.loc6_23.1: i32 = int_value 2 [template = constants.%.3]
-// CHECK:STDOUT:     %.loc6_23.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:     %.loc6_23.3: <bound method> = bound_method %.loc6_23.1, %.loc6_23.2 [template = constants.%.28]
-// CHECK:STDOUT:     %int.convert_checked: init Core.IntLiteral = call %.loc6_23.3(%.loc6_23.1) [template = constants.%.29]
-// CHECK:STDOUT:     %.loc6_23.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.29]
-// CHECK:STDOUT:     %.loc6_23.5: Core.IntLiteral = converted %.loc6_23.1, %.loc6_23.4 [template = constants.%.29]
-// CHECK:STDOUT:     %.loc6_24.1: type = array_type %.loc6_23.5, %T [symbolic = %.loc6_24.2 (constants.%.30)]
+// CHECK:STDOUT:     %.loc6_23: Core.IntLiteral = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_24.1: type = array_type %.loc6_23, %T [symbolic = %.loc6_24.2 (constants.%.4)]
 // CHECK:STDOUT:     %T.ref.loc6_30: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
 // CHECK:STDOUT:     %T.param: type = value_param runtime_param<invalid>
 // CHECK:STDOUT:     %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)]
-// CHECK:STDOUT:     %a.param: @F.%.loc6_24.2 (%.30) = value_param runtime_param0
-// CHECK:STDOUT:     %a: @F.%.loc6_24.2 (%.30) = bind_name a, %a.param
+// CHECK:STDOUT:     %a.param: @F.%.loc6_24.2 (%.4) = value_param runtime_param0
+// CHECK:STDOUT:     %a: @F.%.loc6_24.2 (%.4) = bind_name a, %a.param
 // CHECK:STDOUT:     %return.param: ref @F.%T.loc6_6.2 (%T) = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref @F.%T.loc6_6.2 (%T) = return_slot %return.param
 // CHECK:STDOUT:   }
@@ -661,16 +636,21 @@ fn G() -> C {
 // CHECK:STDOUT: generic fn @F(%T.loc6_6.1: type) {
 // CHECK:STDOUT:   %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc6_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)]
-// CHECK:STDOUT:   %.loc6_24.2: type = array_type constants.%.29, @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_24.2 (constants.%.30)]
+// CHECK:STDOUT:   %.loc6_24.2: type = array_type constants.%.3, @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_24.2 (constants.%.4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn[%T.param_patt: type](%a.param_patt: @F.%.loc6_24.2 (%.30)) -> @F.%T.loc6_6.2 (%T) {
+// CHECK:STDOUT:   fn[%T.param_patt: type](%a.param_patt: @F.%.loc6_24.2 (%.4)) -> @F.%T.loc6_6.2 (%T) {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %a.ref: @F.%.loc6_24.2 (%.30) = name_ref a, %a
-// CHECK:STDOUT:     %.loc6_43: i32 = int_value 0 [template = constants.%.32]
-// CHECK:STDOUT:     %.loc6_44.1: ref @F.%.loc6_24.2 (%.30) = value_as_ref %a.ref
-// CHECK:STDOUT:     %.loc6_44.2: ref @F.%T.loc6_6.2 (%T) = array_index %.loc6_44.1, %.loc6_43
+// CHECK:STDOUT:     %a.ref: @F.%.loc6_24.2 (%.4) = name_ref a, %a
+// CHECK:STDOUT:     %.loc6_43.1: Core.IntLiteral = int_value 0 [template = constants.%.6]
+// CHECK:STDOUT:     %.loc6_43.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc6_43.3: <bound method> = bound_method %.loc6_43.1, %.loc6_43.2 [template = constants.%.31]
+// CHECK:STDOUT:     %int.convert_checked: init i32 = call %.loc6_43.3(%.loc6_43.1) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc6_43.4: i32 = value_of_initializer %int.convert_checked [template = constants.%.32]
+// CHECK:STDOUT:     %.loc6_43.5: i32 = converted %.loc6_43.1, %.loc6_43.4 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc6_44.1: ref @F.%.loc6_24.2 (%.4) = value_as_ref %a.ref
+// CHECK:STDOUT:     %.loc6_44.2: ref @F.%T.loc6_6.2 (%T) = array_index %.loc6_44.1, %.loc6_43.5
 // CHECK:STDOUT:     %.loc6_44.3: @F.%T.loc6_6.2 (%T) = bind_value %.loc6_44.2
 // CHECK:STDOUT:     return %.loc6_44.3
 // CHECK:STDOUT:   }
@@ -679,15 +659,10 @@ fn G() -> C {
 // CHECK:STDOUT: fn @G() -> %return: %C {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc10: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %.loc10_14.1: i32 = int_value 3 [template = constants.%.34]
-// CHECK:STDOUT:   %.loc10_14.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc10_14.3: <bound method> = bound_method %.loc10_14.1, %.loc10_14.2 [template = constants.%.35]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc10_14.3(%.loc10_14.1) [template = constants.%.36]
-// CHECK:STDOUT:   %.loc10_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.36]
-// CHECK:STDOUT:   %.loc10_14.5: Core.IntLiteral = converted %.loc10_14.1, %.loc10_14.4 [template = constants.%.36]
-// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14.5, %C [template = constants.%.37]
-// CHECK:STDOUT:   %a.var: ref %.37 = var a
-// CHECK:STDOUT:   %a: ref %.37 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc10_14: Core.IntLiteral = int_value 3 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, %C [template = constants.%.35]
+// CHECK:STDOUT:   %a.var: ref %.35 = var a
+// CHECK:STDOUT:   %a: ref %.35 = bind_name a, %a.var
 // CHECK:STDOUT:   %.loc10_21.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc10_25.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc10_29.1: %.1 = struct_literal ()
@@ -696,22 +671,22 @@ fn G() -> C {
 // CHECK:STDOUT:   %.loc10_30.3: ref %C = array_index %a.var, %.loc10_30.2
 // CHECK:STDOUT:   %.loc10_21.2: init %C = class_init (), %.loc10_30.3 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc10_30.4: init %C = converted %.loc10_21.1, %.loc10_21.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc10_30.5: i32 = int_value 1 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc10_30.5: i32 = int_value 1 [template = constants.%.37]
 // CHECK:STDOUT:   %.loc10_30.6: ref %C = array_index %a.var, %.loc10_30.5
 // CHECK:STDOUT:   %.loc10_25.2: init %C = class_init (), %.loc10_30.6 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc10_30.7: init %C = converted %.loc10_25.1, %.loc10_25.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc10_30.8: i32 = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_30.8: i32 = int_value 2 [template = constants.%.38]
 // CHECK:STDOUT:   %.loc10_30.9: ref %C = array_index %a.var, %.loc10_30.8
 // CHECK:STDOUT:   %.loc10_29.2: init %C = class_init (), %.loc10_30.9 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc10_30.10: init %C = converted %.loc10_29.1, %.loc10_29.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc10_30.11: init %.37 = array_init (%.loc10_30.4, %.loc10_30.7, %.loc10_30.10) to %a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc10_31: init %.37 = converted %.loc10_30.1, %.loc10_30.11 [template = constants.%array]
+// CHECK:STDOUT:   %.loc10_30.11: init %.35 = array_init (%.loc10_30.4, %.loc10_30.7, %.loc10_30.10) to %a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc10_31: init %.35 = converted %.loc10_30.1, %.loc10_30.11 [template = constants.%array]
 // CHECK:STDOUT:   assign %a.var, %.loc10_31
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %a.ref: ref %.37 = name_ref a, %a
-// CHECK:STDOUT:   %.loc21_10: <specific function> = specific_function %F.ref, @F(constants.%C) [template = constants.%.41]
+// CHECK:STDOUT:   %a.ref: ref %.35 = name_ref a, %a
+// CHECK:STDOUT:   %.loc21_10: <specific function> = specific_function %F.ref, @F(constants.%C) [template = constants.%.40]
 // CHECK:STDOUT:   %.loc8_8.2: ref %C = splice_block %return {}
-// CHECK:STDOUT:   %.loc21_12: %.40 = converted %a.ref, <error> [template = <error>]
+// CHECK:STDOUT:   %.loc21_12: %.39 = converted %a.ref, <error> [template = <error>]
 // CHECK:STDOUT:   %F.call: init %C = call %.loc21_10(<error>) to %.loc8_8.2
 // CHECK:STDOUT:   return %F.call to %return
 // CHECK:STDOUT: }
@@ -719,13 +694,13 @@ fn G() -> C {
 // CHECK:STDOUT: specific @F(constants.%T) {
 // CHECK:STDOUT:   %T.loc6_6.2 => constants.%T
 // CHECK:STDOUT:   %T.patt.loc6_6.2 => constants.%T
-// CHECK:STDOUT:   %.loc6_24.2 => constants.%.30
+// CHECK:STDOUT:   %.loc6_24.2 => constants.%.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%C) {
 // CHECK:STDOUT:   %T.loc6_6.2 => constants.%C
 // CHECK:STDOUT:   %T.patt.loc6_6.2 => constants.%C
-// CHECK:STDOUT:   %.loc6_24.2 => constants.%.40
+// CHECK:STDOUT:   %.loc6_24.2 => constants.%.39
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
@@ -751,16 +726,14 @@ fn G() -> C {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.29: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.30: <bound method> = bound_method %.29, %Convert.15 [template]
-// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.32: type = array_type %.31, %D [template]
+// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.30: type = array_type %.29, %D [template]
 // CHECK:STDOUT:   %tuple.type: type = tuple_type (%.1, %.1, %.1) [template]
-// CHECK:STDOUT:   %.34: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 0 [template]
 // CHECK:STDOUT:   %struct: %D = struct_value () [template]
-// CHECK:STDOUT:   %.35: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %array: %.32 = tuple_value (%struct, %struct, %struct) [template]
+// CHECK:STDOUT:   %.33: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %array: %.30 = tuple_value (%struct, %struct, %struct) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -854,36 +827,31 @@ fn G() -> C {
 // CHECK:STDOUT: fn @G() -> %return: %C {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %D.ref: type = name_ref D, file.%D.decl [template = constants.%D]
-// CHECK:STDOUT:   %.loc13_14.1: i32 = int_value 3 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc13_14.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc13_14.3: <bound method> = bound_method %.loc13_14.1, %.loc13_14.2 [template = constants.%.30]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc13_14.3(%.loc13_14.1) [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_14.5: Core.IntLiteral = converted %.loc13_14.1, %.loc13_14.4 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc13_15: type = array_type %.loc13_14.5, %D [template = constants.%.32]
-// CHECK:STDOUT:   %a.var: ref %.32 = var a
-// CHECK:STDOUT:   %a: ref %.32 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc13_14: Core.IntLiteral = int_value 3 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_15: type = array_type %.loc13_14, %D [template = constants.%.30]
+// CHECK:STDOUT:   %a.var: ref %.30 = var a
+// CHECK:STDOUT:   %a: ref %.30 = bind_name a, %a.var
 // CHECK:STDOUT:   %.loc13_21.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_25.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_29.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %.loc13_30.1: %tuple.type = tuple_literal (%.loc13_21.1, %.loc13_25.1, %.loc13_29.1)
-// CHECK:STDOUT:   %.loc13_30.2: i32 = int_value 0 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_30.2: i32 = int_value 0 [template = constants.%.32]
 // CHECK:STDOUT:   %.loc13_30.3: ref %D = array_index %a.var, %.loc13_30.2
 // CHECK:STDOUT:   %.loc13_21.2: init %D = class_init (), %.loc13_30.3 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.4: init %D = converted %.loc13_21.1, %.loc13_21.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.5: i32 = int_value 1 [template = constants.%.35]
+// CHECK:STDOUT:   %.loc13_30.5: i32 = int_value 1 [template = constants.%.33]
 // CHECK:STDOUT:   %.loc13_30.6: ref %D = array_index %a.var, %.loc13_30.5
 // CHECK:STDOUT:   %.loc13_25.2: init %D = class_init (), %.loc13_30.6 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.7: init %D = converted %.loc13_25.1, %.loc13_25.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.8: i32 = int_value 2 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_30.8: i32 = int_value 2 [template = constants.%.34]
 // CHECK:STDOUT:   %.loc13_30.9: ref %D = array_index %a.var, %.loc13_30.8
 // CHECK:STDOUT:   %.loc13_29.2: init %D = class_init (), %.loc13_30.9 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc13_30.10: init %D = converted %.loc13_29.1, %.loc13_29.2 [template = constants.%struct]
-// CHECK:STDOUT:   %.loc13_30.11: init %.32 = array_init (%.loc13_30.4, %.loc13_30.7, %.loc13_30.10) to %a.var [template = constants.%array]
-// CHECK:STDOUT:   %.loc13_31: init %.32 = converted %.loc13_30.1, %.loc13_30.11 [template = constants.%array]
+// CHECK:STDOUT:   %.loc13_30.11: init %.30 = array_init (%.loc13_30.4, %.loc13_30.7, %.loc13_30.10) to %a.var [template = constants.%array]
+// CHECK:STDOUT:   %.loc13_31: init %.30 = converted %.loc13_30.1, %.loc13_30.11 [template = constants.%array]
 // CHECK:STDOUT:   assign %a.var, %.loc13_31
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %a.ref: ref %.32 = name_ref a, %a
+// CHECK:STDOUT:   %a.ref: ref %.30 = name_ref a, %a
 // CHECK:STDOUT:   return <error> to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 49 - 37
toolchain/check/testdata/deduce/generic_type.carbon

@@ -716,26 +716,33 @@ fn G() -> i32 {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N, 0 [symbolic]
-// CHECK:STDOUT:   %N.patt: i32 = symbolic_binding_pattern N, 0 [symbolic]
+// CHECK:STDOUT:   %N.1: i32 = bind_symbolic_name N, 0 [symbolic]
+// CHECK:STDOUT:   %N.patt.1: i32 = symbolic_binding_pattern N, 0 [symbolic]
 // CHECK:STDOUT:   %WithNontype.type: type = generic_class_type @WithNontype [template]
 // CHECK:STDOUT:   %WithNontype.1: %WithNontype.type = struct_value () [template]
-// CHECK:STDOUT:   %WithNontype.2: type = class_type @WithNontype, @WithNontype(%N) [symbolic]
+// CHECK:STDOUT:   %WithNontype.2: type = class_type @WithNontype, @WithNontype(%N.1) [symbolic]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %.2: <witness> = complete_type_witness %.1 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %WithNontype.3: type = class_type @WithNontype, @WithNontype(%.4) [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %WithNontype.3: type = class_type @WithNontype, @WithNontype(%.30) [template]
 // CHECK:STDOUT:   %struct: %WithNontype.3 = struct_value () [template]
-// CHECK:STDOUT:   %.5: <specific function> = specific_function %F, @F(%.4) [template]
+// CHECK:STDOUT:   %.31: <specific function> = specific_function %F, @F(%.30) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -750,18 +757,18 @@ fn G() -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %WithNontype.decl: %WithNontype.type = class_decl @WithNontype [template = constants.%WithNontype.1] {
-// CHECK:STDOUT:     %N.patt.loc4_19.1: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc4_19.2 (constants.%N.patt)]
-// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc4_19.1, runtime_param<invalid> [symbolic = %N.patt.loc4_19.2 (constants.%N.patt)]
+// CHECK:STDOUT:     %N.patt.loc4_19.1: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc4_19.2 (constants.%N.patt.1)]
+// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc4_19.1, runtime_param<invalid> [symbolic = %N.patt.loc4_19.2 (constants.%N.patt.1)]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc4_23.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc4_23.2: type = converted %int.make_type_32, %.loc4_23.1 [template = i32]
 // CHECK:STDOUT:     %N.param: i32 = value_param runtime_param<invalid>
-// CHECK:STDOUT:     %N.loc4_19.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc4_19.2 (constants.%N)]
+// CHECK:STDOUT:     %N.loc4_19.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc4_19.2 (constants.%N.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %N.patt.loc6_6.1: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_6.2 (constants.%N.patt)]
-// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc6_6.1, runtime_param<invalid> [symbolic = %N.patt.loc6_6.2 (constants.%N.patt)]
+// CHECK:STDOUT:     %N.patt.loc6_6.1: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_6.2 (constants.%N.patt.1)]
+// CHECK:STDOUT:     %N.param_patt: i32 = value_param_pattern %N.patt.loc6_6.1, runtime_param<invalid> [symbolic = %N.patt.loc6_6.2 (constants.%N.patt.1)]
 // CHECK:STDOUT:     %x.patt: @F.%WithNontype.loc6_29.2 (%WithNontype.2) = binding_pattern x
 // CHECK:STDOUT:     %x.param_patt: @F.%WithNontype.loc6_29.2 (%WithNontype.2) = value_param_pattern %x.patt, runtime_param0
 // CHECK:STDOUT:     %return.patt: i32 = return_slot_pattern
@@ -771,13 +778,13 @@ fn G() -> i32 {
 // CHECK:STDOUT:     %.loc6_10.1: type = value_of_initializer %int.make_type_32.loc6_10 [template = i32]
 // CHECK:STDOUT:     %.loc6_10.2: type = converted %int.make_type_32.loc6_10, %.loc6_10.1 [template = i32]
 // CHECK:STDOUT:     %WithNontype.ref: %WithNontype.type = name_ref WithNontype, file.%WithNontype.decl [template = constants.%WithNontype.1]
-// CHECK:STDOUT:     %N.ref.loc6_30: i32 = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N)]
-// CHECK:STDOUT:     %WithNontype.loc6_29.1: type = class_type @WithNontype, @WithNontype(constants.%N) [symbolic = %WithNontype.loc6_29.2 (constants.%WithNontype.2)]
+// CHECK:STDOUT:     %N.ref.loc6_30: i32 = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N.1)]
+// CHECK:STDOUT:     %WithNontype.loc6_29.1: type = class_type @WithNontype, @WithNontype(constants.%N.1) [symbolic = %WithNontype.loc6_29.2 (constants.%WithNontype.2)]
 // CHECK:STDOUT:     %int.make_type_32.loc6_37: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc6_37.1: type = value_of_initializer %int.make_type_32.loc6_37 [template = i32]
 // CHECK:STDOUT:     %.loc6_37.2: type = converted %int.make_type_32.loc6_37, %.loc6_37.1 [template = i32]
 // CHECK:STDOUT:     %N.param: i32 = value_param runtime_param<invalid>
-// CHECK:STDOUT:     %N.loc6_6.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc6_6.2 (constants.%N)]
+// CHECK:STDOUT:     %N.loc6_6.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc6_6.2 (constants.%N.1)]
 // CHECK:STDOUT:     %x.param: @F.%WithNontype.loc6_29.2 (%WithNontype.2) = value_param runtime_param0
 // CHECK:STDOUT:     %x: @F.%WithNontype.loc6_29.2 (%WithNontype.2) = bind_name x, %x.param
 // CHECK:STDOUT:     %return.param: ref i32 = out_param runtime_param1
@@ -796,8 +803,8 @@ fn G() -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic class @WithNontype(%N.loc4_19.1: i32) {
-// CHECK:STDOUT:   %N.loc4_19.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc4_19.2 (constants.%N)]
-// CHECK:STDOUT:   %N.patt.loc4_19.2: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc4_19.2 (constants.%N.patt)]
+// CHECK:STDOUT:   %N.loc4_19.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc4_19.2 (constants.%N.1)]
+// CHECK:STDOUT:   %N.patt.loc4_19.2: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc4_19.2 (constants.%N.patt.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
@@ -810,15 +817,15 @@ fn G() -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(%N.loc6_6.1: i32) {
-// CHECK:STDOUT:   %N.loc6_6.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc6_6.2 (constants.%N)]
-// CHECK:STDOUT:   %N.patt.loc6_6.2: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_6.2 (constants.%N.patt)]
+// CHECK:STDOUT:   %N.loc6_6.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc6_6.2 (constants.%N.1)]
+// CHECK:STDOUT:   %N.patt.loc6_6.2: i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_6.2 (constants.%N.patt.1)]
 // CHECK:STDOUT:   %WithNontype.loc6_29.2: type = class_type @WithNontype, @WithNontype(%N.loc6_6.2) [symbolic = %WithNontype.loc6_29.2 (constants.%WithNontype.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn[%N.param_patt: i32](%x.param_patt: @F.%WithNontype.loc6_29.2 (%WithNontype.2)) -> i32 {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %N.ref.loc6_50: i32 = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N)]
+// CHECK:STDOUT:     %N.ref.loc6_50: i32 = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N.1)]
 // CHECK:STDOUT:     return %N.ref.loc6_50
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -828,13 +835,18 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
 // CHECK:STDOUT:   %.loc9_13.1: %.1 = struct_literal ()
 // CHECK:STDOUT:   %WithNontype.ref: %WithNontype.type = name_ref WithNontype, file.%WithNontype.decl [template = constants.%WithNontype.1]
-// CHECK:STDOUT:   %.loc9_30: i32 = int_value 0 [template = constants.%.4]
-// CHECK:STDOUT:   %WithNontype: type = class_type @WithNontype, @WithNontype(constants.%.4) [template = constants.%WithNontype.3]
+// CHECK:STDOUT:   %.loc9_30: Core.IntLiteral = int_value 0 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_29.1: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc9_29.2: <bound method> = bound_method %.loc9_30, %.loc9_29.1 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked: init i32 = call %.loc9_29.2(%.loc9_30) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc9_29.3: i32 = value_of_initializer %int.convert_checked [template = constants.%.30]
+// CHECK:STDOUT:   %.loc9_29.4: i32 = converted %.loc9_30, %.loc9_29.3 [template = constants.%.30]
+// CHECK:STDOUT:   %WithNontype: type = class_type @WithNontype, @WithNontype(constants.%.30) [template = constants.%WithNontype.3]
 // CHECK:STDOUT:   %.loc9_13.2: ref %WithNontype.3 = temporary_storage
 // CHECK:STDOUT:   %.loc9_13.3: init %WithNontype.3 = class_init (), %.loc9_13.2 [template = constants.%struct]
 // CHECK:STDOUT:   %.loc9_13.4: ref %WithNontype.3 = temporary %.loc9_13.2, %.loc9_13.3
 // CHECK:STDOUT:   %.loc9_15.1: ref %WithNontype.3 = converted %.loc9_13.1, %.loc9_13.4
-// CHECK:STDOUT:   %.loc9_10: <specific function> = specific_function %F.ref, @F(constants.%.4) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_10: <specific function> = specific_function %F.ref, @F(constants.%.30) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc9_15.2: %WithNontype.3 = bind_value %.loc9_15.1
 // CHECK:STDOUT:   %F.call: init i32 = call %.loc9_10(%.loc9_15.2)
 // CHECK:STDOUT:   %.loc9_33.1: i32 = value_of_initializer %F.call
@@ -842,34 +854,34 @@ fn G() -> i32 {
 // CHECK:STDOUT:   return %.loc9_33.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @WithNontype(constants.%N) {
-// CHECK:STDOUT:   %N.loc4_19.2 => constants.%N
-// CHECK:STDOUT:   %N.patt.loc4_19.2 => constants.%N
+// CHECK:STDOUT: specific @WithNontype(constants.%N.1) {
+// CHECK:STDOUT:   %N.loc4_19.2 => constants.%N.1
+// CHECK:STDOUT:   %N.patt.loc4_19.2 => constants.%N.1
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @WithNontype(@F.%N.loc6_6.2) {
-// CHECK:STDOUT:   %N.loc4_19.2 => constants.%N
-// CHECK:STDOUT:   %N.patt.loc4_19.2 => constants.%N
+// CHECK:STDOUT:   %N.loc4_19.2 => constants.%N.1
+// CHECK:STDOUT:   %N.patt.loc4_19.2 => constants.%N.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F(constants.%N) {
-// CHECK:STDOUT:   %N.loc6_6.2 => constants.%N
-// CHECK:STDOUT:   %N.patt.loc6_6.2 => constants.%N
+// CHECK:STDOUT: specific @F(constants.%N.1) {
+// CHECK:STDOUT:   %N.loc6_6.2 => constants.%N.1
+// CHECK:STDOUT:   %N.patt.loc6_6.2 => constants.%N.1
 // CHECK:STDOUT:   %WithNontype.loc6_29.2 => constants.%WithNontype.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @WithNontype(constants.%.4) {
-// CHECK:STDOUT:   %N.loc4_19.2 => constants.%.4
-// CHECK:STDOUT:   %N.patt.loc4_19.2 => constants.%.4
+// CHECK:STDOUT: specific @WithNontype(constants.%.30) {
+// CHECK:STDOUT:   %N.loc4_19.2 => constants.%.30
+// CHECK:STDOUT:   %N.patt.loc4_19.2 => constants.%.30
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F(constants.%.4) {
-// CHECK:STDOUT:   %N.loc6_6.2 => constants.%.4
-// CHECK:STDOUT:   %N.patt.loc6_6.2 => constants.%.4
+// CHECK:STDOUT: specific @F(constants.%.30) {
+// CHECK:STDOUT:   %N.loc6_6.2 => constants.%.30
+// CHECK:STDOUT:   %N.patt.loc6_6.2 => constants.%.30
 // CHECK:STDOUT:   %WithNontype.loc6_29.2 => constants.%WithNontype.3
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:

+ 36 - 16
toolchain/check/testdata/deduce/tuple.carbon

@@ -232,18 +232,28 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:   %HasPair.3: type = class_type @HasPair, @HasPair(%tuple.1) [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %tuple.2: %tuple.type.2 = tuple_value (%.5, %.6) [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.type.3: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
+// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
+// CHECK:STDOUT:   %.30: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.32: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.34: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.2: %tuple.type.2 = tuple_value (%.32, %.34) [template]
 // CHECK:STDOUT:   %HasPair.4: type = class_type @HasPair, @HasPair(%tuple.2) [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.7: <specific function> = specific_function %F, @F(%.5, %.6) [template]
+// CHECK:STDOUT:   %.35: <specific function> = specific_function %F, @F(%.32, %.34) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int32 = %import_ref
+// CHECK:STDOUT:     .Int32 = %import_ref.1
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -314,11 +324,21 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:     %return.param_patt: i32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %HasPair.ref: %HasPair.type = name_ref HasPair, file.%HasPair.decl [template = constants.%HasPair.1]
-// CHECK:STDOUT:     %.loc8_18: i32 = int_value 1 [template = constants.%.5]
-// CHECK:STDOUT:     %.loc8_21: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:     %.loc8_22: %tuple.type.2 = tuple_literal (%.loc8_18, %.loc8_21)
-// CHECK:STDOUT:     %tuple: %tuple.type.2 = tuple_value (%.loc8_18, %.loc8_21) [template = constants.%tuple.2]
-// CHECK:STDOUT:     %.loc8_16: %tuple.type.2 = converted %.loc8_22, %tuple [template = constants.%tuple.2]
+// CHECK:STDOUT:     %.loc8_18: Core.IntLiteral = int_value 1 [template = constants.%.5]
+// CHECK:STDOUT:     %.loc8_21: Core.IntLiteral = int_value 2 [template = constants.%.6]
+// CHECK:STDOUT:     %.loc8_22.1: %tuple.type.3 = tuple_literal (%.loc8_18, %.loc8_21)
+// CHECK:STDOUT:     %.loc8_22.2: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc8_22.3: <bound method> = bound_method %.loc8_18, %.loc8_22.2 [template = constants.%.31]
+// CHECK:STDOUT:     %int.convert_checked.loc8_22.1: init i32 = call %.loc8_22.3(%.loc8_18) [template = constants.%.32]
+// CHECK:STDOUT:     %.loc8_22.4: i32 = value_of_initializer %int.convert_checked.loc8_22.1 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc8_22.5: i32 = converted %.loc8_18, %.loc8_22.4 [template = constants.%.32]
+// CHECK:STDOUT:     %.loc8_22.6: %Convert.type.2 = interface_witness_access constants.%.30, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:     %.loc8_22.7: <bound method> = bound_method %.loc8_21, %.loc8_22.6 [template = constants.%.33]
+// CHECK:STDOUT:     %int.convert_checked.loc8_22.2: init i32 = call %.loc8_22.7(%.loc8_21) [template = constants.%.34]
+// CHECK:STDOUT:     %.loc8_22.8: i32 = value_of_initializer %int.convert_checked.loc8_22.2 [template = constants.%.34]
+// CHECK:STDOUT:     %.loc8_22.9: i32 = converted %.loc8_21, %.loc8_22.8 [template = constants.%.34]
+// CHECK:STDOUT:     %tuple: %tuple.type.2 = tuple_value (%.loc8_22.5, %.loc8_22.9) [template = constants.%tuple.2]
+// CHECK:STDOUT:     %.loc8_16: %tuple.type.2 = converted %.loc8_22.1, %tuple [template = constants.%tuple.2]
 // CHECK:STDOUT:     %HasPair: type = class_type @HasPair, @HasPair(constants.%tuple.2) [template = constants.%HasPair.4]
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc8_29.1: type = value_of_initializer %int.make_type_32 [template = i32]
@@ -365,7 +385,7 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
 // CHECK:STDOUT:   %h.ref: %HasPair.4 = name_ref h, %h
-// CHECK:STDOUT:   %.loc9_10: <specific function> = specific_function %F.ref, @F(constants.%.5, constants.%.6) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_10: <specific function> = specific_function %F.ref, @F(constants.%.32, constants.%.34) [template = constants.%.35]
 // CHECK:STDOUT:   %F.call: init i32 = call %.loc9_10(%h.ref)
 // CHECK:STDOUT:   %.loc9_14.1: i32 = value_of_initializer %F.call
 // CHECK:STDOUT:   %.loc9_14.2: i32 = converted %F.call, %.loc9_14.1
@@ -405,11 +425,11 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F(constants.%.5, constants.%.6) {
-// CHECK:STDOUT:   %A.loc6_6.2 => constants.%.5
-// CHECK:STDOUT:   %A.patt.loc6_6.2 => constants.%.5
-// CHECK:STDOUT:   %B.loc6_15.2 => constants.%.6
-// CHECK:STDOUT:   %B.patt.loc6_15.2 => constants.%.6
+// CHECK:STDOUT: specific @F(constants.%.32, constants.%.34) {
+// CHECK:STDOUT:   %A.loc6_6.2 => constants.%.32
+// CHECK:STDOUT:   %A.patt.loc6_6.2 => constants.%.32
+// CHECK:STDOUT:   %B.loc6_15.2 => constants.%.34
+// CHECK:STDOUT:   %B.patt.loc6_15.2 => constants.%.34
 // CHECK:STDOUT:   %tuple.loc6_40.2 => constants.%tuple.2
 // CHECK:STDOUT:   %HasPair.loc6_34.2 => constants.%HasPair.4
 // CHECK:STDOUT:

+ 136 - 112
toolchain/check/testdata/eval/aggregate.carbon

@@ -23,32 +23,39 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %tuple.type.1: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %tuple.1: %tuple.type.2 = tuple_value (%.2, %.3) [template]
-// CHECK:STDOUT:   %.4: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %.7: type = struct_type {.c: i32, .b: i32, .a: i32} [template]
-// CHECK:STDOUT:   %.8: type = struct_type {.b: i32, .a: i32, .c: i32} [template]
-// CHECK:STDOUT:   %struct.1: %.8 = struct_value (%.3, %.2, %.6) [template]
-// CHECK:STDOUT:   %struct.2: %.4 = struct_value (%.2, %.3, %.6) [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.3: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.type.3: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.33: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.34: <bound method> = bound_method %.2, %Convert.15 [template]
-// CHECK:STDOUT:   %.35: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.36: type = array_type %.35, i32 [template]
-// CHECK:STDOUT:   %.38: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %tuple.type.3: type = tuple_type (i32) [template]
-// CHECK:STDOUT:   %.39: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.40: i32 = int_value 7 [template]
-// CHECK:STDOUT:   %.41: i32 = int_value 9 [template]
-// CHECK:STDOUT:   %tuple.type.4: type = tuple_type (i32, i32, i32, i32) [template]
-// CHECK:STDOUT:   %tuple.2: %tuple.type.4 = tuple_value (%.39, %.40, %.2, %.41) [template]
-// CHECK:STDOUT:   %array: %.36 = tuple_value (%.38) [template]
-// CHECK:STDOUT:   %.43: type = struct_type {.a: i32, .b: i32} [template]
-// CHECK:STDOUT:   %struct.3: %.43 = struct_value (%.6, %.2) [template]
+// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.28: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.29: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.30: <bound method> = bound_method %.3, %Convert.15 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %tuple.1: %tuple.type.2 = tuple_value (%.29, %.31) [template]
+// CHECK:STDOUT:   %.32: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.35: type = struct_type {.c: Core.IntLiteral, .b: Core.IntLiteral, .a: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %.36: type = struct_type {.b: i32, .a: i32, .c: i32} [template]
+// CHECK:STDOUT:   %.38: <bound method> = bound_method %.34, %Convert.15 [template]
+// CHECK:STDOUT:   %.39: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %struct.1: %.36 = struct_value (%.31, %.29, %.39) [template]
+// CHECK:STDOUT:   %struct.2: %.32 = struct_value (%.29, %.31, %.39) [template]
+// CHECK:STDOUT:   %.40: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.42: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %tuple.type.4: type = tuple_type (Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.43: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.44: Core.IntLiteral = int_value 7 [template]
+// CHECK:STDOUT:   %.45: Core.IntLiteral = int_value 9 [template]
+// CHECK:STDOUT:   %tuple.type.5: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %tuple.2: %tuple.type.5 = tuple_value (%.43, %.44, %.2, %.45) [template]
+// CHECK:STDOUT:   %.47: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.48: <bound method> = bound_method %.42, %Convert.15 [template]
+// CHECK:STDOUT:   %array: %.40 = tuple_value (%.47) [template]
+// CHECK:STDOUT:   %.49: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template]
+// CHECK:STDOUT:   %struct.3: %.49 = struct_value (%.34, %.2) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -88,40 +95,30 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
 // CHECK:STDOUT:   %int.make_type_32.loc13_41: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc13_41.1: type = value_of_initializer %int.make_type_32.loc13_41 [template = i32]
 // CHECK:STDOUT:   %.loc13_41.2: type = converted %int.make_type_32.loc13_41, %.loc13_41.1 [template = i32]
-// CHECK:STDOUT:   %.loc13_44: type = struct_type {.a: i32, .b: i32, .c: i32} [template = constants.%.4]
-// CHECK:STDOUT:   %struct_copy.var: ref %.4 = var struct_copy
-// CHECK:STDOUT:   %struct_copy: ref %.4 = bind_name struct_copy, %struct_copy.var
+// CHECK:STDOUT:   %.loc13_44: type = struct_type {.a: i32, .b: i32, .c: i32} [template = constants.%.32]
+// CHECK:STDOUT:   %struct_copy.var: ref %.32 = var struct_copy
+// CHECK:STDOUT:   %struct_copy: ref %.32 = bind_name struct_copy, %struct_copy.var
 // CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc15_24.1: i32 = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc15_24: Core.IntLiteral = int_value 1 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc15_19.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
 // CHECK:STDOUT:   %.loc15_19.2: type = converted %int.make_type_32.loc15, %.loc15_19.1 [template = i32]
-// CHECK:STDOUT:   %.loc15_24.2: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc15_24.3: <bound method> = bound_method %.loc15_24.1, %.loc15_24.2 [template = constants.%.34]
-// CHECK:STDOUT:   %int.convert_checked.loc15: init Core.IntLiteral = call %.loc15_24.3(%.loc15_24.1) [template = constants.%.35]
-// CHECK:STDOUT:   %.loc15_24.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc15 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc15_24.5: Core.IntLiteral = converted %.loc15_24.1, %.loc15_24.4 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc15_25: type = array_type %.loc15_24.5, i32 [template = constants.%.36]
-// CHECK:STDOUT:   %tuple_index.var: ref %.36 = var tuple_index
-// CHECK:STDOUT:   %tuple_index: ref %.36 = bind_name tuple_index, %tuple_index.var
+// CHECK:STDOUT:   %.loc15_25: type = array_type %.loc15_24, i32 [template = constants.%.40]
+// CHECK:STDOUT:   %tuple_index.var: ref %.40 = var tuple_index
+// CHECK:STDOUT:   %tuple_index: ref %.40 = bind_name tuple_index, %tuple_index.var
 // CHECK:STDOUT:   %int.make_type_32.loc17: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc17_26.1: i32 = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_26: Core.IntLiteral = int_value 1 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc17_21.1: type = value_of_initializer %int.make_type_32.loc17 [template = i32]
 // CHECK:STDOUT:   %.loc17_21.2: type = converted %int.make_type_32.loc17, %.loc17_21.1 [template = i32]
-// CHECK:STDOUT:   %.loc17_26.2: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc17_26.3: <bound method> = bound_method %.loc17_26.1, %.loc17_26.2 [template = constants.%.34]
-// CHECK:STDOUT:   %int.convert_checked.loc17: init Core.IntLiteral = call %.loc17_26.3(%.loc17_26.1) [template = constants.%.35]
-// CHECK:STDOUT:   %.loc17_26.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc17 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc17_26.5: Core.IntLiteral = converted %.loc17_26.1, %.loc17_26.4 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc17_27: type = array_type %.loc17_26.5, i32 [template = constants.%.36]
-// CHECK:STDOUT:   %struct_access.var: ref %.36 = var struct_access
-// CHECK:STDOUT:   %struct_access: ref %.36 = bind_name struct_access, %struct_access.var
+// CHECK:STDOUT:   %.loc17_27: type = array_type %.loc17_26, i32 [template = constants.%.40]
+// CHECK:STDOUT:   %struct_access.var: ref %.40 = var struct_access
+// CHECK:STDOUT:   %struct_access: ref %.40 = bind_name struct_access, %struct_access.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_31: i32 = int_value 1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_34: i32 = int_value 2 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_35.1: %tuple.type.2 = tuple_literal (%.loc11_31, %.loc11_34)
+// CHECK:STDOUT:   %.loc11_31: Core.IntLiteral = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc11_34: Core.IntLiteral = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc11_35.1: %tuple.type.3 = tuple_literal (%.loc11_31, %.loc11_34)
 // CHECK:STDOUT:   %int.make_type_32.loc11_41: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %int.make_type_32.loc11_46: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc11_49.1: %tuple.type.1 = tuple_literal (%int.make_type_32.loc11_41, %int.make_type_32.loc11_46)
@@ -130,17 +127,31 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
 // CHECK:STDOUT:   %.loc11_49.4: type = value_of_initializer %int.make_type_32.loc11_46 [template = i32]
 // CHECK:STDOUT:   %.loc11_49.5: type = converted %int.make_type_32.loc11_46, %.loc11_49.4 [template = i32]
 // CHECK:STDOUT:   %.loc11_49.6: type = converted %.loc11_49.1, constants.%tuple.type.2 [template = constants.%tuple.type.2]
-// CHECK:STDOUT:   %.loc11_35.2: ref i32 = tuple_access file.%tuple_copy.var, element0
-// CHECK:STDOUT:   %.loc11_35.3: init i32 = initialize_from %.loc11_31 to %.loc11_35.2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_35.4: ref i32 = tuple_access file.%tuple_copy.var, element1
-// CHECK:STDOUT:   %.loc11_35.5: init i32 = initialize_from %.loc11_34 to %.loc11_35.4 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_35.6: init %tuple.type.2 = tuple_init (%.loc11_35.3, %.loc11_35.5) to file.%tuple_copy.var [template = constants.%tuple.1]
-// CHECK:STDOUT:   %.loc11_50: init %tuple.type.2 = converted %.loc11_35.1, %.loc11_35.6 [template = constants.%tuple.1]
+// CHECK:STDOUT:   %.loc11_35.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_35.3: <bound method> = bound_method %.loc11_31, %.loc11_35.2 [template = constants.%.28]
+// CHECK:STDOUT:   %int.convert_checked.loc11_35.1: init i32 = call %.loc11_35.3(%.loc11_31) [template = constants.%.29]
+// CHECK:STDOUT:   %.loc11_35.4: i32 = value_of_initializer %int.convert_checked.loc11_35.1 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc11_35.5: i32 = converted %.loc11_31, %.loc11_35.4 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc11_35.6: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc11_35.7: <bound method> = bound_method %.loc11_34, %.loc11_35.6 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc11_35.2: init i32 = call %.loc11_35.7(%.loc11_34) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_35.8: i32 = value_of_initializer %int.convert_checked.loc11_35.2 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_35.9: i32 = converted %.loc11_34, %.loc11_35.8 [template = constants.%.31]
+// CHECK:STDOUT:   %tuple.loc11: %tuple.type.2 = tuple_value (%.loc11_35.5, %.loc11_35.9) [template = constants.%tuple.1]
+// CHECK:STDOUT:   %.loc11_37.1: %tuple.type.2 = converted %.loc11_35.1, %tuple.loc11 [template = constants.%tuple.1]
+// CHECK:STDOUT:   %.loc11_37.2: i32 = tuple_access %.loc11_37.1, element0 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc11_37.3: ref i32 = tuple_access file.%tuple_copy.var, element0
+// CHECK:STDOUT:   %.loc11_37.4: init i32 = initialize_from %.loc11_37.2 to %.loc11_37.3 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc11_37.5: i32 = tuple_access %.loc11_37.1, element1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_37.6: ref i32 = tuple_access file.%tuple_copy.var, element1
+// CHECK:STDOUT:   %.loc11_37.7: init i32 = initialize_from %.loc11_37.5 to %.loc11_37.6 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc11_37.8: init %tuple.type.2 = tuple_init (%.loc11_37.4, %.loc11_37.7) to file.%tuple_copy.var [template = constants.%tuple.1]
+// CHECK:STDOUT:   %.loc11_50: init %tuple.type.2 = converted %.loc11_37.1, %.loc11_37.8 [template = constants.%tuple.1]
 // CHECK:STDOUT:   assign file.%tuple_copy.var, %.loc11_50
-// CHECK:STDOUT:   %.loc13_54: i32 = int_value 3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc13_62: i32 = int_value 2 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc13_70: i32 = int_value 1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc13_71: %.7 = struct_literal (%.loc13_54, %.loc13_62, %.loc13_70)
+// CHECK:STDOUT:   %.loc13_54: Core.IntLiteral = int_value 3 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_62: Core.IntLiteral = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc13_70: Core.IntLiteral = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc13_71.1: %.35 = struct_literal (%.loc13_54, %.loc13_62, %.loc13_70)
 // CHECK:STDOUT:   %int.make_type_32.loc13_81: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc13_81.1: type = value_of_initializer %int.make_type_32.loc13_81 [template = i32]
 // CHECK:STDOUT:   %.loc13_81.2: type = converted %int.make_type_32.loc13_81, %.loc13_81.1 [template = i32]
@@ -150,71 +161,84 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
 // CHECK:STDOUT:   %int.make_type_32.loc13_99: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %.loc13_99.1: type = value_of_initializer %int.make_type_32.loc13_99 [template = i32]
 // CHECK:STDOUT:   %.loc13_99.2: type = converted %int.make_type_32.loc13_99, %.loc13_99.1 [template = i32]
-// CHECK:STDOUT:   %.loc13_102: type = struct_type {.b: i32, .a: i32, .c: i32} [template = constants.%.8]
-// CHECK:STDOUT:   %struct.loc13: %.8 = struct_value (%.loc13_62, %.loc13_70, %.loc13_54) [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc13_73.1: %.8 = converted %.loc13_71, %struct.loc13 [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc13_73.2: i32 = struct_access %.loc13_73.1, element1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc13_102: type = struct_type {.b: i32, .a: i32, .c: i32} [template = constants.%.36]
+// CHECK:STDOUT:   %.loc13_71.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_71.3: <bound method> = bound_method %.loc13_62, %.loc13_71.2 [template = constants.%.30]
+// CHECK:STDOUT:   %int.convert_checked.loc13_71.1: init i32 = call %.loc13_71.3(%.loc13_62) [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_71.4: i32 = value_of_initializer %int.convert_checked.loc13_71.1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_71.5: i32 = converted %.loc13_62, %.loc13_71.4 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_71.6: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_71.7: <bound method> = bound_method %.loc13_70, %.loc13_71.6 [template = constants.%.28]
+// CHECK:STDOUT:   %int.convert_checked.loc13_71.2: init i32 = call %.loc13_71.7(%.loc13_70) [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_71.8: i32 = value_of_initializer %int.convert_checked.loc13_71.2 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_71.9: i32 = converted %.loc13_70, %.loc13_71.8 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_71.10: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_71.11: <bound method> = bound_method %.loc13_54, %.loc13_71.10 [template = constants.%.38]
+// CHECK:STDOUT:   %int.convert_checked.loc13_71.3: init i32 = call %.loc13_71.11(%.loc13_54) [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_71.12: i32 = value_of_initializer %int.convert_checked.loc13_71.3 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_71.13: i32 = converted %.loc13_54, %.loc13_71.12 [template = constants.%.39]
+// CHECK:STDOUT:   %struct.loc13: %.36 = struct_value (%.loc13_71.5, %.loc13_71.9, %.loc13_71.13) [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc13_73.1: %.36 = converted %.loc13_71.1, %struct.loc13 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc13_73.2: i32 = struct_access %.loc13_73.1, element1 [template = constants.%.29]
 // CHECK:STDOUT:   %.loc13_73.3: ref i32 = struct_access file.%struct_copy.var, element1
-// CHECK:STDOUT:   %.loc13_73.4: init i32 = initialize_from %.loc13_73.2 to %.loc13_73.3 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc13_73.5: i32 = struct_access %.loc13_73.1, element0 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc13_73.4: init i32 = initialize_from %.loc13_73.2 to %.loc13_73.3 [template = constants.%.29]
+// CHECK:STDOUT:   %.loc13_73.5: i32 = struct_access %.loc13_73.1, element0 [template = constants.%.31]
 // CHECK:STDOUT:   %.loc13_73.6: ref i32 = struct_access file.%struct_copy.var, element0
-// CHECK:STDOUT:   %.loc13_73.7: init i32 = initialize_from %.loc13_73.5 to %.loc13_73.6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc13_73.8: i32 = struct_access %.loc13_73.1, element2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc13_73.7: init i32 = initialize_from %.loc13_73.5 to %.loc13_73.6 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_73.8: i32 = struct_access %.loc13_73.1, element2 [template = constants.%.39]
 // CHECK:STDOUT:   %.loc13_73.9: ref i32 = struct_access file.%struct_copy.var, element2
-// CHECK:STDOUT:   %.loc13_73.10: init i32 = initialize_from %.loc13_73.8 to %.loc13_73.9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc13_73.11: init %.4 = struct_init (%.loc13_73.4, %.loc13_73.7, %.loc13_73.10) to file.%struct_copy.var [template = constants.%struct.2]
-// CHECK:STDOUT:   %.loc13_103: init %.4 = converted %.loc13_73.1, %.loc13_73.11 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc13_73.10: init i32 = initialize_from %.loc13_73.8 to %.loc13_73.9 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc13_73.11: init %.32 = struct_init (%.loc13_73.4, %.loc13_73.7, %.loc13_73.10) to file.%struct_copy.var [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc13_103: init %.32 = converted %.loc13_73.1, %.loc13_73.11 [template = constants.%struct.2]
 // CHECK:STDOUT:   assign file.%struct_copy.var, %.loc13_103
-// CHECK:STDOUT:   %.loc15_30: i32 = int_value 0 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc15_32.1: %tuple.type.3 = tuple_literal (%.loc15_30)
+// CHECK:STDOUT:   %.loc15_30: Core.IntLiteral = int_value 0 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc15_32.1: %tuple.type.4 = tuple_literal (%.loc15_30)
 // CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc15_44: i32 = int_value 5 [template = constants.%.39]
-// CHECK:STDOUT:   %.loc15_47: i32 = int_value 7 [template = constants.%.40]
-// CHECK:STDOUT:   %.loc15_50: i32 = int_value 1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_53: i32 = int_value 9 [template = constants.%.41]
-// CHECK:STDOUT:   %.loc15_54.1: %tuple.type.4 = tuple_literal (%.loc15_44, %.loc15_47, %.loc15_50, %.loc15_53)
-// CHECK:STDOUT:   %.loc15_56: i32 = int_value 2 [template = constants.%.3]
-// CHECK:STDOUT:   %tuple: %tuple.type.4 = tuple_value (%.loc15_44, %.loc15_47, %.loc15_50, %.loc15_53) [template = constants.%tuple.2]
-// CHECK:STDOUT:   %.loc15_54.2: %tuple.type.4 = converted %.loc15_54.1, %tuple [template = constants.%tuple.2]
-// CHECK:STDOUT:   %.loc15_55.1: i32 = tuple_access %.loc15_54.2, element2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc15_44: Core.IntLiteral = int_value 5 [template = constants.%.43]
+// CHECK:STDOUT:   %.loc15_47: Core.IntLiteral = int_value 7 [template = constants.%.44]
+// CHECK:STDOUT:   %.loc15_50: Core.IntLiteral = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc15_53: Core.IntLiteral = int_value 9 [template = constants.%.45]
+// CHECK:STDOUT:   %.loc15_54.1: %tuple.type.5 = tuple_literal (%.loc15_44, %.loc15_47, %.loc15_50, %.loc15_53)
+// CHECK:STDOUT:   %.loc15_56: Core.IntLiteral = int_value 2 [template = constants.%.3]
+// CHECK:STDOUT:   %tuple.loc15: %tuple.type.5 = tuple_value (%.loc15_44, %.loc15_47, %.loc15_50, %.loc15_53) [template = constants.%tuple.2]
+// CHECK:STDOUT:   %.loc15_54.2: %tuple.type.5 = converted %.loc15_54.1, %tuple.loc15 [template = constants.%tuple.2]
+// CHECK:STDOUT:   %.loc15_55: Core.IntLiteral = tuple_access %.loc15_54.2, element2 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc15_38.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
 // CHECK:STDOUT:   %.loc15_38.2: type = converted %int.make_type_32.loc15, %.loc15_38.1 [template = i32]
-// CHECK:STDOUT:   %.loc15_55.2: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc15_55.3: <bound method> = bound_method %.loc15_55.1, %.loc15_55.2 [template = constants.%.34]
-// CHECK:STDOUT:   %int.convert_checked.loc15: init Core.IntLiteral = call %.loc15_55.3(%.loc15_55.1) [template = constants.%.35]
-// CHECK:STDOUT:   %.loc15_55.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc15 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc15_55.5: Core.IntLiteral = converted %.loc15_55.1, %.loc15_55.4 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc15_57: type = array_type %.loc15_55.5, i32 [template = constants.%.36]
-// CHECK:STDOUT:   %.loc15_5: ref %.36 = splice_block file.%tuple_index.var {}
-// CHECK:STDOUT:   %.loc15_32.2: i32 = int_value 0 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc15_32.3: ref i32 = array_index %.loc15_5, %.loc15_32.2
-// CHECK:STDOUT:   %.loc15_32.4: init i32 = initialize_from %.loc15_30 to %.loc15_32.3 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc15_32.5: init %.36 = array_init (%.loc15_32.4) to %.loc15_5 [template = constants.%array]
-// CHECK:STDOUT:   %.loc15_34: init %.36 = converted %.loc15_32.1, %.loc15_32.5 [template = constants.%array]
+// CHECK:STDOUT:   %.loc15_57: type = array_type %.loc15_55, i32 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc15_32.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc15_32.3: <bound method> = bound_method %.loc15_30, %.loc15_32.2 [template = constants.%.48]
+// CHECK:STDOUT:   %int.convert_checked.loc15: init i32 = call %.loc15_32.3(%.loc15_30) [template = constants.%.47]
+// CHECK:STDOUT:   %.loc15_32.4: init i32 = converted %.loc15_30, %int.convert_checked.loc15 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc15_5: ref %.40 = splice_block file.%tuple_index.var {}
+// CHECK:STDOUT:   %.loc15_32.5: i32 = int_value 0 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc15_32.6: ref i32 = array_index %.loc15_5, %.loc15_32.5
+// CHECK:STDOUT:   %.loc15_32.7: init i32 = initialize_from %.loc15_32.4 to %.loc15_32.6 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc15_32.8: init %.40 = array_init (%.loc15_32.7) to %.loc15_5 [template = constants.%array]
+// CHECK:STDOUT:   %.loc15_34: init %.40 = converted %.loc15_32.1, %.loc15_32.8 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%tuple_index.var, %.loc15_34
-// CHECK:STDOUT:   %.loc17_32: i32 = int_value 0 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc17_34.1: %tuple.type.3 = tuple_literal (%.loc17_32)
+// CHECK:STDOUT:   %.loc17_32: Core.IntLiteral = int_value 0 [template = constants.%.42]
+// CHECK:STDOUT:   %.loc17_34.1: %tuple.type.4 = tuple_literal (%.loc17_32)
 // CHECK:STDOUT:   %int.make_type_32.loc17: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc17_51: i32 = int_value 3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc17_59: i32 = int_value 1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc17_60.1: %.43 = struct_literal (%.loc17_51, %.loc17_59)
-// CHECK:STDOUT:   %struct.loc17: %.43 = struct_value (%.loc17_51, %.loc17_59) [template = constants.%struct.3]
-// CHECK:STDOUT:   %.loc17_60.2: %.43 = converted %.loc17_60.1, %struct.loc17 [template = constants.%struct.3]
-// CHECK:STDOUT:   %.loc17_61.1: i32 = struct_access %.loc17_60.2, element1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_51: Core.IntLiteral = int_value 3 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc17_59: Core.IntLiteral = int_value 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc17_60.1: %.49 = struct_literal (%.loc17_51, %.loc17_59)
+// CHECK:STDOUT:   %struct.loc17: %.49 = struct_value (%.loc17_51, %.loc17_59) [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc17_60.2: %.49 = converted %.loc17_60.1, %struct.loc17 [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc17_61: Core.IntLiteral = struct_access %.loc17_60.2, element1 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc17_40.1: type = value_of_initializer %int.make_type_32.loc17 [template = i32]
 // CHECK:STDOUT:   %.loc17_40.2: type = converted %int.make_type_32.loc17, %.loc17_40.1 [template = i32]
-// CHECK:STDOUT:   %.loc17_61.2: %Convert.type.2 = interface_witness_access constants.%.33, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc17_61.3: <bound method> = bound_method %.loc17_61.1, %.loc17_61.2 [template = constants.%.34]
-// CHECK:STDOUT:   %int.convert_checked.loc17: init Core.IntLiteral = call %.loc17_61.3(%.loc17_61.1) [template = constants.%.35]
-// CHECK:STDOUT:   %.loc17_61.4: Core.IntLiteral = value_of_initializer %int.convert_checked.loc17 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc17_61.5: Core.IntLiteral = converted %.loc17_61.1, %.loc17_61.4 [template = constants.%.35]
-// CHECK:STDOUT:   %.loc17_63: type = array_type %.loc17_61.5, i32 [template = constants.%.36]
-// CHECK:STDOUT:   %.loc17_5: ref %.36 = splice_block file.%struct_access.var {}
-// CHECK:STDOUT:   %.loc17_34.2: i32 = int_value 0 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc17_34.3: ref i32 = array_index %.loc17_5, %.loc17_34.2
-// CHECK:STDOUT:   %.loc17_34.4: init i32 = initialize_from %.loc17_32 to %.loc17_34.3 [template = constants.%.38]
-// CHECK:STDOUT:   %.loc17_34.5: init %.36 = array_init (%.loc17_34.4) to %.loc17_5 [template = constants.%array]
-// CHECK:STDOUT:   %.loc17_36: init %.36 = converted %.loc17_34.1, %.loc17_34.5 [template = constants.%array]
+// CHECK:STDOUT:   %.loc17_63: type = array_type %.loc17_61, i32 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc17_34.2: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc17_34.3: <bound method> = bound_method %.loc17_32, %.loc17_34.2 [template = constants.%.48]
+// CHECK:STDOUT:   %int.convert_checked.loc17: init i32 = call %.loc17_34.3(%.loc17_32) [template = constants.%.47]
+// CHECK:STDOUT:   %.loc17_34.4: init i32 = converted %.loc17_32, %int.convert_checked.loc17 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc17_5: ref %.40 = splice_block file.%struct_access.var {}
+// CHECK:STDOUT:   %.loc17_34.5: i32 = int_value 0 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc17_34.6: ref i32 = array_index %.loc17_5, %.loc17_34.5
+// CHECK:STDOUT:   %.loc17_34.7: init i32 = initialize_from %.loc17_34.4 to %.loc17_34.6 [template = constants.%.47]
+// CHECK:STDOUT:   %.loc17_34.8: init %.40 = array_init (%.loc17_34.7) to %.loc17_5 [template = constants.%array]
+// CHECK:STDOUT:   %.loc17_36: init %.40 = converted %.loc17_34.1, %.loc17_34.8 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%struct_access.var, %.loc17_36
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 76 - 58
toolchain/check/testdata/eval/fail_aggregate.carbon

@@ -20,27 +20,34 @@ var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]];
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.6: Core.IntLiteral = int_value 7 [template]
+// CHECK:STDOUT:   %.7: Core.IntLiteral = int_value 9 [template]
+// CHECK:STDOUT:   %tuple.type.2: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.8: Core.IntLiteral = int_value 4 [template]
+// CHECK:STDOUT:   %.9: type = array_type %.8, i32 [template]
+// CHECK:STDOUT:   %.11: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.25: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.26: <bound method> = bound_method %.1, %Convert.15 [template]
-// CHECK:STDOUT:   %.27: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %.28: type = array_type %.27, i32 [template]
-// CHECK:STDOUT:   %.30: i32 = int_value 0 [template]
-// CHECK:STDOUT:   %tuple.type.1: type = tuple_type (i32) [template]
-// CHECK:STDOUT:   %.31: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %.32: i32 = int_value 7 [template]
-// CHECK:STDOUT:   %.33: i32 = int_value 9 [template]
-// CHECK:STDOUT:   %tuple.type.2: type = tuple_type (i32, i32, i32, i32) [template]
-// CHECK:STDOUT:   %.34: i32 = int_value 4 [template]
-// CHECK:STDOUT:   %.35: <bound method> = bound_method %.34, %Convert.15 [template]
-// CHECK:STDOUT:   %.36: Core.IntLiteral = int_value 4 [template]
-// CHECK:STDOUT:   %.37: type = array_type %.36, i32 [template]
-// CHECK:STDOUT:   %.39: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.40: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %array: %.37 = tuple_value (%.31, %.32, %.1, %.33) [template]
+// CHECK:STDOUT:   %.35: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.36: <bound method> = bound_method %.5, %Convert.15 [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 5 [template]
+// CHECK:STDOUT:   %.38: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.39: <bound method> = bound_method %.6, %Convert.15 [template]
+// CHECK:STDOUT:   %.40: i32 = int_value 7 [template]
+// CHECK:STDOUT:   %.41: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.42: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.43: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %.44: <bound method> = bound_method %.7, %Convert.15 [template]
+// CHECK:STDOUT:   %.45: i32 = int_value 9 [template]
+// CHECK:STDOUT:   %array: %.9 = tuple_value (%.37, %.40, %.38, %.45) [template]
+// CHECK:STDOUT:   %.46: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %.47: <bound method> = bound_method %.46, %Convert.15 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -59,57 +66,68 @@ var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]];
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc16_24.1: i32 = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc16_24: Core.IntLiteral = int_value 1 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc16_19.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc16_19.2: type = converted %int.make_type_32, %.loc16_19.1 [template = i32]
-// CHECK:STDOUT:   %.loc16_24.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc16_24.3: <bound method> = bound_method %.loc16_24.1, %.loc16_24.2 [template = constants.%.26]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc16_24.3(%.loc16_24.1) [template = constants.%.27]
-// CHECK:STDOUT:   %.loc16_24.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.27]
-// CHECK:STDOUT:   %.loc16_24.5: Core.IntLiteral = converted %.loc16_24.1, %.loc16_24.4 [template = constants.%.27]
-// CHECK:STDOUT:   %.loc16_25: type = array_type %.loc16_24.5, i32 [template = constants.%.28]
-// CHECK:STDOUT:   %array_index.var: ref %.28 = var array_index
-// CHECK:STDOUT:   %array_index: ref %.28 = bind_name array_index, %array_index.var
+// CHECK:STDOUT:   %.loc16_25: type = array_type %.loc16_24, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %array_index.var: ref %.2 = var array_index
+// CHECK:STDOUT:   %array_index: ref %.2 = bind_name array_index, %array_index.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc16_30: i32 = int_value 0 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc16_30: Core.IntLiteral = int_value 0 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc16_32: %tuple.type.1 = tuple_literal (%.loc16_30)
 // CHECK:STDOUT:   %int.make_type_32.loc16_38: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc16_45: i32 = int_value 5 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc16_48: i32 = int_value 7 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc16_51: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc16_54: i32 = int_value 9 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc16_45: Core.IntLiteral = int_value 5 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc16_48: Core.IntLiteral = int_value 7 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc16_51: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc16_54: Core.IntLiteral = int_value 9 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc16_55.1: %tuple.type.2 = tuple_literal (%.loc16_45, %.loc16_48, %.loc16_51, %.loc16_54)
 // CHECK:STDOUT:   %int.make_type_32.loc16_61: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc16_66.1: i32 = int_value 4 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc16_66: Core.IntLiteral = int_value 4 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc16_61.1: type = value_of_initializer %int.make_type_32.loc16_61 [template = i32]
 // CHECK:STDOUT:   %.loc16_61.2: type = converted %int.make_type_32.loc16_61, %.loc16_61.1 [template = i32]
-// CHECK:STDOUT:   %.loc16_66.2: %Convert.type.2 = interface_witness_access constants.%.25, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc16_66.3: <bound method> = bound_method %.loc16_66.1, %.loc16_66.2 [template = constants.%.35]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc16_66.3(%.loc16_66.1) [template = constants.%.36]
-// CHECK:STDOUT:   %.loc16_66.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.36]
-// CHECK:STDOUT:   %.loc16_66.5: Core.IntLiteral = converted %.loc16_66.1, %.loc16_66.4 [template = constants.%.36]
-// CHECK:STDOUT:   %.loc16_67: type = array_type %.loc16_66.5, i32 [template = constants.%.37]
-// CHECK:STDOUT:   %.loc16_55.2: ref %.37 = temporary_storage
-// CHECK:STDOUT:   %.loc16_55.3: i32 = int_value 0 [template = constants.%.30]
-// CHECK:STDOUT:   %.loc16_55.4: ref i32 = array_index %.loc16_55.2, %.loc16_55.3
-// CHECK:STDOUT:   %.loc16_55.5: init i32 = initialize_from %.loc16_45 to %.loc16_55.4 [template = constants.%.31]
-// CHECK:STDOUT:   %.loc16_55.6: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc16_55.7: ref i32 = array_index %.loc16_55.2, %.loc16_55.6
-// CHECK:STDOUT:   %.loc16_55.8: init i32 = initialize_from %.loc16_48 to %.loc16_55.7 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc16_55.9: i32 = int_value 2 [template = constants.%.39]
-// CHECK:STDOUT:   %.loc16_55.10: ref i32 = array_index %.loc16_55.2, %.loc16_55.9
-// CHECK:STDOUT:   %.loc16_55.11: init i32 = initialize_from %.loc16_51 to %.loc16_55.10 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc16_55.12: i32 = int_value 3 [template = constants.%.40]
-// CHECK:STDOUT:   %.loc16_55.13: ref i32 = array_index %.loc16_55.2, %.loc16_55.12
-// CHECK:STDOUT:   %.loc16_55.14: init i32 = initialize_from %.loc16_54 to %.loc16_55.13 [template = constants.%.33]
-// CHECK:STDOUT:   %.loc16_55.15: init %.37 = array_init (%.loc16_55.5, %.loc16_55.8, %.loc16_55.11, %.loc16_55.14) to %.loc16_55.2 [template = constants.%array]
-// CHECK:STDOUT:   %.loc16_57.1: init %.37 = converted %.loc16_55.1, %.loc16_55.15 [template = constants.%array]
-// CHECK:STDOUT:   %.loc16_70: i32 = int_value 2 [template = constants.%.39]
-// CHECK:STDOUT:   %.loc16_57.2: ref %.37 = temporary %.loc16_55.2, %.loc16_57.1
-// CHECK:STDOUT:   %.loc16_71.1: ref i32 = array_index %.loc16_57.2, %.loc16_70
+// CHECK:STDOUT:   %.loc16_67: type = array_type %.loc16_66, i32 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc16_55.2: %Convert.type.2 = interface_witness_access constants.%.35, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_55.3: <bound method> = bound_method %.loc16_45, %.loc16_55.2 [template = constants.%.36]
+// CHECK:STDOUT:   %int.convert_checked.loc16_55.1: init i32 = call %.loc16_55.3(%.loc16_45) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc16_55.4: init i32 = converted %.loc16_45, %int.convert_checked.loc16_55.1 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc16_55.5: ref %.9 = temporary_storage
+// CHECK:STDOUT:   %.loc16_55.6: i32 = int_value 0 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc16_55.7: ref i32 = array_index %.loc16_55.5, %.loc16_55.6
+// CHECK:STDOUT:   %.loc16_55.8: init i32 = initialize_from %.loc16_55.4 to %.loc16_55.7 [template = constants.%.37]
+// CHECK:STDOUT:   %.loc16_55.9: %Convert.type.2 = interface_witness_access constants.%.35, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_55.10: <bound method> = bound_method %.loc16_48, %.loc16_55.9 [template = constants.%.39]
+// CHECK:STDOUT:   %int.convert_checked.loc16_55.2: init i32 = call %.loc16_55.10(%.loc16_48) [template = constants.%.40]
+// CHECK:STDOUT:   %.loc16_55.11: init i32 = converted %.loc16_48, %int.convert_checked.loc16_55.2 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc16_55.12: i32 = int_value 1 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc16_55.13: ref i32 = array_index %.loc16_55.5, %.loc16_55.12
+// CHECK:STDOUT:   %.loc16_55.14: init i32 = initialize_from %.loc16_55.11 to %.loc16_55.13 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc16_55.15: %Convert.type.2 = interface_witness_access constants.%.35, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_55.16: <bound method> = bound_method %.loc16_51, %.loc16_55.15 [template = constants.%.42]
+// CHECK:STDOUT:   %int.convert_checked.loc16_55.3: init i32 = call %.loc16_55.16(%.loc16_51) [template = constants.%.38]
+// CHECK:STDOUT:   %.loc16_55.17: init i32 = converted %.loc16_51, %int.convert_checked.loc16_55.3 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc16_55.18: i32 = int_value 2 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc16_55.19: ref i32 = array_index %.loc16_55.5, %.loc16_55.18
+// CHECK:STDOUT:   %.loc16_55.20: init i32 = initialize_from %.loc16_55.17 to %.loc16_55.19 [template = constants.%.38]
+// CHECK:STDOUT:   %.loc16_55.21: %Convert.type.2 = interface_witness_access constants.%.35, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_55.22: <bound method> = bound_method %.loc16_54, %.loc16_55.21 [template = constants.%.44]
+// CHECK:STDOUT:   %int.convert_checked.loc16_55.4: init i32 = call %.loc16_55.22(%.loc16_54) [template = constants.%.45]
+// CHECK:STDOUT:   %.loc16_55.23: init i32 = converted %.loc16_54, %int.convert_checked.loc16_55.4 [template = constants.%.45]
+// CHECK:STDOUT:   %.loc16_55.24: i32 = int_value 3 [template = constants.%.43]
+// CHECK:STDOUT:   %.loc16_55.25: ref i32 = array_index %.loc16_55.5, %.loc16_55.24
+// CHECK:STDOUT:   %.loc16_55.26: init i32 = initialize_from %.loc16_55.23 to %.loc16_55.25 [template = constants.%.45]
+// CHECK:STDOUT:   %.loc16_55.27: init %.9 = array_init (%.loc16_55.8, %.loc16_55.14, %.loc16_55.20, %.loc16_55.26) to %.loc16_55.5 [template = constants.%array]
+// CHECK:STDOUT:   %.loc16_57.1: init %.9 = converted %.loc16_55.1, %.loc16_55.27 [template = constants.%array]
+// CHECK:STDOUT:   %.loc16_70.1: Core.IntLiteral = int_value 2 [template = constants.%.46]
+// CHECK:STDOUT:   %.loc16_57.2: ref %.9 = temporary %.loc16_55.5, %.loc16_57.1
+// CHECK:STDOUT:   %.loc16_70.2: %Convert.type.2 = interface_witness_access constants.%.35, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc16_70.3: <bound method> = bound_method %.loc16_70.1, %.loc16_70.2 [template = constants.%.47]
+// CHECK:STDOUT:   %int.convert_checked.loc16_70: init i32 = call %.loc16_70.3(%.loc16_70.1) [template = constants.%.41]
+// CHECK:STDOUT:   %.loc16_70.4: i32 = value_of_initializer %int.convert_checked.loc16_70 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc16_70.5: i32 = converted %.loc16_70.1, %.loc16_70.4 [template = constants.%.41]
+// CHECK:STDOUT:   %.loc16_71.1: ref i32 = array_index %.loc16_57.2, %.loc16_70.5
 // CHECK:STDOUT:   %.loc16_71.2: i32 = bind_value %.loc16_71.1
 // CHECK:STDOUT:   %.loc16_38.1: type = value_of_initializer %int.make_type_32.loc16_38 [template = i32]
 // CHECK:STDOUT:   %.loc16_38.2: type = converted %int.make_type_32.loc16_38, %.loc16_38.1 [template = i32]

+ 7 - 19
toolchain/check/testdata/eval/symbolic.carbon

@@ -27,19 +27,12 @@ fn F(T:! type) {
 // CHECK:STDOUT:   %tuple.type.1: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %tuple.type.2: type = tuple_type (%.1, %.2) [symbolic]
 // CHECK:STDOUT:   %.4: type = struct_type {.a: %T} [symbolic]
-// CHECK:STDOUT:   %.5: i32 = int_value 5 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
-// CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
-// CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.29: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.30: <bound method> = bound_method %.5, %Convert.15 [template]
-// CHECK:STDOUT:   %.31: Core.IntLiteral = int_value 5 [template]
-// CHECK:STDOUT:   %.32: type = array_type %.31, %T [symbolic]
+// CHECK:STDOUT:   %.5: Core.IntLiteral = int_value 5 [template]
+// CHECK:STDOUT:   %.6: type = array_type %.5, %T [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .ImplicitAs = %import_ref.1
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -69,7 +62,7 @@ fn F(T:! type) {
 // CHECK:STDOUT:   %.loc13_15.2: type = const_type @F.%T.loc12_6.2 (%T) [symbolic = %.loc13_15.2 (constants.%.2)]
 // CHECK:STDOUT:   %tuple.type: type = tuple_type (@F.%.loc13_12.2 (%.1), @F.%.loc13_15.2 (%.2)) [symbolic = %tuple.type (constants.%tuple.type.2)]
 // CHECK:STDOUT:   %.loc14_16.2: type = struct_type {.a: @F.%T.loc12_6.2 (%T)} [symbolic = %.loc14_16.2 (constants.%.4)]
-// CHECK:STDOUT:   %.loc15_15.2: type = array_type constants.%.31, @F.%T.loc12_6.2 (%T) [symbolic = %.loc15_15.2 (constants.%.32)]
+// CHECK:STDOUT:   %.loc15_15.2: type = array_type constants.%.5, @F.%T.loc12_6.2 (%T) [symbolic = %.loc15_15.2 (constants.%.6)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%T.param_patt: type) {
 // CHECK:STDOUT:   !entry:
@@ -86,15 +79,10 @@ fn F(T:! type) {
 // CHECK:STDOUT:     %v.var: ref @F.%.loc14_16.2 (%.4) = var v
 // CHECK:STDOUT:     %v: ref @F.%.loc14_16.2 (%.4) = bind_name v, %v.var
 // CHECK:STDOUT:     %T.ref.loc15: type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)]
-// CHECK:STDOUT:     %.loc15_14.1: i32 = int_value 5 [template = constants.%.5]
-// CHECK:STDOUT:     %.loc15_14.2: %Convert.type.2 = interface_witness_access constants.%.29, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:     %.loc15_14.3: <bound method> = bound_method %.loc15_14.1, %.loc15_14.2 [template = constants.%.30]
-// CHECK:STDOUT:     %int.convert_checked: init Core.IntLiteral = call %.loc15_14.3(%.loc15_14.1) [template = constants.%.31]
-// CHECK:STDOUT:     %.loc15_14.4: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.31]
-// CHECK:STDOUT:     %.loc15_14.5: Core.IntLiteral = converted %.loc15_14.1, %.loc15_14.4 [template = constants.%.31]
-// CHECK:STDOUT:     %.loc15_15.1: type = array_type %.loc15_14.5, %T [symbolic = %.loc15_15.2 (constants.%.32)]
-// CHECK:STDOUT:     %w.var: ref @F.%.loc15_15.2 (%.32) = var w
-// CHECK:STDOUT:     %w: ref @F.%.loc15_15.2 (%.32) = bind_name w, %w.var
+// CHECK:STDOUT:     %.loc15_14: Core.IntLiteral = int_value 5 [template = constants.%.5]
+// CHECK:STDOUT:     %.loc15_15.1: type = array_type %.loc15_14, %T [symbolic = %.loc15_15.2 (constants.%.6)]
+// CHECK:STDOUT:     %w.var: ref @F.%.loc15_15.2 (%.6) = var w
+// CHECK:STDOUT:     %w: ref @F.%.loc15_15.2 (%.6) = bind_name w, %w.var
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }

+ 2 - 2
toolchain/check/testdata/expr_category/in_place_tuple_init.carbon

@@ -33,7 +33,7 @@ fn H() -> i32 {
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %H.type: type = fn_type @H [template]
 // CHECK:STDOUT:   %H: %H.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 0 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -128,7 +128,7 @@ fn H() -> i32 {
 // CHECK:STDOUT:   %G.ref: %G.type = name_ref G, file.%G.decl [template = constants.%G]
 // CHECK:STDOUT:   %.loc20_11.1: ref %tuple.type.2 = temporary_storage
 // CHECK:STDOUT:   %G.call: init %tuple.type.2 = call %G.ref() to %.loc20_11.1
-// CHECK:STDOUT:   %.loc20_14: i32 = int_value 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc20_14: Core.IntLiteral = int_value 0 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc20_11.2: ref %tuple.type.2 = temporary %.loc20_11.1, %G.call
 // CHECK:STDOUT:   %.loc20_13.1: ref i32 = tuple_access %.loc20_11.2, element0
 // CHECK:STDOUT:   %.loc20_13.2: i32 = bind_value %.loc20_13.1

+ 39 - 21
toolchain/check/testdata/function/builtin/call.carbon

@@ -19,16 +19,24 @@ var arr: [i32; Add(1, 2)];
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Add.type: type = fn_type @Add [template]
 // CHECK:STDOUT:   %Add: %Add.type = struct_value () [template]
-// CHECK:STDOUT:   %.1: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %.2: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.5: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.28: <bound method> = bound_method %.3, %Convert.15 [template]
-// CHECK:STDOUT:   %.29: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.30: type = array_type %.29, i32 [template]
+// CHECK:STDOUT:   %.26: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.27: <bound method> = bound_method %.1, %Convert.15 [template]
+// CHECK:STDOUT:   %.28: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.2, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.31: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.32: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.33: <bound method> = bound_method %.31, %Convert.16 [template]
+// CHECK:STDOUT:   %.34: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.35: type = array_type %.34, i32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -73,21 +81,31 @@ var arr: [i32; Add(1, 2)];
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:   %Add.ref: %Add.type = name_ref Add, %Add.decl [template = constants.%Add]
-// CHECK:STDOUT:   %.loc13_20: i32 = int_value 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc13_23: i32 = int_value 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc13_20, %.loc13_23) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc13_20.1: Core.IntLiteral = int_value 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc13_23.1: Core.IntLiteral = int_value 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc13_20.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_20.3: <bound method> = bound_method %.loc13_20.1, %.loc13_20.2 [template = constants.%.27]
+// CHECK:STDOUT:   %int.convert_checked.loc13_20: init i32 = call %.loc13_20.3(%.loc13_20.1) [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_20.4: i32 = value_of_initializer %int.convert_checked.loc13_20 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_20.5: i32 = converted %.loc13_20.1, %.loc13_20.4 [template = constants.%.28]
+// CHECK:STDOUT:   %.loc13_23.2: %Convert.type.2 = interface_witness_access constants.%.26, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc13_23.3: <bound method> = bound_method %.loc13_23.1, %.loc13_23.2 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc13_23: init i32 = call %.loc13_23.3(%.loc13_23.1) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc13_23.4: i32 = value_of_initializer %int.convert_checked.loc13_23 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc13_23.5: i32 = converted %.loc13_23.1, %.loc13_23.4 [template = constants.%.30]
+// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc13_20.5, %.loc13_23.5) [template = constants.%.31]
 // CHECK:STDOUT:   %.loc13_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc13_11.2: type = converted %int.make_type_32, %.loc13_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc13_19.1: %Convert.type.2 = interface_witness_access constants.%.27, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc13_19.2: <bound method> = bound_method %int.sadd, %.loc13_19.1 [template = constants.%.28]
-// CHECK:STDOUT:   %.loc13_19.3: i32 = value_of_initializer %int.sadd [template = constants.%.3]
-// CHECK:STDOUT:   %.loc13_19.4: i32 = converted %int.sadd, %.loc13_19.3 [template = constants.%.3]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc13_19.2(%.loc13_19.4) [template = constants.%.29]
-// CHECK:STDOUT:   %.loc13_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.29]
-// CHECK:STDOUT:   %.loc13_19.6: Core.IntLiteral = converted %int.sadd, %.loc13_19.5 [template = constants.%.29]
-// CHECK:STDOUT:   %.loc13_25: type = array_type %.loc13_19.6, i32 [template = constants.%.30]
-// CHECK:STDOUT:   %arr.var: ref %.30 = var arr
-// CHECK:STDOUT:   %arr: ref %.30 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc13_19.1: %Convert.type.5 = interface_witness_access constants.%.32, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc13_19.2: <bound method> = bound_method %int.sadd, %.loc13_19.1 [template = constants.%.33]
+// CHECK:STDOUT:   %.loc13_19.3: i32 = value_of_initializer %int.sadd [template = constants.%.31]
+// CHECK:STDOUT:   %.loc13_19.4: i32 = converted %int.sadd, %.loc13_19.3 [template = constants.%.31]
+// CHECK:STDOUT:   %int.convert_checked.loc13_19: init Core.IntLiteral = call %.loc13_19.2(%.loc13_19.4) [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_19.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc13_19 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_19.6: Core.IntLiteral = converted %int.sadd, %.loc13_19.5 [template = constants.%.34]
+// CHECK:STDOUT:   %.loc13_25: type = array_type %.loc13_19.6, i32 [template = constants.%.35]
+// CHECK:STDOUT:   %arr.var: ref %.35 = var arr
+// CHECK:STDOUT:   %arr: ref %.35 = bind_name arr, %arr.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Add(%a.param_patt: i32, %b.param_patt: i32) -> i32 = "int.sadd";

+ 55 - 29
toolchain/check/testdata/function/builtin/method.carbon

@@ -16,7 +16,7 @@ impl i32 as I {
   fn F[self: i32](other: i32) -> i32 = "int.sadd";
 }
 
-var arr: [i32; 1.(I.F)(2)];
+var arr: [i32; (1 as i32).(I.F)(2)];
 
 // CHECK:STDOUT: --- method.carbon
 // CHECK:STDOUT:
@@ -32,23 +32,36 @@ var arr: [i32; 1.(I.F)(2)];
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]
 // CHECK:STDOUT:   %.3: <witness> = interface_witness (%F.2) [template]
-// CHECK:STDOUT:   %.4: i32 = int_value 1 [template]
-// CHECK:STDOUT:   %.5: <bound method> = bound_method %.4, %F.2 [template]
-// CHECK:STDOUT:   %.6: i32 = int_value 2 [template]
-// CHECK:STDOUT:   %.7: i32 = int_value 3 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
+// CHECK:STDOUT:   %.4: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @As(i32) [template]
+// CHECK:STDOUT:   %Convert.type.4: type = fn_type @Convert.2, @ImplicitAs(i32) [template]
+// CHECK:STDOUT:   %Convert.type.7: type = fn_type @Convert.2, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.type.15: type = fn_type @Convert.11 [template]
 // CHECK:STDOUT:   %Convert.15: %Convert.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.31: <witness> = interface_witness (%Convert.15) [template]
-// CHECK:STDOUT:   %.32: <bound method> = bound_method %.7, %Convert.15 [template]
-// CHECK:STDOUT:   %.33: Core.IntLiteral = int_value 3 [template]
-// CHECK:STDOUT:   %.34: type = array_type %.33, i32 [template]
+// CHECK:STDOUT:   %.28: <witness> = interface_witness (%Convert.15) [template]
+// CHECK:STDOUT:   %.29: <bound method> = bound_method %.4, %Convert.15 [template]
+// CHECK:STDOUT:   %.30: i32 = int_value 1 [template]
+// CHECK:STDOUT:   %.31: <bound method> = bound_method %.30, %F.2 [template]
+// CHECK:STDOUT:   %.32: Core.IntLiteral = int_value 2 [template]
+// CHECK:STDOUT:   %Convert.type.16: type = fn_type @Convert.12 [template]
+// CHECK:STDOUT:   %Convert.16: %Convert.type.16 = struct_value () [template]
+// CHECK:STDOUT:   %.34: <witness> = interface_witness (%Convert.16) [template]
+// CHECK:STDOUT:   %.35: <bound method> = bound_method %.32, %Convert.16 [template]
+// CHECK:STDOUT:   %.36: i32 = int_value 2 [template]
+// CHECK:STDOUT:   %.37: i32 = int_value 3 [template]
+// CHECK:STDOUT:   %Convert.type.17: type = fn_type @Convert.13 [template]
+// CHECK:STDOUT:   %Convert.17: %Convert.type.17 = struct_value () [template]
+// CHECK:STDOUT:   %.38: <witness> = interface_witness (%Convert.17) [template]
+// CHECK:STDOUT:   %.39: <bound method> = bound_method %.37, %Convert.17 [template]
+// CHECK:STDOUT:   %.40: Core.IntLiteral = int_value 3 [template]
+// CHECK:STDOUT:   %.41: type = array_type %.40, i32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:     .Int32 = %import_ref.1
-// CHECK:STDOUT:     .ImplicitAs = %import_ref.2
+// CHECK:STDOUT:     .As = %import_ref.2
+// CHECK:STDOUT:     .ImplicitAs = %import_ref.51
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
@@ -68,26 +81,39 @@ var arr: [i32; 1.(I.F)(2)];
 // CHECK:STDOUT:     %.loc15_6.2: type = converted %int.make_type_32, %.loc15_6.1 [template = i32]
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc19_16: i32 = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.make_type_32.loc19_11: init type = call constants.%Int32() [template = i32]
+// CHECK:STDOUT:   %.loc19_17: Core.IntLiteral = int_value 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.make_type_32.loc19_22: init type = call constants.%Int32() [template = i32]
+// CHECK:STDOUT:   %.loc19_22.1: type = value_of_initializer %int.make_type_32.loc19_22 [template = i32]
+// CHECK:STDOUT:   %.loc19_22.2: type = converted %int.make_type_32.loc19_22, %.loc19_22.1 [template = i32]
+// CHECK:STDOUT:   %.loc19_19.1: %Convert.type.2 = interface_witness_access constants.%.28, element0 [template = constants.%Convert.15]
+// CHECK:STDOUT:   %.loc19_19.2: <bound method> = bound_method %.loc19_17, %.loc19_19.1 [template = constants.%.29]
+// CHECK:STDOUT:   %int.convert_checked.loc19_19: init i32 = call %.loc19_19.2(%.loc19_17) [template = constants.%.30]
+// CHECK:STDOUT:   %.loc19_19.3: i32 = value_of_initializer %int.convert_checked.loc19_19 [template = constants.%.30]
+// CHECK:STDOUT:   %.loc19_19.4: i32 = converted %.loc19_17, %.loc19_19.3 [template = constants.%.30]
 // CHECK:STDOUT:   %I.ref: type = name_ref I, %I.decl [template = constants.%I.type]
 // CHECK:STDOUT:   %F.ref: %.1 = name_ref F, @I.%.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc19_17.1: %F.type.1 = interface_witness_access constants.%.3, element0 [template = constants.%F.2]
-// CHECK:STDOUT:   %.loc19_17.2: <bound method> = bound_method %.loc19_16, %.loc19_17.1 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_24: i32 = int_value 2 [template = constants.%.6]
-// CHECK:STDOUT:   %int.sadd: init i32 = call %.loc19_17.2(%.loc19_16, %.loc19_24) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc19_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
-// CHECK:STDOUT:   %.loc19_11.2: type = converted %int.make_type_32, %.loc19_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc19_23.1: %Convert.type.2 = interface_witness_access constants.%.31, element0 [template = constants.%Convert.15]
-// CHECK:STDOUT:   %.loc19_23.2: <bound method> = bound_method %int.sadd, %.loc19_23.1 [template = constants.%.32]
-// CHECK:STDOUT:   %.loc19_23.3: i32 = value_of_initializer %int.sadd [template = constants.%.7]
-// CHECK:STDOUT:   %.loc19_23.4: i32 = converted %int.sadd, %.loc19_23.3 [template = constants.%.7]
-// CHECK:STDOUT:   %int.convert_checked: init Core.IntLiteral = call %.loc19_23.2(%.loc19_23.4) [template = constants.%.33]
-// CHECK:STDOUT:   %.loc19_23.5: Core.IntLiteral = value_of_initializer %int.convert_checked [template = constants.%.33]
-// CHECK:STDOUT:   %.loc19_23.6: Core.IntLiteral = converted %int.sadd, %.loc19_23.5 [template = constants.%.33]
-// CHECK:STDOUT:   %.loc19_26: type = array_type %.loc19_23.6, i32 [template = constants.%.34]
-// CHECK:STDOUT:   %arr.var: ref %.34 = var arr
-// CHECK:STDOUT:   %arr: ref %.34 = bind_name arr, %arr.var
+// CHECK:STDOUT:   %.loc19_26.1: %F.type.1 = interface_witness_access constants.%.3, element0 [template = constants.%F.2]
+// CHECK:STDOUT:   %.loc19_26.2: <bound method> = bound_method %.loc19_19.4, %.loc19_26.1 [template = constants.%.31]
+// CHECK:STDOUT:   %.loc19_33.1: Core.IntLiteral = int_value 2 [template = constants.%.32]
+// CHECK:STDOUT:   %.loc19_33.2: %Convert.type.4 = interface_witness_access constants.%.34, element0 [template = constants.%Convert.16]
+// CHECK:STDOUT:   %.loc19_33.3: <bound method> = bound_method %.loc19_33.1, %.loc19_33.2 [template = constants.%.35]
+// CHECK:STDOUT:   %int.convert_checked.loc19_33: init i32 = call %.loc19_33.3(%.loc19_33.1) [template = constants.%.36]
+// CHECK:STDOUT:   %.loc19_33.4: i32 = value_of_initializer %int.convert_checked.loc19_33 [template = constants.%.36]
+// CHECK:STDOUT:   %.loc19_33.5: i32 = converted %.loc19_33.1, %.loc19_33.4 [template = constants.%.36]
+// CHECK:STDOUT:   %int.sadd: init i32 = call %.loc19_26.2(%.loc19_19.4, %.loc19_33.5) [template = constants.%.37]
+// CHECK:STDOUT:   %.loc19_11.1: type = value_of_initializer %int.make_type_32.loc19_11 [template = i32]
+// CHECK:STDOUT:   %.loc19_11.2: type = converted %int.make_type_32.loc19_11, %.loc19_11.1 [template = i32]
+// CHECK:STDOUT:   %.loc19_32.1: %Convert.type.7 = interface_witness_access constants.%.38, element0 [template = constants.%Convert.17]
+// CHECK:STDOUT:   %.loc19_32.2: <bound method> = bound_method %int.sadd, %.loc19_32.1 [template = constants.%.39]
+// CHECK:STDOUT:   %.loc19_32.3: i32 = value_of_initializer %int.sadd [template = constants.%.37]
+// CHECK:STDOUT:   %.loc19_32.4: i32 = converted %int.sadd, %.loc19_32.3 [template = constants.%.37]
+// CHECK:STDOUT:   %int.convert_checked.loc19_32: init Core.IntLiteral = call %.loc19_32.2(%.loc19_32.4) [template = constants.%.40]
+// CHECK:STDOUT:   %.loc19_32.5: Core.IntLiteral = value_of_initializer %int.convert_checked.loc19_32 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc19_32.6: Core.IntLiteral = converted %int.sadd, %.loc19_32.5 [template = constants.%.40]
+// CHECK:STDOUT:   %.loc19_35: type = array_type %.loc19_32.6, i32 [template = constants.%.41]
+// CHECK:STDOUT:   %arr.var: ref %.41 = var arr
+// CHECK:STDOUT:   %arr: ref %.41 = bind_name arr, %arr.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {

Некоторые файлы не были показаны из-за большого количества измененных файлов