Skip to content

Commit

Permalink
require a tcx for TypeVisitor
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Mar 15, 2021
1 parent 78c87fc commit 4e8e894
Show file tree
Hide file tree
Showing 23 changed files with 175 additions and 54 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> {
fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> {
self.tcx
}

fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) {
let span = self.tcx.def_span(def_id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorRepor
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor};
use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind};
use rustc_middle::ty::{self, AssocItemContainer, RegionKind, Ty, TypeFoldable, TypeVisitor};
use rustc_middle::ty::{
self, AssocItemContainer, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor,
};
use rustc_span::symbol::Ident;
use rustc_span::{MultiSpan, Span};

Expand Down Expand Up @@ -470,8 +472,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
struct TraitObjectVisitor(Vec<DefId>);

impl TypeVisitor<'_> for TraitObjectVisitor {
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<Self::BreakTy> {
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<Self::BreakTy> {
match t.kind() {
ty::Dynamic(preds, RegionKind::ReStatic) => {
if let Some(def_id) = preds.principal_def_id() {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_infer/src/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ where
};

value.skip_binder().visit_with(&mut ScopeInstantiator {
tcx: self.infcx.tcx,
next_region: &mut next_region,
target_index: ty::INNERMOST,
bound_region_scope: &mut scope,
Expand Down Expand Up @@ -735,13 +736,18 @@ 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,
bound_region_scope: &'me mut BoundRegionScope<'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<T: TypeFoldable<'tcx>>(
&mut self,
t: &ty::Binder<T>,
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_infer/src/infer/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ impl<'a, 'tcx> UnresolvedTypeFinder<'a, 'tcx> {

impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
type BreakTy = (Ty<'tcx>, Option<Span>);
fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> {
bug!("tcx_for_anon_const_substs called for UnresolvedTypeFinder");
}

fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
let t = self.infcx.shallow_resolve(t);
if t.has_infer_types() {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {

impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
type BreakTy = Ty<'tcx>;
fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> {
self.cx.tcx
}

fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match ty.kind() {
Expand Down
42 changes: 34 additions & 8 deletions compiler/rustc_middle/src/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ pub trait TypeFolder<'tcx>: Sized {

pub trait TypeVisitor<'tcx>: Sized {
type BreakTy = !;
/// Supplies the `tcx` for an unevaluated anonymous constant in case its default substs
/// are not yet supplied.
///
/// Visitors which do not look into these substs may leave this unimplemented, so be
/// careful when calling this method elsewhere.
fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx>;

fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<Self::BreakTy> {
t.super_visit_with(self)
Expand Down Expand Up @@ -292,7 +298,8 @@ impl<'tcx> TyCtxt<'tcx> {
value: &impl TypeFoldable<'tcx>,
callback: impl FnMut(ty::Region<'tcx>) -> bool,
) -> bool {
struct RegionVisitor<F> {
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:
Expand All @@ -314,12 +321,16 @@ impl<'tcx> TyCtxt<'tcx> {
callback: F,
}

impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<F>
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<T: TypeFoldable<'tcx>>(
&mut self,
t: &Binder<T>,
Expand Down Expand Up @@ -355,7 +366,9 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback }).is_break()
value
.visit_with(&mut RegionVisitor { tcx: self, outer_index: ty::INNERMOST, callback })
.is_break()
}
}

Expand Down Expand Up @@ -655,7 +668,7 @@ impl<'tcx> TyCtxt<'tcx> {
where
T: TypeFoldable<'tcx>,
{
let mut collector = LateBoundRegionsCollector::new(just_constraint);
let mut collector = LateBoundRegionsCollector::new(self, just_constraint);
let result = value.as_ref().skip_binder().visit_with(&mut collector);
assert!(result.is_continue()); // should never have stopped early
collector.regions
Expand Down Expand Up @@ -830,6 +843,10 @@ struct HasEscapingVarsVisitor {
impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
type BreakTy = FoundEscapingVars;

fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> {
bug!("tcx_for_anon_const_substs called for HasEscpaingVarsVisitor");
}

fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<Self::BreakTy> {
self.outer_index.shift_in(1);
let result = t.super_visit_with(self);
Expand Down Expand Up @@ -897,6 +914,9 @@ struct HasTypeFlagsVisitor {

impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
type BreakTy = FoundFlags;
fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> {
bug!("tcx_for_anon_const_substs called for HasTypeFlagsVisitor");
}

#[inline]
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<Self::BreakTy> {
Expand Down Expand Up @@ -951,7 +971,8 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {

/// Collects all the late-bound regions at the innermost binding level
/// into a hash set.
struct LateBoundRegionsCollector {
struct LateBoundRegionsCollector<'tcx> {
tcx: TyCtxt<'tcx>,
current_index: ty::DebruijnIndex,
regions: FxHashSet<ty::BoundRegionKind>,

Expand All @@ -965,17 +986,22 @@ 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,
}
}
}

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<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<Self::BreakTy> {
self.current_index.shift_in(1);
let result = t.super_visit_with(self);
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1840,18 +1840,22 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
where
T: TypeFoldable<'tcx>,
{
struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
struct LateBoundRegionNameCollector<'a, 'tcx>(TyCtxt<'tcx>, &'a mut FxHashSet<Symbol>);
impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'a, 'tcx> {
fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> {
self.0
}

fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) = *r {
self.0.insert(name);
self.1.insert(name);
}
r.super_visit_with(self)
}
}

self.used_region_names.clear();
let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names);
let mut collector = LateBoundRegionNameCollector(self.tcx, &mut self.used_region_names);
value.visit_with(&mut collector);
self.region_index = 0;
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_mir/src/interpret/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self::BreakTy> {
if !c.needs_subst() {
return ControlFlow::CONTINUE;
Expand Down
14 changes: 11 additions & 3 deletions compiler/rustc_mir/src/monomorphize/polymorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
};

Expand Down Expand Up @@ -287,6 +287,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
}

impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> {
self.tcx
}
#[instrument(skip(self))]
fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if !c.has_param_types_or_consts() {
Expand Down Expand Up @@ -350,13 +353,18 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
}

/// Visitor used to check if a generic parameter is used.
struct HasUsedGenericParams<'a> {
struct HasUsedGenericParams<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
unused_parameters: &'a FiniteBitSet<u32>,
}

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<Self::BreakTy> {
if !c.has_param_types_or_consts() {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_mir/src/util/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,10 @@ pub fn write_allocations<'tcx>(
}
struct CollectAllocIds(BTreeSet<AllocId>);
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<Self::BreakTy> {
if let ty::ConstKind::Value(val) = c.val {
self.0.extend(alloc_ids_from_const(val));
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ where
{
type BreakTy = V::BreakTy;

fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> {
self.def_id_visitor.tcx()
}

fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
let tcx = self.def_id_visitor.tcx();
// InternalSubsts are not visited here because they are visited below in `super_visit_with`.
Expand Down
12 changes: 10 additions & 2 deletions compiler/rustc_trait_selection/src/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {

for required_region in required_region_bounds {
concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
tcx,
op: |r| self.sub_regions(infer::CallReturn(span), required_region, r),
});
}
Expand Down Expand Up @@ -510,6 +511,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
tcx,
op: |r| self.sub_regions(infer::CallReturn(span), least_region, r),
});
}
Expand Down Expand Up @@ -544,6 +546,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
);

concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
tcx: self.tcx,
op: |r| {
self.member_constraint(
opaque_type_def_id,
Expand Down Expand Up @@ -684,14 +687,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
//
// We ignore any type parameters because impl trait values are assumed to
// capture all the in-scope type parameters.
struct ConstrainOpaqueTypeRegionVisitor<OP> {
struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP> {
tcx: TyCtxt<'tcx>,
op: OP,
}

impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<OP>
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<T: TypeFoldable<'tcx>>(
&mut self,
t: &ty::Binder<T>,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,9 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(

impl<'tcx> TypeVisitor<'tcx> for IllegalSelfTypeVisitor<'tcx> {
type BreakTy = ();
fn tcx_for_anon_const_substs<'a>(&'a self) -> TyCtxt<'tcx> {
self.tcx
}

fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_trait_selection/src/traits/structural_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ impl Search<'a, 'tcx> {

impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
type BreakTy = NonStructuralMatchTy<'tcx>;
fn tcx_for_anon_const_substs(&self) -> TyCtxt<'tcx> {
self.tcx()
}

fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
debug!("Search visiting ty: {:?}", ty);
Expand Down
Loading

0 comments on commit 4e8e894

Please sign in to comment.