diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-03-17 16:34:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-17 16:34:47 +0100 |
| commit | 9adf2189f55b6e20ab8b490cc75438ba5ef2e793 (patch) | |
| tree | e9bd055031b655bbd005e0e89a28c00c6360ff8e /src | |
| parent | 3d3f817ff92a9a59e6f2ed50ff76c01800614654 (diff) | |
| parent | e250bd16da5d3016c45e91431fd7b97822f771c0 (diff) | |
| download | rust-9adf2189f55b6e20ab8b490cc75438ba5ef2e793.tar.gz rust-9adf2189f55b6e20ab8b490cc75438ba5ef2e793.zip | |
Rollup merge of #137449 - compiler-errors:control-flow, r=Amanieu,lnicola
Denote `ControlFlow` as `#[must_use]` I've repeatedly hit bugs in the compiler due to `ControlFlow` not being marked `#[must_use]`. There seems to be an accepted ACP to make the type `#[must_use]` (https://github.com/rust-lang/libs-team/issues/444), so this PR implements that part of it. Most of the usages in the compiler that trigger this new warning are "root" usages (calling into an API that uses control-flow internally, but for which the callee doesn't really care) and have been suppressed by `let _ = ...`, but I did legitimately find one instance of a missing `?` and one for a never-used `ControlFlow` value in #137448. Presumably this needs an FCP too, so I'm opening this and nominating it for T-libs-api. This PR also touches the tools (incl. rust-analyzer), but if this went into FCP, I'd split those out into separate PRs which can land before this one does. r? libs-api `@rustbot` label: T-libs-api I-libs-api-nominated
Diffstat (limited to 'src')
16 files changed, 45 insertions, 45 deletions
diff --git a/src/librustdoc/html/length_limit/tests.rs b/src/librustdoc/html/length_limit/tests.rs index 2185c034890..4ebecfd5f24 100644 --- a/src/librustdoc/html/length_limit/tests.rs +++ b/src/librustdoc/html/length_limit/tests.rs @@ -9,41 +9,41 @@ fn empty() { #[test] fn basic() { let mut buf = HtmlWithLimit::new(60); - buf.push("Hello "); + let _ = buf.push("Hello "); buf.open_tag("em"); - buf.push("world"); + let _ = buf.push("world"); buf.close_tag(); - buf.push("!"); + let _ = buf.push("!"); assert_eq!(buf.finish(), "Hello <em>world</em>!"); } #[test] fn no_tags() { let mut buf = HtmlWithLimit::new(60); - buf.push("Hello"); - buf.push(" world!"); + let _ = buf.push("Hello"); + let _ = buf.push(" world!"); assert_eq!(buf.finish(), "Hello world!"); } #[test] fn limit_0() { let mut buf = HtmlWithLimit::new(0); - buf.push("Hello "); + let _ = buf.push("Hello "); buf.open_tag("em"); - buf.push("world"); + let _ = buf.push("world"); buf.close_tag(); - buf.push("!"); + let _ = buf.push("!"); assert_eq!(buf.finish(), ""); } #[test] fn exactly_limit() { let mut buf = HtmlWithLimit::new(12); - buf.push("Hello "); + let _ = buf.push("Hello "); buf.open_tag("em"); - buf.push("world"); + let _ = buf.push("world"); buf.close_tag(); - buf.push("!"); + let _ = buf.push("!"); assert_eq!(buf.finish(), "Hello <em>world</em>!"); } @@ -51,11 +51,11 @@ fn exactly_limit() { fn multiple_nested_tags() { let mut buf = HtmlWithLimit::new(60); buf.open_tag("p"); - buf.push("This is a "); + let _ = buf.push("This is a "); buf.open_tag("em"); - buf.push("paragraph"); + let _ = buf.push("paragraph"); buf.open_tag("strong"); - buf.push("!"); + let _ = buf.push("!"); buf.close_tag(); buf.close_tag(); buf.close_tag(); @@ -66,11 +66,11 @@ fn multiple_nested_tags() { fn forgot_to_close_tags() { let mut buf = HtmlWithLimit::new(60); buf.open_tag("p"); - buf.push("This is a "); + let _ = buf.push("This is a "); buf.open_tag("em"); - buf.push("paragraph"); + let _ = buf.push("paragraph"); buf.open_tag("strong"); - buf.push("!"); + let _ = buf.push("!"); assert_eq!(buf.finish(), "<p>This is a <em>paragraph<strong>!</strong></em></p>"); } @@ -78,10 +78,10 @@ fn forgot_to_close_tags() { fn past_the_limit() { let mut buf = HtmlWithLimit::new(20); buf.open_tag("p"); - (0..10).try_for_each(|n| { + let _ = (0..10).try_for_each(|n| { buf.open_tag("strong"); - buf.push("word#")?; - buf.push(&n.to_string())?; + let _ = buf.push("word#")?; + let _ = buf.push(&n.to_string())?; buf.close_tag(); ControlFlow::Continue(()) }); @@ -100,8 +100,8 @@ fn past_the_limit() { fn quickly_past_the_limit() { let mut buf = HtmlWithLimit::new(6); buf.open_tag("p"); - buf.push("Hello"); - buf.push(" World"); + let _ = buf.push("Hello"); + let _ = buf.push(" World"); // intentionally not closing <p> before finishing assert_eq!(buf.finish(), "<p>Hello</p>"); } @@ -110,7 +110,7 @@ fn quickly_past_the_limit() { fn close_too_many() { let mut buf = HtmlWithLimit::new(60); buf.open_tag("p"); - buf.push("Hello"); + let _ = buf.push("Hello"); buf.close_tag(); // This call does not panic because there are valid cases // where `close_tag()` is called with no tags left to close. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 079651e8603..b067dbf750e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1568,7 +1568,7 @@ fn markdown_summary_with_limit( let mut buf = HtmlWithLimit::new(length_limit); let mut stopped_early = false; - p.try_for_each(|event| { + let _ = p.try_for_each(|event| { match &event { Event::Text(text) => { let r = diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index fb5d49a1004..5afcf51167d 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -129,7 +129,7 @@ impl BreakAfterExprVisitor { }; get_enclosing_block(cx, hir_id).is_some_and(|block| { - visitor.visit_block(block); + let _ = visitor.visit_block(block); visitor.break_after_expr }) } diff --git a/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs b/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs index c9251c1b849..fe999a3b5f8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs +++ b/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs @@ -40,7 +40,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr< // We've checked that `call` is a call to `Stdin::read_line()` with the right receiver, // now let's check if the first use of the string passed to `::read_line()` // is used for operations that will always fail (e.g. parsing "6\n" into a number) - for_each_local_use_after_expr(cx, local_id, call.hir_id, |expr| { + let _ = for_each_local_use_after_expr(cx, local_id, call.hir_id, |expr| { if let Some(parent) = get_parent_expr(cx, expr) { let data = if let ExprKind::MethodCall(segment, recv, args, span) = parent.kind { if args.is_empty() diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 320c0286bb7..0a8e2885648 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -141,7 +141,7 @@ impl PassByRefOrValue { // Gather all the lifetimes found in the output type which may affect whether // `TRIVIALLY_COPY_PASS_BY_REF` should be linted. let mut output_regions = FxHashSet::default(); - for_each_top_level_late_bound_region(fn_sig.skip_binder().output(), |region| -> ControlFlow<!> { + let _ = for_each_top_level_late_bound_region(fn_sig.skip_binder().output(), |region| -> ControlFlow<!> { output_regions.insert(region); ControlFlow::Continue(()) }); diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index a443043bef9..51c7d6fce31 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -381,7 +381,7 @@ impl UnconditionalRecursion { implemented_ty_id, method_span, }; - walk_body(&mut c, body); + let _ = walk_body(&mut c, body); } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 67fb73696f7..65fb342f752 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -145,19 +145,19 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> { let mut result = vec![]; if fps.is_empty() { debug!("Unrestricted search for {:?} impls...", trait_); - self.for_trait_impls(trait_, self_ty_fp, |impls| { + let _ = self.for_trait_impls(trait_, self_ty_fp, |impls| { result.extend(impls.for_trait(trait_).map(id_to_chalk)); ControlFlow::Continue(()) - }) + }); } else { - self.for_trait_impls(trait_, self_ty_fp, |impls| { + let _ = self.for_trait_impls(trait_, self_ty_fp, |impls| { result.extend( fps.iter().flat_map(move |fp| { impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) }), ); ControlFlow::Continue(()) - }) + }); }; debug!("impls_for_trait returned {} impls", result.len()); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index 6a01579bccc..e042c35d0c6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -116,7 +116,7 @@ pub fn dyn_compatibility_of_trait_query( trait_: TraitId, ) -> Option<DynCompatibilityViolation> { let mut res = None; - dyn_compatibility_of_trait_with_callback(db, trait_, &mut |osv| { + let _ = dyn_compatibility_of_trait_with_callback(db, trait_, &mut |osv| { res = Some(osv); ControlFlow::Break(()) }); @@ -597,7 +597,7 @@ fn contains_illegal_impl_trait_in_trait( let ret = sig.skip_binders().ret(); let mut visitor = OpaqueTypeCollector(FxHashSet::default()); - ret.visit_with(visitor.as_dyn(), DebruijnIndex::INNERMOST); + let _ = ret.visit_with(visitor.as_dyn(), DebruijnIndex::INNERMOST); // Since we haven't implemented RPITIT in proper way like rustc yet, // just check whether `ret` contains RPIT for now diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs index 3060b610bb6..50851325bd5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs @@ -53,7 +53,7 @@ fn check_dyn_compatibility<'a>( continue; }; let mut osvs = FxHashSet::default(); - dyn_compatibility_with_callback(&db, trait_id, &mut |osv| { + let _ = dyn_compatibility_with_callback(&db, trait_id, &mut |osv| { osvs.insert(match osv { DynCompatibilityViolation::SizedSelf => SizedSelf, DynCompatibilityViolation::SelfReferential => SelfReferential, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 556091c4046..3e0ce7f1933 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -1143,7 +1143,7 @@ impl<'a> InferenceContext<'a> { non_assocs: FxHashMap::default(), }; for ty in tait_candidates { - ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST); + let _ = ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST); } // Non-assoc TAITs can be define-used everywhere as long as they are diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 624767cedf8..cc02b71f05c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -1033,7 +1033,7 @@ where T: ?Sized + TypeVisitable<Interner>, { let mut collector = PlaceholderCollector { db, placeholders: FxHashSet::default() }; - value.visit_with(&mut collector, DebruijnIndex::INNERMOST); + let _ = value.visit_with(&mut collector, DebruijnIndex::INNERMOST); collector.placeholders.into_iter().collect() } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index db94351dcc9..c7228005271 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -596,7 +596,7 @@ pub(crate) fn iterate_method_candidates<T>( mut callback: impl FnMut(ReceiverAdjustments, AssocItemId, bool) -> Option<T>, ) -> Option<T> { let mut slot = None; - iterate_method_candidates_dyn( + let _ = iterate_method_candidates_dyn( ty, db, env, diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index 4351a34e822..4e45b5a250e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs @@ -260,7 +260,7 @@ fn resolve_impl_trait_item( // attributes here. Use path resolution directly instead. // // FIXME: resolve type aliases (which are not yielded by iterate_path_candidates) - method_resolution::iterate_path_candidates( + let _ = method_resolution::iterate_path_candidates( &canonical, db, environment, diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index a8075509474..29f45846650 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -2911,7 +2911,7 @@ impl Trait { db: &dyn HirDatabase, ) -> Option<Vec<DynCompatibilityViolation>> { let mut violations = vec![]; - hir_ty::dyn_compatibility::dyn_compatibility_with_callback(db, self.id, &mut |violation| { + let _ = hir_ty::dyn_compatibility::dyn_compatibility_with_callback(db, self.id, &mut |violation| { violations.push(violation); ControlFlow::Continue(()) }); @@ -5497,7 +5497,7 @@ impl Type { .generic_def() .map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d)); - method_resolution::iterate_method_candidates_dyn( + let _ = method_resolution::iterate_method_candidates_dyn( &canonical, db, environment, @@ -5584,7 +5584,7 @@ impl Type { .generic_def() .map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d)); - method_resolution::iterate_path_candidates( + let _ = method_resolution::iterate_path_candidates( &canonical, db, environment, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 330587e0dbf..6f4b886a28d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -750,7 +750,7 @@ impl FunctionBody { ast::Stmt::Item(_) => (), ast::Stmt::LetStmt(stmt) => { if let Some(pat) = stmt.pat() { - walk_pat(&pat, &mut |pat| { + let _ = walk_pat(&pat, &mut |pat| { cb(pat); std::ops::ControlFlow::<(), ()>::Continue(()) }); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs index 0b2e8aa6836..56a66070ef7 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs @@ -121,7 +121,7 @@ pub fn walk_patterns_in_expr(start: &ast::Expr, cb: &mut dyn FnMut(ast::Pat)) { match ast::Stmt::cast(node.clone()) { Some(ast::Stmt::LetStmt(l)) => { if let Some(pat) = l.pat() { - walk_pat(&pat, &mut |pat| { + let _ = walk_pat(&pat, &mut |pat| { cb(pat); ControlFlow::<(), ()>::Continue(()) }); @@ -159,7 +159,7 @@ pub fn walk_patterns_in_expr(start: &ast::Expr, cb: &mut dyn FnMut(ast::Pat)) { } } else if let Some(pat) = ast::Pat::cast(node) { preorder.skip_subtree(); - walk_pat(&pat, &mut |pat| { + let _ = walk_pat(&pat, &mut |pat| { cb(pat); ControlFlow::<(), ()>::Continue(()) }); |
