From 033eb494285e32e165422200624558f864f2b9fc Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 12 Mar 2021 00:01:34 +0100 Subject: [PATCH 1/5] extract `ConstKind::Unevaluated` into a struct --- .../rustc_codegen_ssa/src/mir/constant.rs | 2 +- compiler/rustc_middle/src/ty/consts.rs | 12 ++--- compiler/rustc_middle/src/ty/consts/kind.rs | 17 +++++-- compiler/rustc_middle/src/ty/flags.rs | 10 +++-- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/relate.rs | 24 +++++----- .../rustc_middle/src/ty/structural_impls.rs | 10 +++-- compiler/rustc_middle/src/ty/walk.rs | 4 +- .../src/borrow_check/type_check/mod.rs | 4 +- compiler/rustc_mir/src/interpret/operand.rs | 2 +- .../rustc_mir/src/monomorphize/collector.rs | 2 +- .../src/monomorphize/polymorphize.rs | 6 +-- .../src/transform/check_consts/qualifs.rs | 4 +- .../rustc_mir/src/transform/const_prop.rs | 2 +- compiler/rustc_mir/src/transform/inline.rs | 2 +- .../rustc_mir/src/transform/promote_consts.rs | 8 ++-- .../src/transform/required_consts.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 16 +++---- .../src/traits/auto_trait.rs | 7 ++- .../src/traits/const_evaluatable.rs | 45 ++++++++++++------- .../src/traits/fulfill.rs | 15 ++++--- .../src/traits/select/mod.rs | 7 ++- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 5 ++- 25 files changed, 129 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index b79a221a0e74a..67f3def5636b0 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -25,7 +25,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { match self.monomorphize(constant.literal).val { - ty::ConstKind::Unevaluated(def, substs, promoted) => self + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => self .cx .tcx() .const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None) diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index e7b2c9efd63cf..d078e73897161 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -96,18 +96,18 @@ impl<'tcx> Const<'tcx> { let name = tcx.hir().name(hir_id); ty::ConstKind::Param(ty::ParamConst::new(index, name)) } - _ => ty::ConstKind::Unevaluated( - def.to_global(), - InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), - None, - ), + _ => ty::ConstKind::Unevaluated(ty::Unevaluated { + def: def.to_global(), + substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), + promoted: None, + }), }; tcx.mk_const(ty::Const { val, ty }) } - #[inline] /// Interns the given value as a constant. + #[inline] pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self { tcx.mk_const(Self { val: ConstKind::Value(val), ty }) } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 98c215407a8e0..e81547777e8a5 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -9,9 +9,18 @@ use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_target::abi::Size; +/// An unevaluated, potentially generic, constant. +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Hash, HashStable)] +pub struct Unevaluated<'tcx> { + pub def: ty::WithOptConstParam, + pub substs: SubstsRef<'tcx>, + pub promoted: Option, +} + /// Represents a constant in Rust. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)] -#[derive(HashStable)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Hash, HashStable)] pub enum ConstKind<'tcx> { /// A const generic parameter. Param(ty::ParamConst), @@ -27,7 +36,7 @@ pub enum ConstKind<'tcx> { /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. - Unevaluated(ty::WithOptConstParam, SubstsRef<'tcx>, Option), + Unevaluated(Unevaluated<'tcx>), /// Used to hold computed value. Value(ConstValue<'tcx>), @@ -93,7 +102,7 @@ impl<'tcx> ConstKind<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ) -> Option, ErrorReported>> { - if let ConstKind::Unevaluated(def, substs, promoted) = self { + if let ConstKind::Unevaluated(Unevaluated { def, substs, promoted }) = self { use crate::mir::interpret::ErrorHandled; // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 6ecd1ebf37039..d6dc81c5b785d 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -270,10 +270,7 @@ impl FlagComputation { fn add_const(&mut self, c: &ty::Const<'_>) { self.add_ty(c.ty); match c.val { - ty::ConstKind::Unevaluated(_, substs, _) => { - self.add_substs(substs); - self.add_flags(TypeFlags::HAS_CT_PROJECTION); - } + ty::ConstKind::Unevaluated(unevaluated) => self.add_unevaluated_const(unevaluated), ty::ConstKind::Infer(infer) => { self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); match infer { @@ -297,6 +294,11 @@ impl FlagComputation { } } + fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'tcx>) { + self.add_substs(ct.substs); + self.add_flags(TypeFlags::HAS_CT_PROJECTION); + } + fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) { self.add_substs(projection.substs); self.add_ty(projection.ty); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f5aef108927db..a1cfb8bd46556 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -55,7 +55,7 @@ pub use rustc_type_ir::*; pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; -pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt}; +pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, Unevaluated}; pub use self::context::{ tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 53c164d44b3e1..e0abfa36e8ccf 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -915,7 +915,7 @@ pub trait PrettyPrinter<'tcx>: } match ct.val { - ty::ConstKind::Unevaluated(def, substs, promoted) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { if let Some(promoted) = promoted { p!(print_value_path(def.did, substs)); p!(write("::{:?}", promoted)); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index f21545447b204..e54e44a6157e8 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -587,11 +587,10 @@ pub fn super_relate_consts>( new_val.map(ty::ConstKind::Value) } - ( - ty::ConstKind::Unevaluated(a_def, a_substs, None), - ty::ConstKind::Unevaluated(b_def, b_substs, None), - ) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => { - if tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))) { + (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) + if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => + { + if tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs))) { Ok(a.val) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) @@ -601,13 +600,16 @@ pub fn super_relate_consts>( // While this is slightly incorrect, it shouldn't matter for `min_const_generics` // and is the better alternative to waiting until `const_evaluatable_checked` can // be stabilized. - ( - ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted), - ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted), - ) if a_def == b_def && a_promoted == b_promoted => { + (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) + if au.def == bu.def && au.promoted == bu.promoted => + { let substs = - relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?; - Ok(ty::ConstKind::Unevaluated(a_def, substs, a_promoted)) + relation.relate_with_variance(ty::Variance::Invariant, au.substs, bu.substs)?; + Ok(ty::ConstKind::Unevaluated(ty::Unevaluated { + def: au.def, + substs, + promoted: au.promoted, + })) } _ => Err(TypeError::ConstMismatch(expected_found(relation, a, b))), }; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 0ca94a9f1805d..2da23b331e0cb 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -1031,8 +1031,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)), - ty::ConstKind::Unevaluated(did, substs, promoted) => { - ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted) + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { + def, + substs: substs.fold_with(folder), + promoted, + }) } ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) @@ -1045,7 +1049,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match *self { ty::ConstKind::Infer(ic) => ic.visit_with(visitor), ty::ConstKind::Param(p) => p.visit_with(visitor), - ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor), + ty::ConstKind::Unevaluated(ct) => ct.substs.visit_with(visitor), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index bb7fc661d2d8a..c2fe5f1ef3f62 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -195,8 +195,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {} - ty::ConstKind::Unevaluated(_, substs, _) => { - stack.extend(substs.iter().rev()); + ty::ConstKind::Unevaluated(ct) => { + stack.extend(ct.substs.iter().rev()); } } } diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index ab7e75bf4f10c..157adf8438488 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -314,7 +314,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } else { let tcx = self.tcx(); - if let ty::ConstKind::Unevaluated(def, substs, promoted) = constant.literal.val { + if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) = + constant.literal.val + { if let Some(promoted) = promoted { let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, promoted: &Body<'tcx>, diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 2c4aba19e4a2e..93e294651cbaa 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -566,7 +566,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val_val = match val.val { ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)), - ty::ConstKind::Unevaluated(def, substs, promoted) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { let instance = self.resolve(def, substs)?; return Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into()); } diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 20cb989196a98..d187efb5125c8 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -646,7 +646,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match substituted_constant.val { ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output), - ty::ConstKind::Unevaluated(def, substs, promoted) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { match self.tcx.const_eval_resolve(param_env, def, substs, promoted, None) { Ok(val) => collect_const_value(self.tcx, val, self.output), Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {} diff --git a/compiler/rustc_mir/src/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs index 05b0e3a7dab95..30e758c7fdf05 100644 --- a/compiler/rustc_mir/src/monomorphize/polymorphize.rs +++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs @@ -299,7 +299,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.unused_parameters.clear(param.index); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(def, _, Some(p)) + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)}) // Avoid considering `T` unused when constants are of the form: // `>::foo::promoted[p]` if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self => @@ -310,10 +310,10 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.visit_body(&promoted[p]); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(def, unevaluated_substs, None) + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) if self.tcx.def_kind(def.did) == DefKind::AnonConst => { - self.visit_child_body(def.did, unevaluated_substs); + self.visit_child_body(def.did, substs); ControlFlow::CONTINUE } _ => c.super_visit_with(self), diff --git a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs index 13d7166b4b5ae..c8dce55f69a1a 100644 --- a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs @@ -246,7 +246,9 @@ where }; // Check the qualifs of the value of `const` items. - if let ty::ConstKind::Unevaluated(def, _, promoted) = constant.literal.val { + if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = + constant.literal.val + { assert!(promoted.is_none()); // Don't peek inside trait associated constants. if cx.tcx.trait_of_item(def.did).is_none() { diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 9d03b1b027e1b..1b592206a586b 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -490,7 +490,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { if let Some(lint_root) = self.lint_root(source_info) { let lint_only = match c.literal.val { // Promoteds must lint and not error as the user didn't ask for them - ConstKind::Unevaluated(_, _, Some(_)) => true, + ConstKind::Unevaluated(uv) if uv.promoted.is_some() => true, // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. _ => c.literal.needs_subst(), diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index cf85503b3d54b..055da85469e1a 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -638,7 +638,7 @@ impl Inliner<'tcx> { // because we are calling `subst_and_normalize_erasing_regions`. caller_body.required_consts.extend( callee_body.required_consts.iter().copied().filter(|&constant| { - matches!(constant.literal.val, ConstKind::Unevaluated(_, _, _)) + matches!(constant.literal.val, ConstKind::Unevaluated(_)) }), ); } diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs index f60570483cea4..4be8b42993e69 100644 --- a/compiler/rustc_mir/src/transform/promote_consts.rs +++ b/compiler/rustc_mir/src/transform/promote_consts.rs @@ -1000,17 +1000,17 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { user_ty: None, literal: tcx.mk_const(ty::Const { ty, - val: ty::ConstKind::Unevaluated( + val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, - InternalSubsts::for_item(tcx, def.did, |param, _| { + substs: InternalSubsts::for_item(tcx, def.did, |param, _| { if let ty::GenericParamDefKind::Lifetime = param.kind { tcx.lifetimes.re_erased.into() } else { tcx.mk_param_from_def(param) } }), - Some(promoted_id), - ), + promoted: Some(promoted_id), + }), }), })) }; diff --git a/compiler/rustc_mir/src/transform/required_consts.rs b/compiler/rustc_mir/src/transform/required_consts.rs index a63ab30a68fa2..e10cb796849ba 100644 --- a/compiler/rustc_mir/src/transform/required_consts.rs +++ b/compiler/rustc_mir/src/transform/required_consts.rs @@ -16,7 +16,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RequiredConstsVisitor<'a, 'tcx> { fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) { let const_kind = constant.literal.val; - if let ConstKind::Unevaluated(_, _, _) = const_kind { + if let ConstKind::Unevaluated(_) = const_kind { self.required_consts.push(*constant); } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index dfcb52c83c0d7..df2f9c8581f37 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -692,11 +692,11 @@ impl<'thir, 'tcx> Cx<'thir, 'tcx> { // and not the beginning of discriminants (which is always `0`) let substs = InternalSubsts::identity_for_item(self.tcx(), did); let lhs = mk_const(self.tcx().mk_const(ty::Const { - val: ty::ConstKind::Unevaluated( - ty::WithOptConstParam::unknown(did), + val: ty::ConstKind::Unevaluated(ty::Unevaluated { + def: ty::WithOptConstParam::unknown(did), substs, - None, - ), + promoted: None, + }), ty: var_ty, })); let bin = @@ -890,11 +890,11 @@ impl<'thir, 'tcx> Cx<'thir, 'tcx> { debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { literal: self.tcx.mk_const(ty::Const { - val: ty::ConstKind::Unevaluated( - ty::WithOptConstParam::unknown(def_id), + val: ty::ConstKind::Unevaluated(ty::Unevaluated { + def: ty::WithOptConstParam::unknown(def_id), substs, - None, - ), + promoted: None, + }), ty: self.typeck_results().node_type(expr.hir_id), }), user_ty, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6510c9464e145..495758cedb165 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -803,7 +803,12 @@ impl AutoTraitFinder<'tcx> { } ty::PredicateKind::ConstEquate(c1, c2) => { let evaluate = |c: &'tcx ty::Const<'tcx>| { - if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val { + if let ty::ConstKind::Unevaluated(ty::Unevaluated { + def, + substs, + promoted, + }) = c.val + { match select.infcx().const_eval_resolve( obligation.param_env, def, diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index f4983dd7531a2..cf9d3614762c6 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -239,7 +239,9 @@ impl AbstractConst<'tcx> { ct: &ty::Const<'tcx>, ) -> Result>, ErrorReported> { match ct.val { - ty::ConstKind::Unevaluated(def, substs, None) => AbstractConst::new(tcx, def, substs), + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: _ }) => { + AbstractConst::new(tcx, def, substs) + } ty::ConstKind::Error(_) => Err(ErrorReported), _ => Ok(None), } @@ -529,22 +531,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { if let Some(next) = self.build_terminator(block.terminator())? { block = &self.body.basic_blocks()[next]; } else { - assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap()); + break; + } + } + + assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap()); + for n in self.nodes.iter() { + if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n.node { // `AbstractConst`s should not contain any promoteds as they require references which // are not allowed. - assert!(!self.nodes.iter().any(|n| matches!( - n.node, - Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(_, _, Some(_)), ty: _ }) - ))); - - self.nodes[self.locals[mir::RETURN_PLACE]].used = true; - if let Some(&unused) = self.nodes.iter().find(|n| !n.used) { - self.error(Some(unused.span), "dead code")?; - } - - return Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node))); + assert_eq!(ct.promoted, None); } } + + self.nodes[self.locals[mir::RETURN_PLACE]].used = true; + if let Some(&unused) = self.nodes.iter().find(|n| !n.used) { + self.error(Some(unused.span), "dead code")?; + } + + Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node))) } } @@ -670,10 +675,16 @@ pub(super) fn try_unify<'tcx>( // we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This // means that we only allow inference variables if they are equal. (ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => a_val == b_val, - ( - ty::ConstKind::Unevaluated(a_def, a_substs, None), - ty::ConstKind::Unevaluated(b_def, b_substs, None), - ) => a_def == b_def && a_substs == b_substs, + // We expand generic anonymous constants at the start of this function, so this + // branch should only be taking when dealing with associated constants, at + // which point directly comparing them seems like the desired behavior. + // + // FIXME(const_evaluatable_checked): This isn't actually the case. + // We also take this branch for concrete anonymous constants and + // expand generic anonymous constants with concrete substs. + (ty::ConstKind::Unevaluated(a_uv), ty::ConstKind::Unevaluated(b_uv)) => { + a_uv == b_uv + } // FIXME(const_evaluatable_checked): We may want to either actually try // to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like // this, for now we just return false here. diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 7d451fc234106..83b537a78951c 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -516,15 +516,13 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { // if the constants depend on generic parameters. // // Let's just see where this breaks :shrug: - if let ( - ty::ConstKind::Unevaluated(a_def, a_substs, None), - ty::ConstKind::Unevaluated(b_def, b_substs, None), - ) = (c1.val, c2.val) + if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = + (c1.val, c2.val) { if self .selcx .tcx() - .try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))) + .try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs))) { return ProcessResult::Changed(vec![]); } @@ -534,7 +532,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { let stalled_on = &mut pending_obligation.stalled_on; let mut evaluate = |c: &'tcx Const<'tcx>| { - if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val { + if let ty::ConstKind::Unevaluated(ty::Unevaluated { + def, + substs, + promoted, + }) = c.val + { match self.selcx.infcx().const_eval_resolve( obligation.param_env, def, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45b5aff40a6d2..14cec0029f2ec 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -556,7 +556,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts"); let evaluate = |c: &'tcx ty::Const<'tcx>| { - if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val { + if let ty::ConstKind::Unevaluated(ty::Unevaluated { + def, + substs, + promoted, + }) = c.val + { self.infcx .const_eval_resolve( obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index e6ef9b137d899..aee128dec7d12 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -430,7 +430,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { GenericArgKind::Const(constant) => { match constant.val { - ty::ConstKind::Unevaluated(def, substs, promoted) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { assert!(promoted.is_none()); let obligations = self.nominal_obligations(def.did, substs); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index a175da3270638..546f76859951e 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2200,10 +2200,11 @@ fn const_evaluatable_predicates_of<'tcx>( fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { let def_id = self.tcx.hir().local_def_id(c.hir_id); let ct = ty::Const::from_anon_const(self.tcx, def_id); - if let ty::ConstKind::Unevaluated(def, substs, None) = ct.val { + if let ty::ConstKind::Unevaluated(uv) = ct.val { + assert_eq!(uv.promoted, None); let span = self.tcx.hir().span(c.hir_id); self.preds.insert(( - ty::PredicateKind::ConstEvaluatable(def, substs).to_predicate(self.tcx), + ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs).to_predicate(self.tcx), span, )); } From 05e16fc638883a67fe8d0fbbe04b586ce315eaf4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 13 Mar 2021 16:31:38 +0100 Subject: [PATCH 2/5] update `const_eval_resolve` --- compiler/rustc_codegen_cranelift/src/constant.rs | 10 +++++----- compiler/rustc_codegen_ssa/src/mir/constant.rs | 4 ++-- compiler/rustc_infer/src/infer/mod.rs | 7 ++----- compiler/rustc_middle/src/mir/interpret/queries.rs | 10 ++++------ compiler/rustc_middle/src/ty/consts/kind.rs | 3 ++- compiler/rustc_mir/src/monomorphize/collector.rs | 4 ++-- .../rustc_trait_selection/src/traits/auto_trait.rs | 11 ++--------- .../src/traits/const_evaluatable.rs | 6 +++++- .../rustc_trait_selection/src/traits/fulfill.rs | 14 ++++---------- .../rustc_trait_selection/src/traits/select/mod.rs | 11 ++--------- src/librustdoc/clean/utils.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 10 +++++++++- src/tools/clippy/clippy_utils/src/consts.rs | 8 +++++--- 13 files changed, 45 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index b0639cf9e15fe..d637f51649631 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -42,9 +42,9 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { let const_ = fx.monomorphize(constant.literal); match const_.val { ConstKind::Value(_) => {} - ConstKind::Unevaluated(def, ref substs, promoted) => { + ConstKind::Unevaluated(unevaluated) => { if let Err(err) = - fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) + fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { all_constants_ok = false; match err { @@ -116,7 +116,7 @@ pub(crate) fn codegen_constant<'tcx>( let const_ = fx.monomorphize(constant.literal); let const_val = match const_.val { ConstKind::Value(const_val) => const_val, - ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => { + ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => { assert!(substs.is_empty()); assert!(promoted.is_none()); @@ -127,8 +127,8 @@ pub(crate) fn codegen_constant<'tcx>( ) .to_cvalue(fx); } - ConstKind::Unevaluated(def, ref substs, promoted) => { - match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { + ConstKind::Unevaluated(unevaluated) => { + match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { Ok(const_val) => const_val, Err(_) => { span_bug!(constant.span, "erroneous constant not captured by required_consts"); diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 67f3def5636b0..97700590951f2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -25,10 +25,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { match self.monomorphize(constant.literal).val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => self + ty::ConstKind::Unevaluated(ct) => self .cx .tcx() - .const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None) + .const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None) .map_err(|err| { self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); err diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 3df58cb7857f1..7b18f4d0ff6a9 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -18,7 +18,6 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; -use rustc_middle::mir; use rustc_middle::mir::interpret::EvalToConstValueResult; use rustc_middle::traits::select; use rustc_middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; @@ -1499,9 +1498,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn const_eval_resolve( &self, param_env: ty::ParamEnv<'tcx>, - def: ty::WithOptConstParam, - substs: SubstsRef<'tcx>, - promoted: Option, + ty::Unevaluated { def, substs, promoted }: ty::Unevaluated<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { let mut original_values = OriginalQueryValues::default(); @@ -1510,7 +1507,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let (param_env, substs) = canonical.value; // The return value is the evaluated value which doesn't contain any reference to inference // variables, thus we don't need to substitute back the original values. - self.tcx.const_eval_resolve(param_env, def, substs, promoted, span) + self.tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, span) } /// If `typ` is a type variable of some kind, resolve it one level diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 3e7b93b32a6a5..fa7c0670e8ce6 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -1,7 +1,7 @@ use super::{ErrorHandled, EvalToConstValueResult, GlobalId}; use crate::mir; -use crate::ty::subst::{InternalSubsts, SubstsRef}; +use crate::ty::subst::InternalSubsts; use crate::ty::{self, TyCtxt}; use rustc_hir::def_id::DefId; use rustc_span::Span; @@ -35,14 +35,12 @@ impl<'tcx> TyCtxt<'tcx> { pub fn const_eval_resolve( self, param_env: ty::ParamEnv<'tcx>, - def: ty::WithOptConstParam, - substs: SubstsRef<'tcx>, - promoted: Option, + ct: ty::Unevaluated<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { - match ty::Instance::resolve_opt_const_arg(self, param_env, def, substs) { + match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { Ok(Some(instance)) => { - let cid = GlobalId { instance, promoted }; + let cid = GlobalId { instance, promoted: ct.promoted }; self.const_eval_global_id(param_env, cid, span) } Ok(None) => Err(ErrorHandled::TooGeneric), diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index e81547777e8a5..b4c38bfbb461d 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -132,7 +132,8 @@ impl<'tcx> ConstKind<'tcx> { let (param_env, substs) = param_env_and_substs.into_parts(); // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - match tcx.const_eval_resolve(param_env, def, substs, promoted, None) { + match tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, None) + { // NOTE(eddyb) `val` contains no lifetimes/types/consts, // and we use the original type, so nothing from `substs` // (which may be identity substs, see above), diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index d187efb5125c8..02733bf4654d5 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -646,8 +646,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match substituted_constant.val { ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output), - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - match self.tcx.const_eval_resolve(param_env, def, substs, promoted, None) { + ty::ConstKind::Unevaluated(unevaluated) => { + match self.tcx.const_eval_resolve(param_env, unevaluated, None) { Ok(val) => collect_const_value(self.tcx, val, self.output), Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {} Err(ErrorHandled::TooGeneric) => span_bug!( diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 495758cedb165..0d71fc57e394b 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -803,17 +803,10 @@ impl AutoTraitFinder<'tcx> { } ty::PredicateKind::ConstEquate(c1, c2) => { let evaluate = |c: &'tcx ty::Const<'tcx>| { - if let ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs, - promoted, - }) = c.val - { + if let ty::ConstKind::Unevaluated(unevaluated) = c.val { match select.infcx().const_eval_resolve( obligation.param_env, - def, - substs, - promoted, + unevaluated, Some(obligation.cause.span), ) { Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty)), diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index cf9d3614762c6..d5ef72741c4b7 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -163,7 +163,11 @@ pub fn is_const_evaluatable<'cx, 'tcx>( // and hopefully soon change this to an error. // // See #74595 for more details about this. - let concrete = infcx.const_eval_resolve(param_env, def, substs, None, Some(span)); + let concrete = infcx.const_eval_resolve( + param_env, + ty::Unevaluated { def, substs, promoted: None }, + Some(span), + ); if concrete.is_ok() && substs.has_param_types_or_consts() { match infcx.tcx.def_kind(def.did) { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 83b537a78951c..a383658684d59 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -532,23 +532,17 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { let stalled_on = &mut pending_obligation.stalled_on; let mut evaluate = |c: &'tcx Const<'tcx>| { - if let ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs, - promoted, - }) = c.val - { + if let ty::ConstKind::Unevaluated(unevaluated) = c.val { match self.selcx.infcx().const_eval_resolve( obligation.param_env, - def, - substs, - promoted, + unevaluated, Some(obligation.cause.span), ) { Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty)), Err(ErrorHandled::TooGeneric) => { stalled_on.extend( - substs + unevaluated + .substs .iter() .filter_map(TyOrConstInferVar::maybe_from_generic_arg), ); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 14cec0029f2ec..5b38617deff03 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -556,18 +556,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts"); let evaluate = |c: &'tcx ty::Const<'tcx>| { - if let ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs, - promoted, - }) = c.val - { + if let ty::ConstKind::Unevaluated(unevaluated) = c.val { self.infcx .const_eval_resolve( obligation.param_env, - def, - substs, - promoted, + unevaluated, Some(obligation.cause.span), ) .map(|val| ty::Const::from_value(self.tcx(), val, c.ty)) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8b5f5b66c45fc..6f283d501a4f2 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -296,7 +296,7 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String { match n.val { - ty::ConstKind::Unevaluated(def, _, promoted) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => { let mut s = if let Some(def) = def.as_local() { let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did); print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id)) diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 8aebce67917af..3e1db233696fe 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -181,7 +181,15 @@ fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: D let result = cx .tcx - .const_eval_resolve(cx.param_env, ty::WithOptConstParam::unknown(def_id), substs, None, None); + .const_eval_resolve( + cx.param_env, + ty::Unevaluated { + def: ty::WithOptConstParam::unknown(def_id), + substs, + promoted: None + }, + None + ); is_value_unfrozen_raw(cx, result, ty) } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 802c01055a68c..ebe896b7ae867 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -341,9 +341,11 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { .tcx .const_eval_resolve( self.param_env, - ty::WithOptConstParam::unknown(def_id), - substs, - None, + ty::Unevaluated { + def: ty::WithOptConstParam::unknown(def_id), + substs, + promoted: None, + }, None, ) .ok() From 78c87fc3e3307b9e8d38eb8f72b5c44f63d97675 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 13 Mar 2021 17:52:50 +0100 Subject: [PATCH 3/5] bless mir-opt tests --- ...nst_promotion_extern_static.BAR.PromoteTemps.diff | 4 ++-- ...nst_promotion_extern_static.FOO.PromoteTemps.diff | 4 ++-- ...p_unsafe_oob_for_slices.main.ConstProp.32bit.diff | 4 ++-- ...p_unsafe_oob_for_slices.main.ConstProp.64bit.diff | 4 ++-- .../const_prop_fails_gracefully.main.ConstProp.diff | 4 ++-- .../mir-opt/const_prop/ref_deref.main.ConstProp.diff | 4 ++-- .../const_prop/ref_deref.main.PromoteTemps.diff | 4 ++-- .../const_prop/ref_deref_project.main.ConstProp.diff | 4 ++-- .../ref_deref_project.main.PromoteTemps.diff | 4 ++-- .../const_prop/slice_len.main.ConstProp.32bit.diff | 4 ++-- .../const_prop/slice_len.main.ConstProp.64bit.diff | 4 ++-- .../mir-opt/inline/inline_retag.bar.Inline.after.mir | 8 ++++---- .../mir-opt/issue_73223.main.PreCodegen.32bit.diff | 4 ++-- .../mir-opt/issue_73223.main.PreCodegen.64bit.diff | 4 ++-- .../issue_73223.main.SimplifyArmIdentity.32bit.diff | 4 ++-- .../issue_73223.main.SimplifyArmIdentity.64bit.diff | 4 ++-- ...ower_intrinsics.discriminant.LowerIntrinsics.diff | 12 ++++++------ ...se_edges.full_tested_match.PromoteTemps.after.mir | 4 ++-- .../retag.main.SimplifyCfg-elaborate-drops.after.mir | 4 ++-- 19 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index 5ba76c4f0bd70..4e990dd6b705e 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff @@ -22,7 +22,7 @@ - // + ty: &i32 - // + val: Value(Scalar(alloc0)) + // + ty: &[&i32; 1] -+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, [], Some(promoted[0])) ++ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc0)) } @@ -30,7 +30,7 @@ - _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 - _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 + // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:35 -+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, [], Some(promoted[0])) } ++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } + _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 - StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:9:34: 9:35 diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index 1565cc7d5e72f..0a9a3f3c2c5f6 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -24,7 +24,7 @@ - // + ty: *const i32 - // + val: Value(Scalar(alloc2)) + // + ty: &[&i32; 1] -+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0])) ++ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 - // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } @@ -32,7 +32,7 @@ - _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 - _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 + // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:46 -+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0])) } ++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } + _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 - StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:13:45: 13:46 diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff index 8c10b3518d8c8..baa8988f15263 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff @@ -28,10 +28,10 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // ty::Const // + ty: &[i32; 3] - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 - // + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff index 8c10b3518d8c8..baa8988f15263 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff @@ -28,10 +28,10 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // ty::Const // + ty: &[i32; 3] - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 - // + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff index 6034645864656..8ba11df7e0edd 100644 --- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff @@ -19,10 +19,10 @@ _3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, [], None) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, substs: [], promoted: None }) // mir::Constant // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, [], None) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, substs: [], promoted: None }) } _2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 _1 = move _2 as usize (Misc); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39 StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:38: 7:39 diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff index 4fd1b8b227649..56683d7ef037c 100644 --- a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff @@ -14,10 +14,10 @@ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/ref_deref.rs:5:6: 5:10 - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _2 = _4; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 - _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 + _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 diff --git a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff index e7ebfee7f3e01..e1c8085b31b4f 100644 --- a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff @@ -17,10 +17,10 @@ + _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 + // ty::Const + // + ty: &i32 -+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) ++ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // mir::Constant + // + span: $DIR/ref_deref.rs:5:6: 5:10 -+ // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) } ++ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } + _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 - StorageDead(_3); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11 diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff index 812c7c9771801..cce4831b6fe82 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff @@ -14,10 +14,10 @@ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 // ty::Const // + ty: &(i32, i32) - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/ref_deref_project.rs:5:6: 5:17 - // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff index 588c291bcc37a..93ba9de820240 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff @@ -17,10 +17,10 @@ + _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 + // ty::Const + // + ty: &(i32, i32) -+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) ++ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // mir::Constant + // + span: $DIR/ref_deref_project.rs:5:6: 5:17 -+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) } ++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } + _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 - StorageDead(_3); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff index 240cc8e231168..20f93f874c539 100644 --- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff @@ -21,10 +21,10 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 // ty::Const // + ty: &[u32; 3] - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 - // + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 _3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19 diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff index 240cc8e231168..20f93f874c539 100644 --- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff @@ -21,10 +21,10 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 // ty::Const // + ty: &[u32; 3] - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 - // + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 _3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19 diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir index b9fe84fcd0443..0b5dc2b20fc98 100644 --- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir @@ -35,10 +35,10 @@ fn bar() -> bool { _10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[1])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[1]) }) // mir::Constant // + span: $DIR/inline-retag.rs:12:7: 12:9 - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[1])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[1]) }) } Retag(_10); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 _4 = &(*_10); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 Retag(_4); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 @@ -49,10 +49,10 @@ fn bar() -> bool { _9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/inline-retag.rs:12:11: 12:14 - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } Retag(_9); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 _7 = &(*_9); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 Retag(_7); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff index e2ec0e82ebf09..47151b0907a0a 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff @@ -63,10 +63,10 @@ _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _8 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_6.0: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_6.1: &i32) = move _8; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff index e2ec0e82ebf09..47151b0907a0a 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff @@ -63,10 +63,10 @@ _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _8 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_6.0: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_6.1: &i32) = move _8; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff index bd24522271b93..5ae26b73a6548 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff @@ -84,10 +84,10 @@ _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff index bd24522271b93..5ae26b73a6548 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff @@ -84,10 +84,10 @@ _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff index 7da2ff02006bf..83650d837b01b 100644 --- a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -47,10 +47,10 @@ _19 = const discriminant::::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) }) // mir::Constant // + span: $DIR/lower_intrinsics.rs:70:42: 70:44 - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) }) } _7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 _6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 - _5 = discriminant_value::(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45 @@ -71,10 +71,10 @@ _18 = const discriminant::::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 // ty::Const // + ty: &() - // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) }) // mir::Constant // + span: $DIR/lower_intrinsics.rs:71:42: 71:45 - // + literal: Const { ty: &(), val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1])) } + // + literal: Const { ty: &(), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) }) } _11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 _10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 - _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46 @@ -95,10 +95,10 @@ _17 = const discriminant::::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 // ty::Const // + ty: &E - // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/lower_intrinsics.rs:72:42: 72:47 - // + literal: Const { ty: &E, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0])) } + // + literal: Const { ty: &E, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) }) } _15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 _14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 - _13 = discriminant_value::(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48 diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir index 2332e5beafe0f..242138754c5d7 100644 --- a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir +++ b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir @@ -54,10 +54,10 @@ fn full_tested_match() -> () { _11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15 // ty::Const // + ty: &std::option::Option - // + val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/match_false_edges.rs:16:14: 16:15 - // + literal: Const { ty: &std::option::Option, val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &std::option::Option, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } _6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15 _4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27 StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27 diff --git a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir index 8c7d79262b242..d25f98db9f662 100644 --- a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir @@ -149,10 +149,10 @@ fn main() -> () { _27 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:47:21: 47:23 // ty::Const // + ty: &i32 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) // mir::Constant // + span: $DIR/retag.rs:47:21: 47:23 - // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, [], Some(promoted[0])) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } Retag(_27); // scope 7 at $DIR/retag.rs:47:21: 47:23 _23 = &(*_27); // scope 7 at $DIR/retag.rs:47:21: 47:23 Retag(_23); // scope 7 at $DIR/retag.rs:47:21: 47:23 From 4e8e89451c0cc65bdf032f7e43ee7c32c96faf05 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 13 Mar 2021 16:05:15 +0100 Subject: [PATCH 4/5] require a `tcx` for `TypeVisitor` --- .../src/infer/error_reporting/mod.rs | 4 ++ .../nice_region_error/static_impl_trait.rs | 12 ++++-- .../rustc_infer/src/infer/nll_relate/mod.rs | 6 +++ compiler/rustc_infer/src/infer/resolve.rs | 4 ++ compiler/rustc_lint/src/types.rs | 3 ++ compiler/rustc_middle/src/ty/fold.rs | 42 +++++++++++++++---- compiler/rustc_middle/src/ty/print/pretty.rs | 12 ++++-- compiler/rustc_mir/src/interpret/util.rs | 4 ++ .../src/monomorphize/polymorphize.rs | 14 +++++-- compiler/rustc_mir/src/util/pretty.rs | 4 ++ compiler/rustc_privacy/src/lib.rs | 4 ++ .../rustc_trait_selection/src/opaque_types.rs | 12 +++++- .../src/traits/object_safety.rs | 3 ++ .../src/traits/structural_match.rs | 3 ++ compiler/rustc_traits/src/chalk/lowering.rs | 13 +++++- compiler/rustc_typeck/src/check/check.rs | 17 ++++++-- compiler/rustc_typeck/src/check/op.rs | 11 +++-- compiler/rustc_typeck/src/check/wfcheck.rs | 11 +++-- compiler/rustc_typeck/src/collect.rs | 2 +- .../src/constrained_generic_params.rs | 21 ++++++---- compiler/rustc_typeck/src/impl_wf_check.rs | 4 +- .../src/impl_wf_check/min_specialization.rs | 8 ++-- .../clippy_lints/src/redundant_clone.rs | 15 ++++--- 23 files changed, 175 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index eeff48a63950e..6acec41d9b634 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1525,6 +1525,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> { + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) { let span = self.tcx.def_span(def_id); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index fa0d5b8301349..3d03dbdf66397 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -8,7 +8,9 @@ use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorRepor use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor}; use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind}; -use rustc_middle::ty::{self, AssocItemContainer, RegionKind, Ty, TypeFoldable, TypeVisitor}; +use rustc_middle::ty::{ + self, AssocItemContainer, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor, +}; use rustc_span::symbol::Ident; use rustc_span::{MultiSpan, Span}; @@ -470,8 +472,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Collect all the trait objects in a type that could have received an implicit `'static` lifetime. struct TraitObjectVisitor(Vec); -impl TypeVisitor<'_> for TraitObjectVisitor { - fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow { +impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor { + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for TraitObjectVisitor"); + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Dynamic(preds, RegionKind::ReStatic) => { if let Some(def_id) = preds.principal_def_id() { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index e5eb771603cd7..e8ce3a9debe55 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -187,6 +187,7 @@ where }; value.skip_binder().visit_with(&mut ScopeInstantiator { + tcx: self.infcx.tcx, next_region: &mut next_region, target_index: ty::INNERMOST, bound_region_scope: &mut scope, @@ -735,6 +736,7 @@ where /// `for<..`>. For each of those, it creates an entry in /// `bound_region_scope`. struct ScopeInstantiator<'me, 'tcx> { + tcx: TyCtxt<'tcx>, next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>, // The debruijn index of the scope we are instantiating. target_index: ty::DebruijnIndex, @@ -742,6 +744,10 @@ struct ScopeInstantiator<'me, 'tcx> { } impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> { + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>( &mut self, t: &ty::Binder, diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index d72be0134fb4c..9327cab3f12f0 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -121,6 +121,10 @@ impl<'a, 'tcx> UnresolvedTypeFinder<'a, 'tcx> { impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> { type BreakTy = (Ty<'tcx>, Option); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for UnresolvedTypeFinder"); + } + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { let t = self.infcx.shallow_resolve(t); if t.has_infer_types() { diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 2d311cc32f8b7..a6bb5ef9b2b92 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1174,6 +1174,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> { type BreakTy = Ty<'tcx>; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.cx.tcx + } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { match ty.kind() { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 4c7db4e803b8e..751ccf4be247a 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -183,6 +183,12 @@ pub trait TypeFolder<'tcx>: Sized { pub trait TypeVisitor<'tcx>: Sized { type BreakTy = !; + /// Supplies the `tcx` for an unevaluated anonymous constant in case its default substs + /// are not yet supplied. + /// + /// Visitors which do not look into these substs may leave this unimplemented, so be + /// careful when calling this method elsewhere. + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx>; fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { t.super_visit_with(self) @@ -292,7 +298,8 @@ impl<'tcx> TyCtxt<'tcx> { value: &impl TypeFoldable<'tcx>, callback: impl FnMut(ty::Region<'tcx>) -> bool, ) -> bool { - struct RegionVisitor { + struct RegionVisitor<'tcx, F> { + tcx: TyCtxt<'tcx>, /// The index of a binder *just outside* the things we have /// traversed. If we encounter a bound region bound by this /// binder or one outer to it, it appears free. Example: @@ -314,12 +321,16 @@ impl<'tcx> TyCtxt<'tcx> { callback: F, } - impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor + impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<'tcx, F> where F: FnMut(ty::Region<'tcx>) -> bool, { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>( &mut self, t: &Binder, @@ -355,7 +366,9 @@ impl<'tcx> TyCtxt<'tcx> { } } - value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback }).is_break() + value + .visit_with(&mut RegionVisitor { tcx: self, outer_index: ty::INNERMOST, callback }) + .is_break() } } @@ -655,7 +668,7 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable<'tcx>, { - let mut collector = LateBoundRegionsCollector::new(just_constraint); + let mut collector = LateBoundRegionsCollector::new(self, just_constraint); let result = value.as_ref().skip_binder().visit_with(&mut collector); assert!(result.is_continue()); // should never have stopped early collector.regions @@ -830,6 +843,10 @@ struct HasEscapingVarsVisitor { impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { type BreakTy = FoundEscapingVars; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for HasEscpaingVarsVisitor"); + } + fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { self.outer_index.shift_in(1); let result = t.super_visit_with(self); @@ -897,6 +914,9 @@ struct HasTypeFlagsVisitor { impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { type BreakTy = FoundFlags; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for HasTypeFlagsVisitor"); + } #[inline] fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow { @@ -951,7 +971,8 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { /// Collects all the late-bound regions at the innermost binding level /// into a hash set. -struct LateBoundRegionsCollector { +struct LateBoundRegionsCollector<'tcx> { + tcx: TyCtxt<'tcx>, current_index: ty::DebruijnIndex, regions: FxHashSet, @@ -965,9 +986,10 @@ struct LateBoundRegionsCollector { just_constrained: bool, } -impl LateBoundRegionsCollector { - fn new(just_constrained: bool) -> Self { +impl LateBoundRegionsCollector<'tcx> { + fn new(tcx: TyCtxt<'tcx>, just_constrained: bool) -> Self { LateBoundRegionsCollector { + tcx, current_index: ty::INNERMOST, regions: Default::default(), just_constrained, @@ -975,7 +997,11 @@ impl LateBoundRegionsCollector { } } -impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { +impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector<'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { self.current_index.shift_in(1); let result = t.super_visit_with(self); diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e0abfa36e8ccf..a97c6bf4f9a53 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1840,18 +1840,22 @@ impl FmtPrinter<'_, 'tcx, F> { where T: TypeFoldable<'tcx>, { - struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); - impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { + struct LateBoundRegionNameCollector<'a, 'tcx>(TyCtxt<'tcx>, &'a mut FxHashSet); + impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'a, 'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.0 + } + fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) = *r { - self.0.insert(name); + self.1.insert(name); } r.super_visit_with(self) } } self.used_region_names.clear(); - let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names); + let mut collector = LateBoundRegionNameCollector(self.tcx, &mut self.used_region_names); value.visit_with(&mut collector); self.region_index = 0; } diff --git a/compiler/rustc_mir/src/interpret/util.rs b/compiler/rustc_mir/src/interpret/util.rs index 89f34cd07aa4b..b7ab2e88b9623 100644 --- a/compiler/rustc_mir/src/interpret/util.rs +++ b/compiler/rustc_mir/src/interpret/util.rs @@ -21,6 +21,10 @@ where impl<'tcx> TypeVisitor<'tcx> for UsedParamsNeedSubstVisitor<'tcx> { type BreakTy = FoundParam; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow { if !c.needs_subst() { return ControlFlow::CONTINUE; diff --git a/compiler/rustc_mir/src/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs index 30e758c7fdf05..f2e1034f6a321 100644 --- a/compiler/rustc_mir/src/monomorphize/polymorphize.rs +++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs @@ -178,7 +178,7 @@ fn mark_used_by_predicates<'tcx>( // Consider all generic params in a predicate as used if any other parameter in the // predicate is used. let any_param_used = { - let mut vis = HasUsedGenericParams { unused_parameters }; + let mut vis = HasUsedGenericParams { tcx, unused_parameters }; predicate.visit_with(&mut vis).is_break() }; @@ -287,6 +287,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } #[instrument(skip(self))] fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow { if !c.has_param_types_or_consts() { @@ -350,13 +353,18 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } /// Visitor used to check if a generic parameter is used. -struct HasUsedGenericParams<'a> { +struct HasUsedGenericParams<'a, 'tcx> { + tcx: TyCtxt<'tcx>, unused_parameters: &'a FiniteBitSet, } -impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { +impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a, 'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + #[instrument(skip(self))] fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow { if !c.has_param_types_or_consts() { diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 247a0beccaf0f..f6ec9f7491084 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -661,6 +661,10 @@ pub fn write_allocations<'tcx>( } struct CollectAllocIds(BTreeSet); impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for CollectAllocIds") + } + fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow { if let ty::ConstKind::Value(val) = c.val { self.0.extend(alloc_ids_from_const(val)); diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 72be266b338ba..99552850ff0f5 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -178,6 +178,10 @@ where { type BreakTy = V::BreakTy; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.def_id_visitor.tcx() + } + fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { let tcx = self.def_id_visitor.tcx(); // InternalSubsts are not visited here because they are visited below in `super_visit_with`. diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 25ba489032bf1..48e4891fd7657 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -442,6 +442,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { for required_region in required_region_bounds { concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx, op: |r| self.sub_regions(infer::CallReturn(span), required_region, r), }); } @@ -510,6 +511,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx, op: |r| self.sub_regions(infer::CallReturn(span), least_region, r), }); } @@ -544,6 +546,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx: self.tcx, op: |r| { self.member_constraint( opaque_type_def_id, @@ -684,14 +687,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // // We ignore any type parameters because impl trait values are assumed to // capture all the in-scope type parameters. -struct ConstrainOpaqueTypeRegionVisitor { +struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP> { + tcx: TyCtxt<'tcx>, op: OP, } -impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor +impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP> where OP: FnMut(ty::Region<'tcx>), { + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>( &mut self, t: &ty::Binder, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 7de20e477fe04..9f3fc6650a375 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -762,6 +762,9 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( impl<'tcx> TypeVisitor<'tcx> for IllegalSelfTypeVisitor<'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 3d20a8d5cf336..a0c93cadbb6fe 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -131,6 +131,9 @@ impl Search<'a, 'tcx> { impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> { type BreakTy = NonStructuralMatchTy<'tcx>; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx() + } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { debug!("Search visiting ty: {:?}", ty); diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index fdf5f697e6117..5a443be6447e5 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -803,7 +803,7 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>( tcx: TyCtxt<'tcx>, ty: Binder, ) -> (T, chalk_ir::VariableKinds>, BTreeMap) { - let mut bound_vars_collector = BoundVarsCollector::new(); + let mut bound_vars_collector = BoundVarsCollector::new(tcx); ty.as_ref().skip_binder().visit_with(&mut bound_vars_collector); let mut parameters = bound_vars_collector.parameters; let named_parameters: BTreeMap = bound_vars_collector @@ -833,14 +833,16 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>( } crate struct BoundVarsCollector<'tcx> { + tcx: TyCtxt<'tcx>, binder_index: ty::DebruijnIndex, crate parameters: BTreeMap>>, crate named_parameters: Vec, } impl<'tcx> BoundVarsCollector<'tcx> { - crate fn new() -> Self { + crate fn new(tcx: TyCtxt<'tcx>) -> Self { BoundVarsCollector { + tcx, binder_index: ty::INNERMOST, parameters: BTreeMap::new(), named_parameters: vec![], @@ -849,6 +851,9 @@ impl<'tcx> BoundVarsCollector<'tcx> { } impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { self.binder_index.shift_in(1); let result = t.super_visit_with(self); @@ -1060,6 +1065,10 @@ impl PlaceholdersCollector { } impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for PlaceholdersCollector"); + } + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Placeholder(p) if p.universe == self.universe_index => { diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 0010d59f710cd..d9f49ea99d46a 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -486,14 +486,17 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( debug!(?item, ?span); struct FoundParentLifetime; - struct FindParentLifetimeVisitor<'tcx>(&'tcx ty::Generics); + struct FindParentLifetimeVisitor<'tcx>(TyCtxt<'tcx>, &'tcx ty::Generics); impl<'tcx> ty::fold::TypeVisitor<'tcx> for FindParentLifetimeVisitor<'tcx> { type BreakTy = FoundParentLifetime; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.0 + } fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { debug!("FindParentLifetimeVisitor: r={:?}", r); if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r { - if *index < self.0.parent_count as u32 { + if *index < self.1.parent_count as u32 { return ControlFlow::Break(FoundParentLifetime); } else { return ControlFlow::CONTINUE; @@ -515,21 +518,24 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( } struct ProhibitOpaqueVisitor<'tcx> { + tcx: TyCtxt<'tcx>, opaque_identity_ty: Ty<'tcx>, generics: &'tcx ty::Generics, - tcx: TyCtxt<'tcx>, selftys: Vec<(Span, Option)>, } impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> { type BreakTy = Ty<'tcx>; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t); if t == self.opaque_identity_ty { ControlFlow::CONTINUE } else { - t.super_visit_with(&mut FindParentLifetimeVisitor(self.generics)) + t.super_visit_with(&mut FindParentLifetimeVisitor(self.tcx, self.generics)) .map_break(|FoundParentLifetime| t) } } @@ -1568,6 +1574,9 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) { { struct VisitTypes(Vec); impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for VisitTypes"); + } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Opaque(def, _) => { diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 567cb1a90d0d9..dca645dad0ce9 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -428,7 +428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } if let Some(missing_trait) = missing_trait { - let mut visitor = TypeParamVisitor(vec![]); + let mut visitor = TypeParamVisitor(self.tcx, vec![]); visitor.visit_ty(lhs_ty); if op.node == hir::BinOpKind::Add @@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This has nothing here because it means we did string // concatenation (e.g., "Hello " + "World!"). This means // we don't want the note in the else clause to be emitted - } else if let [ty] = &visitor.0[..] { + } else if let [ty] = &visitor.1[..] { if let ty::Param(p) = *ty.kind() { // Check if the method would be found if the type param wasn't // involved. If so, it means that adding a trait bound to the param is @@ -986,12 +986,15 @@ fn suggest_constraining_param( } } -struct TypeParamVisitor<'tcx>(Vec>); +struct TypeParamVisitor<'tcx>(TyCtxt<'tcx>, Vec>); impl<'tcx> TypeVisitor<'tcx> for TypeParamVisitor<'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.0 + } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { if let ty::Param(_) = ty.kind() { - self.0.push(ty); + self.1.push(ty); } ty.super_visit_with(self) } diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 00c6550835b43..1a13629157697 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -784,12 +784,15 @@ fn check_where_clauses<'tcx, 'fcx>( .predicates .iter() .flat_map(|&(pred, sp)| { - #[derive(Default)] - struct CountParams { + struct CountParams<'tcx> { + tcx: TyCtxt<'tcx>, params: FxHashSet, } - impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams { + impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams<'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if let ty::Param(param) = t.kind() { @@ -809,7 +812,7 @@ fn check_where_clauses<'tcx, 'fcx>( c.super_visit_with(self) } } - let mut param_count = CountParams::default(); + let mut param_count = CountParams { tcx: fcx.tcx, params: FxHashSet::default() }; let has_region = pred.visit_with(&mut param_count).is_break(); let substituted_pred = pred.subst(fcx.tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 546f76859951e..d4668de2b9f8c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2169,7 +2169,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP tcx, &mut predicates, trait_ref, - &mut cgp::parameters_for_impl(self_ty, trait_ref), + &mut cgp::parameters_for_impl(tcx, self_ty, trait_ref), ); } diff --git a/compiler/rustc_typeck/src/constrained_generic_params.rs b/compiler/rustc_typeck/src/constrained_generic_params.rs index 529de1a287484..140348ea4ec13 100644 --- a/compiler/rustc_typeck/src/constrained_generic_params.rs +++ b/compiler/rustc_typeck/src/constrained_generic_params.rs @@ -27,12 +27,13 @@ impl From for Parameter { /// Returns the set of parameters constrained by the impl header. pub fn parameters_for_impl<'tcx>( + tcx: TyCtxt<'tcx>, impl_self_ty: Ty<'tcx>, impl_trait_ref: Option>, ) -> FxHashSet { let vec = match impl_trait_ref { - Some(tr) => parameters_for(&tr, false), - None => parameters_for(&impl_self_ty, false), + Some(tr) => parameters_for(tcx, &tr, false), + None => parameters_for(tcx, &impl_self_ty, false), }; vec.into_iter().collect() } @@ -43,20 +44,26 @@ pub fn parameters_for_impl<'tcx>( /// of parameters whose values are needed in order to constrain `ty` - these /// differ, with the latter being a superset, in the presence of projections. pub fn parameters_for<'tcx>( + tcx: TyCtxt<'tcx>, t: &impl TypeFoldable<'tcx>, include_nonconstraining: bool, ) -> Vec { - let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining }; + let mut collector = ParameterCollector { tcx, parameters: vec![], include_nonconstraining }; t.visit_with(&mut collector); collector.parameters } -struct ParameterCollector { +struct ParameterCollector<'tcx> { + tcx: TyCtxt<'tcx>, parameters: Vec, include_nonconstraining: bool, } -impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { +impl<'tcx> TypeVisitor<'tcx> for ParameterCollector<'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Projection(..) | ty::Opaque(..) if !self.include_nonconstraining => { @@ -198,12 +205,12 @@ pub fn setup_constraining_predicates<'tcx>( // `<::Baz as Iterator>::Output = ::Output` // Then the projection only applies if `T` is known, but it still // does not determine `U`. - let inputs = parameters_for(&projection.projection_ty, true); + let inputs = parameters_for(tcx, &projection.projection_ty, true); let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(&p)); if !relies_only_on_inputs { continue; } - input_parameters.extend(parameters_for(&projection.ty, false)); + input_parameters.extend(parameters_for(tcx, &projection.ty, false)); } else { continue; } diff --git a/compiler/rustc_typeck/src/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs index 7713381e62e46..1f22ca3a31b1a 100644 --- a/compiler/rustc_typeck/src/impl_wf_check.rs +++ b/compiler/rustc_typeck/src/impl_wf_check.rs @@ -119,7 +119,7 @@ fn enforce_impl_params_are_constrained( let impl_predicates = tcx.predicates_of(impl_def_id); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); - let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref); + let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref); cgp::identify_constrained_generic_params( tcx, impl_predicates, @@ -136,7 +136,7 @@ fn enforce_impl_params_are_constrained( match item.kind { ty::AssocKind::Type => { if item.defaultness.has_value() { - cgp::parameters_for(&tcx.type_of(def_id), true) + cgp::parameters_for(tcx, &tcx.type_of(def_id), true) } else { Vec::new() } diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index 505d9a59d9c2f..1f3996c0646cc 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -207,15 +207,15 @@ fn unconstrained_parent_impl_substs<'tcx>( continue; } - unconstrained_parameters.extend(cgp::parameters_for(&projection_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, &projection_ty, true)); - for param in cgp::parameters_for(&projected_ty, false) { + for param in cgp::parameters_for(tcx, &projected_ty, false) { if !unconstrained_parameters.contains(¶m) { constrained_params.insert(param.0); } } - unconstrained_parameters.extend(cgp::parameters_for(&projected_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, &projected_ty, true)); } } @@ -249,7 +249,7 @@ fn check_duplicate_params<'tcx>( parent_substs: &Vec>, span: Span, ) { - let mut base_params = cgp::parameters_for(parent_substs, true); + let mut base_params = cgp::parameters_for(tcx, parent_substs, true); base_params.sort_by_key(|param| param.0); if let (_, [duplicate, ..]) = base_params.partition_dedup() { let param = impl1_substs[duplicate.0 as usize]; diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index 6a4537e6735ce..2330633b965c3 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::{ self, traversal, visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor as _}, }; -use rustc_middle::ty::{self, fold::TypeVisitor, Ty}; +use rustc_middle::ty::{self, fold::TypeVisitor, Ty, TyCtxt}; use rustc_mir::dataflow::{Analysis, AnalysisDomain, GenKill, GenKillAnalysis, ResultsCursor}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::{BytePos, Span}; @@ -522,7 +522,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> { self.possible_borrower.add(borrowed.local, lhs); }, other => { - if ContainsRegion + if ContainsRegion(self.cx.tcx) .visit_ty(place.ty(&self.body.local_decls, self.cx.tcx).ty) .is_continue() { @@ -547,7 +547,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> { // If the call returns something with lifetimes, // let's conservatively assume the returned value contains lifetime of all the arguments. // For example, given `let y: Foo<'a> = foo(x)`, `y` is considered to be a possible borrower of `x`. - if ContainsRegion.visit_ty(&self.body.local_decls[*dest].ty).is_continue() { + if ContainsRegion(self.cx.tcx).visit_ty(&self.body.local_decls[*dest].ty).is_continue() { return; } @@ -563,12 +563,15 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> { } } -struct ContainsRegion; +struct ContainsRegion<'tcx>(TyCtxt<'tcx>); -impl TypeVisitor<'_> for ContainsRegion { +impl<'tcx> TypeVisitor<'tcx> for ContainsRegion<'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.0 + } - fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow { + fn visit_region(&mut self, _: ty::Region<'tcx>) -> ControlFlow { ControlFlow::BREAK } } From 371c77bb90e13798a804f220e15f2e4dfa8dc9f8 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 16 Mar 2021 00:05:45 +0100 Subject: [PATCH 5/5] make unevaluated const substs optional --- .../rustc_codegen_cranelift/src/constant.rs | 8 ++--- compiler/rustc_infer/src/infer/mod.rs | 8 ++--- .../rustc_middle/src/mir/interpret/queries.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 4 +++ compiler/rustc_middle/src/ty/consts.rs | 3 +- compiler/rustc_middle/src/ty/consts/kind.rs | 34 +++++++++++++------ compiler/rustc_middle/src/ty/flags.rs | 3 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 ++- compiler/rustc_middle/src/ty/relate.rs | 11 +++--- .../rustc_middle/src/ty/structural_impls.rs | 24 ++++++++----- compiler/rustc_middle/src/ty/walk.rs | 3 +- .../src/borrow_check/type_check/mod.rs | 10 +++--- compiler/rustc_mir/src/interpret/operand.rs | 8 +++-- .../src/monomorphize/polymorphize.rs | 11 +++--- .../src/transform/check_consts/qualifs.rs | 2 +- .../rustc_mir/src/transform/promote_consts.rs | 18 ++++++---- compiler/rustc_mir_build/src/thir/cx/expr.rs | 4 +-- .../src/traits/const_evaluatable.rs | 6 ++-- .../src/traits/fulfill.rs | 14 ++++---- .../rustc_trait_selection/src/traits/wf.rs | 9 ++--- compiler/rustc_typeck/src/collect.rs | 4 ++- compiler/rustc_typeck/src/collect/type_of.rs | 6 +++- src/librustdoc/clean/utils.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- src/tools/clippy/clippy_utils/src/consts.rs | 2 +- 25 files changed, 122 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index d637f51649631..c5c0f19038be9 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -116,13 +116,13 @@ pub(crate) fn codegen_constant<'tcx>( let const_ = fx.monomorphize(constant.literal); let const_val = match const_.val { ConstKind::Value(const_val) => const_val, - ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => { - assert!(substs.is_empty()); - assert!(promoted.is_none()); + ConstKind::Unevaluated(uv) if fx.tcx.is_static(uv.def.did) => { + assert!(uv.substs(fx.tcx).is_empty()); + assert!(uv.promoted.is_none()); return codegen_static_ref( fx, - def.did, + uv.def.did, fx.layout_of(fx.monomorphize(&constant.literal.ty)), ) .to_cvalue(fx); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 7b18f4d0ff6a9..e7c078937d1b4 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1498,16 +1498,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn const_eval_resolve( &self, param_env: ty::ParamEnv<'tcx>, - ty::Unevaluated { def, substs, promoted }: ty::Unevaluated<'tcx>, + unevaluated: ty::Unevaluated<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { let mut original_values = OriginalQueryValues::default(); - let canonical = self.canonicalize_query((param_env, substs), &mut original_values); + let canonical = self.canonicalize_query((param_env, unevaluated), &mut original_values); - let (param_env, substs) = canonical.value; + let (param_env, unevaluated) = canonical.value; // The return value is the evaluated value which doesn't contain any reference to inference // variables, thus we don't need to substitute back the original values. - self.tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, span) + self.tcx.const_eval_resolve(param_env, unevaluated, span) } /// If `typ` is a type variable of some kind, resolve it one level diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index fa7c0670e8ce6..c63613ae3af29 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -38,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> { ct: ty::Unevaluated<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { - match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { + match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs(self)) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: ct.promoted }; self.const_eval_global_id(param_env, cid, span) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b03b26d64606c..1c733eceb92be 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -93,6 +93,10 @@ rustc_queries! { desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) } } + query default_anon_const_substs(key: DefId) -> SubstsRef<'tcx> { + desc { |tcx| "computing the default generic arguments for `{}`", tcx.def_path_str(key) } + } + /// Records the type of every item. query type_of(key: DefId) -> Ty<'tcx> { desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d078e73897161..1b0fa31b302a0 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,6 +1,5 @@ use crate::mir::interpret::ConstValue; use crate::mir::interpret::{LitToConstInput, Scalar}; -use crate::ty::subst::InternalSubsts; use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{ParamEnv, ParamEnvAnd}; use rustc_errors::ErrorReported; @@ -98,7 +97,7 @@ impl<'tcx> Const<'tcx> { } _ => ty::ConstKind::Unevaluated(ty::Unevaluated { def: def.to_global(), - substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), + non_default_substs: None, promoted: None, }), }; diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index b4c38bfbb461d..f934f721cdedc 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -14,10 +14,16 @@ use rustc_target::abi::Size; #[derive(Hash, HashStable)] pub struct Unevaluated<'tcx> { pub def: ty::WithOptConstParam, - pub substs: SubstsRef<'tcx>, + pub non_default_substs: Option>, pub promoted: Option, } +impl<'tcx> Unevaluated<'tcx> { + pub fn substs(self, tcx: TyCtxt<'tcx>) -> SubstsRef<'tcx> { + self.non_default_substs.unwrap_or_else(|| tcx.default_anon_const_substs(self.def.did)) + } +} + /// Represents a constant in Rust. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Hash, HashStable)] @@ -102,7 +108,7 @@ impl<'tcx> ConstKind<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ) -> Option, ErrorReported>> { - if let ConstKind::Unevaluated(Unevaluated { def, substs, promoted }) = self { + if let ConstKind::Unevaluated(unevaluated) = self { use crate::mir::interpret::ErrorHandled; // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` @@ -111,29 +117,35 @@ impl<'tcx> ConstKind<'tcx> { // Note that we erase regions *before* calling `with_reveal_all_normalized`, // so that we don't try to invoke this query with // any region variables. - let param_env_and_substs = tcx + let param_env_and = tcx .erase_regions(param_env) .with_reveal_all_normalized(tcx) - .and(tcx.erase_regions(substs)); + .and(tcx.erase_regions(unevaluated)); // HACK(eddyb) when the query key would contain inference variables, // attempt using identity substs and `ParamEnv` instead, that will succeed // when the expression doesn't depend on any parameters. // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that // we can call `infcx.const_eval_resolve` which handles inference variables. - let param_env_and_substs = if param_env_and_substs.needs_infer() { - tcx.param_env(def.did).and(InternalSubsts::identity_for_item(tcx, def.did)) + let param_env_and = if param_env_and.needs_infer() { + tcx.param_env(unevaluated.def.did).and(ty::Unevaluated { + def: unevaluated.def, + non_default_substs: Some(InternalSubsts::identity_for_item( + tcx, + unevaluated.def.did, + )), + promoted: unevaluated.promoted, + }) } else { - param_env_and_substs + param_env_and }; // FIXME(eddyb) maybe the `const_eval_*` methods should take - // `ty::ParamEnvAnd` instead of having them separate. - let (param_env, substs) = param_env_and_substs.into_parts(); + // `ty::ParamEnvAnd` instead of having them separate. + let (param_env, unevaluated) = param_env_and.into_parts(); // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - match tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, None) - { + match tcx.const_eval_resolve(param_env, unevaluated, None) { // NOTE(eddyb) `val` contains no lifetimes/types/consts, // and we use the original type, so nothing from `substs` // (which may be identity substs, see above), diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index d6dc81c5b785d..78369676bc494 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -295,7 +295,8 @@ impl FlagComputation { } fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'tcx>) { - self.add_substs(ct.substs); + // TODO + self.add_substs(ct.non_default_substs.unwrap()); self.add_flags(TypeFlags::HAS_CT_PROJECTION); } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index a97c6bf4f9a53..d0a2d104afa59 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -915,7 +915,9 @@ pub trait PrettyPrinter<'tcx>: } match ct.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs, promoted }) => { + // TODO + let substs = non_default_substs.unwrap(); if let Some(promoted) = promoted { p!(print_value_path(def.did, substs)); p!(write("::{:?}", promoted)); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index e54e44a6157e8..678ec2354c894 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -590,7 +590,7 @@ pub fn super_relate_consts>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => { - if tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs))) { + if tcx.try_unify_abstract_consts(((au.def, au.substs(tcx)), (bu.def, bu.substs(tcx)))) { Ok(a.val) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) @@ -603,11 +603,14 @@ pub fn super_relate_consts>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def && au.promoted == bu.promoted => { - let substs = - relation.relate_with_variance(ty::Variance::Invariant, au.substs, bu.substs)?; + let substs = relation.relate_with_variance( + ty::Variance::Invariant, + au.substs(tcx), + bu.substs(tcx), + )?; Ok(ty::ConstKind::Unevaluated(ty::Unevaluated { def: au.def, - substs, + non_default_substs: Some(substs), promoted: au.promoted, })) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 2da23b331e0cb..c7a217c5dde97 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -1031,13 +1031,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)), - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs: substs.fold_with(folder), - promoted, - }) - } + ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.fold_with(folder)), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) @@ -1049,7 +1043,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match *self { ty::ConstKind::Infer(ic) => ic.visit_with(visitor), ty::ConstKind::Param(p) => p.visit_with(visitor), - ty::ConstKind::Unevaluated(ct) => ct.substs.visit_with(visitor), + ty::ConstKind::Unevaluated(uv) => uv.visit_with(visitor), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) @@ -1067,3 +1061,17 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { ControlFlow::CONTINUE } } + +impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { + fn super_fold_with>(self, folder: &mut F) -> Self { + ty::Unevaluated { + def: self.def, + non_default_substs: Some(self.substs(folder.tcx()).fold_with(folder)), + promoted: self.promoted, + } + } + + fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.substs(visitor.tcx_for_anon_const_substs()).visit_with(visitor) + } +} diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index c2fe5f1ef3f62..721c96503d140 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -196,7 +196,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Error(_) => {} ty::ConstKind::Unevaluated(ct) => { - stack.extend(ct.substs.iter().rev()); + // TODO + stack.extend(ct.non_default_substs.unwrap().iter().rev()); } } } diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index 157adf8438488..f3f0fb5274da7 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -314,10 +314,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } else { let tcx = self.tcx(); - if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) = - constant.literal.val - { - if let Some(promoted) = promoted { + if let ty::ConstKind::Unevaluated(uv) = constant.literal.val { + if let Some(promoted) = uv.promoted { let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, promoted: &Body<'tcx>, ty, @@ -352,8 +350,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { ConstraintCategory::Boring, self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( constant.literal.ty, - def.did, - UserSubsts { substs, user_self_ty: None }, + uv.def.did, + UserSubsts { substs: uv.substs(tcx), user_self_ty: None }, )), ) { span_mirbug!( diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 93e294651cbaa..b7b5ca3cfc6fd 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -566,9 +566,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val_val = match val.val { ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)), - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - let instance = self.resolve(def, substs)?; - return Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into()); + ty::ConstKind::Unevaluated(uv) => { + let instance = self.resolve(uv.def, uv.substs(*self.tcx))?; + return Ok(self + .eval_to_allocation(GlobalId { instance, promoted: uv.promoted })? + .into()); } ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => { span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", val) diff --git a/compiler/rustc_mir/src/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs index f2e1034f6a321..2f96441b2e044 100644 --- a/compiler/rustc_mir/src/monomorphize/polymorphize.rs +++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs @@ -302,21 +302,24 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.unused_parameters.clear(param.index); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)}) + ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs: _, promoted: Some(p)}) // Avoid considering `T` unused when constants are of the form: // `>::foo::promoted[p]` if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self => { // If there is a promoted, don't look at the substs - since it will always contain // the generic parameters, instead, traverse the promoted MIR. + // + // FIXME(lcnr): This seems incorrect if we get the promoted by inlining. + // We have to consider its substs in that case. let promoted = self.tcx.promoted_mir(def.did); self.visit_body(&promoted[p]); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) - if self.tcx.def_kind(def.did) == DefKind::AnonConst => + ty::ConstKind::Unevaluated(uv) + if self.tcx.def_kind(uv.def.did) == DefKind::AnonConst => { - self.visit_child_body(def.did, substs); + self.visit_child_body(uv.def.did, uv.substs(self.tcx)); ControlFlow::CONTINUE } _ => c.super_visit_with(self), diff --git a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs index c8dce55f69a1a..35351f60a0f11 100644 --- a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs @@ -246,7 +246,7 @@ where }; // Check the qualifs of the value of `const` items. - if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = + if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs: _, promoted }) = constant.literal.val { assert!(promoted.is_none()); diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs index 4be8b42993e69..3a8896faa913d 100644 --- a/compiler/rustc_mir/src/transform/promote_consts.rs +++ b/compiler/rustc_mir/src/transform/promote_consts.rs @@ -1002,13 +1002,17 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { ty, val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, - substs: InternalSubsts::for_item(tcx, def.did, |param, _| { - if let ty::GenericParamDefKind::Lifetime = param.kind { - tcx.lifetimes.re_erased.into() - } else { - tcx.mk_param_from_def(param) - } - }), + non_default_substs: Some(InternalSubsts::for_item( + tcx, + def.did, + |param, _| { + if let ty::GenericParamDefKind::Lifetime = param.kind { + tcx.lifetimes.re_erased.into() + } else { + tcx.mk_param_from_def(param) + } + }, + )), promoted: Some(promoted_id), }), }), diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index df2f9c8581f37..8ac38dec0a4e3 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -694,7 +694,7 @@ impl<'thir, 'tcx> Cx<'thir, 'tcx> { let lhs = mk_const(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Unevaluated(ty::Unevaluated { def: ty::WithOptConstParam::unknown(did), - substs, + non_default_substs: Some(substs), promoted: None, }), ty: var_ty, @@ -892,7 +892,7 @@ impl<'thir, 'tcx> Cx<'thir, 'tcx> { literal: self.tcx.mk_const(ty::Const { val: ty::ConstKind::Unevaluated(ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id), - substs, + non_default_substs: Some(substs), promoted: None, }), ty: self.typeck_results().node_type(expr.hir_id), diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index d5ef72741c4b7..17fea6ba4fe44 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -165,7 +165,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( // See #74595 for more details about this. let concrete = infcx.const_eval_resolve( param_env, - ty::Unevaluated { def, substs, promoted: None }, + ty::Unevaluated { def, non_default_substs: Some(substs), promoted: None }, Some(span), ); @@ -243,9 +243,7 @@ impl AbstractConst<'tcx> { ct: &ty::Const<'tcx>, ) -> Result>, ErrorReported> { match ct.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: _ }) => { - AbstractConst::new(tcx, def, substs) - } + ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.def, uv.substs(tcx)), ty::ConstKind::Error(_) => Err(ErrorReported), _ => Ok(None), } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index a383658684d59..e5879561f3b30 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -511,7 +511,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ty::PredicateKind::ConstEquate(c1, c2) => { debug!(?c1, ?c2, "equating consts"); - if self.selcx.tcx().features().const_evaluatable_checked { + let tcx = self.selcx.tcx(); + if tcx.features().const_evaluatable_checked { // FIXME: we probably should only try to unify abstract constants // if the constants depend on generic parameters. // @@ -519,11 +520,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.val, c2.val) { - if self - .selcx - .tcx() - .try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs))) - { + if tcx.try_unify_abstract_consts(( + (a.def, a.substs(tcx)), + (b.def, b.substs(tcx)), + )) { return ProcessResult::Changed(vec![]); } } @@ -542,7 +542,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { Err(ErrorHandled::TooGeneric) => { stalled_on.extend( unevaluated - .substs + .substs(tcx) .iter() .filter_map(TyOrConstInferVar::maybe_from_generic_arg), ); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index aee128dec7d12..7c4f4ab7ed676 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -430,13 +430,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { GenericArgKind::Const(constant) => { match constant.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - assert!(promoted.is_none()); + ty::ConstKind::Unevaluated(uv) => { + assert!(uv.promoted.is_none()); + let substs = uv.substs(self.tcx()); - let obligations = self.nominal_obligations(def.did, substs); + let obligations = self.nominal_obligations(uv.def.did, substs); self.out.extend(obligations); - let predicate = ty::PredicateKind::ConstEvaluatable(def, substs) + let predicate = ty::PredicateKind::ConstEvaluatable(uv.def, substs) .to_predicate(self.tcx()); let cause = self.cause(traits::MiscObligation); self.out.push(traits::Obligation::with_depth( diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index d4668de2b9f8c..25bd81b5e5b51 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -69,6 +69,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { pub fn provide(providers: &mut Providers) { *providers = Providers { opt_const_param_of: type_of::opt_const_param_of, + default_anon_const_substs: type_of::default_anon_const_substs, type_of: type_of::type_of, item_bounds: item_bounds::item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds, @@ -2204,7 +2205,8 @@ fn const_evaluatable_predicates_of<'tcx>( assert_eq!(uv.promoted, None); let span = self.tcx.hir().span(c.hir_id); self.preds.insert(( - ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs).to_predicate(self.tcx), + ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs(self.tcx)) + .to_predicate(self.tcx), span, )); } diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 3f2f244e44fd2..285e20c7ac2af 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -7,7 +7,7 @@ use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; use rustc_hir::{HirId, Node}; use rustc_middle::hir::map::Map; -use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; +use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; use rustc_span::symbol::Ident; @@ -250,6 +250,10 @@ fn get_path_containing_arg_in_pat<'hir>( arg_path } +pub(super) fn default_anon_const_substs(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> { + InternalSubsts::identity_for_item(tcx, def_id) +} + pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { let def_id = def_id.expect_local(); use rustc_hir::*; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 6f283d501a4f2..c9c0e5e332b89 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -296,7 +296,7 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String { match n.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs: _, promoted }) => { let mut s = if let Some(def) = def.as_local() { let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did); print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id)) diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 3e1db233696fe..68d921044fc8d 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -185,7 +185,7 @@ fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: D cx.param_env, ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id), - substs, + non_default_substs: Some(substs), promoted: None }, None diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index ebe896b7ae867..4199abc54eab8 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -343,7 +343,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { self.param_env, ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id), - substs, + non_default_substs: Some(substs), promoted: None, }, None,