11//! Implements "Stacked Borrows". See <https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md>
22//! for further information.
33
4- use log:: trace;
54use std:: cell:: RefCell ;
65use std:: cmp;
76use std:: fmt;
87use std:: num:: NonZeroU64 ;
98
9+ use log:: trace;
10+
1011use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1112use rustc_hir:: Mutability ;
1213use rustc_middle:: mir:: RetagKind ;
1314use rustc_middle:: ty:: {
1415 self ,
15- layout:: { HasParamEnv , LayoutOf } ,
16+ layout:: { HasParamEnv , LayoutOf , TyAndLayout } ,
1617} ;
1718use rustc_span:: DUMMY_SP ;
1819use rustc_target:: abi:: Size ;
@@ -1086,8 +1087,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
10861087 // Determine mutability and whether to add a protector.
10871088 // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
10881089 // 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 ( ) {
10911092 // References are simple.
10921093 ty:: Ref ( _, _, Mutability :: Mut ) =>
10931094 Some ( (
@@ -1101,15 +1102,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
11011102 Some ( ( RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut } , false ) ) ,
11021103 // Boxes do not get a protector: protectors reflect that references outlive the call
11031104 // 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 ) ) ,
11051109 _ => None ,
11061110 }
1107- }
1111+ } ;
11081112
11091113 // We only reborrow "bare" references/boxes.
11101114 // Not traversing into fields helps with <https://github.com/rust-lang/unsafe-code-guidelines/issues/125>,
11111115 // 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) {
11131117 // Fast path.
11141118 let val = this. read_immediate ( & this. place_to_op ( place) ?) ?;
11151119 let val = this. retag_reference ( & val, mutbl, protector) ?;
0 commit comments