]> git.lizzy.rs Git - rust.git/blobdiff - crates/ide_assists/src/handlers/generate_delegate_methods.rs
Merge #11481
[rust.git] / crates / ide_assists / src / handlers / generate_delegate_methods.rs
index 233f26ed63707181b342316bd32c0114f2c5bded..31b438b15ec4b74785b8cb17206a3fd6495a9757 100644 (file)
@@ -1,5 +1,5 @@
-use hir::{self, HasCrate, HasSource};
-use syntax::ast::{self, make, AstNode, HasGenericParams, HasName, HasVisibility};
+use hir::{self, HasCrate, HasSource, HasVisibility};
+use syntax::ast::{self, make, AstNode, HasGenericParams, HasName, HasVisibility as _};
 
 use crate::{
     utils::{convert_param_list_to_arg_list, find_struct_impl, render_snippet, Cursor},
 pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
     let strukt = ctx.find_node_at_offset::<ast::Struct>()?;
     let strukt_name = strukt.name()?;
+    let current_module = ctx.sema.scope(strukt.syntax()).module()?;
 
-    let (field_name, field_ty) = match ctx.find_node_at_offset::<ast::RecordField>() {
+    let (field_name, field_ty, target) = match ctx.find_node_at_offset::<ast::RecordField>() {
         Some(field) => {
             let field_name = field.name()?;
             let field_ty = field.ty()?;
-            (format!("{}", field_name), field_ty)
+            (format!("{}", field_name), field_ty, field.syntax().text_range())
         }
         None => {
             let field = ctx.find_node_at_offset::<ast::TupleField>()?;
             let field_list = ctx.find_node_at_offset::<ast::TupleFieldList>()?;
             let field_list_index = field_list.fields().position(|it| it == field)?;
             let field_ty = field.ty()?;
-            (format!("{}", field_list_index), field_ty)
+            (format!("{}", field_list_index), field_ty, field.syntax().text_range())
         }
     };
 
@@ -66,14 +67,13 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
     let mut methods = vec![];
     sema_field_ty.iterate_assoc_items(ctx.db(), krate, |item| {
         if let hir::AssocItem::Function(f) = item {
-            if f.self_param(ctx.db()).is_some() {
+            if f.self_param(ctx.db()).is_some() && f.is_visible_from(ctx.db(), current_module) {
                 methods.push(f)
             }
         }
         Option::<()>::None
     });
 
-    let target = field_ty.syntax().text_range();
     for method in methods {
         let adt = ast::Adt::Struct(strukt.clone());
         let name = method.name(ctx.db()).to_string();
@@ -170,7 +170,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::check_assist;
+    use crate::tests::{check_assist, check_assist_not_applicable};
 
     use super::*;
 
@@ -311,4 +311,24 @@ impl<T> Person<T> {
 }"#,
         );
     }
+
+    #[test]
+    fn test_generate_delegate_visibility() {
+        check_assist_not_applicable(
+            generate_delegate_methods,
+            r#"
+mod m {
+    pub struct Age(u8);
+    impl Age {
+        fn age(&self) -> u8 {
+            self.0
+        }
+    }
+}
+
+struct Person {
+    ag$0e: m::Age,
+}"#,
+        )
+    }
 }