Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)>),
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down
45 changes: 45 additions & 0 deletions tests/ui/lint/unused/must_use-pin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#![deny(unused_must_use)]

use std::{ops::Deref, pin::Pin};

#[must_use]
struct MustUse;

#[must_use]
struct MustUsePtr<'a, T>(&'a T);

impl<'a, T> Deref for MustUsePtr<'a, T> {
type Target = T;

fn deref(&self) -> &Self::Target {
self.0
}
}

fn pin_ref() -> Pin<&'static ()> {
Pin::new(&())
}

fn pin_ref_mut() -> Pin<&'static mut ()> {
Pin::new(unimplemented!())
}

fn pin_must_use_ptr() -> Pin<MustUsePtr<'static, ()>> {
Pin::new(MustUsePtr(&()))
}

fn pin_box() -> Pin<Box<()>> {
Box::pin(())
}

fn pin_box_must_use() -> Pin<Box<MustUse>> {
Box::pin(MustUse)
}

fn main() {
pin_ref();
pin_ref_mut();
pin_must_use_ptr(); //~ ERROR unused pinned `MustUsePtr` that must be used
pin_box();
pin_box_must_use(); //~ ERROR unused pinned boxed `MustUse` that must be used
}
20 changes: 20 additions & 0 deletions tests/ui/lint/unused/must_use-pin.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: unused pinned `MustUsePtr` that must be used
--> $DIR/must_use-pin.rs:42:5
|
LL | pin_must_use_ptr();
| ^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/must_use-pin.rs:1:9
|
LL | #![deny(unused_must_use)]
| ^^^^^^^^^^^^^^^

error: unused pinned boxed `MustUse` that must be used
--> $DIR/must_use-pin.rs:44:5
|
LL | pin_box_must_use();
| ^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors