about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-11-15 20:09:19 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-11-20 23:44:37 +0000
commitbb9d720a161221dac6ad7f0fb1cb5e94ab157ab2 (patch)
tree638eaac17367b94247ac83e204f356abeca8cd7c
parent85f26ade8dc3364f29a2c0b0d8f5fe2068df8969 (diff)
downloadrust-bb9d720a161221dac6ad7f0fb1cb5e94ab157ab2.tar.gz
rust-bb9d720a161221dac6ad7f0fb1cb5e94ab157ab2.zip
Do not consider traits as ownable in suggestion
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs62
-rw-r--r--tests/ui/suggestions/missing-lifetime-specifier.stderr5
2 files changed, 55 insertions, 12 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index f7560d9949b..86846aa214a 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -3105,15 +3105,63 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                                 owned_sugg = true;
                             }
                             if let Some(ty) = lt_finder.found {
-                                if let TyKind::Path(None, Path { segments, .. }) = &ty.kind
+                                if let TyKind::Path(None, path @ Path { segments, .. }) = &ty.kind
                                     && segments.len() == 1
-                                    && segments[0].ident.name == sym::str
                                 {
-                                    // Don't suggest `-> str`, suggest `-> String`.
-                                    sugg = vec![
-                                        (lt.span.with_hi(ty.span.hi()), "String".to_string()),
-                                    ];
-                                } else if let TyKind::Slice(inner_ty) = &ty.kind {
+                                    if segments[0].ident.name == sym::str {
+                                        // Don't suggest `-> str`, suggest `-> String`.
+                                        sugg = vec![
+                                            (lt.span.with_hi(ty.span.hi()), "String".to_string()),
+                                        ];
+                                    } else {
+                                        // Check if the path being borrowed is likely to be owned.
+                                        let path: Vec<_> = Segment::from_path(path);
+                                        match self.resolve_path(&path, Some(TypeNS), None) {
+                                            PathResult::Module(
+                                                ModuleOrUniformRoot::Module(module),
+                                            ) => {
+                                                match module.res() {
+                                                    Some(Res::PrimTy(..)) => {}
+                                                    Some(Res::Def(
+                                                        DefKind::Struct
+                                                        | DefKind::Union
+                                                        | DefKind::Enum
+                                                        | DefKind::ForeignTy
+                                                        | DefKind::AssocTy
+                                                        | DefKind::OpaqueTy
+                                                        | DefKind::TyParam,
+                                                        _,
+                                                    )) => {}
+                                                    _ => { // Do not suggest in all other cases.
+                                                        owned_sugg = false;
+                                                    }
+                                                }
+                                            }
+                                            PathResult::NonModule(res) => {
+                                                match res.base_res() {
+                                                    Res::PrimTy(..) => {}
+                                                    Res::Def(
+                                                        DefKind::Struct
+                                                        | DefKind::Union
+                                                        | DefKind::Enum
+                                                        | DefKind::ForeignTy
+                                                        | DefKind::AssocTy
+                                                        | DefKind::OpaqueTy
+                                                        | DefKind::TyParam,
+                                                        _,
+                                                    ) => {}
+                                                    _ => { // Do not suggest in all other cases.
+                                                        owned_sugg = false;
+                                                    }
+                                                }
+                                            }
+                                            _ => { // Do not suggest in all other cases.
+                                                owned_sugg = false;
+                                            }
+                                        }
+                                    }
+                                }
+                                if let TyKind::Slice(inner_ty) = &ty.kind {
                                     // Don't suggest `-> [T]`, suggest `-> Vec<T>`.
                                     sugg = vec![
                                         (lt.span.with_hi(inner_ty.span.lo()), "Vec<".to_string()),
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr
index 484a9b3ad8d..e41f547ce9b 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.stderr
+++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr
@@ -117,11 +117,6 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                             +++++++
-help: instead, you are more likely to want to return an owned value
-   |
-LL -     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
-LL +     static f: RefCell<HashMap<i32, Vec<Vec<Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
-   |
 
 error[E0106]: missing lifetime specifier
   --> $DIR/missing-lifetime-specifier.rs:47:44