diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-05-25 23:58:57 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-25 23:58:57 +0200 |
| commit | 036688f875cf2a1cf848c5f7ba8ed5809cbad46f (patch) | |
| tree | aae1d80d607406cb9c66737bc1553ec201441d0e | |
| parent | a7ff5a00775ca8db59077307b0b9eb706f907941 (diff) | |
| parent | d24ba6d1243db648eac365eaf637264e6d04d5f1 (diff) | |
| download | rust-036688f875cf2a1cf848c5f7ba8ed5809cbad46f.tar.gz rust-036688f875cf2a1cf848c5f7ba8ed5809cbad46f.zip | |
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.
| -rw-r--r-- | src/librustc_mir/transform/nrvo.rs | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/src/librustc_mir/transform/nrvo.rs b/src/librustc_mir/transform/nrvo.rs index 941ffa94aa8..ffad1ebea00 100644 --- a/src/librustc_mir/transform/nrvo.rs +++ b/src/librustc_mir/transform/nrvo.rs @@ -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. |
