Auto merge of #105456 - matthiaskrgr:rollup-yennygf, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #104922 (Detect long types in E0308 and write them to disk) - #105120 (kmc-solid: `std::sys` code maintenance) - #105255 (Make nested RPIT inherit the parent opaque's generics.) - #105317 (make retagging work even with 'unstable' places) - #105405 (Stop passing -export-dynamic to wasm-ld.) - #105408 (Add help for `#![feature(impl_trait_in_fn_trait_return)]`) - #105423 (Use `Symbol` for the crate name instead of `String`/`str`) - #105433 (CI: add missing line continuation marker) - #105434 (Fix warning when libcore is compiled with no_fp_fmt_parse) - #105441 (Remove `UnsafetyState`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7701a7e7d4
69 changed files with 825 additions and 575 deletions
|
|
@ -25,7 +25,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
zlib1g-dev \
|
||||
xz-utils \
|
||||
nodejs \
|
||||
|
||||
\
|
||||
# Install powershell so we can test x.ps1 on Linux
|
||||
apt-transport-https software-properties-common && \
|
||||
curl -s "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" > packages-microsoft-prod.deb && \
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
sudo \
|
||||
xz-utils \
|
||||
tidy \
|
||||
|
||||
\
|
||||
# Install dependencies for chromium browser
|
||||
gconf-service \
|
||||
libasound2 \
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@ fn bar() -> bool {
|
|||
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) }
|
||||
Retag(_10); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
|
||||
_4 = &(*_10); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
|
||||
Retag(_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
|
||||
_3 = &(*_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
|
||||
Retag(_3); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
|
||||
StorageLive(_6); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
|
||||
StorageLive(_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
|
||||
_9 = const _; // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
|
||||
|
|
@ -49,9 +47,7 @@ fn bar() -> bool {
|
|||
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) }
|
||||
Retag(_9); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
|
||||
_7 = &(*_9); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
|
||||
Retag(_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
|
||||
_6 = &(*_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
|
||||
Retag(_6); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
|
||||
Retag(_3); // scope 2 at $DIR/inline_retag.rs:16:8: 16:9
|
||||
Retag(_6); // scope 2 at $DIR/inline_retag.rs:16:17: 16:18
|
||||
StorageLive(_11); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7
|
||||
|
|
|
|||
|
|
@ -68,9 +68,7 @@ fn array_casts() -> () {
|
|||
StorageLive(_3); // scope 1 at $DIR/retag.rs:+2:13: +2:19
|
||||
StorageLive(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
|
||||
_4 = &mut _1; // scope 1 at $DIR/retag.rs:+2:13: +2:19
|
||||
Retag(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
|
||||
_3 = &raw mut (*_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
|
||||
Retag([raw] _3); // scope 1 at $DIR/retag.rs:+2:13: +2:19
|
||||
_2 = move _3 as *mut usize (Pointer(ArrayToPointer)); // scope 1 at $DIR/retag.rs:+2:13: +2:33
|
||||
StorageDead(_3); // scope 1 at $DIR/retag.rs:+2:32: +2:33
|
||||
StorageDead(_4); // scope 1 at $DIR/retag.rs:+2:33: +2:34
|
||||
|
|
@ -96,9 +94,7 @@ fn array_casts() -> () {
|
|||
StorageLive(_10); // scope 4 at $DIR/retag.rs:+6:13: +6:15
|
||||
StorageLive(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
|
||||
_11 = &_8; // scope 4 at $DIR/retag.rs:+6:13: +6:15
|
||||
Retag(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
|
||||
_10 = &raw const (*_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
|
||||
Retag([raw] _10); // scope 4 at $DIR/retag.rs:+6:13: +6:15
|
||||
_9 = move _10 as *const usize (Pointer(ArrayToPointer)); // scope 4 at $DIR/retag.rs:+6:13: +6:31
|
||||
StorageDead(_10); // scope 4 at $DIR/retag.rs:+6:30: +6:31
|
||||
StorageDead(_11); // scope 4 at $DIR/retag.rs:+6:31: +6:32
|
||||
|
|
@ -119,7 +115,6 @@ fn array_casts() -> () {
|
|||
StorageDead(_17); // scope 6 at $DIR/retag.rs:+7:33: +7:34
|
||||
_15 = (*_16); // scope 6 at $DIR/retag.rs:+7:25: +7:34
|
||||
_14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
_35 = const _; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
// mir::Constant
|
||||
|
|
@ -127,7 +122,6 @@ fn array_casts() -> () {
|
|||
// + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) }
|
||||
Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
_18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
Deinit(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
(_13.0: &usize) = move _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
(_13.1: &usize) = move _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
|
|
@ -164,15 +158,11 @@ fn array_casts() -> () {
|
|||
StorageLive(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
StorageLive(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
_31 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
Retag(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
_30 = &(*_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
Retag(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
StorageLive(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
_33 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
Retag(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
_32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
Deinit(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
discriminant(_34) = 0; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ fn std::ptr::drop_in_place(_1: *mut Test) -> () {
|
|||
let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||
|
||||
bb0: {
|
||||
Retag([raw] _1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||
_2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||
_3 = <Test as Drop>::drop(move _2) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||
// mir::Constant
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ fn main::{closure#0}(_1: &[closure@main::{closure#0}], _2: &i32) -> &i32 {
|
|||
_3 = _2; // scope 0 at $DIR/retag.rs:+1:18: +1:19
|
||||
Retag(_3); // scope 0 at $DIR/retag.rs:+1:18: +1:19
|
||||
_0 = &(*_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10
|
||||
Retag(_0); // scope 1 at $DIR/retag.rs:+2:9: +2:10
|
||||
StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6
|
||||
return; // scope 0 at $DIR/retag.rs:+3:6: +3:6
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,13 +65,10 @@ fn main() -> () {
|
|||
Deinit(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24
|
||||
(_5.0: i32) = const 0_i32; // scope 1 at $DIR/retag.rs:+3:17: +3:24
|
||||
_4 = &_5; // scope 1 at $DIR/retag.rs:+3:17: +3:36
|
||||
Retag(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36
|
||||
StorageLive(_6); // scope 1 at $DIR/retag.rs:+3:29: +3:35
|
||||
StorageLive(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
|
||||
_7 = &mut _1; // scope 1 at $DIR/retag.rs:+3:29: +3:35
|
||||
Retag(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
|
||||
_6 = &mut (*_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
|
||||
Retag([2phase] _6); // scope 1 at $DIR/retag.rs:+3:29: +3:35
|
||||
_3 = Test::foo(move _4, move _6) -> [return: bb1, unwind: bb8]; // scope 1 at $DIR/retag.rs:+3:17: +3:36
|
||||
// mir::Constant
|
||||
// + span: $DIR/retag.rs:33:25: 33:28
|
||||
|
|
@ -93,7 +90,6 @@ fn main() -> () {
|
|||
_9 = move _3; // scope 2 at $DIR/retag.rs:+4:19: +4:20
|
||||
Retag(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20
|
||||
_8 = &mut (*_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20
|
||||
Retag(_8); // scope 2 at $DIR/retag.rs:+4:19: +4:20
|
||||
StorageDead(_9); // scope 2 at $DIR/retag.rs:+4:22: +4:23
|
||||
StorageLive(_10); // scope 3 at $DIR/retag.rs:+5:13: +5:14
|
||||
_10 = move _8; // scope 3 at $DIR/retag.rs:+5:17: +5:18
|
||||
|
|
@ -101,7 +97,6 @@ fn main() -> () {
|
|||
StorageLive(_11); // scope 4 at $DIR/retag.rs:+7:13: +7:15
|
||||
StorageLive(_12); // scope 4 at $DIR/retag.rs:+7:18: +7:29
|
||||
_12 = &raw mut (*_10); // scope 4 at $DIR/retag.rs:+7:18: +7:19
|
||||
Retag([raw] _12); // scope 4 at $DIR/retag.rs:+7:18: +7:19
|
||||
_11 = _12; // scope 4 at $DIR/retag.rs:+7:18: +7:29
|
||||
StorageDead(_12); // scope 4 at $DIR/retag.rs:+7:29: +7:30
|
||||
_2 = const (); // scope 1 at $DIR/retag.rs:+2:5: +8:6
|
||||
|
|
@ -122,9 +117,7 @@ fn main() -> () {
|
|||
StorageLive(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18
|
||||
StorageLive(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
|
||||
_18 = &_1; // scope 6 at $DIR/retag.rs:+15:16: +15:18
|
||||
Retag(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
|
||||
_17 = &(*_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
|
||||
Retag(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18
|
||||
_15 = move _16(move _17) -> bb3; // scope 6 at $DIR/retag.rs:+15:14: +15:19
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +132,6 @@ fn main() -> () {
|
|||
Deinit(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12
|
||||
(_21.0: i32) = const 0_i32; // scope 7 at $DIR/retag.rs:+18:5: +18:12
|
||||
_20 = &_21; // scope 7 at $DIR/retag.rs:+18:5: +18:24
|
||||
Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24
|
||||
StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||
StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||
_28 = const _; // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||
|
|
@ -148,9 +140,7 @@ fn main() -> () {
|
|||
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
||||
Retag(_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||
_23 = &(*_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||
Retag(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||
_22 = &(*_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||
Retag(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
|
||||
_19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind: bb7]; // scope 7 at $DIR/retag.rs:+18:5: +18:24
|
||||
// mir::Constant
|
||||
// + span: $DIR/retag.rs:48:13: 48:20
|
||||
|
|
@ -171,7 +161,6 @@ fn main() -> () {
|
|||
StorageLive(_25); // scope 7 at $DIR/retag.rs:+21:9: +21:11
|
||||
StorageLive(_26); // scope 7 at $DIR/retag.rs:+21:14: +21:28
|
||||
_26 = &raw const (*_15); // scope 7 at $DIR/retag.rs:+21:14: +21:16
|
||||
Retag([raw] _26); // scope 7 at $DIR/retag.rs:+21:14: +21:16
|
||||
_25 = _26; // scope 7 at $DIR/retag.rs:+21:14: +21:28
|
||||
StorageDead(_26); // scope 7 at $DIR/retag.rs:+21:28: +21:29
|
||||
StorageLive(_27); // scope 8 at $DIR/retag.rs:+23:5: +23:18
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@ fn <impl at $DIR/retag.rs:12:1: 12:10>::foo(_1: &Test, _2: &mut i32) -> &mut i32
|
|||
Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:23: +0:24
|
||||
StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
|
||||
_3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10
|
||||
Retag(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
|
||||
_0 = &mut (*_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
|
||||
Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10
|
||||
StorageDead(_3); // scope 0 at $DIR/retag.rs:+2:5: +2:6
|
||||
return; // scope 0 at $DIR/retag.rs:+2:6: +2:6
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ impl CodegenBackend for TheBackend {
|
|||
if crate_type != CrateType::Rlib {
|
||||
sess.fatal(&format!("Crate type is {:?}", crate_type));
|
||||
}
|
||||
let output_name = out_filename(sess, crate_type, &outputs, &*crate_name.as_str());
|
||||
let output_name = out_filename(sess, crate_type, &outputs, crate_name);
|
||||
let mut out_file = ::std::fs::File::create(output_name).unwrap();
|
||||
write!(out_file, "This has been \"compiled\" successfully.").unwrap();
|
||||
}
|
||||
|
|
|
|||
17
src/test/ui/async-await/in-trait/nested-rpit.rs
Normal file
17
src/test/ui/async-await/in-trait/nested-rpit.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// check-pass
|
||||
// edition: 2021
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
trait Lockable<K, V> {
|
||||
async fn lock_all_entries(&self) -> impl Future<Output = Guard<'_>>;
|
||||
}
|
||||
|
||||
struct Guard<'a>(PhantomData<&'a ()>);
|
||||
|
||||
fn main() {}
|
||||
86
src/test/ui/diagnostic-width/long-E0308.rs
Normal file
86
src/test/ui/diagnostic-width/long-E0308.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// compile-flags: --diagnostic-width=60
|
||||
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
|
||||
|
||||
struct Atype<T, K>(T, K);
|
||||
struct Btype<T, K>(T, K);
|
||||
struct Ctype<T, K>(T, K);
|
||||
|
||||
fn main() {
|
||||
let x: Atype<
|
||||
Btype<
|
||||
Ctype<
|
||||
Atype<
|
||||
Btype<
|
||||
Ctype<
|
||||
Atype<
|
||||
Btype<
|
||||
Ctype<i32, i32>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
> = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
|
||||
Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
|
||||
Ok("")
|
||||
))))))))))))))))))))))))))))))
|
||||
))))))))))))))))))))))))))))));
|
||||
//~^^^^^ ERROR E0308
|
||||
|
||||
let _ = Some(Ok(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
|
||||
Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
|
||||
Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
|
||||
Some(Some(Some(Some(Some(Some(Some(Some(Some("")))))))))
|
||||
)))))))))))))))))
|
||||
))))))))))))))))))
|
||||
))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
|
||||
Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
|
||||
Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
|
||||
))))))))))))))))))))))))))))))
|
||||
))))))))))))))))))))))));
|
||||
//~^^^^^ ERROR E0308
|
||||
|
||||
let x: Atype<
|
||||
Btype<
|
||||
Ctype<
|
||||
Atype<
|
||||
Btype<
|
||||
Ctype<
|
||||
Atype<
|
||||
Btype<
|
||||
Ctype<i32, i32>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
>,
|
||||
i32
|
||||
> = ();
|
||||
//~^ ERROR E0308
|
||||
|
||||
let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
|
||||
Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
|
||||
Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
|
||||
))))))))))))))))))))))))))))))
|
||||
))))))))))))))))))))))));
|
||||
//~^^^^^ ERROR E0308
|
||||
}
|
||||
80
src/test/ui/diagnostic-width/long-E0308.stderr
Normal file
80
src/test/ui/diagnostic-width/long-E0308.stderr
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/long-E0308.rs:33:9
|
||||
|
|
||||
LL | let x: Atype<
|
||||
| _____________-
|
||||
LL | | Btype<
|
||||
LL | | Ctype<
|
||||
LL | | Atype<
|
||||
... |
|
||||
LL | | i32
|
||||
LL | | > = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
|
||||
| | _____-___^
|
||||
| ||_____|
|
||||
| | expected due to this
|
||||
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
|
||||
LL | | Ok("")
|
||||
LL | | ))))))))))))))))))))))))))))))
|
||||
LL | | ))))))))))))))))))))))))))))));
|
||||
| |__________________________________^ expected struct `Atype`, found enum `Result`
|
||||
|
|
||||
= note: expected struct `Atype<Btype<..., ...>, ...>`
|
||||
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
|
||||
found enum `Result<Result<..., ...>, ...>`
|
||||
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/long-E0308.rs:46:26
|
||||
|
|
||||
LL | ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
|
||||
| __________________________^
|
||||
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
|
||||
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
|
||||
LL | | ))))))))))))))))))))))))))))))
|
||||
LL | | ))))))))))))))))))))))));
|
||||
| |____________________________^ expected enum `Option`, found enum `Result`
|
||||
|
|
||||
= note: expected enum `Option<Result<..., ...>>`
|
||||
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
|
||||
found enum `Result<Result<..., ...>, ...>`
|
||||
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/long-E0308.rs:77:9
|
||||
|
|
||||
LL | let x: Atype<
|
||||
| ____________-
|
||||
LL | | Btype<
|
||||
LL | | Ctype<
|
||||
LL | | Atype<
|
||||
... |
|
||||
LL | | i32
|
||||
LL | | > = ();
|
||||
| | - ^^ expected struct `Atype`, found `()`
|
||||
| |_____|
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected struct `Atype<Btype<..., ...>, ...>`
|
||||
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
|
||||
found unit type `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/long-E0308.rs:80:17
|
||||
|
|
||||
LL | let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
|
||||
| ____________--___^
|
||||
| | |
|
||||
| | expected due to this
|
||||
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
|
||||
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
|
||||
LL | | ))))))))))))))))))))))))))))))
|
||||
LL | | ))))))))))))))))))))))));
|
||||
| |____________________________^ expected `()`, found enum `Result`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<Result<..., ...>, ...>`
|
||||
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
@ -5,7 +5,7 @@ LL | impl<T> Foo for T where Bar<T>: Foo {}
|
|||
| ^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
|
||||
note: required for `Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>` to implement `Foo`
|
||||
note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
|
||||
--> $DIR/E0275.rs:6:9
|
||||
|
|
||||
LL | impl<T> Foo for T where Bar<T>: Foo {}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,18 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t
|
|||
|
|
||||
LL | fn f() -> impl Fn() -> impl Sized { || () }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
|
||||
= help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable
|
||||
|
||||
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
|
||||
--> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32
|
||||
|
|
||||
LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
|
||||
= help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ LL | impl<T> Foo for T where NoData<T>: Foo {
|
|||
| ^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
|
||||
note: required for `NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>` to implement `Foo`
|
||||
note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>>>>>>>` to implement `Foo`
|
||||
--> $DIR/issue-20413.rs:9:9
|
||||
|
|
||||
LL | impl<T> Foo for T where NoData<T>: Foo {
|
||||
|
|
@ -30,13 +30,13 @@ LL | impl<T> Bar for T where EvenLessData<T>: Baz {
|
|||
| ^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
|
||||
note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar`
|
||||
note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>` to implement `Bar`
|
||||
--> $DIR/issue-20413.rs:28:9
|
||||
|
|
||||
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
|
||||
| ^^^ ^
|
||||
= note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
|
||||
note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz`
|
||||
note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>` to implement `Baz`
|
||||
--> $DIR/issue-20413.rs:35:9
|
||||
|
|
||||
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
|
||||
|
|
@ -52,13 +52,13 @@ LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
|
|||
| ^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
|
||||
note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz`
|
||||
note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>` to implement `Baz`
|
||||
--> $DIR/issue-20413.rs:35:9
|
||||
|
|
||||
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
|
||||
| ^^^ ^
|
||||
= note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
|
||||
note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar`
|
||||
note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>` to implement `Bar`
|
||||
--> $DIR/issue-20413.rs:28:9
|
||||
|
|
||||
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ LL | type Next = <GetNext<T::Next> as Next>::Next;
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
|
||||
note: required for `GetNext<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
|
||||
note: required for `GetNext<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
|
||||
--> $DIR/issue-23122-2.rs:10:15
|
||||
|
|
||||
LL | impl<T: Next> Next for GetNext<T> {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ LL | func(&mut iter.map(|x| x + 1))
|
|||
error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>: Iterator`
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
|
||||
= note: required for `&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>` to implement `Iterator`
|
||||
= note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>, ...>, ...>, ...>` to implement `Iterator`
|
||||
= note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt'
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
|
||||
use std::cell::Cell;
|
||||
|
||||
#[rustfmt::skip]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-102374.rs:16:5
|
||||
--> $DIR/issue-102374.rs:17:5
|
||||
|
|
||||
LL | ) -> i32 {
|
||||
| --- expected `i32` because of return type
|
||||
|
|
@ -7,7 +7,8 @@ LL | f
|
|||
| ^ expected `i32`, found fn pointer
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<(&'z1 i32, &'a i32, &'b i32, &'c i32, &'d i32, &'e i32, &'f i32, &'g i32, &'h i32, &'i i32, &'j i32, &'k i32, &'l i32, &'m i32, &'n i32, &'o i32, &'p i32, &'q i32, &'r i32, &'s i32, &'t i32, &'u i32, &'v i32, &'w i32, &'x i32, &'y i32, &'z i32, &'z0 i32)>)`
|
||||
found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<...>)`
|
||||
the full type name has been written to '$TEST_BUILD_DIR/regions/issue-102374/issue-102374.long-type-hash.txt'
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ error[E0275]: overflow evaluating the requirement `(): Sized`
|
|||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`)
|
||||
= note: required for `std::iter::Empty<()>` to implement `Iterator`
|
||||
= note: 171 redundant requirements hidden
|
||||
= note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>` to implement `Iterator`
|
||||
= note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>, ...>>` to implement `Iterator`
|
||||
= note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type-hash.txt'
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ use rustc_target::abi::Size;
|
|||
|
||||
use crate::*;
|
||||
pub mod stacked_borrows;
|
||||
use stacked_borrows::diagnostics::RetagCause;
|
||||
|
||||
pub type CallId = NonZeroU64;
|
||||
|
||||
|
|
@ -265,11 +264,19 @@ impl GlobalStateInner {
|
|||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn retag(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn retag_ptr_value(&mut self, kind: RetagKind, val: &ImmTy<'tcx, Provenance>) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
|
||||
match method {
|
||||
BorrowTrackerMethod::StackedBorrows => this.sb_retag(kind, place),
|
||||
BorrowTrackerMethod::StackedBorrows => this.sb_retag_ptr_value(kind, val),
|
||||
}
|
||||
}
|
||||
|
||||
fn retag_place_contents(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
|
||||
match method {
|
||||
BorrowTrackerMethod::StackedBorrows => this.sb_retag_place_contents(kind, place),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -459,10 +459,10 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
|
|||
Operation::Dealloc(_) => format!(" due to deallocation"),
|
||||
Operation::Access(AccessOp { kind, tag, .. }) =>
|
||||
format!(" due to {kind:?} access for {tag:?}"),
|
||||
Operation::Retag(RetagOp { orig_tag, permission, .. }) => {
|
||||
Operation::Retag(RetagOp { orig_tag, permission, new_tag, .. }) => {
|
||||
let permission = permission
|
||||
.expect("start_grant should set the current permission before popping a tag");
|
||||
format!(" due to {permission:?} retag from {orig_tag:?}")
|
||||
format!(" due to {permission:?} retag from {orig_tag:?} (that retag created {new_tag:?})")
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
//! Implements "Stacked Borrows". See <https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md>
|
||||
//! for further information.
|
||||
|
||||
pub mod diagnostics;
|
||||
mod item;
|
||||
mod stack;
|
||||
|
||||
use log::trace;
|
||||
use std::cmp;
|
||||
use std::fmt::{self, Write};
|
||||
use std::fmt::Write;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::mir::{Mutability, RetagKind};
|
||||
|
|
@ -15,15 +19,13 @@ use rustc_target::abi::{Abi, Size};
|
|||
|
||||
use crate::borrow_tracker::{
|
||||
stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder, TagHistory},
|
||||
AccessKind, GlobalStateInner, ProtectorKind, RetagCause, RetagFields,
|
||||
AccessKind, GlobalStateInner, ProtectorKind, RetagFields,
|
||||
};
|
||||
use crate::*;
|
||||
|
||||
mod item;
|
||||
use diagnostics::RetagCause;
|
||||
pub use item::{Item, Permission};
|
||||
mod stack;
|
||||
pub use stack::Stack;
|
||||
pub mod diagnostics;
|
||||
|
||||
pub type AllocState = Stacks;
|
||||
|
||||
|
|
@ -40,30 +42,104 @@ pub struct Stacks {
|
|||
modified_since_last_gc: bool,
|
||||
}
|
||||
|
||||
/// Indicates which kind of reference is being created.
|
||||
/// Used by high-level `reborrow` to compute which permissions to grant to the
|
||||
/// new pointer.
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
|
||||
enum RefKind {
|
||||
/// `Box`.
|
||||
Box,
|
||||
/// `&mut`.
|
||||
Unique { two_phase: bool },
|
||||
/// `&` with or without interior mutability.
|
||||
Shared,
|
||||
/// `*mut`/`*const` (raw pointers).
|
||||
Raw { mutable: bool },
|
||||
/// Indicates which permissions to grant to the retagged pointer.
|
||||
#[derive(Clone, Debug)]
|
||||
enum NewPermission {
|
||||
Uniform {
|
||||
perm: Permission,
|
||||
access: Option<AccessKind>,
|
||||
protector: Option<ProtectorKind>,
|
||||
},
|
||||
FreezeSensitive {
|
||||
freeze_perm: Permission,
|
||||
freeze_access: Option<AccessKind>,
|
||||
freeze_protector: Option<ProtectorKind>,
|
||||
nonfreeze_perm: Permission,
|
||||
nonfreeze_access: Option<AccessKind>,
|
||||
// nonfreeze_protector must always be None
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Display for RefKind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl NewPermission {
|
||||
/// A key function: determine the permissions to grant at a retag for the given kind of
|
||||
/// reference/pointer.
|
||||
fn from_ref_ty<'tcx>(
|
||||
ty: ty::Ty<'tcx>,
|
||||
kind: RetagKind,
|
||||
cx: &crate::MiriInterpCx<'_, 'tcx>,
|
||||
) -> Self {
|
||||
let protector = (kind == RetagKind::FnEntry).then_some(ProtectorKind::StrongProtector);
|
||||
match ty.kind() {
|
||||
ty::Ref(_, pointee, Mutability::Mut) => {
|
||||
if kind == RetagKind::TwoPhase {
|
||||
// We mostly just give up on 2phase-borrows, and treat these exactly like raw pointers.
|
||||
assert!(protector.is_none()); // RetagKind can't be both FnEntry and TwoPhase.
|
||||
NewPermission::Uniform {
|
||||
perm: Permission::SharedReadWrite,
|
||||
access: None,
|
||||
protector: None,
|
||||
}
|
||||
} else if pointee.is_unpin(*cx.tcx, cx.param_env()) {
|
||||
// A regular full mutable reference.
|
||||
NewPermission::Uniform {
|
||||
perm: Permission::Unique,
|
||||
access: Some(AccessKind::Write),
|
||||
protector,
|
||||
}
|
||||
} else {
|
||||
NewPermission::Uniform {
|
||||
perm: Permission::SharedReadWrite,
|
||||
// FIXME: We emit `dereferenceable` for `!Unpin` mutable references, so we
|
||||
// should do fake accesses here. But then we run into
|
||||
// <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>, so for now
|
||||
// we don't do that.
|
||||
access: None,
|
||||
protector,
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::RawPtr(ty::TypeAndMut { mutbl: Mutability::Mut, .. }) => {
|
||||
assert!(protector.is_none()); // RetagKind can't be both FnEntry and Raw.
|
||||
// Mutable raw pointer. No access, not protected.
|
||||
NewPermission::Uniform {
|
||||
perm: Permission::SharedReadWrite,
|
||||
access: None,
|
||||
protector: None,
|
||||
}
|
||||
}
|
||||
ty::Ref(_, _pointee, Mutability::Not) => {
|
||||
NewPermission::FreezeSensitive {
|
||||
freeze_perm: Permission::SharedReadOnly,
|
||||
freeze_access: Some(AccessKind::Read),
|
||||
freeze_protector: protector,
|
||||
nonfreeze_perm: Permission::SharedReadWrite,
|
||||
// Inside UnsafeCell, this does *not* count as an access, as there
|
||||
// might actually be mutable references further up the stack that
|
||||
// we have to keep alive.
|
||||
nonfreeze_access: None,
|
||||
// We do not protect inside UnsafeCell.
|
||||
// This fixes https://github.com/rust-lang/rust/issues/55005.
|
||||
}
|
||||
}
|
||||
ty::RawPtr(ty::TypeAndMut { mutbl: Mutability::Not, .. }) => {
|
||||
assert!(protector.is_none()); // RetagKind can't be both FnEntry and Raw.
|
||||
// `*const T`, when freshly created, are read-only in the frozen part.
|
||||
NewPermission::FreezeSensitive {
|
||||
freeze_perm: Permission::SharedReadOnly,
|
||||
freeze_access: Some(AccessKind::Read),
|
||||
freeze_protector: None,
|
||||
nonfreeze_perm: Permission::SharedReadWrite,
|
||||
nonfreeze_access: None,
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn protector(&self) -> Option<ProtectorKind> {
|
||||
match self {
|
||||
RefKind::Box => write!(f, "Box"),
|
||||
RefKind::Unique { two_phase: false } => write!(f, "unique reference"),
|
||||
RefKind::Unique { two_phase: true } => write!(f, "unique reference (two-phase)"),
|
||||
RefKind::Shared => write!(f, "shared reference"),
|
||||
RefKind::Raw { mutable: true } => write!(f, "raw (mutable) pointer"),
|
||||
RefKind::Raw { mutable: false } => write!(f, "raw (constant) pointer"),
|
||||
NewPermission::Uniform { protector, .. } => *protector,
|
||||
NewPermission::FreezeSensitive { freeze_protector, .. } => *freeze_protector,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -518,10 +594,9 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
size: Size,
|
||||
kind: RefKind,
|
||||
retag_cause: RetagCause, // What caused this retag, for diagnostics only
|
||||
new_perm: NewPermission,
|
||||
new_tag: BorTag,
|
||||
protect: Option<ProtectorKind>,
|
||||
retag_cause: RetagCause, // What caused this retag, for diagnostics only
|
||||
) -> InterpResult<'tcx, Option<AllocId>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
|
|
@ -532,20 +607,16 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
let global = this.machine.borrow_tracker.as_ref().unwrap().borrow();
|
||||
let ty = place.layout.ty;
|
||||
if global.tracked_pointer_tags.contains(&new_tag) {
|
||||
let mut kind_str = format!("{kind}");
|
||||
match kind {
|
||||
RefKind::Unique { two_phase: false }
|
||||
if !ty.is_unpin(*this.tcx, this.param_env()) =>
|
||||
{
|
||||
write!(kind_str, " (!Unpin pointee type {ty})").unwrap()
|
||||
},
|
||||
RefKind::Shared
|
||||
if !ty.is_freeze(*this.tcx, this.param_env()) =>
|
||||
{
|
||||
write!(kind_str, " (!Freeze pointee type {ty})").unwrap()
|
||||
},
|
||||
_ => write!(kind_str, " (pointee type {ty})").unwrap(),
|
||||
};
|
||||
let mut kind_str = String::new();
|
||||
match new_perm {
|
||||
NewPermission::Uniform { perm, .. } =>
|
||||
write!(kind_str, "{perm:?} permission").unwrap(),
|
||||
NewPermission::FreezeSensitive { freeze_perm, .. } if ty.is_freeze(*this.tcx, this.param_env()) =>
|
||||
write!(kind_str, "{freeze_perm:?} permission").unwrap(),
|
||||
NewPermission::FreezeSensitive { freeze_perm, nonfreeze_perm, .. } =>
|
||||
write!(kind_str, "{freeze_perm:?}/{nonfreeze_perm:?} permission for frozen/non-frozen parts").unwrap(),
|
||||
}
|
||||
write!(kind_str, " (pointee type {ty})").unwrap();
|
||||
this.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
|
||||
new_tag.inner(),
|
||||
Some(kind_str),
|
||||
|
|
@ -579,7 +650,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
);
|
||||
let mut dcx = dcx.build(&mut stacked_borrows.history, base_offset);
|
||||
dcx.log_creation();
|
||||
if protect.is_some() {
|
||||
if new_perm.protector().is_some() {
|
||||
dcx.log_protector();
|
||||
}
|
||||
},
|
||||
|
|
@ -592,8 +663,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
|
||||
if size == Size::ZERO {
|
||||
trace!(
|
||||
"reborrow of size 0: {} reference {:?} derived from {:?} (pointee {})",
|
||||
kind,
|
||||
"reborrow of size 0: reference {:?} derived from {:?} (pointee {})",
|
||||
new_tag,
|
||||
place.ptr,
|
||||
place.layout.ty,
|
||||
|
|
@ -630,8 +700,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
}
|
||||
|
||||
trace!(
|
||||
"reborrow: {} reference {:?} derived from {:?} (pointee {}): {:?}, size {}",
|
||||
kind,
|
||||
"reborrow: reference {:?} derived from {:?} (pointee {}): {:?}, size {}",
|
||||
new_tag,
|
||||
orig_tag,
|
||||
place.layout.ty,
|
||||
|
|
@ -639,7 +708,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
size.bytes()
|
||||
);
|
||||
|
||||
if let Some(protect) = protect {
|
||||
if let Some(protect) = new_perm.protector() {
|
||||
// See comment in `Stack::item_invalidated` for why we store the tag twice.
|
||||
this.frame_mut().extra.borrow_tracker.as_mut().unwrap().protected_tags.push(new_tag);
|
||||
this.machine
|
||||
|
|
@ -651,30 +720,45 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
.insert(new_tag, protect);
|
||||
}
|
||||
|
||||
// Update the stacks.
|
||||
// Make sure that raw pointers and mutable shared references are reborrowed "weak":
|
||||
// There could be existing unique pointers reborrowed from them that should remain valid!
|
||||
let (perm, access) = match kind {
|
||||
RefKind::Unique { two_phase } => {
|
||||
// Permission is Unique only if the type is `Unpin` and this is not twophase
|
||||
if !two_phase && place.layout.ty.is_unpin(*this.tcx, this.param_env()) {
|
||||
(Permission::Unique, Some(AccessKind::Write))
|
||||
} else {
|
||||
// FIXME: We emit `dereferenceable` for `!Unpin` mutable references, so we
|
||||
// should do fake accesses here. But then we run into
|
||||
// <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>, so for now
|
||||
// we don't do that.
|
||||
(Permission::SharedReadWrite, None)
|
||||
// Update the stacks, according to the new permission information we are given.
|
||||
match new_perm {
|
||||
NewPermission::Uniform { perm, access, protector } => {
|
||||
assert!(perm != Permission::SharedReadOnly);
|
||||
// Here we can avoid `borrow()` calls because we have mutable references.
|
||||
// Note that this asserts that the allocation is mutable -- but since we are creating a
|
||||
// mutable pointer, that seems reasonable.
|
||||
let (alloc_extra, machine) = this.get_alloc_extra_mut(alloc_id)?;
|
||||
let stacked_borrows = alloc_extra.borrow_tracker_sb_mut().get_mut();
|
||||
let item = Item::new(new_tag, perm, protector.is_some());
|
||||
let range = alloc_range(base_offset, size);
|
||||
let global = machine.borrow_tracker.as_ref().unwrap().borrow();
|
||||
let dcx = DiagnosticCxBuilder::retag(
|
||||
machine,
|
||||
retag_cause,
|
||||
new_tag,
|
||||
orig_tag,
|
||||
alloc_range(base_offset, size),
|
||||
);
|
||||
stacked_borrows.for_each(range, dcx, |stack, dcx, exposed_tags| {
|
||||
stack.grant(orig_tag, item, access, &global, dcx, exposed_tags)
|
||||
})?;
|
||||
drop(global);
|
||||
if let Some(access) = access {
|
||||
assert_eq!(access, AccessKind::Write);
|
||||
// Make sure the data race model also knows about this.
|
||||
if let Some(data_race) = alloc_extra.data_race.as_mut() {
|
||||
data_race.write(alloc_id, range, machine)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
RefKind::Box => (Permission::Unique, Some(AccessKind::Write)),
|
||||
RefKind::Raw { mutable: true } => {
|
||||
// Creating a raw ptr does not count as an access
|
||||
(Permission::SharedReadWrite, None)
|
||||
}
|
||||
RefKind::Shared | RefKind::Raw { mutable: false } => {
|
||||
// Shared references and *const are a whole different kind of game, the
|
||||
// permission is not uniform across the entire range!
|
||||
NewPermission::FreezeSensitive {
|
||||
freeze_perm,
|
||||
freeze_access,
|
||||
freeze_protector,
|
||||
nonfreeze_perm,
|
||||
nonfreeze_access,
|
||||
} => {
|
||||
// The permission is not uniform across the entire range!
|
||||
// We need a frozen-sensitive reborrow.
|
||||
// We have to use shared references to alloc/memory_extra here since
|
||||
// `visit_freeze_sensitive` needs to access the global state.
|
||||
|
|
@ -684,22 +768,12 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
// Adjust range.
|
||||
range.start += base_offset;
|
||||
// We are only ever `SharedReadOnly` inside the frozen bits.
|
||||
let (perm, access) = if frozen {
|
||||
(Permission::SharedReadOnly, Some(AccessKind::Read))
|
||||
let (perm, access, protector) = if frozen {
|
||||
(freeze_perm, freeze_access, freeze_protector)
|
||||
} else {
|
||||
// Inside UnsafeCell, this does *not* count as an access, as there
|
||||
// might actually be mutable references further up the stack that
|
||||
// we have to keep alive.
|
||||
(Permission::SharedReadWrite, None)
|
||||
(nonfreeze_perm, nonfreeze_access, None)
|
||||
};
|
||||
let protected = if frozen {
|
||||
protect.is_some()
|
||||
} else {
|
||||
// We do not protect inside UnsafeCell.
|
||||
// This fixes https://github.com/rust-lang/rust/issues/55005.
|
||||
false
|
||||
};
|
||||
let item = Item::new(new_tag, perm, protected);
|
||||
let item = Item::new(new_tag, perm, protector.is_some());
|
||||
let global = this.machine.borrow_tracker.as_ref().unwrap().borrow();
|
||||
let dcx = DiagnosticCxBuilder::retag(
|
||||
&this.machine,
|
||||
|
|
@ -721,34 +795,6 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
}
|
||||
Ok(())
|
||||
})?;
|
||||
return Ok(Some(alloc_id));
|
||||
}
|
||||
};
|
||||
|
||||
// Here we can avoid `borrow()` calls because we have mutable references.
|
||||
// Note that this asserts that the allocation is mutable -- but since we are creating a
|
||||
// mutable pointer, that seems reasonable.
|
||||
let (alloc_extra, machine) = this.get_alloc_extra_mut(alloc_id)?;
|
||||
let stacked_borrows = alloc_extra.borrow_tracker_sb_mut().get_mut();
|
||||
let item = Item::new(new_tag, perm, protect.is_some());
|
||||
let range = alloc_range(base_offset, size);
|
||||
let global = machine.borrow_tracker.as_ref().unwrap().borrow();
|
||||
let dcx = DiagnosticCxBuilder::retag(
|
||||
machine,
|
||||
retag_cause,
|
||||
new_tag,
|
||||
orig_tag,
|
||||
alloc_range(base_offset, size),
|
||||
);
|
||||
stacked_borrows.for_each(range, dcx, |stack, dcx, exposed_tags| {
|
||||
stack.grant(orig_tag, item, access, &global, dcx, exposed_tags)
|
||||
})?;
|
||||
drop(global);
|
||||
if let Some(access) = access {
|
||||
assert_eq!(access, AccessKind::Write);
|
||||
// Make sure the data race model also knows about this.
|
||||
if let Some(data_race) = alloc_extra.data_race.as_mut() {
|
||||
data_race.write(alloc_id, range, machine)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -760,9 +806,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
fn sb_retag_reference(
|
||||
&mut self,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
kind: RefKind,
|
||||
retag_cause: RetagCause, // What caused this retag, for diagnostics only
|
||||
protect: Option<ProtectorKind>,
|
||||
new_perm: NewPermission,
|
||||
cause: RetagCause, // What caused this retag, for diagnostics only
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
// We want a place for where the ptr *points to*, so we get one.
|
||||
|
|
@ -780,7 +825,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
let new_tag = this.machine.borrow_tracker.as_mut().unwrap().get_mut().new_ptr();
|
||||
|
||||
// Reborrow.
|
||||
let alloc_id = this.sb_reborrow(&place, size, kind, retag_cause, new_tag, protect)?;
|
||||
let alloc_id = this.sb_reborrow(&place, size, new_perm, new_tag, cause)?;
|
||||
|
||||
// Adjust pointer.
|
||||
let new_place = place.map_provenance(|p| {
|
||||
|
|
@ -807,7 +852,22 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn sb_retag(
|
||||
fn sb_retag_ptr_value(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
let new_perm = NewPermission::from_ref_ty(val.layout.ty, kind, this);
|
||||
let retag_cause = match kind {
|
||||
RetagKind::TwoPhase { .. } => RetagCause::TwoPhase,
|
||||
RetagKind::FnEntry => unreachable!(),
|
||||
RetagKind::Raw | RetagKind::Default => RetagCause::Normal,
|
||||
};
|
||||
this.sb_retag_reference(&val, new_perm, retag_cause)
|
||||
}
|
||||
|
||||
fn sb_retag_place_contents(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
|
|
@ -815,9 +875,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let this = self.eval_context_mut();
|
||||
let retag_fields = this.machine.borrow_tracker.as_mut().unwrap().get_mut().retag_fields;
|
||||
let retag_cause = match kind {
|
||||
RetagKind::TwoPhase { .. } => RetagCause::TwoPhase,
|
||||
RetagKind::Raw | RetagKind::TwoPhase { .. } => unreachable!(), // these can only happen in `retag_ptr_value`
|
||||
RetagKind::FnEntry => RetagCause::FnEntry,
|
||||
RetagKind::Raw | RetagKind::Default => RetagCause::Normal,
|
||||
RetagKind::Default => RetagCause::Normal,
|
||||
};
|
||||
let mut visitor = RetagVisitor { ecx: this, kind, retag_cause, retag_fields };
|
||||
return visitor.visit_value(place);
|
||||
|
|
@ -831,15 +891,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> {
|
||||
#[inline(always)] // yes this helps in our benchmarks
|
||||
fn retag_place(
|
||||
fn retag_ptr_inplace(
|
||||
&mut self,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
ref_kind: RefKind,
|
||||
new_perm: NewPermission,
|
||||
retag_cause: RetagCause,
|
||||
protector: Option<ProtectorKind>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
|
||||
let val = self.ecx.sb_retag_reference(&val, ref_kind, retag_cause, protector)?;
|
||||
let val = self.ecx.sb_retag_reference(&val, new_perm, retag_cause)?;
|
||||
self.ecx.write_immediate(*val, place)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -856,13 +915,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
fn visit_box(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
// Boxes get a weak protectors, since they may be deallocated.
|
||||
self.retag_place(
|
||||
place,
|
||||
RefKind::Box,
|
||||
self.retag_cause,
|
||||
/*protector*/
|
||||
(self.kind == RetagKind::FnEntry).then_some(ProtectorKind::WeakProtector),
|
||||
)
|
||||
let new_perm = NewPermission::Uniform {
|
||||
perm: Permission::Unique,
|
||||
access: Some(AccessKind::Write),
|
||||
protector: (self.kind == RetagKind::FnEntry)
|
||||
.then_some(ProtectorKind::WeakProtector),
|
||||
};
|
||||
self.retag_ptr_inplace(place, new_perm, self.retag_cause)
|
||||
}
|
||||
|
||||
fn visit_value(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
|
|
@ -876,36 +935,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
// Check the type of this value to see what to do with it (retag, or recurse).
|
||||
match place.layout.ty.kind() {
|
||||
ty::Ref(_, _, mutbl) => {
|
||||
let ref_kind = match mutbl {
|
||||
Mutability::Mut =>
|
||||
RefKind::Unique { two_phase: self.kind == RetagKind::TwoPhase },
|
||||
Mutability::Not => RefKind::Shared,
|
||||
};
|
||||
self.retag_place(
|
||||
place,
|
||||
ref_kind,
|
||||
self.retag_cause,
|
||||
/*protector*/
|
||||
(self.kind == RetagKind::FnEntry)
|
||||
.then_some(ProtectorKind::StrongProtector),
|
||||
)?;
|
||||
ty::Ref(..) => {
|
||||
let new_perm =
|
||||
NewPermission::from_ref_ty(place.layout.ty, self.kind, self.ecx);
|
||||
self.retag_ptr_inplace(place, new_perm, self.retag_cause)?;
|
||||
}
|
||||
ty::RawPtr(tym) => {
|
||||
// We definitely do *not* want to recurse into raw pointers -- wide raw
|
||||
// pointers have fields, and for dyn Trait pointees those can have reference
|
||||
// type!
|
||||
if self.kind == RetagKind::Raw {
|
||||
// Raw pointers need to be enabled.
|
||||
self.retag_place(
|
||||
place,
|
||||
RefKind::Raw { mutable: tym.mutbl == Mutability::Mut },
|
||||
self.retag_cause,
|
||||
/*protector*/ None,
|
||||
)?;
|
||||
}
|
||||
ty::RawPtr(..) => {
|
||||
// We do *not* want to recurse into raw pointers -- wide raw pointers have
|
||||
// fields, and for dyn Trait pointees those can have reference type!
|
||||
}
|
||||
_ if place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box()) => {
|
||||
ty::Adt(adt, _) if adt.is_box() => {
|
||||
// Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
|
||||
// (Yes this means we technically also recursively retag the allocator itself
|
||||
// even if field retagging is not enabled. *shrug*)
|
||||
|
|
@ -953,12 +992,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let ptr_layout = this.layout_of(this.tcx.mk_mut_ptr(return_place.layout.ty))?;
|
||||
let val = ImmTy::from_immediate(return_place.to_ref(this), ptr_layout);
|
||||
// Reborrow it. With protection! That is part of the point.
|
||||
let val = this.sb_retag_reference(
|
||||
&val,
|
||||
RefKind::Unique { two_phase: false },
|
||||
RetagCause::FnReturn,
|
||||
/*protector*/ Some(ProtectorKind::StrongProtector),
|
||||
)?;
|
||||
let new_perm = NewPermission::Uniform {
|
||||
perm: Permission::Unique,
|
||||
access: Some(AccessKind::Write),
|
||||
protector: Some(ProtectorKind::StrongProtector),
|
||||
};
|
||||
let val = this.sb_retag_reference(&val, new_perm, RetagCause::FnReturn)?;
|
||||
// And use reborrowed pointer for return place.
|
||||
let return_place = this.ref_to_mplace(&val)?;
|
||||
this.frame_mut().return_place = return_place.into();
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ impl MachineStopType for TerminationInfo {}
|
|||
|
||||
/// Miri specific diagnostics
|
||||
pub enum NonHaltingDiagnostic {
|
||||
/// (new_tag, new_kind, (alloc_id, base_offset, orig_tag))
|
||||
/// (new_tag, new_perm, (alloc_id, base_offset, orig_tag))
|
||||
///
|
||||
/// new_kind is `None` for base tags.
|
||||
/// new_perm is `None` for base tags.
|
||||
CreatedPointerTag(NonZeroU64, Option<String>, Option<(AllocId, AllocRange, ProvenanceExtra)>),
|
||||
/// This `Item` was popped from the borrow stack. The string explains the reason.
|
||||
PoppedPointerTag(Item, String),
|
||||
|
|
@ -393,10 +393,10 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
|||
|
||||
let msg = match &e {
|
||||
CreatedPointerTag(tag, None, _) => format!("created base tag {tag:?}"),
|
||||
CreatedPointerTag(tag, Some(kind), None) => format!("created {tag:?} for {kind}"),
|
||||
CreatedPointerTag(tag, Some(kind), Some((alloc_id, range, orig_tag))) =>
|
||||
CreatedPointerTag(tag, Some(perm), None) => format!("created {tag:?} with {perm} derived from unknown tag"),
|
||||
CreatedPointerTag(tag, Some(perm), Some((alloc_id, range, orig_tag))) =>
|
||||
format!(
|
||||
"created tag {tag:?} for {kind} at {alloc_id:?}{range:?} derived from {orig_tag:?}"
|
||||
"created tag {tag:?} with {perm} at {alloc_id:?}{range:?} derived from {orig_tag:?}"
|
||||
),
|
||||
PoppedPointerTag(item, cause) => format!("popped tracked tag for item {item:?}{cause}"),
|
||||
CreatedCallId(id) => format!("function call with id {id}"),
|
||||
|
|
|
|||
|
|
@ -967,8 +967,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
|||
ptr: Pointer<Self::Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
match ptr.provenance {
|
||||
Provenance::Concrete { alloc_id, tag } =>
|
||||
intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag),
|
||||
Provenance::Concrete { alloc_id, tag } => {
|
||||
intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag)
|
||||
}
|
||||
Provenance::Wildcard => {
|
||||
// No need to do anything for wildcard pointers as
|
||||
// their provenances have already been previously exposed.
|
||||
|
|
@ -1055,13 +1056,26 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn retag(
|
||||
fn retag_ptr_value(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
kind: mir::RetagKind,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
if ecx.machine.borrow_tracker.is_some() {
|
||||
ecx.retag_ptr_value(kind, val)
|
||||
} else {
|
||||
Ok(val.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn retag_place_contents(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
kind: mir::RetagKind,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
if ecx.machine.borrow_tracker.is_some() {
|
||||
ecx.retag(kind, place)?;
|
||||
ecx.retag_place_contents(kind, place)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue