Code change:
gives a warning, but does not.
suggested that we test this out with crater to see if this would generate much substantial noise and how common it would be.
I'd expect it'd be a pretty substantial source of warnings, but that's exactly why I think we should introduce it. People compiling with are asking for these sorts of bugs to be caught, and we should serve them appropriately ;) In any case, running crater would require having an implementation to do a crater run on, so let's do it!
Let's do it. (I'd personally even like an attribute to allow people to opt-in to this for , for example, when T is itself . That way if I make a , I'll get a warning on that I normally wouldn't want but plausibly do now that I'm getting s in the s.)
I've opened a pull request to try this out:
We discussed this on the language team meeting; folks felt generally positive, but we'd like to do a crater run to see what the impact would be like and if there would be many false positives.
I tried this using but it does not seemed to complain when the part of is not used, is the the correct behavior? I hit this when doing where I didn't use part of the tuple which cause it to not work, which I did not know is required to be used.
putting it into a binding, even an unused one, is considered a use, like how doesn't lint. With just calling it lints:

Related discussion:
text: cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); } <del> fn check_must_use( </del> <ins> // Returns whether an error has been emitted (and thus another does not need to be later). fn check_must_use_ty<'tcx>( cx: &LateContext<'_, 'tcx>, ty: Ty<'tcx>, expr: &hir::Expr, span: Span, descr_post_path: &str, ) -> bool { if ty.is_unit() || cx.tcx.is_ty_uninhabited_from( cx.tcx.hir().get_module_parent_by_hir_id(expr.hir_id), ty) { return true; } match ty.sty { ty::Adt(def, _) => check_must_use_def(cx, def.did, span, "", descr_post_path), ty::Opaque(def, _) => { let mut has_emitted = false; for (predicate, _) in &cx.tcx.predicates_of(def).predicates { if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; let def_id = trait_ref.def_id; if check_must_use_def(cx, def_id, span, "implementer of ", "") { has_emitted = true; break; } } } has_emitted } ty::Dynamic(binder, _) => { let mut has_emitted = false; for predicate in binder.skip_binder().iter() { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { let def_id = trait_ref.def_id; if check_must_use_def(cx, def_id, span, "", " trait object") { has_emitted = true; break; } } } has_emitted } ty::Tuple(ref tys) => { let mut has_emitted = false; let spans = if let hir::ExprKind::Tup(comps) = &expr.node { debug_assert_eq!(comps.len(), tys.len()); comps.iter().map(|e| e.span).collect() } else { vec![] }; for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() { let descr_post_path = &format!(" in tuple element {}", i); let span = *spans.get(i).unwrap_or(&span); if check_must_use_ty(cx, ty, expr, span, descr_post_path) { has_emitted = true; } } has_emitted } _ => false, } } // Returns whether an error has been emitted (and thus another does not need to be later). fn check_must_use_def( </ins> cx: &LateContext<'_, '_>, def_id: DefId, <del> sp: Span, </del> <ins> span: Span, </ins> descr_pre_path: &str, descr_post_path: &str, ) -> bool {