diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index d9c4ae4d53f91..1c33e7845cb0b 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -100,10 +100,10 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, val: mir::ConstantKind<'tcx>, -) -> InterpResult<'tcx, mir::DestructuredMirConstant<'tcx>> { +) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> { trace!("destructure_mir_constant: {:?}", val); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.mir_const_to_op(&val, None)?; + let op = ecx.const_to_op(&val, None)?; // We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match val.ty().kind() { @@ -129,7 +129,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( .collect::>>()?; let fields = tcx.arena.alloc_from_iter(fields_iter); - Ok(mir::DestructuredMirConstant { variant, fields }) + Ok(mir::DestructuredConstant { variant, fields }) } #[instrument(skip(tcx), level = "debug")] @@ -139,7 +139,7 @@ pub(crate) fn deref_mir_constant<'tcx>( val: mir::ConstantKind<'tcx>, ) -> mir::ConstantKind<'tcx> { let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.mir_const_to_op(&val, None).unwrap(); + let op = ecx.const_to_op(&val, None).unwrap(); let mplace = ecx.deref_operand(&op).unwrap(); if let Some(alloc_id) = mplace.ptr.provenance { assert_eq!( diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 3177537fee25e..bdebfbb3ff510 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -683,11 +683,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.stack_mut().push(frame); // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check). - for const_ in &body.required_consts { - let span = const_.span; - let const_ = - self.subst_from_current_frame_and_normalize_erasing_regions(const_.literal)?; - self.mir_const_to_op(&const_, None).map_err(|err| { + for ct in &body.required_consts { + let span = ct.span; + let ct = self.subst_from_current_frame_and_normalize_erasing_regions(ct.literal)?; + self.const_to_op(&ct, None).map_err(|err| { // If there was an error, set the span of the current frame to this constant. // Avoiding doing this when evaluation succeeds. self.frame_mut().loc = Err(span); diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 29c745a0886f8..dc5305aabcf89 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -534,7 +534,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // * During ConstProp, with `TooGeneric` or since the `required_consts` were not all // checked yet. // * During CTFE, since promoteds in `const`/`static` initializer bodies can fail. - self.mir_const_to_op(&val, layout)? + self.const_to_op(&val, layout)? } }; trace!("{:?}: {:?}", mir_op, *op); @@ -549,50 +549,42 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ops.iter().map(|op| self.eval_operand(op, None)).collect() } - // Used when the miri-engine runs into a constant and for extracting information from constants - // in patterns via the `const_eval` module - /// The `val` and `layout` are assumed to already be in our interpreter - /// "universe" (param_env). pub fn const_to_op( - &self, - c: ty::Const<'tcx>, - layout: Option>, - ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { - match c.kind() { - ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => throw_inval!(TooGeneric), - ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => { - throw_inval!(AlreadyReported(reported)) - } - ty::ConstKind::Unevaluated(uv) => { - // NOTE: We evaluate to a `ValTree` here as a check to ensure - // we're working with valid constants, even though we never need it. - let instance = self.resolve(uv.def, uv.substs)?; - let cid = GlobalId { instance, promoted: None }; - let _valtree = self - .tcx - .eval_to_valtree(self.param_env.and(cid))? - .unwrap_or_else(|| bug!("unable to create ValTree for {:?}", uv)); - - Ok(self.eval_to_allocation(cid)?.into()) - } - ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => { - span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c) - } - ty::ConstKind::Value(valtree) => { - let ty = c.ty(); - let const_val = self.tcx.valtree_to_const_val((ty, valtree)); - self.const_val_to_op(const_val, ty, layout) - } - } - } - - pub fn mir_const_to_op( &self, val: &mir::ConstantKind<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { match val { - mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout), + mir::ConstantKind::Ty(ct) => { + match ct.kind() { + ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => { + throw_inval!(TooGeneric) + } + ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => { + throw_inval!(AlreadyReported(reported)) + } + ty::ConstKind::Unevaluated(uv) => { + // NOTE: We evaluate to a `ValTree` here as a check to ensure + // we're working with valid constants, even though we never need it. + let instance = self.resolve(uv.def, uv.substs)?; + let cid = GlobalId { instance, promoted: None }; + let _valtree = self + .tcx + .eval_to_valtree(self.param_env.and(cid))? + .unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}")); + + Ok(self.eval_to_allocation(cid)?.into()) + } + ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => { + span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {ct:?}") + } + ty::ConstKind::Value(valtree) => { + let ty = ct.ty(); + let const_val = self.tcx.valtree_to_const_val((ty, valtree)); + self.const_val_to_op(const_val, ty, layout) + } + } + } mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout), mir::ConstantKind::Unevaluated(uv, _) => { let instance = self.resolve(uv.def, uv.substs)?; diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 4207988d700d9..a8c7505329cda 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -211,7 +211,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_env: ty::ParamEnv<'tcx>, constant: mir::ConstantKind<'tcx>, - ) -> mir::DestructuredMirConstant<'tcx> { + ) -> mir::DestructuredConstant<'tcx> { self.try_destructure_mir_constant(param_env.and(constant)).unwrap() } } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index d89efe2b3f024..efd7357afc46c 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -392,16 +392,9 @@ pub enum ClosureOutlivesSubject<'tcx> { Region(ty::RegionVid), } -/// The constituent parts of a type level constant of kind ADT or array. -#[derive(Copy, Clone, Debug, HashStable)] -pub struct DestructuredConst<'tcx> { - pub variant: Option, - pub fields: &'tcx [ty::Const<'tcx>], -} - /// The constituent parts of a mir constant of kind ADT or array. #[derive(Copy, Clone, Debug, HashStable)] -pub struct DestructuredMirConstant<'tcx> { +pub struct DestructuredConstant<'tcx> { pub variant: Option, pub fields: &'tcx [ConstantKind<'tcx>], } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 53c254119f436..1afea4864b8dd 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1007,7 +1007,9 @@ rustc_queries! { /// Tries to destructure an `mir::ConstantKind` ADT or array into its variant index /// and its field values. - query try_destructure_mir_constant(key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>) -> Option> { + query try_destructure_mir_constant( + key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> + ) -> Option> { desc { "destructuring mir constant"} remap_env_constness } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 339ff4d35930d..4bc821dcfa1fb 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,9 +1,6 @@ use crate::mir::interpret::LitToConstInput; use crate::mir::ConstantKind; -use crate::ty::{ - self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, - TyCtxt, TypeVisitable, -}; +use crate::ty::{self, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -151,46 +148,6 @@ impl<'tcx> Const<'tcx> { } } - pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { - debug!("Const::from_inline_const(def_id={:?})", def_id); - - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - - let body_id = match tcx.hir().get(hir_id) { - hir::Node::AnonConst(ac) => ac.body, - _ => span_bug!( - tcx.def_span(def_id.to_def_id()), - "from_inline_const can only process anonymous constants" - ), - }; - - let expr = &tcx.hir().body(body_id).value; - - let ty = tcx.typeck(def_id).node_type(hir_id); - - let ret = match Self::try_eval_lit_or_param(tcx, ty, expr) { - Some(v) => v, - None => { - let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()); - let parent_substs = - tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id)); - let substs = - InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty }) - .substs; - tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Unevaluated(ty::Unevaluated { - def: ty::WithOptConstParam::unknown(def_id).to_global(), - substs, - promoted: (), - }), - ty, - }) - } - }; - debug_assert!(!ret.has_free_regions()); - ret - } - /// Interns the given value as a constant. #[inline] pub fn from_value(tcx: TyCtxt<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Self { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 6bb33b5890be8..11645f840c135 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -680,7 +680,7 @@ macro_rules! ClonePatternFoldableImpls { } ClonePatternFoldableImpls! { <'tcx> - Span, Field, Mutability, Symbol, LocalVarId, usize, ty::Const<'tcx>, + Span, Field, Mutability, Symbol, LocalVarId, usize, Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>, SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>, UserTypeProjection, CanonicalUserTypeAnnotation<'tcx> diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 08ba3f9941d93..cb134a20ea03e 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -471,7 +471,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - self.ecx.mir_const_to_op(&c.literal, None).ok() + self.ecx.const_to_op(&c.literal, None).ok() } /// Returns the value, if any, of evaluating `place`. diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index f16efb365f3cd..2885f06b19cd6 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -292,7 +292,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - match self.ecx.mir_const_to_op(&c.literal, None) { + match self.ecx.const_to_op(&c.literal, None) { Ok(op) => Some(op), Err(error) => { let tcx = self.ecx.tcx.at(c.span); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 70b9c732ff4bf..23e04ae6a5392 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -487,18 +487,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> { match length { &hir::ArrayLen::Infer(_, span) => self.ct_infer(self.tcx.types.usize, None, span), - hir::ArrayLen::Body(anon_const) => self.to_const(anon_const), + hir::ArrayLen::Body(anon_const) => { + let const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); + let span = self.tcx.hir().span(anon_const.hir_id); + let c = ty::Const::from_anon_const(self.tcx, const_def_id); + self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None)); + self.normalize_associated_types_in(span, c) + } } } - pub fn to_const(&self, ast_c: &hir::AnonConst) -> ty::Const<'tcx> { - let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id); - let span = self.tcx.hir().span(ast_c.hir_id); - let c = ty::Const::from_anon_const(self.tcx, const_def_id); - self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None)); - self.normalize_associated_types_in(span, c) - } - pub fn const_arg_to_const( &self, ast_c: &hir::AnonConst, diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs index 1608550aa6ae4..87961890f53e5 100644 --- a/compiler/rustc_typeck/src/coherence/orphan.rs +++ b/compiler/rustc_typeck/src/coherence/orphan.rs @@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; -use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IgnoreRegions; @@ -229,12 +228,8 @@ fn emit_orphan_check_error<'tcx>( "only traits defined in the current crate {msg}" ); err.span_label(sp, "impl doesn't use only types from inside the current crate"); - for (ty, is_target_ty) in &tys { - let mut ty = *ty; - tcx.infer_ctxt().enter(|infcx| { - // Remove the lifetimes unnecessary for this error. - ty = infcx.freshen(ty); - }); + for &(mut ty, is_target_ty) in &tys { + ty = tcx.erase_regions(ty); ty = match ty.kind() { // Remove the type arguments from the output, as they are not relevant. // You can think of this as the reverse of `resolve_vars_if_possible`. @@ -264,7 +259,7 @@ fn emit_orphan_check_error<'tcx>( }; let msg = format!("{} is not defined in the current crate{}", ty, postfix); - if *is_target_ty { + if is_target_ty { // Point at `D` in `impl for C in D` err.span_label(self_ty_span, &msg); } else {