Skip to content

Commit f509862

Browse files
Bail out if new return place has different type than old
1 parent 856cd66 commit f509862

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/librustc_mir/transform/nrvo.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
4444
}
4545
};
4646

47+
// Sometimes, the return place is assigned a local of a different but coercable type, for
48+
// example `&T` instead of `&mut T`. Overwriting the `LocalInfo` for the return place would
49+
// result in it having an incorrect type. Although this doesn't seem to cause a problem in
50+
// codegen, bail out anyways since it happens so rarely.
51+
let ret_ty = body.local_decls[mir::RETURN_PLACE].ty;
52+
let assigned_ty = body.local_decls[returned_local].ty;
53+
if ret_ty != assigned_ty {
54+
debug!("`{:?}` was eligible for NRVO but for type mismatch", src.def_id());
55+
debug!("typeof(_0) != typeof({:?}); {:?} != {:?}", returned_local, ret_ty, assigned_ty);
56+
return;
57+
}
58+
4759
debug!(
4860
"`{:?}` was eligible for NRVO, making {:?} the return place",
4961
src.def_id(),
@@ -60,7 +72,6 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
6072
// Overwrite the debuginfo of `_0` with that of the renamed local.
6173
let (renamed_decl, ret_decl) =
6274
body.local_decls.pick2_mut(returned_local, mir::RETURN_PLACE);
63-
debug_assert_eq!(ret_decl.ty, renamed_decl.ty);
6475
ret_decl.clone_from(renamed_decl);
6576

6677
// The return place is always mutable.

0 commit comments

Comments
 (0)