1
1
//! Implements "Stacked Borrows". See <https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md>
2
2
//! for further information.
3
3
4
- use log:: trace;
5
4
use std:: cell:: RefCell ;
6
5
use std:: cmp;
7
6
use std:: fmt;
8
7
use std:: num:: NonZeroU64 ;
9
8
9
+ use log:: trace;
10
+
10
11
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
11
12
use rustc_hir:: Mutability ;
12
13
use rustc_middle:: mir:: RetagKind ;
13
14
use rustc_middle:: ty:: {
14
15
self ,
15
- layout:: { HasParamEnv , LayoutOf } ,
16
+ layout:: { HasParamEnv , LayoutOf , TyAndLayout } ,
16
17
} ;
17
18
use rustc_span:: DUMMY_SP ;
18
19
use rustc_target:: abi:: Size ;
@@ -1086,8 +1087,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1086
1087
// Determine mutability and whether to add a protector.
1087
1088
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
1088
1089
// making it useless.
1089
- fn qualify ( ty : ty :: Ty < ' _ > , kind : RetagKind ) -> Option < ( RefKind , bool ) > {
1090
- match ty. kind ( ) {
1090
+ let qualify = | layout : TyAndLayout < ' tcx > , kind : RetagKind | -> Option < ( RefKind , bool ) > {
1091
+ match layout . ty . kind ( ) {
1091
1092
// References are simple.
1092
1093
ty:: Ref ( _, _, Mutability :: Mut ) =>
1093
1094
Some ( (
@@ -1101,15 +1102,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1101
1102
Some ( ( RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut } , false ) ) ,
1102
1103
// Boxes do not get a protector: protectors reflect that references outlive the call
1103
1104
// they were passed in to; that's just not the case for boxes.
1104
- ty:: Adt ( ..) if ty. is_box ( ) => Some ( ( RefKind :: Unique { two_phase : false } , false ) ) ,
1105
+ // HACK: We only treat boxes with ZST allocators as 'noalias'.
1106
+ // See https://github.com/rust-lang/rust/issues/95453.
1107
+ ty:: Adt ( ..) if layout. ty . is_box ( ) && layout. field ( this, 1 ) . is_zst ( ) =>
1108
+ Some ( ( RefKind :: Unique { two_phase : false } , false ) ) ,
1105
1109
_ => None ,
1106
1110
}
1107
- }
1111
+ } ;
1108
1112
1109
1113
// We only reborrow "bare" references/boxes.
1110
1114
// Not traversing into fields helps with <https://github.com/rust-lang/unsafe-code-guidelines/issues/125>,
1111
1115
// but might also cost us optimization and analyses. We will have to experiment more with this.
1112
- if let Some ( ( mutbl, protector) ) = qualify ( place. layout . ty , kind) {
1116
+ if let Some ( ( mutbl, protector) ) = qualify ( place. layout , kind) {
1113
1117
// Fast path.
1114
1118
let val = this. read_immediate ( & this. place_to_op ( place) ?) ?;
1115
1119
let val = this. retag_reference ( & val, mutbl, protector) ?;
0 commit comments