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:: fmt;
7
6
use std:: num:: NonZeroU64 ;
8
7
8
+ use log:: trace;
9
+
9
10
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
10
11
use rustc_hir:: Mutability ;
11
12
use rustc_middle:: mir:: RetagKind ;
12
13
use rustc_middle:: ty:: {
13
14
self ,
14
- layout:: { HasParamEnv , LayoutOf } ,
15
+ layout:: { HasParamEnv , LayoutOf , TyAndLayout } ,
15
16
} ;
16
17
use rustc_span:: DUMMY_SP ;
17
18
use rustc_target:: abi:: Size ;
@@ -835,8 +836,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
835
836
// Determine mutability and whether to add a protector.
836
837
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
837
838
// making it useless.
838
- fn qualify ( ty : ty :: Ty < ' _ > , kind : RetagKind ) -> Option < ( RefKind , bool ) > {
839
- match ty. kind ( ) {
839
+ let qualify = | layout : TyAndLayout < ' tcx > , kind : RetagKind | -> Option < ( RefKind , bool ) > {
840
+ match layout . ty . kind ( ) {
840
841
// References are simple.
841
842
ty:: Ref ( _, _, Mutability :: Mut ) =>
842
843
Some ( (
@@ -850,15 +851,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
850
851
Some ( ( RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut } , false ) ) ,
851
852
// Boxes do not get a protector: protectors reflect that references outlive the call
852
853
// they were passed in to; that's just not the case for boxes.
853
- ty:: Adt ( ..) if ty. is_box ( ) => Some ( ( RefKind :: Unique { two_phase : false } , false ) ) ,
854
+ // HACK: We only treat boxes with ZST allocators as 'noalias'.
855
+ // See https://github.com/rust-lang/rust/issues/95453.
856
+ ty:: Adt ( ..) if layout. ty . is_box ( ) && layout. field ( this, 1 ) . is_zst ( ) =>
857
+ Some ( ( RefKind :: Unique { two_phase : false } , false ) ) ,
854
858
_ => None ,
855
859
}
856
- }
860
+ } ;
857
861
858
862
// We only reborrow "bare" references/boxes.
859
863
// Not traversing into fields helps with <https://github.com/rust-lang/unsafe-code-guidelines/issues/125>,
860
864
// but might also cost us optimization and analyses. We will have to experiment more with this.
861
- if let Some ( ( mutbl, protector) ) = qualify ( place. layout . ty , kind) {
865
+ if let Some ( ( mutbl, protector) ) = qualify ( place. layout , kind) {
862
866
// Fast path.
863
867
let val = this. read_immediate ( & this. place_to_op ( place) ?) ?;
864
868
let val = this. retag_reference ( & val, mutbl, protector) ?;
0 commit comments