Skip to content

Commit

Permalink
Auto merge of rust-lang#12597 - Veykril:completions, r=Veykril
Browse files Browse the repository at this point in the history
fix: Fix auto-ref completions inserting into wrong locations

Fixes rust-lang/rust-analyzer#8058
  • Loading branch information
bors committed Jun 20, 2022
2 parents 9fdfa9f + 8b07898 commit 439a513
Show file tree
Hide file tree
Showing 21 changed files with 352 additions and 212 deletions.
54 changes: 47 additions & 7 deletions crates/ide-completion/src/completions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ use crate::{
const_::render_const,
function::{render_fn, render_method},
literal::{render_struct_literal, render_variant_lit},
macro_::render_macro,
macro_::{render_macro, render_macro_pat},
pattern::{render_struct_pat, render_variant_pat},
render_field, render_path_resolution, render_resolution_simple, render_tuple_field,
render_field, render_path_resolution, render_pattern_resolution, render_tuple_field,
type_alias::{render_type_alias, render_type_alias_with_eq},
union_literal::render_union_literal,
RenderContext,
Expand Down Expand Up @@ -134,10 +134,14 @@ impl Completions {
item.add_to(self);
}

pub(crate) fn add_crate_roots(&mut self, ctx: &CompletionContext) {
pub(crate) fn add_crate_roots(
&mut self,
ctx: &CompletionContext,
path_ctx: &PathCompletionCtx,
) {
ctx.process_all_names(&mut |name, res| match res {
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => {
self.add_module(ctx, m, name);
self.add_module(ctx, path_ctx, m, name);
}
_ => (),
});
Expand All @@ -160,25 +164,36 @@ impl Completions {
);
}

pub(crate) fn add_resolution_simple(
pub(crate) fn add_pattern_resolution(
&mut self,
ctx: &CompletionContext,
pattern_ctx: &PatternContext,
local_name: hir::Name,
resolution: hir::ScopeDef,
) {
if ctx.is_scope_def_hidden(resolution) {
cov_mark::hit!(qualified_path_doc_hidden);
return;
}
self.add(render_resolution_simple(RenderContext::new(ctx), local_name, resolution).build());
self.add(
render_pattern_resolution(RenderContext::new(ctx), pattern_ctx, local_name, resolution)
.build(),
);
}

pub(crate) fn add_module(
&mut self,
ctx: &CompletionContext,
path_ctx: &PathCompletionCtx,
module: hir::Module,
local_name: hir::Name,
) {
self.add_resolution_simple(ctx, local_name, hir::ScopeDef::ModuleDef(module.into()));
self.add_path_resolution(
ctx,
path_ctx,
local_name,
hir::ScopeDef::ModuleDef(module.into()),
);
}

pub(crate) fn add_macro(
Expand All @@ -204,6 +219,29 @@ impl Completions {
);
}

pub(crate) fn add_macro_pat(
&mut self,
ctx: &CompletionContext,
pattern_ctx: &PatternContext,
mac: hir::Macro,
local_name: hir::Name,
) {
let is_private_editable = match ctx.is_visible(&mac) {
Visible::Yes => false,
Visible::Editable => true,
Visible::No => return,
};
self.add(
render_macro_pat(
RenderContext::new(ctx).private_editable(is_private_editable),
pattern_ctx,
local_name,
mac,
)
.build(),
);
}

pub(crate) fn add_function(
&mut self,
ctx: &CompletionContext,
Expand Down Expand Up @@ -341,6 +379,7 @@ impl Completions {
pub(crate) fn add_field(
&mut self,
ctx: &CompletionContext,
dot_access: &DotAccess,
receiver: Option<hir::Name>,
field: hir::Field,
ty: &hir::Type,
Expand All @@ -352,6 +391,7 @@ impl Completions {
};
let item = render_field(
RenderContext::new(ctx).private_editable(is_private_editable),
dot_access,
receiver,
field,
ty,
Expand Down
8 changes: 5 additions & 3 deletions crates/ide-completion/src/completions/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,24 @@ pub(crate) fn complete_attribute_path(
acc.add_macro(ctx, path_ctx, m, name)
}
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
acc.add_module(ctx, m, name)
acc.add_module(ctx, path_ctx, m, name)
}
_ => (),
}
}
return;
}
// fresh use tree with leading colon2, only show crate roots
Qualified::Absolute => acc.add_crate_roots(ctx),
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
// only show modules in a fresh UseTree
Qualified::No => {
ctx.process_all_names(&mut |name, def| match def {
hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_attr(ctx.db) => {
acc.add_macro(ctx, path_ctx, m, name)
}
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
acc.add_module(ctx, path_ctx, m, name)
}
_ => (),
});
acc.add_nameref_keywords_with_colon(ctx);
Expand Down
8 changes: 5 additions & 3 deletions crates/ide-completion/src/completions/attribute/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ pub(crate) fn complete_derive_path(
{
acc.add_macro(ctx, path_ctx, mac, name)
}
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
acc.add_module(ctx, path_ctx, m, name)
}
_ => (),
}
}
}
Qualified::Absolute => acc.add_crate_roots(ctx),
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
// only show modules in a fresh UseTree
Qualified::No => {
ctx.process_all_names(&mut |name, def| {
Expand All @@ -51,7 +53,7 @@ pub(crate) fn complete_derive_path(
mac
}
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
return acc.add_module(ctx, m, name);
return acc.add_module(ctx, path_ctx, m, name);
}
_ => return,
};
Expand Down
16 changes: 14 additions & 2 deletions crates/ide-completion/src/completions/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext, dot_a
acc,
ctx,
&receiver_ty,
|acc, field, ty| acc.add_field(ctx, None, field, &ty),
|acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty),
|acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty),
);
}
Expand Down Expand Up @@ -64,7 +64,19 @@ pub(crate) fn complete_undotted_self(
acc,
ctx,
&ty,
|acc, field, ty| acc.add_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
|acc, field, ty| {
acc.add_field(
ctx,
&DotAccess {
receiver: None,
receiver_ty: None,
kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal: false },
},
Some(hir::known::SELF_PARAM),
field,
&ty,
)
},
|acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
);
complete_methods(ctx, &ty, |func| {
Expand Down
2 changes: 1 addition & 1 deletion crates/ide-completion/src/completions/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ pub(crate) fn complete_expr_path(
_ => (),
}
}
Qualified::Absolute => acc.add_crate_roots(ctx),
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
Qualified::No => {
acc.add_nameref_keywords_with_colon(ctx);
if let Some(adt) =
Expand Down
64 changes: 50 additions & 14 deletions crates/ide-completion/src/completions/flyimport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
CompletionContext, DotAccess, PathCompletionCtx, PathKind, PatternContext, Qualified,
TypeLocation,
},
render::{render_resolution_with_import, RenderContext},
render::{render_resolution_with_import, render_resolution_with_import_pat, RenderContext},
};

use super::Completions;
Expand Down Expand Up @@ -149,30 +149,22 @@ pub(crate) fn import_on_the_fly_path(
pub(crate) fn import_on_the_fly_pat(
acc: &mut Completions,
ctx: &CompletionContext,
pat_ctx: &PatternContext,
pattern_ctx: &PatternContext,
) -> Option<()> {
if !ctx.config.enable_imports_on_the_fly {
return None;
}
if let PatternContext { record_pat: Some(_), .. } = pat_ctx {
if let PatternContext { record_pat: Some(_), .. } = pattern_ctx {
return None;
}

let potential_import_name = import_name(ctx);
let import_assets = import_assets_for_path(ctx, &potential_import_name, None)?;

import_on_the_fly(
import_on_the_fly_pat2(
acc,
ctx,
&PathCompletionCtx {
has_call_parens: false,
has_macro_bang: false,
qualified: Qualified::No,
parent: None,
kind: crate::context::PathKind::Pat { pat_ctx: pat_ctx.clone() },
has_type_args: false,
use_tree_parent: false,
},
pattern_ctx,
import_assets,
ctx.original_token.parent()?,
potential_import_name,
Expand Down Expand Up @@ -287,6 +279,50 @@ fn import_on_the_fly(
Some(())
}

fn import_on_the_fly_pat2(
acc: &mut Completions,
ctx: &CompletionContext,
pattern_ctx: &PatternContext,
import_assets: ImportAssets,
position: SyntaxNode,
potential_import_name: String,
) -> Option<()> {
let _p = profile::span("import_on_the_fly_pat").detail(|| potential_import_name.clone());

if ImportScope::find_insert_use_container(&position, &ctx.sema).is_none() {
return None;
}

let ns_filter = |import: &LocatedImport| match import.original_item {
ItemInNs::Macros(mac) => mac.is_fn_like(ctx.db),
ItemInNs::Types(_) => true,
ItemInNs::Values(def) => matches!(def, hir::ModuleDef::Const(_)),
};
let user_input_lowercased = potential_import_name.to_lowercase();

acc.add_all(
import_assets
.search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind)
.into_iter()
.filter(ns_filter)
.filter(|import| {
!ctx.is_item_hidden(&import.item_to_import)
&& !ctx.is_item_hidden(&import.original_item)
})
.sorted_by_key(|located_import| {
compute_fuzzy_completion_order_key(
&located_import.import_path,
&user_input_lowercased,
)
})
.filter_map(|import| {
render_resolution_with_import_pat(RenderContext::new(ctx), pattern_ctx, import)
})
.map(|builder| builder.build()),
);
Some(())
}

fn import_on_the_fly_method(
acc: &mut Completions,
ctx: &CompletionContext,
Expand All @@ -295,7 +331,7 @@ fn import_on_the_fly_method(
position: SyntaxNode,
potential_import_name: String,
) -> Option<()> {
let _p = profile::span("import_on_the_fly").detail(|| potential_import_name.clone());
let _p = profile::span("import_on_the_fly_method").detail(|| potential_import_name.clone());

if ImportScope::find_insert_use_container(&position, &ctx.sema).is_none() {
return None;
Expand Down
8 changes: 5 additions & 3 deletions crates/ide-completion/src/completions/item_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub(crate) fn complete_item_list(
acc.add_macro(ctx, path_ctx, m, name)
}
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
acc.add_module(ctx, m, name)
acc.add_module(ctx, path_ctx, m, name)
}
_ => (),
}
Expand All @@ -55,13 +55,15 @@ pub(crate) fn complete_item_list(
acc.add_keyword(ctx, "super::");
}
}
Qualified::Absolute => acc.add_crate_roots(ctx),
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
Qualified::No if ctx.qualifier_ctx.none() => {
ctx.process_all_names(&mut |name, def| match def {
hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(ctx.db) => {
acc.add_macro(ctx, path_ctx, m, name)
}
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
acc.add_module(ctx, path_ctx, m, name)
}
_ => (),
});
acc.add_nameref_keywords_with_colon(ctx);
Expand Down
19 changes: 3 additions & 16 deletions crates/ide-completion/src/completions/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,7 @@ pub(crate) fn complete_pattern(
hir::ModuleDef::Const(..) => refutable,
hir::ModuleDef::Module(..) => true,
hir::ModuleDef::Macro(mac) if mac.is_fn_like(ctx.db) => {
return acc.add_macro(
ctx,
&PathCompletionCtx {
has_call_parens: false,
has_macro_bang: false,
qualified: Qualified::No,
parent: None,
kind: crate::context::PathKind::Pat { pat_ctx: pattern_ctx.clone() },
has_type_args: false,
use_tree_parent: false,
},
mac,
name,
)
return acc.add_macro_pat(ctx, pattern_ctx, mac, name);
}
_ => false,
},
Expand All @@ -116,7 +103,7 @@ pub(crate) fn complete_pattern(
| ScopeDef::Unknown => false,
};
if add_simple_path {
acc.add_resolution_simple(ctx, name, res);
acc.add_pattern_resolution(ctx, pattern_ctx, name, res);
}
});
}
Expand Down Expand Up @@ -205,7 +192,7 @@ pub(crate) fn complete_pattern_path(
}
}
// qualifier can only be none here if we are in a TuplePat or RecordPat in which case special characters have to follow the path
Qualified::Absolute => acc.add_crate_roots(ctx),
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
Qualified::No => {
ctx.process_all_names(&mut |name, res| {
// FIXME: properly filter here
Expand Down
Loading

0 comments on commit 439a513

Please sign in to comment.