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

Remove `CHECK` from `GetCurrentReturnSlot` (#4688)

`GetCurrentReturnSlot` is sometimes called when there is no return slot
while checking incorrect Carbon code. This change also updates
`fail_returned_var_no_return_type.carbon` to cover one such case.
Geoff Romer 1 год назад
Родитель
Сommit
557c9b022a

+ 1 - 1
toolchain/check/return.cpp

@@ -28,7 +28,6 @@ static auto GetCurrentReturnSlot(Context& context) -> SemIR::InstId {
   auto return_slot_id = context.scope_stack()
                             .LookupInLexicalScopes(SemIR::NameId::ReturnSlot)
                             .first;
-  CARBON_CHECK(return_slot_id.is_valid());
   return return_slot_id;
 }
 
@@ -176,6 +175,7 @@ auto BuildReturnWithExpr(Context& context, Parse::ReturnStatementId node_id,
     expr_id = SemIR::ErrorInst::SingletonInstId;
   } else if (return_info.has_return_slot()) {
     return_slot_id = GetCurrentReturnSlot(context);
+    CARBON_CHECK(return_slot_id.is_valid());
     // Note that this can import a function and invalidate `function`.
     expr_id = Initialize(context, node_id, return_slot_id, expr_id);
   } else {

+ 63 - 6
toolchain/check/testdata/return/fail_returned_var_no_return_type.carbon

@@ -8,18 +8,38 @@
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/return/fail_returned_var_no_return_type.carbon
 
+// --- fail_procedure_with_returned_var.carbon
+
+library "[[@TEST_NAME]]";
+
 fn Procedure() {
-  // CHECK:STDERR: fail_returned_var_no_return_type.carbon:[[@LINE+6]]:3: error: cannot declare a `returned var` in this function [ReturnedVarWithNoReturnType]
+  // CHECK:STDERR: fail_procedure_with_returned_var.carbon:[[@LINE+7]]:3: error: cannot declare a `returned var` in this function [ReturnedVarWithNoReturnType]
   // CHECK:STDERR:   returned var v: () = ();
   // CHECK:STDERR:   ^~~~~~~~
-  // CHECK:STDERR: fail_returned_var_no_return_type.carbon:[[@LINE-4]]:1: note: there was no return type provided [ReturnTypeOmittedNote]
+  // CHECK:STDERR: fail_procedure_with_returned_var.carbon:[[@LINE-4]]:1: note: there was no return type provided [ReturnTypeOmittedNote]
   // CHECK:STDERR: fn Procedure() {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~
+  // CHECK:STDERR:
   returned var v: () = ();
   return;
 }
 
-// CHECK:STDOUT: --- fail_returned_var_no_return_type.carbon
+// --- fail_forgot_return_type.carbon
+
+library "[[@TEST_NAME]]";
+
+fn ForgotReturnType() {
+  // CHECK:STDERR: fail_forgot_return_type.carbon:[[@LINE+6]]:3: error: cannot declare a `returned var` in this function [ReturnedVarWithNoReturnType]
+  // CHECK:STDERR:   returned var v: () = ();
+  // CHECK:STDERR:   ^~~~~~~~
+  // CHECK:STDERR: fail_forgot_return_type.carbon:[[@LINE-4]]:1: note: there was no return type provided [ReturnTypeOmittedNote]
+  // CHECK:STDERR: fn ForgotReturnType() {
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~
+  returned var v: () = ();
+  return var;
+}
+
+// CHECK:STDOUT: --- fail_procedure_with_returned_var.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Procedure.type: type = fn_type @Procedure [template]
@@ -45,11 +65,48 @@ fn Procedure() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Procedure() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc18_20.1: %empty_tuple.type = tuple_literal ()
-// CHECK:STDOUT:   %.loc18_20.2: type = converted %.loc18_20.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
+// CHECK:STDOUT:   %.loc12_20.1: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:   %.loc12_20.2: type = converted %.loc12_20.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
 // CHECK:STDOUT:   %v: %empty_tuple.type = bind_name v, <error>
-// CHECK:STDOUT:   %.loc18_25: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:   %.loc12_25: %empty_tuple.type = tuple_literal ()
 // CHECK:STDOUT:   assign <error>, <error>
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: --- fail_forgot_return_type.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %ForgotReturnType.type: type = fn_type @ForgotReturnType [template]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
+// CHECK:STDOUT:   %ForgotReturnType: %ForgotReturnType.type = struct_value () [template]
+// CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Core = imports.%Core
+// CHECK:STDOUT:     .ForgotReturnType = %ForgotReturnType.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
+// CHECK:STDOUT:   %ForgotReturnType.decl: %ForgotReturnType.type = fn_decl @ForgotReturnType [template = constants.%ForgotReturnType] {} {}
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @ForgotReturnType() {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %.loc11_20.1: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:   %.loc11_20.2: type = converted %.loc11_20.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
+// CHECK:STDOUT:   %v: %empty_tuple.type = bind_name v, <error>
+// CHECK:STDOUT:   %.loc11_25: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:   assign <error>, <error>
+// CHECK:STDOUT:   %tuple: %empty_tuple.type = tuple_value () [template = constants.%empty_tuple]
+// CHECK:STDOUT:   %.loc11_16: %empty_tuple.type = converted %v, %tuple [template = constants.%empty_tuple]
+// CHECK:STDOUT:   return %.loc11_16
+// CHECK:STDOUT: }
+// CHECK:STDOUT: