if !ctx.config.enable_imports_on_the_fly {
return None;
}
- if ctx.use_item_syntax.is_some()
- || ctx.attribute_under_caret.is_some()
- || ctx.mod_declaration_under_caret.is_some()
- || ctx.record_lit_syntax.is_some()
- || ctx.has_impl_or_trait_parent()
- {
+ if ctx.use_item_syntax.is_some() || ctx.is_path_disallowed() {
return None;
}
let potential_import_name = {
if !ctx.lifetime_allowed {
return;
}
+ let lp_string;
let param_lifetime = match (
&ctx.lifetime_syntax,
ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime()),
) {
(Some(lt), Some(lp)) if lp == lt.clone() => return,
- (Some(_), Some(lp)) => Some(lp.to_string()),
+ (Some(_), Some(lp)) => {
+ lp_string = lp.to_string();
+ Some(&lp_string)
+ }
_ => None,
};
ctx.scope.process_all_names(&mut |name, res| {
if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
- if param_lifetime != Some(name.to_string()) {
- acc.add_resolution(ctx, name.to_string(), &res);
+ let name = name.to_string();
+ if param_lifetime != Some(&name) {
+ acc.add_resolution(ctx, name, &res);
}
}
});
pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) {
// Show only macros in top level.
- if ctx.is_new_item {
- ctx.scope.process_all_names(&mut |name, res| {
- if let hir::ScopeDef::MacroDef(mac) = res {
- acc.add_macro(ctx, Some(name.to_string()), mac);
- }
- })
+ if !ctx.is_new_item {
+ return;
}
+
+ ctx.scope.process_all_names(&mut |name, res| {
+ if let hir::ScopeDef::MacroDef(mac) = res {
+ acc.add_macro(ctx, Some(name.to_string()), mac);
+ }
+ })
}
#[cfg(test)]
use crate::{CompletionContext, Completions};
pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
+ if ctx.is_path_disallowed() {
+ return;
+ }
let path = match &ctx.path_qual {
Some(path) => path.clone(),
None => return,
};
- if ctx.attribute_under_caret.is_some() || ctx.mod_declaration_under_caret.is_some() {
- return;
- }
-
- let context_module = ctx.scope.module();
-
let resolution = match ctx.sema.resolve_path(&path) {
Some(res) => res,
None => return,
};
+ let context_module = ctx.scope.module();
// Add associated types on type parameters and `Self`.
resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| {
let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_lit.clone()));
let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default();
let impl_default_trait = default_trait
- .and_then(|default_trait| ty.map(|ty| ty.impls_trait(ctx.db, default_trait, &[])))
- .unwrap_or(false);
+ .zip(ty)
+ .map_or(false, |(default_trait, ty)| ty.impls_trait(ctx.db, default_trait, &[]));
let missing_fields = ctx.sema.record_literal_missing_fields(record_lit);
if impl_default_trait && !missing_fields.is_empty() {
let completion_text = "..Default::default()";
- let completion_text = completion_text
- .strip_prefix(ctx.token.to_string().as_str())
- .unwrap_or(completion_text);
let mut item = CompletionItem::new(
CompletionKind::Snippet,
ctx.source_range(),
- "..Default::default()",
+ completion_text,
);
+ let completion_text =
+ completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
item.insert_text(completion_text).kind(SymbolKind::Field);
item.add_to(acc);
}
if !ctx.is_trivial_path {
return;
}
- if ctx.record_lit_syntax.is_some()
- || ctx.record_pat_syntax.is_some()
- || ctx.attribute_under_caret.is_some()
- || ctx.mod_declaration_under_caret.is_some()
- || ctx.has_impl_or_trait_parent()
- {
+ if ctx.is_path_disallowed() {
return;
}
pub(super) is_path_type: bool,
pub(super) has_type_args: bool,
pub(super) attribute_under_caret: Option<ast::Attr>,
- pub(super) locals: Vec<(String, Local)>,
-
pub(super) mod_declaration_under_caret: Option<ast::Module>,
+ pub(super) locals: Vec<(String, Local)>,
// keyword patterns
pub(super) previous_token: Option<SyntaxToken>,
- pub(super) in_loop_body: bool,
pub(super) prev_sibling: Option<PrevSibling>,
+ pub(super) in_loop_body: bool,
pub(super) is_match_arm: bool,
pub(super) incomplete_let: bool,
self.prev_sibling.is_some()
}
+ pub(crate) fn is_path_disallowed(&self) -> bool {
+ self.record_lit_syntax.is_some()
+ || self.record_pat_syntax.is_some()
+ || self.attribute_under_caret.is_some()
+ || self.mod_declaration_under_caret.is_some()
+ || self.has_impl_or_trait_parent()
+ }
+
fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) {
let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap();
let syntax_element = NodeOrToken::Token(fake_ident_token);