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
This commit is contained in:
commit
9adf2189f5
24 changed files with 67 additions and 62 deletions
|
|
@ -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
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
});
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ impl UnconditionalRecursion {
|
|||
implemented_ty_id,
|
||||
method_span,
|
||||
};
|
||||
walk_body(&mut c, body);
|
||||
let _ = walk_body(&mut c, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue