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:
commit
036688f875
1 changed files with 6 additions and 12 deletions
|
@ -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!(
|
debug!(
|
||||||
"`{:?}` was eligible for NRVO, making {:?} the return place",
|
"`{:?}` was eligible for NRVO, making {:?} the return place",
|
||||||
src.def_id(),
|
src.def_id(),
|
||||||
|
@ -72,6 +60,12 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
|
||||||
// Overwrite the debuginfo of `_0` with that of the renamed local.
|
// Overwrite the debuginfo of `_0` with that of the renamed local.
|
||||||
let (renamed_decl, ret_decl) =
|
let (renamed_decl, ret_decl) =
|
||||||
body.local_decls.pick2_mut(returned_local, mir::RETURN_PLACE);
|
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);
|
ret_decl.clone_from(renamed_decl);
|
||||||
|
|
||||||
// The return place is always mutable.
|
// The return place is always mutable.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue