mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Convert TypeVisitor
and DefIdVisitor
to use VisitorResult
This commit is contained in:
parent
5abfb3775d
commit
be9b125d41
@ -3970,6 +3970,7 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.11.0",
|
"itertools 0.11.0",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
|
"rustc_ast_ir",
|
||||||
"rustc_attr",
|
"rustc_attr",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
@ -4038,6 +4039,7 @@ dependencies = [
|
|||||||
name = "rustc_infer"
|
name = "rustc_infer"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"rustc_ast_ir",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
"rustc_fluent_macro",
|
"rustc_fluent_macro",
|
||||||
@ -4632,6 +4634,7 @@ dependencies = [
|
|||||||
"bitflags 2.4.2",
|
"bitflags 2.4.2",
|
||||||
"itertools 0.11.0",
|
"itertools 0.11.0",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
|
"rustc_ast_ir",
|
||||||
"rustc_attr",
|
"rustc_attr",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
@ -4670,6 +4673,7 @@ name = "rustc_transmute"
|
|||||||
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_hir",
|
"rustc_hir",
|
||||||
"rustc_infer",
|
"rustc_infer",
|
||||||
|
@ -30,9 +30,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
|
||||||
type BreakTy = FoundParam;
|
type Result = ControlFlow<FoundParam>;
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||||
if !ty.has_param() {
|
if !ty.has_param() {
|
||||||
return ControlFlow::Continue(());
|
return ControlFlow::Continue(());
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
match c.kind() {
|
||||||
ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam),
|
ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam),
|
||||||
_ => c.super_visit_with(self),
|
_ => c.super_visit_with(self),
|
||||||
|
@ -17,7 +17,7 @@ use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
|
|||||||
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor};
|
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor};
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{ControlFlow, Deref};
|
use std::ops::Deref;
|
||||||
|
|
||||||
use super::ops::{self, NonConstOp, Status};
|
use super::ops::{self, NonConstOp, Status};
|
||||||
use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
|
use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
|
||||||
@ -164,9 +164,9 @@ struct LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
|
impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::FnPtr(_) => ControlFlow::Continue(()),
|
ty::FnPtr(_) => {}
|
||||||
ty::Ref(_, _, hir::Mutability::Mut) => {
|
ty::Ref(_, _, hir::Mutability::Mut) => {
|
||||||
self.checker.check_op(ops::ty::MutRef(self.kind));
|
self.checker.check_op(ops::ty::MutRef(self.kind));
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
|
@ -1474,15 +1474,14 @@ fn opaque_type_cycle_error(
|
|||||||
closures: Vec<DefId>,
|
closures: Vec<DefId>,
|
||||||
}
|
}
|
||||||
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
|
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() {
|
match *t.kind() {
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
|
||||||
self.opaques.push(def);
|
self.opaques.push(def);
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
|
ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
|
||||||
self.closures.push(def_id);
|
self.closures.push(def_id);
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self);
|
||||||
}
|
}
|
||||||
_ => t.super_visit_with(self),
|
_ => t.super_visit_with(self),
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use rustc_trait_selection::regions::InferCtxtRegionExt;
|
|||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
elaborate, normalize_param_env_or_error, outlives_bounds::InferCtxtExt, ObligationCtxt,
|
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.
|
/// 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>(
|
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> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'tcx> {
|
||||||
type BreakTy = !;
|
fn visit_ty(&mut self, ty: Ty<'tcx>) {
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
|
|
||||||
if let ty::Alias(ty::Projection, proj) = *ty.kind()
|
if let ty::Alias(ty::Projection, proj) = *ty.kind()
|
||||||
&& self.tcx.is_impl_trait_in_trait(proj.def_id)
|
&& 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)
|
.explicit_item_bounds(proj.def_id)
|
||||||
.iter_instantiated_copied(self.tcx, proj.args)
|
.iter_instantiated_copied(self.tcx, proj.args)
|
||||||
{
|
{
|
||||||
pred.visit_with(self)?;
|
pred.visit_with(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
} else {
|
} else {
|
||||||
ty.super_visit_with(self)
|
ty.super_visit_with(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -809,9 +809,7 @@ impl<'tcx> GATArgsCollector<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
|
||||||
type BreakTy = !;
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
|
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
|
||||||
for (idx, arg) in p.args.iter().enumerate() {
|
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>,
|
params: FxHashSet<u32>,
|
||||||
}
|
}
|
||||||
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for CountParams {
|
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for CountParams {
|
||||||
type BreakTy = ();
|
type Result = ControlFlow<()>;
|
||||||
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
if let ty::Param(param) = t.kind() {
|
if let ty::Param(param) = t.kind() {
|
||||||
self.params.insert(param.index);
|
self.params.insert(param.index);
|
||||||
}
|
}
|
||||||
t.super_visit_with(self)
|
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(())
|
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() {
|
if let ty::ConstKind::Param(param) = c.kind() {
|
||||||
self.params.insert(param.index);
|
self.params.insert(param.index);
|
||||||
}
|
}
|
||||||
|
@ -1964,31 +1964,26 @@ fn is_late_bound_map(
|
|||||||
arg_is_constrained: Box<[bool]>,
|
arg_is_constrained: Box<[bool]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
|
||||||
use ty::Ty;
|
use ty::Ty;
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstrainedCollectorPostAstConv {
|
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() {
|
match t.kind() {
|
||||||
ty::Param(param_ty) => {
|
ty::Param(param_ty) => {
|
||||||
self.arg_is_constrained[param_ty.index as usize] = true;
|
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)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, _: ty::Const<'tcx>) -> ControlFlow<!> {
|
fn visit_const(&mut self, _: ty::Const<'tcx>) {}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<!> {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
debug!("r={:?}", r.kind());
|
debug!("r={:?}", r.kind());
|
||||||
if let ty::RegionKind::ReEarlyParam(region) = r.kind() {
|
if let ty::RegionKind::ReEarlyParam(region) = r.kind() {
|
||||||
self.arg_is_constrained[region.index as usize] = true;
|
self.arg_is_constrained[region.index as usize] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use rustc_data_structures::fx::FxHashSet;
|
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_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_type_ir::fold::TypeFoldable;
|
use rustc_type_ir::fold::TypeFoldable;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct Parameter(pub u32);
|
pub struct Parameter(pub u32);
|
||||||
@ -61,13 +60,13 @@ struct ParameterCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for 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() {
|
match *t.kind() {
|
||||||
// Projections are not injective in general.
|
// Projections are not injective in general.
|
||||||
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _)
|
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _)
|
||||||
if !self.include_nonconstraining =>
|
if !self.include_nonconstraining =>
|
||||||
{
|
{
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
// All weak alias types should've been expanded beforehand.
|
// All weak alias types should've been expanded beforehand.
|
||||||
ty::Alias(ty::Weak, _) if !self.include_nonconstraining => {
|
ty::Alias(ty::Weak, _) if !self.include_nonconstraining => {
|
||||||
@ -80,18 +79,17 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
|
|||||||
t.super_visit_with(self)
|
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 {
|
if let ty::ReEarlyParam(data) = *r {
|
||||||
self.parameters.push(Parameter::from(data));
|
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() {
|
match c.kind() {
|
||||||
ty::ConstKind::Unevaluated(..) if !self.include_nonconstraining => {
|
ty::ConstKind::Unevaluated(..) if !self.include_nonconstraining => {
|
||||||
// Constant expressions are not injective in general.
|
// Constant expressions are not injective in general.
|
||||||
return c.ty().visit_with(self);
|
return;
|
||||||
}
|
}
|
||||||
ty::ConstKind::Param(data) => {
|
ty::ConstKind::Param(data) => {
|
||||||
self.parameters.push(Parameter::from(data));
|
self.parameters.push(Parameter::from(data));
|
||||||
|
@ -10,7 +10,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
|||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
|
use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
|
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
/// Defines the `TermsContext` basically houses an arena where we can
|
/// Defines the `TermsContext` basically houses an arena where we can
|
||||||
/// allocate terms.
|
/// allocate terms.
|
||||||
@ -89,15 +88,14 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
|||||||
|
|
||||||
impl<'tcx> OpaqueTypeLifetimeCollector<'tcx> {
|
impl<'tcx> OpaqueTypeLifetimeCollector<'tcx> {
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
#[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) {
|
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);
|
let child_variances = self.tcx.variances_of(def_id);
|
||||||
for (a, v) in args.iter().zip_eq(child_variances) {
|
for (a, v) in args.iter().zip_eq(child_variances) {
|
||||||
if *v != ty::Bivariant {
|
if *v != ty::Bivariant {
|
||||||
a.visit_with(self)?;
|
a.visit_with(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
} else {
|
} else {
|
||||||
args.visit_with(self)
|
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> {
|
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> {
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
#[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() {
|
if let ty::RegionKind::ReEarlyParam(ebr) = r.kind() {
|
||||||
self.variances[ebr.index as usize] = ty::Invariant;
|
self.variances[ebr.index as usize] = ty::Invariant;
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
#[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() {
|
match t.kind() {
|
||||||
ty::Alias(_, ty::AliasTy { def_id, args, .. })
|
ty::Alias(_, ty::AliasTy { def_id, args, .. })
|
||||||
if matches!(self.tcx.def_kind(*def_id), DefKind::OpaqueTy) =>
|
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),
|
_ => t.super_visit_with(self),
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
itertools = "0.11"
|
itertools = "0.11"
|
||||||
rustc_ast = { path = "../rustc_ast" }
|
rustc_ast = { path = "../rustc_ast" }
|
||||||
|
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||||
rustc_attr = { path = "../rustc_attr" }
|
rustc_attr = { path = "../rustc_attr" }
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
rustc_errors = { path = "../rustc_errors" }
|
rustc_errors = { path = "../rustc_errors" }
|
||||||
|
@ -396,9 +396,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expected_ty: Ty<'tcx>,
|
expected_ty: Ty<'tcx>,
|
||||||
}
|
}
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MentionsTy<'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MentionsTy<'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 {
|
||||||
if t == self.expected_ty {
|
if t == self.expected_ty {
|
||||||
ControlFlow::Break(())
|
ControlFlow::Break(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -337,8 +337,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
) -> Option<ty::GenericArg<'tcx>> {
|
) -> Option<ty::GenericArg<'tcx>> {
|
||||||
struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId);
|
struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId);
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindAmbiguousParameter<'_, 'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindAmbiguousParameter<'_, 'tcx> {
|
||||||
type BreakTy = ty::GenericArg<'tcx>;
|
type Result = ControlFlow<ty::GenericArg<'tcx>>;
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||||
if let Some(origin) = self.0.type_var_origin(ty)
|
if let Some(origin) = self.0.type_var_origin(ty)
|
||||||
&& let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind
|
&& let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind
|
||||||
&& let generics = self.0.tcx.generics_of(self.1)
|
&& let generics = self.0.tcx.generics_of(self.1)
|
||||||
|
@ -8,6 +8,7 @@ doctest = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
|
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" }
|
||||||
|
@ -79,7 +79,7 @@ use rustc_middle::ty::{
|
|||||||
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
|
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ops::{ControlFlow, Deref};
|
use std::ops::Deref;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{cmp, fmt, iter};
|
use std::{cmp, fmt, iter};
|
||||||
|
|
||||||
@ -1623,7 +1623,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypesVisitor<'tcx> {
|
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypesVisitor<'tcx> {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) {
|
if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) {
|
||||||
let span = self.tcx.def_span(def_id);
|
let span = self.tcx.def_span(def_id);
|
||||||
// Avoid cluttering the output when the "found" and error span overlap:
|
// Avoid cluttering the output when the "found" and error span overlap:
|
||||||
|
@ -23,7 +23,6 @@ use rustc_span::symbol::Ident;
|
|||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
/// Print the error message for lifetime errors when the return type is a static `impl Trait`,
|
/// Print the error message for lifetime errors when the return type is a static `impl Trait`,
|
||||||
@ -545,13 +544,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||||||
pub struct TraitObjectVisitor(pub FxIndexSet<DefId>);
|
pub struct TraitObjectVisitor(pub FxIndexSet<DefId>);
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for TraitObjectVisitor {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for TraitObjectVisitor {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::Dynamic(preds, re, _) if re.is_static() => {
|
ty::Dynamic(preds, re, _) if re.is_static() => {
|
||||||
if let Some(def_id) = preds.principal_def_id() {
|
if let Some(def_id) = preds.principal_def_id() {
|
||||||
self.0.insert(def_id);
|
self.0.insert(def_id);
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
_ => t.super_visit_with(self),
|
_ => t.super_visit_with(self),
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,6 @@ use rustc_middle::ty::print::RegionHighlightMode;
|
|||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
/// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
|
/// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
|
||||||
pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option<ErrorGuaranteed> {
|
pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option<ErrorGuaranteed> {
|
||||||
@ -76,12 +74,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for HighlightBuilder<'tcx> {
|
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for HighlightBuilder<'tcx> {
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
if !r.has_name() && self.counter <= 3 {
|
if !r.has_name() && self.counter <= 3 {
|
||||||
self.highlight.highlighting_region(r, self.counter);
|
self.highlight.highlighting_region(r, self.counter);
|
||||||
self.counter += 1;
|
self.counter += 1;
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ use rustc_middle::ty::{
|
|||||||
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||||
};
|
};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
mod table;
|
mod table;
|
||||||
|
|
||||||
@ -415,29 +414,22 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'t
|
|||||||
where
|
where
|
||||||
OP: FnMut(ty::Region<'tcx>),
|
OP: FnMut(ty::Region<'tcx>),
|
||||||
{
|
{
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
|
||||||
&mut self,
|
|
||||||
t: &ty::Binder<'tcx, T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
t.super_visit_with(self);
|
t.super_visit_with(self);
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
match *r {
|
match *r {
|
||||||
// ignore bound regions, keep visiting
|
// ignore bound regions, keep visiting
|
||||||
ty::ReBound(_, _) => ControlFlow::Continue(()),
|
ty::ReBound(_, _) => {}
|
||||||
_ => {
|
_ => (self.op)(r),
|
||||||
(self.op)(r);
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) {
|
||||||
// We're only interested in types involving regions
|
// We're only interested in types involving regions
|
||||||
if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
|
if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
@ -488,8 +480,6 @@ where
|
|||||||
ty.super_visit_with(self);
|
ty.super_visit_with(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ use rustc_middle::ty::{
|
|||||||
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
|
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
use crate::infer::outlives::test_type_match;
|
use crate::infer::outlives::test_type_match;
|
||||||
use crate::infer::region_constraints::VerifyIfEq;
|
use crate::infer::region_constraints::VerifyIfEq;
|
||||||
|
|
||||||
@ -26,29 +24,22 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for FreeRegionsVisitor<'tcx, OP>
|
|||||||
where
|
where
|
||||||
OP: FnMut(ty::Region<'tcx>),
|
OP: FnMut(ty::Region<'tcx>),
|
||||||
{
|
{
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
|
||||||
&mut self,
|
|
||||||
t: &ty::Binder<'tcx, T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
t.super_visit_with(self);
|
t.super_visit_with(self);
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
match *r {
|
match *r {
|
||||||
// ignore bound regions, keep visiting
|
// ignore bound regions, keep visiting
|
||||||
ty::ReBound(_, _) => ControlFlow::Continue(()),
|
ty::ReBound(_, _) => {}
|
||||||
_ => {
|
_ => (self.op)(r),
|
||||||
(self.op)(r);
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) {
|
||||||
// We're only interested in types involving regions
|
// We're only interested in types involving regions
|
||||||
if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
|
if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Don't consider alias bounds on types that have escaping bound
|
// FIXME: Don't consider alias bounds on types that have escaping bound
|
||||||
@ -102,7 +93,7 @@ where
|
|||||||
&& outlives_bounds[1..].iter().all(|other_r| other_r == r)
|
&& outlives_bounds[1..].iter().all(|other_r| other_r == r)
|
||||||
{
|
{
|
||||||
assert!(r.type_flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS));
|
assert!(r.type_flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS));
|
||||||
r.visit_with(self)?;
|
r.visit_with(self);
|
||||||
} else {
|
} else {
|
||||||
// Skip lifetime parameters that are not captures.
|
// Skip lifetime parameters that are not captures.
|
||||||
let variances = match kind {
|
let variances = match kind {
|
||||||
@ -114,17 +105,13 @@ where
|
|||||||
if variances.map(|variances| variances[idx])
|
if variances.map(|variances| variances[idx])
|
||||||
!= Some(ty::Variance::Bivariant)
|
!= Some(ty::Variance::Bivariant)
|
||||||
{
|
{
|
||||||
s.visit_with(self)?;
|
s.visit_with(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => ty.super_visit_with(self),
|
||||||
ty.super_visit_with(self)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use crate::traits;
|
use crate::traits;
|
||||||
use crate::traits::project::Normalized;
|
use crate::traits::project::Normalized;
|
||||||
|
use rustc_ast_ir::try_visit;
|
||||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
||||||
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor};
|
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor};
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
// Structural impls for the structs in `traits`.
|
// Structural impls for the structs in `traits`.
|
||||||
|
|
||||||
@ -84,8 +84,8 @@ impl<'tcx, O: TypeFoldable<TyCtxt<'tcx>>> TypeFoldable<TyCtxt<'tcx>>
|
|||||||
impl<'tcx, O: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>>
|
impl<'tcx, O: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>>
|
||||||
for traits::Obligation<'tcx, O>
|
for traits::Obligation<'tcx, O>
|
||||||
{
|
{
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.predicate.visit_with(visitor)?;
|
try_visit!(self.predicate.visit_with(visitor));
|
||||||
self.param_env.visit_with(visitor)
|
self.param_env.visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1474,9 +1474,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
|
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
|
||||||
struct ProhibitOpaqueTypes;
|
struct ProhibitOpaqueTypes;
|
||||||
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueTypes {
|
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueTypes {
|
||||||
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 {
|
||||||
if !ty.has_opaque_types() {
|
if !ty.has_opaque_types() {
|
||||||
return ControlFlow::Continue(());
|
return ControlFlow::Continue(());
|
||||||
}
|
}
|
||||||
@ -1620,9 +1620,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'vis, 'a, 'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for FnPtrFinder<'vis, 'a, 'tcx> {
|
impl<'vis, 'a, 'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for FnPtrFinder<'vis, 'a, '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 {
|
||||||
if let ty::FnPtr(sig) = ty.kind()
|
if let ty::FnPtr(sig) = ty.kind()
|
||||||
&& !self.visitor.is_internal_abi(sig.abi())
|
&& !self.visitor.is_internal_abi(sig.abi())
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,14 @@ pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
|
|||||||
s.add_bounds(synstructure::AddBounds::Generics);
|
s.add_bounds(synstructure::AddBounds::Generics);
|
||||||
let body_visit = s.each(|bind| {
|
let body_visit = s.each(|bind| {
|
||||||
quote! {
|
quote! {
|
||||||
::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor)?;
|
match ::rustc_ast_ir::visit::VisitorResult::branch(
|
||||||
|
::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor)
|
||||||
|
) {
|
||||||
|
::core::ops::ControlFlow::Continue(()) => {},
|
||||||
|
::core::ops::ControlFlow::Break(r) => {
|
||||||
|
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
s.bind_with(|_| synstructure::BindStyle::Move);
|
s.bind_with(|_| synstructure::BindStyle::Move);
|
||||||
@ -45,9 +52,9 @@ pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
|
|||||||
fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(
|
fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(
|
||||||
&self,
|
&self,
|
||||||
__visitor: &mut __V
|
__visitor: &mut __V
|
||||||
) -> ::std::ops::ControlFlow<__V::BreakTy> {
|
) -> __V::Result {
|
||||||
match *self { #body_visit }
|
match *self { #body_visit }
|
||||||
::std::ops::ControlFlow::Continue(())
|
<__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -85,9 +85,9 @@ macro_rules! TrivialTypeTraversalImpls {
|
|||||||
fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<'tcx>>>(
|
fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<'tcx>>>(
|
||||||
&self,
|
&self,
|
||||||
_: &mut F)
|
_: &mut F)
|
||||||
-> ::std::ops::ControlFlow<F::BreakTy>
|
-> F::Result
|
||||||
{
|
{
|
||||||
::std::ops::ControlFlow::Continue(())
|
<F::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::ops::ControlFlow;
|
use rustc_ast_ir::try_visit;
|
||||||
|
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
|
use rustc_span::def_id::DefId;
|
||||||
|
|
||||||
use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints};
|
use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints};
|
||||||
use crate::traits::query::NoSolution;
|
use crate::traits::query::NoSolution;
|
||||||
@ -9,7 +9,6 @@ use crate::ty::{
|
|||||||
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable,
|
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable,
|
||||||
TypeVisitor,
|
TypeVisitor,
|
||||||
};
|
};
|
||||||
use rustc_span::def_id::DefId;
|
|
||||||
|
|
||||||
use super::BuiltinImplSource;
|
use super::BuiltinImplSource;
|
||||||
|
|
||||||
@ -196,13 +195,9 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
&self,
|
try_visit!(self.region_constraints.visit_with(visitor));
|
||||||
visitor: &mut V,
|
self.opaque_types.visit_with(visitor)
|
||||||
) -> std::ops::ControlFlow<V::BreakTy> {
|
|
||||||
self.region_constraints.visit_with(visitor)?;
|
|
||||||
self.opaque_types.visit_with(visitor)?;
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,10 +230,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
&self,
|
|
||||||
visitor: &mut V,
|
|
||||||
) -> std::ops::ControlFlow<V::BreakTy> {
|
|
||||||
self.opaque_types.visit_with(visitor)
|
self.opaque_types.visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,9 +482,9 @@ pub struct IsSuggestableVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'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() {
|
match *t.kind() {
|
||||||
Infer(InferTy::TyVar(_)) if self.infer_suggestable => {}
|
Infer(InferTy::TyVar(_)) if self.infer_suggestable => {}
|
||||||
|
|
||||||
@ -536,7 +536,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
|
|||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: Const<'tcx>) -> Self::Result {
|
||||||
match c.kind() {
|
match c.kind() {
|
||||||
ConstKind::Infer(InferConst::Var(_)) if self.infer_suggestable => {}
|
ConstKind::Infer(InferConst::Var(_)) if self.infer_suggestable => {}
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ use crate::ty::sty::{ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineCon
|
|||||||
use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
|
use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||||
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
||||||
|
|
||||||
|
use rustc_ast_ir::visit::VisitorResult;
|
||||||
|
use rustc_ast_ir::walk_visitable_list;
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
use rustc_errors::{DiagArgValue, IntoDiagnosticArg};
|
use rustc_errors::{DiagArgValue, IntoDiagnosticArg};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
@ -19,7 +21,7 @@ use std::cmp::Ordering;
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
use std::ops::{ControlFlow, Deref};
|
use std::ops::Deref;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
/// An entity in the Rust type system, which can be one of
|
/// An entity in the Rust type system, which can be one of
|
||||||
@ -240,7 +242,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
match self.unpack() {
|
match self.unpack() {
|
||||||
GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
|
GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
|
||||||
GenericArgKind::Type(ty) => ty.visit_with(visitor),
|
GenericArgKind::Type(ty) => ty.visit_with(visitor),
|
||||||
@ -554,8 +556,9 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
|
|||||||
|
|
||||||
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> {
|
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
walk_visitable_list!(visitor, self.iter());
|
||||||
|
V::Result::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ pub use generics::*;
|
|||||||
pub use intrinsic::IntrinsicDef;
|
pub use intrinsic::IntrinsicDef;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::node_id::NodeMap;
|
use rustc_ast::node_id::NodeMap;
|
||||||
pub use rustc_ast_ir::{Movability, Mutability};
|
pub use rustc_ast_ir::{try_visit, Movability, Mutability};
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
@ -64,7 +64,6 @@ use std::hash::{Hash, Hasher};
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::{fmt, str};
|
use std::{fmt, str};
|
||||||
|
|
||||||
@ -599,7 +598,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.unpack().visit_with(visitor)
|
self.unpack().visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1043,8 +1042,8 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.caller_bounds().visit_with(visitor)?;
|
try_visit!(self.caller_bounds().visit_with(visitor));
|
||||||
self.reveal().visit_with(visitor)
|
self.reveal().visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ use std::cell::Cell;
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt::{self, Write as _};
|
use std::fmt::{self, Write as _};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::{ControlFlow, Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
// `pretty` is a separate module only for organization.
|
// `pretty` is a separate module only for organization.
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -2667,9 +2667,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for RegionNameCollector<'tcx> {
|
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for RegionNameCollector<'tcx> {
|
||||||
type BreakTy = ();
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
trace!("address: {:p}", r.0.0);
|
trace!("address: {:p}", r.0.0);
|
||||||
|
|
||||||
// Collect all named lifetimes. These allow us to prevent duplication
|
// Collect all named lifetimes. These allow us to prevent duplication
|
||||||
@ -2678,18 +2676,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
|||||||
if let Some(name) = r.get_name() {
|
if let Some(name) = r.get_name() {
|
||||||
self.used_region_names.insert(name);
|
self.used_region_names.insert(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We collect types in order to prevent really large types from compiling for
|
// We collect types in order to prevent really large types from compiling for
|
||||||
// a really long time. See issue #83150 for why this is necessary.
|
// a really long time. See issue #83150 for why this is necessary.
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) {
|
||||||
let not_previously_inserted = self.type_collector.insert(ty);
|
let not_previously_inserted = self.type_collector.insert(ty);
|
||||||
if not_previously_inserted {
|
if not_previously_inserted {
|
||||||
ty.super_visit_with(self)
|
ty.super_visit_with(self)
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,14 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
|
|||||||
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
||||||
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||||
use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
|
use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
|
||||||
|
use rustc_ast_ir::try_visit;
|
||||||
|
use rustc_ast_ir::visit::VisitorResult;
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_target::abi::TyAndLayout;
|
use rustc_target::abi::TyAndLayout;
|
||||||
use rustc_type_ir::{ConstKind, DebugWithInfcx, InferCtxtLike, WithInfcx};
|
use rustc_type_ir::{ConstKind, DebugWithInfcx, InferCtxtLike, WithInfcx};
|
||||||
|
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
use super::print::PrettyPrinter;
|
use super::print::PrettyPrinter;
|
||||||
use super::{GenericArg, GenericArgKind, Region};
|
use super::{GenericArg, GenericArgKind, Region};
|
||||||
@ -482,11 +483,8 @@ impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
|
|||||||
// Traversal implementations.
|
// Traversal implementations.
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, _visitor: &mut V) -> V::Result {
|
||||||
&self,
|
V::Result::output()
|
||||||
_visitor: &mut V,
|
|
||||||
) -> ControlFlow<V::BreakTy> {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +498,7 @@ impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> TypeFoldable<TyCtxt<'tcx>> for ty::Bin
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
|
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
visitor.visit_binder(self)
|
visitor.visit_binder(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -517,10 +515,7 @@ impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> TypeSuperFoldable<TyCtxt<'tcx>> for ty
|
|||||||
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeSuperVisitable<TyCtxt<'tcx>>
|
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeSuperVisitable<TyCtxt<'tcx>>
|
||||||
for ty::Binder<'tcx, T>
|
for ty::Binder<'tcx, T>
|
||||||
{
|
{
|
||||||
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
&self,
|
|
||||||
visitor: &mut V,
|
|
||||||
) -> ControlFlow<V::BreakTy> {
|
|
||||||
self.as_ref().skip_binder().visit_with(visitor)
|
self.as_ref().skip_binder().visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -553,7 +548,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
visitor.visit_ty(*self)
|
visitor.visit_ty(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -609,27 +604,24 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
|
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||||
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
&self,
|
|
||||||
visitor: &mut V,
|
|
||||||
) -> ControlFlow<V::BreakTy> {
|
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
ty::RawPtr(ref tm) => tm.visit_with(visitor),
|
ty::RawPtr(ref tm) => tm.visit_with(visitor),
|
||||||
ty::Array(typ, sz) => {
|
ty::Array(typ, sz) => {
|
||||||
typ.visit_with(visitor)?;
|
try_visit!(typ.visit_with(visitor));
|
||||||
sz.visit_with(visitor)
|
sz.visit_with(visitor)
|
||||||
}
|
}
|
||||||
ty::Slice(typ) => typ.visit_with(visitor),
|
ty::Slice(typ) => typ.visit_with(visitor),
|
||||||
ty::Adt(_, args) => args.visit_with(visitor),
|
ty::Adt(_, args) => args.visit_with(visitor),
|
||||||
ty::Dynamic(ref trait_ty, ref reg, _) => {
|
ty::Dynamic(ref trait_ty, ref reg, _) => {
|
||||||
trait_ty.visit_with(visitor)?;
|
try_visit!(trait_ty.visit_with(visitor));
|
||||||
reg.visit_with(visitor)
|
reg.visit_with(visitor)
|
||||||
}
|
}
|
||||||
ty::Tuple(ts) => ts.visit_with(visitor),
|
ty::Tuple(ts) => ts.visit_with(visitor),
|
||||||
ty::FnDef(_, args) => args.visit_with(visitor),
|
ty::FnDef(_, args) => args.visit_with(visitor),
|
||||||
ty::FnPtr(ref f) => f.visit_with(visitor),
|
ty::FnPtr(ref f) => f.visit_with(visitor),
|
||||||
ty::Ref(r, ty, _) => {
|
ty::Ref(r, ty, _) => {
|
||||||
r.visit_with(visitor)?;
|
try_visit!(r.visit_with(visitor));
|
||||||
ty.visit_with(visitor)
|
ty.visit_with(visitor)
|
||||||
}
|
}
|
||||||
ty::Coroutine(_did, ref args) => args.visit_with(visitor),
|
ty::Coroutine(_did, ref args) => args.visit_with(visitor),
|
||||||
@ -650,7 +642,7 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||||||
| ty::Placeholder(..)
|
| ty::Placeholder(..)
|
||||||
| ty::Param(..)
|
| ty::Param(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Foreign(..) => ControlFlow::Continue(()),
|
| ty::Foreign(..) => V::Result::output(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -665,7 +657,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
visitor.visit_region(*self)
|
visitor.visit_region(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -690,13 +682,13 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
visitor.visit_predicate(*self)
|
visitor.visit_predicate(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
visitor.visit_predicate(self.as_predicate())
|
visitor.visit_predicate(self.as_predicate())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -712,10 +704,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
|
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
|
||||||
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
&self,
|
|
||||||
visitor: &mut V,
|
|
||||||
) -> ControlFlow<V::BreakTy> {
|
|
||||||
self.kind().visit_with(visitor)
|
self.kind().visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -739,7 +728,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
visitor.visit_const(*self)
|
visitor.visit_const(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -771,16 +760,13 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
||||||
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
&self,
|
try_visit!(self.ty().visit_with(visitor));
|
||||||
visitor: &mut V,
|
|
||||||
) -> ControlFlow<V::BreakTy> {
|
|
||||||
self.ty().visit_with(visitor)?;
|
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
ConstKind::Param(p) => p.visit_with(visitor),
|
ConstKind::Param(p) => p.visit_with(visitor),
|
||||||
ConstKind::Infer(i) => i.visit_with(visitor),
|
ConstKind::Infer(i) => i.visit_with(visitor),
|
||||||
ConstKind::Bound(d, b) => {
|
ConstKind::Bound(d, b) => {
|
||||||
d.visit_with(visitor)?;
|
try_visit!(d.visit_with(visitor));
|
||||||
b.visit_with(visitor)
|
b.visit_with(visitor)
|
||||||
}
|
}
|
||||||
ConstKind::Placeholder(p) => p.visit_with(visitor),
|
ConstKind::Placeholder(p) => p.visit_with(visitor),
|
||||||
@ -802,25 +788,19 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, _visitor: &mut V) -> V::Result {
|
||||||
&self,
|
V::Result::output()
|
||||||
_visitor: &mut V,
|
|
||||||
) -> ControlFlow<V::BreakTy> {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
|
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
|
||||||
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
&self,
|
|
||||||
visitor: &mut V,
|
|
||||||
) -> ControlFlow<V::BreakTy> {
|
|
||||||
self.args.visit_with(visitor)
|
self.args.visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
visitor.visit_ty(self.ty)
|
visitor.visit_ty(self.ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -828,10 +808,9 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
|
|||||||
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>> + Debug + Clone> TypeVisitable<TyCtxt<'tcx>>
|
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>> + Debug + Clone> TypeVisitable<TyCtxt<'tcx>>
|
||||||
for Spanned<T>
|
for Spanned<T>
|
||||||
{
|
{
|
||||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.node.visit_with(visitor)?;
|
try_visit!(self.node.visit_with(visitor));
|
||||||
self.span.visit_with(visitor)?;
|
self.span.visit_with(visitor)
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2113,9 +2113,9 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
struct ContainsTyVisitor<'tcx>(Ty<'tcx>);
|
struct ContainsTyVisitor<'tcx>(Ty<'tcx>);
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTyVisitor<'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTyVisitor<'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 {
|
||||||
if self.0 == t { ControlFlow::Break(()) } else { t.super_visit_with(self) }
|
if self.0 == t { ControlFlow::Break(()) } else { t.super_visit_with(self) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2131,9 +2131,9 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
struct ContainsClosureVisitor;
|
struct ContainsClosureVisitor;
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsClosureVisitor {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsClosureVisitor {
|
||||||
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 {
|
||||||
if let ty::Closure(..) = t.kind() {
|
if let ty::Closure(..) = t.kind() {
|
||||||
ControlFlow::Break(())
|
ControlFlow::Break(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -64,19 +64,19 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
where
|
where
|
||||||
F: FnMut(ty::Region<'tcx>) -> bool,
|
F: FnMut(ty::Region<'tcx>) -> bool,
|
||||||
{
|
{
|
||||||
type BreakTy = ();
|
type Result = ControlFlow<()>;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: &Binder<'tcx, T>,
|
t: &Binder<'tcx, T>,
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
) -> Self::Result {
|
||||||
self.outer_index.shift_in(1);
|
self.outer_index.shift_in(1);
|
||||||
let result = t.super_visit_with(self);
|
let result = t.super_visit_with(self);
|
||||||
self.outer_index.shift_out(1);
|
self.outer_index.shift_out(1);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReBound(debruijn, _) if debruijn < self.outer_index => {
|
ty::ReBound(debruijn, _) if debruijn < self.outer_index => {
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
@ -91,7 +91,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||||
// We're only interested in types involving regions
|
// We're only interested in types involving regions
|
||||||
if ty.flags().intersects(TypeFlags::HAS_FREE_REGIONS) {
|
if ty.flags().intersects(TypeFlags::HAS_FREE_REGIONS) {
|
||||||
ty.super_visit_with(self)
|
ty.super_visit_with(self)
|
||||||
@ -140,8 +140,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
let mut collector = LateBoundRegionsCollector::new(just_constrained);
|
let mut collector = LateBoundRegionsCollector::new(just_constrained);
|
||||||
let value = value.skip_binder();
|
let value = value.skip_binder();
|
||||||
let value = if just_constrained { self.expand_weak_alias_tys(value) } else { value };
|
let value = if just_constrained { self.expand_weak_alias_tys(value) } else { value };
|
||||||
let result = value.visit_with(&mut collector);
|
value.visit_with(&mut collector);
|
||||||
assert!(result.is_continue()); // should never have stopped early
|
|
||||||
collector.regions
|
collector.regions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,19 +164,19 @@ impl<'tcx> ValidateBoundVars<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
|
||||||
type BreakTy = ();
|
type Result = ControlFlow<()>;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: &Binder<'tcx, T>,
|
t: &Binder<'tcx, T>,
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
) -> Self::Result {
|
||||||
self.binder_index.shift_in(1);
|
self.binder_index.shift_in(1);
|
||||||
let result = t.super_visit_with(self);
|
let result = t.super_visit_with(self);
|
||||||
self.binder_index.shift_out(1);
|
self.binder_index.shift_out(1);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||||
if t.outer_exclusive_binder() < self.binder_index
|
if t.outer_exclusive_binder() < self.binder_index
|
||||||
|| !self.visited.insert((self.binder_index, t))
|
|| !self.visited.insert((self.binder_index, t))
|
||||||
{
|
{
|
||||||
@ -211,7 +210,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
|
|||||||
t.super_visit_with(self)
|
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 {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReBound(index, br) if index == self.binder_index => {
|
ty::ReBound(index, br) if index == self.binder_index => {
|
||||||
if self.bound_vars.len() <= br.var.as_usize() {
|
if self.bound_vars.len() <= br.var.as_usize() {
|
||||||
@ -266,23 +265,19 @@ impl LateBoundRegionsCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) {
|
||||||
&mut self,
|
|
||||||
t: &Binder<'tcx, T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
self.current_index.shift_in(1);
|
self.current_index.shift_in(1);
|
||||||
let result = t.super_visit_with(self);
|
t.super_visit_with(self);
|
||||||
self.current_index.shift_out(1);
|
self.current_index.shift_out(1);
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
if self.just_constrained {
|
if self.just_constrained {
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
// If we are only looking for "constrained" regions, we have to ignore the
|
// If we are only looking for "constrained" regions, we have to ignore the
|
||||||
// inputs to a projection as they may not appear in the normalized form.
|
// inputs to a projection as they may not appear in the normalized form.
|
||||||
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) => {
|
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) => {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
// All weak alias types should've been expanded beforehand.
|
// All weak alias types should've been expanded beforehand.
|
||||||
ty::Alias(ty::Weak, _) => bug!("unexpected weak alias type"),
|
ty::Alias(ty::Weak, _) => bug!("unexpected weak alias type"),
|
||||||
@ -293,26 +288,25 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
|
|||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: ty::Const<'tcx>) {
|
||||||
// if we are only looking for "constrained" region, we have to
|
// if we are only looking for "constrained" region, we have to
|
||||||
// ignore the inputs of an unevaluated const, as they may not appear
|
// ignore the inputs of an unevaluated const, as they may not appear
|
||||||
// in the normalized form
|
// in the normalized form
|
||||||
if self.just_constrained {
|
if self.just_constrained {
|
||||||
if let ty::ConstKind::Unevaluated(..) = c.kind() {
|
if let ty::ConstKind::Unevaluated(..) = c.kind() {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.super_visit_with(self)
|
c.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::ReBound(debruijn, br) = *r {
|
if let ty::ReBound(debruijn, br) = *r {
|
||||||
if debruijn == self.current_index {
|
if debruijn == self.current_index {
|
||||||
self.regions.insert(br.kind);
|
self.regions.insert(br.kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +326,7 @@ impl MaxUniverse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
if let ty::Placeholder(placeholder) = t.kind() {
|
if let ty::Placeholder(placeholder) = t.kind() {
|
||||||
self.max_universe = ty::UniverseIndex::from_u32(
|
self.max_universe = ty::UniverseIndex::from_u32(
|
||||||
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
||||||
@ -342,7 +336,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
|||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: ty::consts::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: ty::consts::Const<'tcx>) {
|
||||||
if let ty::ConstKind::Placeholder(placeholder) = c.kind() {
|
if let ty::ConstKind::Placeholder(placeholder) = c.kind() {
|
||||||
self.max_universe = ty::UniverseIndex::from_u32(
|
self.max_universe = ty::UniverseIndex::from_u32(
|
||||||
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
||||||
@ -352,13 +346,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
|||||||
c.super_visit_with(self)
|
c.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::RePlaceholder(placeholder) = *r {
|
if let ty::RePlaceholder(placeholder) = *r {
|
||||||
self.max_universe = ty::UniverseIndex::from_u32(
|
self.max_universe = ty::UniverseIndex::from_u32(
|
||||||
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ use rustc_middle::ty::{
|
|||||||
GenericArgsRef, Ty, TyCtxt, UnusedGenericParams,
|
GenericArgsRef, Ty, TyCtxt, UnusedGenericParams,
|
||||||
};
|
};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
use crate::errors::UnusedGenericParamsHint;
|
use crate::errors::UnusedGenericParamsHint;
|
||||||
|
|
||||||
@ -291,31 +290,29 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
|
|||||||
|
|
||||||
impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for MarkUsedGenericParams<'a, 'tcx> {
|
impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for MarkUsedGenericParams<'a, 'tcx> {
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: ty::Const<'tcx>) {
|
||||||
if !c.has_non_region_param() {
|
if !c.has_non_region_param() {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match c.kind() {
|
match c.kind() {
|
||||||
ty::ConstKind::Param(param) => {
|
ty::ConstKind::Param(param) => {
|
||||||
debug!(?param);
|
debug!(?param);
|
||||||
self.unused_parameters.mark_used(param.index);
|
self.unused_parameters.mark_used(param.index);
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args })
|
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args })
|
||||||
if matches!(self.tcx.def_kind(def), DefKind::AnonConst) =>
|
if matches!(self.tcx.def_kind(def), DefKind::AnonConst) =>
|
||||||
{
|
{
|
||||||
self.visit_child_body(def, args);
|
self.visit_child_body(def, args);
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
_ => c.super_visit_with(self),
|
_ => c.super_visit_with(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) {
|
||||||
if !ty.has_non_region_param() {
|
if !ty.has_non_region_param() {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
@ -323,18 +320,16 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for MarkUsedGenericParams<'a, 'tcx> {
|
|||||||
debug!(?def_id);
|
debug!(?def_id);
|
||||||
// Avoid cycle errors with coroutines.
|
// Avoid cycle errors with coroutines.
|
||||||
if def_id == self.def_id {
|
if def_id == self.def_id {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consider any generic parameters used by any closures/coroutines as used in the
|
// Consider any generic parameters used by any closures/coroutines as used in the
|
||||||
// parent.
|
// parent.
|
||||||
self.visit_child_body(def_id, args);
|
self.visit_child_body(def_id, args);
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
ty::Param(param) => {
|
ty::Param(param) => {
|
||||||
debug!(?param);
|
debug!(?param);
|
||||||
self.unused_parameters.mark_used(param.index);
|
self.unused_parameters.mark_used(param.index);
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
_ => ty.super_visit_with(self),
|
_ => ty.super_visit_with(self),
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ extern crate tracing;
|
|||||||
|
|
||||||
mod errors;
|
mod errors;
|
||||||
|
|
||||||
|
use rustc_ast::visit::{try_visit, VisitorResult};
|
||||||
use rustc_ast::MacroDef;
|
use rustc_ast::MacroDef;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
@ -67,17 +68,13 @@ impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
|
|||||||
/// manually. Second, it doesn't visit some type components like signatures of fn types, or traits
|
/// manually. Second, it doesn't visit some type components like signatures of fn types, or traits
|
||||||
/// in `impl Trait`, see individual comments in `DefIdVisitorSkeleton::visit_ty`.
|
/// in `impl Trait`, see individual comments in `DefIdVisitorSkeleton::visit_ty`.
|
||||||
trait DefIdVisitor<'tcx> {
|
trait DefIdVisitor<'tcx> {
|
||||||
type BreakTy = ();
|
type Result: VisitorResult = ();
|
||||||
const SHALLOW: bool = false;
|
const SHALLOW: bool = false;
|
||||||
const SKIP_ASSOC_TYS: bool = false;
|
const SKIP_ASSOC_TYS: bool = false;
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||||
fn visit_def_id(
|
fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display)
|
||||||
&mut self,
|
-> Self::Result;
|
||||||
def_id: DefId,
|
|
||||||
kind: &str,
|
|
||||||
descr: &dyn fmt::Display,
|
|
||||||
) -> ControlFlow<Self::BreakTy>;
|
|
||||||
|
|
||||||
/// Not overridden, but used to actually visit types and traits.
|
/// Not overridden, but used to actually visit types and traits.
|
||||||
fn skeleton(&mut self) -> DefIdVisitorSkeleton<'_, 'tcx, Self> {
|
fn skeleton(&mut self) -> DefIdVisitorSkeleton<'_, 'tcx, Self> {
|
||||||
@ -87,25 +84,16 @@ trait DefIdVisitor<'tcx> {
|
|||||||
dummy: Default::default(),
|
dummy: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit(
|
fn visit(&mut self, ty_fragment: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result {
|
||||||
&mut self,
|
|
||||||
ty_fragment: impl TypeVisitable<TyCtxt<'tcx>>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
ty_fragment.visit_with(&mut self.skeleton())
|
ty_fragment.visit_with(&mut self.skeleton())
|
||||||
}
|
}
|
||||||
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> Self::Result {
|
||||||
self.skeleton().visit_trait(trait_ref)
|
self.skeleton().visit_trait(trait_ref)
|
||||||
}
|
}
|
||||||
fn visit_predicates(
|
fn visit_predicates(&mut self, predicates: ty::GenericPredicates<'tcx>) -> Self::Result {
|
||||||
&mut self,
|
|
||||||
predicates: ty::GenericPredicates<'tcx>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
self.skeleton().visit_clauses(predicates.predicates)
|
self.skeleton().visit_clauses(predicates.predicates)
|
||||||
}
|
}
|
||||||
fn visit_clauses(
|
fn visit_clauses(&mut self, clauses: &[(ty::Clause<'tcx>, Span)]) -> Self::Result {
|
||||||
&mut self,
|
|
||||||
clauses: &[(ty::Clause<'tcx>, Span)],
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
self.skeleton().visit_clauses(clauses)
|
self.skeleton().visit_clauses(clauses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,36 +108,42 @@ impl<'tcx, V> DefIdVisitorSkeleton<'_, 'tcx, V>
|
|||||||
where
|
where
|
||||||
V: DefIdVisitor<'tcx> + ?Sized,
|
V: DefIdVisitor<'tcx> + ?Sized,
|
||||||
{
|
{
|
||||||
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<V::BreakTy> {
|
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> V::Result {
|
||||||
let TraitRef { def_id, args, .. } = trait_ref;
|
let TraitRef { def_id, args, .. } = trait_ref;
|
||||||
self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref.print_only_trait_path())?;
|
try_visit!(self.def_id_visitor.visit_def_id(
|
||||||
if V::SHALLOW { ControlFlow::Continue(()) } else { args.visit_with(self) }
|
def_id,
|
||||||
|
"trait",
|
||||||
|
&trait_ref.print_only_trait_path()
|
||||||
|
));
|
||||||
|
if V::SHALLOW { V::Result::output() } else { args.visit_with(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> {
|
fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> V::Result {
|
||||||
let tcx = self.def_id_visitor.tcx();
|
let tcx = self.def_id_visitor.tcx();
|
||||||
let (trait_ref, assoc_args) = projection.trait_ref_and_own_args(tcx);
|
let (trait_ref, assoc_args) = projection.trait_ref_and_own_args(tcx);
|
||||||
self.visit_trait(trait_ref)?;
|
try_visit!(self.visit_trait(trait_ref));
|
||||||
if V::SHALLOW {
|
if V::SHALLOW {
|
||||||
ControlFlow::Continue(())
|
V::Result::output()
|
||||||
} else {
|
} else {
|
||||||
assoc_args.iter().try_for_each(|arg| arg.visit_with(self))
|
V::Result::from_branch(
|
||||||
|
assoc_args.iter().try_for_each(|arg| arg.visit_with(self).branch()),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_clause(&mut self, clause: ty::Clause<'tcx>) -> ControlFlow<V::BreakTy> {
|
fn visit_clause(&mut self, clause: ty::Clause<'tcx>) -> V::Result {
|
||||||
match clause.kind().skip_binder() {
|
match clause.kind().skip_binder() {
|
||||||
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
|
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
|
||||||
self.visit_trait(trait_ref)
|
self.visit_trait(trait_ref)
|
||||||
}
|
}
|
||||||
ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
|
ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
|
||||||
term.visit_with(self)?;
|
try_visit!(term.visit_with(self));
|
||||||
self.visit_projection_ty(projection_ty)
|
self.visit_projection_ty(projection_ty)
|
||||||
}
|
}
|
||||||
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => ty.visit_with(self),
|
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => ty.visit_with(self),
|
||||||
ty::ClauseKind::RegionOutlives(..) => ControlFlow::Continue(()),
|
ty::ClauseKind::RegionOutlives(..) => V::Result::output(),
|
||||||
ty::ClauseKind::ConstArgHasType(ct, ty) => {
|
ty::ClauseKind::ConstArgHasType(ct, ty) => {
|
||||||
ct.visit_with(self)?;
|
try_visit!(ct.visit_with(self));
|
||||||
ty.visit_with(self)
|
ty.visit_with(self)
|
||||||
}
|
}
|
||||||
ty::ClauseKind::ConstEvaluatable(ct) => ct.visit_with(self),
|
ty::ClauseKind::ConstEvaluatable(ct) => ct.visit_with(self),
|
||||||
@ -157,8 +151,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_clauses(&mut self, clauses: &[(ty::Clause<'tcx>, Span)]) -> ControlFlow<V::BreakTy> {
|
fn visit_clauses(&mut self, clauses: &[(ty::Clause<'tcx>, Span)]) -> V::Result {
|
||||||
clauses.into_iter().try_for_each(|&(clause, _span)| self.visit_clause(clause))
|
for &(clause, _) in clauses {
|
||||||
|
try_visit!(self.visit_clause(clause));
|
||||||
|
}
|
||||||
|
V::Result::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,13 +163,13 @@ impl<'tcx, V> TypeVisitor<TyCtxt<'tcx>> for DefIdVisitorSkeleton<'_, 'tcx, V>
|
|||||||
where
|
where
|
||||||
V: DefIdVisitor<'tcx> + ?Sized,
|
V: DefIdVisitor<'tcx> + ?Sized,
|
||||||
{
|
{
|
||||||
type BreakTy = V::BreakTy;
|
type Result = V::Result;
|
||||||
|
|
||||||
fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> Self::Result {
|
||||||
self.visit_clause(p.as_clause().unwrap())
|
self.visit_clause(p.as_clause().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||||
let tcx = self.def_id_visitor.tcx();
|
let tcx = self.def_id_visitor.tcx();
|
||||||
// GenericArgs are not visited here because they are visited below
|
// GenericArgs are not visited here because they are visited below
|
||||||
// in `super_visit_with`.
|
// in `super_visit_with`.
|
||||||
@ -183,16 +180,16 @@ where
|
|||||||
| ty::Closure(def_id, ..)
|
| ty::Closure(def_id, ..)
|
||||||
| ty::CoroutineClosure(def_id, ..)
|
| ty::CoroutineClosure(def_id, ..)
|
||||||
| ty::Coroutine(def_id, ..) => {
|
| ty::Coroutine(def_id, ..) => {
|
||||||
self.def_id_visitor.visit_def_id(def_id, "type", &ty)?;
|
try_visit!(self.def_id_visitor.visit_def_id(def_id, "type", &ty));
|
||||||
if V::SHALLOW {
|
if V::SHALLOW {
|
||||||
return ControlFlow::Continue(());
|
return V::Result::output();
|
||||||
}
|
}
|
||||||
// Default type visitor doesn't visit signatures of fn types.
|
// Default type visitor doesn't visit signatures of fn types.
|
||||||
// Something like `fn() -> Priv {my_func}` is considered a private type even if
|
// Something like `fn() -> Priv {my_func}` is considered a private type even if
|
||||||
// `my_func` is public, so we need to visit signatures.
|
// `my_func` is public, so we need to visit signatures.
|
||||||
if let ty::FnDef(..) = ty.kind() {
|
if let ty::FnDef(..) = ty.kind() {
|
||||||
// FIXME: this should probably use `args` from `FnDef`
|
// FIXME: this should probably use `args` from `FnDef`
|
||||||
tcx.fn_sig(def_id).instantiate_identity().visit_with(self)?;
|
try_visit!(tcx.fn_sig(def_id).instantiate_identity().visit_with(self));
|
||||||
}
|
}
|
||||||
// Inherent static methods don't have self type in args.
|
// Inherent static methods don't have self type in args.
|
||||||
// Something like `fn() {my_method}` type of the method
|
// Something like `fn() {my_method}` type of the method
|
||||||
@ -200,7 +197,9 @@ where
|
|||||||
// so we need to visit the self type additionally.
|
// so we need to visit the self type additionally.
|
||||||
if let Some(assoc_item) = tcx.opt_associated_item(def_id) {
|
if let Some(assoc_item) = tcx.opt_associated_item(def_id) {
|
||||||
if let Some(impl_def_id) = assoc_item.impl_container(tcx) {
|
if let Some(impl_def_id) = assoc_item.impl_container(tcx) {
|
||||||
tcx.type_of(impl_def_id).instantiate_identity().visit_with(self)?;
|
try_visit!(
|
||||||
|
tcx.type_of(impl_def_id).instantiate_identity().visit_with(self)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,10 +210,10 @@ where
|
|||||||
// as visible/reachable even if `Type` is private.
|
// as visible/reachable even if `Type` is private.
|
||||||
// Ideally, associated types should be instantiated in the same way as
|
// Ideally, associated types should be instantiated in the same way as
|
||||||
// free type aliases, but this isn't done yet.
|
// free type aliases, but this isn't done yet.
|
||||||
return ControlFlow::Continue(());
|
return V::Result::output();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.def_id_visitor.visit_def_id(
|
try_visit!(self.def_id_visitor.visit_def_id(
|
||||||
data.def_id,
|
data.def_id,
|
||||||
match kind {
|
match kind {
|
||||||
ty::Inherent | ty::Projection => "associated type",
|
ty::Inherent | ty::Projection => "associated type",
|
||||||
@ -222,15 +221,17 @@ where
|
|||||||
ty::Opaque => unreachable!(),
|
ty::Opaque => unreachable!(),
|
||||||
},
|
},
|
||||||
&LazyDefPathStr { def_id: data.def_id, tcx },
|
&LazyDefPathStr { def_id: data.def_id, tcx },
|
||||||
)?;
|
));
|
||||||
|
|
||||||
// This will also visit args if necessary, so we don't need to recurse.
|
// This will also visit args if necessary, so we don't need to recurse.
|
||||||
return if V::SHALLOW {
|
return if V::SHALLOW {
|
||||||
ControlFlow::Continue(())
|
V::Result::output()
|
||||||
} else if kind == ty::Projection {
|
} else if kind == ty::Projection {
|
||||||
self.visit_projection_ty(data)
|
self.visit_projection_ty(data)
|
||||||
} else {
|
} else {
|
||||||
data.args.iter().try_for_each(|arg| arg.visit_with(self))
|
V::Result::from_branch(
|
||||||
|
data.args.iter().try_for_each(|arg| arg.visit_with(self).branch()),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ty::Dynamic(predicates, ..) => {
|
ty::Dynamic(predicates, ..) => {
|
||||||
@ -245,7 +246,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let ty::ExistentialTraitRef { def_id, args: _ } = trait_ref;
|
let ty::ExistentialTraitRef { def_id, args: _ } = trait_ref;
|
||||||
self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref)?;
|
try_visit!(self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
|
||||||
@ -258,7 +259,7 @@ where
|
|||||||
// through the trait list (default type visitor doesn't visit those traits).
|
// through the trait list (default type visitor doesn't visit those traits).
|
||||||
// All traits in the list are considered the "primary" part of the type
|
// All traits in the list are considered the "primary" part of the type
|
||||||
// and are visited by shallow visitors.
|
// and are visited by shallow visitors.
|
||||||
self.visit_clauses(tcx.explicit_item_bounds(def_id).skip_binder())?;
|
try_visit!(self.visit_clauses(tcx.explicit_item_bounds(def_id).skip_binder()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// These types don't have their own def-ids (but may have subcomponents
|
// These types don't have their own def-ids (but may have subcomponents
|
||||||
@ -285,10 +286,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if V::SHALLOW { ControlFlow::Continue(()) } else { ty.super_visit_with(self) }
|
if V::SHALLOW { V::Result::output() } else { ty.super_visit_with(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: Const<'tcx>) -> Self::Result {
|
||||||
let tcx = self.def_id_visitor.tcx();
|
let tcx = self.def_id_visitor.tcx();
|
||||||
tcx.expand_abstract_consts(c).super_visit_with(self)
|
tcx.expand_abstract_consts(c).super_visit_with(self)
|
||||||
}
|
}
|
||||||
@ -316,16 +317,10 @@ impl<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> DefIdVisitor<'tcx>
|
|||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
fn visit_def_id(
|
fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) {
|
||||||
&mut self,
|
|
||||||
def_id: DefId,
|
|
||||||
_kind: &str,
|
|
||||||
_descr: &dyn fmt::Display,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
self.min = VL::new_min(self, def_id);
|
self.min = VL::new_min(self, def_id);
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,12 +831,7 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
|
|||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.ev.tcx
|
self.ev.tcx
|
||||||
}
|
}
|
||||||
fn visit_def_id(
|
fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) {
|
||||||
&mut self,
|
|
||||||
def_id: DefId,
|
|
||||||
_kind: &str,
|
|
||||||
_descr: &dyn fmt::Display,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
// All effective visibilities except `reachable_through_impl_trait` are limited to
|
// All effective visibilities except `reachable_through_impl_trait` are limited to
|
||||||
// nominal visibility. If any type or trait is leaked farther than that, it will
|
// nominal visibility. If any type or trait is leaked farther than that, it will
|
||||||
@ -850,7 +840,6 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
|
|||||||
.then(|| self.ev.tcx.local_visibility(def_id));
|
.then(|| self.ev.tcx.local_visibility(def_id));
|
||||||
self.ev.update_eff_vis(def_id, self.effective_vis, max_vis, self.level);
|
self.ev.update_eff_vis(def_id, self.effective_vis, max_vis, self.level);
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1233,6 +1222,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||||
|
type Result = ControlFlow<()>;
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
@ -1241,7 +1231,7 @@ impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
|||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
kind: &str,
|
kind: &str,
|
||||||
descr: &dyn fmt::Display,
|
descr: &dyn fmt::Display,
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
) -> Self::Result {
|
||||||
if self.check_def_id(def_id, kind, descr) {
|
if self.check_def_id(def_id, kind, descr) {
|
||||||
ControlFlow::Break(())
|
ControlFlow::Break(())
|
||||||
} else {
|
} else {
|
||||||
@ -1407,6 +1397,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
|
impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
|
||||||
|
type Result = ControlFlow<()>;
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
@ -1415,7 +1406,7 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
|
|||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
kind: &str,
|
kind: &str,
|
||||||
descr: &dyn fmt::Display,
|
descr: &dyn fmt::Display,
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
) -> Self::Result {
|
||||||
if self.check_def_id(def_id, kind, descr) {
|
if self.check_def_id(def_id, kind, descr) {
|
||||||
ControlFlow::Break(())
|
ControlFlow::Break(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,6 +8,7 @@ edition = "2021"
|
|||||||
bitflags = "2.4.1"
|
bitflags = "2.4.1"
|
||||||
itertools = "0.11.0"
|
itertools = "0.11.0"
|
||||||
rustc_ast = { path = "../rustc_ast" }
|
rustc_ast = { path = "../rustc_ast" }
|
||||||
|
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||||
rustc_attr = { path = "../rustc_attr" }
|
rustc_attr = { path = "../rustc_attr" }
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
rustc_errors = { path = "../rustc_errors" }
|
rustc_errors = { path = "../rustc_errors" }
|
||||||
|
@ -648,8 +648,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTermOrNotNameable<'_, 'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTermOrNotNameable<'_, '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() {
|
match *t.kind() {
|
||||||
ty::Infer(ty::TyVar(vid)) => {
|
ty::Infer(ty::TyVar(vid)) => {
|
||||||
if let ty::TermKind::Ty(term) = self.term.unpack()
|
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() {
|
match c.kind() {
|
||||||
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
|
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
|
||||||
if let ty::TermKind::Const(term) = self.term.unpack()
|
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> {
|
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);
|
let ty = self.infcx.shallow_resolve(ty);
|
||||||
if ty.is_ty_var() {
|
if ty.is_ty_var() {
|
||||||
let Ok(InferOk { value: (), obligations }) =
|
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")
|
bug!("we always expect to be able to plug an infer var with placeholder")
|
||||||
};
|
};
|
||||||
assert_eq!(obligations, &[]);
|
assert_eq!(obligations, &[]);
|
||||||
ControlFlow::Continue(())
|
|
||||||
} else {
|
} 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);
|
let ct = self.infcx.shallow_resolve(ct);
|
||||||
if ct.is_ct_infer() {
|
if ct.is_ct_infer() {
|
||||||
let Ok(InferOk { value: (), obligations }) =
|
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")
|
bug!("we always expect to be able to plug an infer var with placeholder")
|
||||||
};
|
};
|
||||||
assert_eq!(obligations, &[]);
|
assert_eq!(obligations, &[]);
|
||||||
ControlFlow::Continue(())
|
|
||||||
} else {
|
} 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 {
|
if let ty::ReVar(vid) = *r {
|
||||||
let r = self
|
let r = self
|
||||||
.infcx
|
.infcx
|
||||||
@ -555,7 +553,6 @@ fn plug_infer_with_placeholders<'tcx>(
|
|||||||
assert_eq!(obligations, &[]);
|
assert_eq!(obligations, &[]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,12 +865,12 @@ impl<'tcx, F, E> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx, F>
|
|||||||
where
|
where
|
||||||
F: FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
|
F: FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
|
||||||
{
|
{
|
||||||
type BreakTy = OrphanCheckEarlyExit<'tcx, E>;
|
type Result = ControlFlow<OrphanCheckEarlyExit<'tcx, E>>;
|
||||||
fn visit_region(&mut self, _r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, _r: ty::Region<'tcx>) -> Self::Result {
|
||||||
ControlFlow::Continue(())
|
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`.
|
// Need to lazily normalize here in with `-Znext-solver=coherence`.
|
||||||
let ty = match (self.lazily_normalize_ty)(ty) {
|
let ty = match (self.lazily_normalize_ty)(ty) {
|
||||||
Ok(ty) => ty,
|
Ok(ty) => ty,
|
||||||
@ -996,7 +993,7 @@ where
|
|||||||
/// As these should be quite rare as const arguments and especially rare as impl
|
/// As these should be quite rare as const arguments and especially rare as impl
|
||||||
/// parameters, allowing uncovered const parameters in impls seems more useful
|
/// parameters, allowing uncovered const parameters in impls seems more useful
|
||||||
/// than allowing `impl<T> Trait<local_fn_ptr, T> for i32` to compile.
|
/// 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(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
|||||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||||
|
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
use crate::traits::ObligationCtxt;
|
use crate::traits::ObligationCtxt;
|
||||||
|
|
||||||
@ -170,8 +169,7 @@ fn satisfied_from_param_env<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for Visitor<'a, 'tcx> {
|
impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for Visitor<'a, 'tcx> {
|
||||||
type BreakTy = ();
|
fn visit_const(&mut self, c: ty::Const<'tcx>) {
|
||||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
debug!("is_const_evaluatable: candidate={:?}", c);
|
debug!("is_const_evaluatable: candidate={:?}", c);
|
||||||
if self.infcx.probe(|_| {
|
if self.infcx.probe(|_| {
|
||||||
let ocx = ObligationCtxt::new(self.infcx);
|
let ocx = ObligationCtxt::new(self.infcx);
|
||||||
@ -187,7 +185,7 @@ fn satisfied_from_param_env<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let ty::ConstKind::Expr(e) = c.kind() {
|
if let ty::ConstKind::Expr(e) = c.kind() {
|
||||||
e.visit_with(self)
|
e.visit_with(self);
|
||||||
} else {
|
} else {
|
||||||
// FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s args.
|
// 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
|
// 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
|
// 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
|
// this will be incorrect. It might be worth investigating making `predicates_of` elaborate
|
||||||
// all of the `ConstEvaluatable` bounds rather than having a visitor here.
|
// all of the `ConstEvaluatable` bounds rather than having a visitor here.
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,9 +152,9 @@ impl ArgKind {
|
|||||||
struct HasNumericInferVisitor;
|
struct HasNumericInferVisitor;
|
||||||
|
|
||||||
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for 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(_))) {
|
if matches!(ty.kind(), ty::Infer(ty::FloatVar(_) | ty::IntVar(_))) {
|
||||||
ControlFlow::Break(())
|
ControlFlow::Break(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -435,8 +435,8 @@ fn is_impossible_associated_item(
|
|||||||
trait_item_def_id: DefId,
|
trait_item_def_id: DefId,
|
||||||
}
|
}
|
||||||
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'tcx> {
|
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'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 {
|
||||||
// If this is a parameter from the trait item's own generics, then bail
|
// If this is a parameter from the trait item's own generics, then bail
|
||||||
if let ty::Param(param) = t.kind()
|
if let ty::Param(param) = t.kind()
|
||||||
&& let param_def_id = self.generics.type_param(param, self.tcx).def_id
|
&& 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)
|
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()
|
if let ty::ReEarlyParam(param) = r.kind()
|
||||||
&& let param_def_id = self.generics.region_param(¶m, self.tcx).def_id
|
&& let param_def_id = self.generics.region_param(¶m, self.tcx).def_id
|
||||||
&& self.tcx.parent(param_def_id) == self.trait_item_def_id
|
&& self.tcx.parent(param_def_id) == self.trait_item_def_id
|
||||||
@ -455,7 +455,7 @@ fn is_impossible_associated_item(
|
|||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
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()
|
if let ty::ConstKind::Param(param) = ct.kind()
|
||||||
&& let param_def_id = self.generics.const_param(¶m, self.tcx).def_id
|
&& let param_def_id = self.generics.const_param(¶m, self.tcx).def_id
|
||||||
&& self.tcx.parent(param_def_id) == self.trait_item_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> {
|
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() {
|
match t.kind() {
|
||||||
ty::Param(_) => {
|
ty::Param(_) => {
|
||||||
if t == self.tcx.types.self_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`.
|
// 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.
|
// This is only possible for unevaluated constants, so we walk these here.
|
||||||
self.tcx.expand_abstract_consts(ct).super_visit_with(self)
|
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_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
use super::NoSolution;
|
use super::NoSolution;
|
||||||
|
|
||||||
pub use rustc_middle::traits::query::NormalizationResult;
|
pub use rustc_middle::traits::query::NormalizationResult;
|
||||||
@ -123,28 +121,23 @@ struct MaxEscapingBoundVarVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
|
||||||
&mut self,
|
|
||||||
t: &ty::Binder<'tcx, T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
self.outer_index.shift_in(1);
|
self.outer_index.shift_in(1);
|
||||||
let result = t.super_visit_with(self);
|
t.super_visit_with(self);
|
||||||
self.outer_index.shift_out(1);
|
self.outer_index.shift_out(1);
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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 {
|
if t.outer_exclusive_binder() > self.outer_index {
|
||||||
self.escaping = self
|
self.escaping = self
|
||||||
.escaping
|
.escaping
|
||||||
.max(t.outer_exclusive_binder().as_usize() - self.outer_index.as_usize());
|
.max(t.outer_exclusive_binder().as_usize() - self.outer_index.as_usize());
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReBound(debruijn, _) if debruijn > self.outer_index => {
|
ty::ReBound(debruijn, _) if debruijn > self.outer_index => {
|
||||||
self.escaping =
|
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 {
|
if ct.outer_exclusive_binder() > self.outer_index {
|
||||||
self.escaping = self
|
self.escaping = self
|
||||||
.escaping
|
.escaping
|
||||||
.max(ct.outer_exclusive_binder().as_usize() - self.outer_index.as_usize());
|
.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> {
|
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);
|
debug!("Search visiting ty: {:?}", ty);
|
||||||
|
|
||||||
let (adt_def, args) = match *ty.kind() {
|
let (adt_def, args) = match *ty.kind() {
|
||||||
|
@ -5,6 +5,7 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
|
rustc_ast_ir = { path = "../rustc_ast_ir", optional = true }
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
rustc_hir = { path = "../rustc_hir", optional = true }
|
rustc_hir = { path = "../rustc_hir", optional = true }
|
||||||
rustc_infer = { path = "../rustc_infer", optional = true }
|
rustc_infer = { path = "../rustc_infer", optional = true }
|
||||||
@ -23,6 +24,7 @@ rustc = [
|
|||||||
"rustc_middle",
|
"rustc_middle",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
|
"rustc_ast_ir",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -202,8 +202,8 @@ impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'t
|
|||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
||||||
#[instrument(skip(self), ret, level = "trace")]
|
#[instrument(skip(self), ret, level = "trace")]
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
t.super_visit_with(self)?;
|
t.super_visit_with(self);
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
|
ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
|
||||||
self.visit_opaque_ty(alias_ty);
|
self.visit_opaque_ty(alias_ty);
|
||||||
@ -212,7 +212,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
|||||||
self.tcx
|
self.tcx
|
||||||
.type_of(alias_ty.def_id)
|
.type_of(alias_ty.def_id)
|
||||||
.instantiate(self.tcx, alias_ty.args)
|
.instantiate(self.tcx, alias_ty.args)
|
||||||
.visit_with(self)?;
|
.visit_with(self);
|
||||||
}
|
}
|
||||||
ty::Alias(ty::Projection, alias_ty) => {
|
ty::Alias(ty::Projection, alias_ty) => {
|
||||||
// This avoids having to do normalization of `Self::AssocTy` by only
|
// This avoids having to do normalization of `Self::AssocTy` by only
|
||||||
@ -244,11 +244,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if check_args_compatible(self.tcx, assoc, impl_args) {
|
if check_args_compatible(self.tcx, assoc, impl_args) {
|
||||||
return self
|
self.tcx
|
||||||
.tcx
|
|
||||||
.type_of(assoc.def_id)
|
.type_of(assoc.def_id)
|
||||||
.instantiate(self.tcx, impl_args)
|
.instantiate(self.tcx, impl_args)
|
||||||
.visit_with(self);
|
.visit_with(self);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
self.tcx.dcx().span_delayed_bug(
|
self.tcx.dcx().span_delayed_bug(
|
||||||
self.tcx.def_span(assoc.def_id),
|
self.tcx.def_span(assoc.def_id),
|
||||||
@ -261,10 +261,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
|||||||
}
|
}
|
||||||
ty::Adt(def, _) if def.did().is_local() => {
|
ty::Adt(def, _) if def.did().is_local() => {
|
||||||
if let CollectionMode::ImplTraitInAssocTypes = self.mode {
|
if let CollectionMode::ImplTraitInAssocTypes = self.mode {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
if !self.seen.insert(def.did().expect_local()) {
|
if !self.seen.insert(def.did().expect_local()) {
|
||||||
return ControlFlow::Continue(());
|
return;
|
||||||
}
|
}
|
||||||
for variant in def.variants().iter() {
|
for variant in def.variants().iter() {
|
||||||
for field in variant.fields.iter() {
|
for field in variant.fields.iter() {
|
||||||
@ -283,7 +283,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
|||||||
}
|
}
|
||||||
_ => trace!(kind=?t.kind()),
|
_ => trace!(kind=?t.kind()),
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,17 +174,13 @@ struct ImplTraitInTraitFinder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, binder: &ty::Binder<'tcx, T>) {
|
||||||
&mut self,
|
|
||||||
binder: &ty::Binder<'tcx, T>,
|
|
||||||
) -> std::ops::ControlFlow<Self::BreakTy> {
|
|
||||||
self.depth.shift_in(1);
|
self.depth.shift_in(1);
|
||||||
let binder = binder.super_visit_with(self);
|
binder.super_visit_with(self);
|
||||||
self.depth.shift_out(1);
|
self.depth.shift_out(1);
|
||||||
binder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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, unshifted_alias_ty) = *ty.kind()
|
if let ty::Alias(ty::Projection, unshifted_alias_ty) = *ty.kind()
|
||||||
&& let Some(
|
&& let Some(
|
||||||
ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
|
ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
use rustc_ast_ir::try_visit;
|
||||||
|
use rustc_ast_ir::visit::VisitorResult;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
||||||
use crate::visit::{TypeVisitable, TypeVisitor};
|
use crate::visit::{TypeVisitable, TypeVisitor};
|
||||||
@ -107,9 +108,9 @@ impl<I: Interner, V: TypeVisitable<I>> TypeVisitable<I> for Canonical<I, V>
|
|||||||
where
|
where
|
||||||
I::CanonicalVars: TypeVisitable<I>,
|
I::CanonicalVars: TypeVisitable<I>,
|
||||||
{
|
{
|
||||||
fn visit_with<F: TypeVisitor<I>>(&self, folder: &mut F) -> ControlFlow<F::BreakTy> {
|
fn visit_with<F: TypeVisitor<I>>(&self, folder: &mut F) -> F::Result {
|
||||||
self.value.visit_with(folder)?;
|
try_visit!(self.value.visit_with(folder));
|
||||||
self.max_universe.visit_with(folder)?;
|
try_visit!(self.max_universe.visit_with(folder));
|
||||||
self.variables.visit_with(folder)
|
self.variables.visit_with(folder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +138,7 @@ impl<I: Interner> TypeVisitable<I> for CanonicalVarInfo<I>
|
|||||||
where
|
where
|
||||||
I::Ty: TypeVisitable<I>,
|
I::Ty: TypeVisitable<I>,
|
||||||
{
|
{
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.kind.visit_with(visitor)
|
self.kind.visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,13 +252,13 @@ impl<I: Interner> TypeVisitable<I> for CanonicalVarKind<I>
|
|||||||
where
|
where
|
||||||
I::Ty: TypeVisitable<I>,
|
I::Ty: TypeVisitable<I>,
|
||||||
{
|
{
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
match self {
|
match self {
|
||||||
CanonicalVarKind::Ty(_)
|
CanonicalVarKind::Ty(_)
|
||||||
| CanonicalVarKind::PlaceholderTy(_)
|
| CanonicalVarKind::PlaceholderTy(_)
|
||||||
| CanonicalVarKind::Region(_)
|
| CanonicalVarKind::Region(_)
|
||||||
| CanonicalVarKind::PlaceholderRegion(_)
|
| CanonicalVarKind::PlaceholderRegion(_)
|
||||||
| CanonicalVarKind::Effect => ControlFlow::Continue(()),
|
| CanonicalVarKind::Effect => V::Result::output(),
|
||||||
CanonicalVarKind::Const(_, ty) | CanonicalVarKind::PlaceholderConst(_, ty) => {
|
CanonicalVarKind::Const(_, ty) | CanonicalVarKind::PlaceholderConst(_, ty) => {
|
||||||
ty.visit_with(visitor)
|
ty.visit_with(visitor)
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,15 @@ use std::hash::Hash;
|
|||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
use std::sync::Arc as Lrc;
|
use std::sync::Arc as Lrc;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
pub mod visit;
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
pub mod codec;
|
pub mod codec;
|
||||||
pub mod fold;
|
pub mod fold;
|
||||||
pub mod new;
|
pub mod new;
|
||||||
pub mod ty_info;
|
pub mod ty_info;
|
||||||
pub mod ty_kind;
|
pub mod ty_kind;
|
||||||
pub mod visit;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
@ -25,9 +25,9 @@ macro_rules! TrivialTypeTraversalImpls {
|
|||||||
fn visit_with<F: $crate::visit::TypeVisitor<I>>(
|
fn visit_with<F: $crate::visit::TypeVisitor<I>>(
|
||||||
&self,
|
&self,
|
||||||
_: &mut F)
|
_: &mut F)
|
||||||
-> ::std::ops::ControlFlow<F::BreakTy>
|
-> F::Result
|
||||||
{
|
{
|
||||||
::std::ops::ControlFlow::Continue(())
|
<F::Result as rustc_ast_ir::visit::VisitorResult>::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
use rustc_ast_ir::try_visit;
|
||||||
|
use rustc_ast_ir::visit::VisitorResult;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
||||||
use crate::visit::{TypeVisitable, TypeVisitor};
|
use crate::visit::{TypeVisitable, TypeVisitor};
|
||||||
@ -91,14 +92,14 @@ where
|
|||||||
I::TypeOutlivesPredicate: TypeVisitable<I>,
|
I::TypeOutlivesPredicate: TypeVisitable<I>,
|
||||||
I::RegionOutlivesPredicate: TypeVisitable<I>,
|
I::RegionOutlivesPredicate: TypeVisitable<I>,
|
||||||
{
|
{
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
match self {
|
match self {
|
||||||
ClauseKind::Trait(p) => p.visit_with(visitor),
|
ClauseKind::Trait(p) => p.visit_with(visitor),
|
||||||
ClauseKind::RegionOutlives(p) => p.visit_with(visitor),
|
ClauseKind::RegionOutlives(p) => p.visit_with(visitor),
|
||||||
ClauseKind::TypeOutlives(p) => p.visit_with(visitor),
|
ClauseKind::TypeOutlives(p) => p.visit_with(visitor),
|
||||||
ClauseKind::Projection(p) => p.visit_with(visitor),
|
ClauseKind::Projection(p) => p.visit_with(visitor),
|
||||||
ClauseKind::ConstArgHasType(c, t) => {
|
ClauseKind::ConstArgHasType(c, t) => {
|
||||||
c.visit_with(visitor)?;
|
try_visit!(c.visit_with(visitor));
|
||||||
t.visit_with(visitor)
|
t.visit_with(visitor)
|
||||||
}
|
}
|
||||||
ClauseKind::WellFormed(p) => p.visit_with(visitor),
|
ClauseKind::WellFormed(p) => p.visit_with(visitor),
|
||||||
@ -205,21 +206,21 @@ where
|
|||||||
I::NormalizesTo: TypeVisitable<I>,
|
I::NormalizesTo: TypeVisitable<I>,
|
||||||
ClauseKind<I>: TypeVisitable<I>,
|
ClauseKind<I>: TypeVisitable<I>,
|
||||||
{
|
{
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
match self {
|
match self {
|
||||||
PredicateKind::Clause(p) => p.visit_with(visitor),
|
PredicateKind::Clause(p) => p.visit_with(visitor),
|
||||||
PredicateKind::ObjectSafe(d) => d.visit_with(visitor),
|
PredicateKind::ObjectSafe(d) => d.visit_with(visitor),
|
||||||
PredicateKind::Subtype(s) => s.visit_with(visitor),
|
PredicateKind::Subtype(s) => s.visit_with(visitor),
|
||||||
PredicateKind::Coerce(s) => s.visit_with(visitor),
|
PredicateKind::Coerce(s) => s.visit_with(visitor),
|
||||||
PredicateKind::ConstEquate(a, b) => {
|
PredicateKind::ConstEquate(a, b) => {
|
||||||
a.visit_with(visitor)?;
|
try_visit!(a.visit_with(visitor));
|
||||||
b.visit_with(visitor)
|
b.visit_with(visitor)
|
||||||
}
|
}
|
||||||
PredicateKind::Ambiguous => ControlFlow::Continue(()),
|
PredicateKind::Ambiguous => V::Result::output(),
|
||||||
PredicateKind::NormalizesTo(p) => p.visit_with(visitor),
|
PredicateKind::NormalizesTo(p) => p.visit_with(visitor),
|
||||||
PredicateKind::AliasRelate(a, b, d) => {
|
PredicateKind::AliasRelate(a, b, d) => {
|
||||||
a.visit_with(visitor)?;
|
try_visit!(a.visit_with(visitor));
|
||||||
b.visit_with(visitor)?;
|
try_visit!(b.visit_with(visitor));
|
||||||
d.visit_with(visitor)
|
d.visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use rustc_ast_ir::try_visit;
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
@ -831,8 +832,8 @@ impl<I: Interner> TypeVisitable<I> for TypeAndMut<I>
|
|||||||
where
|
where
|
||||||
I::Ty: TypeVisitable<I>,
|
I::Ty: TypeVisitable<I>,
|
||||||
{
|
{
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> std::ops::ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.ty.visit_with(visitor)?;
|
try_visit!(self.ty.visit_with(visitor));
|
||||||
self.mutbl.visit_with(visitor)
|
self.mutbl.visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
//! - u.visit_with(visitor)
|
//! - u.visit_with(visitor)
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
use rustc_ast_ir::visit::VisitorResult;
|
||||||
|
use rustc_ast_ir::{try_visit, walk_visitable_list};
|
||||||
use rustc_index::{Idx, IndexVec};
|
use rustc_index::{Idx, IndexVec};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
@ -63,7 +65,7 @@ pub trait TypeVisitable<I: Interner>: fmt::Debug + Clone {
|
|||||||
/// that calls a visitor method specifically for that type (such as
|
/// that calls a visitor method specifically for that type (such as
|
||||||
/// `V::visit_ty`). This is where control transfers from `TypeVisitable` to
|
/// `V::visit_ty`). This is where control transfers from `TypeVisitable` to
|
||||||
/// `TypeVisitor`.
|
/// `TypeVisitor`.
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This trait is implemented for types of interest.
|
// This trait is implemented for types of interest.
|
||||||
@ -74,7 +76,7 @@ pub trait TypeSuperVisitable<I: Interner>: TypeVisitable<I> {
|
|||||||
/// that method. For example, in `MyVisitor::visit_ty(ty)`, it is valid to
|
/// that method. For example, in `MyVisitor::visit_ty(ty)`, it is valid to
|
||||||
/// call `ty.super_visit_with(self)`, but any other visiting should be done
|
/// call `ty.super_visit_with(self)`, but any other visiting should be done
|
||||||
/// with `xyz.visit_with(self)`.
|
/// with `xyz.visit_with(self)`.
|
||||||
fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
|
fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This trait is implemented for every visiting traversal. There is a visit
|
/// This trait is implemented for every visiting traversal. There is a visit
|
||||||
@ -82,33 +84,30 @@ pub trait TypeSuperVisitable<I: Interner>: TypeVisitable<I> {
|
|||||||
/// that recurses into the type's fields in a non-custom fashion.
|
/// that recurses into the type's fields in a non-custom fashion.
|
||||||
pub trait TypeVisitor<I: Interner>: Sized {
|
pub trait TypeVisitor<I: Interner>: Sized {
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
type BreakTy = !;
|
type Result: VisitorResult = ();
|
||||||
|
|
||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
type BreakTy;
|
type Result: VisitorResult;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<I>>(
|
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> Self::Result {
|
||||||
&mut self,
|
|
||||||
t: &I::Binder<T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The default region visitor is a no-op because `Region` is non-recursive
|
// The default region visitor is a no-op because `Region` is non-recursive
|
||||||
// and has no `super_visit_with` method to call.
|
// and has no `super_visit_with` method to call.
|
||||||
fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, _r: I::Region) -> Self::Result {
|
||||||
ControlFlow::Continue(())
|
Self::Result::output()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: I::Const) -> Self::Result {
|
||||||
c.super_visit_with(self)
|
c.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
fn visit_predicate(&mut self, p: I::Predicate) -> Self::Result {
|
||||||
p.super_visit_with(self)
|
p.super_visit_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,8 +116,8 @@ pub trait TypeVisitor<I: Interner>: Sized {
|
|||||||
// Traversal implementations.
|
// Traversal implementations.
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>, U: TypeVisitable<I>> TypeVisitable<I> for (T, U) {
|
impl<I: Interner, T: TypeVisitable<I>, U: TypeVisitable<I>> TypeVisitable<I> for (T, U) {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.0.visit_with(visitor)?;
|
try_visit!(self.0.visit_with(visitor));
|
||||||
self.1.visit_with(visitor)
|
self.1.visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,24 +125,24 @@ impl<I: Interner, T: TypeVisitable<I>, U: TypeVisitable<I>> TypeVisitable<I> for
|
|||||||
impl<I: Interner, A: TypeVisitable<I>, B: TypeVisitable<I>, C: TypeVisitable<I>> TypeVisitable<I>
|
impl<I: Interner, A: TypeVisitable<I>, B: TypeVisitable<I>, C: TypeVisitable<I>> TypeVisitable<I>
|
||||||
for (A, B, C)
|
for (A, B, C)
|
||||||
{
|
{
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.0.visit_with(visitor)?;
|
try_visit!(self.0.visit_with(visitor));
|
||||||
self.1.visit_with(visitor)?;
|
try_visit!(self.1.visit_with(visitor));
|
||||||
self.2.visit_with(visitor)
|
self.2.visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Option<T> {
|
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Option<T> {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
match self {
|
match self {
|
||||||
Some(v) => v.visit_with(visitor),
|
Some(v) => v.visit_with(visitor),
|
||||||
None => ControlFlow::Continue(()),
|
None => V::Result::output(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>> TypeVisitable<I> for Result<T, E> {
|
impl<I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>> TypeVisitable<I> for Result<T, E> {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
match self {
|
match self {
|
||||||
Ok(v) => v.visit_with(visitor),
|
Ok(v) => v.visit_with(visitor),
|
||||||
Err(e) => e.visit_with(visitor),
|
Err(e) => e.visit_with(visitor),
|
||||||
@ -152,20 +151,21 @@ impl<I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>> TypeVisitable<I> for
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Lrc<T> {
|
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Lrc<T> {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
(**self).visit_with(visitor)
|
(**self).visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<T> {
|
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<T> {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
(**self).visit_with(visitor)
|
(**self).visit_with(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Vec<T> {
|
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Vec<T> {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
walk_visitable_list!(visitor, self.iter());
|
||||||
|
V::Result::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,20 +173,23 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Vec<T> {
|
|||||||
// case, because we can't return a new slice. But note that there are a couple
|
// case, because we can't return a new slice. But note that there are a couple
|
||||||
// of trivial impls of `TypeFoldable` for specific slice types elsewhere.
|
// of trivial impls of `TypeFoldable` for specific slice types elsewhere.
|
||||||
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for &[T] {
|
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for &[T] {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
walk_visitable_list!(visitor, self.iter());
|
||||||
|
V::Result::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<[T]> {
|
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<[T]> {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
walk_visitable_list!(visitor, self.iter());
|
||||||
|
V::Result::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix, T> {
|
impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix, T> {
|
||||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
walk_visitable_list!(visitor, self.iter());
|
||||||
|
V::Result::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,12 +369,9 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
|
|||||||
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
|
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
|
||||||
// specifically detect this case in `visit_binder`.
|
// specifically detect this case in `visit_binder`.
|
||||||
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
||||||
type BreakTy = FoundFlags;
|
type Result = ControlFlow<FoundFlags>;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<I>>(
|
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> Self::Result {
|
||||||
&mut self,
|
|
||||||
t: &I::Binder<T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// If we're looking for the HAS_BINDER_VARS flag, check if the
|
// If we're looking for the HAS_BINDER_VARS flag, check if the
|
||||||
// binder has vars. This won't be present in the binder's bound
|
// binder has vars. This won't be present in the binder's bound
|
||||||
// value, so we need to check here too.
|
// value, so we need to check here too.
|
||||||
@ -383,7 +383,7 @@ impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
|
||||||
// Note: no `super_visit_with` call.
|
// Note: no `super_visit_with` call.
|
||||||
let flags = t.flags();
|
let flags = t.flags();
|
||||||
if flags.intersects(self.flags) {
|
if flags.intersects(self.flags) {
|
||||||
@ -394,7 +394,7 @@ impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: I::Region) -> Self::Result {
|
||||||
// Note: no `super_visit_with` call, as usual for `Region`.
|
// Note: no `super_visit_with` call, as usual for `Region`.
|
||||||
let flags = r.flags();
|
let flags = r.flags();
|
||||||
if flags.intersects(self.flags) {
|
if flags.intersects(self.flags) {
|
||||||
@ -405,7 +405,7 @@ impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: I::Const) -> Self::Result {
|
||||||
// Note: no `super_visit_with` call.
|
// Note: no `super_visit_with` call.
|
||||||
if c.flags().intersects(self.flags) {
|
if c.flags().intersects(self.flags) {
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
@ -415,7 +415,7 @@ impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
fn visit_predicate(&mut self, predicate: I::Predicate) -> Self::Result {
|
||||||
// Note: no `super_visit_with` call.
|
// Note: no `super_visit_with` call.
|
||||||
if predicate.flags().intersects(self.flags) {
|
if predicate.flags().intersects(self.flags) {
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
@ -459,12 +459,9 @@ struct HasEscapingVarsVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
||||||
type BreakTy = FoundEscapingVars;
|
type Result = ControlFlow<FoundEscapingVars>;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<I>>(
|
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> Self::Result {
|
||||||
&mut self,
|
|
||||||
t: &I::Binder<T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
self.outer_index.shift_in(1);
|
self.outer_index.shift_in(1);
|
||||||
let result = t.super_visit_with(self);
|
let result = t.super_visit_with(self);
|
||||||
self.outer_index.shift_out(1);
|
self.outer_index.shift_out(1);
|
||||||
@ -472,7 +469,7 @@ impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
|
||||||
// If the outer-exclusive-binder is *strictly greater* than
|
// If the outer-exclusive-binder is *strictly greater* than
|
||||||
// `outer_index`, that means that `t` contains some content
|
// `outer_index`, that means that `t` contains some content
|
||||||
// bound at `outer_index` or above (because
|
// bound at `outer_index` or above (because
|
||||||
@ -486,7 +483,7 @@ impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: I::Region) -> Self::Result {
|
||||||
// If the region is bound by `outer_index` or anything outside
|
// If the region is bound by `outer_index` or anything outside
|
||||||
// of outer index, then it escapes the binders we have
|
// of outer index, then it escapes the binders we have
|
||||||
// visited.
|
// visited.
|
||||||
@ -497,7 +494,7 @@ impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, ct: I::Const) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, ct: I::Const) -> Self::Result {
|
||||||
// If the outer-exclusive-binder is *strictly greater* than
|
// If the outer-exclusive-binder is *strictly greater* than
|
||||||
// `outer_index`, that means that `ct` contains some content
|
// `outer_index`, that means that `ct` contains some content
|
||||||
// bound at `outer_index` or above (because
|
// bound at `outer_index` or above (because
|
||||||
@ -511,7 +508,7 @@ impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
fn visit_predicate(&mut self, predicate: I::Predicate) -> Self::Result {
|
||||||
if predicate.outer_exclusive_binder() > self.outer_index {
|
if predicate.outer_exclusive_binder() > self.outer_index {
|
||||||
ControlFlow::Break(FoundEscapingVars)
|
ControlFlow::Break(FoundEscapingVars)
|
||||||
} else {
|
} else {
|
||||||
@ -523,9 +520,9 @@ impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
|||||||
struct HasErrorVisitor;
|
struct HasErrorVisitor;
|
||||||
|
|
||||||
impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
|
impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
|
||||||
type BreakTy = I::ErrorGuaranteed;
|
type Result = ControlFlow<I::ErrorGuaranteed>;
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: <I as Interner>::Ty) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: <I as Interner>::Ty) -> Self::Result {
|
||||||
if let ty::Error(guar) = t.kind() {
|
if let ty::Error(guar) = t.kind() {
|
||||||
ControlFlow::Break(guar)
|
ControlFlow::Break(guar)
|
||||||
} else {
|
} else {
|
||||||
@ -533,7 +530,7 @@ impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: <I as Interner>::Const) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: <I as Interner>::Const) -> Self::Result {
|
||||||
if let ty::ConstKind::Error(guar) = c.kind() {
|
if let ty::ConstKind::Error(guar) = c.kind() {
|
||||||
ControlFlow::Break(guar)
|
ControlFlow::Break(guar)
|
||||||
} else {
|
} else {
|
||||||
@ -541,7 +538,7 @@ impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: <I as Interner>::Region) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: <I as Interner>::Region) -> Self::Result {
|
||||||
if let ty::ReError(guar) = r.kind() {
|
if let ty::ReError(guar) = r.kind() {
|
||||||
ControlFlow::Break(guar)
|
ControlFlow::Break(guar)
|
||||||
} else {
|
} else {
|
||||||
|
@ -22,9 +22,9 @@ fn get_enum_ty(enum_ty: Ty<'_>) -> Option<Ty<'_>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTyVisitor {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTyVisitor {
|
||||||
type BreakTy = Ty<'tcx>;
|
type Result = ControlFlow<Ty<'tcx>>;
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||||
self.level += 1;
|
self.level += 1;
|
||||||
if self.level == 1 {
|
if self.level == 1 {
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
|
@ -141,9 +141,9 @@ impl<'a, 'b, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'b,
|
|||||||
struct ContainsRegion;
|
struct ContainsRegion;
|
||||||
|
|
||||||
impl TypeVisitor<TyCtxt<'_>> for ContainsRegion {
|
impl TypeVisitor<TyCtxt<'_>> for ContainsRegion {
|
||||||
type BreakTy = ();
|
type Result = ControlFlow<()>;
|
||||||
|
|
||||||
fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, _: ty::Region<'_>) -> Self::Result {
|
||||||
ControlFlow::Break(())
|
ControlFlow::Break(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -916,8 +916,8 @@ pub fn for_each_top_level_late_bound_region<B>(
|
|||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow<B>> TypeVisitor<TyCtxt<'tcx>> for V<F> {
|
impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow<B>> TypeVisitor<TyCtxt<'tcx>> for V<F> {
|
||||||
type BreakTy = B;
|
type Result = ControlFlow<B>;
|
||||||
fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: Region<'tcx>) -> Self::Result {
|
||||||
if let RegionKind::ReBound(idx, bound) = r.kind()
|
if let RegionKind::ReBound(idx, bound) = r.kind()
|
||||||
&& idx.as_u32() == self.index
|
&& idx.as_u32() == self.index
|
||||||
{
|
{
|
||||||
@ -926,7 +926,7 @@ pub fn for_each_top_level_late_bound_region<B>(
|
|||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> {
|
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result {
|
||||||
self.index += 1;
|
self.index += 1;
|
||||||
let res = t.super_visit_with(self);
|
let res = t.super_visit_with(self);
|
||||||
self.index -= 1;
|
self.index -= 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user