1
Fork 0

Convert SpannedTypeVisitor to use VisitorResult

This commit is contained in:
Jason Newcomb 2024-02-24 19:25:04 -05:00
parent be9b125d41
commit ea9ae30671
5 changed files with 24 additions and 28 deletions

View file

@ -4689,6 +4689,7 @@ name = "rustc_ty_utils"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"itertools 0.11.0", "itertools 0.11.0",
"rustc_ast_ir",
"rustc_data_structures", "rustc_data_structures",
"rustc_errors", "rustc_errors",
"rustc_fluent_macro", "rustc_fluent_macro",

View file

@ -1065,8 +1065,8 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
} }
impl<'tcx> rustc_ty_utils::sig_types::SpannedTypeVisitor<'tcx> for TypePrivacyVisitor<'tcx> { impl<'tcx> rustc_ty_utils::sig_types::SpannedTypeVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
type BreakTy = (); type Result = ControlFlow<()>;
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<()> { fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result {
self.span = span; self.span = span;
value.visit_with(&mut self.skeleton()) value.visit_with(&mut self.skeleton())
} }

View file

@ -6,6 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
# tidy-alphabetical-start # tidy-alphabetical-start
itertools = "0.11" itertools = "0.11"
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_data_structures = { path = "../rustc_data_structures" } rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" } rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -8,7 +8,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::check_args_compatible; use rustc_trait_selection::traits::check_args_compatible;
use std::ops::ControlFlow;
use crate::errors::{DuplicateArg, NotParam}; use crate::errors::{DuplicateArg, NotParam};
@ -194,9 +193,8 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> { impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
#[instrument(skip(self), ret, level = "trace")] #[instrument(skip(self), ret, level = "trace")]
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<!> { fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
self.visit_spanned(span, value); self.visit_spanned(span, value);
ControlFlow::Continue(())
} }
} }

View file

@ -1,27 +1,23 @@
//! This module contains helpers for walking all types of //! This module contains helpers for walking all types of
//! a signature, while preserving spans as much as possible //! a signature, while preserving spans as much as possible
use std::ops::ControlFlow; use rustc_ast_ir::try_visit;
use rustc_ast_ir::visit::VisitorResult;
use rustc_hir::{def::DefKind, def_id::LocalDefId}; use rustc_hir::{def::DefKind, def_id::LocalDefId};
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
use rustc_type_ir::visit::TypeVisitable; use rustc_type_ir::visit::TypeVisitable;
pub trait SpannedTypeVisitor<'tcx> { pub trait SpannedTypeVisitor<'tcx> {
type BreakTy = !; type Result: VisitorResult = ();
fn visit( fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result;
&mut self,
span: Span,
value: impl TypeVisitable<TyCtxt<'tcx>>,
) -> ControlFlow<Self::BreakTy>;
} }
pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
item: LocalDefId, item: LocalDefId,
visitor: &mut V, visitor: &mut V,
) -> ControlFlow<V::BreakTy> { ) -> V::Result {
let kind = tcx.def_kind(item); let kind = tcx.def_kind(item);
trace!(?kind); trace!(?kind);
match kind { match kind {
@ -30,12 +26,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
let ty_sig = tcx.fn_sig(item).instantiate_identity(); let ty_sig = tcx.fn_sig(item).instantiate_identity();
let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap(); let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap();
// Walk over the inputs and outputs manually in order to get good spans for them. // Walk over the inputs and outputs manually in order to get good spans for them.
visitor.visit(hir_sig.output.span(), ty_sig.output()); try_visit!(visitor.visit(hir_sig.output.span(), ty_sig.output()));
for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) { for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
visitor.visit(hir.span, ty.map_bound(|x| *x))?; try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
} }
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
visitor.visit(span, pred)?; try_visit!(visitor.visit(span, pred));
} }
} }
// Walk over the type behind the alias // Walk over the type behind the alias
@ -44,32 +40,32 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
if let Some(ty) = tcx.hir_node_by_def_id(item).ty() { if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
// Associated types in traits don't necessarily have a type that we can visit // Associated types in traits don't necessarily have a type that we can visit
visitor.visit(ty.span, tcx.type_of(item).instantiate_identity())?; try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity()));
} }
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
visitor.visit(span, pred)?; try_visit!(visitor.visit(span, pred));
} }
} }
DefKind::OpaqueTy => { DefKind::OpaqueTy => {
for (pred, span) in tcx.explicit_item_bounds(item).instantiate_identity_iter_copied() { for (pred, span) in tcx.explicit_item_bounds(item).instantiate_identity_iter_copied() {
visitor.visit(span, pred)?; try_visit!(visitor.visit(span, pred));
} }
} }
// Look at field types // Look at field types
DefKind::Struct | DefKind::Union | DefKind::Enum => { DefKind::Struct | DefKind::Union | DefKind::Enum => {
let span = tcx.def_ident_span(item).unwrap(); let span = tcx.def_ident_span(item).unwrap();
let ty = tcx.type_of(item).instantiate_identity(); let ty = tcx.type_of(item).instantiate_identity();
visitor.visit(span, ty); try_visit!(visitor.visit(span, ty));
let ty::Adt(def, args) = ty.kind() else { let ty::Adt(def, args) = ty.kind() else {
span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind()) span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind())
}; };
for field in def.all_fields() { for field in def.all_fields() {
let span = tcx.def_ident_span(field.did).unwrap(); let span = tcx.def_ident_span(field.did).unwrap();
let ty = field.ty(tcx, args); let ty = field.ty(tcx, args);
visitor.visit(span, ty); try_visit!(visitor.visit(span, ty));
} }
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
visitor.visit(span, pred)?; try_visit!(visitor.visit(span, pred));
} }
} }
// These are not part of a public API, they can only appear as hidden types, and there // These are not part of a public API, they can only appear as hidden types, and there
@ -80,20 +76,20 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
if of_trait { if of_trait {
let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span; let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..]; let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..];
visitor.visit(span, args)?; try_visit!(visitor.visit(span, args));
} }
let span = match tcx.hir_node_by_def_id(item).ty() { let span = match tcx.hir_node_by_def_id(item).ty() {
Some(ty) => ty.span, Some(ty) => ty.span,
_ => tcx.def_span(item), _ => tcx.def_span(item),
}; };
visitor.visit(span, tcx.type_of(item).instantiate_identity()); try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity()));
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
visitor.visit(span, pred)?; try_visit!(visitor.visit(span, pred));
} }
} }
DefKind::TraitAlias | DefKind::Trait => { DefKind::TraitAlias | DefKind::Trait => {
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
visitor.visit(span, pred)?; try_visit!(visitor.visit(span, pred));
} }
} }
| DefKind::Variant | DefKind::Variant
@ -116,5 +112,5 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
| DefKind::Mod | DefKind::Mod
| DefKind::Use => {} | DefKind::Use => {}
} }
ControlFlow::Continue(()) V::Result::output()
} }