Skip to content

Commit 291f59b

Browse files
committed
Pretty print pattern type values with transmute if they don't satisfy their pattern
1 parent 5e55679 commit 291f59b

File tree

8 files changed

+53
-13
lines changed

8 files changed

+53
-13
lines changed

compiler/rustc_const_eval/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ pub fn provide(providers: &mut Providers) {
5252
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
5353
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
5454
};
55+
providers.hooks.validate_scalar_in_layout =
56+
|tcx, scalar, layout| util::validate_scalar_in_layout(tcx, scalar, layout);
5557
}
5658

5759
/// `rustc_driver::main` installs a handler that will set this to `true` if

compiler/rustc_const_eval/src/util/check_validity_requirement.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn check_validity_requirement<'tcx>(
3434

3535
let layout_cx = LayoutCx::new(tcx, input.typing_env);
3636
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
37-
check_validity_requirement_strict(layout, &layout_cx, kind)
37+
Ok(check_validity_requirement_strict(layout, &layout_cx, kind))
3838
} else {
3939
check_validity_requirement_lax(layout, &layout_cx, kind)
4040
}
@@ -46,7 +46,7 @@ fn check_validity_requirement_strict<'tcx>(
4646
ty: TyAndLayout<'tcx>,
4747
cx: &LayoutCx<'tcx>,
4848
kind: ValidityRequirement,
49-
) -> Result<bool, &'tcx LayoutError<'tcx>> {
49+
) -> bool {
5050
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
5151

5252
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env, machine);
@@ -69,14 +69,13 @@ fn check_validity_requirement_strict<'tcx>(
6969
// due to this.
7070
// The value we are validating is temporary and discarded at the end of this function, so
7171
// there is no point in reseting provenance and padding.
72-
Ok(cx
73-
.validate_operand(
74-
&allocated.into(),
75-
/*recursive*/ false,
76-
/*reset_provenance_and_padding*/ false,
77-
)
78-
.discard_err()
79-
.is_some())
72+
cx.validate_operand(
73+
&allocated.into(),
74+
/*recursive*/ false,
75+
/*reset_provenance_and_padding*/ false,
76+
)
77+
.discard_err()
78+
.is_some()
8079
}
8180

8281
/// Implements the 'lax' (default) version of the [`check_validity_requirement`] checks; see that

compiler/rustc_const_eval/src/util/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ pub(crate) mod caller_location;
55
mod check_validity_requirement;
66
mod compare_types;
77
mod type_name;
8+
mod validate_scalar_in_layout;
89

910
pub use self::alignment::{is_disaligned, is_within_packed};
1011
pub use self::check_validity_requirement::check_validity_requirement;
1112
pub use self::compare_types::{relate_types, sub_types};
1213
pub use self::type_name::type_name;
14+
pub(crate) use self::validate_scalar_in_layout::validate_scalar_in_layout;
1315

1416
/// Classify whether an operator is "left-homogeneous", i.e., the LHS has the
1517
/// same type as the result.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use rustc_middle::query::TyCtxtAt;
2+
use rustc_middle::ty::layout::TyAndLayout;
3+
use rustc_middle::ty::{self, ScalarInt};
4+
5+
use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
6+
use crate::interpret::{InterpCx, MemoryKind};
7+
8+
pub(crate) fn validate_scalar_in_layout<'tcx>(
9+
tcx: TyCtxtAt<'tcx>,
10+
scalar: ScalarInt,
11+
layout: TyAndLayout<'tcx>,
12+
) -> bool {
13+
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
14+
15+
let mut cx = InterpCx::new(tcx.tcx, tcx.span, ty::TypingEnv::fully_monomorphized(), machine);
16+
17+
let allocated = cx
18+
.allocate(layout, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
19+
.expect("OOM: failed to allocate for uninit check");
20+
21+
cx.write_scalar(scalar, &allocated).unwrap();
22+
23+
cx.validate_operand(
24+
&allocated.into(),
25+
/*recursive*/ false,
26+
/*reset_provenance_and_padding*/ false,
27+
)
28+
.discard_err()
29+
.is_some()
30+
}

compiler/rustc_middle/src/hooks/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ declare_hooks! {
121121
hook save_dep_graph() -> ();
122122

123123
hook query_key_hash_verify_all() -> ();
124+
125+
hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, layout: crate::ty::layout::TyAndLayout<'tcx>) -> bool;
124126
}
125127

126128
#[cold]

compiler/rustc_middle/src/ty/print/pretty.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1740,7 +1740,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
17401740
" as ",
17411741
)?;
17421742
}
1743-
ty::Pat(base_ty, pat) => {
1743+
ty::Pat(base_ty, pat)
1744+
if self
1745+
.tcx()
1746+
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
1747+
.is_ok_and(|layout| self.tcx().validate_scalar_in_layout(int, layout)) =>
1748+
{
17441749
self.pretty_print_const_scalar_int(int, *base_ty, print_ty)?;
17451750
p!(write(" is {pat:?}"));
17461751
}

tests/mir-opt/pattern_types.main.PreCodegen.after.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fn main() -> () {
55
scope 1 {
66
debug x => const 2_u32 is 1..=;
77
scope 2 {
8-
debug y => const 0_u32 is 1..=;
8+
debug y => const {transmute(0x00000000): (u32) is 1..=};
99
}
1010
}
1111

tests/mir-opt/pattern_types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ use std::pat::pattern_type;
77
fn main() {
88
// CHECK: debug x => const 2_u32 is 1..=
99
let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(2) };
10-
// CHECK: debug y => const 0_u32 is 1..=
10+
// CHECK: debug y => const {transmute(0x00000000): (u32) is 1..=}
1111
let y: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) };
1212
}

0 commit comments

Comments
 (0)