From f4b606fd1703fb54bf75f064482312a67beb4a7b Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 13 Mar 2021 16:05:15 +0100 Subject: [PATCH] require a `tcx` for `TypeVisitor` --- .../src/infer/error_reporting/mod.rs | 4 ++ .../nice_region_error/static_impl_trait.rs | 12 +++-- .../rustc_infer/src/infer/nll_relate/mod.rs | 6 +++ compiler/rustc_infer/src/infer/resolve.rs | 5 ++ compiler/rustc_lint/src/types.rs | 3 ++ compiler/rustc_middle/src/ty/fold.rs | 46 +++++++++++++++---- compiler/rustc_middle/src/ty/print/pretty.rs | 6 +++ compiler/rustc_mir/src/interpret/util.rs | 4 ++ .../src/monomorphize/polymorphize.rs | 14 ++++-- compiler/rustc_mir/src/util/pretty.rs | 4 ++ compiler/rustc_privacy/src/lib.rs | 4 ++ .../rustc_trait_selection/src/opaque_types.rs | 12 ++++- .../src/traits/object_safety.rs | 3 ++ .../src/traits/structural_match.rs | 3 ++ compiler/rustc_traits/src/chalk/lowering.rs | 14 +++++- compiler/rustc_ty_utils/src/instance.rs | 3 ++ compiler/rustc_typeck/src/check/check.rs | 17 +++++-- compiler/rustc_typeck/src/check/op.rs | 11 +++-- compiler/rustc_typeck/src/check/wfcheck.rs | 11 +++-- compiler/rustc_typeck/src/collect.rs | 2 +- .../src/constrained_generic_params.rs | 21 ++++++--- compiler/rustc_typeck/src/impl_wf_check.rs | 4 +- .../src/impl_wf_check/min_specialization.rs | 8 ++-- .../clippy_lints/src/redundant_clone.rs | 15 +++--- 24 files changed, 182 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 4830158c15a..14fdf03e06d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1537,6 +1537,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> { + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) { let span = self.tcx.def_span(def_id); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index fde4ec05ffc..d3d55d89db6 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 @@ -9,7 +9,9 @@ use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorRepor use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor}; use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind}; -use rustc_middle::ty::{self, AssocItemContainer, RegionKind, Ty, TypeFoldable, TypeVisitor}; +use rustc_middle::ty::{ + self, AssocItemContainer, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor, +}; use rustc_span::symbol::Ident; use rustc_span::{MultiSpan, Span}; @@ -476,8 +478,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Collect all the trait objects in a type that could have received an implicit `'static` lifetime. pub(super) struct TraitObjectVisitor(pub(super) FxHashSet); -impl TypeVisitor<'_> for TraitObjectVisitor { - fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow { +impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor { + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for TraitObjectVisitor"); + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Dynamic(preds, RegionKind::ReStatic) => { if let Some(def_id) = preds.principal_def_id() { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 042e6159aff..8f1ebb116fd 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -202,6 +202,7 @@ where }; value.skip_binder().visit_with(&mut ScopeInstantiator { + tcx: self.infcx.tcx, next_region: &mut next_region, target_index: ty::INNERMOST, bound_region_scope: &mut scope, @@ -757,6 +758,7 @@ where /// `for<..`>. For each of those, it creates an entry in /// `bound_region_scope`. struct ScopeInstantiator<'me, 'tcx> { + tcx: TyCtxt<'tcx>, next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>, // The debruijn index of the scope we are instantiating. target_index: ty::DebruijnIndex, @@ -764,6 +766,10 @@ struct ScopeInstantiator<'me, 'tcx> { } impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> { + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>( &mut self, t: &ty::Binder<'tcx, T>, diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 48b8ee17594..e5ad44c7427 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -126,6 +126,11 @@ impl<'a, 'tcx> UnresolvedTypeFinder<'a, 'tcx> { impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> { type BreakTy = (Ty<'tcx>, Option); + + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + 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/types.rs b/compiler/rustc_lint/src/types.rs index 829a2abef0d..1194d8edc09 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1160,6 +1160,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> { type BreakTy = Ty<'tcx>; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.cx.tcx + } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { match ty.kind() { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index a40210d5a36..40b3ffb8955 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -189,6 +189,12 @@ pub trait TypeFolder<'tcx>: Sized { pub trait TypeVisitor<'tcx>: Sized { type BreakTy = !; + /// Supplies the `tcx` for an unevaluated anonymous constant in case its default substs + /// are not yet supplied. + /// + /// Visitors which do not look into these substs may leave this unimplemented, so be + /// careful when calling this method elsewhere. + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx>; fn visit_binder>( &mut self, @@ -301,7 +307,8 @@ impl<'tcx> TyCtxt<'tcx> { value: &impl TypeFoldable<'tcx>, callback: impl FnMut(ty::Region<'tcx>) -> bool, ) -> bool { - struct RegionVisitor { + struct RegionVisitor<'tcx, F> { + tcx: TyCtxt<'tcx>, /// The index of a binder *just outside* the things we have /// traversed. If we encounter a bound region bound by this /// binder or one outer to it, it appears free. Example: @@ -323,12 +330,16 @@ impl<'tcx> TyCtxt<'tcx> { callback: F, } - impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor + impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<'tcx, F> where F: FnMut(ty::Region<'tcx>) -> bool, { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>( &mut self, t: &Binder<'tcx, T>, @@ -364,7 +375,9 @@ impl<'tcx> TyCtxt<'tcx> { } } - value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback }).is_break() + value + .visit_with(&mut RegionVisitor { tcx: self, outer_index: ty::INNERMOST, callback }) + .is_break() } } @@ -708,7 +721,7 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable<'tcx>, { - let mut collector = LateBoundRegionsCollector::new(just_constraint); + let mut collector = LateBoundRegionsCollector::new(self, just_constraint); let result = value.as_ref().skip_binder().visit_with(&mut collector); assert!(result.is_continue()); // should never have stopped early collector.regions @@ -775,6 +788,10 @@ impl<'tcx> ValidateBoundVars<'tcx> { impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("default anon const substs can't contain bound vars"); + } + fn visit_binder>( &mut self, t: &Binder<'tcx, T>, @@ -989,6 +1006,10 @@ struct HasEscapingVarsVisitor { impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { type BreakTy = FoundEscapingVars; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for HasEscpaingVarsVisitor"); + } + fn visit_binder>( &mut self, t: &Binder<'tcx, T>, @@ -1059,6 +1080,9 @@ struct HasTypeFlagsVisitor { impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { type BreakTy = FoundFlags; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for HasTypeFlagsVisitor"); + } #[inline] fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow { @@ -1113,7 +1137,8 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { /// Collects all the late-bound regions at the innermost binding level /// into a hash set. -struct LateBoundRegionsCollector { +struct LateBoundRegionsCollector<'tcx> { + tcx: TyCtxt<'tcx>, current_index: ty::DebruijnIndex, regions: FxHashSet, @@ -1127,9 +1152,10 @@ struct LateBoundRegionsCollector { just_constrained: bool, } -impl LateBoundRegionsCollector { - fn new(just_constrained: bool) -> Self { +impl LateBoundRegionsCollector<'tcx> { + fn new(tcx: TyCtxt<'tcx>, just_constrained: bool) -> Self { LateBoundRegionsCollector { + tcx, current_index: ty::INNERMOST, regions: Default::default(), just_constrained, @@ -1137,7 +1163,11 @@ impl LateBoundRegionsCollector { } } -impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { +impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector<'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>( &mut self, t: &Binder<'tcx, T>, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 4befeb1d827..ef999285f53 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2017,6 +2017,7 @@ impl FmtPrinter<'_, 'tcx, F> { debug!("prepare_late_bound_region_info(value: {:?})", value); struct LateBoundRegionNameCollector<'a, 'tcx> { + tcx: TyCtxt<'tcx>, used_region_names: &'a mut FxHashSet, type_collector: SsoHashSet>, } @@ -2024,6 +2025,10 @@ impl FmtPrinter<'_, 'tcx, F> { impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_, 'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r); if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r { @@ -2053,6 +2058,7 @@ impl 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(), }; diff --git a/compiler/rustc_mir/src/interpret/util.rs b/compiler/rustc_mir/src/interpret/util.rs index 89f34cd07aa..b7ab2e88b96 100644 --- a/compiler/rustc_mir/src/interpret/util.rs +++ b/compiler/rustc_mir/src/interpret/util.rs @@ -21,6 +21,10 @@ where impl<'tcx> TypeVisitor<'tcx> for UsedParamsNeedSubstVisitor<'tcx> { type BreakTy = FoundParam; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow { if !c.needs_subst() { return ControlFlow::CONTINUE; diff --git a/compiler/rustc_mir/src/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs index fea1adfa3d5..dd7500e9e9d 100644 --- a/compiler/rustc_mir/src/monomorphize/polymorphize.rs +++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs @@ -178,7 +178,7 @@ fn mark_used_by_predicates<'tcx>( // Consider all generic params in a predicate as used if any other parameter in the // predicate is used. let any_param_used = { - let mut vis = HasUsedGenericParams { unused_parameters }; + let mut vis = HasUsedGenericParams { tcx, unused_parameters }; predicate.visit_with(&mut vis).is_break() }; @@ -283,6 +283,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } #[instrument(skip(self))] fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow { if !c.has_param_types_or_consts() { @@ -346,13 +349,18 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } /// Visitor used to check if a generic parameter is used. -struct HasUsedGenericParams<'a> { +struct HasUsedGenericParams<'a, 'tcx> { + tcx: TyCtxt<'tcx>, unused_parameters: &'a FiniteBitSet, } -impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { +impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a, 'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + #[instrument(skip(self))] fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow { if !c.has_param_types_or_consts() { diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 7598a011bb6..435fca4a11b 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -682,6 +682,10 @@ pub fn write_allocations<'tcx>( } struct CollectAllocIds(BTreeSet); impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for CollectAllocIds") + } + fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow { if let ty::ConstKind::Value(val) = c.val { self.0.extend(alloc_ids_from_const(val)); diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index d84175724cc..45d31068668 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -179,6 +179,10 @@ where { type BreakTy = V::BreakTy; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.def_id_visitor.tcx() + } + fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { let tcx = self.def_id_visitor.tcx(); // InternalSubsts are not visited here because they are visited below in `super_visit_with`. diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index c5a6e301deb..083a962ac7b 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -352,6 +352,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if !required_region_bounds.is_empty() { for required_region in required_region_bounds { concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx, op: |r| self.sub_regions(infer::CallReturn(span), required_region, r), }); } @@ -427,6 +428,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx, op: |r| self.sub_regions(infer::CallReturn(span), least_region, r), }); } @@ -461,6 +463,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx: self.tcx, op: |r| { self.member_constraint( opaque_type_key.def_id, @@ -546,14 +549,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // // We ignore any type parameters because impl trait values are assumed to // capture all the in-scope type parameters. -struct ConstrainOpaqueTypeRegionVisitor { +struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP> { + tcx: TyCtxt<'tcx>, op: OP, } -impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor +impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP> where OP: FnMut(ty::Region<'tcx>), { + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>( &mut self, t: &ty::Binder<'tcx, T>, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 02b43de0d16..b81ca52f9fd 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -771,6 +771,9 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( impl<'tcx> TypeVisitor<'tcx> for IllegalSelfTypeVisitor<'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index a6323a65aad..fd7dc55ac84 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -130,6 +130,9 @@ impl Search<'a, 'tcx> { impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> { type BreakTy = NonStructuralMatchTy<'tcx>; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx() + } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { debug!("Search visiting ty: {:?}", ty); diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 330fd497fa1..d07eeaedd82 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(); + let mut bound_vars_collector = BoundVarsCollector::new(tcx); ty.as_ref().skip_binder().visit_with(&mut bound_vars_collector); let mut parameters = bound_vars_collector.parameters; let named_parameters: BTreeMap = bound_vars_collector @@ -836,14 +836,16 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>( } crate struct BoundVarsCollector<'tcx> { + tcx: TyCtxt<'tcx>, binder_index: ty::DebruijnIndex, crate parameters: BTreeMap>>, crate named_parameters: Vec, } impl<'tcx> BoundVarsCollector<'tcx> { - crate fn new() -> Self { + crate fn new(tcx: TyCtxt<'tcx>) -> Self { BoundVarsCollector { + tcx, binder_index: ty::INNERMOST, parameters: BTreeMap::new(), named_parameters: vec![], @@ -852,6 +854,10 @@ impl<'tcx> BoundVarsCollector<'tcx> { } impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_binder>( &mut self, t: &Binder<'tcx, T>, @@ -1070,6 +1076,10 @@ impl PlaceholdersCollector { } impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for PlaceholdersCollector"); + } + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Placeholder(p) if p.universe == self.universe_index => { diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 4c03abb38ca..b9fbb5da3e6 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -54,6 +54,9 @@ impl<'tcx> BoundVarsCollector<'tcx> { impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("default anon const substs can't be bound vars"); + } fn visit_binder>( &mut self, t: &Binder<'tcx, T>, diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index a7fd2088842..06fae26f7df 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -470,14 +470,17 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( debug!(?item, ?span); struct FoundParentLifetime; - struct FindParentLifetimeVisitor<'tcx>(&'tcx ty::Generics); + struct FindParentLifetimeVisitor<'tcx>(TyCtxt<'tcx>, &'tcx ty::Generics); impl<'tcx> ty::fold::TypeVisitor<'tcx> for FindParentLifetimeVisitor<'tcx> { type BreakTy = FoundParentLifetime; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.0 + } fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { debug!("FindParentLifetimeVisitor: r={:?}", r); if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r { - if *index < self.0.parent_count as u32 { + if *index < self.1.parent_count as u32 { return ControlFlow::Break(FoundParentLifetime); } else { return ControlFlow::CONTINUE; @@ -499,21 +502,24 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( } struct ProhibitOpaqueVisitor<'tcx> { + tcx: TyCtxt<'tcx>, opaque_identity_ty: Ty<'tcx>, generics: &'tcx ty::Generics, - tcx: TyCtxt<'tcx>, selftys: Vec<(Span, Option)>, } impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> { type BreakTy = Ty<'tcx>; + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t); if t == self.opaque_identity_ty { ControlFlow::CONTINUE } else { - t.super_visit_with(&mut FindParentLifetimeVisitor(self.generics)) + t.super_visit_with(&mut FindParentLifetimeVisitor(self.tcx, self.generics)) .map_break(|FoundParentLifetime| t) } } @@ -1580,6 +1586,9 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) { { struct VisitTypes(Vec); impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + bug!("tcx_for_anon_const_substs called for VisitTypes"); + } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Opaque(def, _) => { diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 963436d05d8..3503d68e8f0 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -428,7 +428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } if let Some(missing_trait) = missing_trait { - let mut visitor = TypeParamVisitor(vec![]); + let mut visitor = TypeParamVisitor(self.tcx, vec![]); visitor.visit_ty(lhs_ty); if op.node == hir::BinOpKind::Add @@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This has nothing here because it means we did string // concatenation (e.g., "Hello " + "World!"). This means // we don't want the note in the else clause to be emitted - } else if let [ty] = &visitor.0[..] { + } else if let [ty] = &visitor.1[..] { if let ty::Param(p) = *ty.kind() { // Check if the method would be found if the type param wasn't // involved. If so, it means that adding a trait bound to the param is @@ -1003,12 +1003,15 @@ fn suggest_constraining_param( } } -struct TypeParamVisitor<'tcx>(Vec>); +struct TypeParamVisitor<'tcx>(TyCtxt<'tcx>, Vec>); impl<'tcx> TypeVisitor<'tcx> for TypeParamVisitor<'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.0 + } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { if let ty::Param(_) = ty.kind() { - self.0.push(ty); + self.1.push(ty); } ty.super_visit_with(self) } diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 632b9492ee4..44caf348a98 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -825,12 +825,15 @@ fn check_where_clauses<'tcx, 'fcx>( .predicates .iter() .flat_map(|&(pred, sp)| { - #[derive(Default)] - struct CountParams { + struct CountParams<'tcx> { + tcx: TyCtxt<'tcx>, params: FxHashSet, } - impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams { + impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams<'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if let ty::Param(param) = t.kind() { @@ -850,7 +853,7 @@ fn check_where_clauses<'tcx, 'fcx>( c.super_visit_with(self) } } - let mut param_count = CountParams::default(); + let mut param_count = CountParams { tcx: fcx.tcx, params: FxHashSet::default() }; let has_region = pred.visit_with(&mut param_count).is_break(); let substituted_pred = pred.subst(tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1c6fd5983cb..d5316352c54 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2320,7 +2320,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP tcx, &mut predicates, trait_ref, - &mut cgp::parameters_for_impl(self_ty, trait_ref), + &mut cgp::parameters_for_impl(tcx, self_ty, trait_ref), ); } diff --git a/compiler/rustc_typeck/src/constrained_generic_params.rs b/compiler/rustc_typeck/src/constrained_generic_params.rs index 529de1a2874..140348ea4ec 100644 --- a/compiler/rustc_typeck/src/constrained_generic_params.rs +++ b/compiler/rustc_typeck/src/constrained_generic_params.rs @@ -27,12 +27,13 @@ impl From for Parameter { /// Returns the set of parameters constrained by the impl header. pub fn parameters_for_impl<'tcx>( + tcx: TyCtxt<'tcx>, impl_self_ty: Ty<'tcx>, impl_trait_ref: Option>, ) -> FxHashSet { let vec = match impl_trait_ref { - Some(tr) => parameters_for(&tr, false), - None => parameters_for(&impl_self_ty, false), + Some(tr) => parameters_for(tcx, &tr, false), + None => parameters_for(tcx, &impl_self_ty, false), }; vec.into_iter().collect() } @@ -43,20 +44,26 @@ pub fn parameters_for_impl<'tcx>( /// of parameters whose values are needed in order to constrain `ty` - these /// differ, with the latter being a superset, in the presence of projections. pub fn parameters_for<'tcx>( + tcx: TyCtxt<'tcx>, t: &impl TypeFoldable<'tcx>, include_nonconstraining: bool, ) -> Vec { - let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining }; + let mut collector = ParameterCollector { tcx, parameters: vec![], include_nonconstraining }; t.visit_with(&mut collector); collector.parameters } -struct ParameterCollector { +struct ParameterCollector<'tcx> { + tcx: TyCtxt<'tcx>, parameters: Vec, include_nonconstraining: bool, } -impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { +impl<'tcx> TypeVisitor<'tcx> for ParameterCollector<'tcx> { + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Projection(..) | ty::Opaque(..) if !self.include_nonconstraining => { @@ -198,12 +205,12 @@ pub fn setup_constraining_predicates<'tcx>( // `<::Baz as Iterator>::Output = ::Output` // Then the projection only applies if `T` is known, but it still // does not determine `U`. - let inputs = parameters_for(&projection.projection_ty, true); + let inputs = parameters_for(tcx, &projection.projection_ty, true); let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(&p)); if !relies_only_on_inputs { continue; } - input_parameters.extend(parameters_for(&projection.ty, false)); + input_parameters.extend(parameters_for(tcx, &projection.ty, false)); } else { continue; } diff --git a/compiler/rustc_typeck/src/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs index 12409468605..194c4efdbb0 100644 --- a/compiler/rustc_typeck/src/impl_wf_check.rs +++ b/compiler/rustc_typeck/src/impl_wf_check.rs @@ -119,7 +119,7 @@ fn enforce_impl_params_are_constrained( let impl_predicates = tcx.predicates_of(impl_def_id); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); - let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref); + let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref); cgp::identify_constrained_generic_params( tcx, impl_predicates, @@ -136,7 +136,7 @@ fn enforce_impl_params_are_constrained( match item.kind { ty::AssocKind::Type => { if item.defaultness.has_value() { - cgp::parameters_for(&tcx.type_of(def_id), true) + cgp::parameters_for(tcx, &tcx.type_of(def_id), true) } else { Vec::new() } diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index e148370a036..2d71c87bee7 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -207,15 +207,15 @@ fn unconstrained_parent_impl_substs<'tcx>( continue; } - unconstrained_parameters.extend(cgp::parameters_for(&projection_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, &projection_ty, true)); - for param in cgp::parameters_for(&projected_ty, false) { + for param in cgp::parameters_for(tcx, &projected_ty, false) { if !unconstrained_parameters.contains(¶m) { constrained_params.insert(param.0); } } - unconstrained_parameters.extend(cgp::parameters_for(&projected_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, &projected_ty, true)); } } @@ -249,7 +249,7 @@ fn check_duplicate_params<'tcx>( parent_substs: &Vec>, span: Span, ) { - let mut base_params = cgp::parameters_for(parent_substs, true); + let mut base_params = cgp::parameters_for(tcx, parent_substs, true); base_params.sort_by_key(|param| param.0); if let (_, [duplicate, ..]) = base_params.partition_dedup() { let param = impl1_substs[duplicate.0 as usize]; diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index 530b3396abe..2335d2248aa 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}; +use rustc_middle::ty::{self, fold::TypeVisitor, Ty, TyCtxt}; use rustc_mir::dataflow::{Analysis, AnalysisDomain, GenKill, GenKillAnalysis, ResultsCursor}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::{BytePos, Span}; @@ -576,7 +576,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> { self.possible_borrower.add(borrowed.local, lhs); }, other => { - if ContainsRegion + if ContainsRegion(self.cx.tcx) .visit_ty(place.ty(&self.body.local_decls, self.cx.tcx).ty) .is_continue() { @@ -625,7 +625,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> { .flat_map(HybridBitSet::iter) .collect(); - if ContainsRegion.visit_ty(self.body.local_decls[*dest].ty).is_break() { + if ContainsRegion(self.cx.tcx).visit_ty(self.body.local_decls[*dest].ty).is_break() { mutable_variables.push(*dest); } @@ -701,12 +701,15 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'a, 'tcx> { } } -struct ContainsRegion; +struct ContainsRegion<'tcx>(TyCtxt<'tcx>); -impl TypeVisitor<'_> for ContainsRegion { +impl<'tcx> TypeVisitor<'tcx> for ContainsRegion<'tcx> { type BreakTy = (); + fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> { + self.0 + } - fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow { + fn visit_region(&mut self, _: ty::Region<'tcx>) -> ControlFlow { ControlFlow::BREAK } }