]> git.lizzy.rs Git - rust.git/commitdiff
spell the real selftype
authorcsmoe <csmoe@msn.com>
Sat, 13 Feb 2021 06:45:53 +0000 (14:45 +0800)
committercsmoe <csmoe@msn.com>
Sat, 13 Feb 2021 06:45:53 +0000 (14:45 +0800)
compiler/rustc_typeck/src/check/check.rs
src/test/ui/async-await/issues/issue-78600.stderr

index 990d19914381dd6c345e7ddc05fe935d2584c3fb..21613bbc6f2e44ed608da38c361a7caf250356f3 100644 (file)
@@ -9,7 +9,7 @@
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{ItemKind, Node};
+use rustc_hir::{def::Res, ItemKind, Node, PathSegment};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
 use rustc_middle::ty::fold::TypeFoldable;
@@ -516,10 +516,11 @@ fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy
         }
     }
 
-    #[derive(Debug)]
     struct ProhibitOpaqueVisitor<'tcx> {
         opaque_identity_ty: Ty<'tcx>,
         generics: &'tcx ty::Generics,
+        tcx: TyCtxt<'tcx>,
+        selftys: Vec<(Span, Option<String>)>,
     }
 
     impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
@@ -536,6 +537,29 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
         }
     }
 
+    impl Visitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
+        type Map = rustc_middle::hir::map::Map<'tcx>;
+
+        fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
+            hir::intravisit::NestedVisitorMap::OnlyBodies(self.tcx.hir())
+        }
+
+        fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
+            match arg.kind {
+                hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
+                    [PathSegment { res: Some(Res::SelfTy(_, impl_ref)), .. }] => {
+                        let impl_ty_name =
+                            impl_ref.map(|(def_id, _)| self.tcx.def_path_str(def_id));
+                        self.selftys.push((path.span, impl_ty_name));
+                    }
+                    _ => {}
+                },
+                _ => {}
+            }
+            hir::intravisit::walk_ty(self, arg);
+        }
+    }
+
     if let ItemKind::OpaqueTy(hir::OpaqueTy {
         origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
         ..
@@ -547,18 +571,19 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
                 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
             ),
             generics: tcx.generics_of(def_id),
+            tcx,
+            selftys: vec![],
         };
         let prohibit_opaque = tcx
             .explicit_item_bounds(def_id)
             .iter()
             .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor));
         debug!(
-            "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}",
-            prohibit_opaque, visitor
+            "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor.opaque_identity_ty={:?}, visitor.generics={:?}",
+            prohibit_opaque, visitor.opaque_identity_ty, visitor.generics
         );
 
         if let Some(ty) = prohibit_opaque.break_value() {
-            let mut visitor = SelfTySpanVisitor { tcx, selfty_spans: vec![] };
             visitor.visit_item(&item);
             let is_async = match item.kind {
                 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
@@ -576,11 +601,11 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
                 if is_async { "async fn" } else { "impl Trait" },
             );
 
-            for span in visitor.selfty_spans {
+            for (span, name) in visitor.selftys {
                 err.span_suggestion(
                     span,
                     "consider spelling out the type instead",
-                    format!("{:?}", ty),
+                    name.unwrap_or_else(|| format!("{:?}", ty)),
                     Applicability::MaybeIncorrect,
                 );
             }
@@ -1591,31 +1616,3 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
     }
     err.emit();
 }
-
-struct SelfTySpanVisitor<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    selfty_spans: Vec<Span>,
-}
-
-impl Visitor<'tcx> for SelfTySpanVisitor<'tcx> {
-    type Map = rustc_middle::hir::map::Map<'tcx>;
-
-    fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
-        hir::intravisit::NestedVisitorMap::OnlyBodies(self.tcx.hir())
-    }
-
-    fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
-        match arg.kind {
-            hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
-                [segment]
-                    if segment.res.map(|res| matches!(res, Res::SelfTy(_, _))).unwrap_or(false) =>
-                {
-                    self.selfty_spans.push(path.span);
-                }
-                _ => {}
-            },
-            _ => {}
-        }
-        hir::intravisit::walk_ty(self, arg);
-    }
-}
index 8e3dc0406fafc52973dcd293fc657ad0d757acd4..92b66147106e1eae7ecf4b851d1f1975cf9af1c6 100644 (file)
@@ -4,7 +4,7 @@ error[E0760]: `async fn` return type cannot contain a projection or `Self` that
 LL |     async fn new(i: &'a i32) -> Result<Self, ()> {
    |                                 ^^^^^^^----^^^^^
    |                                        |
-   |                                        help: consider spelling out the type instead: `std::result::Result<S<'a>, ()>`
+   |                                        help: consider spelling out the type instead: `S<'a>`
 
 error: aborting due to previous error