From 71bbb603f4108bc1f0bc8c8395ec725bb66e7802 Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 12 Jan 2022 03:19:52 +0000 Subject: [PATCH 1/4] initial revert --- .../src/type_check/liveness/trace.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +- .../rustc_codegen_cranelift/src/constant.rs | 10 +- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 2 +- .../rustc_const_eval/src/interpret/operand.rs | 2 +- .../rustc_const_eval/src/interpret/util.rs | 10 +- .../src/transform/check_consts/check.rs | 2 +- .../src/transform/check_consts/qualifs.rs | 2 +- .../src/transform/promote_consts.rs | 19 +- .../src/infer/canonical/canonicalizer.rs | 2 +- compiler/rustc_infer/src/infer/combine.rs | 20 +- .../src/infer/error_reporting/mod.rs | 4 - .../infer/error_reporting/need_type_info.rs | 6 +- .../nice_region_error/static_impl_trait.rs | 6 - .../trait_impl_difference.rs | 19 +- compiler/rustc_infer/src/infer/freshen.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 14 +- .../rustc_infer/src/infer/nll_relate/mod.rs | 6 - .../rustc_infer/src/infer/opaque_types.rs | 12 +- .../src/infer/outlives/components.rs | 2 +- .../rustc_infer/src/infer/outlives/verify.rs | 2 +- compiler/rustc_infer/src/infer/resolve.rs | 5 - compiler/rustc_lint/src/builtin.rs | 6 +- .../src/enum_intrinsics_non_enums.rs | 2 +- compiler/rustc_lint/src/noop_method_call.rs | 2 +- compiler/rustc_lint/src/types.rs | 3 - .../rustc_middle/src/mir/interpret/queries.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 9 +- compiler/rustc_middle/src/mir/pretty.rs | 10 +- compiler/rustc_middle/src/query/mod.rs | 9 +- compiler/rustc_middle/src/ty/consts.rs | 6 +- compiler/rustc_middle/src/ty/consts/kind.rs | 73 +---- compiler/rustc_middle/src/ty/erase_regions.rs | 4 +- compiler/rustc_middle/src/ty/flags.rs | 34 +-- compiler/rustc_middle/src/ty/fold.rs | 262 +++--------------- compiler/rustc_middle/src/ty/layout.rs | 6 +- compiler/rustc_middle/src/ty/mod.rs | 4 +- compiler/rustc_middle/src/ty/print/pretty.rs | 55 ++-- compiler/rustc_middle/src/ty/relate.rs | 8 +- .../rustc_middle/src/ty/structural_impls.rs | 74 +---- compiler/rustc_middle/src/ty/sty.rs | 20 +- compiler/rustc_middle/src/ty/subst.rs | 2 +- compiler/rustc_middle/src/ty/walk.rs | 41 +-- compiler/rustc_mir_build/src/build/mod.rs | 10 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 14 +- .../src/thir/pattern/const_to_pat.rs | 2 +- .../rustc_mir_transform/src/const_prop.rs | 13 +- .../src/function_item_references.rs | 4 +- .../rustc_mir_transform/src/inline/cycle.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 6 +- compiler/rustc_mir_transform/src/shim.rs | 24 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- .../src/partitioning/default.rs | 4 +- .../rustc_monomorphize/src/polymorphize.rs | 24 +- compiler/rustc_privacy/src/lib.rs | 8 +- compiler/rustc_query_impl/src/keys.rs | 11 +- compiler/rustc_symbol_mangling/src/legacy.rs | 4 +- compiler/rustc_symbol_mangling/src/v0.rs | 4 +- .../src/traits/coherence.rs | 2 +- .../src/traits/const_evaluatable.rs | 71 +++-- .../src/traits/error_reporting/mod.rs | 4 +- .../src/traits/fulfill.rs | 22 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/object_safety.rs | 38 ++- .../src/traits/query/normalize.rs | 16 +- .../src/traits/select/confirmation.rs | 4 +- .../src/traits/select/mod.rs | 19 +- .../src/traits/structural_match.rs | 3 - .../rustc_trait_selection/src/traits/wf.rs | 21 +- compiler/rustc_traits/src/chalk/lowering.rs | 15 +- compiler/rustc_ty_utils/src/instance.rs | 4 - compiler/rustc_ty_utils/src/ty.rs | 14 +- compiler/rustc_type_ir/src/lib.rs | 112 +++----- compiler/rustc_typeck/src/astconv/mod.rs | 6 +- compiler/rustc_typeck/src/check/check.rs | 26 +- compiler/rustc_typeck/src/check/dropck.rs | 6 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 8 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 2 +- compiler/rustc_typeck/src/check/op.rs | 11 +- compiler/rustc_typeck/src/check/wfcheck.rs | 43 +-- compiler/rustc_typeck/src/check/writeback.rs | 4 +- compiler/rustc_typeck/src/collect.rs | 5 +- compiler/rustc_typeck/src/collect/type_of.rs | 28 +- .../src/constrained_generic_params.rs | 21 +- compiler/rustc_typeck/src/impl_wf_check.rs | 4 +- .../src/impl_wf_check/min_specialization.rs | 10 +- .../src/outlives/implicit_infer.rs | 15 +- .../rustc_typeck/src/variance/constraints.rs | 3 +- src/librustdoc/clean/utils.rs | 2 +- ...motion_extern_static.BAR.PromoteTemps.diff | 2 +- ...motion_extern_static.FOO.PromoteTemps.diff | 2 +- ...e_oob_for_slices.main.ConstProp.32bit.diff | 2 +- ...e_oob_for_slices.main.ConstProp.64bit.diff | 2 +- ..._prop_fails_gracefully.main.ConstProp.diff | 2 +- .../const_prop/ref_deref.main.ConstProp.diff | 2 +- .../ref_deref.main.PromoteTemps.diff | 2 +- .../ref_deref_project.main.ConstProp.diff | 2 +- .../ref_deref_project.main.PromoteTemps.diff | 2 +- .../slice_len.main.ConstProp.32bit.diff | 2 +- .../slice_len.main.ConstProp.64bit.diff | 2 +- .../inline/inline_retag.bar.Inline.after.mir | 4 +- .../issue_73223.main.PreCodegen.32bit.diff | 2 +- .../issue_73223.main.PreCodegen.64bit.diff | 2 +- ..._73223.main.SimplifyArmIdentity.32bit.diff | 2 +- ..._73223.main.SimplifyArmIdentity.64bit.diff | 2 +- ...trinsics.discriminant.LowerIntrinsics.diff | 6 +- ...s.full_tested_match.PromoteTemps.after.mir | 2 +- ...asts.SimplifyCfg-elaborate-drops.after.mir | 2 +- ...main.SimplifyCfg-elaborate-drops.after.mir | 2 +- src/tools/clippy/clippy_lints/src/escape.rs | 5 +- .../clippy/clippy_lints/src/let_underscore.rs | 2 +- .../clippy_lints/src/loops/same_item_push.rs | 2 +- .../clippy/clippy_lints/src/methods/mod.rs | 10 +- .../src/needless_pass_by_value.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 6 +- .../src/non_send_fields_in_send_ty.rs | 8 +- .../clippy_lints/src/redundant_clone.rs | 15 +- src/tools/clippy/clippy_lints/src/returns.rs | 2 +- .../src/self_named_constructors.rs | 4 +- .../clippy_lints/src/unnecessary_sort_by.rs | 2 +- src/tools/clippy/clippy_lints/src/use_self.rs | 2 +- src/tools/clippy/clippy_utils/src/consts.rs | 6 +- src/tools/clippy/clippy_utils/src/lib.rs | 6 +- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 10 +- 127 files changed, 541 insertions(+), 1051 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 094af20f52efc..169de23facce2 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -171,7 +171,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> { for (local, location) in drop_used { if !live_locals.contains(&local) { let local_ty = self.cx.body.local_decls[local].ty; - if local_ty.has_free_regions(self.cx.typeck.tcx()) { + if local_ty.has_free_regions() { self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations); } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 1f745f977d4c4..4c98e964ab0df 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -425,7 +425,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( constant.literal.ty(), uv.def.did, - UserSubsts { substs: uv.substs(self.tcx()), user_self_ty: None }, + UserSubsts { substs: uv.substs, user_self_ty: None }, )), ) { span_mirbug!( @@ -1969,7 +1969,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let predicates = self.prove_closure_bounds( tcx, def_id.expect_local(), - uv.substs(tcx), + uv.substs, location, ); self.normalize_and_prove_instantiated_predicates( diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 9a6c45ae98d5f..0c06c77472b91 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -129,11 +129,13 @@ pub(crate) fn codegen_constant<'tcx>( }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, - ConstKind::Unevaluated(uv) if fx.tcx.is_static(uv.def.did) => { - assert!(uv.substs(fx.tcx).is_empty()); - assert!(uv.promoted.is_none()); + ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if fx.tcx.is_static(def.did) => + { + assert!(substs.is_empty()); + assert!(promoted.is_none()); - return codegen_static_ref(fx, uv.def.did, fx.layout_of(const_.ty)).to_cvalue(fx); + return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx); } ConstKind::Unevaluated(unevaluated) => { match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 01f7868df3492..d1cea147a7a70 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -507,7 +507,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { ty::Adt(def, ..) if !def.is_box() => { // Again, only create type information if full debuginfo is enabled if cx.sess().opts.debuginfo == DebugInfo::Full - && !impl_self_ty.definitely_needs_subst(cx.tcx) + && !impl_self_ty.needs_subst() { Some(type_metadata(cx, impl_self_ty, rustc_span::DUMMY_SP)) } else { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index dcfe5fcc2ca73..5ce4e606fd20b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1477,7 +1477,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"), LocalRef::Operand(None) => { let dst_layout = bx.layout_of(self.monomorphized_place_ty(dst.as_ref())); - assert!(!dst_layout.ty.has_erasable_regions(self.cx.tcx())); + assert!(!dst_layout.ty.has_erasable_regions()); let place = PlaceRef::alloca(bx, dst_layout); place.storage_live(bx); self.codegen_transmute_into(bx, src, place); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 1ef863e84af7f..814e4d626e119 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -209,7 +209,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let mut allocate_local = |local| { let decl = &mir.local_decls[local]; let layout = bx.layout_of(fx.monomorphize(decl.ty)); - assert!(!layout.ty.has_erasable_regions(cx.tcx())); + assert!(!layout.ty.has_erasable_regions()); if local == mir::RETURN_PLACE && fx.fn_abi.ret.is_indirect() { debug!("alloc: {:?} (return place) -> place", local); diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index dfec4509685f6..e9c94c0cc434c 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -568,7 +568,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)), ty::ConstKind::Unevaluated(uv) => { - let instance = self.resolve(uv.def, uv.substs(*self.tcx))?; + let instance = self.resolve(uv.def, uv.substs)?; Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) } ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => { diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index a16388d5de219..3dde34a64103e 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -9,7 +9,7 @@ where T: TypeFoldable<'tcx>, { debug!("ensure_monomorphic_enough: ty={:?}", ty); - if !ty.potentially_needs_subst() { + if !ty.needs_subst() { return Ok(()); } @@ -21,12 +21,8 @@ where impl<'tcx> TypeVisitor<'tcx> for UsedParamsNeedSubstVisitor<'tcx> { type BreakTy = FoundParam; - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { - if !ty.potentially_needs_subst() { + if !ty.needs_subst() { return ControlFlow::CONTINUE; } @@ -44,7 +40,7 @@ where let is_used = unused_params.contains(index).map_or(true, |unused| !unused); // Only recurse when generic parameters in fns, closures and generators // are used and require substitution. - match (is_used, subst.definitely_needs_subst(self.tcx)) { + match (is_used, subst.needs_subst()) { // Just in case there are closures or generators within this subst, // recurse. (true, true) => return subst.super_visit_with(self), diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index de4824eb667c4..e3a5253b876a8 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -348,7 +348,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { fn check_local_or_return_ty(&mut self, ty: Ty<'tcx>, local: Local) { let kind = self.body.local_kind(local); - for ty in ty.walk(self.tcx) { + for ty in ty.walk() { let ty = match ty.unpack() { GenericArgKind::Type(ty) => ty, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 27f2da34262a1..e5504497e34f6 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -338,7 +338,7 @@ where // Check the qualifs of the value of `const` items. if let Some(ct) = constant.literal.const_for_ty() { - if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs_: _, promoted }) = ct.val { + if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.val { // Use qualifs of the type for the promoted. Promoteds in MIR body should be possible // only for `NeedsNonConstDrop` with precise drop checking. This is the only const // check performed after the promotion. Verify that with an assertion. diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 55fba5d7ddf69..ac282a5ecc82c 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -843,17 +843,13 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { ty, val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, - 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) - } - }, - )), + 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) + } + }), promoted: Some(promoted_id), }), }) @@ -969,7 +965,6 @@ pub fn promote_candidates<'tcx>( scope.parent_scope = None; let promoted = Body::new( - tcx, body.source, // `promoted` gets filled in below IndexVec::new(), IndexVec::from_elem_n(scope, 1), diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 6023973665360..0e267179e3099 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -470,7 +470,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { { let needs_canonical_flags = if canonicalize_region_mode.any() { TypeFlags::NEEDS_INFER | - TypeFlags::HAS_POTENTIAL_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_POTENTIAL_FREE_REGIONS` + TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS` TypeFlags::HAS_TY_PLACEHOLDER | TypeFlags::HAS_CT_PLACEHOLDER } else { diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index da71edbd2d941..a77fd8fae8d20 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -129,8 +129,6 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { where R: ConstEquateRelation<'tcx>, { - let a = self.tcx.expose_default_const_substs(a); - let b = self.tcx.expose_default_const_substs(b); debug!("{}.consts({:?}, {:?})", relation.tag(), a, b); if a == b { return Ok(a); @@ -746,9 +744,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } } } - ty::ConstKind::Unevaluated(uv) if self.tcx().lazy_normalization() => { - assert_eq!(uv.promoted, None); - let substs = uv.substs(self.tcx()); + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if self.tcx().lazy_normalization() => + { + assert_eq!(promoted, None); let substs = self.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), @@ -757,7 +756,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { )?; Ok(self.tcx().mk_const(ty::Const { ty: c.ty, - val: ty::ConstKind::Unevaluated(ty::Unevaluated::new(uv.def, substs)), + val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }), })) } _ => relate::super_relate_consts(self, c, c), @@ -991,9 +990,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } } - ty::ConstKind::Unevaluated(uv) if self.tcx().lazy_normalization() => { - assert_eq!(uv.promoted, None); - let substs = uv.substs(self.tcx()); + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if self.tcx().lazy_normalization() => + { + assert_eq!(promoted, None); let substs = self.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), @@ -1002,7 +1002,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { )?; Ok(self.tcx().mk_const(ty::Const { ty: c.ty, - val: ty::ConstKind::Unevaluated(ty::Unevaluated::new(uv.def, substs)), + val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }), })) } _ => relate::super_relate_consts(self, c, c), diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 6d39dadc7ba3f..7aba41e81e166 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1550,10 +1550,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(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/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 8bb0e8b960ca5..bd94744b66714 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -52,7 +52,7 @@ impl<'a, 'tcx> FindHirNodeVisitor<'a, 'tcx> { fn node_ty_contains_target(&self, hir_id: HirId) -> Option> { self.node_type_opt(hir_id).map(|ty| self.infcx.resolve_vars_if_possible(ty)).filter(|ty| { - ty.walk(self.infcx.tcx).any(|inner| { + ty.walk().any(|inner| { inner == self.target || match (inner.unpack(), self.target.unpack()) { (GenericArgKind::Type(inner_ty), GenericArgKind::Type(target_ty)) => { @@ -445,9 +445,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { parent: None, } } - ty::ConstKind::Unevaluated(ty::Unevaluated { - substs_: Some(substs), .. - }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { substs, .. }) => { assert!(substs.has_infer_types_or_consts()); // FIXME: We only use the first inference variable we encounter in 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 b6dff2e53e9cd..fb1a7d16adcb7 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 @@ -557,12 +557,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { pub(super) struct TraitObjectVisitor(pub(super) FxHashSet); impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor { - fn tcx_for_anon_const_substs(&self) -> Option> { - // The default anon const substs cannot include - // trait objects, so we don't have to bother looking. - None - } - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Dynamic(preds, RegionKind::ReStatic) => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index f5fb82dbf31d2..cd6b51195e491 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -80,26 +80,21 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // Mark all unnamed regions in the type with a number. // This diagnostic is called in response to lifetime errors, so be informative. - struct HighlightBuilder<'tcx> { + struct HighlightBuilder { highlight: RegionHighlightMode, - tcx: TyCtxt<'tcx>, counter: usize, } - impl<'tcx> HighlightBuilder<'tcx> { - fn build(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> RegionHighlightMode { + impl HighlightBuilder { + fn build(ty: Ty<'_>) -> RegionHighlightMode { let mut builder = - HighlightBuilder { highlight: RegionHighlightMode::default(), counter: 1, tcx }; + HighlightBuilder { highlight: RegionHighlightMode::default(), counter: 1 }; builder.visit_ty(ty); builder.highlight } } - impl<'tcx> ty::fold::TypeVisitor<'tcx> for HighlightBuilder<'tcx> { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - + impl<'tcx> ty::fold::TypeVisitor<'tcx> for HighlightBuilder { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { if !r.has_name() && self.counter <= 3 { self.highlight.highlighting_region(r, self.counter); @@ -109,12 +104,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } } - let expected_highlight = HighlightBuilder::build(self.tcx(), expected); + let expected_highlight = HighlightBuilder::build(expected); let expected = self .infcx .extract_inference_diagnostics_data(expected.into(), Some(expected_highlight)) .name; - let found_highlight = HighlightBuilder::build(self.tcx(), found); + let found_highlight = HighlightBuilder::build(found); let found = self.infcx.extract_inference_diagnostics_data(found.into(), Some(found_highlight)).name; diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index c40e409891bc2..4af1bdf97a773 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -146,7 +146,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !t.needs_infer() && !t.has_erasable_regions(self.tcx()) { + if !t.needs_infer() && !t.has_erasable_regions() { return t; } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index d3664e53447d0..39822d1af7d17 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -668,10 +668,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// canonicalizing the consts. pub fn try_unify_abstract_consts( &self, - a: ty::Unevaluated<'tcx, ()>, - b: ty::Unevaluated<'tcx, ()>, + a: ty::Unevaluated<'tcx>, + b: ty::Unevaluated<'tcx>, ) -> bool { - let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default()); + let canonical = self.canonicalize_query( + ((a.def, a.substs), (b.def, b.substs)), + &mut OriginalQueryValues::default(), + ); debug!("canonical consts: {:?}", &canonical.value); self.tcx.try_unify_abstract_consts(canonical.value) @@ -1585,8 +1588,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { unevaluated: ty::Unevaluated<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { - let mut substs = unevaluated.substs(self.tcx); - substs = self.resolve_vars_if_possible(substs); + let substs = self.resolve_vars_if_possible(unevaluated.substs); // Postpone the evaluation of constants whose substs depend on inference // variables @@ -1599,7 +1601,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let unevaluated = ty::Unevaluated { def: unevaluated.def, - substs_: Some(substs_erased), + substs: substs_erased, promoted: unevaluated.promoted, }; diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index ebc0e80cdf267..0a210ed053ce4 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -201,7 +201,6 @@ 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, @@ -759,7 +758,6 @@ 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, @@ -767,10 +765,6 @@ struct ScopeInstantiator<'me, 'tcx> { } impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - fn visit_binder>( &mut self, t: &ty::Binder<'tcx, T>, diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 04b1a42e5beef..5da64c49ff088 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -316,7 +316,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { - tcx: self.tcx, op: |r| { self.member_constraint( opaque_type_key.def_id, @@ -368,19 +367,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // // We ignore any type parameters because impl trait values are assumed to // capture all the in-scope type parameters. -struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP> { - tcx: TyCtxt<'tcx>, +struct ConstrainOpaqueTypeRegionVisitor { op: OP, } -impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP> +impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor where OP: FnMut(ty::Region<'tcx>), { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - fn visit_binder>( &mut self, t: &ty::Binder<'tcx, T>, @@ -402,7 +396,7 @@ where fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { // We're only interested in types involving regions - if !ty.flags().intersects(ty::TypeFlags::HAS_POTENTIAL_FREE_REGIONS) { + if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) { return ControlFlow::CONTINUE; } diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index 22e18deac25e4..fbf149a4788e3 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -196,7 +196,7 @@ fn compute_components_recursive<'tcx>( out: &mut SmallVec<[Component<'tcx>; 4]>, visited: &mut SsoHashSet>, ) { - for child in parent.walk_shallow(tcx, visited) { + for child in parent.walk_shallow(visited) { match child.unpack() { GenericArgKind::Type(ty) => { compute_components(tcx, ty, out, visited); diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index dba73251b4f0d..f69212c599b62 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -189,7 +189,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { visited: &mut SsoHashSet>, ) -> VerifyBound<'tcx> { let mut bounds = parent - .walk_shallow(self.tcx, visited) + .walk_shallow(visited) .filter_map(|child| match child.unpack() { GenericArgKind::Type(ty) => Some(self.type_bound(ty, visited)), GenericArgKind::Lifetime(lt) => { diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index f036e1214aaf7..744599113849b 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -126,11 +126,6 @@ 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) -> Option> { - Some(self.infcx.tcx) - } - 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/builtin.rs b/compiler/rustc_lint/src/builtin.rs index c0384875a47c9..43389a2b0771a 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -152,8 +152,8 @@ declare_lint! { declare_lint_pass!(BoxPointers => [BOX_POINTERS]); impl BoxPointers { - fn check_heap_type<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { - for leaf in ty.walk(cx.tcx) { + fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) { + for leaf in ty.walk() { if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { if leaf_ty.is_box() { cx.struct_span_lint(BOX_POINTERS, span, |lint| { @@ -1663,7 +1663,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { ConstEquate(..) | TypeWellFormedFromEnv(..) => continue, }; - if predicate.is_global(cx.tcx) { + if predicate.is_global() { cx.struct_span_lint(TRIVIAL_BOUNDS, span, |lint| { lint.build(&format!( "{} bound {} does not depend on any type \ diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs index 65772d02376d4..c5e15a88fdf1c 100644 --- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs +++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs @@ -38,7 +38,7 @@ declare_lint_pass!(EnumIntrinsicsNonEnums => [ENUM_INTRINSICS_NON_ENUMS]); /// Returns `true` if we know for sure that the given type is not an enum. Note that for cases where /// the type is generic, we can't be certain if it will be an enum so we have to assume that it is. fn is_non_enum(t: Ty<'_>) -> bool { - !t.is_enum() && !t.potentially_needs_subst() + !t.is_enum() && !t.needs_subst() } fn enforce_mem_discriminant( diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 600504f7c1280..4bcd4c6d6038d 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { _ => return, }; let substs = cx.typeck_results().node_substs(expr.hir_id); - if substs.definitely_needs_subst(cx.tcx) { + if substs.needs_subst() { // We can't resolve on types that require monomorphization, so we don't handle them if // we need to perfom substitution. return; diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 32ed6dad7f8c3..1acff13d1aa33 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1175,9 +1175,6 @@ 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) -> Option> { - Some(self.cx.tcx) - } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { match ty.kind() { diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index f983185563315..ec0f5b7d0595c 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(self)) { + match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { 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/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 6d1d9dd9720d4..b2a590a18eb6c 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -288,7 +288,6 @@ pub struct Body<'tcx> { impl<'tcx> Body<'tcx> { pub fn new( - tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, basic_blocks: IndexVec>, source_scopes: IndexVec>, @@ -331,7 +330,7 @@ impl<'tcx> Body<'tcx> { predecessor_cache: PredecessorCache::new(), is_cyclic: GraphIsCyclicCache::new(), }; - body.is_polymorphic = body.definitely_has_param_types_or_consts(tcx); + body.is_polymorphic = body.has_param_types_or_consts(); body } @@ -341,7 +340,7 @@ impl<'tcx> Body<'tcx> { /// is only useful for testing but cannot be `#[cfg(test)]` because it is used in a different /// crate. pub fn new_cfg_only(basic_blocks: IndexVec>) -> Self { - Body { + let mut body = Body { phase: MirPhase::Build, source: MirSource::item(DefId::local(CRATE_DEF_INDEX)), basic_blocks, @@ -357,7 +356,9 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, predecessor_cache: PredecessorCache::new(), is_cyclic: GraphIsCyclicCache::new(), - } + }; + body.is_polymorphic = body.has_param_types_or_consts(); + body } #[inline] diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 8cc705384b03e..f2ad591071114 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -476,8 +476,8 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { ty::ConstKind::Unevaluated(uv) => format!( "Unevaluated({}, {:?}, {:?})", self.tcx.def_path_str(uv.def.did), - uv.substs(self.tcx), - uv.promoted + uv.substs, + uv.promoted, ), ty::ConstKind::Value(val) => format!("Value({:?})", val), ty::ConstKind::Error(_) => "Error".to_string(), @@ -683,12 +683,6 @@ pub fn write_allocations<'tcx>( } struct CollectAllocIds(BTreeSet); impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds { - fn tcx_for_anon_const_substs(&self) -> Option> { - // `AllocId`s are only inside of `ConstKind::Value` which - // can't be part of the anon const default substs. - None - } - 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_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3772f1c9feab0..73bda1337b679 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -110,10 +110,6 @@ rustc_queries! { separate_provide_extern } - 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| @@ -318,11 +314,12 @@ rustc_queries! { } query try_unify_abstract_consts(key: ( - ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()> + (ty::WithOptConstParam, SubstsRef<'tcx>), + (ty::WithOptConstParam, SubstsRef<'tcx>) )) -> bool { desc { |tcx| "trying to unify the generic constants {} and {}", - tcx.def_path_str(key.0.def.did), tcx.def_path_str(key.1.def.did) + tcx.def_path_str(key.0.0.did), tcx.def_path_str(key.1.0.did) } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 27e22ccac02a7..644289d16f1c8 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -61,7 +61,7 @@ impl<'tcx> Const<'tcx> { None => tcx.mk_const(ty::Const { val: ty::ConstKind::Unevaluated(ty::Unevaluated { def: def.to_global(), - substs_: None, + substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), promoted: None, }), ty, @@ -153,14 +153,14 @@ impl<'tcx> Const<'tcx> { tcx.mk_const(ty::Const { val: ty::ConstKind::Unevaluated(ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id).to_global(), - substs_: Some(substs), + substs, promoted: None, }), ty, }) } }; - debug_assert!(!ret.has_free_regions(tcx)); + debug_assert!(!ret.has_free_regions()); ret } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 7188eed544551..f2db95d162b88 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -1,5 +1,4 @@ use std::convert::TryInto; -use std::fmt; use crate::mir::interpret::{AllocId, ConstValue, Scalar}; use crate::mir::Promoted; @@ -13,53 +12,12 @@ use rustc_target::abi::Size; use super::ScalarInt; /// An unevaluated, potentially generic, constant. -/// -/// If `substs_` is `None` it means that this anon const -/// still has its default substs. -/// -/// We check for all possible substs in `fn default_anon_const_substs`, -/// so refer to that check for more info. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Hash, HashStable)] -pub struct Unevaluated<'tcx, P = Option> { +pub struct Unevaluated<'tcx> { pub def: ty::WithOptConstParam, - pub substs_: Option>, - pub promoted: P, -} - -impl<'tcx> Unevaluated<'tcx> { - #[inline] - pub fn shrink(self) -> Unevaluated<'tcx, ()> { - debug_assert_eq!(self.promoted, None); - Unevaluated { def: self.def, substs_: self.substs_, promoted: () } - } -} - -impl<'tcx> Unevaluated<'tcx, ()> { - #[inline] - pub fn expand(self) -> Unevaluated<'tcx> { - Unevaluated { def: self.def, substs_: self.substs_, promoted: None } - } -} - -impl<'tcx, P: Default> Unevaluated<'tcx, P> { - #[inline] - pub fn new(def: ty::WithOptConstParam, substs: SubstsRef<'tcx>) -> Unevaluated<'tcx, P> { - Unevaluated { def, substs_: Some(substs), promoted: Default::default() } - } -} - -impl<'tcx, P: Default + PartialEq + fmt::Debug> Unevaluated<'tcx, P> { - #[inline] - pub fn substs(self, tcx: TyCtxt<'tcx>) -> SubstsRef<'tcx> { - self.substs_.unwrap_or_else(|| { - // We must not use the parents default substs for promoted constants - // as that can result in incorrect substs and calls the `default_anon_const_substs` - // for something that might not actually be a constant. - debug_assert_eq!(self.promoted, Default::default()); - tcx.default_anon_const_substs(self.def.did) - }) - } + pub substs: SubstsRef<'tcx>, + pub promoted: Option, } /// Represents a constant in Rust. @@ -151,7 +109,7 @@ impl<'tcx> ConstKind<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ) -> Option, ErrorReported>> { - if let ConstKind::Unevaluated(unevaluated) = 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` @@ -160,32 +118,29 @@ 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 = tcx + let param_env_and_substs = tcx .erase_regions(param_env) .with_reveal_all_normalized(tcx) - .and(tcx.erase_regions(unevaluated)); + .and(tcx.erase_regions(substs)); // 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 = if param_env_and.needs_infer() { - tcx.param_env(unevaluated.def.did).and(ty::Unevaluated { - def: unevaluated.def, - substs_: Some(InternalSubsts::identity_for_item(tcx, unevaluated.def.did)), - promoted: unevaluated.promoted, - }) + 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)) } else { - param_env_and + param_env_and_substs }; // FIXME(eddyb) maybe the `const_eval_*` methods should take - // `ty::ParamEnvAnd` instead of having them separate. - let (param_env, unevaluated) = param_env_and.into_parts(); + // `ty::ParamEnvAnd` instead of having them separate. + 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, unevaluated, 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_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 0d290752e8fd8..ef4f77c8a69e1 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -21,9 +21,7 @@ impl<'tcx> TyCtxt<'tcx> { T: TypeFoldable<'tcx>, { // If there's nothing to erase avoid performing the query at all - if !value - .has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_POTENTIAL_FREE_REGIONS) - { + if !value.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { return value; } debug!("erase_regions({:?})", value); diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 617c522ac8197..cc858771b423a 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -34,12 +34,6 @@ impl FlagComputation { result.flags } - pub fn for_unevaluated_const(uv: ty::Unevaluated<'_>) -> TypeFlags { - let mut result = FlagComputation::new(); - result.add_unevaluated_const(uv); - result.flags - } - fn add_flags(&mut self, flags: TypeFlags) { self.flags = self.flags | flags; } @@ -97,7 +91,7 @@ impl FlagComputation { &ty::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), &ty::Param(_) => { - self.add_flags(TypeFlags::HAS_KNOWN_TY_PARAM); + self.add_flags(TypeFlags::HAS_TY_PARAM); self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } @@ -252,8 +246,8 @@ impl FlagComputation { ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => { self.add_substs(substs); } - ty::PredicateKind::ConstEvaluatable(uv) => { - self.add_unevaluated_const(uv); + ty::PredicateKind::ConstEvaluatable(_def_id, substs) => { + self.add_substs(substs); } ty::PredicateKind::ConstEquate(expected, found) => { self.add_const(expected); @@ -298,7 +292,7 @@ impl FlagComputation { self.add_bound_var(debruijn); } ty::ConstKind::Param(_) => { - self.add_flags(TypeFlags::HAS_KNOWN_CT_PARAM); + self.add_flags(TypeFlags::HAS_CT_PARAM); self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Placeholder(_) => { @@ -310,24 +304,8 @@ impl FlagComputation { } } - fn add_unevaluated_const

(&mut self, ct: ty::Unevaluated<'_, P>) { - // The generic arguments of unevaluated consts are a bit special, - // see the `rustc-dev-guide` for more information. - // - // FIXME(@lcnr): Actually add a link here. - if let Some(substs) = ct.substs_ { - // If they are available, we treat them as ordinary generic arguments. - self.add_substs(substs); - } else { - // Otherwise, we add `HAS_UNKNOWN_DEFAULT_CONST_SUBSTS` to signify - // that our const may potentially refer to generic parameters. - // - // Note that depending on which generic parameters are actually - // used in this constant, we may not actually refer to any generic - // parameters at all. - self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); - self.add_flags(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS); - } + fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'_>) { + self.add_substs(ct.substs); self.add_flags(TypeFlags::HAS_CT_PROJECTION); } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index f5be8b21e8aca..1288b6e1a8b07 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -95,15 +95,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { self.has_vars_bound_at_or_above(ty::INNERMOST) } - fn definitely_has_type_flags(&self, tcx: TyCtxt<'tcx>, flags: TypeFlags) -> bool { - self.visit_with(&mut HasTypeFlagsVisitor { tcx: Some(tcx), flags }).break_value() - == Some(FoundFlags) - } - #[instrument(level = "trace")] fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.visit_with(&mut HasTypeFlagsVisitor { tcx: None, flags }).break_value() - == Some(FoundFlags) + self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags) } fn has_projections(&self) -> bool { self.has_type_flags(TypeFlags::HAS_PROJECTION) @@ -114,18 +108,8 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn references_error(&self) -> bool { self.has_type_flags(TypeFlags::HAS_ERROR) } - fn potentially_has_param_types_or_consts(&self) -> bool { - self.has_type_flags( - TypeFlags::HAS_KNOWN_TY_PARAM - | TypeFlags::HAS_KNOWN_CT_PARAM - | TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS, - ) - } - fn definitely_has_param_types_or_consts(&self, tcx: TyCtxt<'tcx>) -> bool { - self.definitely_has_type_flags( - tcx, - TypeFlags::HAS_KNOWN_TY_PARAM | TypeFlags::HAS_KNOWN_CT_PARAM, - ) + fn has_param_types_or_consts(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM) } fn has_infer_regions(&self) -> bool { self.has_type_flags(TypeFlags::HAS_RE_INFER) @@ -146,18 +130,13 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { | TypeFlags::HAS_CT_PLACEHOLDER, ) } - fn potentially_needs_subst(&self) -> bool { - self.has_type_flags( - TypeFlags::KNOWN_NEEDS_SUBST | TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS, - ) - } - fn definitely_needs_subst(&self, tcx: TyCtxt<'tcx>) -> bool { - self.definitely_has_type_flags(tcx, TypeFlags::KNOWN_NEEDS_SUBST) + fn needs_subst(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_SUBST) } /// "Free" regions in this context means that it has any region /// that is not (a) erased or (b) late-bound. - fn has_free_regions(&self, tcx: TyCtxt<'tcx>) -> bool { - self.definitely_has_type_flags(tcx, TypeFlags::HAS_KNOWN_FREE_REGIONS) + fn has_free_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) } fn has_erased_regions(&self) -> bool { @@ -165,25 +144,15 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { } /// True if there are any un-erased free regions. - fn has_erasable_regions(&self, tcx: TyCtxt<'tcx>) -> bool { - self.definitely_has_type_flags(tcx, TypeFlags::HAS_KNOWN_FREE_REGIONS) - } - - /// Indicates whether this value definitely references only 'global' - /// generic parameters that are the same regardless of what fn we are - /// in. This is used for caching. - /// - /// Note that this function is pessimistic and may incorrectly return - /// `false`. - fn is_known_global(&self) -> bool { - !self.has_type_flags(TypeFlags::HAS_POTENTIAL_FREE_LOCAL_NAMES) + fn has_erasable_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) } /// Indicates whether this value references only 'global' /// generic parameters that are the same regardless of what fn we are /// in. This is used for caching. - fn is_global(&self, tcx: TyCtxt<'tcx>) -> bool { - !self.definitely_has_type_flags(tcx, TypeFlags::HAS_KNOWN_FREE_LOCAL_NAMES) + fn is_global(&self) -> bool { + !self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES) } /// True if there are any late-bound regions @@ -361,17 +330,6 @@ where pub trait TypeVisitor<'tcx>: Sized { type BreakTy = !; - /// Supplies the `tcx` for an unevaluated anonymous constant in case its default substs - /// are not yet supplied. - /// - /// Returning `None` for this method is only recommended if the `TypeVisitor` - /// does not care about default anon const substs, as it ignores generic parameters, - /// and fetching the default substs would cause a query cycle. - /// - /// For visitors which return `None` we completely skip the default substs in `ty::Unevaluated::super_visit_with`. - /// This means that incorrectly returning `None` can very quickly lead to ICE or other critical bugs, so be careful and - /// try to return an actual `tcx` if possible. - fn tcx_for_anon_const_substs(&self) -> Option>; fn visit_binder>( &mut self, @@ -392,10 +350,6 @@ pub trait TypeVisitor<'tcx>: Sized { c.super_visit_with(self) } - fn visit_unevaluated_const(&mut self, uv: ty::Unevaluated<'tcx>) -> ControlFlow { - uv.super_visit_with(self) - } - fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow { p.super_visit_with(self) } @@ -488,8 +442,7 @@ impl<'tcx> TyCtxt<'tcx> { value: &impl TypeFoldable<'tcx>, callback: impl FnMut(ty::Region<'tcx>) -> bool, ) -> bool { - struct RegionVisitor<'tcx, F> { - tcx: TyCtxt<'tcx>, + struct RegionVisitor { /// 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: @@ -511,16 +464,12 @@ impl<'tcx> TyCtxt<'tcx> { callback: F, } - impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<'tcx, F> + impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor where F: FnMut(ty::Region<'tcx>) -> bool, { type BreakTy = (); - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - fn visit_binder>( &mut self, t: &Binder<'tcx, T>, @@ -548,7 +497,7 @@ impl<'tcx> TyCtxt<'tcx> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { // We're only interested in types involving regions - if ty.flags().intersects(TypeFlags::HAS_POTENTIAL_FREE_REGIONS) { + if ty.flags().intersects(TypeFlags::HAS_FREE_REGIONS) { ty.super_visit_with(self) } else { ControlFlow::CONTINUE @@ -556,9 +505,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - value - .visit_with(&mut RegionVisitor { tcx: self, outer_index: ty::INNERMOST, callback }) - .is_break() + value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback }).is_break() } } @@ -897,7 +844,7 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable<'tcx>, { - let mut collector = LateBoundRegionsCollector::new(self, just_constraint); + let mut collector = LateBoundRegionsCollector::new(just_constraint); let result = value.as_ref().skip_binder().visit_with(&mut collector); assert!(result.is_continue()); // should never have stopped early collector.regions @@ -964,11 +911,6 @@ impl<'tcx> ValidateBoundVars<'tcx> { impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { type BreakTy = (); - fn tcx_for_anon_const_substs(&self) -> Option> { - // Anonymous constants do not contain bound vars in their substs by default. - None - } - fn visit_binder>( &mut self, t: &Binder<'tcx, T>, @@ -1183,11 +1125,6 @@ struct HasEscapingVarsVisitor { impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { type BreakTy = FoundEscapingVars; - fn tcx_for_anon_const_substs(&self) -> Option> { - // Anonymous constants do not contain bound vars in their substs by default. - None - } - fn visit_binder>( &mut self, t: &Binder<'tcx, T>, @@ -1252,35 +1189,32 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { struct FoundFlags; // FIXME: Optimize for checking for infer flags -struct HasTypeFlagsVisitor<'tcx> { - tcx: Option>, +struct HasTypeFlagsVisitor { flags: ty::TypeFlags, } -impl<'tcx> std::fmt::Debug for HasTypeFlagsVisitor<'tcx> { +impl std::fmt::Debug for HasTypeFlagsVisitor { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.flags.fmt(fmt) } } -impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> { +impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { type BreakTy = FoundFlags; - fn tcx_for_anon_const_substs(&self) -> Option> { - bug!("we shouldn't call this method as we manually look at ct substs"); - } #[inline] #[instrument(level = "trace")] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - let flags = t.flags(); - trace!(t.flags=?t.flags()); - if flags.intersects(self.flags) { + fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow { + debug!( + "HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", + t, + t.flags(), + self.flags + ); + if t.flags().intersects(self.flags) { ControlFlow::Break(FoundFlags) } else { - match flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { - true if self.tcx.is_some() => UnknownConstSubstsVisitor::search(&self, t), - _ => ControlFlow::CONTINUE, - } + ControlFlow::CONTINUE } } @@ -1304,143 +1238,28 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> { if flags.intersects(self.flags) { ControlFlow::Break(FoundFlags) } else { - match flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { - true if self.tcx.is_some() => UnknownConstSubstsVisitor::search(&self, c), - _ => ControlFlow::CONTINUE, - } - } - } - - #[inline] - #[instrument(level = "trace")] - fn visit_unevaluated_const(&mut self, uv: ty::Unevaluated<'tcx>) -> ControlFlow { - let flags = FlagComputation::for_unevaluated_const(uv); - trace!(r.flags=?flags); - if flags.intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - match flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { - true if self.tcx.is_some() => UnknownConstSubstsVisitor::search(&self, uv), - _ => ControlFlow::CONTINUE, - } + ControlFlow::CONTINUE } } #[inline] #[instrument(level = "trace")] fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow { - let flags = predicate.inner.flags; - trace!(predicate.flags=?flags); - if flags.intersects(self.flags) { + debug!( + "HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}", + predicate, predicate.inner.flags, self.flags + ); + if predicate.inner.flags.intersects(self.flags) { ControlFlow::Break(FoundFlags) - } else { - match flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { - true if self.tcx.is_some() => UnknownConstSubstsVisitor::search(&self, predicate), - _ => ControlFlow::CONTINUE, - } - } - } -} - -struct UnknownConstSubstsVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - flags: ty::TypeFlags, -} - -impl<'tcx> UnknownConstSubstsVisitor<'tcx> { - /// This is fairly cold and we don't want to - /// bloat the size of the `HasTypeFlagsVisitor`. - #[inline(never)] - pub fn search>( - visitor: &HasTypeFlagsVisitor<'tcx>, - v: T, - ) -> ControlFlow { - if visitor.flags.intersects(TypeFlags::MAY_NEED_DEFAULT_CONST_SUBSTS) { - v.super_visit_with(&mut UnknownConstSubstsVisitor { - tcx: visitor.tcx.unwrap(), - flags: visitor.flags, - }) } else { ControlFlow::CONTINUE } } } -impl<'tcx> TypeVisitor<'tcx> for UnknownConstSubstsVisitor<'tcx> { - type BreakTy = FoundFlags; - fn tcx_for_anon_const_substs(&self) -> Option> { - bug!("we shouldn't call this method as we manually look at ct substs"); - } - - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - if t.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { - t.super_visit_with(self) - } else { - ControlFlow::CONTINUE - } - } - - #[inline] - fn visit_unevaluated_const(&mut self, uv: ty::Unevaluated<'tcx>) -> ControlFlow { - if uv.substs_.is_none() { - self.tcx - .default_anon_const_substs(uv.def.did) - .visit_with(&mut HasTypeFlagsVisitor { tcx: Some(self.tcx), flags: self.flags }) - } else { - ControlFlow::CONTINUE - } - } - - #[inline] - fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow { - if predicate.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { - predicate.super_visit_with(self) - } else { - ControlFlow::CONTINUE - } - } -} - -impl<'tcx> TyCtxt<'tcx> { - /// This is a HACK(const_generics) and should probably not be needed. - /// Might however be perf relevant, so who knows. - /// - /// FIXME(@lcnr): explain this function a bit more - pub fn expose_default_const_substs>(self, v: T) -> T { - v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }) - } -} - -struct ExposeDefaultConstSubstsFolder<'tcx> { - tcx: TyCtxt<'tcx>, -} - -impl<'tcx> TypeFolder<'tcx> for ExposeDefaultConstSubstsFolder<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if ty.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { - ty.super_fold_with(self) - } else { - ty - } - } - - fn fold_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { - if pred.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { - pred.super_fold_with(self) - } else { - pred - } - } -} - /// Collects all the late-bound regions at the innermost binding level /// into a hash set. -struct LateBoundRegionsCollector<'tcx> { - tcx: TyCtxt<'tcx>, +struct LateBoundRegionsCollector { current_index: ty::DebruijnIndex, regions: FxHashSet, @@ -1454,10 +1273,9 @@ struct LateBoundRegionsCollector<'tcx> { just_constrained: bool, } -impl<'tcx> LateBoundRegionsCollector<'tcx> { - fn new(tcx: TyCtxt<'tcx>, just_constrained: bool) -> Self { +impl LateBoundRegionsCollector { + fn new(just_constrained: bool) -> Self { LateBoundRegionsCollector { - tcx, current_index: ty::INNERMOST, regions: Default::default(), just_constrained, @@ -1465,11 +1283,7 @@ impl<'tcx> LateBoundRegionsCollector<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector<'tcx> { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - +impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { fn visit_binder>( &mut self, t: &Binder<'tcx, T>, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 4e6b2acb67f91..caf33fa5d213b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1769,9 +1769,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Ignore layouts that are done with non-empty environments or // non-monomorphic layouts, as the user only wants to see the stuff // resulting from the final codegen session. - if layout.ty.definitely_has_param_types_or_consts(self.tcx) - || !self.param_env.caller_bounds().is_empty() - { + if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds().is_empty() { return; } @@ -1936,7 +1934,7 @@ impl<'tcx> SizeSkeleton<'tcx> { let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env); match tail.kind() { ty::Param(_) | ty::Projection(_) => { - debug_assert!(tail.definitely_has_param_types_or_consts(tcx)); + debug_assert!(tail.has_param_types_or_consts()); Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) }) } _ => bug!( diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f1868459f2702..8d3dab7c6b3be 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -598,7 +598,7 @@ pub enum PredicateKind<'tcx> { Coerce(CoercePredicate<'tcx>), /// Constant initializer must evaluate successfully. - ConstEvaluatable(ty::Unevaluated<'tcx, ()>), + ConstEvaluatable(ty::WithOptConstParam, SubstsRef<'tcx>), /// Constants must be equal. The first component is the const that is expected. ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>), @@ -1417,7 +1417,7 @@ impl<'tcx> ParamEnv<'tcx> { Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, Reveal::All => { - if value.is_known_global() { + if value.is_global() { ParamEnvAnd { param_env: self.without_caller_bounds(), value } } else { ParamEnvAnd { param_env: self, value } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 350386f8d9317..f5d3861bab4c4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1153,28 +1153,29 @@ pub trait PrettyPrinter<'tcx>: } match ct.val { - ty::ConstKind::Unevaluated(uv) => { - if let Some(promoted) = uv.promoted { - let substs = uv.substs_.unwrap(); - p!(print_value_path(uv.def.did, substs)); - p!(write("::{:?}", promoted)); - } else { - let tcx = self.tcx(); - match tcx.def_kind(uv.def.did) { - DefKind::Static | DefKind::Const | DefKind::AssocConst => { - p!(print_value_path(uv.def.did, uv.substs(tcx))) - } - _ => { - if uv.def.is_local() { - let span = tcx.def_span(uv.def.did); - if let Ok(snip) = tcx.sess.source_map().span_to_snippet(span) { - p!(write("{}", snip)) - } else { - print_underscore!() - } + ty::ConstKind::Unevaluated(ty::Unevaluated { + def, + substs, + promoted: Some(promoted), + }) => { + p!(print_value_path(def.did, substs)); + p!(write("::{:?}", promoted)); + } + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) => { + match self.tcx().def_kind(def.did) { + DefKind::Static | DefKind::Const | DefKind::AssocConst => { + p!(print_value_path(def.did, substs)) + } + _ => { + if def.is_local() { + let span = self.tcx().def_span(def.did); + if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) { + p!(write("{}", snip)) } else { print_underscore!() } + } else { + print_underscore!() } } } @@ -1419,7 +1420,7 @@ pub trait PrettyPrinter<'tcx>: // Aggregates, printed as array/tuple/struct/variant construction syntax. // - // NB: the `potentially_has_param_types_or_consts` check ensures that we can use + // NB: the `has_param_types_or_consts` check ensures that we can use // the `destructure_const` query with an empty `ty::ParamEnv` without // introducing ICEs (e.g. via `layout_of`) from missing bounds. // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized` @@ -1427,9 +1428,7 @@ pub trait PrettyPrinter<'tcx>: // // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the // correct `ty::ParamEnv` to allow printing *all* constant values. - (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) - if !ty.potentially_has_param_types_or_consts() => - { + (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => { let contents = self.tcx().destructure_const( ty::ParamEnv::reveal_all() .and(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(ct), ty })), @@ -2246,7 +2245,6 @@ impl<'tcx, F: fmt::Write> FmtPrinter<'_, 'tcx, F> { T: TypeFoldable<'tcx>, { struct LateBoundRegionNameCollector<'a, 'tcx> { - tcx: TyCtxt<'tcx>, used_region_names: &'a mut FxHashSet, type_collector: SsoHashSet>, } @@ -2254,10 +2252,6 @@ impl<'tcx, F: fmt::Write> FmtPrinter<'_, 'tcx, F> { impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_, 'tcx> { type BreakTy = (); - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - #[instrument(skip(self), level = "trace")] fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { trace!("address: {:p}", r); @@ -2288,7 +2282,6 @@ impl<'tcx, F: fmt::Write> FmtPrinter<'_, 'tcx, F> { self.used_region_names.clear(); let mut collector = LateBoundRegionNameCollector { - tcx: self.tcx, used_region_names: &mut self.used_region_names, type_collector: SsoHashSet::new(), }; @@ -2546,8 +2539,8 @@ define_print_and_forward_display! { print_value_path(closure_def_id, &[]), write("` implements the trait `{}`", kind)) } - ty::PredicateKind::ConstEvaluatable(uv) => { - p!("the constant `", print_value_path(uv.def.did, uv.substs_.map_or(&[], |x| x)), "` can be evaluated") + ty::PredicateKind::ConstEvaluatable(def, substs) => { + p!("the constant `", print_value_path(def.did, substs), "` can be evaluated") } ty::PredicateKind::ConstEquate(c1, c2) => { p!("the constant `", print(c1), "` equals `", print(c2), "`") diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 63ed318cadb89..97b5d52ea38e4 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -587,7 +587,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if tcx.features().generic_const_exprs => { - tcx.try_unify_abstract_consts((au.shrink(), bu.shrink())) + tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs))) } // While this is slightly incorrect, it shouldn't matter for `min_const_generics` @@ -599,13 +599,13 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( let substs = relation.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), - au.substs(tcx), - bu.substs(tcx), + au.substs, + bu.substs, )?; return Ok(tcx.mk_const(ty::Const { val: ty::ConstKind::Unevaluated(ty::Unevaluated { def: au.def, - substs_: Some(substs), + substs, promoted: au.promoted, }), ty: a.ty, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index bb8c2b180e40e..1c49ceeb1535e 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -184,8 +184,8 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) } - ty::PredicateKind::ConstEvaluatable(uv) => { - write!(f, "ConstEvaluatable({:?}, {:?})", uv.def, uv.substs_) + ty::PredicateKind::ConstEvaluatable(def_id, substs) => { + write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) } ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2), ty::PredicateKind::TypeWellFormedFromEnv(ty) => { @@ -445,8 +445,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { ty::PredicateKind::ObjectSafe(trait_def_id) => { Some(ty::PredicateKind::ObjectSafe(trait_def_id)) } - ty::PredicateKind::ConstEvaluatable(uv) => { - tcx.lift(uv).map(|uv| ty::PredicateKind::ConstEvaluatable(uv)) + ty::PredicateKind::ConstEvaluatable(def_id, substs) => { + tcx.lift(substs).map(|substs| ty::PredicateKind::ConstEvaluatable(def_id, substs)) } ty::PredicateKind::ConstEquate(c1, c2) => { tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2)) @@ -1185,7 +1185,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { Ok(match self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?), - ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?), + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { + def, + substs: substs.try_fold_with(folder)?, + promoted, + }) + } ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) @@ -1197,7 +1203,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(uv) => uv.visit_with(visitor), + ty::ConstKind::Unevaluated(ct) => ct.substs.visit_with(visitor), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) @@ -1218,59 +1224,3 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { ControlFlow::CONTINUE } } - -impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { - fn try_super_fold_with>( - self, - folder: &mut F, - ) -> Result { - Ok(ty::Unevaluated { - def: self.def, - substs_: Some(self.substs(folder.tcx()).try_fold_with(folder)?), - promoted: self.promoted, - }) - } - - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - visitor.visit_unevaluated_const(*self) - } - - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { - if let Some(tcx) = visitor.tcx_for_anon_const_substs() { - self.substs(tcx).visit_with(visitor) - } else if let Some(substs) = self.substs_ { - substs.visit_with(visitor) - } else { - debug!("ignoring default substs of `{:?}`", self.def); - ControlFlow::CONTINUE - } - } -} - -impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> { - fn try_super_fold_with>( - self, - folder: &mut F, - ) -> Result { - Ok(ty::Unevaluated { - def: self.def, - substs_: Some(self.substs(folder.tcx()).try_fold_with(folder)?), - promoted: self.promoted, - }) - } - - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - visitor.visit_unevaluated_const(self.expand()) - } - - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { - if let Some(tcx) = visitor.tcx_for_anon_const_substs() { - self.substs(tcx).visit_with(visitor) - } else if let Some(substs) = self.substs_ { - substs.visit_with(visitor) - } else { - debug!("ignoring default substs of `{:?}`", self.def); - ControlFlow::CONTINUE - } - } -} diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0d37711d72e67..92fb7612688c0 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1642,26 +1642,26 @@ impl RegionKind { match *self { ty::ReVar(..) => { - flags = flags | TypeFlags::HAS_KNOWN_FREE_REGIONS; - flags = flags | TypeFlags::HAS_KNOWN_FREE_LOCAL_REGIONS; + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; flags = flags | TypeFlags::HAS_RE_INFER; } ty::RePlaceholder(..) => { - flags = flags | TypeFlags::HAS_KNOWN_FREE_REGIONS; - flags = flags | TypeFlags::HAS_KNOWN_FREE_LOCAL_REGIONS; + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; flags = flags | TypeFlags::HAS_RE_PLACEHOLDER; } ty::ReEarlyBound(..) => { - flags = flags | TypeFlags::HAS_KNOWN_FREE_REGIONS; - flags = flags | TypeFlags::HAS_KNOWN_FREE_LOCAL_REGIONS; - flags = flags | TypeFlags::HAS_KNOWN_RE_PARAM; + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; + flags = flags | TypeFlags::HAS_RE_PARAM; } ty::ReFree { .. } => { - flags = flags | TypeFlags::HAS_KNOWN_FREE_REGIONS; - flags = flags | TypeFlags::HAS_KNOWN_FREE_LOCAL_REGIONS; + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; } ty::ReEmpty(_) | ty::ReStatic => { - flags = flags | TypeFlags::HAS_KNOWN_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_REGIONS; } ty::ReLateBound(..) => { flags = flags | TypeFlags::HAS_RE_LATE_BOUND; diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index a71181149149d..ab33fbcca15a3 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -505,7 +505,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !t.potentially_needs_subst() { + if !t.needs_subst() { return t; } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index ba5775fd77376..6808316a23095 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -1,8 +1,8 @@ //! An iterator over the type substructure. //! WARNING: this does not keep track of the region depth. +use crate::ty; use crate::ty::subst::{GenericArg, GenericArgKind}; -use crate::ty::{self, TyCtxt}; use rustc_data_structures::sso::SsoHashSet; use smallvec::{self, SmallVec}; @@ -11,7 +11,6 @@ use smallvec::{self, SmallVec}; type TypeWalkerStack<'tcx> = SmallVec<[GenericArg<'tcx>; 8]>; pub struct TypeWalker<'tcx> { - expose_default_const_substs: Option>, stack: TypeWalkerStack<'tcx>, last_subtree: usize, pub visited: SsoHashSet>, @@ -26,13 +25,8 @@ pub struct TypeWalker<'tcx> { /// It maintains a set of visited types and /// skips any types that are already there. impl<'tcx> TypeWalker<'tcx> { - fn new(expose_default_const_substs: Option>, root: GenericArg<'tcx>) -> Self { - Self { - expose_default_const_substs, - stack: smallvec![root], - last_subtree: 1, - visited: SsoHashSet::new(), - } + pub fn new(root: GenericArg<'tcx>) -> Self { + Self { stack: smallvec![root], last_subtree: 1, visited: SsoHashSet::new() } } /// Skips the subtree corresponding to the last type @@ -61,7 +55,7 @@ impl<'tcx> Iterator for TypeWalker<'tcx> { let next = self.stack.pop()?; self.last_subtree = self.stack.len(); if self.visited.insert(next) { - push_inner(self.expose_default_const_substs, &mut self.stack, next); + push_inner(&mut self.stack, next); debug!("next: stack={:?}", self.stack); return Some(next); } @@ -80,8 +74,8 @@ impl<'tcx> GenericArg<'tcx> { /// Foo> => { Foo>, Bar, isize } /// [isize] => { [isize], isize } /// ``` - pub fn walk(self, tcx: TyCtxt<'tcx>) -> TypeWalker<'tcx> { - TypeWalker::new(Some(tcx), self) + pub fn walk(self) -> TypeWalker<'tcx> { + TypeWalker::new(self) } /// Iterator that walks the immediate children of `self`. Hence @@ -93,21 +87,16 @@ impl<'tcx> GenericArg<'tcx> { /// and skips any types that are already there. pub fn walk_shallow( self, - tcx: TyCtxt<'tcx>, visited: &mut SsoHashSet>, ) -> impl Iterator> { let mut stack = SmallVec::new(); - push_inner(Some(tcx), &mut stack, self); + push_inner(&mut stack, self); stack.retain(|a| visited.insert(*a)); stack.into_iter() } } impl<'tcx> super::TyS<'tcx> { - pub fn walk_ignoring_default_const_substs(&'tcx self) -> TypeWalker<'tcx> { - TypeWalker::new(None, self.into()) - } - /// Iterator that walks `self` and any types reachable from /// `self`, in depth-first order. Note that just walks the types /// that appear in `self`, it does not descend into the fields of @@ -118,8 +107,8 @@ impl<'tcx> super::TyS<'tcx> { /// Foo> => { Foo>, Bar, isize } /// [isize] => { [isize], isize } /// ``` - pub fn walk(&'tcx self, tcx: TyCtxt<'tcx>) -> TypeWalker<'tcx> { - TypeWalker::new(Some(tcx), self.into()) + pub fn walk(&'tcx self) -> TypeWalker<'tcx> { + TypeWalker::new(self.into()) } } @@ -129,11 +118,7 @@ impl<'tcx> super::TyS<'tcx> { /// known to be significant to any code, but it seems like the /// natural order one would expect (basically, the order of the /// types as they are written). -fn push_inner<'tcx>( - expose_default_const_substs: Option>, - stack: &mut TypeWalkerStack<'tcx>, - parent: GenericArg<'tcx>, -) { +fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) { match parent.unpack() { GenericArgKind::Type(parent_ty) => match *parent_ty.kind() { ty::Bool @@ -211,11 +196,7 @@ fn push_inner<'tcx>( | ty::ConstKind::Error(_) => {} ty::ConstKind::Unevaluated(ct) => { - if let Some(tcx) = expose_default_const_substs { - stack.extend(ct.substs(tcx).iter().rev()); - } else if let Some(substs) = ct.substs_ { - stack.extend(substs.iter().rev()); - } + stack.extend(ct.substs.iter().rev()); } } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index a4f3a63e40b60..e2a42de71b956 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -244,10 +244,10 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ // The exception is `body.user_type_annotations`, which is used unmodified // by borrow checking. debug_assert!( - !(body.local_decls.has_free_regions(tcx) - || body.basic_blocks().has_free_regions(tcx) - || body.var_debug_info.has_free_regions(tcx) - || body.yield_ty().has_free_regions(tcx)), + !(body.local_decls.has_free_regions() + || body.basic_blocks().has_free_regions() + || body.var_debug_info.has_free_regions() + || body.yield_ty().has_free_regions()), "Unexpected free regions in MIR: {:?}", body, ); @@ -760,7 +760,6 @@ fn construct_error<'a, 'tcx>( cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable); let mut body = Body::new( - tcx, MirSource::item(def.did.to_def_id()), cfg.basic_blocks, source_scopes, @@ -849,7 +848,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } Body::new( - self.tcx, MirSource::item(self.def_id), self.cfg.basic_blocks, self.source_scopes, diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c62de1543883e..e090ecf2114d6 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -716,10 +716,11 @@ impl<'tcx> Cx<'tcx> { // and not the beginning of discriminants (which is always `0`) let substs = InternalSubsts::identity_for_item(self.tcx(), did); let lhs = ty::Const { - val: ty::ConstKind::Unevaluated(ty::Unevaluated::new( - ty::WithOptConstParam::unknown(did), + val: ty::ConstKind::Unevaluated(ty::Unevaluated { + def: ty::WithOptConstParam::unknown(did), substs, - )), + promoted: None, + }), ty: var_ty, }; let lhs = self.thir.exprs.push(mk_const(self.tcx().mk_const(lhs))); @@ -911,10 +912,11 @@ impl<'tcx> Cx<'tcx> { debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { literal: self.tcx.mk_const(ty::Const { - val: ty::ConstKind::Unevaluated(ty::Unevaluated::new( - ty::WithOptConstParam::unknown(def_id), + val: ty::ConstKind::Unevaluated(ty::Unevaluated { + def: ty::WithOptConstParam::unknown(def_id), substs, - )), + promoted: None, + }), ty: self.typeck_results().node_type(expr.hir_id), }), user_ty, diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index dd16e3cde75ae..50512139f5dda 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -240,7 +240,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // code at the moment, because types like `for <'a> fn(&'a ())` do // not *yet* implement `PartialEq`. So for now we leave this here. has_impl - || ty.walk(self.tcx()).any(|t| match t.unpack() { + || ty.walk().any(|t| match t.unpack() { ty::subst::GenericArgKind::Lifetime(_) => false, ty::subst::GenericArgKind::Type(t) => t.is_fn_ptr(), ty::subst::GenericArgKind::Const(_) => false, diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index e3ff6ad45490d..911fa092d72a0 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -126,7 +126,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { .predicates_of(def_id.to_def_id()) .predicates .iter() - .filter_map(|(p, _)| if p.is_global(tcx) { Some(*p) } else { None }); + .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); if traits::impossible_predicates( tcx, traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(), @@ -138,7 +138,6 @@ impl<'tcx> MirPass<'tcx> for ConstProp { trace!("ConstProp starting for {:?}", def_id); let dummy_body = &Body::new( - tcx, body.source, body.basic_blocks().clone(), body.source_scopes.clone(), @@ -475,7 +474,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// Returns the value, if any, of evaluating `c`. fn eval_constant(&mut self, c: &Constant<'tcx>, source_info: SourceInfo) -> Option> { // FIXME we need to revisit this for #67176 - if c.definitely_needs_subst(self.tcx) { + if c.needs_subst() { return None; } @@ -490,14 +489,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Promoteds must lint and not error as the user didn't ask for them ConstKind::Unevaluated(ty::Unevaluated { def: _, - substs_: _, + substs: _, promoted: Some(_), }) => true, // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. - _ => c.literal.definitely_needs_subst(*tcx), + _ => c.literal.needs_subst(), }, - ConstantKind::Val(_, ty) => ty.definitely_needs_subst(*tcx), + ConstantKind::Val(_, ty) => ty.needs_subst(), }; if lint_only { // Out of backwards compatibility we cannot report hard errors in unused @@ -728,7 +727,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } // FIXME we need to revisit this for #67176 - if rvalue.definitely_needs_subst(self.tcx) { + if rvalue.needs_subst() { return None; } diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 05834b443d0d9..f364a332a788c 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -49,7 +49,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> { // Handle calls to `transmute` if self.tcx.is_diagnostic_item(sym::transmute, def_id) { let arg_ty = args[0].ty(self.body, self.tcx); - for generic_inner_ty in arg_ty.walk(self.tcx) { + for generic_inner_ty in arg_ty.walk() { if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() { if let Some((fn_id, fn_substs)) = FunctionItemRefChecker::is_fn_ref(inner_ty) @@ -110,7 +110,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { let arg_defs = self.tcx.fn_sig(def_id).skip_binder().inputs(); for (arg_num, arg_def) in arg_defs.iter().enumerate() { // For all types reachable from the argument type in the fn sig - for generic_inner_ty in arg_def.walk(self.tcx) { + for generic_inner_ty in arg_def.walk() { if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() { // If the inner type matches the type bound by `Pointer` if TyS::same_type(inner_ty, bound_ty) { diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 747e760a18b92..44ded1647fc28 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -89,7 +89,7 @@ crate fn mir_callgraph_reachable<'tcx>( // FIXME: A not fully substituted drop shim can cause ICEs if one attempts to // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this // needs some more analysis. - if callee.definitely_needs_subst(tcx) { + if callee.needs_subst() { continue; } } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 638baa0b8d376..9b78cdd555062 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -342,7 +342,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) - } } - debug_assert!(!body.has_free_regions(tcx), "Free regions in MIR for CTFE"); + debug_assert!(!body.has_free_regions(), "Free regions in MIR for CTFE"); body } @@ -530,7 +530,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did)).steal(); run_optimization_passes(tcx, &mut body); - debug_assert!(!body.has_free_regions(tcx), "Free regions in optimized MIR"); + debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR"); body } @@ -557,7 +557,7 @@ fn promoted_mir<'tcx>( run_post_borrowck_cleanup_passes(tcx, body); } - debug_assert!(!promoted.has_free_regions(tcx), "Free regions in promoted MIR"); + debug_assert!(!promoted.has_free_regions(), "Free regions in promoted MIR"); tcx.arena.alloc(promoted) } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 58996dcd6735a..919171db39e31 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -171,7 +171,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) let source = MirSource::from_instance(ty::InstanceDef::DropGlue(def_id, ty)); let mut body = - new_body(tcx, source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); + new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); if ty.is_some() { // The first argument (index 0), but add 1 for the return value. @@ -210,7 +210,6 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) } fn new_body<'tcx>( - tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, basic_blocks: IndexVec>, local_decls: IndexVec>, @@ -218,7 +217,6 @@ fn new_body<'tcx>( span: Span, ) -> Body<'tcx> { Body::new( - tcx, source, basic_blocks, IndexVec::from_elem_n( @@ -362,14 +360,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { self.def_id, self.sig.inputs_and_output[0], )); - new_body( - self.tcx, - source, - self.blocks, - self.local_decls, - self.sig.inputs().len(), - self.span, - ) + new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span) } fn source_info(&self) -> SourceInfo { @@ -719,14 +710,8 @@ fn build_call_shim<'tcx>( block(&mut blocks, vec![], TerminatorKind::Resume, true); } - let mut body = new_body( - tcx, - MirSource::from_instance(instance), - blocks, - local_decls, - sig.inputs().len(), - span, - ); + let mut body = + new_body(MirSource::from_instance(instance), blocks, local_decls, sig.inputs().len(), span); if let Abi::RustCall = sig.abi { body.spread_arg = Some(Local::new(sig.inputs().len())); @@ -791,7 +776,6 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { let source = MirSource::item(ctor_id); let body = new_body( - tcx, source, IndexVec::from_elem_n(start_block, 1), local_decls, diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 3e06e7f36d419..7e7f693870656 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -573,7 +573,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { let type_length = instance .substs .iter() - .flat_map(|arg| arg.walk(tcx)) + .flat_map(|arg| arg.walk()) .filter(|arg| match arg.unpack() { GenericArgKind::Type(_) | GenericArgKind::Const(_) => true, GenericArgKind::Lifetime(_) => false, diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 516c9a9259d4f..681271be7beb9 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -303,9 +303,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( // When polymorphization is enabled, methods which do not depend on their generic // parameters, but the self-type of their impl block do will fail to normalize. - if !tcx.sess.opts.debugging_opts.polymorphize - || !instance.definitely_needs_subst(tcx) - { + if !tcx.sess.opts.debugging_opts.polymorphize || !instance.needs_subst() { // This is a method within an impl, find out what the self-type is: let impl_self_ty = tcx.subst_and_normalize_erasing_regions( instance.substs, diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 595080619da6f..4b17c22a68c26 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -277,12 +277,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) -> Option> { - Some(self.tcx) - } #[instrument(level = "debug", skip(self))] fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow { - if !c.potentially_has_param_types_or_consts() { + if !c.has_param_types_or_consts() { return ControlFlow::CONTINUE; } @@ -292,7 +289,7 @@ 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, 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 => @@ -306,7 +303,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { ty::ConstKind::Unevaluated(uv) if matches!(self.tcx.def_kind(uv.def.did), DefKind::AnonConst | DefKind::InlineConst) => { - self.visit_child_body(uv.def.did, uv.substs(self.tcx)); + self.visit_child_body(uv.def.did, uv.substs); ControlFlow::CONTINUE } _ => c.super_visit_with(self), @@ -315,7 +312,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { - if !ty.potentially_has_param_types_or_consts() { + if !ty.has_param_types_or_consts() { return ControlFlow::CONTINUE; } @@ -343,21 +340,16 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } /// Visitor used to check if a generic parameter is used. -struct HasUsedGenericParams<'a, 'tcx> { - tcx: TyCtxt<'tcx>, +struct HasUsedGenericParams<'a> { unused_parameters: &'a FiniteBitSet, } -impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a, 'tcx> { +impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { type BreakTy = (); - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - #[instrument(level = "debug", skip(self))] fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow { - if !c.potentially_has_param_types_or_consts() { + if !c.has_param_types_or_consts() { return ControlFlow::CONTINUE; } @@ -375,7 +367,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { - if !ty.potentially_has_param_types_or_consts() { + if !ty.has_param_types_or_consts() { return ControlFlow::CONTINUE; } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e7741ccc4e424..aa9ccddbdc5ba 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -135,11 +135,11 @@ where ty.visit_with(self) } ty::PredicateKind::RegionOutlives(..) => ControlFlow::CONTINUE, - ty::PredicateKind::ConstEvaluatable(uv) + ty::PredicateKind::ConstEvaluatable(defs, substs) if self.def_id_visitor.tcx().features().generic_const_exprs => { let tcx = self.def_id_visitor.tcx(); - if let Ok(Some(ct)) = AbstractConst::new(tcx, uv) { + if let Ok(Some(ct)) = AbstractConst::new(tcx, defs, substs) { self.visit_abstract_const_expr(tcx, ct)?; } ControlFlow::CONTINUE @@ -177,10 +177,6 @@ where { type BreakTy = V::BreakTy; - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(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_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index 581a2bce2e50e..8ab48b838ea69 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -245,13 +245,18 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { } } -impl<'tcx> Key for (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>) { +impl<'tcx> Key + for ( + (ty::WithOptConstParam, SubstsRef<'tcx>), + (ty::WithOptConstParam, SubstsRef<'tcx>), + ) +{ #[inline(always)] fn query_crate_is_local(&self) -> bool { - (self.0).def.did.krate == LOCAL_CRATE + (self.0).0.did.krate == LOCAL_CRATE } fn default_span(&self, tcx: TyCtxt<'_>) -> Span { - (self.0).def.did.default_span(tcx) + (self.0).0.did.default_span(tcx) } } diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 6d02d04fe80e7..c981b3ff54663 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -107,9 +107,9 @@ fn get_symbol_hash<'tcx>( tcx.def_path_hash(def_id).hash_stable(&mut hcx, &mut hasher); // Include the main item-type. Note that, in this case, the - // assertions about `definitely_needs_subst` may not hold, but this item-type + // assertions about `needs_subst` may not hold, but this item-type // ought to be the same for every reference anyway. - assert!(!item_type.has_erasable_regions(tcx)); + assert!(!item_type.has_erasable_regions()); hcx.while_hashing_spans(false, |hcx| { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { item_type.hash_stable(hcx, &mut hasher); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index c2519adcbe416..14e12bed59e1e 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -317,9 +317,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { // Encode impl generic params if the substitutions contain parameters (implying // polymorphization is enabled) and this isn't an inherent impl. - if impl_trait_ref.is_some() - && substs.iter().any(|a| a.definitely_has_param_types_or_consts(self.tcx)) - { + if impl_trait_ref.is_some() && substs.iter().any(|a| a.has_param_types_or_consts()) { self = self.path_generic_args( |this| { this.path_append_ns( diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 290426aa82787..d174e00df77a9 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -444,7 +444,7 @@ fn orphan_check_trait_ref<'tcx>( ) -> Result<(), OrphanCheckErr<'tcx>> { debug!("orphan_check_trait_ref(trait_ref={:?}, in_crate={:?})", trait_ref, in_crate); - if trait_ref.needs_infer() && trait_ref.definitely_needs_subst(tcx) { + if trait_ref.needs_infer() && trait_ref.needs_subst() { bug!( "can't orphan check a trait ref with both params and inference variables {:?}", trait_ref diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 0ea3a18ca34fa..7d02983569ef3 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -19,7 +19,7 @@ use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; use rustc_session::lint; -use rustc_span::def_id::LocalDefId; +use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; use std::cmp; @@ -29,20 +29,26 @@ use std::ops::ControlFlow; /// Check if a given constant can be evaluated. pub fn is_const_evaluatable<'cx, 'tcx>( infcx: &InferCtxt<'cx, 'tcx>, - uv: ty::Unevaluated<'tcx, ()>, + def: ty::WithOptConstParam, + substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, span: Span, ) -> Result<(), NotConstEvaluatable> { - debug!("is_const_evaluatable({:?})", uv); + debug!("is_const_evaluatable({:?}, {:?})", def, substs); if infcx.tcx.features().generic_const_exprs { let tcx = infcx.tcx; - match AbstractConst::new(tcx, uv)? { + match AbstractConst::new(tcx, def, substs)? { // We are looking at a generic abstract constant. Some(ct) => { for pred in param_env.caller_bounds() { match pred.kind().skip_binder() { - ty::PredicateKind::ConstEvaluatable(uv) => { - if let Some(b_ct) = AbstractConst::new(tcx, uv)? { + ty::PredicateKind::ConstEvaluatable(b_def, b_substs) => { + if b_def == def && b_substs == substs { + debug!("is_const_evaluatable: caller_bound ~~> ok"); + return Ok(()); + } + + if let Some(b_ct) = AbstractConst::new(tcx, b_def, b_substs)? { // Try to unify with each subtree in the AbstractConst to allow for // `N + 1` being const evaluatable even if theres only a `ConstEvaluatable` // predicate for `(N + 1) * 2` @@ -84,7 +90,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( Node::Leaf(leaf) => { if leaf.has_infer_types_or_consts() { failure_kind = FailureKind::MentionsInfer; - } else if leaf.definitely_has_param_types_or_consts(tcx) { + } else if leaf.has_param_types_or_consts() { failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam); } @@ -93,7 +99,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( Node::Cast(_, _, ty) => { if ty.has_infer_types_or_consts() { failure_kind = FailureKind::MentionsInfer; - } else if ty.definitely_has_param_types_or_consts(tcx) { + } else if ty.has_param_types_or_consts() { failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam); } @@ -126,7 +132,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } let future_compat_lint = || { - if let Some(local_def_id) = uv.def.did.as_local() { + if let Some(local_def_id) = def.did.as_local() { infcx.tcx.struct_span_lint_hir( lint::builtin::CONST_EVALUATABLE_UNCHECKED, infcx.tcx.hir().local_def_id_to_hir_id(local_def_id), @@ -147,12 +153,16 @@ 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, uv.expand(), Some(span)); - - if concrete.is_ok() && uv.substs(infcx.tcx).definitely_has_param_types_or_consts(infcx.tcx) { - match infcx.tcx.def_kind(uv.def.did) { + 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) { DefKind::AnonConst | DefKind::InlineConst => { - let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def); + let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(def); if mir_body.is_polymorphic { future_compat_lint(); @@ -164,7 +174,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( debug!(?concrete, "is_const_evaluatable"); match concrete { - Err(ErrorHandled::TooGeneric) => Err(match uv.has_infer_types_or_consts() { + Err(ErrorHandled::TooGeneric) => Err(match substs.has_infer_types_or_consts() { true => NotConstEvaluatable::MentionsInfer, false => NotConstEvaluatable::MentionsParam, }), @@ -192,11 +202,12 @@ pub struct AbstractConst<'tcx> { impl<'tcx> AbstractConst<'tcx> { pub fn new( tcx: TyCtxt<'tcx>, - uv: ty::Unevaluated<'tcx, ()>, + def: ty::WithOptConstParam, + substs: SubstsRef<'tcx>, ) -> Result>, ErrorReported> { - let inner = tcx.thir_abstract_const_opt_const_arg(uv.def)?; - debug!("AbstractConst::new({:?}) = {:?}", uv, inner); - Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs(tcx) })) + let inner = tcx.thir_abstract_const_opt_const_arg(def)?; + debug!("AbstractConst::new({:?}, {:?}) = {:?}", def, substs, inner); + Ok(inner.map(|inner| AbstractConst { inner, substs })) } pub fn from_const( @@ -204,7 +215,9 @@ impl<'tcx> AbstractConst<'tcx> { ct: &ty::Const<'tcx>, ) -> Result>, ErrorReported> { match ct.val { - ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()), + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: _ }) => { + AbstractConst::new(tcx, def, substs) + } ty::ConstKind::Error(_) => Err(ErrorReported), _ => Ok(None), } @@ -271,7 +284,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { struct IsThirPolymorphic<'a, 'tcx> { is_poly: bool, thir: &'a thir::Thir<'tcx>, - tcx: TyCtxt<'tcx>, } use thir::visit; @@ -281,25 +293,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { } fn visit_expr(&mut self, expr: &thir::Expr<'tcx>) { - self.is_poly |= expr.ty.definitely_has_param_types_or_consts(self.tcx); + self.is_poly |= expr.ty.has_param_types_or_consts(); if !self.is_poly { visit::walk_expr(self, expr) } } fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) { - self.is_poly |= pat.ty.definitely_has_param_types_or_consts(self.tcx); + self.is_poly |= pat.ty.has_param_types_or_consts(); if !self.is_poly { visit::walk_pat(self, pat); } } fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) { - self.is_poly |= ct.definitely_has_param_types_or_consts(self.tcx); + self.is_poly |= ct.has_param_types_or_consts(); } } - let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body, tcx }; + let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; visit::walk_expr(&mut is_poly_vis, &body[body_id]); debug!("AbstractConstBuilder: is_poly={}", is_poly_vis.is_poly); if !is_poly_vis.is_poly { @@ -527,11 +539,14 @@ pub(super) fn thir_abstract_const<'tcx>( pub(super) fn try_unify_abstract_consts<'tcx>( tcx: TyCtxt<'tcx>, - (a, b): (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>), + ((a, a_substs), (b, b_substs)): ( + (ty::WithOptConstParam, SubstsRef<'tcx>), + (ty::WithOptConstParam, SubstsRef<'tcx>), + ), ) -> bool { (|| { - if let Some(a) = AbstractConst::new(tcx, a)? { - if let Some(b) = AbstractConst::new(tcx, b)? { + if let Some(a) = AbstractConst::new(tcx, a, a_substs)? { + if let Some(b) = AbstractConst::new(tcx, b, b_substs)? { return Ok(try_unify(tcx, a, b)); } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 72878b6cb3858..711f242333ceb 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -819,10 +819,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::ConstEvaluatable(uv) => { + ty::PredicateKind::ConstEvaluatable(def, _) => { let mut err = self.tcx.sess.struct_span_err(span, "unconstrained generic constant"); - let const_span = self.tcx.def_span(uv.def.did); + let const_span = self.tcx.def_span(def.did); match self.tcx.sess.source_map().span_to_snippet(const_span) { Ok(snippet) => err.help(&format!( "try adding a `where` bound using this expression: `where [(); {}]:`", diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 42e3f0db15e53..be8a64e529956 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -527,10 +527,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { } } - ty::PredicateKind::ConstEvaluatable(uv) => { + ty::PredicateKind::ConstEvaluatable(def_id, substs) => { match const_evaluatable::is_const_evaluatable( self.selcx.infcx(), - uv, + def_id, + substs, obligation.param_env, obligation.cause.span, ) { @@ -538,9 +539,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { Err(NotConstEvaluatable::MentionsInfer) => { pending_obligation.stalled_on.clear(); pending_obligation.stalled_on.extend( - uv.substs(infcx.tcx) - .iter() - .filter_map(TyOrConstInferVar::maybe_from_generic_arg), + substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg), ); ProcessResult::Unchanged } @@ -564,7 +563,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.val, c2.val) { - if infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) { + if infcx.try_unify_abstract_consts(a, b) { return ProcessResult::Changed(vec![]); } } @@ -583,7 +582,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { Err(ErrorHandled::TooGeneric) => { stalled_on.extend( unevaluated - .substs(tcx) + .substs .iter() .filter_map(TyOrConstInferVar::maybe_from_generic_arg), ); @@ -654,7 +653,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { stalled_on: &mut Vec>, ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { let infcx = self.selcx.infcx(); - if obligation.predicate.is_known_global() { + if obligation.predicate.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. if infcx.predicate_must_hold_considering_regions(obligation) { @@ -708,7 +707,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { let tcx = self.selcx.tcx(); - if obligation.predicate.is_global(tcx) { + if obligation.predicate.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. if self.selcx.infcx().predicate_must_hold_considering_regions(obligation) { @@ -756,15 +755,14 @@ fn substs_infer_vars<'a, 'tcx>( selcx: &mut SelectionContext<'a, 'tcx>, substs: ty::Binder<'tcx, SubstsRef<'tcx>>, ) -> impl Iterator> { - let tcx = selcx.tcx(); selcx .infcx() .resolve_vars_if_possible(substs) .skip_binder() // ok because this check doesn't care about regions .iter() .filter(|arg| arg.has_infer_types_or_consts()) - .flat_map(move |arg| { - let mut walker = arg.walk(tcx); + .flat_map(|arg| { + let mut walker = arg.walk(); while let Some(c) = walker.next() { if !c.has_infer_types_or_consts() { walker.visited.remove(&c); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index a8f26982d2e42..23f534858b82a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -465,7 +465,7 @@ fn subst_and_check_impossible_predicates<'tcx>( debug!("subst_and_check_impossible_predicates(key={:?})", key); let mut predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates; - predicates.retain(|predicate| !predicate.definitely_needs_subst(tcx)); + predicates.retain(|predicate| !predicate.needs_subst()); let result = impossible_predicates(tcx, predicates); debug!("subst_and_check_impossible_predicates(key={:?}) = {:?}", key, result); diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 4e84849bc1e23..1e2c0f546555f 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -274,7 +274,7 @@ fn predicate_references_self<'tcx>( (predicate, sp): (ty::Predicate<'tcx>, Span), ) -> Option { let self_ty = tcx.types.self_param; - let has_self_ty = |arg: &GenericArg<'tcx>| arg.walk(tcx).any(|arg| arg == self_ty.into()); + let has_self_ty = |arg: &GenericArg<'_>| arg.walk().any(|arg| arg == self_ty.into()); match predicate.kind().skip_binder() { ty::PredicateKind::Trait(ref data) => { // In the case of a trait predicate, we can skip the "self" type. @@ -768,9 +768,6 @@ 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(&self) -> Option> { - Some(self.tcx) - } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { @@ -816,10 +813,9 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( } } - fn visit_unevaluated_const( - &mut self, - uv: ty::Unevaluated<'tcx>, - ) -> ControlFlow { + fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow { + self.visit_ty(ct.ty)?; + // Constants can only influence object safety if they reference `Self`. // This is only possible for unevaluated constants, so we walk these here. // @@ -833,7 +829,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( // This shouldn't really matter though as we can't really use any // constants which are not considered const evaluatable. use rustc_middle::thir::abstract_const::Node; - if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) { + if let Ok(Some(ct)) = AbstractConst::from_const(self.tcx, ct) { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| { match node.root(self.tcx) { Node::Leaf(leaf) => self.visit_const(leaf), @@ -847,6 +843,30 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( ControlFlow::CONTINUE } } + + fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow { + if let ty::PredicateKind::ConstEvaluatable(def, substs) = pred.kind().skip_binder() { + // FIXME(generic_const_exprs): We should probably deduplicate the logic for + // `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to + // take a `ty::Const` instead. + use rustc_middle::thir::abstract_const::Node; + if let Ok(Some(ct)) = AbstractConst::new(self.tcx, def, substs) { + const_evaluatable::walk_abstract_const(self.tcx, ct, |node| { + match node.root(self.tcx) { + Node::Leaf(leaf) => self.visit_const(leaf), + Node::Cast(_, _, ty) => self.visit_ty(ty), + Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { + ControlFlow::CONTINUE + } + } + }) + } else { + ControlFlow::CONTINUE + } + } else { + pred.super_visit_with(self) + } + } } value diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 26bacf787e2eb..81ee22c1de4d9 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -77,11 +77,8 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> { // The rest of the code is already set up to be lazy about replacing bound vars, // and only when we actually have to normalize. if value.has_escaping_bound_vars() { - let mut max_visitor = MaxEscapingBoundVarVisitor { - tcx: self.infcx.tcx, - outer_index: ty::INNERMOST, - escaping: 0, - }; + let mut max_visitor = + MaxEscapingBoundVarVisitor { outer_index: ty::INNERMOST, escaping: 0 }; value.visit_with(&mut max_visitor); if max_visitor.escaping > 0 { normalizer.universes.extend((0..max_visitor.escaping).map(|_| None)); @@ -104,18 +101,13 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> { } /// Visitor to find the maximum escaping bound var -struct MaxEscapingBoundVarVisitor<'tcx> { - tcx: TyCtxt<'tcx>, +struct MaxEscapingBoundVarVisitor { // The index which would count as escaping outer_index: ty::DebruijnIndex, escaping: usize, } -impl<'tcx> TypeVisitor<'tcx> for MaxEscapingBoundVarVisitor<'tcx> { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - +impl<'tcx> TypeVisitor<'tcx> for MaxEscapingBoundVarVisitor { fn visit_binder>( &mut self, t: &ty::Binder<'tcx, T>, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index b7fc578ea3bd3..36af78b66edfa 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -997,7 +997,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tail_field_ty = tcx.type_of(tail_field.did); let mut unsizing_params = GrowableBitSet::new_empty(); - for arg in tail_field_ty.walk(tcx) { + for arg in tail_field_ty.walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.insert(i); } @@ -1006,7 +1006,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Ensure none of the other fields mention the parameters used // in unsizing. for field in prefix_fields { - for arg in tcx.type_of(field.did).walk(tcx) { + for arg in tcx.type_of(field.did).walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.remove(i); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index bb3b3203a7c20..79f54e6aba02d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -526,7 +526,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // contain the "'static" lifetime (any other lifetime // would either be late-bound or local), so it is guaranteed // to outlive any other lifetime - if pred.0.is_global(self.infcx.tcx) && !pred.0.has_late_bound_regions() { + if pred.0.is_global() && !pred.0.has_late_bound_regions() { Ok(EvaluatedToOk) } else { Ok(EvaluatedToOkModuloRegions) @@ -619,10 +619,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::PredicateKind::ConstEvaluatable(uv) => { + ty::PredicateKind::ConstEvaluatable(def_id, substs) => { match const_evaluatable::is_const_evaluatable( self.infcx, - uv, + def_id, + substs, obligation.param_env, obligation.cause.span, ) { @@ -644,7 +645,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.val, c2.val) { - if self.infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) { + if self.infcx.try_unify_abstract_consts(a, b) { return Ok(EvaluatedToOk); } } @@ -711,12 +712,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { mut obligation: TraitObligation<'tcx>, ) -> Result { if !self.intercrate - && obligation.is_global(self.tcx()) - && obligation - .param_env - .caller_bounds() - .iter() - .all(|bound| bound.definitely_needs_subst(self.tcx())) + && obligation.is_global() + && obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst()) { // If a param env has no global bounds, global obligations do not // depend on its particular value in order to work, so we can clear @@ -1535,7 +1532,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the param_env so that it can be given the lowest priority. See // #50825 for the motivation for this. let is_global = |cand: &ty::PolyTraitPredicate<'tcx>| { - cand.is_global(self.infcx.tcx) && !cand.has_late_bound_regions() + cand.is_global() && !cand.has_late_bound_regions() }; // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 55feb3c1de17d..85905ba4a2142 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -131,9 +131,6 @@ impl<'a, 'tcx> Search<'a, 'tcx> { impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> { type BreakTy = NonStructuralMatchTy<'tcx>; - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx()) - } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { debug!("Search visiting ty: {:?}", ty); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 72ffe9085cbe7..044861829f1d3 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -131,9 +131,8 @@ pub fn predicate_obligations<'a, 'tcx>( wf.compute(a.into()); wf.compute(b.into()); } - ty::PredicateKind::ConstEvaluatable(uv) => { - let substs = uv.substs(wf.tcx()); - let obligations = wf.nominal_obligations(uv.def.did, substs); + ty::PredicateKind::ConstEvaluatable(def, substs) => { + let obligations = wf.nominal_obligations(def.did, substs); wf.out.extend(obligations); for arg in substs.iter() { @@ -429,7 +428,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes all the predicates needed to validate that `ty` is WF into `out`. fn compute(&mut self, arg: GenericArg<'tcx>) { - let mut walker = arg.walk(self.tcx()); + let mut walker = arg.walk(); let param_env = self.param_env; let depth = self.recursion_depth; while let Some(arg) = walker.next() { @@ -442,17 +441,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { GenericArgKind::Const(constant) => { match constant.val { - ty::ConstKind::Unevaluated(uv) => { - assert!(uv.promoted.is_none()); - let substs = uv.substs(self.tcx()); + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { + assert!(promoted.is_none()); - let obligations = self.nominal_obligations(uv.def.did, substs); + let obligations = self.nominal_obligations(def.did, substs); self.out.extend(obligations); - let predicate = ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable( - ty::Unevaluated::new(uv.def, substs), - )) - .to_predicate(self.tcx()); + let predicate = + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(def, substs)) + .to_predicate(self.tcx()); let cause = self.cause(traits::MiscObligation); self.out.push(traits::Obligation::with_depth( cause, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index cc07bfc500816..36c536c0ba3b2 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -806,7 +806,7 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>( tcx: TyCtxt<'tcx>, ty: Binder<'tcx, T>, ) -> (T, chalk_ir::VariableKinds>, BTreeMap) { - let mut bound_vars_collector = BoundVarsCollector::new(tcx); + let mut bound_vars_collector = BoundVarsCollector::new(); 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 @@ -836,16 +836,14 @@ 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(tcx: TyCtxt<'tcx>) -> Self { + crate fn new() -> Self { BoundVarsCollector { - tcx, binder_index: ty::INNERMOST, parameters: BTreeMap::new(), named_parameters: vec![], @@ -854,10 +852,6 @@ impl<'tcx> BoundVarsCollector<'tcx> { } impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - fn visit_binder>( &mut self, t: &Binder<'tcx, T>, @@ -1076,11 +1070,6 @@ impl PlaceholdersCollector { } impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { - fn tcx_for_anon_const_substs(&self) -> Option> { - // Anon const substs do not contain placeholders by default. - None - } - 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_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index e0aea786b837a..e7cc0f69e9f95 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -54,10 +54,6 @@ impl<'tcx> BoundVarsCollector<'tcx> { impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { type BreakTy = (); - fn tcx_for_anon_const_substs(&self) -> Option> { - // Anon const substs do not contain bound vars by default. - None - } fn visit_binder>( &mut self, t: &Binder<'tcx, T>, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 8f50e3e0fe1ca..b1c9840ad985e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -157,16 +157,6 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { predicates.extend(environment); } - // It's important that we include the default substs in unevaluated - // constants, since `Unevaluated` instances in predicates whose substs are None - // can lead to "duplicate" caller bounds candidates during trait selection, - // duplicate in the sense that both have their default substs, but the - // candidate that resulted from a superpredicate still uses `None` in its - // `substs_` field of `Unevaluated` to indicate that it has its default substs, - // whereas the other candidate has `substs_: Some(default_substs)`, see - // issue #89334 - predicates = tcx.expose_default_const_substs(predicates); - let local_did = def_id.as_local(); let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)); @@ -334,7 +324,7 @@ fn well_formed_types_in_env<'tcx>( // constituents are well-formed. NodeKind::InherentImpl => { let self_ty = tcx.type_of(def_id); - inputs.extend(self_ty.walk(tcx)); + inputs.extend(self_ty.walk()); } // In an fn, we assume that the arguments and all their constituents are @@ -343,7 +333,7 @@ fn well_formed_types_in_env<'tcx>( let fn_sig = tcx.fn_sig(def_id); let fn_sig = tcx.liberate_late_bound_regions(def_id, fn_sig); - inputs.extend(fn_sig.inputs().iter().flat_map(|ty| ty.walk(tcx))); + inputs.extend(fn_sig.inputs().iter().flat_map(|ty| ty.walk())); } NodeKind::Other => (), diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index f11c93e933996..ec6fb622d32aa 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -19,116 +19,94 @@ bitflags! { // Does this have parameters? Used to determine whether substitution is // required. /// Does this have `Param`? - const HAS_KNOWN_TY_PARAM = 1 << 0; + const HAS_TY_PARAM = 1 << 0; /// Does this have `ReEarlyBound`? - const HAS_KNOWN_RE_PARAM = 1 << 1; + const HAS_RE_PARAM = 1 << 1; /// Does this have `ConstKind::Param`? - const HAS_KNOWN_CT_PARAM = 1 << 2; + const HAS_CT_PARAM = 1 << 2; - const KNOWN_NEEDS_SUBST = TypeFlags::HAS_KNOWN_TY_PARAM.bits - | TypeFlags::HAS_KNOWN_RE_PARAM.bits - | TypeFlags::HAS_KNOWN_CT_PARAM.bits; + const NEEDS_SUBST = TypeFlags::HAS_TY_PARAM.bits + | TypeFlags::HAS_RE_PARAM.bits + | TypeFlags::HAS_CT_PARAM.bits; /// Does this have `Infer`? - const HAS_TY_INFER = 1 << 3; + const HAS_TY_INFER = 1 << 3; /// Does this have `ReVar`? - const HAS_RE_INFER = 1 << 4; + const HAS_RE_INFER = 1 << 4; /// Does this have `ConstKind::Infer`? - const HAS_CT_INFER = 1 << 5; + const HAS_CT_INFER = 1 << 5; /// Does this have inference variables? Used to determine whether /// inference is required. - const NEEDS_INFER = TypeFlags::HAS_TY_INFER.bits - | TypeFlags::HAS_RE_INFER.bits - | TypeFlags::HAS_CT_INFER.bits; + const NEEDS_INFER = TypeFlags::HAS_TY_INFER.bits + | TypeFlags::HAS_RE_INFER.bits + | TypeFlags::HAS_CT_INFER.bits; /// Does this have `Placeholder`? - const HAS_TY_PLACEHOLDER = 1 << 6; + const HAS_TY_PLACEHOLDER = 1 << 6; /// Does this have `RePlaceholder`? - const HAS_RE_PLACEHOLDER = 1 << 7; + const HAS_RE_PLACEHOLDER = 1 << 7; /// Does this have `ConstKind::Placeholder`? - const HAS_CT_PLACEHOLDER = 1 << 8; + const HAS_CT_PLACEHOLDER = 1 << 8; /// `true` if there are "names" of regions and so forth /// that are local to a particular fn/inferctxt - const HAS_KNOWN_FREE_LOCAL_REGIONS = 1 << 9; + const HAS_FREE_LOCAL_REGIONS = 1 << 9; /// `true` if there are "names" of types and regions and so forth /// that are local to a particular fn - const HAS_KNOWN_FREE_LOCAL_NAMES = TypeFlags::HAS_KNOWN_TY_PARAM.bits - | TypeFlags::HAS_KNOWN_CT_PARAM.bits - | TypeFlags::HAS_TY_INFER.bits - | TypeFlags::HAS_CT_INFER.bits - | TypeFlags::HAS_TY_PLACEHOLDER.bits - | TypeFlags::HAS_CT_PLACEHOLDER.bits - // We consider 'freshened' types and constants - // to depend on a particular fn. - // The freshening process throws away information, - // which can make things unsuitable for use in a global - // cache. Note that there is no 'fresh lifetime' flag - - // freshening replaces all lifetimes with `ReErased`, - // which is different from how types/const are freshened. - | TypeFlags::HAS_TY_FRESH.bits - | TypeFlags::HAS_CT_FRESH.bits - | TypeFlags::HAS_KNOWN_FREE_LOCAL_REGIONS.bits; - - const HAS_POTENTIAL_FREE_LOCAL_NAMES = TypeFlags::HAS_KNOWN_FREE_LOCAL_NAMES.bits - | TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS.bits; + const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_PARAM.bits + | TypeFlags::HAS_CT_PARAM.bits + | TypeFlags::HAS_TY_INFER.bits + | TypeFlags::HAS_CT_INFER.bits + | TypeFlags::HAS_TY_PLACEHOLDER.bits + | TypeFlags::HAS_CT_PLACEHOLDER.bits + // We consider 'freshened' types and constants + // to depend on a particular fn. + // The freshening process throws away information, + // which can make things unsuitable for use in a global + // cache. Note that there is no 'fresh lifetime' flag - + // freshening replaces all lifetimes with `ReErased`, + // which is different from how types/const are freshened. + | TypeFlags::HAS_TY_FRESH.bits + | TypeFlags::HAS_CT_FRESH.bits + | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits; /// Does this have `Projection`? - const HAS_TY_PROJECTION = 1 << 10; + const HAS_TY_PROJECTION = 1 << 10; /// Does this have `Opaque`? - const HAS_TY_OPAQUE = 1 << 11; + const HAS_TY_OPAQUE = 1 << 11; /// Does this have `ConstKind::Unevaluated`? - const HAS_CT_PROJECTION = 1 << 12; + const HAS_CT_PROJECTION = 1 << 12; /// Could this type be normalized further? - const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits - | TypeFlags::HAS_TY_OPAQUE.bits - | TypeFlags::HAS_CT_PROJECTION.bits; + const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits + | TypeFlags::HAS_TY_OPAQUE.bits + | TypeFlags::HAS_CT_PROJECTION.bits; /// Is an error type/const reachable? - const HAS_ERROR = 1 << 13; + const HAS_ERROR = 1 << 13; /// Does this have any region that "appears free" in the type? /// Basically anything but `ReLateBound` and `ReErased`. - const HAS_KNOWN_FREE_REGIONS = 1 << 14; - - const HAS_POTENTIAL_FREE_REGIONS = TypeFlags::HAS_KNOWN_FREE_REGIONS.bits - | TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS.bits; + const HAS_FREE_REGIONS = 1 << 14; /// Does this have any `ReLateBound` regions? Used to check /// if a global bound is safe to evaluate. - const HAS_RE_LATE_BOUND = 1 << 15; + const HAS_RE_LATE_BOUND = 1 << 15; /// Does this have any `ReErased` regions? - const HAS_RE_ERASED = 1 << 16; + const HAS_RE_ERASED = 1 << 16; /// Does this value have parameters/placeholders/inference variables which could be /// replaced later, in a way that would change the results of `impl` specialization? - /// - /// Note that this flag being set is not a guarantee, as it is also - /// set if there are any anon consts with unknown default substs. - const STILL_FURTHER_SPECIALIZABLE = 1 << 17; + const STILL_FURTHER_SPECIALIZABLE = 1 << 17; /// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`? - const HAS_TY_FRESH = 1 << 18; + const HAS_TY_FRESH = 1 << 18; /// Does this value have `InferConst::Fresh`? - const HAS_CT_FRESH = 1 << 19; - - /// Does this value have unknown default anon const substs. - /// - /// For more details refer to... - /// FIXME(@lcnr): ask me for now, still have to write all of this. - const HAS_UNKNOWN_DEFAULT_CONST_SUBSTS = 1 << 20; - /// Flags which can be influenced by default anon const substs. - const MAY_NEED_DEFAULT_CONST_SUBSTS = TypeFlags::HAS_KNOWN_RE_PARAM.bits - | TypeFlags::HAS_KNOWN_TY_PARAM.bits - | TypeFlags::HAS_KNOWN_CT_PARAM.bits - | TypeFlags::HAS_KNOWN_FREE_LOCAL_REGIONS.bits - | TypeFlags::HAS_KNOWN_FREE_REGIONS.bits; - + const HAS_CT_FRESH = 1 << 19; } } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 17cf366761124..6097307ad9e4d 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -388,7 +388,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if self.is_object && has_default { let default_ty = tcx.at(self.span).type_of(param.def_id); let self_param = tcx.types.self_param; - if default_ty.walk(tcx).any(|arg| arg == self_param.into()) { + if default_ty.walk().any(|arg| arg == self_param.into()) { // There is no suitable inference default for a type parameter // that references self, in an object type. return true; @@ -1370,7 +1370,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // A `Self` within the original bound will be substituted with a // `trait_object_dummy_self`, so check for that. let references_self = - pred.skip_binder().ty.walk(tcx).any(|arg| arg == dummy_self.into()); + pred.skip_binder().ty.walk().any(|arg| arg == dummy_self.into()); // If the projection output contains `Self`, force the user to // elaborate it explicitly to avoid a lot of complexity. @@ -2216,7 +2216,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.prohibit_generics(path.segments); // Try to evaluate any array length constants. let normalized_ty = self.normalize_ty(span, tcx.at(span).type_of(def_id)); - if forbid_generic && normalized_ty.definitely_needs_subst(tcx) { + if forbid_generic && normalized_ty.needs_subst() { let mut err = tcx.sess.struct_span_err( path.span, "generic `Self` types are currently not permitted in anonymous constants", diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index de560d50795b0..3a26fa82892cc 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -462,17 +462,14 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( debug!(?item, ?span); struct FoundParentLifetime; - struct FindParentLifetimeVisitor<'tcx>(TyCtxt<'tcx>, &'tcx ty::Generics); + struct FindParentLifetimeVisitor<'tcx>(&'tcx ty::Generics); impl<'tcx> ty::fold::TypeVisitor<'tcx> for FindParentLifetimeVisitor<'tcx> { type BreakTy = FoundParentLifetime; - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(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.1.parent_count as u32 { + if *index < self.0.parent_count as u32 { return ControlFlow::Break(FoundParentLifetime); } else { return ControlFlow::CONTINUE; @@ -494,24 +491,21 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( } 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) -> Option> { - Some(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.tcx, self.generics)) + t.super_visit_with(&mut FindParentLifetimeVisitor(self.generics)) .map_break(|FoundParentLifetime| t) } } @@ -1381,7 +1375,7 @@ pub(super) fn check_type_params_are_used<'tcx>( return; } - for leaf in ty.walk(tcx) { + for leaf in ty.walk() { if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { if let ty::Param(param) = leaf_ty.kind() { debug!("found use of ty param {:?}", param); @@ -1477,12 +1471,8 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t))) .filter(|(_, ty)| !matches!(ty.kind(), ty::Never)) { - struct OpaqueTypeCollector(Vec); - impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypeCollector { - fn tcx_for_anon_const_substs(&self) -> Option> { - // Default anon const substs cannot contain opaque types. - None - } + struct VisitTypes(Vec); + impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Opaque(def, _) => { @@ -1493,7 +1483,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { } } } - let mut visitor = OpaqueTypeCollector(vec![]); + let mut visitor = VisitTypes(vec![]); ty.visit_with(&mut visitor); for def_id in visitor.0 { let ty_span = tcx.def_span(def_id); diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 3cc66aaf0d79c..7d7289772629b 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -237,9 +237,9 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( relator.relate(predicate.rebind(a), p.rebind(b)).is_ok() } ( - ty::PredicateKind::ConstEvaluatable(a), - ty::PredicateKind::ConstEvaluatable(b), - ) => tcx.try_unify_abstract_consts((a, b)), + ty::PredicateKind::ConstEvaluatable(a_def, a_substs), + ty::PredicateKind::ConstEvaluatable(b_def, b_substs), + ) => tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))), ( ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_a, lt_a)), ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_b, lt_b)), diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 1aca2911533ad..a031f802b6d98 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -235,7 +235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { debug!("fcx {}", self.tag()); - if self.can_contain_user_lifetime_bounds((substs, user_self_ty)) { + if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) { let canonicalized = self.infcx.canonicalize_user_type_annotation(UserType::TypeOf( def_id, UserSubsts { substs, user_self_ty }, @@ -489,7 +489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.to_ty(ast_ty); debug!("to_ty_saving_user_provided_ty: ty={:?}", ty); - if self.can_contain_user_lifetime_bounds(ty) { + if Self::can_contain_user_lifetime_bounds(ty) { let c_ty = self.infcx.canonicalize_response(UserType::Ty(ty)); debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty); self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty); @@ -541,11 +541,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // reader, although I have my doubts). Also pass in types with inference // types, because they may be repeated. Other sorts of things are already // sufficiently enforced with erased regions. =) - fn can_contain_user_lifetime_bounds(&self, t: T) -> bool + fn can_contain_user_lifetime_bounds(t: T) -> bool where T: TypeFoldable<'tcx>, { - t.has_free_regions(self.tcx) || t.has_projections() || t.has_infer_types() + t.has_free_regions() || t.has_projections() || t.has_infer_types() } pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index e796fe58170d2..7c15cea68c59f 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1036,7 +1036,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.resolve_vars_if_possible(ty); // We walk the argument type because the argument's type could have // been `Option`, but the `FulfillmentError` references `T`. - if ty.walk(self.tcx).any(|arg| arg == self_) { Some(i) } else { None } + if ty.walk().any(|arg| arg == self_) { Some(i) } else { None } }) .collect::>(); diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 8ebfcdd539b67..29f7bdf358669 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -423,7 +423,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } if let Some(missing_trait) = missing_trait { - let mut visitor = TypeParamVisitor(self.tcx, vec![]); + let mut visitor = TypeParamVisitor(vec![]); visitor.visit_ty(lhs_ty); if op.node == hir::BinOpKind::Add @@ -434,7 +434,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.1[..] { + } else if let [ty] = &visitor.0[..] { 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 @@ -991,15 +991,12 @@ fn suggest_constraining_param( } } -struct TypeParamVisitor<'tcx>(TyCtxt<'tcx>, Vec>); +struct TypeParamVisitor<'tcx>(Vec>); impl<'tcx> TypeVisitor<'tcx> for TypeParamVisitor<'tcx> { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.0) - } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { if let ty::Param(_) = ty.kind() { - self.1.push(ty); + self.0.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 7c4f5d16abcab..9f8e06adbf953 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -311,7 +311,7 @@ fn check_gat_where_clauses( // of the function signature. In our example, the GAT in the return // type is `::Item<'a>`, so 'a and Self are arguments. let (regions, types) = - GATSubstCollector::visit(tcx, trait_item.def_id.to_def_id(), sig.output()); + GATSubstCollector::visit(trait_item.def_id.to_def_id(), sig.output()); // If both regions and types are empty, then this GAT isn't in the // return type, and we shouldn't try to do clause analysis @@ -600,7 +600,6 @@ fn region_known_to_outlive<'tcx>( /// the two vectors, `regions` and `types` (depending on their kind). For each /// parameter `Pi` also track the index `i`. struct GATSubstCollector<'tcx> { - tcx: TyCtxt<'tcx>, gat: DefId, // Which region appears and which parameter index its subsituted for regions: FxHashSet<(ty::Region<'tcx>, usize)>, @@ -610,16 +609,11 @@ struct GATSubstCollector<'tcx> { impl<'tcx> GATSubstCollector<'tcx> { fn visit>( - tcx: TyCtxt<'tcx>, gat: DefId, t: T, ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) { - let mut visitor = GATSubstCollector { - tcx, - gat, - regions: FxHashSet::default(), - types: FxHashSet::default(), - }; + let mut visitor = + GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() }; t.visit_with(&mut visitor); (visitor.regions, visitor.types) } @@ -647,10 +641,6 @@ impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> { } t.super_visit_with(self) } - - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } } fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool { @@ -982,10 +972,10 @@ fn check_type_defn<'tcx, F>( fcx.register_predicate(traits::Obligation::new( cause, fcx.param_env, - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new( + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable( ty::WithOptConstParam::unknown(discr_def_id.to_def_id()), discr_substs, - ))) + )) .to_predicate(tcx), )); } @@ -1197,7 +1187,7 @@ fn check_where_clauses<'tcx, 'fcx>( // Ignore dependent defaults -- that is, where the default of one type // parameter includes another (e.g., ``). In those cases, we can't // be sure if it will error or not as user might always specify the other. - if !ty.definitely_needs_subst(tcx) { + if !ty.needs_subst() { fcx.register_wf_obligation( ty.into(), tcx.def_span(param.def_id), @@ -1213,7 +1203,7 @@ fn check_where_clauses<'tcx, 'fcx>( // for `struct Foo` // we should eagerly error. let default_ct = tcx.const_param_default(param.def_id); - if !default_ct.definitely_needs_subst(tcx) { + if !default_ct.needs_subst() { fcx.register_wf_obligation( default_ct.into(), tcx.def_span(param.def_id), @@ -1247,7 +1237,7 @@ fn check_where_clauses<'tcx, 'fcx>( if is_our_default(param) { let default_ty = tcx.type_of(param.def_id); // ... and it's not a dependent default, ... - if !default_ty.definitely_needs_subst(tcx) { + if !default_ty.needs_subst() { // ... then substitute it with the default. return default_ty.into(); } @@ -1260,7 +1250,7 @@ fn check_where_clauses<'tcx, 'fcx>( if is_our_default(param) { let default_ct = tcx.const_param_default(param.def_id); // ... and it's not a dependent default, ... - if !default_ct.definitely_needs_subst(tcx) { + if !default_ct.needs_subst() { // ... then substitute it with the default. return default_ct.into(); } @@ -1276,15 +1266,12 @@ fn check_where_clauses<'tcx, 'fcx>( .predicates .iter() .flat_map(|&(pred, sp)| { - struct CountParams<'tcx> { - tcx: TyCtxt<'tcx>, + #[derive(Default)] + struct CountParams { params: FxHashSet, } - impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams<'tcx> { + impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams { type BreakTy = (); - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if let ty::Param(param) = t.kind() { @@ -1304,12 +1291,12 @@ fn check_where_clauses<'tcx, 'fcx>( c.super_visit_with(self) } } - let mut param_count = CountParams { tcx: fcx.tcx, params: FxHashSet::default() }; + let mut param_count = CountParams::default(); let has_region = pred.visit_with(&mut param_count).is_break(); let substituted_pred = pred.subst(tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. - if substituted_pred.definitely_has_param_types_or_consts(tcx) + if substituted_pred.has_param_types_or_consts() || param_count.params.len() > 1 || has_region { @@ -1697,7 +1684,7 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirI for obligation in implied_obligations { let pred = obligation.predicate; // Match the existing behavior. - if pred.is_global(fcx.tcx) && !pred.has_late_bound_regions() { + if pred.is_global() && !pred.has_late_bound_regions() { let pred = fcx.normalize_associated_types_in(span, pred); let hir_node = fcx.tcx.hir().find(id); diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index fdc8b6b5e6451..bb407d563e7aa 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -130,7 +130,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn write_ty_to_typeck_results(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) { debug!("write_ty_to_typeck_results({:?}, {:?})", hir_id, ty); - assert!(!ty.needs_infer() && !ty.has_placeholders() && !ty.has_free_regions(self.tcx())); + assert!(!ty.needs_infer() && !ty.has_placeholders() && !ty.has_free_regions()); self.typeck_results.node_types_mut().insert(hir_id, ty); } @@ -750,7 +750,7 @@ impl<'tcx> TypeFolder<'tcx> for EraseEarlyRegions<'tcx> { self.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if ty.has_type_flags(ty::TypeFlags::HAS_POTENTIAL_FREE_REGIONS) { + if ty.has_type_flags(ty::TypeFlags::HAS_FREE_REGIONS) { ty.super_fold_with(self) } else { ty diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 3cccdb27448fd..d3142716390f7 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -67,7 +67,6 @@ 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, @@ -2279,7 +2278,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP tcx, &mut predicates, trait_ref, - &mut cgp::parameters_for_impl(tcx, self_ty, trait_ref), + &mut cgp::parameters_for_impl(self_ty, trait_ref), ); } @@ -2314,7 +2313,7 @@ fn const_evaluatable_predicates_of<'tcx>( assert_eq!(uv.promoted, None); let span = self.tcx.hir().span(c.hir_id); self.preds.insert(( - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink())) + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs)) .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 ae8d262fcf176..e4e1d4c66f0fb 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -6,7 +6,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::{InternalSubsts, SubstsRef}; +use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_span::symbol::Ident; @@ -280,32 +280,6 @@ fn get_path_containing_arg_in_pat<'hir>( arg_path } -pub(super) fn default_anon_const_substs(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> { - let generics = tcx.generics_of(def_id); - if let Some(parent) = generics.parent { - // This is the reason we bother with having optional anon const substs. - // - // In the future the substs of an anon const will depend on its parents predicates - // at which point eagerly looking at them will cause a query cycle. - // - // So for now this is only an assurance that this approach won't cause cycle errors in - // the future. - let _cycle_check = tcx.predicates_of(parent); - } - - let substs = InternalSubsts::identity_for_item(tcx, def_id); - // We only expect substs with the following type flags as default substs. - // - // Getting this wrong can lead to ICE and unsoundness, so we assert it here. - for arg in substs.iter() { - let allowed_flags = ty::TypeFlags::MAY_NEED_DEFAULT_CONST_SUBSTS - | ty::TypeFlags::STILL_FURTHER_SPECIALIZABLE - | ty::TypeFlags::HAS_ERROR; - assert!(!arg.has_type_flags(!allowed_flags)); - } - substs -} - pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { let def_id = def_id.expect_local(); use rustc_hir::*; diff --git a/compiler/rustc_typeck/src/constrained_generic_params.rs b/compiler/rustc_typeck/src/constrained_generic_params.rs index 88877ad78525a..1095290132347 100644 --- a/compiler/rustc_typeck/src/constrained_generic_params.rs +++ b/compiler/rustc_typeck/src/constrained_generic_params.rs @@ -27,13 +27,12 @@ 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(tcx, &tr, false), - None => parameters_for(tcx, &impl_self_ty, false), + Some(tr) => parameters_for(&tr, false), + None => parameters_for(&impl_self_ty, false), }; vec.into_iter().collect() } @@ -44,26 +43,20 @@ 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 { tcx, parameters: vec![], include_nonconstraining }; + let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining }; t.visit_with(&mut collector); collector.parameters } -struct ParameterCollector<'tcx> { - tcx: TyCtxt<'tcx>, +struct ParameterCollector { parameters: Vec, include_nonconstraining: bool, } -impl<'tcx> TypeVisitor<'tcx> for ParameterCollector<'tcx> { - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.tcx) - } - +impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Projection(..) | ty::Opaque(..) if !self.include_nonconstraining => { @@ -205,12 +198,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(tcx, &projection.projection_ty, true); + let inputs = parameters_for(&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(tcx, &projection.ty, false)); + input_parameters.extend(parameters_for(&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 ae6321de7f2d5..16049089151c4 100644 --- a/compiler/rustc_typeck/src/impl_wf_check.rs +++ b/compiler/rustc_typeck/src/impl_wf_check.rs @@ -117,7 +117,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(tcx, impl_self_ty, impl_trait_ref); + let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref); cgp::identify_constrained_generic_params( tcx, impl_predicates, @@ -134,7 +134,7 @@ fn enforce_impl_params_are_constrained( match item.kind { ty::AssocKind::Type => { if item.defaultness.has_value() { - cgp::parameters_for(tcx, &tcx.type_of(def_id), true) + cgp::parameters_for(&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 4fb422c801b1d..6296f2ab32a52 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -206,15 +206,15 @@ fn unconstrained_parent_impl_substs<'tcx>( continue; } - unconstrained_parameters.extend(cgp::parameters_for(tcx, &projection_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(&projection_ty, true)); - for param in cgp::parameters_for(tcx, &projected_ty, false) { + for param in cgp::parameters_for(&projected_ty, false) { if !unconstrained_parameters.contains(¶m) { constrained_params.insert(param.0); } } - unconstrained_parameters.extend(cgp::parameters_for(tcx, &projected_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(&projected_ty, true)); } } @@ -248,7 +248,7 @@ fn check_duplicate_params<'tcx>( parent_substs: &Vec>, span: Span, ) { - let mut base_params = cgp::parameters_for(tcx, parent_substs, true); + let mut base_params = cgp::parameters_for(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]; @@ -376,7 +376,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc match predicate.kind().skip_binder() { // Global predicates are either always true or always false, so we // are fine to specialize on. - _ if predicate.is_global(tcx) => (), + _ if predicate.is_global() => (), // We allow specializing on explicitly marked traits with no associated // items. ty::PredicateKind::Trait(ty::TraitPredicate { diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 86d712e2d7922..89f0bd8d42154 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -114,18 +114,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( required_predicates: &mut RequiredPredicates<'tcx>, explicit_map: &mut ExplicitPredicatesMap<'tcx>, ) { - // We must not look into the default substs of consts - // as computing those depends on the results of `predicates_of`. - // - // Luckily the only types contained in default substs are type - // parameters which don't matter here. - // - // FIXME(adt_const_params): Once complex const parameter types - // are allowed, this might be incorrect. I think that we will still be - // fine, as all outlives relations of the const param types should also - // be part of the adt containing it, but we should still both update the - // documentation and add some tests for this. - for arg in field_ty.walk_ignoring_default_const_substs() { + for arg in field_ty.walk() { let ty = match arg.unpack() { GenericArgKind::Type(ty) => ty, @@ -317,7 +306,7 @@ pub fn check_explicit_predicates<'tcx>( // 'b`. if let Some(self_ty) = ignored_self_ty { if let GenericArgKind::Type(ty) = outlives_predicate.0.unpack() { - if ty.walk(tcx).any(|arg| arg == self_ty.into()) { + if ty.walk().any(|arg| arg == self_ty.into()) { debug!("skipping self ty = {:?}", &ty); continue; } diff --git a/compiler/rustc_typeck/src/variance/constraints.rs b/compiler/rustc_typeck/src/variance/constraints.rs index 33c27ce86ddb5..b2b607a2ffc28 100644 --- a/compiler/rustc_typeck/src/variance/constraints.rs +++ b/compiler/rustc_typeck/src/variance/constraints.rs @@ -405,8 +405,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { match &val.val { ty::ConstKind::Unevaluated(uv) => { - let substs = uv.substs(self.tcx()); - self.add_constraints_from_invariant_substs(current, substs, variance); + self.add_constraints_from_invariant_substs(current, uv.substs, variance); } _ => {} } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index b14430d10e9fc..38da9a4635db8 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -229,7 +229,7 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { crate fn print_const(cx: &DocContext<'_>, n: &ty::Const<'_>) -> String { match n.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs_: _, 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/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index 4ae783a7f46ff..1e53136563885 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 @@ -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:44 + // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:44 -+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[HASH]::BAR), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } ++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[HASH]::BAR), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } + _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44 _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44 - 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 705c2ed06b382..a012285c7ec88 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 @@ -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:55 + // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:55 -+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[HASH]::FOO), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } ++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[HASH]::FOO), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } + _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55 _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55 - 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 7fb954b8356cd..7627ed5462396 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 @@ -31,7 +31,7 @@ // + val: Unevaluated(main, [], 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(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[HASH]::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 7fb954b8356cd..7627ed5462396 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 @@ -31,7 +31,7 @@ // + val: Unevaluated(main, [], 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(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[HASH]::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 827a86c2376e8..e6220176778dc 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 @@ -22,7 +22,7 @@ // + val: Unevaluated(FOO, [], None) // mir::Constant // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[HASH]::main::FOO), const_param_did: None }, substs_: Some([]), promoted: None }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[HASH]::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 496b9718c6ad9..d602e12a370a3 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 @@ -17,7 +17,7 @@ // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/ref_deref.rs:5:6: 5:10 - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[HASH]::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 07c3b0cd58f2d..35916d90e5640 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 @@ -20,7 +20,7 @@ + // + val: Unevaluated(main, [], Some(promoted[0])) + // mir::Constant + // + span: $DIR/ref_deref.rs:5:6: 5:10 -+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } ++ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[HASH]::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 2545b89c1d3ee..39651884e775d 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 @@ -17,7 +17,7 @@ // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/ref_deref_project.rs:5:6: 5:17 - // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[HASH]::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 f728d55ba6ede..501d72056795c 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 @@ -20,7 +20,7 @@ + // + val: Unevaluated(main, [], Some(promoted[0])) + // mir::Constant + // + span: $DIR/ref_deref_project.rs:5:6: 5:17 -+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } ++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[HASH]::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 12c77e0b042a3..6a580278d5f12 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 @@ -25,7 +25,7 @@ // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 - // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[HASH]::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 StorageLive(_10); // 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 12c77e0b042a3..6a580278d5f12 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 @@ -25,7 +25,7 @@ // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 - // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[HASH]::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 StorageLive(_10); // 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 37f6fc91cf95f..486fc7541c3af 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 @@ -38,7 +38,7 @@ fn bar() -> bool { // + val: Unevaluated(bar, [], Some(promoted[1])) // mir::Constant // + span: $DIR/inline-retag.rs:12:7: 12:9 - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[HASH]::bar), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[1]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[HASH]::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 @@ -52,7 +52,7 @@ fn bar() -> bool { // + val: Unevaluated(bar, [], Some(promoted[0])) // mir::Constant // + span: $DIR/inline-retag.rs:12:11: 12:14 - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[HASH]::bar), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[HASH]::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 20e5191310caf..7938c0a23e8e9 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff @@ -66,7 +66,7 @@ // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[HASH]::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 20e5191310caf..7938c0a23e8e9 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff @@ -66,7 +66,7 @@ // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[HASH]::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 04e4af70bb75e..20771bf4231a0 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff @@ -87,7 +87,7 @@ // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[HASH]::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 04e4af70bb75e..20771bf4231a0 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff @@ -87,7 +87,7 @@ // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[HASH]::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 b8f44b7672a20..75d0e75f5b15d 100644 --- a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -50,7 +50,7 @@ // + val: Unevaluated(discriminant, [T], Some(promoted[2])) // mir::Constant // + span: $DIR/lower_intrinsics.rs:75:42: 75:44 - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[HASH]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[2]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[HASH]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) }) } _7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44 _6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44 - _5 = discriminant_value::(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:75:5: 75:45 @@ -74,7 +74,7 @@ // + val: Unevaluated(discriminant, [T], Some(promoted[1])) // mir::Constant // + span: $DIR/lower_intrinsics.rs:76:42: 76:45 - // + literal: Const { ty: &(), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[HASH]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[1]) }) } + // + literal: Const { ty: &(), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[HASH]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) }) } _11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45 _10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45 - _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:76:5: 76:46 @@ -98,7 +98,7 @@ // + val: Unevaluated(discriminant, [T], Some(promoted[0])) // mir::Constant // + span: $DIR/lower_intrinsics.rs:77:42: 77:47 - // + literal: Const { ty: &E, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[HASH]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &E, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[HASH]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) }) } _15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47 _14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47 - _13 = discriminant_value::(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:77:5: 77: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 0ef06da0cb758..51425af4bdf9a 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 @@ -57,7 +57,7 @@ fn full_tested_match() -> () { // + val: Unevaluated(full_tested_match, [], Some(promoted[0])) // mir::Constant // + span: $DIR/match_false_edges.rs:16:14: 16:15 - // + literal: Const { ty: &std::option::Option, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[HASH]::full_tested_match), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &std::option::Option, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[HASH]::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.array_casts.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir index defb04db7dece..1db36c352ff36 100644 --- a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir @@ -127,7 +127,7 @@ fn array_casts() -> () { // + val: Unevaluated(array_casts, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: &usize, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:15 ~ retag[HASH]::array_casts), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &usize, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:15 ~ retag[HASH]::array_casts), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL 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 3f35f15a56d76..cffe723898777 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 @@ -153,7 +153,7 @@ fn main() -> () { // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/retag.rs:47:21: 47:23 - // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[HASH]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) } + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[HASH]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } Retag(_28); // scope 7 at $DIR/retag.rs:47:21: 47:23 _23 = &(*_28); // scope 7 at $DIR/retag.rs:47:21: 47:23 Retag(_23); // scope 7 at $DIR/retag.rs:47:21: 47:23 diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index bc5d2f6278dee..336d098799ac0 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -54,7 +54,7 @@ fn is_non_trait_box(ty: Ty<'_>) -> bool { struct EscapeDelegate<'a, 'tcx> { cx: &'a LateContext<'tcx>, set: HirIdSet, - trait_self_ty: Option>, + trait_self_ty: Option>, too_large_for_stack: u64, } @@ -175,8 +175,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { // skip if there is a `self` parameter binding to a type // that contains `Self` (i.e.: `self: Box`), see #4804 if let Some(trait_self_ty) = self.trait_self_ty { - if map.name(cmt.hir_id) == kw::SelfLower && contains_ty(self.cx.tcx, cmt.place.ty(), trait_self_ty) - { + if map.name(cmt.hir_id) == kw::SelfLower && contains_ty(cmt.place.ty(), trait_self_ty) { return; } } diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs index d03276f7f98ba..cb1ef01f5ba9d 100644 --- a/src/tools/clippy/clippy_lints/src/let_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs @@ -124,7 +124,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { if let Some(init) = local.init; then { let init_ty = cx.typeck_results().expr_ty(init); - let contains_sync_guard = init_ty.walk(cx.tcx).any(|inner| match inner.unpack() { + let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() { GenericArgKind::Type(inner_ty) => { SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path)) }, diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs index 2eb247de9f42b..ab83291461fb4 100644 --- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs +++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs @@ -49,7 +49,7 @@ pub(super) fn check<'tcx>( if same_item_push_visitor.should_lint(); if let Some((vec, pushed_item)) = same_item_push_visitor.vec_push; let vec_ty = cx.typeck_results().expr_ty(vec); - let ty = vec_ty.walk(cx.tcx).nth(1).unwrap().expect_ty(); + let ty = vec_ty.walk().nth(1).unwrap().expect_ty(); if cx .tcx .lang_items() diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 1041f644e32eb..a13b15518612b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -2129,10 +2129,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods { // walk the return type and check for Self (this does not check associated types) if let Some(self_adt) = self_ty.ty_adt_def() { - if contains_adt_constructor(cx.tcx, ret_ty, self_adt) { + if contains_adt_constructor(ret_ty, self_adt) { return; } - } else if contains_ty(cx.tcx, ret_ty, self_ty) { + } else if contains_ty(ret_ty, self_ty) { return; } @@ -2143,10 +2143,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() { // walk the associated type and check for Self if let Some(self_adt) = self_ty.ty_adt_def() { - if contains_adt_constructor(cx.tcx, projection_predicate.ty, self_adt) { + if contains_adt_constructor(projection_predicate.ty, self_adt) { return; } - } else if contains_ty(cx.tcx, projection_predicate.ty, self_ty) { + } else if contains_ty(projection_predicate.ty, self_ty) { return; } } @@ -2195,7 +2195,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if let TraitItemKind::Fn(_, _) = item.kind; let ret_ty = return_ty(cx, item.hir_id()); let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder(); - if !contains_ty(cx.tcx, ret_ty, self_ty); + if !contains_ty(ret_ty, self_ty); then { span_lint( diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 35877d51c0c16..ebd4fb0bf51cc 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -118,7 +118,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { let fn_def_id = cx.tcx.hir().local_def_id(hir_id); let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter()) - .filter(|p| !p.is_global(cx.tcx)) + .filter(|p| !p.is_global()) .filter_map(|obligation| { // Note that we do not want to deal with qualified predicates here. match obligation.predicate.kind().no_bound_vars() { 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 7d2ff083b7e07..88e5f5366b62d 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -188,7 +188,11 @@ 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::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs), + 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_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index 203f03d3603c8..ab1559c85d8b1 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { non_send_fields.push(NonSendField { def: field_def, ty: field_ty, - generic_params: collect_generic_params(cx, field_ty), + generic_params: collect_generic_params(field_ty), }) } } @@ -171,8 +171,8 @@ impl<'tcx> NonSendField<'tcx> { /// Given a type, collect all of its generic parameters. /// Example: `MyStruct>` => `vec![P, Q, R]` -fn collect_generic_params<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Vec> { - ty.walk(cx.tcx) +fn collect_generic_params(ty: Ty<'_>) -> Vec> { + ty.walk() .filter_map(|inner| match inner.unpack() { GenericArgKind::Type(inner_ty) => Some(inner_ty), _ => None, @@ -226,7 +226,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t /// Checks if the type contains any pointer-like types in substs (including nested ones) fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> bool { - for ty_node in target_ty.walk(cx.tcx) { + for ty_node in target_ty.walk() { if let GenericArgKind::Type(inner_ty) = ty_node.unpack() { match inner_ty.kind() { ty::RawPtr(_) => { diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index 1991a01fb60be..dce1f66107a62 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -14,7 +14,7 @@ use rustc_middle::mir::{ visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor as _}, Mutability, }; -use rustc_middle::ty::{self, fold::TypeVisitor, Ty, TyCtxt}; +use rustc_middle::ty::{self, fold::TypeVisitor, Ty}; use rustc_mir_dataflow::{Analysis, AnalysisDomain, CallReturnPlaces, GenKill, GenKillAnalysis, ResultsCursor}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::{BytePos, Span}; @@ -575,7 +575,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> { self.possible_borrower.add(borrowed.local, lhs); }, other => { - if ContainsRegion(self.cx.tcx) + if ContainsRegion .visit_ty(place.ty(&self.body.local_decls, self.cx.tcx).ty) .is_continue() { @@ -624,7 +624,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> { .flat_map(HybridBitSet::iter) .collect(); - if ContainsRegion(self.cx.tcx) + if ContainsRegion .visit_ty(self.body.local_decls[*dest].ty) .is_break() { @@ -703,15 +703,12 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'a, 'tcx> { } } -struct ContainsRegion<'tcx>(TyCtxt<'tcx>); +struct ContainsRegion; -impl<'tcx> TypeVisitor<'tcx> for ContainsRegion<'tcx> { +impl TypeVisitor<'_> for ContainsRegion { type BreakTy = (); - fn tcx_for_anon_const_substs(&self) -> Option> { - Some(self.0) - } - fn visit_region(&mut self, _: ty::Region<'tcx>) -> ControlFlow { + fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow { ControlFlow::BREAK } } diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index 112ccdcdd4202..52e708f628a24 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -301,7 +301,7 @@ impl<'tcx> Visitor<'tcx> for BorrowVisitor<'_, 'tcx> { .fn_sig(def_id) .output() .skip_binder() - .walk(self.cx.tcx) + .walk() .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(_))); } diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index d386663e49858..9516a1ee8726a 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -63,10 +63,10 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { // Ensure method is constructor-like if let Some(self_adt) = self_ty.ty_adt_def() { - if !contains_adt_constructor(cx.tcx, ret_ty, self_adt) { + if !contains_adt_constructor(ret_ty, self_adt) { return; } - } else if !contains_ty(cx.tcx, ret_ty, self_ty) { + } else if !contains_ty(ret_ty, self_ty) { return; } diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs index d024577f48531..32adccdbd1ced 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs @@ -226,7 +226,7 @@ fn expr_borrows(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let ty = cx.typeck_results().expr_ty(expr); matches!(ty.kind(), ty::Ref(..)) || ty - .walk(cx.tcx) + .walk() .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(_))) } diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index a86db58741eb6..cf9a4a5e6d37d 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -170,7 +170,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { // // See also https://github.com/rust-lang/rust-clippy/issues/2894. for (impl_hir_ty, trait_sem_ty) in impl_inputs_outputs.zip(trait_method_sig.inputs_and_output) { - if trait_sem_ty.walk(cx.tcx).any(|inner| inner == self_ty.into()) { + if trait_sem_ty.walk().any(|inner| inner == self_ty.into()) { let mut visitor = SkipTyCollector::default(); visitor.visit_ty(impl_hir_ty); types_to_skip.extend(visitor.types_to_skip); diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 34c5af848a6db..d8f04d0284f1f 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -413,7 +413,11 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { .tcx .const_eval_resolve( self.param_env, - ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs), + ty::Unevaluated { + def: ty::WithOptConstParam::unknown(def_id), + substs, + promoted: None, + }, None, ) .ok() diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 57183b58b2a11..e89c218e2fa64 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1956,7 +1956,7 @@ pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool { .predicates_of(did) .predicates .iter() - .filter_map(|(p, _)| if p.is_global(cx.tcx) { Some(*p) } else { None }); + .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); traits::impossible_predicates( cx.tcx, traits::elaborate_predicates(cx.tcx, predicates) @@ -2002,7 +2002,7 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option return Some("slice".into()), rustc_ty::Array(..) => return Some("array".into()), rustc_ty::Tuple(..) => return Some("tuple".into()), @@ -2010,7 +2010,7 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: } fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult { - for arg in ty.walk(tcx) { + for arg in ty.walk() { let ty = match arg.unpack() { GenericArgKind::Type(ty) => ty, diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 72317447159a9..f109b7845b4bd 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -37,8 +37,8 @@ pub fn can_partially_move_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool } /// Walks into `ty` and returns `true` if any inner type is the same as `other_ty` -pub fn contains_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, other_ty: Ty<'tcx>) -> bool { - ty.walk(tcx).any(|inner| match inner.unpack() { +pub fn contains_ty(ty: Ty<'_>, other_ty: Ty<'_>) -> bool { + ty.walk().any(|inner| match inner.unpack() { GenericArgKind::Type(inner_ty) => ty::TyS::same_type(other_ty, inner_ty), GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false, }) @@ -46,8 +46,8 @@ pub fn contains_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, other_ty: Ty<'tcx>) -> /// Walks into `ty` and returns `true` if any inner type is an instance of the given adt /// constructor. -pub fn contains_adt_constructor<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, adt: &'tcx AdtDef) -> bool { - ty.walk(tcx).any(|inner| match inner.unpack() { +pub fn contains_adt_constructor(ty: Ty<'_>, adt: &AdtDef) -> bool { + ty.walk().any(|inner| match inner.unpack() { GenericArgKind::Type(inner_ty) => inner_ty.ty_adt_def() == Some(adt), GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false, }) @@ -221,7 +221,7 @@ fn is_normalizable_helper<'tcx>( .iter() .all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache)) }), - _ => ty.walk(cx.tcx).all(|generic_arg| match generic_arg.unpack() { + _ => ty.walk().all(|generic_arg| match generic_arg.unpack() { GenericArgKind::Type(inner_ty) if inner_ty != ty => { is_normalizable_helper(cx, param_env, inner_ty, cache) }, From dec8ed438c530a3b722a5ee881c9fef180cc97b1 Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 12 Jan 2022 23:29:10 +0000 Subject: [PATCH 2/4] attempt to re-add `ty::Unevaluated` visitor and friends --- compiler/rustc_infer/src/infer/mod.rs | 9 +-- compiler/rustc_middle/src/query/mod.rs | 5 +- compiler/rustc_middle/src/ty/consts/kind.rs | 48 +++++++++++---- compiler/rustc_middle/src/ty/flags.rs | 12 +++- compiler/rustc_middle/src/ty/fold.rs | 16 +++++ compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +- compiler/rustc_middle/src/ty/relate.rs | 2 +- .../rustc_middle/src/ty/structural_impls.rs | 60 +++++++++++++++---- compiler/rustc_mir_build/src/thir/cx/expr.rs | 14 ++--- compiler/rustc_privacy/src/lib.rs | 4 +- compiler/rustc_query_impl/src/keys.rs | 11 +--- .../src/traits/const_evaluatable.rs | 58 +++++++----------- .../src/traits/error_reporting/mod.rs | 4 +- .../src/traits/fulfill.rs | 11 ++-- .../src/traits/object_safety.rs | 4 +- .../src/traits/select/mod.rs | 7 +-- .../rustc_trait_selection/src/traits/wf.rs | 14 ++--- compiler/rustc_typeck/src/check/dropck.rs | 6 +- compiler/rustc_typeck/src/check/wfcheck.rs | 4 +- compiler/rustc_typeck/src/collect.rs | 2 +- 21 files changed, 175 insertions(+), 122 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 39822d1af7d17..266eec08cebf5 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -668,13 +668,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// canonicalizing the consts. pub fn try_unify_abstract_consts( &self, - a: ty::Unevaluated<'tcx>, - b: ty::Unevaluated<'tcx>, + a: ty::Unevaluated<'tcx, ()>, + b: ty::Unevaluated<'tcx, ()>, ) -> bool { - let canonical = self.canonicalize_query( - ((a.def, a.substs), (b.def, b.substs)), - &mut OriginalQueryValues::default(), - ); + let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default()); debug!("canonical consts: {:?}", &canonical.value); self.tcx.try_unify_abstract_consts(canonical.value) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 73bda1337b679..5dc7b21964266 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -314,12 +314,11 @@ rustc_queries! { } query try_unify_abstract_consts(key: ( - (ty::WithOptConstParam, SubstsRef<'tcx>), - (ty::WithOptConstParam, SubstsRef<'tcx>) + ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()> )) -> bool { desc { |tcx| "trying to unify the generic constants {} and {}", - tcx.def_path_str(key.0.0.did), tcx.def_path_str(key.1.0.did) + tcx.def_path_str(key.0.def.did), tcx.def_path_str(key.1.def.did) } } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index f2db95d162b88..8dbd2596ad895 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -12,12 +12,31 @@ use rustc_target::abi::Size; use super::ScalarInt; /// An unevaluated, potentially generic, constant. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)] #[derive(Hash, HashStable)] -pub struct Unevaluated<'tcx> { +pub struct Unevaluated<'tcx, P = Option> { pub def: ty::WithOptConstParam, pub substs: SubstsRef<'tcx>, - pub promoted: Option, + pub promoted: P, +} + +impl<'tcx> Unevaluated<'tcx> { + pub fn shrink(self) -> Unevaluated<'tcx, ()> { + debug_assert_eq!(self.promoted, None); + Unevaluated { def: self.def, substs: self.substs, promoted: () } + } +} + +impl<'tcx> Unevaluated<'tcx, ()> { + pub fn expand(self) -> Unevaluated<'tcx> { + Unevaluated { def: self.def, substs: self.substs, promoted: None } + } +} + +impl<'tcx, P: Default> Unevaluated<'tcx, P> { + pub fn new(def: ty::WithOptConstParam, substs: SubstsRef<'tcx>) -> Unevaluated<'tcx, P> { + Unevaluated { def, substs, promoted: Default::default() } + } } /// Represents a constant in Rust. @@ -109,7 +128,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` @@ -118,29 +137,32 @@ 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, + substs: 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 cc858771b423a..b6e673983fd4e 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -34,6 +34,12 @@ impl FlagComputation { result.flags } + pub fn for_unevaluated_const(uv: ty::Unevaluated<'_>) -> TypeFlags { + let mut result = FlagComputation::new(); + result.add_unevaluated_const(uv); + result.flags + } + fn add_flags(&mut self, flags: TypeFlags) { self.flags = self.flags | flags; } @@ -246,8 +252,8 @@ impl FlagComputation { ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => { self.add_substs(substs); } - ty::PredicateKind::ConstEvaluatable(_def_id, substs) => { - self.add_substs(substs); + ty::PredicateKind::ConstEvaluatable(uv) => { + self.add_unevaluated_const(uv); } ty::PredicateKind::ConstEquate(expected, found) => { self.add_const(expected); @@ -304,7 +310,7 @@ impl FlagComputation { } } - fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'_>) { + fn add_unevaluated_const

(&mut self, ct: ty::Unevaluated<'_, P>) { self.add_substs(ct.substs); self.add_flags(TypeFlags::HAS_CT_PROJECTION); } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 1288b6e1a8b07..3133cdfdd7a72 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -350,6 +350,10 @@ pub trait TypeVisitor<'tcx>: Sized { c.super_visit_with(self) } + fn visit_unevaluated_const(&mut self, uv: ty::Unevaluated<'tcx>) -> ControlFlow { + uv.super_visit_with(self) + } + fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow { p.super_visit_with(self) } @@ -1242,6 +1246,18 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { } } + #[inline] + #[instrument(level = "trace")] + fn visit_unevaluated_const(&mut self, uv: ty::Unevaluated<'tcx>) -> ControlFlow { + let flags = FlagComputation::for_unevaluated_const(uv); + trace!(r.flags=?flags); + if flags.intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::CONTINUE + } + } + #[inline] #[instrument(level = "trace")] fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8d3dab7c6b3be..82700537d3a83 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -598,7 +598,7 @@ pub enum PredicateKind<'tcx> { Coerce(CoercePredicate<'tcx>), /// Constant initializer must evaluate successfully. - ConstEvaluatable(ty::WithOptConstParam, SubstsRef<'tcx>), + ConstEvaluatable(ty::Unevaluated<'tcx, ()>), /// Constants must be equal. The first component is the const that is expected. ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f5d3861bab4c4..d9167e1980f62 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2539,8 +2539,8 @@ define_print_and_forward_display! { print_value_path(closure_def_id, &[]), write("` implements the trait `{}`", kind)) } - ty::PredicateKind::ConstEvaluatable(def, substs) => { - p!("the constant `", print_value_path(def.did, substs), "` can be evaluated") + ty::PredicateKind::ConstEvaluatable(uv) => { + p!("the constant `", print_value_path(uv.def.did, uv.substs), "` can be evaluated") } ty::PredicateKind::ConstEquate(c1, c2) => { p!("the constant `", print(c1), "` equals `", print(c2), "`") diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 97b5d52ea38e4..9e381cabdfe84 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -587,7 +587,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if tcx.features().generic_const_exprs => { - tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs))) + tcx.try_unify_abstract_consts((au.shrink(), bu.shrink())) } // While this is slightly incorrect, it shouldn't matter for `min_const_generics` diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 1c49ceeb1535e..63ebbcbc5bb67 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -184,8 +184,8 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) } - ty::PredicateKind::ConstEvaluatable(def_id, substs) => { - write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) + ty::PredicateKind::ConstEvaluatable(uv) => { + write!(f, "ConstEvaluatable({:?}, {:?})", uv.def, uv.substs) } ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2), ty::PredicateKind::TypeWellFormedFromEnv(ty) => { @@ -445,8 +445,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { ty::PredicateKind::ObjectSafe(trait_def_id) => { Some(ty::PredicateKind::ObjectSafe(trait_def_id)) } - ty::PredicateKind::ConstEvaluatable(def_id, substs) => { - tcx.lift(substs).map(|substs| ty::PredicateKind::ConstEvaluatable(def_id, substs)) + ty::PredicateKind::ConstEvaluatable(uv) => { + tcx.lift(uv).map(|uv| ty::PredicateKind::ConstEvaluatable(uv)) } ty::PredicateKind::ConstEquate(c1, c2) => { tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2)) @@ -1185,13 +1185,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { Ok(match self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?), - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs: substs.try_fold_with(folder)?, - promoted, - }) - } + ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) @@ -1203,7 +1197,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(_) @@ -1224,3 +1218,45 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { ControlFlow::CONTINUE } } + +impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + Ok(ty::Unevaluated { + def: self.def, + substs: self.substs.try_fold_with(folder)?, + promoted: self.promoted, + }) + } + + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + visitor.visit_unevaluated_const(*self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.substs.visit_with(visitor) + } +} + +impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + Ok(ty::Unevaluated { + def: self.def, + substs: self.substs.try_fold_with(folder)?, + promoted: self.promoted, + }) + } + + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + visitor.visit_unevaluated_const(self.expand()) + } + + fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.substs.visit_with(visitor) + } +} diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index e090ecf2114d6..c62de1543883e 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -716,11 +716,10 @@ impl<'tcx> Cx<'tcx> { // and not the beginning of discriminants (which is always `0`) let substs = InternalSubsts::identity_for_item(self.tcx(), did); let lhs = ty::Const { - val: ty::ConstKind::Unevaluated(ty::Unevaluated { - def: ty::WithOptConstParam::unknown(did), + val: ty::ConstKind::Unevaluated(ty::Unevaluated::new( + ty::WithOptConstParam::unknown(did), substs, - promoted: None, - }), + )), ty: var_ty, }; let lhs = self.thir.exprs.push(mk_const(self.tcx().mk_const(lhs))); @@ -912,11 +911,10 @@ impl<'tcx> Cx<'tcx> { debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { literal: self.tcx.mk_const(ty::Const { - val: ty::ConstKind::Unevaluated(ty::Unevaluated { - def: ty::WithOptConstParam::unknown(def_id), + val: ty::ConstKind::Unevaluated(ty::Unevaluated::new( + ty::WithOptConstParam::unknown(def_id), substs, - promoted: None, - }), + )), ty: self.typeck_results().node_type(expr.hir_id), }), user_ty, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index aa9ccddbdc5ba..217d767e4ab8e 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -135,11 +135,11 @@ where ty.visit_with(self) } ty::PredicateKind::RegionOutlives(..) => ControlFlow::CONTINUE, - ty::PredicateKind::ConstEvaluatable(defs, substs) + ty::PredicateKind::ConstEvaluatable(uv) if self.def_id_visitor.tcx().features().generic_const_exprs => { let tcx = self.def_id_visitor.tcx(); - if let Ok(Some(ct)) = AbstractConst::new(tcx, defs, substs) { + if let Ok(Some(ct)) = AbstractConst::new(tcx, uv) { self.visit_abstract_const_expr(tcx, ct)?; } ControlFlow::CONTINUE diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index 8ab48b838ea69..581a2bce2e50e 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -245,18 +245,13 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { } } -impl<'tcx> Key - for ( - (ty::WithOptConstParam, SubstsRef<'tcx>), - (ty::WithOptConstParam, SubstsRef<'tcx>), - ) -{ +impl<'tcx> Key for (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>) { #[inline(always)] fn query_crate_is_local(&self) -> bool { - (self.0).0.did.krate == LOCAL_CRATE + (self.0).def.did.krate == LOCAL_CRATE } fn default_span(&self, tcx: TyCtxt<'_>) -> Span { - (self.0).0.did.default_span(tcx) + (self.0).def.did.default_span(tcx) } } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 7d02983569ef3..5a69c5d50ff76 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -19,7 +19,7 @@ use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; use rustc_session::lint; -use rustc_span::def_id::{DefId, LocalDefId}; +use rustc_span::def_id::LocalDefId; use rustc_span::Span; use std::cmp; @@ -29,26 +29,20 @@ use std::ops::ControlFlow; /// Check if a given constant can be evaluated. pub fn is_const_evaluatable<'cx, 'tcx>( infcx: &InferCtxt<'cx, 'tcx>, - def: ty::WithOptConstParam, - substs: SubstsRef<'tcx>, + uv: ty::Unevaluated<'tcx, ()>, param_env: ty::ParamEnv<'tcx>, span: Span, ) -> Result<(), NotConstEvaluatable> { - debug!("is_const_evaluatable({:?}, {:?})", def, substs); + debug!("is_const_evaluatable({:?})", uv); if infcx.tcx.features().generic_const_exprs { let tcx = infcx.tcx; - match AbstractConst::new(tcx, def, substs)? { + match AbstractConst::new(tcx, uv)? { // We are looking at a generic abstract constant. Some(ct) => { for pred in param_env.caller_bounds() { match pred.kind().skip_binder() { - ty::PredicateKind::ConstEvaluatable(b_def, b_substs) => { - if b_def == def && b_substs == substs { - debug!("is_const_evaluatable: caller_bound ~~> ok"); - return Ok(()); - } - - if let Some(b_ct) = AbstractConst::new(tcx, b_def, b_substs)? { + ty::PredicateKind::ConstEvaluatable(uv) => { + if let Some(b_ct) = AbstractConst::new(tcx, uv)? { // Try to unify with each subtree in the AbstractConst to allow for // `N + 1` being const evaluatable even if theres only a `ConstEvaluatable` // predicate for `(N + 1) * 2` @@ -132,7 +126,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } let future_compat_lint = || { - if let Some(local_def_id) = def.did.as_local() { + if let Some(local_def_id) = uv.def.did.as_local() { infcx.tcx.struct_span_lint_hir( lint::builtin::CONST_EVALUATABLE_UNCHECKED, infcx.tcx.hir().local_def_id_to_hir_id(local_def_id), @@ -153,16 +147,12 @@ 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, - 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) { + let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); + + if concrete.is_ok() && uv.substs.has_param_types_or_consts() { + match infcx.tcx.def_kind(uv.def.did) { DefKind::AnonConst | DefKind::InlineConst => { - let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(def); + let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def); if mir_body.is_polymorphic { future_compat_lint(); @@ -174,7 +164,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( debug!(?concrete, "is_const_evaluatable"); match concrete { - Err(ErrorHandled::TooGeneric) => Err(match substs.has_infer_types_or_consts() { + Err(ErrorHandled::TooGeneric) => Err(match uv.has_infer_types_or_consts() { true => NotConstEvaluatable::MentionsInfer, false => NotConstEvaluatable::MentionsParam, }), @@ -202,12 +192,11 @@ pub struct AbstractConst<'tcx> { impl<'tcx> AbstractConst<'tcx> { pub fn new( tcx: TyCtxt<'tcx>, - def: ty::WithOptConstParam, - substs: SubstsRef<'tcx>, + uv: ty::Unevaluated<'tcx, ()>, ) -> Result>, ErrorReported> { - let inner = tcx.thir_abstract_const_opt_const_arg(def)?; - debug!("AbstractConst::new({:?}, {:?}) = {:?}", def, substs, inner); - Ok(inner.map(|inner| AbstractConst { inner, substs })) + let inner = tcx.thir_abstract_const_opt_const_arg(uv.def)?; + debug!("AbstractConst::new({:?}) = {:?}", uv, inner); + Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs })) } pub fn from_const( @@ -215,9 +204,7 @@ impl<'tcx> 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.shrink()), ty::ConstKind::Error(_) => Err(ErrorReported), _ => Ok(None), } @@ -539,14 +526,11 @@ pub(super) fn thir_abstract_const<'tcx>( pub(super) fn try_unify_abstract_consts<'tcx>( tcx: TyCtxt<'tcx>, - ((a, a_substs), (b, b_substs)): ( - (ty::WithOptConstParam, SubstsRef<'tcx>), - (ty::WithOptConstParam, SubstsRef<'tcx>), - ), + (a, b): (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>), ) -> bool { (|| { - if let Some(a) = AbstractConst::new(tcx, a, a_substs)? { - if let Some(b) = AbstractConst::new(tcx, b, b_substs)? { + if let Some(a) = AbstractConst::new(tcx, a)? { + if let Some(b) = AbstractConst::new(tcx, b)? { return Ok(try_unify(tcx, a, b)); } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 711f242333ceb..72878b6cb3858 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -819,10 +819,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::ConstEvaluatable(def, _) => { + ty::PredicateKind::ConstEvaluatable(uv) => { let mut err = self.tcx.sess.struct_span_err(span, "unconstrained generic constant"); - let const_span = self.tcx.def_span(def.did); + let const_span = self.tcx.def_span(uv.def.did); match self.tcx.sess.source_map().span_to_snippet(const_span) { Ok(snippet) => err.help(&format!( "try adding a `where` bound using this expression: `where [(); {}]:`", diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index be8a64e529956..346590a2de26f 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -527,11 +527,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { } } - ty::PredicateKind::ConstEvaluatable(def_id, substs) => { + ty::PredicateKind::ConstEvaluatable(uv) => { match const_evaluatable::is_const_evaluatable( self.selcx.infcx(), - def_id, - substs, + uv, obligation.param_env, obligation.cause.span, ) { @@ -539,7 +538,9 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { Err(NotConstEvaluatable::MentionsInfer) => { pending_obligation.stalled_on.clear(); pending_obligation.stalled_on.extend( - substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg), + uv.substs + .iter() + .filter_map(TyOrConstInferVar::maybe_from_generic_arg), ); ProcessResult::Unchanged } @@ -563,7 +564,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.val, c2.val) { - if infcx.try_unify_abstract_consts(a, b) { + if infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) { return ProcessResult::Changed(vec![]); } } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 1e2c0f546555f..8a1864278de3e 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -845,12 +845,12 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( } fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow { - if let ty::PredicateKind::ConstEvaluatable(def, substs) = pred.kind().skip_binder() { + if let ty::PredicateKind::ConstEvaluatable(uv) = pred.kind().skip_binder() { // FIXME(generic_const_exprs): We should probably deduplicate the logic for // `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to // take a `ty::Const` instead. use rustc_middle::thir::abstract_const::Node; - if let Ok(Some(ct)) = AbstractConst::new(self.tcx, def, substs) { + if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv) { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| { match node.root(self.tcx) { Node::Leaf(leaf) => self.visit_const(leaf), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 79f54e6aba02d..20e2fc24df18a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -619,11 +619,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::PredicateKind::ConstEvaluatable(def_id, substs) => { + ty::PredicateKind::ConstEvaluatable(uv) => { match const_evaluatable::is_const_evaluatable( self.infcx, - def_id, - substs, + uv, obligation.param_env, obligation.cause.span, ) { @@ -645,7 +644,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.val, c2.val) { - if self.infcx.try_unify_abstract_consts(a, b) { + if self.infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) { return Ok(EvaluatedToOk); } } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 044861829f1d3..dcf9bdc1e1bbe 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -131,11 +131,11 @@ pub fn predicate_obligations<'a, 'tcx>( wf.compute(a.into()); wf.compute(b.into()); } - ty::PredicateKind::ConstEvaluatable(def, substs) => { - let obligations = wf.nominal_obligations(def.did, substs); + ty::PredicateKind::ConstEvaluatable(uv) => { + let obligations = wf.nominal_obligations(uv.def.did, uv.substs); wf.out.extend(obligations); - for arg in substs.iter() { + for arg in uv.substs.iter() { wf.compute(arg); } } @@ -441,14 +441,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 obligations = self.nominal_obligations(def.did, substs); + let obligations = self.nominal_obligations(uv.def.did, uv.substs); self.out.extend(obligations); let predicate = - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(def, substs)) + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink())) .to_predicate(self.tcx()); let cause = self.cause(traits::MiscObligation); self.out.push(traits::Obligation::with_depth( diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 7d7289772629b..3cc66aaf0d79c 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -237,9 +237,9 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( relator.relate(predicate.rebind(a), p.rebind(b)).is_ok() } ( - ty::PredicateKind::ConstEvaluatable(a_def, a_substs), - ty::PredicateKind::ConstEvaluatable(b_def, b_substs), - ) => tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))), + ty::PredicateKind::ConstEvaluatable(a), + ty::PredicateKind::ConstEvaluatable(b), + ) => tcx.try_unify_abstract_consts((a, b)), ( ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_a, lt_a)), ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_b, lt_b)), diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 9f8e06adbf953..abd237f4a757b 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -972,10 +972,10 @@ fn check_type_defn<'tcx, F>( fcx.register_predicate(traits::Obligation::new( cause, fcx.param_env, - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable( + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new( ty::WithOptConstParam::unknown(discr_def_id.to_def_id()), discr_substs, - )) + ))) .to_predicate(tcx), )); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index d3142716390f7..cdd6ddaa9b8a6 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2313,7 +2313,7 @@ fn const_evaluatable_predicates_of<'tcx>( assert_eq!(uv.promoted, None); let span = self.tcx.hir().span(c.hir_id); self.preds.insert(( - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs)) + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink())) .to_predicate(self.tcx), span, )); From 408a086f97992f4b035e20303242c527e32b2491 Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 12 Jan 2022 23:38:32 +0000 Subject: [PATCH 3/4] unrevert # 88557 --- .../src/traits/object_safety.rs | 33 +++---------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8a1864278de3e..185d64eab707a 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -813,9 +813,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( } } - fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow { - self.visit_ty(ct.ty)?; - + fn visit_unevaluated_const( + &mut self, + uv: ty::Unevaluated<'tcx>, + ) -> ControlFlow { // Constants can only influence object safety if they reference `Self`. // This is only possible for unevaluated constants, so we walk these here. // @@ -829,7 +830,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( // This shouldn't really matter though as we can't really use any // constants which are not considered const evaluatable. use rustc_middle::thir::abstract_const::Node; - if let Ok(Some(ct)) = AbstractConst::from_const(self.tcx, ct) { + if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| { match node.root(self.tcx) { Node::Leaf(leaf) => self.visit_const(leaf), @@ -843,30 +844,6 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( ControlFlow::CONTINUE } } - - fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow { - if let ty::PredicateKind::ConstEvaluatable(uv) = pred.kind().skip_binder() { - // FIXME(generic_const_exprs): We should probably deduplicate the logic for - // `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to - // take a `ty::Const` instead. - use rustc_middle::thir::abstract_const::Node; - if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv) { - const_evaluatable::walk_abstract_const(self.tcx, ct, |node| { - match node.root(self.tcx) { - Node::Leaf(leaf) => self.visit_const(leaf), - Node::Cast(_, _, ty) => self.visit_ty(ty), - Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { - ControlFlow::CONTINUE - } - } - }) - } else { - ControlFlow::CONTINUE - } - } else { - pred.super_visit_with(self) - } - } } value From 3f3a10fa64278173718b1fb9ee9ae85b14380af0 Mon Sep 17 00:00:00 2001 From: Ellen Date: Thu, 13 Jan 2022 09:26:27 +0000 Subject: [PATCH 4/4] nyahggdshjjghsdfhgsf --- compiler/rustc_middle/src/ty/consts/kind.rs | 3 +++ compiler/rustc_trait_selection/src/traits/wf.rs | 2 -- compiler/rustc_typeck/src/check/check.rs | 8 ++++---- src/tools/clippy/clippy_lints/src/escape.rs | 2 +- src/tools/clippy/clippy_lints/src/non_copy_const.rs | 7 +++---- src/tools/clippy/clippy_utils/src/consts.rs | 7 +++---- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 8dbd2596ad895..af7c2c5cb4cff 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -21,6 +21,7 @@ pub struct Unevaluated<'tcx, P = Option> { } impl<'tcx> Unevaluated<'tcx> { + #[inline] pub fn shrink(self) -> Unevaluated<'tcx, ()> { debug_assert_eq!(self.promoted, None); Unevaluated { def: self.def, substs: self.substs, promoted: () } @@ -28,12 +29,14 @@ impl<'tcx> Unevaluated<'tcx> { } impl<'tcx> Unevaluated<'tcx, ()> { + #[inline] pub fn expand(self) -> Unevaluated<'tcx> { Unevaluated { def: self.def, substs: self.substs, promoted: None } } } impl<'tcx, P: Default> Unevaluated<'tcx, P> { + #[inline] pub fn new(def: ty::WithOptConstParam, substs: SubstsRef<'tcx>) -> Unevaluated<'tcx, P> { Unevaluated { def, substs, promoted: Default::default() } } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index dcf9bdc1e1bbe..f6e98f427108f 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -442,8 +442,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { GenericArgKind::Const(constant) => { match constant.val { ty::ConstKind::Unevaluated(uv) => { - assert!(uv.promoted.is_none()); - let obligations = self.nominal_obligations(uv.def.did, uv.substs); self.out.extend(obligations); diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 3a26fa82892cc..5c64312c28f84 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -491,9 +491,9 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( } struct ProhibitOpaqueVisitor<'tcx> { + tcx: TyCtxt<'tcx>, opaque_identity_ty: Ty<'tcx>, generics: &'tcx ty::Generics, - tcx: TyCtxt<'tcx>, selftys: Vec<(Span, Option)>, } @@ -1471,8 +1471,8 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t))) .filter(|(_, ty)| !matches!(ty.kind(), ty::Never)) { - struct VisitTypes(Vec); - impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes { + struct OpaqueTypeCollector(Vec); + impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypeCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Opaque(def, _) => { @@ -1483,7 +1483,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { } } } - let mut visitor = VisitTypes(vec![]); + let mut visitor = OpaqueTypeCollector(vec![]); ty.visit_with(&mut visitor); for def_id in visitor.0 { let ty_span = tcx.def_span(def_id); diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 336d098799ac0..d6e2bb806887d 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -54,7 +54,7 @@ fn is_non_trait_box(ty: Ty<'_>) -> bool { struct EscapeDelegate<'a, 'tcx> { cx: &'a LateContext<'tcx>, set: HirIdSet, - trait_self_ty: Option>, + trait_self_ty: Option>, too_large_for_stack: u64, } 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 88e5f5366b62d..435f3071c8091 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -188,11 +188,10 @@ 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::Unevaluated { - def: ty::WithOptConstParam::unknown(def_id), + ty::Unevaluated::new( + 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 d8f04d0284f1f..e09a663538ddc 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -413,11 +413,10 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { .tcx .const_eval_resolve( self.param_env, - ty::Unevaluated { - def: ty::WithOptConstParam::unknown(def_id), + ty::Unevaluated::new( + ty::WithOptConstParam::unknown(def_id), substs, - promoted: None, - }, + ), None, ) .ok()