]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/future_not_send.rs
Fix more β€œa”/β€œan” typos
[rust.git] / clippy_lints / src / future_not_send.rs
index 0a02aa7533c176e4ebd13ec012f192e379a599f0..3e35ada7b2a1c909aaeb416f8e11d8be6bc85c31 100644 (file)
@@ -1,21 +1,25 @@
-use crate::utils;
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::return_ty;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, FnDecl, HirId};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{Opaque, PredicateKind::Trait, ToPolyTraitRef};
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::{Opaque, PredicateKind::Trait};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::{sym, Span};
 use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt;
 use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine};
 
 declare_clippy_lint! {
-    /// **What it does:** This lint requires Future implementations returned from
+    /// ### What it does
+    /// This lint requires Future implementations returned from
     /// functions and methods to implement the `Send` marker trait. It is mostly
     /// used by library authors (public and internal) that target an audience where
     /// multithreaded executors are likely to be used for running these Futures.
     ///
-    /// **Why is this bad?** A Future implementation captures some state that it
+    /// ### Why is this bad?
+    /// A Future implementation captures some state that it
     /// needs to eventually produce its final value. When targeting a multithreaded
     /// executor (which is the norm on non-embedded devices) this means that this
     /// state may need to be transported to other threads, in other words the
     /// modifying the library where the offending Future implementation is
     /// produced.
     ///
-    /// **Known problems:** None.
-    ///
-    /// **Example:**
-    ///
+    /// ### Example
     /// ```rust
     /// async fn not_send(bytes: std::rc::Rc<[u8]>) {}
     /// ```
 
 declare_lint_pass!(FutureNotSend => [FUTURE_NOT_SEND]);
 
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FutureNotSend {
+impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
     fn check_fn(
         &mut self,
-        cx: &LateContext<'a, 'tcx>,
+        cx: &LateContext<'tcx>,
         kind: FnKind<'tcx>,
         decl: &'tcx FnDecl<'tcx>,
         _: &'tcx Body<'tcx>,
         _: Span,
         hir_id: HirId,
     ) {
-        if let FnKind::Closure(_) = kind {
+        if let FnKind::Closure = kind {
             return;
         }
-        let ret_ty = utils::return_ty(cx, hir_id);
-        if let Opaque(id, subst) = ret_ty.kind {
-            let preds = cx.tcx.predicates_of(id).instantiate(cx.tcx, subst);
+        let ret_ty = return_ty(cx, hir_id);
+        if let Opaque(id, subst) = *ret_ty.kind() {
+            let preds = cx.tcx.explicit_item_bounds(id);
             let mut is_future = false;
-            for p in preds.predicates {
+            for &(p, _span) in preds {
+                let p = p.subst(cx.tcx, subst);
                 if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
-                    if Some(trait_ref.def_id()) == cx.tcx.lang_items().future_trait() {
+                    if Some(trait_ref.value.def_id()) == cx.tcx.lang_items().future_trait() {
                         is_future = true;
                         break;
                     }
@@ -82,7 +84,7 @@ fn check_fn(
                     fulfillment_cx.select_all_or_error(&infcx)
                 });
                 if let Err(send_errors) = send_result {
-                    utils::span_lint_and_then(
+                    span_lint_and_then(
                         cx,
                         FUTURE_NOT_SEND,
                         span,
@@ -91,16 +93,15 @@ fn check_fn(
                             cx.tcx.infer_ctxt().enter(|infcx| {
                                 for FulfillmentError { obligation, .. } in send_errors {
                                     infcx.maybe_note_obligation_cause_for_async_await(db, &obligation);
-                                    if let Trait(trait_pred, _) = obligation.predicate.kind() {
-                                        let trait_ref = trait_pred.to_poly_trait_ref();
-                                        db.note(&*format!(
+                                    if let Trait(trait_pred) = obligation.predicate.kind().skip_binder() {
+                                        db.note(&format!(
                                             "`{}` doesn't implement `{}`",
-                                            trait_ref.self_ty(),
-                                            trait_ref.print_only_trait_path(),
+                                            trait_pred.self_ty(),
+                                            trait_pred.trait_ref.print_only_trait_path(),
                                         ));
                                     }
                                 }
-                            })
+                            });
                         },
                     );
                 }