mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2026-03-27 20:40:59 +00:00
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:
@@ -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!()}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user