1
Fork 0

Rollup merge of #72451 - ecstatic-morse:nrvo-type-mismatch, r=matthewjasper

Perform MIR NRVO even if types don't match

This is the most straightforward way to resolve #72428, but it could cause problems in codegen since the type of `_0` may no longer match the return type of the body.
This commit is contained in:
Dylan DPC 2020-05-25 23:58:57 +02:00 committed by GitHub
commit 036688f875
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -44,18 +44,6 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
}
};
// Sometimes, the return place is assigned a local of a different but coercable type, for
// example `&T` instead of `&mut T`. Overwriting the `LocalInfo` for the return place would
// result in it having an incorrect type. Although this doesn't seem to cause a problem in
// codegen, bail out anyways since it happens so rarely.
let ret_ty = body.local_decls[mir::RETURN_PLACE].ty;
let assigned_ty = body.local_decls[returned_local].ty;
if ret_ty != assigned_ty {
debug!("`{:?}` was eligible for NRVO but for type mismatch", src.def_id());
debug!("typeof(_0) != typeof({:?}); {:?} != {:?}", returned_local, ret_ty, assigned_ty);
return;
}
debug!(
"`{:?}` was eligible for NRVO, making {:?} the return place",
src.def_id(),
@ -72,6 +60,12 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
// Overwrite the debuginfo of `_0` with that of the renamed local.
let (renamed_decl, ret_decl) =
body.local_decls.pick2_mut(returned_local, mir::RETURN_PLACE);
// Sometimes, the return place is assigned a local of a different but coercable type, for
// example `&mut T` instead of `&T`. Overwriting the `LocalInfo` for the return place means
// its type may no longer match the return type of its function. This doesn't cause a
// problem in codegen because these two types are layout-compatible, but may be unexpected.
debug!("_0: {:?} = {:?}: {:?}", ret_decl.ty, returned_local, renamed_decl.ty);
ret_decl.clone_from(renamed_decl);
// The return place is always mutable.