Auto merge of #118054 - max-niederman:pinned-must-use, r=Nilstrieb
Lint pinned `#[must_use]` pointers (in particular, `Box<T>` where `T` is `#[must_use]`) in `unused_must_use`. Fixes: #111458 This is motivated by a common async/await pattern: ```rs fn foo() -> Pin<Box<dyn Future<Output = i32>>> { Box::pin(async { 42 }) } // call `foo`, but forget to await the result foo(); ``` Unlike with `async fn` or return position `impl Future`, this does not currently warn the user that the `Future` is unused. To fix this, I've extended the `unused_must_use` lint to catch `Pin<P>`, where `P` must be used. In particular, this applies to `Pin<Box<T>>`, where `T` must be used. I'm not sure if there are other pointers where this applies, but I can't think of any situation the user wouldn't want to be warned.
This commit is contained in:
commit
097261f241
3 changed files with 83 additions and 0 deletions
|
@ -251,6 +251,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
/// The root of the normal must_use lint with an optional message.
|
||||
Def(Span, DefId, Option<Symbol>),
|
||||
Boxed(Box<Self>),
|
||||
Pinned(Box<Self>),
|
||||
Opaque(Box<Self>),
|
||||
TraitObject(Box<Self>),
|
||||
TupleElement(Vec<(usize, Self)>),
|
||||
|
@ -284,6 +285,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
is_ty_must_use(cx, boxed_ty, expr, span)
|
||||
.map(|inner| MustUsePath::Boxed(Box::new(inner)))
|
||||
}
|
||||
ty::Adt(def, args) if cx.tcx.lang_items().pin_type() == Some(def.did()) => {
|
||||
let pinned_ty = args.type_at(0);
|
||||
is_ty_must_use(cx, pinned_ty, expr, span)
|
||||
.map(|inner| MustUsePath::Pinned(Box::new(inner)))
|
||||
}
|
||||
ty::Adt(def, _) => is_def_must_use(cx, def.did(), span),
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
|
||||
elaborate(
|
||||
|
@ -425,6 +431,18 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::Pinned(path) => {
|
||||
let descr_pre = &format!("{descr_pre}pinned ");
|
||||
emit_must_use_untranslated(
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::Opaque(path) => {
|
||||
let descr_pre = &format!("{descr_pre}implementer{plural_suffix} of ");
|
||||
emit_must_use_untranslated(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue