From f233323f6d4529322613de04289a8d6efc2ab618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 19 Feb 2022 00:00:00 +0000 Subject: [PATCH] Gracefully handle non-UTF-8 string slices when pretty printing --- compiler/rustc_middle/src/ty/print/pretty.rs | 3 +- .../invalid_constant.main.ConstProp.diff | 70 ++++++++++--------- .../mir-opt/const_prop/invalid_constant.rs | 8 +++ .../ui/const-generics/issues/issue-75763.rs | 16 ----- 4 files changed, 47 insertions(+), 50 deletions(-) delete mode 100644 src/test/ui/const-generics/issues/issue-75763.rs diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index fbf30b58818..636b571a922 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -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 => { diff --git a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff index 03f827f63f3..9480566897f 100644 --- a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff @@ -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<"���">; // 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(): 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(): 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 } } diff --git a/src/test/mir-opt/const_prop/invalid_constant.rs b/src/test/mir-opt/const_prop/invalid_constant.rs index e0879cf4800..492ef404916 100644 --- a/src/test/mir-opt/const_prop/invalid_constant.rs +++ b/src/test/mir-opt/const_prop/invalid_constant.rs @@ -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; + let _non_utf8_str: Str::<{ + unsafe { std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) } + }>; } diff --git a/src/test/ui/const-generics/issues/issue-75763.rs b/src/test/ui/const-generics/issues/issue-75763.rs deleted file mode 100644 index 214a04b8a6b..00000000000 --- a/src/test/ui/const-generics/issues/issue-75763.rs +++ /dev/null @@ -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; - -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]) - } - }>; -}