Merge pull request #21665 from raushan728/fix-param-name-bug

fix: prevent qualifying parameter names in add_missing_impl_members
This commit is contained in:
A4-Tacks
2026-02-19 05:23:19 +00:00
committed by GitHub
2 changed files with 197 additions and 0 deletions

View File

@@ -2534,6 +2534,86 @@ impl Test for () {
${0:todo!()}
}
}
"#,
);
}
#[test]
fn test_param_name_not_qualified() {
check_assist(
add_missing_impl_members,
r#"
mod ptr {
pub struct NonNull<T>(T);
}
mod alloc {
use super::ptr::NonNull;
pub trait Allocator {
unsafe fn deallocate(&self, ptr: NonNull<u8>);
}
}
struct System;
unsafe impl alloc::Allocator for System {
$0
}
"#,
r#"
mod ptr {
pub struct NonNull<T>(T);
}
mod alloc {
use super::ptr::NonNull;
pub trait Allocator {
unsafe fn deallocate(&self, ptr: NonNull<u8>);
}
}
struct System;
unsafe impl alloc::Allocator for System {
unsafe fn deallocate(&self, ptr: ptr::NonNull<u8>) {
${0:todo!()}
}
}
"#,
);
}
#[test]
fn test_param_name_shadows_module() {
check_assist(
add_missing_impl_members,
r#"
mod m { }
use m as p;
pub trait Allocator {
fn deallocate(&self, p: u8);
}
struct System;
impl Allocator for System {
$0
}
"#,
r#"
mod m { }
use m as p;
pub trait Allocator {
fn deallocate(&self, p: u8);
}
struct System;
impl Allocator for System {
fn deallocate(&self, p: u8) {
${0:todo!()}
}
}
"#,
);
}

View File

@@ -553,6 +553,39 @@ impl Ctx<'_> {
return None;
}
// Similarly, modules cannot be used in pattern position.
if matches!(def, hir::ModuleDef::Module(_)) {
return None;
}
if matches!(
def,
hir::ModuleDef::Function(_)
| hir::ModuleDef::Trait(_)
| hir::ModuleDef::TypeAlias(_)
) {
return None;
}
if let hir::ModuleDef::Adt(adt) = def {
match adt {
hir::Adt::Struct(s)
if s.kind(self.source_scope.db) != hir::StructKind::Unit =>
{
return None;
}
hir::Adt::Union(_) => return None,
hir::Adt::Enum(_) => return None,
_ => (),
}
}
if let hir::ModuleDef::Variant(v) = def
&& v.kind(self.source_scope.db) != hir::StructKind::Unit
{
return None;
}
let cfg = FindPathConfig {
prefer_no_std: false,
prefer_prelude: true,
@@ -632,3 +665,87 @@ fn find_trait_for_assoc_item(
None
}
#[cfg(test)]
mod tests {
use crate::RootDatabase;
use crate::path_transform::PathTransform;
use hir::Semantics;
use syntax::{AstNode, ast::HasName};
use test_fixture::WithFixture;
use test_utils::assert_eq_text;
#[test]
fn test_transform_ident_pat() {
let (db, file_id) = RootDatabase::with_single_file(
r#"
mod foo {
pub struct UnitStruct;
pub struct RecordStruct {}
pub enum Enum { UnitVariant, RecordVariant {} }
pub fn function() {}
pub const CONST: i32 = 0;
pub static STATIC: i32 = 0;
pub type Alias = i32;
pub union Union { f: i32 }
}
mod bar {
fn anchor() {}
}
fn main() {
use foo::*;
use foo::Enum::*;
let UnitStruct = ();
let RecordStruct = ();
let Enum = ();
let UnitVariant = ();
let RecordVariant = ();
let function = ();
let CONST = ();
let STATIC = ();
let Alias = ();
let Union = ();
}
"#,
);
let sema = Semantics::new(&db);
let source_file = sema.parse(file_id);
let function = source_file
.syntax()
.descendants()
.filter_map(syntax::ast::Fn::cast)
.find(|it| it.name().unwrap().text() == "main")
.unwrap();
let source_scope = sema.scope(function.body().unwrap().syntax()).unwrap();
let anchor = source_file
.syntax()
.descendants()
.filter_map(syntax::ast::Fn::cast)
.find(|it| it.name().unwrap().text() == "anchor")
.unwrap();
let target_scope = sema.scope(anchor.body().unwrap().syntax()).unwrap();
let transform = PathTransform::generic_transformation(&target_scope, &source_scope);
let transformed = transform.apply(function.body().unwrap().syntax());
let expected = r#"{
use crate::foo::*;
use crate::foo::Enum::*;
let crate::foo::UnitStruct = ();
let RecordStruct = ();
let Enum = ();
let crate::foo::Enum::UnitVariant = ();
let RecordVariant = ();
let function = ();
let crate::foo::CONST = ();
let crate::foo::STATIC = ();
let Alias = ();
let Union = ();
}"#;
assert_eq_text!(expected, &transformed.to_string());
}
}