Skip to content

TypeVisitor: use std::ops::ControlFlow instead of bool #78182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 31, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -71,6 +71,7 @@ use rustc_middle::ty::{
};
use rustc_span::{BytePos, DesugaringKind, Pos, Span};
use rustc_target::spec::abi;
use std::ops::ControlFlow;
use std::{cmp, fmt};

mod note;
@@ -1497,7 +1498,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<()> {
if let Some((kind, def_id)) = TyCategory::from_ty(t) {
let span = self.tcx.def_span(def_id);
// Avoid cluttering the output when the "found" and error span overlap:
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@ use rustc_middle::ty::{self, AssocItemContainer, RegionKind, Ty, TypeFoldable, T
use rustc_span::symbol::Ident;
use rustc_span::{MultiSpan, Span};

use std::ops::ControlFlow;

impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// Print the error message for lifetime errors when the return type is a static `impl Trait`,
/// `dyn Trait` or if a method call on a trait object introduces a static requirement.
@@ -472,13 +474,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
struct TraitObjectVisitor(Vec<DefId>);

impl TypeVisitor<'_> for TraitObjectVisitor {
fn visit_ty(&mut self, t: Ty<'_>) -> bool {
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<()> {
match t.kind() {
ty::Dynamic(preds, RegionKind::ReStatic) => {
if let Some(def_id) = preds.principal_def_id() {
self.0.push(def_id);
}
false
ControlFlow::CONTINUE
}
_ => t.super_visit_with(self),
}
9 changes: 5 additions & 4 deletions compiler/rustc_infer/src/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor};
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
use std::fmt::Debug;
use std::ops::ControlFlow;

#[derive(PartialEq)]
pub enum NormalizationStrategy {
@@ -740,15 +741,15 @@ struct ScopeInstantiator<'me, 'tcx> {
}

impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ControlFlow<()> {
self.target_index.shift_in(1);
t.super_visit_with(self);
self.target_index.shift_out(1);

false
ControlFlow::CONTINUE
}

fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<()> {
let ScopeInstantiator { bound_region_scope, next_region, .. } = self;

match r {
@@ -759,7 +760,7 @@ impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
_ => {}
}

false
ControlFlow::CONTINUE
}
}

8 changes: 5 additions & 3 deletions compiler/rustc_infer/src/infer/resolve.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@ use super::{FixupError, FixupResult, InferCtxt, Span};
use rustc_middle::ty::fold::{TypeFolder, TypeVisitor};
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};

use std::ops::ControlFlow;

///////////////////////////////////////////////////////////////////////////
// OPPORTUNISTIC VAR RESOLVER

@@ -121,7 +123,7 @@ impl<'a, 'tcx> UnresolvedTypeFinder<'a, 'tcx> {
}

impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<()> {
let t = self.infcx.shallow_resolve(t);
if t.has_infer_types() {
if let ty::Infer(infer_ty) = *t.kind() {
@@ -143,15 +145,15 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
None
};
self.first_unresolved = Some((t, ty_var_span));
true // Halt visiting.
ControlFlow::BREAK
} else {
// Otherwise, visit its contents.
t.super_visit_with(self)
}
} else {
// All type variables in inference types must already be resolved,
// - no need to visit the contents, continue visiting.
false
ControlFlow::CONTINUE
}
}
}
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
#![feature(never_type)]
#![feature(or_patterns)]
#![feature(in_band_lifetimes)]
#![feature(control_flow_enum)]
#![recursion_limit = "512"] // For rustdoc

#[macro_use]
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/traits/structural_impls.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ use rustc_middle::ty;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};

use std::fmt;
use std::ops::ControlFlow;

// Structural impls for the structs in `traits`.

@@ -68,7 +69,7 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx
}
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
self.predicate.visit_with(visitor)
}
}
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@
#![feature(or_patterns)]
#![feature(half_open_range_patterns)]
#![feature(exclusive_range_pattern)]
#![feature(control_flow_enum)]
#![recursion_limit = "256"]

#[macro_use]
11 changes: 8 additions & 3 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants};
use rustc_target::spec::abi::Abi as SpecAbi;

use std::cmp;
use std::ops::ControlFlow;
use tracing::debug;

declare_lint! {
@@ -1135,11 +1136,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
};

impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<()> {
match ty.kind() {
ty::Opaque(..) => {
self.ty = Some(ty);
true
ControlFlow::BREAK
}
// Consider opaque types within projections FFI-safe if they do not normalize
// to more opaque types.
@@ -1148,7 +1149,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {

// If `ty` is a opaque type directly then `super_visit_with` won't invoke
// this function again.
if ty.has_opaque_types() { self.visit_ty(ty) } else { false }
if ty.has_opaque_types() {
self.visit_ty(ty)
} else {
ControlFlow::CONTINUE
}
}
_ => ty.super_visit_with(self),
}
11 changes: 8 additions & 3 deletions compiler/rustc_macros/src/type_foldable.rs
Original file line number Diff line number Diff line change
@@ -15,8 +15,12 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
}
})
});
let body_visit = s.fold(false, |acc, bind| {
quote! { #acc || ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder) }

let body_visit = s.fold(quote!(), |acc, bind| {
quote! {
#acc
::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder)?;
}
});

s.bound_impl(
@@ -32,8 +36,9 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
&self,
__folder: &mut __F
) -> bool {
) -> ::std::ops::ControlFlow<()> {
match *self { #body_visit }
::std::ops::ControlFlow::CONTINUE
}
},
)
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@
#![feature(int_error_matching)]
#![feature(half_open_range_patterns)]
#![feature(exclusive_range_pattern)]
#![feature(control_flow_enum)]
#![recursion_limit = "512"]

#[macro_use]
18 changes: 10 additions & 8 deletions compiler/rustc_middle/src/macros.rs
Original file line number Diff line number Diff line change
@@ -62,9 +62,9 @@ macro_rules! CloneTypeFoldableImpls {
fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
_: &mut F)
-> bool
-> ::std::ops::ControlFlow<()>
{
false
::std::ops::ControlFlow::CONTINUE
}
}
)+
@@ -105,7 +105,7 @@ macro_rules! EnumTypeFoldableImpl {
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> bool {
) -> ::std::ops::ControlFlow<()> {
EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
}
}
@@ -179,9 +179,10 @@ macro_rules! EnumTypeFoldableImpl {
input($($input)*)
output(
$variant ( $($variant_arg),* ) => {
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
$($crate::ty::fold::TypeFoldable::visit_with(
$variant_arg, $visitor
))*
)?;)*
::std::ops::ControlFlow::CONTINUE
}
$($output)*
)
@@ -196,9 +197,10 @@ macro_rules! EnumTypeFoldableImpl {
input($($input)*)
output(
$variant { $($variant_arg),* } => {
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
$($crate::ty::fold::TypeFoldable::visit_with(
$variant_arg, $visitor
))*
)?;)*
::std::ops::ControlFlow::CONTINUE
}
$($output)*
)
@@ -212,7 +214,7 @@ macro_rules! EnumTypeFoldableImpl {
@VisitVariants($this, $visitor)
input($($input)*)
output(
$variant => { false }
$variant => { ::std::ops::ControlFlow::CONTINUE }
$($output)*
)
)
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ use rustc_target::abi;
use rustc_target::asm::InlineAsmRegOrRegClass;
use std::borrow::Cow;
use std::fmt::{self, Debug, Display, Formatter, Write};
use std::ops::{Index, IndexMut};
use std::ops::{ControlFlow, Index, IndexMut};
use std::slice;
use std::{iter, mem, option};

@@ -2489,7 +2489,7 @@ impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
UserTypeProjection { base, projs }
}

fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<()> {
self.base.visit_with(visitor)
// Note: there's nothing in `self.proj` to visit.
}
Loading