]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_middle/ty/diagnostics.rs
Account for multiple impl/dyn Trait in return type when suggesting `'_`
[rust.git] / src / librustc_middle / ty / diagnostics.rs
index a2812e117ed39571f9e7e154bfdf27c4f1237143..b22727bdd7587b71848ce692971577f2cf1cdc3c 100644 (file)
@@ -236,7 +236,9 @@ pub fn suggest_constraining_type_param(
     }
 }
 
-pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>);
+/// Collect al types that have an implicit `'static` obligation that we could suggest `'_` for.
+pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>, pub crate::hir::map::Map<'tcx>);
+
 impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
     type Map = rustc_hir::intravisit::ErasedMap<'v>;
 
@@ -245,15 +247,24 @@ fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
     }
 
     fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
-        if let hir::TyKind::TraitObject(
-            _,
-            hir::Lifetime {
-                name: hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
-                ..
-            },
-        ) = ty.kind
-        {
-            self.0.push(ty);
+        match ty.kind {
+            hir::TyKind::TraitObject(
+                _,
+                hir::Lifetime {
+                    name:
+                        hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
+                    ..
+                },
+            ) => {
+                self.0.push(ty);
+            }
+            hir::TyKind::OpaqueDef(item_id, _) => {
+                self.0.push(ty);
+                let item = self.1.expect_item(item_id.id);
+                hir::intravisit::walk_item(self, item);
+            }
+            _ => {}
         }
+        hir::intravisit::walk_ty(self, ty);
     }
 }