]> git.lizzy.rs Git - rust.git/commitdiff
Fix completion of trait items
authorFlorian Diebold <flodiebold@gmail.com>
Sat, 14 Mar 2020 19:48:36 +0000 (20:48 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Sat, 14 Mar 2020 19:48:36 +0000 (20:48 +0100)
Trait items should be public by default.

crates/ra_hir_def/src/data.rs
crates/ra_hir_def/src/visibility.rs
crates/ra_ide/src/completion/complete_dot.rs

index a72eb53690a5df58ad8a978e99956fd29e57492c..85df07e607cf2d395bcae7d2d1384e99da3b47ec 100644 (file)
@@ -34,7 +34,8 @@ pub struct FunctionData {
 
 impl FunctionData {
     pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> {
-        let src = func.lookup(db).source(db);
+        let loc = func.lookup(db);
+        let src = loc.source(db);
         let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
         let mut params = Vec::new();
         let mut has_self_param = false;
@@ -76,7 +77,9 @@ pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<Func
             ret_type
         };
 
-        let visibility = RawVisibility::from_ast(db, src.map(|s| s.visibility()));
+        let vis_default = RawVisibility::default_for_container(loc.container);
+        let visibility =
+            RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility()));
 
         let sig = FunctionData { name, params, ret_type, has_self_param, visibility };
         Arc::new(sig)
@@ -105,10 +108,13 @@ pub(crate) fn type_alias_data_query(
         db: &impl DefDatabase,
         typ: TypeAliasId,
     ) -> Arc<TypeAliasData> {
-        let node = typ.lookup(db).source(db);
+        let loc = typ.lookup(db);
+        let node = loc.source(db);
         let name = node.value.name().map_or_else(Name::missing, |n| n.as_name());
         let type_ref = node.value.type_ref().map(TypeRef::from_ast);
-        let visibility = RawVisibility::from_ast(db, node.map(|n| n.visibility()));
+        let vis_default = RawVisibility::default_for_container(loc.container);
+        let visibility =
+            RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility()));
         Arc::new(TypeAliasData { name, type_ref, visibility })
     }
 }
@@ -230,22 +236,26 @@ pub struct ConstData {
 
 impl ConstData {
     pub(crate) fn const_data_query(db: &impl DefDatabase, konst: ConstId) -> Arc<ConstData> {
-        let node = konst.lookup(db).source(db);
-        Arc::new(ConstData::new(db, node))
+        let loc = konst.lookup(db);
+        let node = loc.source(db);
+        let vis_default = RawVisibility::default_for_container(loc.container);
+        Arc::new(ConstData::new(db, vis_default, node))
     }
 
     pub(crate) fn static_data_query(db: &impl DefDatabase, konst: StaticId) -> Arc<ConstData> {
         let node = konst.lookup(db).source(db);
-        Arc::new(ConstData::new(db, node))
+        Arc::new(ConstData::new(db, RawVisibility::private(), node))
     }
 
     fn new<N: NameOwner + TypeAscriptionOwner + VisibilityOwner>(
         db: &impl DefDatabase,
+        vis_default: RawVisibility,
         node: InFile<N>,
     ) -> ConstData {
         let name = node.value.name().map(|n| n.as_name());
         let type_ref = TypeRef::from_ast_opt(node.value.ascribed_type());
-        let visibility = RawVisibility::from_ast(db, node.map(|n| n.visibility()));
+        let visibility =
+            RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility()));
         ConstData { name, type_ref, visibility }
     }
 }
index d8296da4b60b2a8a60d742c465ea8a52144764e2..e0c59e9056dba04bcec7e972b981ed102e27035b 100644 (file)
@@ -6,7 +6,7 @@
 use crate::{
     db::DefDatabase,
     path::{ModPath, PathKind},
-    ModuleId,
+    AssocContainerId, ModuleId,
 };
 
 /// Visibility of an item, not yet resolved.
@@ -20,11 +20,30 @@ pub enum RawVisibility {
 }
 
 impl RawVisibility {
-    const fn private() -> RawVisibility {
+    pub(crate) const fn private() -> RawVisibility {
         let path = ModPath { kind: PathKind::Super(0), segments: Vec::new() };
         RawVisibility::Module(path)
     }
 
+    pub(crate) fn default_for_container(container_id: AssocContainerId) -> Self {
+        match container_id {
+            AssocContainerId::TraitId(_) => RawVisibility::Public,
+            _ => RawVisibility::private(),
+        }
+    }
+
+    pub(crate) fn from_ast_with_default(
+        db: &impl DefDatabase,
+        default: RawVisibility,
+        node: InFile<Option<ast::Visibility>>,
+    ) -> RawVisibility {
+        Self::from_ast_with_hygiene_and_default(
+            node.value,
+            default,
+            &Hygiene::new(db, node.file_id),
+        )
+    }
+
     pub(crate) fn from_ast(
         db: &impl DefDatabase,
         node: InFile<Option<ast::Visibility>>,
@@ -35,9 +54,17 @@ pub(crate) fn from_ast(
     pub(crate) fn from_ast_with_hygiene(
         node: Option<ast::Visibility>,
         hygiene: &Hygiene,
+    ) -> RawVisibility {
+        Self::from_ast_with_hygiene_and_default(node, RawVisibility::private(), hygiene)
+    }
+
+    pub(crate) fn from_ast_with_hygiene_and_default(
+        node: Option<ast::Visibility>,
+        default: RawVisibility,
+        hygiene: &Hygiene,
     ) -> RawVisibility {
         let node = match node {
-            None => return RawVisibility::private(),
+            None => return default,
             Some(node) => node,
         };
         match node.kind() {
index 81e5037aa149e88ebfc5de8bf9c7493a1732afb9..f07611d88dfa924becc3bfdc4771d90e73dd1a4d 100644 (file)
@@ -401,6 +401,38 @@ fn foo(a: &A) {
         );
     }
 
+    #[test]
+    fn completes_trait_method_from_other_module() {
+        assert_debug_snapshot!(
+            do_ref_completion(
+                r"
+            struct A {}
+            mod m {
+                pub trait Trait { fn the_method(&self); }
+            }
+            use m::Trait;
+            impl Trait for A {}
+            fn foo(a: A) {
+               a.<|>
+            }
+            ",
+            ),
+            @r###"
+        [
+            CompletionItem {
+                label: "the_method()",
+                source_range: [219; 219),
+                delete: [219; 219),
+                insert: "the_method()$0",
+                kind: Method,
+                lookup: "the_method",
+                detail: "fn the_method(&self)",
+            },
+        ]
+        "###
+        );
+    }
+
     #[test]
     fn test_no_non_self_method() {
         assert_debug_snapshot!(