+ // Returns whether an error has been emitted (and thus another does not need to be later).
+ fn check_must_use_ty(
+ cx: &LateContext<'_, '_>,
+ ty: ty::Ty<'_>,
+ span: Span,
+ ) -> bool {
+ match ty.sty {
+ ty::Adt(def, _) => check_must_use_def(cx, def.did, span, "", ""),
+ 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) => {
+ tys.iter().map(|k| k.expect_ty()).any(|ty| {
+ check_must_use_ty(cx, ty, span)
+ })
+ }
+ _ => false,
+ }
+ }
+
+ // Returns whether an error has been emitted (and thus another does not need to be later).
+ fn check_must_use_def(