Gracefully handle non-UTF-8 string slices when pretty printing

This commit is contained in:
Tomasz Miąsko 2022-02-19 00:00:00 +00:00
parent 25ad89e47b
commit f233323f6d
4 changed files with 47 additions and 50 deletions

View file

@ -1443,8 +1443,7 @@ pub trait PrettyPrinter<'tcx>:
// relocations (we have an active `str` reference here). We don't use this
// result to affect interpreter execution.
let slice = data.inspect_with_uninit_and_ptr_outside_interpreter(start..end);
let s = std::str::from_utf8(slice).expect("non utf8 str from miri");
p!(write("{:?}", s));
p!(write("{:?}", String::from_utf8_lossy(slice)));
Ok(self)
}
(ConstValue::ByRef { alloc, offset }, ty::Array(t, n)) if *t == u8_type => {

View file

@ -2,63 +2,69 @@
+ // MIR for `main` after ConstProp
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/invalid_constant.rs:13:11: 13:11
let _1: main::InvalidChar; // in scope 0 at $DIR/invalid_constant.rs:19:9: 19:22
let mut _3: main::InvalidTag; // in scope 0 at $DIR/invalid_constant.rs:26:25: 26:46
let mut _5: main::NoVariants; // in scope 0 at $DIR/invalid_constant.rs:33:35: 33:56
let mut _0: (); // return place in scope 0 at $DIR/invalid_constant.rs:15:11: 15:11
let _1: main::InvalidChar; // in scope 0 at $DIR/invalid_constant.rs:21:9: 21:22
let mut _3: main::InvalidTag; // in scope 0 at $DIR/invalid_constant.rs:28:25: 28:46
let mut _5: main::NoVariants; // in scope 0 at $DIR/invalid_constant.rs:35:35: 35:56
scope 1 {
debug _invalid_char => _1; // in scope 1 at $DIR/invalid_constant.rs:19:9: 19:22
let _2: [main::InvalidTag; 1]; // in scope 1 at $DIR/invalid_constant.rs:26:9: 26:21
debug _invalid_char => _1; // in scope 1 at $DIR/invalid_constant.rs:21:9: 21:22
let _2: [main::InvalidTag; 1]; // in scope 1 at $DIR/invalid_constant.rs:28:9: 28:21
scope 2 {
debug _invalid_tag => _2; // in scope 2 at $DIR/invalid_constant.rs:26:9: 26:21
let _4: [main::NoVariants; 1]; // in scope 2 at $DIR/invalid_constant.rs:33:9: 33:31
debug _invalid_tag => _2; // in scope 2 at $DIR/invalid_constant.rs:28:9: 28:21
let _4: [main::NoVariants; 1]; // in scope 2 at $DIR/invalid_constant.rs:35:9: 35:31
scope 3 {
debug _enum_without_variants => _4; // in scope 3 at $DIR/invalid_constant.rs:33:9: 33:31
debug _enum_without_variants => _4; // in scope 3 at $DIR/invalid_constant.rs:35:9: 35:31
let _6: main::Str<"<22><><EFBFBD>">; // in scope 3 at $DIR/invalid_constant.rs:39:9: 39:22
scope 4 {
debug _non_utf8_str => _6; // in scope 4 at $DIR/invalid_constant.rs:39:9: 39:22
}
}
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/invalid_constant.rs:19:9: 19:22
- _1 = const { InvalidChar { int: 0x110001 } }; // scope 0 at $DIR/invalid_constant.rs:19:25: 19:64
+ _1 = const InvalidChar { int: 1114113_u32, chr: {transmute(0x00110001): char} }; // scope 0 at $DIR/invalid_constant.rs:19:25: 19:64
StorageLive(_1); // scope 0 at $DIR/invalid_constant.rs:21:9: 21:22
- _1 = const { InvalidChar { int: 0x110001 } }; // scope 0 at $DIR/invalid_constant.rs:21:25: 21:64
+ _1 = const InvalidChar { int: 1114113_u32, chr: {transmute(0x00110001): char} }; // scope 0 at $DIR/invalid_constant.rs:21:25: 21:64
// ty::Const
// + ty: main::InvalidChar
- // + val: Unevaluated(main::{constant#0}, [main::InvalidChar], None)
+ // + val: Value(Scalar(0x00110001))
// mir::Constant
// + span: $DIR/invalid_constant.rs:19:25: 19:64
// + span: $DIR/invalid_constant.rs:21:25: 21:64
- // + literal: Const { ty: main::InvalidChar, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ invalid_constant[726d]::main::{constant#0}), const_param_did: None }, substs: [main::InvalidChar], promoted: None }) }
+ // + literal: Const { ty: main::InvalidChar, val: Value(Scalar(0x00110001)) }
StorageLive(_2); // scope 1 at $DIR/invalid_constant.rs:26:9: 26:21
StorageLive(_3); // scope 1 at $DIR/invalid_constant.rs:26:25: 26:46
(_3.0: u32) = const 4_u32; // scope 1 at $DIR/invalid_constant.rs:26:25: 26:46
- _2 = [move _3]; // scope 1 at $DIR/invalid_constant.rs:26:24: 26:47
+ _2 = [const InvalidTag { int: 4_u32, e: Scalar(0x00000004): E }]; // scope 1 at $DIR/invalid_constant.rs:26:24: 26:47
StorageLive(_2); // scope 1 at $DIR/invalid_constant.rs:28:9: 28:21
StorageLive(_3); // scope 1 at $DIR/invalid_constant.rs:28:25: 28:46
(_3.0: u32) = const 4_u32; // scope 1 at $DIR/invalid_constant.rs:28:25: 28:46
- _2 = [move _3]; // scope 1 at $DIR/invalid_constant.rs:28:24: 28:47
+ _2 = [const InvalidTag { int: 4_u32, e: Scalar(0x00000004): E }]; // scope 1 at $DIR/invalid_constant.rs:28:24: 28:47
+ // ty::Const
+ // + ty: main::InvalidTag
+ // + val: Value(Scalar(0x00000004))
+ // mir::Constant
+ // + span: $DIR/invalid_constant.rs:26:24: 26:47
+ // + span: $DIR/invalid_constant.rs:28:24: 28:47
+ // + literal: Const { ty: main::InvalidTag, val: Value(Scalar(0x00000004)) }
StorageDead(_3); // scope 1 at $DIR/invalid_constant.rs:26:46: 26:47
StorageLive(_4); // scope 2 at $DIR/invalid_constant.rs:33:9: 33:31
StorageLive(_5); // scope 2 at $DIR/invalid_constant.rs:33:35: 33:56
(_5.0: u32) = const 0_u32; // scope 2 at $DIR/invalid_constant.rs:33:35: 33:56
- _4 = [move _5]; // scope 2 at $DIR/invalid_constant.rs:33:34: 33:57
+ _4 = [const NoVariants { int: 0_u32, empty: Scalar(<ZST>): Empty }]; // scope 2 at $DIR/invalid_constant.rs:33:34: 33:57
StorageDead(_3); // scope 1 at $DIR/invalid_constant.rs:28:46: 28:47
StorageLive(_4); // scope 2 at $DIR/invalid_constant.rs:35:9: 35:31
StorageLive(_5); // scope 2 at $DIR/invalid_constant.rs:35:35: 35:56
(_5.0: u32) = const 0_u32; // scope 2 at $DIR/invalid_constant.rs:35:35: 35:56
- _4 = [move _5]; // scope 2 at $DIR/invalid_constant.rs:35:34: 35:57
+ _4 = [const NoVariants { int: 0_u32, empty: Scalar(<ZST>): Empty }]; // scope 2 at $DIR/invalid_constant.rs:35:34: 35:57
+ // ty::Const
+ // + ty: main::NoVariants
+ // + val: Value(Scalar(0x00000000))
+ // mir::Constant
+ // + span: $DIR/invalid_constant.rs:33:34: 33:57
+ // + span: $DIR/invalid_constant.rs:35:34: 35:57
+ // + literal: Const { ty: main::NoVariants, val: Value(Scalar(0x00000000)) }
StorageDead(_5); // scope 2 at $DIR/invalid_constant.rs:33:56: 33:57
nop; // scope 0 at $DIR/invalid_constant.rs:13:11: 34:2
StorageDead(_4); // scope 2 at $DIR/invalid_constant.rs:34:1: 34:2
StorageDead(_2); // scope 1 at $DIR/invalid_constant.rs:34:1: 34:2
StorageDead(_1); // scope 0 at $DIR/invalid_constant.rs:34:1: 34:2
return; // scope 0 at $DIR/invalid_constant.rs:34:2: 34:2
StorageDead(_5); // scope 2 at $DIR/invalid_constant.rs:35:56: 35:57
StorageLive(_6); // scope 3 at $DIR/invalid_constant.rs:39:9: 39:22
nop; // scope 0 at $DIR/invalid_constant.rs:15:11: 42:2
StorageDead(_6); // scope 3 at $DIR/invalid_constant.rs:42:1: 42:2
StorageDead(_4); // scope 2 at $DIR/invalid_constant.rs:42:1: 42:2
StorageDead(_2); // scope 1 at $DIR/invalid_constant.rs:42:1: 42:2
StorageDead(_1); // scope 0 at $DIR/invalid_constant.rs:42:1: 42:2
return; // scope 0 at $DIR/invalid_constant.rs:42:2: 42:2
}
}

View file

@ -1,6 +1,8 @@
// Verify that we can pretty print invalid constants.
#![feature(adt_const_params)]
#![feature(inline_const)]
#![allow(incomplete_features)]
#[derive(Copy, Clone)]
#[repr(u32)]
@ -31,4 +33,10 @@ fn main() {
empty: Empty,
}
let _enum_without_variants = [NoVariants { int: 0 }];
// A non-UTF-8 string slice. Regression test for #75763 and #78520.
struct Str<const S: &'static str>;
let _non_utf8_str: Str::<{
unsafe { std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) }
}>;
}

View file

@ -1,16 +0,0 @@
// ignore-test
// FIXME(const_generics): This test causes an ICE after reverting #76030.
#![feature(adt_const_params)]
#![allow(incomplete_features)]
struct Bug<const S: &'static str>;
fn main() {
let b: Bug::<{
unsafe {
// FIXME(adt_const_params): Decide on how to deal with invalid values as const params.
std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5])
}
}>;
}