1
Fork 0

Convert TypeVisitor and DefIdVisitor to use VisitorResult

This commit is contained in:
Jason Newcomb 2024-02-24 17:22:28 -05:00
parent 5abfb3775d
commit be9b125d41
53 changed files with 345 additions and 448 deletions

View file

@ -1474,15 +1474,14 @@ fn opaque_type_cycle_error(
closures: Vec<DefId>,
}
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match *t.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
self.opaques.push(def);
ControlFlow::Continue(())
}
ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
self.closures.push(def_id);
t.super_visit_with(self)
t.super_visit_with(self);
}
_ => t.super_visit_with(self),
}

View file

@ -12,7 +12,6 @@ use rustc_trait_selection::regions::InferCtxtRegionExt;
use rustc_trait_selection::traits::{
elaborate, normalize_param_env_or_error, outlives_bounds::InferCtxtExt, ObligationCtxt,
};
use std::ops::ControlFlow;
/// Check that an implementation does not refine an RPITIT from a trait method signature.
pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
@ -211,9 +210,7 @@ struct ImplTraitInTraitCollector<'tcx> {
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'tcx> {
type BreakTy = !;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, ty: Ty<'tcx>) {
if let ty::Alias(ty::Projection, proj) = *ty.kind()
&& self.tcx.is_impl_trait_in_trait(proj.def_id)
{
@ -223,12 +220,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'tcx> {
.explicit_item_bounds(proj.def_id)
.iter_instantiated_copied(self.tcx, proj.args)
{
pred.visit_with(self)?;
pred.visit_with(self);
}
}
ControlFlow::Continue(())
} else {
ty.super_visit_with(self)
ty.super_visit_with(self);
}
}
}

View file

@ -809,9 +809,7 @@ impl<'tcx> GATArgsCollector<'tcx> {
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
type BreakTy = !;
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
for (idx, arg) in p.args.iter().enumerate() {
@ -1456,20 +1454,19 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
params: FxHashSet<u32>,
}
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for CountParams {
type BreakTy = ();
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
type Result = ControlFlow<()>;
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if let ty::Param(param) = t.kind() {
self.params.insert(param.index);
}
t.super_visit_with(self)
}
fn visit_region(&mut self, _: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_region(&mut self, _: ty::Region<'tcx>) -> Self::Result {
ControlFlow::Break(())
}
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
if let ty::ConstKind::Param(param) = c.kind() {
self.params.insert(param.index);
}

View file

@ -1964,31 +1964,26 @@ fn is_late_bound_map(
arg_is_constrained: Box<[bool]>,
}
use std::ops::ControlFlow;
use ty::Ty;
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstrainedCollectorPostAstConv {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::Param(param_ty) => {
self.arg_is_constrained[param_ty.index as usize] = true;
}
ty::Alias(ty::Projection | ty::Inherent, _) => return ControlFlow::Continue(()),
ty::Alias(ty::Projection | ty::Inherent, _) => return,
_ => (),
}
t.super_visit_with(self)
}
fn visit_const(&mut self, _: ty::Const<'tcx>) -> ControlFlow<!> {
ControlFlow::Continue(())
}
fn visit_const(&mut self, _: ty::Const<'tcx>) {}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<!> {
fn visit_region(&mut self, r: ty::Region<'tcx>) {
debug!("r={:?}", r.kind());
if let ty::RegionKind::ReEarlyParam(region) = r.kind() {
self.arg_is_constrained[region.index as usize] = true;
}
ControlFlow::Continue(())
}
}

View file

@ -1,9 +1,8 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitor};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;
use rustc_type_ir::fold::TypeFoldable;
use std::ops::ControlFlow;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Parameter(pub u32);
@ -61,13 +60,13 @@ struct ParameterCollector {
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match *t.kind() {
// Projections are not injective in general.
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _)
if !self.include_nonconstraining =>
{
return ControlFlow::Continue(());
return;
}
// All weak alias types should've been expanded beforehand.
ty::Alias(ty::Weak, _) if !self.include_nonconstraining => {
@ -80,18 +79,17 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
t.super_visit_with(self)
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_region(&mut self, r: ty::Region<'tcx>) {
if let ty::ReEarlyParam(data) = *r {
self.parameters.push(Parameter::from(data));
}
ControlFlow::Continue(())
}
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) {
match c.kind() {
ty::ConstKind::Unevaluated(..) if !self.include_nonconstraining => {
// Constant expressions are not injective in general.
return c.ty().visit_with(self);
return;
}
ty::ConstKind::Param(data) => {
self.parameters.push(Parameter::from(data));

View file

@ -10,7 +10,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
use std::ops::ControlFlow;
/// Defines the `TermsContext` basically houses an arena where we can
/// allocate terms.
@ -89,15 +88,14 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
impl<'tcx> OpaqueTypeLifetimeCollector<'tcx> {
#[instrument(level = "trace", skip(self), ret)]
fn visit_opaque(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) -> ControlFlow<!> {
fn visit_opaque(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) {
if def_id != self.root_def_id && self.tcx.is_descendant_of(def_id, self.root_def_id) {
let child_variances = self.tcx.variances_of(def_id);
for (a, v) in args.iter().zip_eq(child_variances) {
if *v != ty::Bivariant {
a.visit_with(self)?;
a.visit_with(self);
}
}
ControlFlow::Continue(())
} else {
args.visit_with(self)
}
@ -106,20 +104,19 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> {
#[instrument(level = "trace", skip(self), ret)]
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_region(&mut self, r: ty::Region<'tcx>) {
if let ty::RegionKind::ReEarlyParam(ebr) = r.kind() {
self.variances[ebr.index as usize] = ty::Invariant;
}
ControlFlow::Continue(())
}
#[instrument(level = "trace", skip(self), ret)]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::Alias(_, ty::AliasTy { def_id, args, .. })
if matches!(self.tcx.def_kind(*def_id), DefKind::OpaqueTy) =>
{
self.visit_opaque(*def_id, args)
self.visit_opaque(*def_id, args);
}
_ => t.super_visit_with(self),
}