From 4dcf988360b52610582deedbb7b6e3f84d5e7dae Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 28 Jun 2023 09:23:34 +0000 Subject: [PATCH 1/7] Specialize `try_destructure_mir_constant` for its sole user --- compiler/rustc_const_eval/src/const_eval/mod.rs | 11 ++++++----- compiler/rustc_const_eval/src/interpret/operand.rs | 2 +- compiler/rustc_const_eval/src/lib.rs | 6 ++---- compiler/rustc_middle/src/mir/mod.rs | 7 +------ compiler/rustc_middle/src/query/keys.rs | 9 +++++++++ compiler/rustc_middle/src/query/mod.rs | 6 ++++-- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 5cc1fa2a4974b..900adb559bde9 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -6,7 +6,7 @@ use crate::interpret::{ }; use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{source_map::DUMMY_SP, symbol::Symbol}; mod error; @@ -89,14 +89,15 @@ pub(crate) fn eval_to_valtree<'tcx>( #[instrument(skip(tcx), level = "debug")] pub(crate) fn try_destructure_mir_constant<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - val: mir::ConstantKind<'tcx>, + val: ConstValue<'tcx>, + ty: Ty<'tcx>, ) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> { + let param_env = ty::ParamEnv::reveal_all(); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No); - let op = ecx.eval_mir_constant(&val, None, None)?; + let op = ecx.const_val_to_op(val, ty, None)?; // We go to `usize` as we cannot allocate anything bigger anyway. - let (field_count, variant, down) = match val.ty().kind() { + let (field_count, variant, down) = match ty.kind() { ty::Array(_, len) => (len.eval_target_usize(tcx, param_env) as usize, None, op), ty::Adt(def, _) if def.variants().is_empty() => { throw_ub!(Unreachable) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index e30af165501e5..ba3be9083be1a 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -633,7 +633,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - pub(super) fn const_val_to_op( + pub(crate) fn const_val_to_op( &self, val_val: ConstValue<'tcx>, ty: Ty<'tcx>, diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 8314f53ba57bb..826d2a15721a5 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -52,10 +52,8 @@ pub fn provide(providers: &mut Providers) { let (param_env, raw) = param_env_and_value.into_parts(); const_eval::eval_to_valtree(tcx, param_env, raw) }; - providers.try_destructure_mir_constant = |tcx, param_env_and_value| { - let (param_env, value) = param_env_and_value.into_parts(); - const_eval::try_destructure_mir_constant(tcx, param_env, value).ok() - }; + providers.try_destructure_mir_constant = + |tcx, (cv, ty)| const_eval::try_destructure_mir_constant(tcx, cv, ty).ok(); providers.valtree_to_const_val = |tcx, (ty, valtree)| { const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree) }; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 124b569204807..af244d870c074 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2882,15 +2882,10 @@ fn pretty_print_const_value<'tcx>( // introducing ICEs (e.g. via `layout_of`) from missing bounds. // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized` // to be able to destructure the tuple into `(0u8, *mut T)` - // - // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the - // correct `ty::ParamEnv` to allow printing *all* constant values. (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => { let ct = tcx.lift(ct).unwrap(); let ty = tcx.lift(ty).unwrap(); - if let Some(contents) = tcx.try_destructure_mir_constant( - ty::ParamEnv::reveal_all().and(ConstantKind::Val(ct, ty)), - ) { + if let Some(contents) = tcx.try_destructure_mir_constant((ct, ty)) { let fields = contents.fields.to_vec(); match *ty.kind() { ty::Array(..) => { diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 4006a6cd1cc1f..0119e07a44e15 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -2,6 +2,7 @@ use crate::infer::canonical::Canonical; use crate::mir; +use crate::mir::interpret::ConstValue; use crate::traits; use crate::ty::fast_reject::SimplifiedType; use crate::ty::layout::{TyAndLayout, ValidityRequirement}; @@ -333,6 +334,14 @@ impl<'tcx> Key for (ty::Const<'tcx>, FieldIdx) { } } +impl<'tcx> Key for (ConstValue<'tcx>, Ty<'tcx>) { + type CacheSelector = DefaultCacheSelector; + + fn default_span(&self, _: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + impl<'tcx> Key for mir::interpret::ConstAlloc<'tcx> { type CacheSelector = DefaultCacheSelector; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0e1c6d19e3189..81efbd8b094d2 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1087,11 +1087,13 @@ rustc_queries! { } /// Tries to destructure an `mir::ConstantKind` ADT or array into its variant index - /// and its field values. + /// and its field values. This should only be used for pretty printing. query try_destructure_mir_constant( - key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> + key: (ConstValue<'tcx>, Ty<'tcx>) ) -> Option> { desc { "destructuring MIR constant"} + no_hash + eval_always } query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { From a0eb348d3828a6332a8372536a008bfbf7585c03 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 28 Jun 2023 09:34:26 +0000 Subject: [PATCH 2/7] Specialize `DestructuredConstant` to its one user (pretty printing) --- compiler/rustc_const_eval/src/const_eval/mod.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 15 ++++++++++----- compiler/rustc_middle/src/mir/query.rs | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 900adb559bde9..f23cb905c2379 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -115,7 +115,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( .map(|i| { let field_op = ecx.operand_field(&down, i)?; let val = op_to_const(&ecx, &field_op); - Ok(mir::ConstantKind::Val(val, field_op.layout.ty)) + Ok((val, field_op.layout.ty)) }) .collect::>>()?; let fields = tcx.arena.alloc_from_iter(fields_iter); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index af244d870c074..6f1be38ee872d 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2806,13 +2806,16 @@ fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Resul write!(fmt, "b\"{}\"", byte_str.escape_ascii()) } -fn comma_sep<'tcx>(fmt: &mut Formatter<'_>, elems: Vec>) -> fmt::Result { +fn comma_sep<'tcx>( + fmt: &mut Formatter<'_>, + elems: Vec<(ConstValue<'tcx>, Ty<'tcx>)>, +) -> fmt::Result { let mut first = true; - for elem in elems { + for (ct, ty) in elems { if !first { fmt.write_str(", ")?; } - fmt.write_str(&format!("{}", elem))?; + pretty_print_const_value(ct, ty, fmt, true)?; first = false; } Ok(()) @@ -2925,12 +2928,14 @@ fn pretty_print_const_value<'tcx>( None => { fmt.write_str(" {{ ")?; let mut first = true; - for (field_def, field) in iter::zip(&variant_def.fields, fields) + for (field_def, (ct, ty)) in + iter::zip(&variant_def.fields, fields) { if !first { fmt.write_str(", ")?; } - fmt.write_str(&format!("{}: {}", field_def.name, field))?; + write!(fmt, "{}: ", field_def.name)?; + pretty_print_const_value(ct, ty, fmt, true)?; first = false; } fmt.write_str(" }}")?; diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 13a1011e328ee..613b132ff2d5c 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,6 +1,6 @@ //! Values computed by queries that use MIR. -use crate::mir::ConstantKind; +use crate::mir::interpret::ConstValue; use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordSet; @@ -444,7 +444,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> { #[derive(Copy, Clone, Debug, HashStable)] pub struct DestructuredConstant<'tcx> { pub variant: Option, - pub fields: &'tcx [ConstantKind<'tcx>], + pub fields: &'tcx [(ConstValue<'tcx>, Ty<'tcx>)], } /// Coverage information summarized from a MIR if instrumented for source code coverage (see From 09b89efa70905275dc6abfe17666508127734407 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 28 Jun 2023 09:43:31 +0000 Subject: [PATCH 3/7] Remove a function argument that is always passed with the same value. --- .../rustc_const_eval/src/interpret/operand.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 26 ++++--------- compiler/rustc_middle/src/ty/print/pretty.rs | 39 +++++++------------ 3 files changed, 21 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index ba3be9083be1a..5f89d652fab21 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -106,7 +106,7 @@ impl std::fmt::Display for ImmTy<'_, Prov> { // Just print the ptr value. `pretty_print_const_scalar_ptr` would also try to // print what is points to, which would fail since it has no access to the local // memory. - cx.pretty_print_const_pointer(ptr, ty, true) + cx.pretty_print_const_pointer(ptr, ty) } } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 6f1be38ee872d..480a12c4cb435 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2776,7 +2776,7 @@ impl<'tcx> Display for ConstantKind<'tcx> { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { match *self { ConstantKind::Ty(c) => pretty_print_const(c, fmt, true), - ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true), + ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt), // FIXME(valtrees): Correctly print mir constants. ConstantKind::Unevaluated(..) => { fmt.write_str("_")?; @@ -2815,7 +2815,7 @@ fn comma_sep<'tcx>( if !first { fmt.write_str(", ")?; } - pretty_print_const_value(ct, ty, fmt, true)?; + pretty_print_const_value(ct, ty, fmt)?; first = false; } Ok(()) @@ -2826,7 +2826,6 @@ fn pretty_print_const_value<'tcx>( ct: ConstValue<'tcx>, ty: Ty<'tcx>, fmt: &mut Formatter<'_>, - print_ty: bool, ) -> fmt::Result { use crate::ty::print::PrettyPrinter; @@ -2935,7 +2934,7 @@ fn pretty_print_const_value<'tcx>( fmt.write_str(", ")?; } write!(fmt, "{}: ", field_def.name)?; - pretty_print_const_value(ct, ty, fmt, true)?; + pretty_print_const_value(ct, ty, fmt)?; first = false; } fmt.write_str(" }}")?; @@ -2945,20 +2944,13 @@ fn pretty_print_const_value<'tcx>( _ => unreachable!(), } return Ok(()); - } else { - // Fall back to debug pretty printing for invalid constants. - fmt.write_str(&format!("{:?}", ct))?; - if print_ty { - fmt.write_str(&format!(": {}", ty))?; - } - return Ok(()); - }; + } } (ConstValue::Scalar(scalar), _) => { let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS); cx.print_alloc_ids = true; let ty = tcx.lift(ty).unwrap(); - cx = cx.pretty_print_const_scalar(scalar, ty, print_ty)?; + cx = cx.pretty_print_const_scalar(scalar, ty)?; fmt.write_str(&cx.into_buffer())?; return Ok(()); } @@ -2973,12 +2965,8 @@ fn pretty_print_const_value<'tcx>( // their fields instead of just dumping the memory. _ => {} } - // fallback - fmt.write_str(&format!("{:?}", ct))?; - if print_ty { - fmt.write_str(&format!(": {}", ty))?; - } - Ok(()) + // Fall back to debug pretty printing for invalid constants. + write!(fmt, "{ct:?}: {ty}") }) } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 45233745c67e7..b771f666567bc 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1393,11 +1393,10 @@ pub trait PrettyPrinter<'tcx>: self, scalar: Scalar, ty: Ty<'tcx>, - print_ty: bool, ) -> Result { match scalar { - Scalar::Ptr(ptr, _size) => self.pretty_print_const_scalar_ptr(ptr, ty, print_ty), - Scalar::Int(int) => self.pretty_print_const_scalar_int(int, ty, print_ty), + Scalar::Ptr(ptr, _size) => self.pretty_print_const_scalar_ptr(ptr, ty), + Scalar::Int(int) => self.pretty_print_const_scalar_int(int, ty, true), } } @@ -1405,7 +1404,6 @@ pub trait PrettyPrinter<'tcx>: mut self, ptr: Pointer, ty: Ty<'tcx>, - print_ty: bool, ) -> Result { define_scoped_cx!(self); @@ -1459,7 +1457,7 @@ pub trait PrettyPrinter<'tcx>: _ => {} } // Any pointer values not covered by a branch above - self = self.pretty_print_const_pointer(ptr, ty, print_ty)?; + self = self.pretty_print_const_pointer(ptr, ty)?; Ok(self) } @@ -1527,24 +1525,18 @@ pub trait PrettyPrinter<'tcx>: /// This is overridden for MIR printing because we only want to hide alloc ids from users, not /// from MIR where it is actually useful. fn pretty_print_const_pointer( - mut self, + self, _: Pointer, ty: Ty<'tcx>, - print_ty: bool, ) -> Result { - if print_ty { - self.typed_value( - |mut this| { - this.write_str("&_")?; - Ok(this) - }, - |this| this.print_type(ty), - ": ", - ) - } else { - self.write_str("&_")?; - Ok(self) - } + self.typed_value( + |mut this| { + this.write_str("&_")?; + Ok(this) + }, + |this| this.print_type(ty), + ": ", + ) } fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result { @@ -2156,7 +2148,6 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { self, p: Pointer, ty: Ty<'tcx>, - print_ty: bool, ) -> Result { let print = |mut this: Self| { define_scoped_cx!(this); @@ -2167,11 +2158,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { } Ok(this) }; - if print_ty { - self.typed_value(print, |this| this.print_type(ty), ": ") - } else { - print(self) - } + self.typed_value(print, |this| this.print_type(ty), ": ") } } From 46cce98134a1dd7d8c835b1dfadc891cc9891eb5 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 28 Jun 2023 13:22:02 +0000 Subject: [PATCH 4/7] Use options instead of errors if the errors are never needed --- .../rustc_const_eval/src/const_eval/mod.rs | 22 +++++++++---------- compiler/rustc_const_eval/src/lib.rs | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index f23cb905c2379..38b03f66e03ff 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,9 +1,7 @@ // Not in interpret to make sure we do not use private implementation details use crate::errors::MaxNumNodesInConstErr; -use crate::interpret::{ - intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, Scalar, -}; +use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, Scalar}; use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -91,20 +89,20 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>, -) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> { +) -> Option> { let param_env = ty::ParamEnv::reveal_all(); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No); - let op = ecx.const_val_to_op(val, ty, None)?; + let op = ecx.const_val_to_op(val, ty, None).ok()?; // We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match ty.kind() { ty::Array(_, len) => (len.eval_target_usize(tcx, param_env) as usize, None, op), ty::Adt(def, _) if def.variants().is_empty() => { - throw_ub!(Unreachable) + return None; } ty::Adt(def, _) => { - let variant = ecx.read_discriminant(&op)?.1; - let down = ecx.operand_downcast(&op, variant)?; + let variant = ecx.read_discriminant(&op).ok()?.1; + let down = ecx.operand_downcast(&op, variant).ok()?; (def.variants()[variant].fields.len(), Some(variant), down) } ty::Tuple(substs) => (substs.len(), None, op), @@ -113,12 +111,12 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( let fields_iter = (0..field_count) .map(|i| { - let field_op = ecx.operand_field(&down, i)?; + let field_op = ecx.operand_field(&down, i).ok()?; let val = op_to_const(&ecx, &field_op); - Ok((val, field_op.layout.ty)) + Some((val, field_op.layout.ty)) }) - .collect::>>()?; + .collect::>>()?; let fields = tcx.arena.alloc_from_iter(fields_iter); - Ok(mir::DestructuredConstant { variant, fields }) + Some(mir::DestructuredConstant { variant, fields }) } diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 826d2a15721a5..d82f03b863961 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -53,7 +53,7 @@ pub fn provide(providers: &mut Providers) { const_eval::eval_to_valtree(tcx, param_env, raw) }; providers.try_destructure_mir_constant = - |tcx, (cv, ty)| const_eval::try_destructure_mir_constant(tcx, cv, ty).ok(); + |tcx, (cv, ty)| const_eval::try_destructure_mir_constant(tcx, cv, ty); providers.valtree_to_const_val = |tcx, (ty, valtree)| { const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree) }; From 8ac1a67d11890d3248ba4b10ff8abe3f465c3afd Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 5 Jul 2023 15:51:52 +0000 Subject: [PATCH 5/7] Name the destructure_mir_constant query appropriately --- compiler/rustc_const_eval/src/const_eval/mod.rs | 2 +- compiler/rustc_const_eval/src/lib.rs | 4 ++-- compiler/rustc_middle/src/mir/mod.rs | 4 ++-- compiler/rustc_middle/src/query/mod.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 38b03f66e03ff..a3064b53db1b0 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -85,7 +85,7 @@ pub(crate) fn eval_to_valtree<'tcx>( } #[instrument(skip(tcx), level = "debug")] -pub(crate) fn try_destructure_mir_constant<'tcx>( +pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>( tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>, diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index d82f03b863961..c126f749bf328 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -52,8 +52,8 @@ pub fn provide(providers: &mut Providers) { let (param_env, raw) = param_env_and_value.into_parts(); const_eval::eval_to_valtree(tcx, param_env, raw) }; - providers.try_destructure_mir_constant = - |tcx, (cv, ty)| const_eval::try_destructure_mir_constant(tcx, cv, ty); + providers.try_destructure_mir_constant_for_diagnostics = + |tcx, (cv, ty)| const_eval::try_destructure_mir_constant_for_diagnostics(tcx, cv, ty); providers.valtree_to_const_val = |tcx, (ty, valtree)| { const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree) }; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 480a12c4cb435..b2647bfe7d626 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2887,8 +2887,8 @@ fn pretty_print_const_value<'tcx>( (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => { let ct = tcx.lift(ct).unwrap(); let ty = tcx.lift(ty).unwrap(); - if let Some(contents) = tcx.try_destructure_mir_constant((ct, ty)) { - let fields = contents.fields.to_vec(); + if let Some(contents) = tcx.try_destructure_mir_constant_for_diagnostics((ct, ty)) { + let fields: Vec<(ConstValue<'_>, Ty<'_>)> = contents.fields.to_vec(); match *ty.kind() { ty::Array(..) => { fmt.write_str("[")?; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 81efbd8b094d2..d58a1a655332a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1088,7 +1088,7 @@ rustc_queries! { /// Tries to destructure an `mir::ConstantKind` ADT or array into its variant index /// and its field values. This should only be used for pretty printing. - query try_destructure_mir_constant( + query try_destructure_mir_constant_for_diagnostics( key: (ConstValue<'tcx>, Ty<'tcx>) ) -> Option> { desc { "destructuring MIR constant"} From e1e04a8beed95e78b1391c7f4650fb68abd86f8f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 5 Jul 2023 15:58:19 +0000 Subject: [PATCH 6/7] Document magic boolean --- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index b771f666567bc..fc27f98a96fa4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1396,7 +1396,9 @@ pub trait PrettyPrinter<'tcx>: ) -> Result { match scalar { Scalar::Ptr(ptr, _size) => self.pretty_print_const_scalar_ptr(ptr, ty), - Scalar::Int(int) => self.pretty_print_const_scalar_int(int, ty, true), + Scalar::Int(int) => { + self.pretty_print_const_scalar_int(int, ty, /* print_ty */ true) + } } } From 3dfc7ec05d1ac233af6f614eaedc67522e20d930 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 5 Jul 2023 16:16:03 +0000 Subject: [PATCH 7/7] Patch clippy --- src/tools/clippy/clippy_utils/src/consts.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index dd3cda8ec5277..b7f62af75b815 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -725,13 +725,14 @@ fn field_of_struct<'tcx>( result: mir::ConstantKind<'tcx>, field: &Ident, ) -> Option> { - if let Some(dc) = lcx.tcx.try_destructure_mir_constant(lcx.param_env.and(result)) + if let mir::ConstantKind::Val(result, ty) = result + && let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_diagnostics((result, ty)) && let Some(dc_variant) = dc.variant && let Some(variant) = adt_def.variants().get(dc_variant) && let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name) - && let Some(dc_field) = dc.fields.get(field_idx) + && let Some(&(val, ty)) = dc.fields.get(field_idx) { - Some(*dc_field) + Some(mir::ConstantKind::Val(val, ty)) } else { None