about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-09-25 22:23:36 +0000
committerMichael Goulet <michael@errs.io>2022-10-20 17:31:01 +0000
commit8509819aef02c28c3f636dc04ad7b6087f7dc334 (patch)
treecfff3bcc6dbc2fcb71ec48696390cca67469d1ba
parent542febd2d383b5082277c7d165b098c0a3b513f6 (diff)
downloadrust-8509819aef02c28c3f636dc04ad7b6087f7dc334.tar.gz
rust-8509819aef02c28c3f636dc04ad7b6087f7dc334.zip
Elaborate supertrait bounds when triggering unused_must_use on impl Trait
-rw-r--r--compiler/rustc_lint/src/unused.rs8
-rw-r--r--src/test/ui/lint/unused/unused-supertrait.rs11
-rw-r--r--src/test/ui/lint/unused/unused-supertrait.stderr15
3 files changed, 32 insertions, 2 deletions
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 787c9518b50..36657909b19 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -7,6 +7,7 @@ use rustc_errors::{fluent, pluralize, Applicability, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
+use rustc_infer::traits::util::elaborate_predicates_with_span;
 use rustc_middle::ty::adjustment;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::symbol::Symbol;
@@ -204,10 +205,13 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                 ty::Adt(def, _) => check_must_use_def(cx, def.did(), span, descr_pre, descr_post),
                 ty::Opaque(def, _) => {
                     let mut has_emitted = false;
-                    for &(predicate, _) in cx.tcx.explicit_item_bounds(def) {
+                    for obligation in elaborate_predicates_with_span(
+                        cx.tcx,
+                        cx.tcx.explicit_item_bounds(def).iter().cloned(),
+                    ) {
                         // We only look at the `DefId`, so it is safe to skip the binder here.
                         if let ty::PredicateKind::Trait(ref poly_trait_predicate) =
-                            predicate.kind().skip_binder()
+                            obligation.predicate.kind().skip_binder()
                         {
                             let def_id = poly_trait_predicate.trait_ref.def_id;
                             let descr_pre =
diff --git a/src/test/ui/lint/unused/unused-supertrait.rs b/src/test/ui/lint/unused/unused-supertrait.rs
new file mode 100644
index 00000000000..64a8e520457
--- /dev/null
+++ b/src/test/ui/lint/unused/unused-supertrait.rs
@@ -0,0 +1,11 @@
+#![deny(unused_must_use)]
+
+fn it() -> impl ExactSizeIterator<Item = ()> {
+    let x: Box<dyn ExactSizeIterator<Item = ()>> = todo!();
+    x
+}
+
+fn main() {
+    it();
+    //~^ ERROR unused implementer of `Iterator` that must be used
+}
diff --git a/src/test/ui/lint/unused/unused-supertrait.stderr b/src/test/ui/lint/unused/unused-supertrait.stderr
new file mode 100644
index 00000000000..d2f8c007848
--- /dev/null
+++ b/src/test/ui/lint/unused/unused-supertrait.stderr
@@ -0,0 +1,15 @@
+error: unused implementer of `Iterator` that must be used
+  --> $DIR/unused-supertrait.rs:9:5
+   |
+LL |     it();
+   |     ^^^^^
+   |
+   = note: iterators are lazy and do nothing unless consumed
+note: the lint level is defined here
+  --> $DIR/unused-supertrait.rs:1:9
+   |
+LL | #![deny(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+