about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-12-05 18:26:37 +0000
committerGitHub <noreply@github.com>2024-12-05 18:26:37 +0000
commitf31547dc0e1f22228f744266d331185e4dcb73ed (patch)
tree01da4f226494fdaf1e2b90beae7a7bca796e384a
parent0d8e5113d5b1171422dc7b235a2a76415147b4d6 (diff)
parent64832b0ddb274bc752b1627c95fa0558d847e27d (diff)
downloadrust-f31547dc0e1f22228f744266d331185e4dcb73ed.tar.gz
rust-f31547dc0e1f22228f744266d331185e4dcb73ed.zip
Merge pull request #18621 from Veykril/push-suuyuvsmqpyq
fix: Resolve generic parameters within use captures
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/defs.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/rename.rs69
5 files changed, 90 insertions, 2 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index 0ca7070fd05..316406c151f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -642,9 +642,9 @@ impl Resolver {
         })
     }
 
-    pub fn generic_params(&self) -> Option<&Arc<GenericParams>> {
+    pub fn generic_params(&self) -> Option<&GenericParams> {
         self.scopes().find_map(|scope| match scope {
-            Scope::GenericParams { params, .. } => Some(params),
+            Scope::GenericParams { params, .. } => Some(&**params),
             _ => None,
         })
     }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index 0b09cf27926..f9d3f9d07e6 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -1517,6 +1517,10 @@ impl<'db> SemanticsImpl<'db> {
         self.analyze(path.syntax())?.resolve_path(self.db, path)
     }
 
+    pub fn resolve_use_type_arg(&self, name: &ast::NameRef) -> Option<TypeParam> {
+        self.analyze(name.syntax())?.resolve_use_type_arg(name)
+    }
+
     pub fn resolve_mod_path(
         &self,
         scope: &SyntaxNode,
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 56ed81f053c..4329a888b39 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -642,6 +642,14 @@ impl SourceAnalyzer {
         }
     }
 
+    pub(crate) fn resolve_use_type_arg(&self, name: &ast::NameRef) -> Option<crate::TypeParam> {
+        let name = name.as_name();
+        self.resolver
+            .all_generic_params()
+            .find_map(|(params, parent)| params.find_type_by_name(&name, *parent))
+            .map(crate::TypeParam::from)
+    }
+
     pub(crate) fn resolve_path(
         &self,
         db: &dyn HirDatabase,
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
index 5eec33636be..932ca373020 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
@@ -733,6 +733,12 @@ impl NameRefClass {
                     }
                     None
                 },
+                ast::UseBoundGenericArgs(_) => {
+                    sema.resolve_use_type_arg(name_ref)
+                        .map(GenericParam::TypeParam)
+                        .map(Definition::GenericParam)
+                        .map(NameRefClass::Definition)
+                },
                 ast::ExternCrate(extern_crate_ast) => {
                     let extern_crate = sema.to_def(&extern_crate_ast)?;
                     let krate = extern_crate.resolved_crate(sema.db)?;
@@ -764,6 +770,7 @@ impl NameRefClass {
                 sema.resolve_label(lifetime).map(Definition::Label).map(NameRefClass::Definition)
             }
             SyntaxKind::LIFETIME_ARG
+            | SyntaxKind::USE_BOUND_GENERIC_ARGS
             | SyntaxKind::SELF_PARAM
             | SyntaxKind::TYPE_BOUND
             | SyntaxKind::WHERE_PRED
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index 665fc954d23..a9519c03b32 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -3105,4 +3105,73 @@ fn main() { let _: Baz; }
 "#,
         );
     }
+
+    #[test]
+    fn rename_type_param_ref_in_use_bound() {
+        check(
+            "U",
+            r#"
+fn foo<T>() -> impl use<T$0> Trait {}
+"#,
+            r#"
+fn foo<U>() -> impl use<U> Trait {}
+"#,
+        );
+    }
+
+    #[test]
+    fn rename_type_param_in_use_bound() {
+        check(
+            "U",
+            r#"
+fn foo<T$0>() -> impl use<T> Trait {}
+"#,
+            r#"
+fn foo<U>() -> impl use<U> Trait {}
+"#,
+        );
+    }
+
+    #[test]
+    fn rename_lifetime_param_ref_in_use_bound() {
+        check(
+            "u",
+            r#"
+fn foo<'t>() -> impl use<'t$0> Trait {}
+"#,
+            r#"
+fn foo<'u>() -> impl use<'u> Trait {}
+"#,
+        );
+    }
+
+    #[test]
+    fn rename_lifetime_param_in_use_bound() {
+        check(
+            "u",
+            r#"
+fn foo<'t$0>() -> impl use<'t> Trait {}
+"#,
+            r#"
+fn foo<'u>() -> impl use<'u> Trait {}
+"#,
+        );
+    }
+
+    #[test]
+    fn rename_parent_type_param_in_use_bound() {
+        check(
+            "U",
+            r#"
+trait Trait<T> {
+    fn foo() -> impl use<T$0> Trait {}
+}
+"#,
+            r#"
+trait Trait<U> {
+    fn foo() -> impl use<U> Trait {}
+}
+"#,
+        );
+    }
 }