Skip to content

Commit

Permalink
Overhaul the intravisit::Map trait.
Browse files Browse the repository at this point in the history
First of all, note that `Map` has three different relevant meanings.
- The `intravisit::Map` trait.
- The `map::Map` struct.
- The `NestedFilter::Map` associated type.

The `intravisit::Map` trait is impl'd twice.
- For `!`, where the methods are all unreachable.
- For `map::Map`, which gets HIR stuff from the `TyCtxt`.

As part of getting rid of `map::Map`, this commit changes `impl
intravisit::Map for map::Map` to `impl intravisit::Map for TyCtxt`. It's
fairly straightforward except various things are renamed, because the
existing names would no longer have made sense.

- `trait intravisit::Map` becomes `trait intravisit::HirTyCtxt`, so named
  because it gets some HIR stuff from a `TyCtxt`.
- `NestedFilter::Map` assoc type becomes `NestedFilter::MaybeTyCtxt`,
  because it's always `!` or `TyCtxt`.
- `Visitor::nested_visit_map` becomes `Visitor::maybe_tcx`.

I deliberately made the new trait and associated type names different to
avoid the old `type Map: Map` situation, which I found confusing. We now
have `type MaybeTyCtxt: HirTyCtxt`.
  • Loading branch information
nnethercote committed Feb 4, 2025
1 parent 8d93815 commit 90a871b
Show file tree
Hide file tree
Showing 59 changed files with 207 additions and 209 deletions.
16 changes: 8 additions & 8 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,13 +348,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
expr: Option<&'hir hir::Expr<'hir>>,
pat: Option<&'hir hir::Pat<'hir>>,
parent_pat: Option<&'hir hir::Pat<'hir>>,
hir: rustc_middle::hir::map::Map<'hir>,
tcx: TyCtxt<'hir>,
}
impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> {
type NestedFilter = OnlyBodies;

fn nested_visit_map(&mut self) -> Self::Map {
self.hir
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}

fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
Expand Down Expand Up @@ -396,7 +396,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
expr: None,
pat: None,
parent_pat: None,
hir,
tcx: self.infcx.tcx,
};
finder.visit_expr(expr);
if let Some(span) = span
Expand Down Expand Up @@ -2455,7 +2455,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let body_expr = tcx.hir_body(body_id).value;

struct ClosureFinder<'hir> {
hir: rustc_middle::hir::map::Map<'hir>,
tcx: TyCtxt<'hir>,
borrow_span: Span,
res: Option<(&'hir hir::Expr<'hir>, &'hir hir::Closure<'hir>)>,
/// The path expression with the `borrow_span` span
Expand All @@ -2464,8 +2464,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
impl<'hir> Visitor<'hir> for ClosureFinder<'hir> {
type NestedFilter = OnlyBodies;

fn nested_visit_map(&mut self) -> Self::Map {
self.hir
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}

fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
Expand All @@ -2491,7 +2491,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {

// Find the closure that most tightly wraps `capture_kind_span`
let mut finder =
ClosureFinder { hir, borrow_span: capture_kind_span, res: None, error_path: None };
ClosureFinder { tcx, borrow_span: capture_kind_span, res: None, error_path: None };
finder.visit_expr(body_expr);
let Some((closure_expr, closure)) = finder.res else { return };

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ impl<'tcx> BorrowExplanation<'tcx> {

impl<'hir> rustc_hir::intravisit::Visitor<'hir> for FindLetExpr<'hir> {
type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}
fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
if let hir::ExprKind::If(cond, _conseq, _alt)
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, CaptureBy, ExprKind, HirId, Node};
use rustc_middle::bug;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
use rustc_span::{BytePos, ExpnKind, MacroKind, Span};
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
Expand Down Expand Up @@ -690,7 +690,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
/// make it bind by reference instead (if possible)
struct BindingFinder<'tcx> {
typeck_results: &'tcx ty::TypeckResults<'tcx>,
hir: rustc_middle::hir::map::Map<'tcx>,
tcx: TyCtxt<'tcx>,
/// Input: the span of the pattern we're finding bindings in
pat_span: Span,
/// Input: the spans of the bindings we're providing suggestions for
Expand All @@ -709,8 +709,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
impl<'tcx> Visitor<'tcx> for BindingFinder<'tcx> {
type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;

fn nested_visit_map(&mut self) -> Self::Map {
self.hir
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}

fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> Self::Result {
Expand Down Expand Up @@ -782,7 +782,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
let mut finder = BindingFinder {
typeck_results,
hir,
tcx: self.infcx.tcx,
pat_span,
binding_spans,
found_pat: false,
Expand Down
66 changes: 34 additions & 32 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! within one another.
//! - Example: Examine each expression to look for its type and do some check or other.
//! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
//! `nested_filter::OnlyBodies` (and implement `nested_visit_map`), and use
//! `nested_filter::OnlyBodies` (and implement `maybe_tcx`), and use
//! `tcx.hir().visit_all_item_likes_in_crate(&mut visitor)`. Within your
//! `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke
//! `intravisit::walk_expr()` to keep walking the subparts).
Expand All @@ -30,7 +30,7 @@
//! - Example: Lifetime resolution, which wants to bring lifetimes declared on the
//! impl into scope while visiting the impl-items, and then back out again.
//! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
//! `nested_filter::All` (and implement `nested_visit_map`). Walk your crate with
//! `nested_filter::All` (and implement `maybe_tcx`). Walk your crate with
//! `tcx.hir().walk_toplevel_module(visitor)` invoked on `tcx.hir().krate()`.
//! - Pro: Visitor methods for any kind of HIR node, not just item-like things.
//! - Pro: Preserves nesting information
Expand Down Expand Up @@ -106,41 +106,43 @@ impl<'a> FnKind<'a> {
}
}

/// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
pub trait Map<'hir> {
/// HIR things retrievable from `TyCtxt`, avoiding an explicit dependence on
/// `TyCtxt`. The only impls are for `!` (where these functions are never
/// called) and `TyCtxt` (in `rustc_middle`).
pub trait HirTyCtxt<'hir> {
/// Retrieves the `Node` corresponding to `id`.
fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
fn body(&self, id: BodyId) -> &'hir Body<'hir>;
fn item(&self, id: ItemId) -> &'hir Item<'hir>;
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
fn hir_body(&self, id: BodyId) -> &'hir Body<'hir>;
fn hir_item(&self, id: ItemId) -> &'hir Item<'hir>;
fn hir_trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
fn hir_impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
fn hir_foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
}

// Used when no map is actually available, forcing manual implementation of nested visitors.
impl<'hir> Map<'hir> for ! {
// Used when no tcx is actually available, forcing manual implementation of nested visitors.
impl<'hir> HirTyCtxt<'hir> for ! {
fn hir_node(&self, _: HirId) -> Node<'hir> {
unreachable!();
}
fn body(&self, _: BodyId) -> &'hir Body<'hir> {
fn hir_body(&self, _: BodyId) -> &'hir Body<'hir> {
unreachable!();
}
fn item(&self, _: ItemId) -> &'hir Item<'hir> {
fn hir_item(&self, _: ItemId) -> &'hir Item<'hir> {
unreachable!();
}
fn trait_item(&self, _: TraitItemId) -> &'hir TraitItem<'hir> {
fn hir_trait_item(&self, _: TraitItemId) -> &'hir TraitItem<'hir> {
unreachable!();
}
fn impl_item(&self, _: ImplItemId) -> &'hir ImplItem<'hir> {
fn hir_impl_item(&self, _: ImplItemId) -> &'hir ImplItem<'hir> {
unreachable!();
}
fn foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> {
fn hir_foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> {
unreachable!();
}
}

pub mod nested_filter {
use super::Map;
use super::HirTyCtxt;

/// Specifies what nested things a visitor wants to visit. By "nested
/// things", we are referring to bits of HIR that are not directly embedded
Expand All @@ -155,7 +157,7 @@ pub mod nested_filter {
/// See the comments at [`rustc_hir::intravisit`] for more details on the overall
/// visit strategy.
pub trait NestedFilter<'hir> {
type Map: Map<'hir>;
type MaybeTyCtxt: HirTyCtxt<'hir>;

/// Whether the visitor visits nested "item-like" things.
/// E.g., item, impl-item.
Expand All @@ -171,10 +173,10 @@ pub mod nested_filter {
///
/// Use this if you are only walking some particular kind of tree
/// (i.e., a type, or fn signature) and you don't want to thread a
/// HIR map around.
/// `tcx` around.
pub struct None(());
impl NestedFilter<'_> for None {
type Map = !;
type MaybeTyCtxt = !;
const INTER: bool = false;
const INTRA: bool = false;
}
Expand All @@ -199,18 +201,18 @@ use nested_filter::NestedFilter;
/// to monitor future changes to `Visitor` in case a new method with a
/// new default implementation gets introduced.)
pub trait Visitor<'v>: Sized {
// This type should not be overridden, it exists for convenient usage as `Self::Map`.
type Map: Map<'v> = <Self::NestedFilter as NestedFilter<'v>>::Map;
// This type should not be overridden, it exists for convenient usage as `Self::MaybeTyCtxt`.
type MaybeTyCtxt: HirTyCtxt<'v> = <Self::NestedFilter as NestedFilter<'v>>::MaybeTyCtxt;

///////////////////////////////////////////////////////////////////////////
// Nested items.

/// Override this type to control which nested HIR are visited; see
/// [`NestedFilter`] for details. If you override this type, you
/// must also override [`nested_visit_map`](Self::nested_visit_map).
/// must also override [`maybe_tcx`](Self::maybe_tcx).
///
/// **If for some reason you want the nested behavior, but don't
/// have a `Map` at your disposal:** then override the
/// have a `tcx` at your disposal:** then override the
/// `visit_nested_XXX` methods. If a new `visit_nested_XXX` variant is
/// added in the future, it will cause a panic which can be detected
/// and fixed appropriately.
Expand All @@ -222,9 +224,9 @@ pub trait Visitor<'v>: Sized {

/// If `type NestedFilter` is set to visit nested items, this method
/// must also be overridden to provide a map to retrieve nested items.
fn nested_visit_map(&mut self) -> Self::Map {
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
panic!(
"nested_visit_map must be implemented or consider using \
"maybe_tcx must be implemented or consider using \
`type NestedFilter = nested_filter::None` (the default)"
);
}
Expand All @@ -236,10 +238,10 @@ pub trait Visitor<'v>: Sized {
/// "deep" visit patterns described at
/// [`rustc_hir::intravisit`]. The only reason to override
/// this method is if you want a nested pattern but cannot supply a
/// [`Map`]; see `nested_visit_map` for advice.
/// [`Map`]; see `maybe_tcx` for advice.
fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
if Self::NestedFilter::INTER {
let item = self.nested_visit_map().item(id);
let item = self.maybe_tcx().hir_item(id);
try_visit!(self.visit_item(item));
}
Self::Result::output()
Expand All @@ -250,7 +252,7 @@ pub trait Visitor<'v>: Sized {
/// method.
fn visit_nested_trait_item(&mut self, id: TraitItemId) -> Self::Result {
if Self::NestedFilter::INTER {
let item = self.nested_visit_map().trait_item(id);
let item = self.maybe_tcx().hir_trait_item(id);
try_visit!(self.visit_trait_item(item));
}
Self::Result::output()
Expand All @@ -261,7 +263,7 @@ pub trait Visitor<'v>: Sized {
/// method.
fn visit_nested_impl_item(&mut self, id: ImplItemId) -> Self::Result {
if Self::NestedFilter::INTER {
let item = self.nested_visit_map().impl_item(id);
let item = self.maybe_tcx().hir_impl_item(id);
try_visit!(self.visit_impl_item(item));
}
Self::Result::output()
Expand All @@ -272,7 +274,7 @@ pub trait Visitor<'v>: Sized {
/// method.
fn visit_nested_foreign_item(&mut self, id: ForeignItemId) -> Self::Result {
if Self::NestedFilter::INTER {
let item = self.nested_visit_map().foreign_item(id);
let item = self.maybe_tcx().hir_foreign_item(id);
try_visit!(self.visit_foreign_item(item));
}
Self::Result::output()
Expand All @@ -283,7 +285,7 @@ pub trait Visitor<'v>: Sized {
/// `Self::NestedFilter`.
fn visit_nested_body(&mut self, id: BodyId) -> Self::Result {
if Self::NestedFilter::INTRA {
let body = self.nested_visit_map().body(id);
let body = self.maybe_tcx().hir_body(id);
try_visit!(self.visit_body(body));
}
Self::Result::output()
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ fn best_definition_site_of_opaque<'tcx>(
impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
type NestedFilter = nested_filter::All;
type Result = ControlFlow<(Span, LocalDefId)>;
fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> Self::Result {
if let hir::ExprKind::Closure(closure) = ex.kind {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
type NestedFilter = nested_filter::OnlyBodies;

fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}

fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
impl<'tcx> intravisit::Visitor<'tcx> for AnonConstFinder<'tcx> {
type NestedFilter = nested_filter::All;

fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}

fn visit_anon_const(&mut self, c: &'tcx rustc_hir::AnonConst) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,8 @@ enum NonLifetimeBinderAllowed {
impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies;

fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}

fn visit_nested_body(&mut self, body: hir::BodyId) {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ impl TaitConstraintLocator<'_> {
impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
type NestedFilter = nested_filter::All;

fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
if let hir::ExprKind::Closure(closure) = ex.kind {
Expand Down Expand Up @@ -441,8 +441,8 @@ impl RpitConstraintChecker<'_> {
impl<'tcx> intravisit::Visitor<'tcx> for RpitConstraintChecker<'tcx> {
type NestedFilter = nested_filter::OnlyBodies;

fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
if let hir::ExprKind::Closure(closure) = ex.kind {
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use rustc_span::source_map::SourceMap;
use rustc_span::{FileName, Ident, Span, Symbol, kw};
use {rustc_ast as ast, rustc_hir as hir};

pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String {
to_string(&map, |s| s.print_node(map.hir_node(hir_id)))
pub fn id_to_string(cx: &dyn rustc_hir::intravisit::HirTyCtxt<'_>, hir_id: HirId) -> String {
to_string(&cx, |s| s.print_node(cx.hir_node(hir_id)))
}

pub enum AnnNode<'a> {
Expand Down Expand Up @@ -53,15 +53,15 @@ pub trait PpAnn {
fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {}
}

impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> {
impl PpAnn for &dyn rustc_hir::intravisit::HirTyCtxt<'_> {
fn nested(&self, state: &mut State<'_>, nested: Nested) {
match nested {
Nested::Item(id) => state.print_item(self.item(id)),
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
Nested::Body(id) => state.print_expr(self.body(id).value),
Nested::BodyParamPat(id, i) => state.print_pat(self.body(id).params[i].pat),
Nested::Item(id) => state.print_item(self.hir_item(id)),
Nested::TraitItem(id) => state.print_trait_item(self.hir_trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.hir_impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.hir_foreign_item(id)),
Nested::Body(id) => state.print_expr(self.hir_body(id).value),
Nested::BodyParamPat(id, i) => state.print_pat(self.hir_body(id).params[i].pat),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2729,8 +2729,8 @@ struct FindClosureArg<'tcx> {
impl<'tcx> Visitor<'tcx> for FindClosureArg<'tcx> {
type NestedFilter = rustc_middle::hir::nested_filter::All;

fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}

fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
Expand Down
Loading

0 comments on commit 90a871b

Please sign in to comment.