diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2024-12-05 18:26:37 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-05 18:26:37 +0000 |
| commit | f31547dc0e1f22228f744266d331185e4dcb73ed (patch) | |
| tree | 01da4f226494fdaf1e2b90beae7a7bca796e384a | |
| parent | 0d8e5113d5b1171422dc7b235a2a76415147b4d6 (diff) | |
| parent | 64832b0ddb274bc752b1627c95fa0558d847e27d (diff) | |
| download | rust-f31547dc0e1f22228f744266d331185e4dcb73ed.tar.gz rust-f31547dc0e1f22228f744266d331185e4dcb73ed.zip | |
Merge pull request #18621 from Veykril/push-suuyuvsmqpyq
fix: Resolve generic parameters within use captures
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 {} +} +"#, + ); + } } |
