Convert TypeVisitor
and DefIdVisitor
to use VisitorResult
This commit is contained in:
parent
5abfb3775d
commit
be9b125d41
53 changed files with 345 additions and 448 deletions
|
@ -648,8 +648,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTermOrNotNameable<'_, 'tcx> {
|
||||
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 {
|
||||
match *t.kind() {
|
||||
ty::Infer(ty::TyVar(vid)) => {
|
||||
if let ty::TermKind::Ty(term) = self.term.unpack()
|
||||
|
@ -672,7 +672,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
|
||||
match c.kind() {
|
||||
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
|
||||
if let ty::TermKind::Const(term) = self.term.unpack()
|
||||
|
|
|
@ -474,7 +474,7 @@ fn plug_infer_with_placeholders<'tcx>(
|
|||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for PlugInferWithPlaceholder<'_, 'tcx> {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) {
|
||||
let ty = self.infcx.shallow_resolve(ty);
|
||||
if ty.is_ty_var() {
|
||||
let Ok(InferOk { value: (), obligations }) =
|
||||
|
@ -496,13 +496,12 @@ fn plug_infer_with_placeholders<'tcx>(
|
|||
bug!("we always expect to be able to plug an infer var with placeholder")
|
||||
};
|
||||
assert_eq!(obligations, &[]);
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
ty.super_visit_with(self)
|
||||
ty.super_visit_with(self);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) {
|
||||
let ct = self.infcx.shallow_resolve(ct);
|
||||
if ct.is_ct_infer() {
|
||||
let Ok(InferOk { value: (), obligations }) =
|
||||
|
@ -519,13 +518,12 @@ fn plug_infer_with_placeholders<'tcx>(
|
|||
bug!("we always expect to be able to plug an infer var with placeholder")
|
||||
};
|
||||
assert_eq!(obligations, &[]);
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
ct.super_visit_with(self)
|
||||
ct.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::ReVar(vid) = *r {
|
||||
let r = self
|
||||
.infcx
|
||||
|
@ -555,7 +553,6 @@ fn plug_infer_with_placeholders<'tcx>(
|
|||
assert_eq!(obligations, &[]);
|
||||
}
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,12 +865,12 @@ impl<'tcx, F, E> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx, F>
|
|||
where
|
||||
F: FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
|
||||
{
|
||||
type BreakTy = OrphanCheckEarlyExit<'tcx, E>;
|
||||
fn visit_region(&mut self, _r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
type Result = ControlFlow<OrphanCheckEarlyExit<'tcx, E>>;
|
||||
fn visit_region(&mut self, _r: ty::Region<'tcx>) -> Self::Result {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||
// Need to lazily normalize here in with `-Znext-solver=coherence`.
|
||||
let ty = match (self.lazily_normalize_ty)(ty) {
|
||||
Ok(ty) => ty,
|
||||
|
@ -996,7 +993,7 @@ where
|
|||
/// As these should be quite rare as const arguments and especially rare as impl
|
||||
/// parameters, allowing uncovered const parameters in impls seems more useful
|
||||
/// than allowing `impl<T> Trait<local_fn_ptr, T> for i32` to compile.
|
||||
fn visit_const(&mut self, _c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_const(&mut self, _c: ty::Const<'tcx>) -> Self::Result {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
|||
use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
|
||||
use rustc_span::Span;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use crate::traits::ObligationCtxt;
|
||||
|
||||
|
@ -170,8 +169,7 @@ fn satisfied_from_param_env<'tcx>(
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for Visitor<'a, 'tcx> {
|
||||
type BreakTy = ();
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) {
|
||||
debug!("is_const_evaluatable: candidate={:?}", c);
|
||||
if self.infcx.probe(|_| {
|
||||
let ocx = ObligationCtxt::new(self.infcx);
|
||||
|
@ -187,7 +185,7 @@ fn satisfied_from_param_env<'tcx>(
|
|||
}
|
||||
|
||||
if let ty::ConstKind::Expr(e) = c.kind() {
|
||||
e.visit_with(self)
|
||||
e.visit_with(self);
|
||||
} else {
|
||||
// FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s args.
|
||||
// This is currently unobservable as `<T as Trait<{ U + 1 }>>::ASSOC` creates an anon const
|
||||
|
@ -196,7 +194,6 @@ fn satisfied_from_param_env<'tcx>(
|
|||
// If we start allowing directly writing `ConstKind::Expr` without an intermediate anon const
|
||||
// this will be incorrect. It might be worth investigating making `predicates_of` elaborate
|
||||
// all of the `ConstEvaluatable` bounds rather than having a visitor here.
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,9 +152,9 @@ impl ArgKind {
|
|||
struct HasNumericInferVisitor;
|
||||
|
||||
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for HasNumericInferVisitor {
|
||||
type BreakTy = ();
|
||||
type Result = ControlFlow<()>;
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||
if matches!(ty.kind(), ty::Infer(ty::FloatVar(_) | ty::IntVar(_))) {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
|
|
|
@ -435,8 +435,8 @@ fn is_impossible_associated_item(
|
|||
trait_item_def_id: DefId,
|
||||
}
|
||||
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'tcx> {
|
||||
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 this is a parameter from the trait item's own generics, then bail
|
||||
if let ty::Param(param) = t.kind()
|
||||
&& let param_def_id = self.generics.type_param(param, self.tcx).def_id
|
||||
|
@ -446,7 +446,7 @@ fn is_impossible_associated_item(
|
|||
}
|
||||
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>) -> Self::Result {
|
||||
if let ty::ReEarlyParam(param) = r.kind()
|
||||
&& let param_def_id = self.generics.region_param(¶m, self.tcx).def_id
|
||||
&& self.tcx.parent(param_def_id) == self.trait_item_def_id
|
||||
|
@ -455,7 +455,7 @@ fn is_impossible_associated_item(
|
|||
}
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
|
||||
if let ty::ConstKind::Param(param) = ct.kind()
|
||||
&& let param_def_id = self.generics.const_param(¶m, self.tcx).def_id
|
||||
&& self.tcx.parent(param_def_id) == self.trait_item_def_id
|
||||
|
|
|
@ -834,9 +834,9 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
|
|||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalSelfTypeVisitor<'tcx> {
|
||||
type BreakTy = ();
|
||||
type Result = ControlFlow<()>;
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||
match t.kind() {
|
||||
ty::Param(_) => {
|
||||
if t == self.tcx.types.self_param {
|
||||
|
@ -887,7 +887,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
|
||||
// Constants can only influence object safety if they are generic and reference `Self`.
|
||||
// This is only possible for unevaluated constants, so we walk these here.
|
||||
self.tcx.expand_abstract_consts(ct).super_visit_with(self)
|
||||
|
|
|
@ -18,8 +18,6 @@ use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableEx
|
|||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use super::NoSolution;
|
||||
|
||||
pub use rustc_middle::traits::query::NormalizationResult;
|
||||
|
@ -123,28 +121,23 @@ struct MaxEscapingBoundVarVisitor {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
|
||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
t: &ty::Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
|
||||
self.outer_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
t.super_visit_with(self);
|
||||
self.outer_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||
if t.outer_exclusive_binder() > self.outer_index {
|
||||
self.escaping = self
|
||||
.escaping
|
||||
.max(t.outer_exclusive_binder().as_usize() - self.outer_index.as_usize());
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||
match *r {
|
||||
ty::ReBound(debruijn, _) if debruijn > self.outer_index => {
|
||||
self.escaping =
|
||||
|
@ -152,16 +145,14 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) {
|
||||
if ct.outer_exclusive_binder() > self.outer_index {
|
||||
self.escaping = self
|
||||
.escaping
|
||||
.max(ct.outer_exclusive_binder().as_usize() - self.outer_index.as_usize());
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,9 +53,9 @@ impl<'tcx> Search<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
|
||||
type BreakTy = Ty<'tcx>;
|
||||
type Result = ControlFlow<Ty<'tcx>>;
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||
debug!("Search visiting ty: {:?}", ty);
|
||||
|
||||
let (adt_def, args) = match *ty.kind() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue