about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src/diagnostics
diff options
context:
space:
mode:
authoryanchen4791 <ychen2@futurewei.com>2022-12-05 16:51:49 -0800
committeryanchen4791 <ychen2@futurewei.com>2023-01-23 09:54:45 -0800
commit62a1e76d2beaa87d7f02a55e2d7faa03cdd5fd7f (patch)
treecda00d5ef8dd90bf0a35e170439b9fb798a2ad81 /compiler/rustc_borrowck/src/diagnostics
parentc8e6a9e8b6251bbc8276cb78cabe1998deecbed7 (diff)
downloadrust-62a1e76d2beaa87d7f02a55e2d7faa03cdd5fd7f.tar.gz
rust-62a1e76d2beaa87d7f02a55e2d7faa03cdd5fd7f.zip
Add hint for missing lifetime bound on trait object when type alias is used
Diffstat (limited to 'compiler/rustc_borrowck/src/diagnostics')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs59
1 files changed, 40 insertions, 19 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 187861ba127..87db08ef5b5 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -813,17 +813,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             if *outlived_f != ty::ReStatic {
                 return;
             }
+            let suitable_region = self.infcx.tcx.is_suitable_region(f);
+            let Some(suitable_region) = suitable_region else { return; };
 
-            let fn_returns = self
-                .infcx
-                .tcx
-                .is_suitable_region(f)
-                .map(|r| self.infcx.tcx.return_type_impl_or_dyn_traits(r.def_id))
-                .unwrap_or_default();
-
-            if fn_returns.is_empty() {
-                return;
-            }
+            let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id);
 
             let param = if let Some(param) = find_param_with_region(self.infcx.tcx, f, outlived_f) {
                 param
@@ -839,15 +832,43 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             };
             let captures = format!("captures data from {arg}");
 
-            return nice_region_error::suggest_new_region_bound(
-                self.infcx.tcx,
-                diag,
-                fn_returns,
-                lifetime.to_string(),
-                Some(arg),
-                captures,
-                Some((param.param_ty_span, param.param_ty.to_string())),
-                self.infcx.tcx.is_suitable_region(f).map(|r| r.def_id),
+            if !fn_returns.is_empty() {
+                nice_region_error::suggest_new_region_bound(
+                    self.infcx.tcx,
+                    diag,
+                    fn_returns,
+                    lifetime.to_string(),
+                    Some(arg),
+                    captures,
+                    Some((param.param_ty_span, param.param_ty.to_string())),
+                    Some(suitable_region.def_id),
+                );
+                return;
+            }
+
+            let Some((alias_tys, alias_span)) = self
+                .infcx
+                .tcx
+                .return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id) else { return; };
+
+            // in case the return type of the method is a type alias
+            let mut spans_suggs: Vec<_> = Vec::new();
+            for alias_ty in alias_tys {
+                if alias_ty.span.desugaring_kind().is_some() {
+                    // Skip `async` desugaring `impl Future`.
+                    ()
+                }
+                if let TyKind::TraitObject(_, lt, _) = alias_ty.kind {
+                    spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
+                }
+            }
+            spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));
+            diag.multipart_suggestion_verbose(
+                &format!(
+                    "to declare that the trait object {captures}, you can add a lifetime parameter `'a` in the type alias"
+                ),
+                spans_suggs,
+                Applicability::MaybeIncorrect,
             );
         }
     }