@@ -44,6 +44,18 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
44
44
}
45
45
} ;
46
46
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
+
47
59
debug ! (
48
60
"`{:?}` was eligible for NRVO, making {:?} the return place" ,
49
61
src. def_id( ) ,
@@ -60,7 +72,6 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
60
72
// Overwrite the debuginfo of `_0` with that of the renamed local.
61
73
let ( renamed_decl, ret_decl) =
62
74
body. local_decls . pick2_mut ( returned_local, mir:: RETURN_PLACE ) ;
63
- debug_assert_eq ! ( ret_decl. ty, renamed_decl. ty) ;
64
75
ret_decl. clone_from ( renamed_decl) ;
65
76
66
77
// The return place is always mutable.
0 commit comments