Skip to content

Commit 0d033de

Browse files
committed
Auto merge of rust-lang#78182 - LeSeulArtichaut:ty-visitor-contolflow, r=lcnr,oli-obk
TypeVisitor: use `std::ops::ControlFlow` instead of `bool` Implements MCP rust-lang/compiler-team#374. Blocked on FCP in rust-lang/compiler-team#374. r? `@lcnr` cc `@jonas-schievink`
2 parents ffe5288 + 9433eb8 commit 0d033de

File tree

38 files changed

+522
-375
lines changed

38 files changed

+522
-375
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ use rustc_middle::ty::{
7171
};
7272
use rustc_span::{BytePos, DesugaringKind, Pos, Span};
7373
use rustc_target::spec::abi;
74+
use std::ops::ControlFlow;
7475
use std::{cmp, fmt};
7576

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

14991500
impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> {
1500-
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1501+
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<()> {
15011502
if let Some((kind, def_id)) = TyCategory::from_ty(t) {
15021503
let span = self.tcx.def_span(def_id);
15031504
// Avoid cluttering the output when the "found" and error span overlap:

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use rustc_middle::ty::{self, AssocItemContainer, RegionKind, Ty, TypeFoldable, T
1515
use rustc_span::symbol::Ident;
1616
use rustc_span::{MultiSpan, Span};
1717

18+
use std::ops::ControlFlow;
19+
1820
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
1921
/// Print the error message for lifetime errors when the return type is a static `impl Trait`,
2022
/// `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> {
472474
struct TraitObjectVisitor(Vec<DefId>);
473475

474476
impl TypeVisitor<'_> for TraitObjectVisitor {
475-
fn visit_ty(&mut self, t: Ty<'_>) -> bool {
477+
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<()> {
476478
match t.kind() {
477479
ty::Dynamic(preds, RegionKind::ReStatic) => {
478480
if let Some(def_id) = preds.principal_def_id() {
479481
self.0.push(def_id);
480482
}
481-
false
483+
ControlFlow::CONTINUE
482484
}
483485
_ => t.super_visit_with(self),
484486
}

compiler/rustc_infer/src/infer/nll_relate/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor};
3030
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
3131
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
3232
use std::fmt::Debug;
33+
use std::ops::ControlFlow;
3334

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

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

748-
false
749+
ControlFlow::CONTINUE
749750
}
750751

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

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

762-
false
763+
ControlFlow::CONTINUE
763764
}
764765
}
765766

compiler/rustc_infer/src/infer/resolve.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use super::{FixupError, FixupResult, InferCtxt, Span};
33
use rustc_middle::ty::fold::{TypeFolder, TypeVisitor};
44
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
55

6+
use std::ops::ControlFlow;
7+
68
///////////////////////////////////////////////////////////////////////////
79
// OPPORTUNISTIC VAR RESOLVER
810

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

123125
impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
124-
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
126+
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<()> {
125127
let t = self.infcx.shallow_resolve(t);
126128
if t.has_infer_types() {
127129
if let ty::Infer(infer_ty) = *t.kind() {
@@ -143,15 +145,15 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
143145
None
144146
};
145147
self.first_unresolved = Some((t, ty_var_span));
146-
true // Halt visiting.
148+
ControlFlow::BREAK
147149
} else {
148150
// Otherwise, visit its contents.
149151
t.super_visit_with(self)
150152
}
151153
} else {
152154
// All type variables in inference types must already be resolved,
153155
// - no need to visit the contents, continue visiting.
154-
false
156+
ControlFlow::CONTINUE
155157
}
156158
}
157159
}

compiler/rustc_infer/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#![feature(never_type)]
2323
#![feature(or_patterns)]
2424
#![feature(in_band_lifetimes)]
25+
#![feature(control_flow_enum)]
2526
#![recursion_limit = "512"] // For rustdoc
2627

2728
#[macro_use]

compiler/rustc_infer/src/traits/structural_impls.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_middle::ty;
44
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
55

66
use std::fmt;
7+
use std::ops::ControlFlow;
78

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

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

71-
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
72+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
7273
self.predicate.visit_with(visitor)
7374
}
7475
}

compiler/rustc_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#![feature(or_patterns)]
3838
#![feature(half_open_range_patterns)]
3939
#![feature(exclusive_range_pattern)]
40+
#![feature(control_flow_enum)]
4041
#![recursion_limit = "256"]
4142

4243
#[macro_use]

compiler/rustc_lint/src/types.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants};
1818
use rustc_target::spec::abi::Abi as SpecAbi;
1919

2020
use std::cmp;
21+
use std::ops::ControlFlow;
2122
use tracing::debug;
2223

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

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

11491150
// If `ty` is a opaque type directly then `super_visit_with` won't invoke
11501151
// this function again.
1151-
if ty.has_opaque_types() { self.visit_ty(ty) } else { false }
1152+
if ty.has_opaque_types() {
1153+
self.visit_ty(ty)
1154+
} else {
1155+
ControlFlow::CONTINUE
1156+
}
11521157
}
11531158
_ => ty.super_visit_with(self),
11541159
}

compiler/rustc_macros/src/type_foldable.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
1515
}
1616
})
1717
});
18-
let body_visit = s.fold(false, |acc, bind| {
19-
quote! { #acc || ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder) }
18+
19+
let body_visit = s.fold(quote!(), |acc, bind| {
20+
quote! {
21+
#acc
22+
::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder)?;
23+
}
2024
});
2125

2226
s.bound_impl(
@@ -32,8 +36,9 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
3236
fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
3337
&self,
3438
__folder: &mut __F
35-
) -> bool {
39+
) -> ::std::ops::ControlFlow<()> {
3640
match *self { #body_visit }
41+
::std::ops::ControlFlow::CONTINUE
3742
}
3843
},
3944
)

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#![feature(int_error_matching)]
5050
#![feature(half_open_range_patterns)]
5151
#![feature(exclusive_range_pattern)]
52+
#![feature(control_flow_enum)]
5253
#![recursion_limit = "512"]
5354

5455
#[macro_use]

compiler/rustc_middle/src/macros.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ macro_rules! CloneTypeFoldableImpls {
6262
fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
6363
&self,
6464
_: &mut F)
65-
-> bool
65+
-> ::std::ops::ControlFlow<()>
6666
{
67-
false
67+
::std::ops::ControlFlow::CONTINUE
6868
}
6969
}
7070
)+
@@ -105,7 +105,7 @@ macro_rules! EnumTypeFoldableImpl {
105105
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
106106
&self,
107107
visitor: &mut V,
108-
) -> bool {
108+
) -> ::std::ops::ControlFlow<()> {
109109
EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
110110
}
111111
}
@@ -179,9 +179,10 @@ macro_rules! EnumTypeFoldableImpl {
179179
input($($input)*)
180180
output(
181181
$variant ( $($variant_arg),* ) => {
182-
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
182+
$($crate::ty::fold::TypeFoldable::visit_with(
183183
$variant_arg, $visitor
184-
))*
184+
)?;)*
185+
::std::ops::ControlFlow::CONTINUE
185186
}
186187
$($output)*
187188
)
@@ -196,9 +197,10 @@ macro_rules! EnumTypeFoldableImpl {
196197
input($($input)*)
197198
output(
198199
$variant { $($variant_arg),* } => {
199-
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
200+
$($crate::ty::fold::TypeFoldable::visit_with(
200201
$variant_arg, $visitor
201-
))*
202+
)?;)*
203+
::std::ops::ControlFlow::CONTINUE
202204
}
203205
$($output)*
204206
)
@@ -212,7 +214,7 @@ macro_rules! EnumTypeFoldableImpl {
212214
@VisitVariants($this, $visitor)
213215
input($($input)*)
214216
output(
215-
$variant => { false }
217+
$variant => { ::std::ops::ControlFlow::CONTINUE }
216218
$($output)*
217219
)
218220
)

compiler/rustc_middle/src/mir/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustc_target::abi;
3232
use rustc_target::asm::InlineAsmRegOrRegClass;
3333
use std::borrow::Cow;
3434
use std::fmt::{self, Debug, Display, Formatter, Write};
35-
use std::ops::{Index, IndexMut};
35+
use std::ops::{ControlFlow, Index, IndexMut};
3636
use std::slice;
3737
use std::{iter, mem, option};
3838

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

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

0 commit comments

Comments
 (0)