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
+1 -4
View File
@@ -157,13 +157,10 @@ auto BuildReturnWithExpr(Context& context, SemIR::LocId loc_id,
// We already diagnosed that the return type is invalid. Don't try to
// convert to it.
expr_id = SemIR::ErrorInst::InstId;
} else if (return_info.has_return_slot()) {
} else {
return_slot_id = GetCurrentReturnSlot(context);
CARBON_CHECK(return_slot_id.has_value());
expr_id = Initialize(context, loc_id, return_slot_id, expr_id);
} else {
expr_id =
ConvertToValueOfType(context, loc_id, expr_id, return_info.type_id);
}
AddReturnCleanupBlockWithExpr(