about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2020-05-21 19:27:12 -0700
committerDylan MacKenzie <ecstaticmorse@gmail.com>2020-05-21 19:31:16 -0700
commitd24ba6d1243db648eac365eaf637264e6d04d5f1 (patch)
treec2935c9e8bd62e72ab9afd6e13b44aecc86d2041
parent06c9fef822b890054fcefa9a567b57eb6edfe638 (diff)
downloadrust-d24ba6d1243db648eac365eaf637264e6d04d5f1.tar.gz
rust-d24ba6d1243db648eac365eaf637264e6d04d5f1.zip
Perform MIR NRVO even if types don't match
-rw-r--r--src/librustc_mir/transform/nrvo.rs18
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.