]> git.lizzy.rs Git - rust.git/commitdiff
internal: Collapse completion ctx path qualifier and is_absolute_path into enum
authorLukas Wirth <lukastw97@gmail.com>
Fri, 17 Jun 2022 14:36:22 +0000 (16:36 +0200)
committerLukas Wirth <lukastw97@gmail.com>
Fri, 17 Jun 2022 14:36:22 +0000 (16:36 +0200)
14 files changed:
crates/ide-completion/src/completions/attribute.rs
crates/ide-completion/src/completions/attribute/derive.rs
crates/ide-completion/src/completions/dot.rs
crates/ide-completion/src/completions/expr.rs
crates/ide-completion/src/completions/field.rs
crates/ide-completion/src/completions/item_list.rs
crates/ide-completion/src/completions/pattern.rs
crates/ide-completion/src/completions/record.rs
crates/ide-completion/src/completions/snippet.rs
crates/ide-completion/src/completions/type.rs
crates/ide-completion/src/completions/use_.rs
crates/ide-completion/src/completions/vis.rs
crates/ide-completion/src/context.rs
crates/ide-completion/src/context/analysis.rs

index 0b7479fd0e84f748724ad247a4325f4bd559803f..56e51d32e20d7d6bd401d6cbe700610f8ac39222 100644 (file)
@@ -18,7 +18,9 @@
 
 use crate::{
     completions::module_or_attr,
-    context::{CompletionContext, IdentContext, PathCompletionCtx, PathKind, PathQualifierCtx},
+    context::{
+        CompletionContext, IdentContext, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified,
+    },
     item::CompletionItem,
     Completions,
 };
@@ -72,18 +74,17 @@ pub(crate) fn complete_known_attribute_input(
 }
 
 pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) {
-    let (is_absolute_path, qualifier, is_inner, annotated_item_kind) = match ctx.path_context() {
+    let (qualified, is_inner, annotated_item_kind) = match ctx.path_context() {
         Some(&PathCompletionCtx {
             kind: PathKind::Attr { kind, annotated_item_kind },
-            is_absolute_path,
-            ref qualifier,
+            ref qualified,
             ..
-        }) => (is_absolute_path, qualifier, kind == AttrKind::Inner, annotated_item_kind),
+        }) => (qualified, kind == AttrKind::Inner, annotated_item_kind),
         _ => return,
     };
 
-    match qualifier {
-        Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
+    match qualified {
+        Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
             if *is_super_chain {
                 acc.add_keyword(ctx, "super::");
             }
@@ -101,9 +102,9 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext)
             return;
         }
         // fresh use tree with leading colon2, only show crate roots
-        None if is_absolute_path => acc.add_crate_roots(ctx),
+        Qualified::Absolute => acc.add_crate_roots(ctx),
         // only show modules in a fresh UseTree
-        None => {
+        Qualified::No => {
             ctx.process_all_names(&mut |name, def| {
                 if let Some(def) = module_or_attr(ctx.db, def) {
                     acc.add_resolution(ctx, name, def);
index 19414e4b31568ff117e5ba9a1f445edd9734cf8c..0d4a292e0f725cffebd866b7e99540f59aec1ee4 100644 (file)
@@ -5,26 +5,21 @@
 use syntax::SmolStr;
 
 use crate::{
-    context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx},
+    context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified},
     item::CompletionItem,
     Completions,
 };
 
 pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
-    let (qualifier, is_absolute_path) = match ctx.path_context() {
-        Some(&PathCompletionCtx {
-            kind: PathKind::Derive,
-            ref qualifier,
-            is_absolute_path,
-            ..
-        }) => (qualifier, is_absolute_path),
+    let qualified = match ctx.path_context() {
+        Some(&PathCompletionCtx { kind: PathKind::Derive, ref qualified, .. }) => qualified,
         _ => return,
     };
 
     let core = ctx.famous_defs().core();
 
-    match qualifier {
-        Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
+    match qualified {
+        Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
             if *is_super_chain {
                 acc.add_keyword(ctx, "super::");
             }
@@ -47,9 +42,9 @@ pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
                 }
             }
         }
-        None if is_absolute_path => acc.add_crate_roots(ctx),
+        Qualified::Absolute => acc.add_crate_roots(ctx),
         // only show modules in a fresh UseTree
-        None => {
+        Qualified::No => {
             ctx.process_all_names(&mut |name, def| {
                 let mac = match def {
                     ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac))
@@ -65,7 +60,7 @@ pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
 
                 match (core, mac.module(ctx.db).krate()) {
                     // show derive dependencies for `core`/`std` derives
-                    (Some(core), mac_krate) if core == mac_krate && qualifier.is_none() => {}
+                    (Some(core), mac_krate) if core == mac_krate => {}
                     _ => return acc.add_resolution(ctx, name, def),
                 };
 
index ade57bed958ec06745eb01bd3130fcd1242d00d3..bdafdf4152e968efd4c32fe55d2fceedc479281c 100644 (file)
@@ -5,7 +5,7 @@
 use crate::{
     context::{
         CompletionContext, DotAccess, DotAccessKind, NameRefContext, NameRefKind,
-        PathCompletionCtx, PathKind,
+        PathCompletionCtx, PathKind, Qualified,
     },
     CompletionItem, CompletionItemKind, Completions,
 };
@@ -50,8 +50,7 @@ fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
     match ctx.path_context() {
         Some(
             path_ctx @ PathCompletionCtx {
-                is_absolute_path: false,
-                qualifier: None,
+                qualified: Qualified::No,
                 kind: PathKind::Expr { .. },
                 ..
             },
index e97545eae50d0482f4c9970c05c3189e6e479b2a..f0a8529c78eb98ddf4b170923586db2ed3ba6dd4 100644 (file)
@@ -4,7 +4,9 @@
 use ide_db::FxHashSet;
 
 use crate::{
-    context::{NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PathQualifierCtx},
+    context::{
+        NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified,
+    },
     CompletionContext, Completions,
 };
 
@@ -12,8 +14,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
     let _p = profile::span("complete_expr_path");
 
     let (
-        is_absolute_path,
-        qualifier,
+        qualified,
         in_block_expr,
         in_loop_body,
         is_func_update,
@@ -33,14 +34,12 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
                             ref ref_expr_parent,
                             ref is_func_update,
                         },
-                    is_absolute_path,
-                    ref qualifier,
+                    ref qualified,
                     ..
                 })),
             ..
         }) if ctx.qualifier_ctx.none() => (
-            is_absolute_path,
-            qualifier,
+            qualified,
             in_block_expr,
             in_loop_body,
             is_func_update.is_some(),
@@ -61,8 +60,8 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
         }
     };
 
-    match qualifier {
-        Some(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
+    match qualified {
+        Qualified::With(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
             if *is_infer_qualifier {
                 ctx.traits_in_scope()
                     .0
@@ -174,8 +173,8 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
                 _ => (),
             }
         }
-        None if is_absolute_path => acc.add_crate_roots(ctx),
-        None => {
+        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::No => {
             acc.add_nameref_keywords_with_colon(ctx);
             if let Some(adt) =
                 ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
@@ -237,7 +236,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
                 add_keyword("true", "true");
                 add_keyword("false", "false");
 
-                if (in_condition && !is_absolute_path) || in_block_expr {
+                if in_condition || in_block_expr {
                     add_keyword("let", "let");
                 }
 
index c540b87a46fda9b0a208025a8e600d7e9394a9dc..a9f598fffd3dbefee3f5a10f08ba7e02a50d217b 100644 (file)
@@ -3,7 +3,7 @@
 use crate::{
     context::{
         IdentContext, NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx,
-        PathKind, TypeLocation,
+        PathKind, Qualified, TypeLocation,
     },
     CompletionContext, Completions,
 };
@@ -15,8 +15,7 @@ pub(crate) fn complete_field_list(acc: &mut Completions, ctx: &CompletionContext
             kind:
                 Some(NameRefKind::Path(PathCompletionCtx {
                     has_macro_bang: false,
-                    is_absolute_path: false,
-                    qualifier: None,
+                    qualified: Qualified::No,
                     parent: None,
                     kind: PathKind::Type { location: TypeLocation::TupleField },
                     has_type_args: false,
index d44bf0a6ab743d68ef3e398e2a154820ab2fc4c4..e3f3b7f5282774d5f94edb0a385e3e44fa71a639 100644 (file)
@@ -2,7 +2,7 @@
 
 use crate::{
     completions::module_or_fn_macro,
-    context::{ItemListKind, PathCompletionCtx, PathKind, PathQualifierCtx},
+    context::{ItemListKind, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified},
     CompletionContext, Completions,
 };
 
@@ -16,23 +16,17 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
         return;
     }
 
-    let (&is_absolute_path, path_qualifier, kind, is_trivial_path) = match ctx.path_context() {
-        Some(
-            ctx @ PathCompletionCtx {
-                kind: PathKind::Item { kind },
-                is_absolute_path,
-                qualifier,
-                ..
-            },
-        ) => (is_absolute_path, qualifier, Some(kind), ctx.is_trivial_path()),
+    let (qualified, kind, is_trivial_path) = match ctx.path_context() {
+        Some(ctx @ PathCompletionCtx { kind: PathKind::Item { kind }, qualified, .. }) => {
+            (qualified, Some(kind), ctx.is_trivial_path())
+        }
         Some(
             ctx @ PathCompletionCtx {
                 kind: PathKind::Expr { in_block_expr: true, .. },
-                is_absolute_path,
-                qualifier,
+                qualified,
                 ..
             },
-        ) => (is_absolute_path, qualifier, None, ctx.is_trivial_path()),
+        ) => (qualified, None, ctx.is_trivial_path()),
         _ => return,
     };
 
@@ -49,8 +43,8 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
         return;
     }
 
-    match path_qualifier {
-        Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
+    match qualified {
+        Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
             if let Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))) = resolution {
                 for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
                     if let Some(def) = module_or_fn_macro(ctx.db, def) {
@@ -63,8 +57,8 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
                 acc.add_keyword(ctx, "super::");
             }
         }
-        None if is_absolute_path => acc.add_crate_roots(ctx),
-        None if ctx.qualifier_ctx.none() => {
+        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::No if ctx.qualifier_ctx.none() => {
             ctx.process_all_names(&mut |name, def| {
                 if let Some(def) = module_or_fn_macro(ctx.db, def) {
                     acc.add_resolution(ctx, name, def);
@@ -72,7 +66,7 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
             });
             acc.add_nameref_keywords_with_colon(ctx);
         }
-        None => {}
+        Qualified::No => {}
     }
 }
 
index ab35dadf92b49ee8243610ac10cac785091928e7..b7710ae70dae2fd0fbd542f731c6be15dbb56d84 100644 (file)
@@ -5,7 +5,7 @@
 use syntax::ast::Pat;
 
 use crate::{
-    context::{PathCompletionCtx, PathQualifierCtx, PatternRefutability},
+    context::{PathCompletionCtx, PathQualifierCtx, PatternRefutability, Qualified},
     CompletionContext, Completions,
 };
 
@@ -111,10 +111,10 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
 fn pattern_path_completion(
     acc: &mut Completions,
     ctx: &CompletionContext,
-    PathCompletionCtx { qualifier, is_absolute_path, .. }: &PathCompletionCtx,
+    PathCompletionCtx { qualified, .. }: &PathCompletionCtx,
 ) {
-    match qualifier {
-        Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
+    match qualified {
+        Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
             if *is_super_chain {
                 acc.add_keyword(ctx, "super::");
             }
@@ -197,8 +197,8 @@ fn pattern_path_completion(
             }
         }
         // qualifier can only be none here if we are in a TuplePat or RecordPat in which case special characters have to follow the path
-        None if *is_absolute_path => acc.add_crate_roots(ctx),
-        None => {
+        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::No => {
             ctx.process_all_names(&mut |name, res| {
                 // FIXME: properly filter here
                 if let ScopeDef::ModuleDef(_) = res {
index d74ae260b5dfa771d0936aa07c5a269a01b086a4..5ba355f6ae8ef9b4e211a3a56f081e21f88506bd 100644 (file)
@@ -3,7 +3,9 @@
 use syntax::{ast::Expr, T};
 
 use crate::{
-    context::{NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PatternContext},
+    context::{
+        NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PatternContext, Qualified,
+    },
     CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
     CompletionRelevancePostfixMatch, Completions,
 };
@@ -19,7 +21,7 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
                 NameRefKind::RecordExpr(record_expr)
                 | NameRefKind::Path(PathCompletionCtx {
                     kind: PathKind::Expr { is_func_update: Some(record_expr), .. },
-                    qualifier: None,
+                    qualified: Qualified::No,
                     ..
                 }),
             ),
index ebc3bb5a6f9b921b4f055b24370a7f31e72a84a3..293311fe910483936ec63bd7cfbde49c5a7dab26 100644 (file)
@@ -4,7 +4,7 @@
 use ide_db::{imports::insert_use::ImportScope, SnippetCap};
 
 use crate::{
-    context::{ItemListKind, PathCompletionCtx, PathKind},
+    context::{ItemListKind, PathCompletionCtx, PathKind, Qualified},
     item::Builder,
     CompletionContext, CompletionItem, CompletionItemKind, Completions, SnippetScope,
 };
@@ -18,8 +18,7 @@ fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str)
 pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) {
     let &can_be_stmt = match ctx.path_context() {
         Some(PathCompletionCtx {
-            is_absolute_path: false,
-            qualifier: None,
+            qualified: Qualified::No,
             kind: PathKind::Expr { in_block_expr, .. },
             ..
         }) => in_block_expr,
@@ -44,8 +43,7 @@ pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionConte
 pub(crate) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) {
     let path_kind = match ctx.path_context() {
         Some(PathCompletionCtx {
-            is_absolute_path: false,
-            qualifier: None,
+            qualified: Qualified::No,
             kind: kind @ (PathKind::Item { .. } | PathKind::Expr { in_block_expr: true, .. }),
             ..
         }) => kind,
index 3b2e383a09d7cd63b1cc95da157ea8378de70efa..f2418d76ccc5de1d67ba70e0c302ca4ec7d77eae 100644 (file)
@@ -5,7 +5,10 @@
 use syntax::{ast, AstNode};
 
 use crate::{
-    context::{PathCompletionCtx, PathKind, PathQualifierCtx, TypeAscriptionTarget, TypeLocation},
+    context::{
+        PathCompletionCtx, PathKind, PathQualifierCtx, Qualified, TypeAscriptionTarget,
+        TypeLocation,
+    },
     render::render_type_inference,
     CompletionContext, Completions,
 };
 pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext) {
     let _p = profile::span("complete_type_path");
 
-    let (&is_absolute_path, location, qualifier) = match ctx.path_context() {
-        Some(PathCompletionCtx {
-            kind: PathKind::Type { location },
-            is_absolute_path,
-            qualifier,
-            ..
-        }) => (is_absolute_path, location, qualifier),
+    let (location, qualified) = match ctx.path_context() {
+        Some(PathCompletionCtx { kind: PathKind::Type { location }, qualified, .. }) => {
+            (location, qualified)
+        }
         _ => return,
     };
 
@@ -54,8 +54,8 @@ pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext)
         hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
     };
 
-    match qualifier {
-        Some(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
+    match qualified {
+        Qualified::With(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
             if *is_infer_qualifier {
                 ctx.traits_in_scope()
                     .0
@@ -151,8 +151,8 @@ pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext)
                 _ => (),
             }
         }
-        None if is_absolute_path => acc.add_crate_roots(ctx),
-        None => {
+        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::No => {
             acc.add_nameref_keywords_with_colon(ctx);
             if let TypeLocation::TypeBound = location {
                 ctx.process_all_names(&mut |name, res| {
index 5d062098d7d623f9f98ac334d34706041d794cc8..3b6ce8fc1ad982a9da212ff1d367c8d72276d27c 100644 (file)
@@ -7,30 +7,30 @@
 use crate::{
     context::{
         CompletionContext, NameRefContext, NameRefKind, PathCompletionCtx, PathKind,
-        PathQualifierCtx,
+        PathQualifierCtx, Qualified,
     },
     item::Builder,
     CompletionItem, CompletionItemKind, CompletionRelevance, Completions,
 };
 
 pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext) {
-    let (&is_absolute_path, qualifier, name_ref) = match ctx.nameref_ctx() {
+    let (qualified, name_ref) = match ctx.nameref_ctx() {
         Some(NameRefContext {
-            kind:
-                Some(NameRefKind::Path(PathCompletionCtx {
-                    kind: PathKind::Use,
-                    is_absolute_path,
-                    qualifier,
-                    ..
-                })),
+            kind: Some(NameRefKind::Path(PathCompletionCtx { kind: PathKind::Use, qualified, .. })),
             nameref,
             ..
-        }) => (is_absolute_path, qualifier, nameref),
+        }) => (qualified, nameref),
         _ => return,
     };
 
-    match qualifier {
-        Some(PathQualifierCtx { path, resolution, is_super_chain, use_tree_parent, .. }) => {
+    match qualified {
+        Qualified::With(PathQualifierCtx {
+            path,
+            resolution,
+            is_super_chain,
+            use_tree_parent,
+            ..
+        }) => {
             if *is_super_chain {
                 acc.add_keyword(ctx, "super::");
             }
@@ -105,12 +105,12 @@ pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext)
             }
         }
         // fresh use tree with leading colon2, only show crate roots
-        None if is_absolute_path => {
+        Qualified::Absolute => {
             cov_mark::hit!(use_tree_crate_roots_only);
             acc.add_crate_roots(ctx);
         }
         // only show modules and non-std enum in a fresh UseTree
-        None => {
+        Qualified::No => {
             cov_mark::hit!(unqualified_path_selected_only);
             ctx.process_all_names(&mut |name, res| {
                 match res {
index d538f1879e74e12ba3d12e2e9d92ee8b2679a14a..b971808626681c0ee78d9c8d54033ce6ac8ea0ca 100644 (file)
@@ -3,23 +3,20 @@
 use hir::ScopeDef;
 
 use crate::{
-    context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx},
+    context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified},
     Completions,
 };
 
 pub(crate) fn complete_vis_path(acc: &mut Completions, ctx: &CompletionContext) {
-    let (&is_absolute_path, qualifier, &has_in_token) = match ctx.path_context() {
-        Some(PathCompletionCtx {
-            kind: PathKind::Vis { has_in_token },
-            is_absolute_path,
-            qualifier,
-            ..
-        }) => (is_absolute_path, qualifier, has_in_token),
+    let (qualified, &has_in_token) = match ctx.path_context() {
+        Some(PathCompletionCtx { kind: PathKind::Vis { has_in_token }, qualified, .. }) => {
+            (qualified, has_in_token)
+        }
         _ => return,
     };
 
-    match qualifier {
-        Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
+    match qualified {
+        Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
             // Try completing next child module of the path that is still a parent of the current module
             if let Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))) = resolution {
                 let next_towards_current = ctx
@@ -40,13 +37,13 @@ pub(crate) fn complete_vis_path(acc: &mut Completions, ctx: &CompletionContext)
                 acc.add_keyword(ctx, "super::");
             }
         }
-        None if !is_absolute_path => {
+        Qualified::Absolute => {}
+        Qualified::No => {
             if !has_in_token {
                 cov_mark::hit!(kw_completion_in);
                 acc.add_keyword(ctx, "in");
             }
             acc.add_nameref_keywords(ctx);
         }
-        _ => {}
     }
 }
index 767ea5c20de25f7844905565a501d1c05687f617..4ed083a52454697b15237077029b36e107dd3c53 100644 (file)
@@ -57,10 +57,8 @@ pub(crate) struct PathCompletionCtx {
     pub(super) has_call_parens: bool,
     /// If this has a macro call bang !
     pub(super) has_macro_bang: bool,
-    /// Whether this path stars with a `::`.
-    pub(super) is_absolute_path: bool,
-    /// The qualifier of the current path if it exists.
-    pub(super) qualifier: Option<PathQualifierCtx>,
+    /// The qualifier of the current path.
+    pub(super) qualified: Qualified,
     /// The parent of the path we are completing.
     pub(super) parent: Option<ast::Path>,
     pub(super) kind: PathKind,
@@ -75,8 +73,7 @@ pub(super) fn is_trivial_path(&self) -> bool {
             PathCompletionCtx {
                 has_call_parens: false,
                 has_macro_bang: false,
-                is_absolute_path: false,
-                qualifier: None,
+                qualified: Qualified::No,
                 parent: None,
                 has_type_args: false,
                 ..
@@ -147,6 +144,14 @@ pub(super) enum ItemListKind {
     ExternBlock,
 }
 
+#[derive(Debug)]
+pub(super) enum Qualified {
+    No,
+    With(PathQualifierCtx),
+    /// Whether the path is an absolute path
+    Absolute,
+}
+
 /// The path qualifier state of the path we are completing.
 #[derive(Debug)]
 pub(crate) struct PathQualifierCtx {
@@ -400,7 +405,10 @@ pub(crate) fn path_context(&self) -> Option<&PathCompletionCtx> {
     }
 
     pub(crate) fn path_qual(&self) -> Option<&ast::Path> {
-        self.path_context().and_then(|it| it.qualifier.as_ref().map(|it| &it.path))
+        self.path_context().and_then(|it| match &it.qualified {
+            Qualified::With(it) => Some(&it.path),
+            _ => None,
+        })
     }
 
     /// Checks if an item is visible and not `doc(hidden)` at the completion site.
index c672c2761a5198f4bb8ec2274d23edfcf322c86f..8d38677df6933520d3ba1ff0e8ef949827066a1a 100644 (file)
@@ -13,7 +13,7 @@
 use crate::context::{
     CompletionContext, DotAccess, DotAccessKind, IdentContext, ItemListKind, LifetimeContext,
     LifetimeKind, NameContext, NameKind, NameRefContext, NameRefKind, ParamKind, PathCompletionCtx,
-    PathKind, PathQualifierCtx, PatternContext, PatternRefutability, QualifierCtx,
+    PathKind, PathQualifierCtx, PatternContext, PatternRefutability, Qualified, QualifierCtx,
     TypeAscriptionTarget, TypeLocation, COMPLETION_MARKER,
 };
 
@@ -585,8 +585,7 @@ fn classify_name_ref(
         let mut path_ctx = PathCompletionCtx {
             has_call_parens: false,
             has_macro_bang: false,
-            is_absolute_path: false,
-            qualifier: None,
+            qualified: Qualified::No,
             parent: path.parent_path(),
             kind: PathKind::Item { kind: ItemListKind::SourceFile },
             has_type_args: false,
@@ -854,41 +853,40 @@ fn classify_name_ref(
 
         // calculate the qualifier context
         if let Some((path, use_tree_parent)) = path_or_use_tree_qualifier(&path) {
-            if !use_tree_parent {
-                path_ctx.is_absolute_path =
-                    path.top_path().segment().map_or(false, |it| it.coloncolon_token().is_some());
+            if !use_tree_parent && segment.coloncolon_token().is_some() {
+                path_ctx.qualified = Qualified::Absolute;
+            } else {
+                let path = path
+                    .segment()
+                    .and_then(|it| find_node_in_file(original_file, &it))
+                    .map(|it| it.parent_path());
+                if let Some(path) = path {
+                    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());
+
+                    // `<_>::$0`
+                    let is_infer_qualifier = path.qualifier().is_none()
+                        && matches!(
+                            path.segment().and_then(|it| it.kind()),
+                            Some(ast::PathSegmentKind::Type {
+                                type_ref: Some(ast::Type::InferType(_)),
+                                trait_ref: None,
+                            })
+                        );
+
+                    path_ctx.qualified = Qualified::With(PathQualifierCtx {
+                        path,
+                        resolution: res,
+                        is_super_chain,
+                        use_tree_parent,
+                        is_infer_qualifier,
+                    })
+                };
             }
-
-            let path = path
-                .segment()
-                .and_then(|it| find_node_in_file(original_file, &it))
-                .map(|it| it.parent_path());
-            path_ctx.qualifier = path.map(|path| {
-                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());
-
-                // `<_>::$0`
-                let is_infer_qualifier = path.qualifier().is_none()
-                    && matches!(
-                        path.segment().and_then(|it| it.kind()),
-                        Some(ast::PathSegmentKind::Type {
-                            type_ref: Some(ast::Type::InferType(_)),
-                            trait_ref: None,
-                        })
-                    );
-
-                PathQualifierCtx {
-                    path,
-                    resolution: res,
-                    is_super_chain,
-                    use_tree_parent,
-                    is_infer_qualifier,
-                }
-            });
         } else if let Some(segment) = path.segment() {
             if segment.coloncolon_token().is_some() {
-                path_ctx.is_absolute_path = true;
+                path_ctx.qualified = Qualified::Absolute;
             }
         }