Skip to content

Commit d2049e2

Browse files
authored
Unrolled build for rust-lang#121563
Rollup merge of rust-lang#121563 - Jarcho:use_cf, r=petrochenkov Use `ControlFlow` in visitors. Follow up to rust-lang#121256 This does have a few small behaviour changes in some diagnostic output where the visitor will now find the first match rather than the last match. The change in `find_anon_types.rs` has the only affected test. I don't see this being an issue as the last occurrence isn't any better of a choice than the first.
2 parents 74acabe + 822b10d commit d2049e2

File tree

17 files changed

+238
-268
lines changed

17 files changed

+238
-268
lines changed

compiler/rustc_ast_lowering/src/format.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::LoweringContext;
2+
use core::ops::ControlFlow;
23
use rustc_ast as ast;
34
use rustc_ast::visit::Visitor;
45
use rustc_ast::*;
@@ -594,30 +595,32 @@ fn expand_format_args<'hir>(
594595
}
595596

596597
fn may_contain_yield_point(e: &ast::Expr) -> bool {
597-
struct MayContainYieldPoint(bool);
598+
struct MayContainYieldPoint;
598599

599600
impl Visitor<'_> for MayContainYieldPoint {
600-
fn visit_expr(&mut self, e: &ast::Expr) {
601+
type Result = ControlFlow<()>;
602+
603+
fn visit_expr(&mut self, e: &ast::Expr) -> ControlFlow<()> {
601604
if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind {
602-
self.0 = true;
605+
ControlFlow::Break(())
603606
} else {
604607
visit::walk_expr(self, e);
608+
ControlFlow::Continue(())
605609
}
606610
}
607611

608-
fn visit_mac_call(&mut self, _: &ast::MacCall) {
612+
fn visit_mac_call(&mut self, _: &ast::MacCall) -> ControlFlow<()> {
609613
// Macros should be expanded at this point.
610614
unreachable!("unexpanded macro in ast lowering");
611615
}
612616

613-
fn visit_item(&mut self, _: &ast::Item) {
617+
fn visit_item(&mut self, _: &ast::Item) -> ControlFlow<()> {
614618
// Do not recurse into nested items.
619+
ControlFlow::Continue(())
615620
}
616621
}
617622

618-
let mut visitor = MayContainYieldPoint(false);
619-
visitor.visit_expr(e);
620-
visitor.0
623+
MayContainYieldPoint.visit_expr(e).is_break()
621624
}
622625

623626
fn for_all_argument_indexes(template: &mut [FormatArgsPiece], mut f: impl FnMut(&mut usize)) {

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+29-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![allow(rustc::diagnostic_outside_of_impl)]
22
#![allow(rustc::untranslatable_diagnostic)]
33

4+
use core::ops::ControlFlow;
45
use hir::ExprKind;
56
use rustc_errors::{Applicability, Diag};
67
use rustc_hir as hir;
@@ -727,30 +728,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
727728
_ => local_decl.source_info.span,
728729
};
729730

730-
struct BindingFinder {
731-
span: Span,
732-
hir_id: Option<hir::HirId>,
733-
}
734-
735-
impl<'tcx> Visitor<'tcx> for BindingFinder {
736-
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
737-
if let hir::StmtKind::Local(local) = s.kind {
738-
if local.pat.span == self.span {
739-
self.hir_id = Some(local.hir_id);
740-
}
741-
}
742-
hir::intravisit::walk_stmt(self, s);
743-
}
744-
}
745-
746731
let def_id = self.body.source.def_id();
747732
let hir_id = if let Some(local_def_id) = def_id.as_local()
748733
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
749734
{
750735
let body = self.infcx.tcx.hir().body(body_id);
751-
let mut v = BindingFinder { span: pat_span, hir_id: None };
752-
v.visit_body(body);
753-
v.hir_id
736+
BindingFinder { span: pat_span }.visit_body(body).break_value()
754737
} else {
755738
None
756739
};
@@ -859,17 +842,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
859842
};
860843

861844
let hir_map = self.infcx.tcx.hir();
862-
struct Finder<'tcx> {
845+
struct Finder {
863846
span: Span,
864-
expr: Option<&'tcx Expr<'tcx>>,
865847
}
866848

867-
impl<'tcx> Visitor<'tcx> for Finder<'tcx> {
868-
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
869-
if e.span == self.span && self.expr.is_none() {
870-
self.expr = Some(e);
849+
impl<'tcx> Visitor<'tcx> for Finder {
850+
type Result = ControlFlow<&'tcx Expr<'tcx>>;
851+
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) -> Self::Result {
852+
if e.span == self.span {
853+
ControlFlow::Break(e)
854+
} else {
855+
hir::intravisit::walk_expr(self, e)
871856
}
872-
hir::intravisit::walk_expr(self, e);
873857
}
874858
}
875859
if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id())
@@ -878,9 +862,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
878862
// `span` corresponds to the expression being iterated, find the `for`-loop desugared
879863
// expression with that span in order to identify potential fixes when encountering a
880864
// read-only iterator that should be mutable.
881-
let mut v = Finder { span, expr: None };
882-
v.visit_block(block);
883-
if let Some(expr) = v.expr
865+
if let ControlFlow::Break(expr) = (Finder { span }).visit_block(block)
884866
&& let Call(_, [expr]) = expr.kind
885867
{
886868
match expr.kind {
@@ -1179,29 +1161,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
11791161
);
11801162
}
11811163
Some((false, err_label_span, message)) => {
1182-
struct BindingFinder {
1183-
span: Span,
1184-
hir_id: Option<hir::HirId>,
1185-
}
1186-
1187-
impl<'tcx> Visitor<'tcx> for BindingFinder {
1188-
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
1189-
if let hir::StmtKind::Local(local) = s.kind {
1190-
if local.pat.span == self.span {
1191-
self.hir_id = Some(local.hir_id);
1192-
}
1193-
}
1194-
hir::intravisit::walk_stmt(self, s);
1195-
}
1196-
}
11971164
let def_id = self.body.source.def_id();
11981165
let hir_id = if let Some(local_def_id) = def_id.as_local()
11991166
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
12001167
{
12011168
let body = self.infcx.tcx.hir().body(body_id);
1202-
let mut v = BindingFinder { span: err_label_span, hir_id: None };
1203-
v.visit_body(body);
1204-
v.hir_id
1169+
BindingFinder { span: err_label_span }.visit_body(body).break_value()
12051170
} else {
12061171
None
12071172
};
@@ -1333,6 +1298,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
13331298
}
13341299
}
13351300

1301+
struct BindingFinder {
1302+
span: Span,
1303+
}
1304+
1305+
impl<'tcx> Visitor<'tcx> for BindingFinder {
1306+
type Result = ControlFlow<hir::HirId>;
1307+
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) -> Self::Result {
1308+
if let hir::StmtKind::Local(local) = s.kind
1309+
&& local.pat.span == self.span
1310+
{
1311+
ControlFlow::Break(local.hir_id)
1312+
} else {
1313+
hir::intravisit::walk_stmt(self, s)
1314+
}
1315+
}
1316+
}
1317+
13361318
pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
13371319
debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
13381320

compiler/rustc_borrowck/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#![feature(assert_matches)]
77
#![feature(associated_type_bounds)]
88
#![feature(box_patterns)]
9+
#![feature(control_flow_enum)]
910
#![feature(let_chains)]
1011
#![feature(min_specialization)]
1112
#![feature(never_type)]

compiler/rustc_builtin_macros/src/cfg_eval.rs

+33-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
22

3+
use core::ops::ControlFlow;
34
use rustc_ast as ast;
45
use rustc_ast::mut_visit::MutVisitor;
56
use rustc_ast::ptr::P;
@@ -87,41 +88,40 @@ fn flat_map_annotatable(
8788
}
8889
}
8990

90-
struct CfgFinder {
91-
has_cfg_or_cfg_attr: bool,
92-
}
93-
94-
impl CfgFinder {
95-
fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
96-
let mut finder = CfgFinder { has_cfg_or_cfg_attr: false };
97-
match annotatable {
98-
Annotatable::Item(item) => finder.visit_item(item),
99-
Annotatable::TraitItem(item) => finder.visit_assoc_item(item, visit::AssocCtxt::Trait),
100-
Annotatable::ImplItem(item) => finder.visit_assoc_item(item, visit::AssocCtxt::Impl),
101-
Annotatable::ForeignItem(item) => finder.visit_foreign_item(item),
102-
Annotatable::Stmt(stmt) => finder.visit_stmt(stmt),
103-
Annotatable::Expr(expr) => finder.visit_expr(expr),
104-
Annotatable::Arm(arm) => finder.visit_arm(arm),
105-
Annotatable::ExprField(field) => finder.visit_expr_field(field),
106-
Annotatable::PatField(field) => finder.visit_pat_field(field),
107-
Annotatable::GenericParam(param) => finder.visit_generic_param(param),
108-
Annotatable::Param(param) => finder.visit_param(param),
109-
Annotatable::FieldDef(field) => finder.visit_field_def(field),
110-
Annotatable::Variant(variant) => finder.visit_variant(variant),
111-
Annotatable::Crate(krate) => finder.visit_crate(krate),
112-
};
113-
finder.has_cfg_or_cfg_attr
114-
}
115-
}
91+
fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
92+
struct CfgFinder;
11693

117-
impl<'ast> visit::Visitor<'ast> for CfgFinder {
118-
fn visit_attribute(&mut self, attr: &'ast Attribute) {
119-
// We want short-circuiting behavior, so don't use the '|=' operator.
120-
self.has_cfg_or_cfg_attr = self.has_cfg_or_cfg_attr
121-
|| attr
94+
impl<'ast> visit::Visitor<'ast> for CfgFinder {
95+
type Result = ControlFlow<()>;
96+
fn visit_attribute(&mut self, attr: &'ast Attribute) -> ControlFlow<()> {
97+
if attr
12298
.ident()
123-
.is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr);
99+
.is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr)
100+
{
101+
ControlFlow::Break(())
102+
} else {
103+
ControlFlow::Continue(())
104+
}
105+
}
124106
}
107+
108+
let res = match annotatable {
109+
Annotatable::Item(item) => CfgFinder.visit_item(item),
110+
Annotatable::TraitItem(item) => CfgFinder.visit_assoc_item(item, visit::AssocCtxt::Trait),
111+
Annotatable::ImplItem(item) => CfgFinder.visit_assoc_item(item, visit::AssocCtxt::Impl),
112+
Annotatable::ForeignItem(item) => CfgFinder.visit_foreign_item(item),
113+
Annotatable::Stmt(stmt) => CfgFinder.visit_stmt(stmt),
114+
Annotatable::Expr(expr) => CfgFinder.visit_expr(expr),
115+
Annotatable::Arm(arm) => CfgFinder.visit_arm(arm),
116+
Annotatable::ExprField(field) => CfgFinder.visit_expr_field(field),
117+
Annotatable::PatField(field) => CfgFinder.visit_pat_field(field),
118+
Annotatable::GenericParam(param) => CfgFinder.visit_generic_param(param),
119+
Annotatable::Param(param) => CfgFinder.visit_param(param),
120+
Annotatable::FieldDef(field) => CfgFinder.visit_field_def(field),
121+
Annotatable::Variant(variant) => CfgFinder.visit_variant(variant),
122+
Annotatable::Crate(krate) => CfgFinder.visit_crate(krate),
123+
};
124+
res.is_break()
125125
}
126126

127127
impl CfgEval<'_, '_> {
@@ -132,7 +132,7 @@ impl CfgEval<'_, '_> {
132132
fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Option<Annotatable> {
133133
// Tokenizing and re-parsing the `Annotatable` can have a significant
134134
// performance impact, so try to avoid it if possible
135-
if !CfgFinder::has_cfg_or_cfg_attr(&annotatable) {
135+
if !has_cfg_or_cfg_attr(&annotatable) {
136136
return Some(annotatable);
137137
}
138138

compiler/rustc_builtin_macros/src/deriving/default.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::deriving::generic::ty::*;
22
use crate::deriving::generic::*;
33
use crate::errors;
4+
use core::ops::ControlFlow;
45
use rustc_ast as ast;
56
use rustc_ast::visit::walk_list;
67
use rustc_ast::{attr, EnumDef, VariantData};
@@ -231,20 +232,19 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, '
231232
}
232233

233234
fn has_a_default_variant(item: &Annotatable) -> bool {
234-
struct HasDefaultAttrOnVariant {
235-
found: bool,
236-
}
235+
struct HasDefaultAttrOnVariant;
237236

238237
impl<'ast> rustc_ast::visit::Visitor<'ast> for HasDefaultAttrOnVariant {
239-
fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) {
238+
type Result = ControlFlow<()>;
239+
fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) -> ControlFlow<()> {
240240
if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) {
241-
self.found = true;
241+
ControlFlow::Break(())
242+
} else {
243+
// no need to subrecurse.
244+
ControlFlow::Continue(())
242245
}
243-
// no need to subrecurse.
244246
}
245247
}
246248

247-
let mut visitor = HasDefaultAttrOnVariant { found: false };
248-
item.visit_with(&mut visitor);
249-
visitor.found
249+
item.visit_with(&mut HasDefaultAttrOnVariant).is_break()
250250
}

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::potentially_plural_count;
22
use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
3+
use core::ops::ControlFlow;
34
use hir::def_id::{DefId, DefIdMap, LocalDefId};
45
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
56
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
@@ -1565,24 +1566,24 @@ fn compare_synthetic_generics<'tcx>(
15651566
let (sig, _) = impl_m.expect_fn();
15661567
let input_tys = sig.decl.inputs;
15671568

1568-
struct Visitor(Option<Span>, hir::def_id::LocalDefId);
1569+
struct Visitor(hir::def_id::LocalDefId);
15691570
impl<'v> intravisit::Visitor<'v> for Visitor {
1570-
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
1571-
intravisit::walk_ty(self, ty);
1571+
type Result = ControlFlow<Span>;
1572+
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) -> Self::Result {
15721573
if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
15731574
&& let Res::Def(DefKind::TyParam, def_id) = path.res
1574-
&& def_id == self.1.to_def_id()
1575+
&& def_id == self.0.to_def_id()
15751576
{
1576-
self.0 = Some(ty.span);
1577+
ControlFlow::Break(ty.span)
1578+
} else {
1579+
intravisit::walk_ty(self, ty)
15771580
}
15781581
}
15791582
}
15801583

1581-
let mut visitor = Visitor(None, impl_def_id);
1582-
for ty in input_tys {
1583-
intravisit::Visitor::visit_ty(&mut visitor, ty);
1584-
}
1585-
let span = visitor.0?;
1584+
let span = input_tys.iter().find_map(|ty| {
1585+
intravisit::Visitor::visit_ty(&mut Visitor(impl_def_id), ty).break_value()
1586+
})?;
15861587

15871588
let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
15881589
let bounds = bounds.first()?.span().to(bounds.last()?.span());

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+9-13
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//! the types in HIR to identify late-bound lifetimes and assign their Debruijn indices. This file
77
//! is also responsible for assigning their semantics to implicit lifetimes in trait objects.
88
9+
use core::ops::ControlFlow;
910
use rustc_ast::visit::walk_list;
1011
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
1112
use rustc_errors::{codes::*, struct_span_code_err};
@@ -417,23 +418,18 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
417418
{
418419
if let &hir::ClosureBinder::For { span: for_sp, .. } = binder {
419420
fn span_of_infer(ty: &hir::Ty<'_>) -> Option<Span> {
420-
struct V(Option<Span>);
421-
421+
struct V;
422422
impl<'v> Visitor<'v> for V {
423-
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
424-
match t.kind {
425-
_ if self.0.is_some() => (),
426-
hir::TyKind::Infer => {
427-
self.0 = Some(t.span);
428-
}
429-
_ => intravisit::walk_ty(self, t),
423+
type Result = ControlFlow<Span>;
424+
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) -> Self::Result {
425+
if matches!(t.kind, hir::TyKind::Infer) {
426+
ControlFlow::Break(t.span)
427+
} else {
428+
intravisit::walk_ty(self, t)
430429
}
431430
}
432431
}
433-
434-
let mut v = V(None);
435-
v.visit_ty(ty);
436-
v.0
432+
V.visit_ty(ty).break_value()
437433
}
438434

439435
let infer_in_rt_sp = match fn_decl.output {

0 commit comments

Comments
 (0)