about summary refs log tree commit diff
diff options
context:
space:
mode:
authorfeniljain <fkjainco@gmail.com>2022-07-10 14:08:49 +0530
committerfeniljain <fkjainco@gmail.com>2022-07-14 17:07:43 +0530
commit4cbde4ed8f9764e0ecf922279f26613fa3edca54 (patch)
treed17735335cfe162a9f8d3bd2c113014f35dbce23
parent5342f47f4276641ddb5f0a5e08fb307742d6cdc4 (diff)
downloadrust-4cbde4ed8f9764e0ecf922279f26613fa3edca54.tar.gz
rust-4cbde4ed8f9764e0ecf922279f26613fa3edca54.zip
fix(completion): `super::` completion at crate root and module depth
aware
-rw-r--r--crates/ide-completion/src/completions.rs24
-rw-r--r--crates/ide-completion/src/completions/attribute.rs6
-rw-r--r--crates/ide-completion/src/completions/attribute/derive.rs6
-rw-r--r--crates/ide-completion/src/completions/item_list.rs6
-rw-r--r--crates/ide-completion/src/completions/pattern.rs6
-rw-r--r--crates/ide-completion/src/completions/use_.rs7
-rw-r--r--crates/ide-completion/src/completions/vis.rs6
-rw-r--r--crates/ide-completion/src/context.rs24
-rw-r--r--crates/ide-completion/src/context/analysis.rs23
-rw-r--r--crates/ide-completion/src/tests/attribute.rs26
-rw-r--r--crates/ide-completion/src/tests/expression.rs12
-rw-r--r--crates/ide-completion/src/tests/item.rs2
-rw-r--r--crates/ide-completion/src/tests/item_list.rs6
-rw-r--r--crates/ide-completion/src/tests/pattern.rs2
-rw-r--r--crates/ide-completion/src/tests/predicate.rs6
-rw-r--r--crates/ide-completion/src/tests/record.rs1
-rw-r--r--crates/ide-completion/src/tests/type_pos.rs20
-rw-r--r--crates/ide-completion/src/tests/use_tree.rs67
-rw-r--r--crates/ide-completion/src/tests/visibility.rs2
19 files changed, 140 insertions, 112 deletions
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index 1bcbb3aaa65..b254e458eb5 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -91,11 +91,31 @@ impl Completions {
     }
 
     pub(crate) fn add_nameref_keywords_with_colon(&mut self, ctx: &CompletionContext) {
-        ["self::", "super::", "crate::"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
+        ["self::", "crate::"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
+
+        if ctx.depth_from_crate_root > 0 {
+            self.add_keyword(ctx, "super::");
+        }
     }
 
     pub(crate) fn add_nameref_keywords(&mut self, ctx: &CompletionContext) {
-        ["self", "super", "crate"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
+        ["self", "crate"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
+
+        if ctx.depth_from_crate_root > 0 {
+            self.add_keyword(ctx, "super");
+        }
+    }
+
+    pub(crate) fn add_super_keyword(
+        &mut self,
+        ctx: &CompletionContext,
+        super_chain_len: Option<usize>,
+    ) {
+        if let Some(len) = super_chain_len {
+            if len > 0 && len < ctx.depth_from_crate_root {
+                self.add_keyword(ctx, "super::");
+            }
+        }
     }
 
     pub(crate) fn add_keyword_snippet_expr(
diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs
index 2de33a73622..cbf40e91344 100644
--- a/crates/ide-completion/src/completions/attribute.rs
+++ b/crates/ide-completion/src/completions/attribute.rs
@@ -82,12 +82,10 @@ pub(crate) fn complete_attribute_path(
     match qualified {
         Qualified::With {
             resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
-            is_super_chain,
+            super_chain_len,
             ..
         } => {
-            if *is_super_chain {
-                acc.add_keyword(ctx, "super::");
-            }
+            acc.add_super_keyword(ctx, *super_chain_len);
 
             for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
                 match def {
diff --git a/crates/ide-completion/src/completions/attribute/derive.rs b/crates/ide-completion/src/completions/attribute/derive.rs
index 48eb76029ff..b3cc1826a6e 100644
--- a/crates/ide-completion/src/completions/attribute/derive.rs
+++ b/crates/ide-completion/src/completions/attribute/derive.rs
@@ -21,12 +21,10 @@ pub(crate) fn complete_derive_path(
     match qualified {
         Qualified::With {
             resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
-            is_super_chain,
+            super_chain_len,
             ..
         } => {
-            if *is_super_chain {
-                acc.add_keyword(ctx, "super::");
-            }
+            acc.add_super_keyword(ctx, *super_chain_len);
 
             for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
                 match def {
diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs
index 4a32e0ebf58..43b48993902 100644
--- a/crates/ide-completion/src/completions/item_list.rs
+++ b/crates/ide-completion/src/completions/item_list.rs
@@ -36,7 +36,7 @@ pub(crate) fn complete_item_list(
     match qualified {
         Qualified::With {
             resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
-            is_super_chain,
+            super_chain_len,
             ..
         } => {
             for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
@@ -51,9 +51,7 @@ pub(crate) fn complete_item_list(
                 }
             }
 
-            if *is_super_chain {
-                acc.add_keyword(ctx, "super::");
-            }
+            acc.add_super_keyword(ctx, *super_chain_len);
         }
         Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
         Qualified::No if ctx.qualifier_ctx.none() => {
diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs
index 65b6eee1888..8d7fbc6627a 100644
--- a/crates/ide-completion/src/completions/pattern.rs
+++ b/crates/ide-completion/src/completions/pattern.rs
@@ -111,10 +111,8 @@ pub(crate) fn complete_pattern_path(
     path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx,
 ) {
     match qualified {
-        Qualified::With { resolution: Some(resolution), is_super_chain, .. } => {
-            if *is_super_chain {
-                acc.add_keyword(ctx, "super::");
-            }
+        Qualified::With { resolution: Some(resolution), super_chain_len, .. } => {
+            acc.add_super_keyword(ctx, *super_chain_len);
 
             match resolution {
                 hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {
diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs
index e5689f332dd..d4827771ad7 100644
--- a/crates/ide-completion/src/completions/use_.rs
+++ b/crates/ide-completion/src/completions/use_.rs
@@ -17,10 +17,9 @@ pub(crate) fn complete_use_path(
     name_ref: &Option<ast::NameRef>,
 ) {
     match qualified {
-        Qualified::With { path, resolution: Some(resolution), is_super_chain } => {
-            if *is_super_chain {
-                acc.add_keyword(ctx, "super::");
-            }
+        Qualified::With { path, resolution: Some(resolution), super_chain_len } => {
+            acc.add_super_keyword(ctx, *super_chain_len);
+
             // only show `self` in a new use-tree when the qualifier doesn't end in self
             let not_preceded_by_self = *use_tree_parent
                 && !matches!(
diff --git a/crates/ide-completion/src/completions/vis.rs b/crates/ide-completion/src/completions/vis.rs
index 6621aafe4bd..39028eca41c 100644
--- a/crates/ide-completion/src/completions/vis.rs
+++ b/crates/ide-completion/src/completions/vis.rs
@@ -14,7 +14,7 @@ pub(crate) fn complete_vis_path(
     match qualified {
         Qualified::With {
             resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
-            is_super_chain,
+            super_chain_len,
             ..
         } => {
             // Try completing next child module of the path that is still a parent of the current module
@@ -27,9 +27,7 @@ pub(crate) fn complete_vis_path(
                 }
             }
 
-            if *is_super_chain {
-                acc.add_keyword(ctx, "super::");
-            }
+            acc.add_super_keyword(ctx, *super_chain_len);
         }
         Qualified::Absolute | Qualified::Infer | Qualified::With { .. } => {}
         Qualified::No => {
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index b371c978808..c93fd0d7bb0 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -4,6 +4,8 @@ mod analysis;
 #[cfg(test)]
 mod tests;
 
+use std::iter;
+
 use base_db::SourceDatabaseExt;
 use hir::{
     HasAttrs, Local, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo,
@@ -174,8 +176,17 @@ pub(super) enum Qualified {
     With {
         path: ast::Path,
         resolution: Option<PathResolution>,
-        /// Whether this path consists solely of `super` segments
-        is_super_chain: bool,
+        /// How many `super` segments are present in the path
+        ///
+        /// This would be None, if path is not solely made of
+        /// `super` segments, e.g.
+        ///
+        /// ```rust
+        ///   use super::foo;
+        /// ```
+        ///
+        /// Otherwise it should be Some(count of `super`)
+        super_chain_len: Option<usize>,
     },
     /// <_>::
     Infer,
@@ -343,6 +354,12 @@ pub(crate) struct CompletionContext<'a> {
     pub(super) qualifier_ctx: QualifierCtx,
 
     pub(super) locals: FxHashMap<Name, Local>,
+
+    /// - crate-root
+    ///  - mod foo
+    ///   - mod bar
+    /// Here depth will be 2: {[bar<->foo], [foo<->crate-root]}
+    pub(super) depth_from_crate_root: usize,
 }
 
 impl<'a> CompletionContext<'a> {
@@ -521,6 +538,8 @@ impl<'a> CompletionContext<'a> {
             }
         });
 
+        let depth_from_crate_root = iter::successors(module.parent(db), |m| m.parent(db)).count();
+
         let mut ctx = CompletionContext {
             sema,
             scope,
@@ -535,6 +554,7 @@ impl<'a> CompletionContext<'a> {
             expected_type: None,
             qualifier_ctx: Default::default(),
             locals,
+            depth_from_crate_root,
         };
         let ident_ctx = ctx.expand_and_analyze(
             original_file.syntax().clone(),
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs
index e13950d56a9..7fc77aae91f 100644
--- a/crates/ide-completion/src/context/analysis.rs
+++ b/crates/ide-completion/src/context/analysis.rs
@@ -899,10 +899,25 @@ impl<'a> CompletionContext<'a> {
                         Qualified::Infer
                     } else {
                         let res = sema.resolve_path(&path);
-                        let is_super_chain =
-                            iter::successors(Some(path.clone()), |p| p.qualifier())
-                                .all(|p| p.segment().and_then(|s| s.super_token()).is_some());
-                        Qualified::With { path, resolution: res, is_super_chain }
+
+                        // For understanding how and why super_chain_len is calculated the way it
+                        // is check the documentation at it's definition
+                        let mut segment_count = 0;
+                        let super_count = iter::successors(Some(path.clone()), |p| p.qualifier())
+                            .take_while(|p| {
+                                p.segment()
+                                    .and_then(|s| {
+                                        segment_count += 1;
+                                        s.super_token()
+                                    })
+                                    .is_some()
+                            })
+                            .count();
+
+                        let super_chain_len =
+                            if segment_count > super_count { None } else { Some(super_count) };
+
+                        Qualified::With { path, resolution: res, super_chain_len }
                     }
                 };
             }
diff --git a/crates/ide-completion/src/tests/attribute.rs b/crates/ide-completion/src/tests/attribute.rs
index 3b366c94bf0..1578ba2c377 100644
--- a/crates/ide-completion/src/tests/attribute.rs
+++ b/crates/ide-completion/src/tests/attribute.rs
@@ -35,7 +35,6 @@ struct Foo;
             md proc_macros
             kw crate::
             kw self::
-            kw super::
         "#]],
     )
 }
@@ -85,7 +84,6 @@ fn with_existing_attr() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     )
 }
@@ -117,7 +115,6 @@ fn attr_on_source_file() {
             at windows_subsystem = "…"
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -190,7 +187,6 @@ fn attr_on_macro_rules() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -214,7 +210,6 @@ fn attr_on_macro_def() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -239,7 +234,6 @@ fn attr_on_extern_crate() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -263,7 +257,6 @@ fn attr_on_use() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -287,7 +280,6 @@ fn attr_on_type_alias() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -320,7 +312,6 @@ struct Foo;
             md core
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -347,7 +338,6 @@ fn attr_on_enum() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -371,7 +361,6 @@ fn attr_on_const() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -400,7 +389,6 @@ fn attr_on_static() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -425,7 +413,6 @@ fn attr_on_trait() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -450,7 +437,6 @@ fn attr_on_impl() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
     check(
@@ -470,7 +456,6 @@ fn attr_on_impl() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -495,7 +480,6 @@ fn attr_on_extern_block() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
     check(
@@ -516,7 +500,6 @@ fn attr_on_extern_block() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -535,7 +518,6 @@ fn attr_on_variant() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -574,7 +556,6 @@ fn attr_on_fn() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -622,7 +603,6 @@ fn attr_in_source_file_end() {
             at warn(…)
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -679,7 +659,6 @@ mod derive {
                 md core
                 kw crate::
                 kw self::
-                kw super::
             "#]],
         );
     }
@@ -701,7 +680,6 @@ mod derive {
                 md core
                 kw crate::
                 kw self::
-                kw super::
             "#]],
         )
     }
@@ -723,7 +701,6 @@ mod derive {
                 md core
                 kw crate::
                 kw self::
-                kw super::
             "#]],
         );
     }
@@ -744,7 +721,6 @@ mod derive {
                 md core
                 kw crate::
                 kw self::
-                kw super::
             "#]],
         );
     }
@@ -763,7 +739,6 @@ mod derive {
                 md proc_macros
                 kw crate::
                 kw self::
-                kw super::
             "#]],
         );
         check_derive(
@@ -779,7 +754,6 @@ use proc_macros::DeriveIdentity;
                 md proc_macros
                 kw crate::
                 kw self::
-                kw super::
             "#]],
         );
     }
diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs
index c05a7ad9fa5..ce9d01d337b 100644
--- a/crates/ide-completion/src/tests/expression.rs
+++ b/crates/ide-completion/src/tests/expression.rs
@@ -58,7 +58,6 @@ fn baz() {
             kw mut
             kw return
             kw self::
-            kw super::
             kw true
             kw unsafe
             kw while
@@ -100,7 +99,6 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
             kw match
             kw return
             kw self::
-            kw super::
             kw true
             kw unsafe
             kw while
@@ -162,7 +160,6 @@ impl Unit {
             kw self::
             kw static
             kw struct
-            kw super::
             kw trait
             kw true
             kw type
@@ -240,7 +237,6 @@ fn complete_in_block() {
             kw self::
             kw static
             kw struct
-            kw super::
             kw trait
             kw true
             kw type
@@ -288,7 +284,6 @@ fn complete_after_if_expr() {
             kw self::
             kw static
             kw struct
-            kw super::
             kw trait
             kw true
             kw type
@@ -326,7 +321,6 @@ fn complete_in_match_arm() {
             kw match
             kw return
             kw self::
-            kw super::
             kw true
             kw unsafe
             kw while
@@ -362,7 +356,6 @@ fn completes_in_loop_ctx() {
             kw self::
             kw static
             kw struct
-            kw super::
             kw trait
             kw true
             kw type
@@ -394,7 +387,6 @@ fn completes_in_let_initializer() {
             kw match
             kw return
             kw self::
-            kw super::
             kw true
             kw unsafe
             kw while
@@ -429,7 +421,6 @@ fn foo() {
             kw match
             kw return
             kw self::
-            kw super::
             kw true
             kw unsafe
             kw while
@@ -465,7 +456,6 @@ fn foo() {
             kw match
             kw return
             kw self::
-            kw super::
             kw true
             kw unsafe
             kw while
@@ -497,7 +487,6 @@ fn quux(x: i32) {
             kw match
             kw return
             kw self::
-            kw super::
             kw true
             kw unsafe
             kw while
@@ -525,7 +514,6 @@ fn quux(x: i32) {
             kw match
             kw return
             kw self::
-            kw super::
             kw true
             kw unsafe
             kw while
diff --git a/crates/ide-completion/src/tests/item.rs b/crates/ide-completion/src/tests/item.rs
index 81303eb38f4..409413c1dcd 100644
--- a/crates/ide-completion/src/tests/item.rs
+++ b/crates/ide-completion/src/tests/item.rs
@@ -29,7 +29,6 @@ impl Tra$0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     )
 }
@@ -52,7 +51,6 @@ impl Trait for Str$0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     )
 }
diff --git a/crates/ide-completion/src/tests/item_list.rs b/crates/ide-completion/src/tests/item_list.rs
index 09ea78a3d50..5076c6e86ca 100644
--- a/crates/ide-completion/src/tests/item_list.rs
+++ b/crates/ide-completion/src/tests/item_list.rs
@@ -60,7 +60,6 @@ fn in_source_file_item_list() {
             kw self::
             kw static
             kw struct
-            kw super::
             kw trait
             kw type
             kw union
@@ -93,7 +92,6 @@ fn in_item_list_after_attr() {
             kw self::
             kw static
             kw struct
-            kw super::
             kw trait
             kw type
             kw union
@@ -175,7 +173,6 @@ fn in_impl_assoc_item_list() {
             kw pub(crate)
             kw pub(super)
             kw self::
-            kw super::
             kw unsafe
         "#]],
     )
@@ -195,7 +192,6 @@ fn in_impl_assoc_item_list_after_attr() {
             kw pub(crate)
             kw pub(super)
             kw self::
-            kw super::
             kw unsafe
         "#]],
     )
@@ -212,7 +208,6 @@ fn in_trait_assoc_item_list() {
             kw crate::
             kw fn
             kw self::
-            kw super::
             kw type
             kw unsafe
         "#]],
@@ -247,7 +242,6 @@ impl Test for () {
             ta type Type1 =
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
diff --git a/crates/ide-completion/src/tests/pattern.rs b/crates/ide-completion/src/tests/pattern.rs
index 63ccf9003b4..18088680660 100644
--- a/crates/ide-completion/src/tests/pattern.rs
+++ b/crates/ide-completion/src/tests/pattern.rs
@@ -414,7 +414,6 @@ fn foo() {
             st Bar
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
     check_empty(
@@ -430,7 +429,6 @@ fn foo() {
             st Foo
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
     check_empty(
diff --git a/crates/ide-completion/src/tests/predicate.rs b/crates/ide-completion/src/tests/predicate.rs
index f2b9c061dc5..a8676e2f247 100644
--- a/crates/ide-completion/src/tests/predicate.rs
+++ b/crates/ide-completion/src/tests/predicate.rs
@@ -28,7 +28,6 @@ struct Foo<'lt, T, const C: usize> where $0 {}
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -45,7 +44,6 @@ struct Foo<'lt, T, const C: usize> where T: $0 {}
             tt Trait
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -64,7 +62,6 @@ struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
             tt Trait
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -81,7 +78,6 @@ struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
             tt Trait
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -105,7 +101,6 @@ struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -131,7 +126,6 @@ impl Record {
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs
index d9b31832085..ec32602fa3c 100644
--- a/crates/ide-completion/src/tests/record.rs
+++ b/crates/ide-completion/src/tests/record.rs
@@ -171,7 +171,6 @@ fn main() {
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
     check(
diff --git a/crates/ide-completion/src/tests/type_pos.rs b/crates/ide-completion/src/tests/type_pos.rs
index fcd4743f74f..f0b7726c51d 100644
--- a/crates/ide-completion/src/tests/type_pos.rs
+++ b/crates/ide-completion/src/tests/type_pos.rs
@@ -31,7 +31,6 @@ struct Foo<'lt, T, const C: usize> {
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     )
 }
@@ -60,7 +59,6 @@ struct Foo<'lt, T, const C: usize>(f$0);
             kw pub(crate)
             kw pub(super)
             kw self::
-            kw super::
         "#]],
     )
 }
@@ -84,7 +82,6 @@ fn x<'lt, T, const C: usize>() -> $0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -115,7 +112,6 @@ fn foo() -> B$0 {
         it ()
         kw crate::
         kw self::
-        kw super::
     "#]],
     )
 }
@@ -141,7 +137,6 @@ const FOO: $0 = Foo(2);
             it Foo<i32>
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -168,7 +163,6 @@ fn f2() {
             it i32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -197,7 +191,6 @@ fn f2() {
             it u64
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -223,7 +216,6 @@ fn f2(x: u64) -> $0 {
             it u64
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -250,7 +242,6 @@ fn f2(x: $0) {
             it i32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -285,7 +276,6 @@ fn foo<'lt, T, const C: usize>() {
             it a::Foo<a::Foo<i32>>
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -315,7 +305,6 @@ fn foo<'lt, T, const C: usize>() {
             it Foo<i32>
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -342,7 +331,6 @@ fn foo<'lt, T, const C: usize>() {
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
     check(
@@ -412,7 +400,6 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
     check(
@@ -465,7 +452,6 @@ impl Tr<$0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -512,7 +498,6 @@ fn f(t: impl MyTrait<u$0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 
@@ -539,7 +524,6 @@ fn f(t: impl MyTrait<u8, u$0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 
@@ -584,7 +568,6 @@ fn f(t: impl MyTrait<u$0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 
@@ -613,7 +596,6 @@ fn f(t: impl MyTrait<u8, u$0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 
@@ -658,7 +640,6 @@ fn f(t: impl MyTrait<Item1 = $0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 
@@ -685,7 +666,6 @@ fn f(t: impl MyTrait<Item1 = u8, Item2 = $0
             bt u32
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
diff --git a/crates/ide-completion/src/tests/use_tree.rs b/crates/ide-completion/src/tests/use_tree.rs
index 109007c7a07..037d7dce52e 100644
--- a/crates/ide-completion/src/tests/use_tree.rs
+++ b/crates/ide-completion/src/tests/use_tree.rs
@@ -31,7 +31,6 @@ mod foo {}
             md other_crate
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
@@ -214,7 +213,6 @@ struct Bar;
             md bar
             md foo
             st Bar
-            kw super::
         "#]],
     );
 }
@@ -284,9 +282,73 @@ pub use $0;
             md bar
             kw crate::
             kw self::
+        "#]],
+    );
+}
+
+#[test]
+fn pub_suggest_use_tree_super_acc_to_depth_in_tree() {
+    // https://github.com/rust-lang/rust-analyzer/issues/12439
+    // Check discussion in https://github.com/rust-lang/rust-analyzer/pull/12447
+
+    check(
+        r#"
+mod foo {
+    mod bar {
+        pub use super::$0;
+    }
+}
+"#,
+        expect![[r#"
+            md bar
+            kw super::
+        "#]],
+    );
+
+    // Not suggest super when at crate root
+    check(
+        r#"
+mod foo {
+    mod bar {
+        pub use super::super::$0;
+    }
+}
+"#,
+        expect![[r#"
+            md foo
+        "#]],
+    );
+
+    check(
+        r#"
+mod foo {
+    use $0;
+}
+"#,
+        expect![[r#"
+            kw crate::
+            kw self::
             kw super::
         "#]],
     );
+
+    // Not suggest super after another kw in path ( here it is foo1 )
+    check(
+        r#"
+mod foo {
+    mod bar {
+        use super::super::foo1::$0;
+    }
+}
+
+mod foo1 {
+    pub mod bar1 {}
+}
+"#,
+        expect![[r#"
+            md bar1
+        "#]],
+    );
 }
 
 #[test]
@@ -301,7 +363,6 @@ use {$0};
             md bar
             kw crate::
             kw self::
-            kw super::
         "#]],
     );
 }
diff --git a/crates/ide-completion/src/tests/visibility.rs b/crates/ide-completion/src/tests/visibility.rs
index 151dd6a7e85..c18d6e66dd6 100644
--- a/crates/ide-completion/src/tests/visibility.rs
+++ b/crates/ide-completion/src/tests/visibility.rs
@@ -25,7 +25,6 @@ pub($0)
             kw crate
             kw in
             kw self
-            kw super
         "#]],
     );
 }
@@ -39,7 +38,6 @@ pub(in $0)
         expect![[r#"
             kw crate
             kw self
-            kw super
         "#]],
     );
 }