Remove special case for returning value expressions by copy (#6052)

When returning a value from a function whose return type has a by-copy
initializing representation, perform initialization like we do when the
return type has an in-place initializing representation. This makes our
SemIR representation more uniform, as the return expression will now
always be an initializing expression rather than a value expression, but
more importantly it means that attempts to return a non-copyable type by
value now fail, even if the type has a by-copy initializing
representation.

This catches a bunch of places where we were returning a value of an
unconstrained template parameter `T:! type`, which we were incorrectly
allowing because we didn't notice it was not copyable. Unfortunately
this then requires quite a few test updates.

Like #6034, this exposes a lowering issue where lowering crashes when
attempting to lower a specific copy operation for certain types; a
couple more tests are temporarily disabled here. An upcoming PR
dependent on this one will fix the issue and re-enable those tests.
This commit is contained in:
Richard Smith
2025-09-12 00:13:33 +00:00
committed by GitHub
parent 896ef4da0e
commit d60900cbeb
231 changed files with 8664 additions and 9042 deletions
+4 -2
View File
@@ -27,9 +27,9 @@ fn Main() {
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %Echo.type: type = fn_type @Echo [concrete]
// CHECK:STDOUT: %Echo: %Echo.type = struct_value () [concrete]
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: %Main.type: type = fn_type @Main [concrete]
// CHECK:STDOUT: %Main: %Main.type = struct_value () [concrete]
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -60,7 +60,9 @@ fn Main() {
// CHECK:STDOUT: fn @Echo(%a.param: %empty_struct_type) -> %empty_struct_type {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %a.ref: %empty_struct_type = name_ref a, %a
// CHECK:STDOUT: return %a.ref
// CHECK:STDOUT: %.loc16_10: init %empty_struct_type = struct_init () to %return [concrete = constants.%empty_struct]
// CHECK:STDOUT: %.loc16_11: init %empty_struct_type = converted %a.ref, %.loc16_10 [concrete = constants.%empty_struct]
// CHECK:STDOUT: return %.loc16_11 to %return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Main() {