فهرست منبع

Remove BinaryOperatorAdd (#3469)

BinaryOperatorAdd had been added early on as a proof-of-concept for
toolchain design for parsing -> checking flow. However, it doesn't
reflect the interface direction for operators, and now other portions of
the toolchain demonstrate the relevant logic. Instead, it's just a bit
of an outlier versus other instructions which have evolved over time.
Jon Ross-Perkins 2 سال پیش
والد
کامیت
8ace1dcb78

+ 0 - 1
toolchain/check/context.cpp

@@ -830,7 +830,6 @@ class TypeCompleter {
       case SemIR::ArrayInit::Kind:
       case SemIR::Assign::Kind:
       case SemIR::BaseDecl::Kind:
-      case SemIR::BinaryOperatorAdd::Kind:
       case SemIR::BindName::Kind:
       case SemIR::BindValue::Kind:
       case SemIR::BlockArg::Kind:

+ 0 - 13
toolchain/check/handle_operator.cpp

@@ -14,19 +14,6 @@ auto HandleInfixOperator(Context& context, Parse::NodeId parse_node) -> bool {
   // Figure out the operator for the token.
   auto token = context.parse_tree().node_token(parse_node);
   switch (auto token_kind = context.tokens().GetKind(token)) {
-    case Lex::TokenKind::Plus:
-      // TODO: This should search for a compatible interface. For now, it's a
-      // very trivial check of validity on the operation.
-      lhs_id = ConvertToValueOfType(context, parse_node, lhs_id,
-                                    context.insts().Get(rhs_id).type_id());
-      rhs_id = ConvertToValueExpr(context, rhs_id);
-
-      context.AddInstAndPush(
-          parse_node, SemIR::BinaryOperatorAdd{
-                          parse_node, context.insts().Get(lhs_id).type_id(),
-                          lhs_id, rhs_id});
-      return true;
-
     case Lex::TokenKind::And:
     case Lex::TokenKind::Or: {
       // The first operand is wrapped in a ShortCircuitOperand, which we

+ 11 - 8
toolchain/check/testdata/basics/parens.carbon

@@ -4,17 +4,20 @@
 //
 // AUTOUPDATE
 
-var test_i32: i32 = ((1) + (2));
+var a: i32 = (1);
+var b: i32 = ((2));
 
 // CHECK:STDOUT: --- parens.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.test_i32 = %test_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:   %.loc7_23: i32 = int_literal 1
-// CHECK:STDOUT:   %.loc7_29: i32 = int_literal 2
-// CHECK:STDOUT:   %.loc7_26: i32 = add %.loc7_23, %.loc7_29
-// CHECK:STDOUT:   assign %test_i32.var, %.loc7_26
+// CHECK:STDOUT:   package: <namespace> = namespace {.a = %a, .b = %b}
+// CHECK:STDOUT:   %a.var: ref i32 = var a
+// CHECK:STDOUT:   %a: ref i32 = bind_name a, %a.var
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 1
+// CHECK:STDOUT:   assign %a.var, %.loc7
+// CHECK:STDOUT:   %b.var: ref i32 = var b
+// CHECK:STDOUT:   %b: ref i32 = bind_name b, %b.var
+// CHECK:STDOUT:   %.loc8: i32 = int_literal 2
+// CHECK:STDOUT:   assign %b.var, %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 42 - 34
toolchain/check/testdata/basics/raw_and_textual_ir.carbon

@@ -8,8 +8,8 @@
 //
 // AUTOUPDATE
 
-fn Foo(n: i32) -> (i32, f64) {
-  return (n + 2, 3.4);
+fn Foo(n: i32) -> (i32, i32, f64) {
+  return (n, 2, 3.4);
 }
 
 // CHECK:STDOUT: ---
@@ -31,9 +31,11 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT:     typeBlock0:
 // CHECK:STDOUT:       0:               typeTypeType
 // CHECK:STDOUT:       1:               typeTypeType
+// CHECK:STDOUT:       2:               typeTypeType
 // CHECK:STDOUT:     typeBlock1:
 // CHECK:STDOUT:       0:               type1
-// CHECK:STDOUT:       1:               type3
+// CHECK:STDOUT:       1:               type1
+// CHECK:STDOUT:       2:               type3
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     inst+0:          {kind: Namespace, arg0: name_scope0, type: type0}
 // CHECK:STDOUT:     inst+1:          {kind: Param, arg0: name1, type: type1}
@@ -45,24 +47,26 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT:     inst+7:          {kind: PointerType, arg0: type4, type: typeTypeType}
 // CHECK:STDOUT:     inst+8:          {kind: FunctionDecl, arg0: function0, type: type6}
 // CHECK:STDOUT:     inst+9:          {kind: NameRef, arg0: name1, arg1: inst+1, type: type1}
-// CHECK:STDOUT:     inst+10:         {kind: IntLiteral, arg0: int3, type: type1}
-// CHECK:STDOUT:     inst+11:         {kind: BinaryOperatorAdd, arg0: inst+9, arg1: inst+10, type: type1}
-// CHECK:STDOUT:     inst+12:         {kind: RealLiteral, arg0: real0, type: type3}
-// CHECK:STDOUT:     inst+13:         {kind: TupleLiteral, arg0: block5, type: type4}
-// CHECK:STDOUT:     inst+14:         {kind: TupleAccess, arg0: inst+6, arg1: element0, type: type1}
-// CHECK:STDOUT:     inst+15:         {kind: InitializeFrom, arg0: inst+11, arg1: inst+14, type: type1}
-// CHECK:STDOUT:     inst+16:         {kind: TupleAccess, arg0: inst+6, arg1: element1, type: type3}
-// CHECK:STDOUT:     inst+17:         {kind: InitializeFrom, arg0: inst+12, arg1: inst+16, type: type3}
-// CHECK:STDOUT:     inst+18:         {kind: TupleInit, arg0: block6, arg1: inst+6, type: type4}
-// CHECK:STDOUT:     inst+19:         {kind: Converted, arg0: inst+13, arg1: inst+18, type: type4}
-// CHECK:STDOUT:     inst+20:         {kind: ReturnExpr, arg0: inst+19}
+// CHECK:STDOUT:     inst+10:         {kind: IntLiteral, arg0: int4, type: type1}
+// CHECK:STDOUT:     inst+11:         {kind: RealLiteral, arg0: real0, type: type3}
+// CHECK:STDOUT:     inst+12:         {kind: TupleLiteral, arg0: block5, type: type4}
+// CHECK:STDOUT:     inst+13:         {kind: TupleAccess, arg0: inst+6, arg1: element0, type: type1}
+// CHECK:STDOUT:     inst+14:         {kind: InitializeFrom, arg0: inst+9, arg1: inst+13, type: type1}
+// CHECK:STDOUT:     inst+15:         {kind: TupleAccess, arg0: inst+6, arg1: element1, type: type1}
+// CHECK:STDOUT:     inst+16:         {kind: InitializeFrom, arg0: inst+10, arg1: inst+15, type: type1}
+// CHECK:STDOUT:     inst+17:         {kind: TupleAccess, arg0: inst+6, arg1: element2, type: type3}
+// CHECK:STDOUT:     inst+18:         {kind: InitializeFrom, arg0: inst+11, arg1: inst+17, type: type3}
+// CHECK:STDOUT:     inst+19:         {kind: TupleInit, arg0: block6, arg1: inst+6, type: type4}
+// CHECK:STDOUT:     inst+20:         {kind: Converted, arg0: inst+12, arg1: inst+19, type: type4}
+// CHECK:STDOUT:     inst+21:         {kind: ReturnExpr, arg0: inst+20}
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     block0:          {}
 // CHECK:STDOUT:     block1:
 // CHECK:STDOUT:       0:               inst+1
 // CHECK:STDOUT:     block2:
 // CHECK:STDOUT:       0:               instIntType
-// CHECK:STDOUT:       1:               instFloatType
+// CHECK:STDOUT:       1:               instIntType
+// CHECK:STDOUT:       2:               instFloatType
 // CHECK:STDOUT:     block3:
 // CHECK:STDOUT:       0:               inst+1
 // CHECK:STDOUT:       1:               inst+3
@@ -81,12 +85,15 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT:       9:               inst+18
 // CHECK:STDOUT:       10:              inst+19
 // CHECK:STDOUT:       11:              inst+20
+// CHECK:STDOUT:       12:              inst+21
 // CHECK:STDOUT:     block5:
-// CHECK:STDOUT:       0:               inst+11
-// CHECK:STDOUT:       1:               inst+12
+// CHECK:STDOUT:       0:               inst+9
+// CHECK:STDOUT:       1:               inst+10
+// CHECK:STDOUT:       2:               inst+11
 // CHECK:STDOUT:     block6:
-// CHECK:STDOUT:       0:               inst+15
-// CHECK:STDOUT:       1:               inst+17
+// CHECK:STDOUT:       0:               inst+14
+// CHECK:STDOUT:       1:               inst+16
+// CHECK:STDOUT:       2:               inst+18
 // CHECK:STDOUT:     block7:
 // CHECK:STDOUT:       0:               inst+0
 // CHECK:STDOUT:       1:               inst+8
@@ -95,9 +102,9 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT: --- raw_and_textual_ir.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11_28.1: type = tuple_type (type, type)
-// CHECK:STDOUT:   %.loc11_28.2: type = tuple_type (i32, f64)
-// CHECK:STDOUT:   %.loc11_28.3: type = ptr_type (i32, f64)
+// CHECK:STDOUT:   %.loc11_33.1: type = tuple_type (type, type, type)
+// CHECK:STDOUT:   %.loc11_33.2: type = tuple_type (i32, i32, f64)
+// CHECK:STDOUT:   %.loc11_33.3: type = ptr_type (i32, i32, f64)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -105,19 +112,20 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Foo(%n: i32) -> %return: (i32, f64) {
+// CHECK:STDOUT: fn @Foo(%n: i32) -> %return: (i32, i32, f64) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %n.ref: i32 = name_ref n, %n
-// CHECK:STDOUT:   %.loc12_15: i32 = int_literal 2
-// CHECK:STDOUT:   %.loc12_13: i32 = add %n.ref, %.loc12_15
-// CHECK:STDOUT:   %.loc12_18: f64 = real_literal 34e-1
-// CHECK:STDOUT:   %.loc12_21.1: (i32, f64) = tuple_literal (%.loc12_13, %.loc12_18)
-// CHECK:STDOUT:   %.loc12_21.2: ref i32 = tuple_access %return, element0
-// CHECK:STDOUT:   %.loc12_21.3: init i32 = initialize_from %.loc12_13 to %.loc12_21.2
-// CHECK:STDOUT:   %.loc12_21.4: ref f64 = tuple_access %return, element1
-// CHECK:STDOUT:   %.loc12_21.5: init f64 = initialize_from %.loc12_18 to %.loc12_21.4
-// CHECK:STDOUT:   %.loc12_21.6: init (i32, f64) = tuple_init (%.loc12_21.3, %.loc12_21.5) to %return
-// CHECK:STDOUT:   %.loc12_21.7: init (i32, f64) = converted %.loc12_21.1, %.loc12_21.6
-// CHECK:STDOUT:   return %.loc12_21.7
+// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2
+// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1
+// CHECK:STDOUT:   %.loc12_20.1: (i32, i32, f64) = tuple_literal (%n.ref, %.loc12_14, %.loc12_17)
+// CHECK:STDOUT:   %.loc12_20.2: ref i32 = tuple_access %return, element0
+// CHECK:STDOUT:   %.loc12_20.3: init i32 = initialize_from %n.ref to %.loc12_20.2
+// CHECK:STDOUT:   %.loc12_20.4: ref i32 = tuple_access %return, element1
+// CHECK:STDOUT:   %.loc12_20.5: init i32 = initialize_from %.loc12_14 to %.loc12_20.4
+// CHECK:STDOUT:   %.loc12_20.6: ref f64 = tuple_access %return, element2
+// CHECK:STDOUT:   %.loc12_20.7: init f64 = initialize_from %.loc12_17 to %.loc12_20.6
+// CHECK:STDOUT:   %.loc12_20.8: init (i32, i32, f64) = tuple_init (%.loc12_20.3, %.loc12_20.5, %.loc12_20.7) to %return
+// CHECK:STDOUT:   %.loc12_20.9: init (i32, i32, f64) = converted %.loc12_20.1, %.loc12_20.8
+// CHECK:STDOUT:   return %.loc12_20.9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 26 - 19
toolchain/check/testdata/basics/raw_ir.carbon

@@ -8,8 +8,8 @@
 //
 // AUTOUPDATE
 
-fn Foo(n: i32) -> (i32, f64) {
-  return (n + 2, 3.4);
+fn Foo(n: i32) -> (i32, i32, f64) {
+  return (n, 2, 3.4);
 }
 
 // CHECK:STDOUT: ---
@@ -31,9 +31,11 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT:     typeBlock0:
 // CHECK:STDOUT:       0:               typeTypeType
 // CHECK:STDOUT:       1:               typeTypeType
+// CHECK:STDOUT:       2:               typeTypeType
 // CHECK:STDOUT:     typeBlock1:
 // CHECK:STDOUT:       0:               type1
-// CHECK:STDOUT:       1:               type3
+// CHECK:STDOUT:       1:               type1
+// CHECK:STDOUT:       2:               type3
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     inst+0:          {kind: Namespace, arg0: name_scope0, type: type0}
 // CHECK:STDOUT:     inst+1:          {kind: Param, arg0: name1, type: type1}
@@ -45,24 +47,26 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT:     inst+7:          {kind: PointerType, arg0: type4, type: typeTypeType}
 // CHECK:STDOUT:     inst+8:          {kind: FunctionDecl, arg0: function0, type: type6}
 // CHECK:STDOUT:     inst+9:          {kind: NameRef, arg0: name1, arg1: inst+1, type: type1}
-// CHECK:STDOUT:     inst+10:         {kind: IntLiteral, arg0: int3, type: type1}
-// CHECK:STDOUT:     inst+11:         {kind: BinaryOperatorAdd, arg0: inst+9, arg1: inst+10, type: type1}
-// CHECK:STDOUT:     inst+12:         {kind: RealLiteral, arg0: real0, type: type3}
-// CHECK:STDOUT:     inst+13:         {kind: TupleLiteral, arg0: block5, type: type4}
-// CHECK:STDOUT:     inst+14:         {kind: TupleAccess, arg0: inst+6, arg1: element0, type: type1}
-// CHECK:STDOUT:     inst+15:         {kind: InitializeFrom, arg0: inst+11, arg1: inst+14, type: type1}
-// CHECK:STDOUT:     inst+16:         {kind: TupleAccess, arg0: inst+6, arg1: element1, type: type3}
-// CHECK:STDOUT:     inst+17:         {kind: InitializeFrom, arg0: inst+12, arg1: inst+16, type: type3}
-// CHECK:STDOUT:     inst+18:         {kind: TupleInit, arg0: block6, arg1: inst+6, type: type4}
-// CHECK:STDOUT:     inst+19:         {kind: Converted, arg0: inst+13, arg1: inst+18, type: type4}
-// CHECK:STDOUT:     inst+20:         {kind: ReturnExpr, arg0: inst+19}
+// CHECK:STDOUT:     inst+10:         {kind: IntLiteral, arg0: int4, type: type1}
+// CHECK:STDOUT:     inst+11:         {kind: RealLiteral, arg0: real0, type: type3}
+// CHECK:STDOUT:     inst+12:         {kind: TupleLiteral, arg0: block5, type: type4}
+// CHECK:STDOUT:     inst+13:         {kind: TupleAccess, arg0: inst+6, arg1: element0, type: type1}
+// CHECK:STDOUT:     inst+14:         {kind: InitializeFrom, arg0: inst+9, arg1: inst+13, type: type1}
+// CHECK:STDOUT:     inst+15:         {kind: TupleAccess, arg0: inst+6, arg1: element1, type: type1}
+// CHECK:STDOUT:     inst+16:         {kind: InitializeFrom, arg0: inst+10, arg1: inst+15, type: type1}
+// CHECK:STDOUT:     inst+17:         {kind: TupleAccess, arg0: inst+6, arg1: element2, type: type3}
+// CHECK:STDOUT:     inst+18:         {kind: InitializeFrom, arg0: inst+11, arg1: inst+17, type: type3}
+// CHECK:STDOUT:     inst+19:         {kind: TupleInit, arg0: block6, arg1: inst+6, type: type4}
+// CHECK:STDOUT:     inst+20:         {kind: Converted, arg0: inst+12, arg1: inst+19, type: type4}
+// CHECK:STDOUT:     inst+21:         {kind: ReturnExpr, arg0: inst+20}
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     block0:          {}
 // CHECK:STDOUT:     block1:
 // CHECK:STDOUT:       0:               inst+1
 // CHECK:STDOUT:     block2:
 // CHECK:STDOUT:       0:               instIntType
-// CHECK:STDOUT:       1:               instFloatType
+// CHECK:STDOUT:       1:               instIntType
+// CHECK:STDOUT:       2:               instFloatType
 // CHECK:STDOUT:     block3:
 // CHECK:STDOUT:       0:               inst+1
 // CHECK:STDOUT:       1:               inst+3
@@ -81,12 +85,15 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT:       9:               inst+18
 // CHECK:STDOUT:       10:              inst+19
 // CHECK:STDOUT:       11:              inst+20
+// CHECK:STDOUT:       12:              inst+21
 // CHECK:STDOUT:     block5:
-// CHECK:STDOUT:       0:               inst+11
-// CHECK:STDOUT:       1:               inst+12
+// CHECK:STDOUT:       0:               inst+9
+// CHECK:STDOUT:       1:               inst+10
+// CHECK:STDOUT:       2:               inst+11
 // CHECK:STDOUT:     block6:
-// CHECK:STDOUT:       0:               inst+15
-// CHECK:STDOUT:       1:               inst+17
+// CHECK:STDOUT:       0:               inst+14
+// CHECK:STDOUT:       1:               inst+16
+// CHECK:STDOUT:       2:               inst+18
 // CHECK:STDOUT:     block7:
 // CHECK:STDOUT:       0:               inst+0
 // CHECK:STDOUT:       1:               inst+8

+ 18 - 17
toolchain/check/testdata/basics/textual_ir.carbon

@@ -8,16 +8,16 @@
 //
 // AUTOUPDATE
 
-fn Foo(n: i32) -> (i32, f64) {
-  return (n + 2, 3.4);
+fn Foo(n: i32) -> (i32, i32, f64) {
+  return (n, 2, 3.4);
 }
 
 // CHECK:STDOUT: --- textual_ir.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11_28.1: type = tuple_type (type, type)
-// CHECK:STDOUT:   %.loc11_28.2: type = tuple_type (i32, f64)
-// CHECK:STDOUT:   %.loc11_28.3: type = ptr_type (i32, f64)
+// CHECK:STDOUT:   %.loc11_33.1: type = tuple_type (type, type, type)
+// CHECK:STDOUT:   %.loc11_33.2: type = tuple_type (i32, i32, f64)
+// CHECK:STDOUT:   %.loc11_33.3: type = ptr_type (i32, i32, f64)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -25,19 +25,20 @@ fn Foo(n: i32) -> (i32, f64) {
 // CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Foo(%n: i32) -> %return: (i32, f64) {
+// CHECK:STDOUT: fn @Foo(%n: i32) -> %return: (i32, i32, f64) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %n.ref: i32 = name_ref n, %n
-// CHECK:STDOUT:   %.loc12_15: i32 = int_literal 2
-// CHECK:STDOUT:   %.loc12_13: i32 = add %n.ref, %.loc12_15
-// CHECK:STDOUT:   %.loc12_18: f64 = real_literal 34e-1
-// CHECK:STDOUT:   %.loc12_21.1: (i32, f64) = tuple_literal (%.loc12_13, %.loc12_18)
-// CHECK:STDOUT:   %.loc12_21.2: ref i32 = tuple_access %return, element0
-// CHECK:STDOUT:   %.loc12_21.3: init i32 = initialize_from %.loc12_13 to %.loc12_21.2
-// CHECK:STDOUT:   %.loc12_21.4: ref f64 = tuple_access %return, element1
-// CHECK:STDOUT:   %.loc12_21.5: init f64 = initialize_from %.loc12_18 to %.loc12_21.4
-// CHECK:STDOUT:   %.loc12_21.6: init (i32, f64) = tuple_init (%.loc12_21.3, %.loc12_21.5) to %return
-// CHECK:STDOUT:   %.loc12_21.7: init (i32, f64) = converted %.loc12_21.1, %.loc12_21.6
-// CHECK:STDOUT:   return %.loc12_21.7
+// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2
+// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1
+// CHECK:STDOUT:   %.loc12_20.1: (i32, i32, f64) = tuple_literal (%n.ref, %.loc12_14, %.loc12_17)
+// CHECK:STDOUT:   %.loc12_20.2: ref i32 = tuple_access %return, element0
+// CHECK:STDOUT:   %.loc12_20.3: init i32 = initialize_from %n.ref to %.loc12_20.2
+// CHECK:STDOUT:   %.loc12_20.4: ref i32 = tuple_access %return, element1
+// CHECK:STDOUT:   %.loc12_20.5: init i32 = initialize_from %.loc12_14 to %.loc12_20.4
+// CHECK:STDOUT:   %.loc12_20.6: ref f64 = tuple_access %return, element2
+// CHECK:STDOUT:   %.loc12_20.7: init f64 = initialize_from %.loc12_17 to %.loc12_20.6
+// CHECK:STDOUT:   %.loc12_20.8: init (i32, i32, f64) = tuple_init (%.loc12_20.3, %.loc12_20.5, %.loc12_20.7) to %return
+// CHECK:STDOUT:   %.loc12_20.9: init (i32, i32, f64) = converted %.loc12_20.1, %.loc12_20.8
+// CHECK:STDOUT:   return %.loc12_20.9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 17 - 11
toolchain/check/testdata/class/field_access.carbon

@@ -9,11 +9,12 @@ class Class {
   var k: i32;
 }
 
-fn Run() -> i32 {
+fn Run() {
   var c: Class;
   c.j = 1;
   c.k = 2;
-  return c.j + c.k;
+  var cj: i32 = c.j;
+  var ck: i32 = c.k;
 }
 
 // CHECK:STDOUT: --- field_access.carbon
@@ -43,7 +44,7 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   .k = %k
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Run() -> i32 {
+// CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class
 // CHECK:STDOUT:   %c.var: ref Class = var c
@@ -56,13 +57,18 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   %.loc15_4: ref i32 = class_element_access %c.ref.loc15, element1
 // CHECK:STDOUT:   %.loc15_9: i32 = int_literal 2
 // CHECK:STDOUT:   assign %.loc15_4, %.loc15_9
-// CHECK:STDOUT:   %c.ref.loc16_10: ref Class = name_ref c, %c
-// CHECK:STDOUT:   %.loc16_11.1: ref i32 = class_element_access %c.ref.loc16_10, element0
-// CHECK:STDOUT:   %c.ref.loc16_16: ref Class = name_ref c, %c
-// CHECK:STDOUT:   %.loc16_17.1: ref i32 = class_element_access %c.ref.loc16_16, element1
-// CHECK:STDOUT:   %.loc16_11.2: i32 = bind_value %.loc16_11.1
-// CHECK:STDOUT:   %.loc16_17.2: i32 = bind_value %.loc16_17.1
-// CHECK:STDOUT:   %.loc16_14: i32 = add %.loc16_11.2, %.loc16_17.2
-// CHECK:STDOUT:   return %.loc16_14
+// CHECK:STDOUT:   %cj.var: ref i32 = var cj
+// CHECK:STDOUT:   %cj: ref i32 = bind_name cj, %cj.var
+// CHECK:STDOUT:   %c.ref.loc16: ref Class = name_ref c, %c
+// CHECK:STDOUT:   %.loc16_18.1: ref i32 = class_element_access %c.ref.loc16, element0
+// CHECK:STDOUT:   %.loc16_18.2: i32 = bind_value %.loc16_18.1
+// CHECK:STDOUT:   assign %cj.var, %.loc16_18.2
+// CHECK:STDOUT:   %ck.var: ref i32 = var ck
+// CHECK:STDOUT:   %ck: ref i32 = bind_name ck, %ck.var
+// CHECK:STDOUT:   %c.ref.loc17: ref Class = name_ref c, %c
+// CHECK:STDOUT:   %.loc17_18.1: ref i32 = class_element_access %c.ref.loc17, element1
+// CHECK:STDOUT:   %.loc17_18.2: i32 = bind_value %.loc17_18.1
+// CHECK:STDOUT:   assign %ck.var, %.loc17_18.2
+// CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 19 - 13
toolchain/check/testdata/class/field_access_in_value.carbon

@@ -9,12 +9,13 @@ class Class {
   var k: i32;
 }
 
-fn Run() -> i32 {
+fn Test() {
   var cv: Class;
   cv.j = 1;
   cv.k = 2;
   let c: Class = cv;
-  return c.j + c.k;
+  var cj: i32 = c.j;
+  var ck: i32 = c.k;
 }
 
 // CHECK:STDOUT: --- field_access_in_value.carbon
@@ -25,10 +26,10 @@ fn Run() -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.Class = %Class.decl, .Run = %Run}
+// CHECK:STDOUT:   package: <namespace> = namespace {.Class = %Class.decl, .Test = %Test}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
 // CHECK:STDOUT:   %Class: type = class_type @Class
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run
+// CHECK:STDOUT:   %Test: <function> = fn_decl @Test
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
@@ -44,7 +45,7 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   .k = %k
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Run() -> i32 {
+// CHECK:STDOUT: fn @Test() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Class.ref.loc13: type = name_ref Class, file.%Class
 // CHECK:STDOUT:   %cv.var: ref Class = var cv
@@ -61,13 +62,18 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   %cv.ref.loc16: ref Class = name_ref cv, %cv
 // CHECK:STDOUT:   %.loc16: Class = bind_value %cv.ref.loc16
 // CHECK:STDOUT:   %c: Class = bind_name c, %.loc16
-// CHECK:STDOUT:   %c.ref.loc17_10: Class = name_ref c, %c
-// CHECK:STDOUT:   %.loc17_11.1: ref i32 = class_element_access %c.ref.loc17_10, element0
-// CHECK:STDOUT:   %.loc17_11.2: i32 = bind_value %.loc17_11.1
-// CHECK:STDOUT:   %c.ref.loc17_16: Class = name_ref c, %c
-// CHECK:STDOUT:   %.loc17_17.1: ref i32 = class_element_access %c.ref.loc17_16, element1
-// CHECK:STDOUT:   %.loc17_17.2: i32 = bind_value %.loc17_17.1
-// CHECK:STDOUT:   %.loc17_14: i32 = add %.loc17_11.2, %.loc17_17.2
-// CHECK:STDOUT:   return %.loc17_14
+// CHECK:STDOUT:   %cj.var: ref i32 = var cj
+// CHECK:STDOUT:   %cj: ref i32 = bind_name cj, %cj.var
+// CHECK:STDOUT:   %c.ref.loc17: Class = name_ref c, %c
+// CHECK:STDOUT:   %.loc17_18.1: ref i32 = class_element_access %c.ref.loc17, element0
+// CHECK:STDOUT:   %.loc17_18.2: i32 = bind_value %.loc17_18.1
+// CHECK:STDOUT:   assign %cj.var, %.loc17_18.2
+// CHECK:STDOUT:   %ck.var: ref i32 = var ck
+// CHECK:STDOUT:   %ck: ref i32 = bind_name ck, %ck.var
+// CHECK:STDOUT:   %c.ref.loc18: Class = name_ref c, %c
+// CHECK:STDOUT:   %.loc18_18.1: ref i32 = class_element_access %c.ref.loc18, element1
+// CHECK:STDOUT:   %.loc18_18.2: i32 = bind_value %.loc18_18.1
+// CHECK:STDOUT:   assign %ck.var, %.loc18_18.2
+// CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 15 - 13
toolchain/check/testdata/class/scope.carbon

@@ -18,8 +18,9 @@ fn F() -> i32 {
   return 2;
 }
 
-fn Run() -> i32 {
-  return F() + Class.F();
+fn Run() {
+  var a: i32 = F();
+  var b: i32 = Class.F();
 }
 
 // CHECK:STDOUT: --- scope.carbon
@@ -66,18 +67,19 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   return %.loc18
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Run() -> i32 {
+// CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref.loc22_10: <function> = name_ref F, file.%F
-// CHECK:STDOUT:   %.loc22_11: init i32 = call %F.ref.loc22_10()
+// CHECK:STDOUT:   %a.var: ref i32 = var a
+// CHECK:STDOUT:   %a: ref i32 = bind_name a, %a.var
+// CHECK:STDOUT:   %F.ref.loc22: <function> = name_ref F, file.%F
+// CHECK:STDOUT:   %.loc22: init i32 = call %F.ref.loc22()
+// CHECK:STDOUT:   assign %a.var, %.loc22
+// CHECK:STDOUT:   %b.var: ref i32 = var b
+// CHECK:STDOUT:   %b: ref i32 = bind_name b, %b.var
 // CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class
-// CHECK:STDOUT:   %F.ref.loc22_21: <function> = name_ref F, @Class.%F
-// CHECK:STDOUT:   %.loc22_23.1: init i32 = call %F.ref.loc22_21()
-// CHECK:STDOUT:   %.loc22_14.1: i32 = value_of_initializer %.loc22_11
-// CHECK:STDOUT:   %.loc22_14.2: i32 = converted %.loc22_11, %.loc22_14.1
-// CHECK:STDOUT:   %.loc22_23.2: i32 = value_of_initializer %.loc22_23.1
-// CHECK:STDOUT:   %.loc22_23.3: i32 = converted %.loc22_23.1, %.loc22_23.2
-// CHECK:STDOUT:   %.loc22_14.3: i32 = add %.loc22_14.2, %.loc22_23.3
-// CHECK:STDOUT:   return %.loc22_14.3
+// CHECK:STDOUT:   %F.ref.loc23: <function> = name_ref F, @Class.%F
+// CHECK:STDOUT:   %.loc23: init i32 = call %F.ref.loc23()
+// CHECK:STDOUT:   assign %b.var, %.loc23
+// CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 23 - 15
toolchain/check/testdata/function/call/more_param_ir.carbon

@@ -4,17 +4,20 @@
 //
 // AUTOUPDATE
 
-fn Foo(a: i32, b: i32, c: i32) {}
+fn Foo(a: i32, b: i32) {}
 
 fn Main() {
-  // Generates multiple IR instructions for the first two parameters.
-  Foo(1 + 2 + 3, 4 + 5, 6);
+  var x: (i32,) = (1,);
+  // Generates multiple IR instructions for the first parameter.
+  Foo(x[0], 6);
 }
 
 // CHECK:STDOUT: --- more_param_ir.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11: type = tuple_type ()
+// CHECK:STDOUT:   %.loc10_15.1: type = tuple_type (type)
+// CHECK:STDOUT:   %.loc10_15.2: type = tuple_type (i32)
+// CHECK:STDOUT:   %.loc12: type = tuple_type ()
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -23,24 +26,29 @@ fn Main() {
 // CHECK:STDOUT:   %Main: <function> = fn_decl @Main
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Foo(%a: i32, %b: i32, %c: i32) {
+// CHECK:STDOUT: fn @Foo(%a: i32, %b: i32) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() {
 // CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %.loc10_15.1: (type,) = tuple_literal (i32)
+// CHECK:STDOUT:   %.loc10_15.2: type = converted %.loc10_15.1, constants.%.loc10_15.2
+// CHECK:STDOUT:   %x.var: ref (i32,) = var x
+// CHECK:STDOUT:   %x: ref (i32,) = bind_name x, %x.var
+// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1
+// CHECK:STDOUT:   %.loc10_22.1: (i32,) = tuple_literal (%.loc10_20)
+// CHECK:STDOUT:   %.loc10_22.2: init (i32,) = tuple_init (%.loc10_20) to %x.var
+// CHECK:STDOUT:   %.loc10_22.3: init (i32,) = converted %.loc10_22.1, %.loc10_22.2
+// CHECK:STDOUT:   assign %x.var, %.loc10_22.3
 // CHECK:STDOUT:   %Foo.ref: <function> = name_ref Foo, file.%Foo
-// CHECK:STDOUT:   %.loc11_7: i32 = int_literal 1
-// CHECK:STDOUT:   %.loc11_11: i32 = int_literal 2
-// CHECK:STDOUT:   %.loc11_9: i32 = add %.loc11_7, %.loc11_11
-// CHECK:STDOUT:   %.loc11_15: i32 = int_literal 3
-// CHECK:STDOUT:   %.loc11_13: i32 = add %.loc11_9, %.loc11_15
-// CHECK:STDOUT:   %.loc11_18: i32 = int_literal 4
-// CHECK:STDOUT:   %.loc11_22: i32 = int_literal 5
-// CHECK:STDOUT:   %.loc11_20: i32 = add %.loc11_18, %.loc11_22
-// CHECK:STDOUT:   %.loc11_25: i32 = int_literal 6
-// CHECK:STDOUT:   %.loc11_6: init () = call %Foo.ref(%.loc11_13, %.loc11_20, %.loc11_25)
+// CHECK:STDOUT:   %x.ref: ref (i32,) = name_ref x, %x
+// CHECK:STDOUT:   %.loc12_9: i32 = int_literal 0
+// CHECK:STDOUT:   %.loc12_10.1: ref i32 = tuple_index %x.ref, %.loc12_9
+// CHECK:STDOUT:   %.loc12_13: i32 = int_literal 6
+// CHECK:STDOUT:   %.loc12_10.2: i32 = bind_value %.loc12_10.1
+// CHECK:STDOUT:   %.loc12_6: init () = call %Foo.ref(%.loc12_10.2, %.loc12_13)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 31 - 11
toolchain/check/testdata/if_expr/basic.carbon

@@ -5,11 +5,17 @@
 // AUTOUPDATE
 
 fn F(b: bool, n: i32, m: i32) -> i32 {
-  return if b then n + m else m + n;
+  var x: [i32; 1] = (0,);
+  return if b then x[m] else x[n];
 }
 
 // CHECK:STDOUT: --- basic.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.loc8_17: type = ptr_type [i32; 1]
+// CHECK:STDOUT:   %.loc8_24: type = tuple_type (i32)
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.F = %F}
 // CHECK:STDOUT:   %F: <function> = fn_decl @F
@@ -17,23 +23,37 @@ fn F(b: bool, n: i32, m: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(%b: bool, %n: i32, %m: i32) -> i32 {
 // CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %.loc8_16: i32 = int_literal 1
+// CHECK:STDOUT:   %.loc8_17: type = array_type %.loc8_16, i32
+// CHECK:STDOUT:   %x.var: ref [i32; 1] = var x
+// CHECK:STDOUT:   %x: ref [i32; 1] = bind_name x, %x.var
+// CHECK:STDOUT:   %.loc8_22: i32 = int_literal 0
+// CHECK:STDOUT:   %.loc8_24.1: (i32,) = tuple_literal (%.loc8_22)
+// CHECK:STDOUT:   %.loc8_24.2: i32 = int_literal 0
+// CHECK:STDOUT:   %.loc8_24.3: ref i32 = array_index %x.var, %.loc8_24.2
+// CHECK:STDOUT:   %.loc8_24.4: init i32 = initialize_from %.loc8_22 to %.loc8_24.3
+// CHECK:STDOUT:   %.loc8_24.5: init [i32; 1] = array_init (%.loc8_24.4) to %x.var
+// CHECK:STDOUT:   %.loc8_24.6: init [i32; 1] = converted %.loc8_24.1, %.loc8_24.5
+// CHECK:STDOUT:   assign %x.var, %.loc8_24.6
 // CHECK:STDOUT:   %b.ref: bool = name_ref b, %b
 // CHECK:STDOUT:   if %b.ref br !if.expr.then else br !if.expr.else
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then:
-// CHECK:STDOUT:   %n.ref.loc8_20: i32 = name_ref n, %n
-// CHECK:STDOUT:   %m.ref.loc8_24: i32 = name_ref m, %m
-// CHECK:STDOUT:   %.loc8_22: i32 = add %n.ref.loc8_20, %m.ref.loc8_24
-// CHECK:STDOUT:   br !if.expr.result(%.loc8_22)
+// CHECK:STDOUT:   %x.ref.loc9_20: ref [i32; 1] = name_ref x, %x
+// CHECK:STDOUT:   %m.ref: i32 = name_ref m, %m
+// CHECK:STDOUT:   %.loc9_23.1: ref i32 = array_index %x.ref.loc9_20, %m.ref
+// CHECK:STDOUT:   %.loc9_23.2: i32 = bind_value %.loc9_23.1
+// CHECK:STDOUT:   br !if.expr.result(%.loc9_23.2)
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.else:
-// CHECK:STDOUT:   %m.ref.loc8_31: i32 = name_ref m, %m
-// CHECK:STDOUT:   %n.ref.loc8_35: i32 = name_ref n, %n
-// CHECK:STDOUT:   %.loc8_33: i32 = add %m.ref.loc8_31, %n.ref.loc8_35
-// CHECK:STDOUT:   br !if.expr.result(%.loc8_33)
+// CHECK:STDOUT:   %x.ref.loc9_30: ref [i32; 1] = name_ref x, %x
+// CHECK:STDOUT:   %n.ref: i32 = name_ref n, %n
+// CHECK:STDOUT:   %.loc9_33.1: ref i32 = array_index %x.ref.loc9_30, %n.ref
+// CHECK:STDOUT:   %.loc9_33.2: i32 = bind_value %.loc9_33.1
+// CHECK:STDOUT:   br !if.expr.result(%.loc9_33.2)
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.result:
-// CHECK:STDOUT:   %.loc8_10: i32 = block_arg !if.expr.result
-// CHECK:STDOUT:   return %.loc8_10
+// CHECK:STDOUT:   %.loc9_10: i32 = block_arg !if.expr.result
+// CHECK:STDOUT:   return %.loc9_10
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 12 - 10
toolchain/check/testdata/operators/fail_type_mismatch.carbon

@@ -4,11 +4,11 @@
 //
 // AUTOUPDATE
 
-fn Main() -> i32 {
-  // CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+3]]:13: ERROR: Cannot implicitly convert from `i32` to `f64`.
-  // CHECK:STDERR:   return 12 + 3.4;
-  // CHECK:STDERR:             ^
-  return 12 + 3.4;
+fn Main() {
+  // CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+3]]:17: ERROR: Cannot implicitly convert from `i32` to `bool`.
+  // CHECK:STDERR:   var x: bool = not 12;
+  // CHECK:STDERR:                 ^~~
+  var x: bool = not 12;
 }
 
 // CHECK:STDOUT: --- fail_type_mismatch.carbon
@@ -18,11 +18,13 @@ fn Main() -> i32 {
 // CHECK:STDOUT:   %Main: <function> = fn_decl @Main
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Main() -> i32 {
+// CHECK:STDOUT: fn @Main() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_10: i32 = int_literal 12
-// CHECK:STDOUT:   %.loc11_15: f64 = real_literal 34e-1
-// CHECK:STDOUT:   %.loc11_13: <error> = add <error>, %.loc11_15
-// CHECK:STDOUT:   return <error>
+// CHECK:STDOUT:   %x.var: ref bool = var x
+// CHECK:STDOUT:   %x: ref bool = bind_name x, %x.var
+// CHECK:STDOUT:   %.loc11_21: i32 = int_literal 12
+// CHECK:STDOUT:   %.loc11_17: <error> = not <error>
+// CHECK:STDOUT:   assign %x.var, <error>
+// CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 0 - 32
toolchain/check/testdata/operators/fail_type_mismatch_once.carbon

@@ -1,32 +0,0 @@
-// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
-// Exceptions. See /LICENSE for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-// AUTOUPDATE
-
-fn Main() -> i32 {
-  // The following line has two mismatches, but after the first, it shouldn't
-  // keep erroring.
-  // CHECK:STDERR: fail_type_mismatch_once.carbon:[[@LINE+3]]:13: ERROR: Cannot implicitly convert from `i32` to `f64`.
-  // CHECK:STDERR:   return 12 + 3.4 + 12;
-  // CHECK:STDERR:             ^
-  return 12 + 3.4 + 12;
-}
-
-// CHECK:STDOUT: --- fail_type_mismatch_once.carbon
-// CHECK:STDOUT:
-// CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.Main = %Main}
-// CHECK:STDOUT:   %Main: <function> = fn_decl @Main
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: fn @Main() -> i32 {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc13_10: i32 = int_literal 12
-// CHECK:STDOUT:   %.loc13_15: f64 = real_literal 34e-1
-// CHECK:STDOUT:   %.loc13_13: <error> = add <error>, %.loc13_15
-// CHECK:STDOUT:   %.loc13_21: i32 = int_literal 12
-// CHECK:STDOUT:   %.loc13_19: <error> = add <error>, %.loc13_21
-// CHECK:STDOUT:   return <error>
-// CHECK:STDOUT: }
-// CHECK:STDOUT:

+ 4 - 7
toolchain/check/testdata/operators/binary_op.carbon → toolchain/check/testdata/operators/fail_unimplemented_op.carbon

@@ -5,21 +5,18 @@
 // AUTOUPDATE
 
 fn Main() -> i32 {
+  // CHECK:STDERR: fail_unimplemented_op.carbon:[[@LINE+3]]:13: ERROR: Semantics TODO: `Handle +`.
+  // CHECK:STDERR:   return 12 + 34;
+  // CHECK:STDERR:             ^
   return 12 + 34;
 }
 
-// CHECK:STDOUT: --- binary_op.carbon
+// CHECK:STDOUT: --- fail_unimplemented_op.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.Main = %Main}
-// CHECK:STDOUT:   %Main: <function> = fn_decl @Main
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc8_10: i32 = int_literal 12
-// CHECK:STDOUT:   %.loc8_15: i32 = int_literal 34
-// CHECK:STDOUT:   %.loc8_13: i32 = add %.loc8_10, %.loc8_15
-// CHECK:STDOUT:   return %.loc8_13
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 13 - 6
toolchain/check/testdata/pointer/fail_address_of_value.carbon

@@ -37,9 +37,9 @@ fn AddressOfLiteral() {
 
 fn AddressOfOperator() {
   // CHECK:STDERR: fail_address_of_value.carbon:[[@LINE+3]]:3: ERROR: Cannot take the address of non-reference expression.
-  // CHECK:STDERR:   &(1 + 1);
+  // CHECK:STDERR:   &(true and false);
   // CHECK:STDERR:   ^
-  &(1 + 1);
+  &(true and false);
   // CHECK:STDERR: fail_address_of_value.carbon:[[@LINE+3]]:3: ERROR: Cannot take the address of a temporary object.
   // CHECK:STDERR:   &H().a;
   // CHECK:STDERR:   ^
@@ -133,10 +133,17 @@ fn AddressOfParam(param: i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @AddressOfOperator() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc42_5: i32 = int_literal 1
-// CHECK:STDOUT:   %.loc42_9: i32 = int_literal 1
-// CHECK:STDOUT:   %.loc42_7: i32 = add %.loc42_5, %.loc42_9
-// CHECK:STDOUT:   %.loc42_3: i32* = address_of %.loc42_7
+// CHECK:STDOUT:   %.loc42_5: bool = bool_literal true
+// CHECK:STDOUT:   %.loc42_10.1: bool = bool_literal false
+// CHECK:STDOUT:   if %.loc42_5 br !and.rhs else br !and.result(%.loc42_10.1)
+// CHECK:STDOUT:
+// CHECK:STDOUT: !and.rhs:
+// CHECK:STDOUT:   %.loc42_14: bool = bool_literal false
+// CHECK:STDOUT:   br !and.result(%.loc42_14)
+// CHECK:STDOUT:
+// CHECK:STDOUT: !and.result:
+// CHECK:STDOUT:   %.loc42_10.2: bool = block_arg !and.result
+// CHECK:STDOUT:   %.loc42_3: bool* = address_of %.loc42_10.2
 // CHECK:STDOUT:   %H.ref: <function> = name_ref H, file.%H
 // CHECK:STDOUT:   %.loc46_5.1: init {.a: i32} = call %H.ref()
 // CHECK:STDOUT:   %.loc46_5.2: ref {.a: i32} = temporary_storage

+ 1 - 1
toolchain/check/testdata/return/code_after_return.carbon

@@ -6,7 +6,7 @@
 
 fn Main() {
   return;
-  var n: i32 = 1 + 1;
+  var n: i32 = 1;
 }
 
 // CHECK:STDOUT: --- code_after_return.carbon

+ 0 - 6
toolchain/lower/handle.cpp

@@ -51,12 +51,6 @@ auto HandleAssign(FunctionContext& context, SemIR::InstId /*inst_id*/,
   context.FinishInit(storage_type_id, inst.lhs_id, inst.rhs_id);
 }
 
-auto HandleBinaryOperatorAdd(FunctionContext& /*context*/,
-                             SemIR::InstId /*inst_id*/,
-                             SemIR::BinaryOperatorAdd inst) -> void {
-  CARBON_FATAL() << "TODO: Add support: " << inst;
-}
-
 auto HandleBindName(FunctionContext& context, SemIR::InstId inst_id,
                     SemIR::BindName inst) -> void {
   context.SetLocal(inst_id, context.GetValue(inst.value_id));

+ 0 - 3
toolchain/sem_ir/file.cpp

@@ -188,7 +188,6 @@ static auto GetTypePrecedence(InstKind kind) -> int {
     case ArrayInit::Kind:
     case Assign::Kind:
     case BaseDecl::Kind:
-    case BinaryOperatorAdd::Kind:
     case BindName::Kind:
     case BindValue::Kind:
     case BlockArg::Kind:
@@ -389,7 +388,6 @@ auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {
       case ArrayInit::Kind:
       case Assign::Kind:
       case BaseDecl::Kind:
-      case BinaryOperatorAdd::Kind:
       case BindName::Kind:
       case BindValue::Kind:
       case BlockArg::Kind:
@@ -493,7 +491,6 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
 
       case AddressOf::Kind:
       case ArrayType::Kind:
-      case BinaryOperatorAdd::Kind:
       case BindValue::Kind:
       case BlockArg::Kind:
       case BoolLiteral::Kind:

+ 0 - 1
toolchain/sem_ir/inst_kind.def

@@ -23,7 +23,6 @@ CARBON_SEM_IR_INST_KIND(ArrayInit)
 CARBON_SEM_IR_INST_KIND(ArrayType)
 CARBON_SEM_IR_INST_KIND(Assign)
 CARBON_SEM_IR_INST_KIND(BaseDecl)
-CARBON_SEM_IR_INST_KIND(BinaryOperatorAdd)
 CARBON_SEM_IR_INST_KIND(BindName)
 CARBON_SEM_IR_INST_KIND(BindValue)
 CARBON_SEM_IR_INST_KIND(BlockArg)

+ 0 - 9
toolchain/sem_ir/typed_insts.h

@@ -98,15 +98,6 @@ struct BaseDecl {
   ElementIndex index;
 };
 
-struct BinaryOperatorAdd {
-  static constexpr auto Kind = InstKind::BinaryOperatorAdd.Define("add");
-
-  Parse::NodeId parse_node;
-  TypeId type_id;
-  InstId lhs_id;
-  InstId rhs_id;
-};
-
 struct BindName {
   static constexpr auto Kind = InstKind::BindName.Define("bind_name");