Skip to content

Commit be3dc67

Browse files
bors[bot]Veykril
andauthored
Merge #8125
8125: Don't use an untyped String for ActiveParam tracking r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents 104a198 + 38048c3 commit be3dc67

File tree

5 files changed

+44
-24
lines changed

5 files changed

+44
-24
lines changed

crates/ide/src/syntax_highlighting/inject.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub(super) fn ra_fixture(
2323
expanded: SyntaxToken,
2424
) -> Option<()> {
2525
let active_parameter = ActiveParameter::at_token(&sema, expanded)?;
26-
if !active_parameter.name.starts_with("ra_fixture") {
26+
if !active_parameter.ident().map_or(false, |name| name.text().starts_with("ra_fixture")) {
2727
return None;
2828
}
2929
let value = literal.value()?;

crates/ide_completion/src/context.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type};
44
use ide_db::base_db::{FilePosition, SourceDatabase};
55
use ide_db::{call_info::ActiveParameter, RootDatabase};
66
use syntax::{
7-
algo::find_node_at_offset, ast, match_ast, AstNode, NodeOrToken, SyntaxKind::*, SyntaxNode,
8-
SyntaxToken, TextRange, TextSize,
7+
algo::find_node_at_offset,
8+
ast::{self, NameOrNameRef, NameOwner},
9+
match_ast, AstNode, NodeOrToken,
10+
SyntaxKind::*,
11+
SyntaxNode, SyntaxToken, TextRange, TextSize,
912
};
1013

1114
use text_edit::Indel;
@@ -35,7 +38,7 @@ pub(crate) struct CompletionContext<'a> {
3538
/// The token before the cursor, in the macro-expanded file.
3639
pub(super) token: SyntaxToken,
3740
pub(super) krate: Option<hir::Crate>,
38-
pub(super) expected_name: Option<String>,
41+
pub(super) expected_name: Option<NameOrNameRef>,
3942
pub(super) expected_type: Option<Type>,
4043
pub(super) name_ref_syntax: Option<ast::NameRef>,
4144
pub(super) function_syntax: Option<ast::Fn>,
@@ -292,21 +295,21 @@ impl<'a> CompletionContext<'a> {
292295
file_with_fake_ident: SyntaxNode,
293296
offset: TextSize,
294297
) {
295-
let expected = {
298+
let (expected_type, expected_name) = {
296299
let mut node = match self.token.parent() {
297300
Some(it) => it,
298301
None => return,
299302
};
300303
loop {
301-
let ret = match_ast! {
304+
break match_ast! {
302305
match node {
303306
ast::LetStmt(it) => {
304307
cov_mark::hit!(expected_type_let_with_leading_char);
305308
cov_mark::hit!(expected_type_let_without_leading_char);
306309
let ty = it.pat()
307310
.and_then(|pat| self.sema.type_of_pat(&pat));
308311
let name = if let Some(ast::Pat::IdentPat(ident)) = it.pat() {
309-
Some(ident.syntax().text().to_string())
312+
ident.name().map(NameOrNameRef::Name)
310313
} else {
311314
None
312315
};
@@ -319,18 +322,21 @@ impl<'a> CompletionContext<'a> {
319322
ActiveParameter::at_token(
320323
&self.sema,
321324
self.token.clone(),
322-
).map(|ap| (Some(ap.ty), Some(ap.name)))
325+
).map(|ap| {
326+
let name = ap.ident().map(NameOrNameRef::Name);
327+
(Some(ap.ty), name)
328+
})
323329
.unwrap_or((None, None))
324330
},
325331
ast::RecordExprFieldList(_it) => {
326332
cov_mark::hit!(expected_type_struct_field_without_leading_char);
327333
self.token.prev_sibling_or_token()
328334
.and_then(|se| se.into_node())
329335
.and_then(|node| ast::RecordExprField::cast(node))
330-
.and_then(|rf| self.sema.resolve_record_field(&rf))
331-
.map(|f|(
336+
.and_then(|rf| self.sema.resolve_record_field(&rf).zip(Some(rf)))
337+
.map(|(f, rf)|(
332338
Some(f.0.signature_ty(self.db)),
333-
Some(f.0.name(self.db).to_string()),
339+
rf.field_name().map(NameOrNameRef::NameRef),
334340
))
335341
.unwrap_or((None, None))
336342
},
@@ -340,7 +346,7 @@ impl<'a> CompletionContext<'a> {
340346
.resolve_record_field(&it)
341347
.map(|f|(
342348
Some(f.0.signature_ty(self.db)),
343-
Some(f.0.name(self.db).to_string()),
349+
it.field_name().map(NameOrNameRef::NameRef),
344350
))
345351
.unwrap_or((None, None))
346352
},
@@ -378,12 +384,10 @@ impl<'a> CompletionContext<'a> {
378384
},
379385
}
380386
};
381-
382-
break ret;
383387
}
384388
};
385-
self.expected_type = expected.0;
386-
self.expected_name = expected.1;
389+
self.expected_type = expected_type;
390+
self.expected_name = expected_name;
387391
self.attribute_under_caret = find_node_at_offset(&file_with_fake_ident, offset);
388392

389393
// First, let's try to complete a reference to some declaration.
@@ -631,7 +635,9 @@ mod tests {
631635
.map(|t| t.display_test(&db).to_string())
632636
.unwrap_or("?".to_owned());
633637

634-
let name = completion_context.expected_name.unwrap_or("?".to_owned());
638+
let name = completion_context
639+
.expected_name
640+
.map_or_else(|| "?".to_owned(), |name| name.to_string());
635641

636642
expect.assert_eq(&format!("ty: {}, name: {}", ty, name));
637643
}

crates/ide_completion/src/render.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ impl<'a> Render<'a> {
243243

244244
item.set_relevance(CompletionRelevance {
245245
exact_type_match: compute_exact_type_match(self.ctx.completion, &ty),
246-
exact_name_match: compute_exact_name_match(self.ctx.completion, local_name.clone()),
246+
exact_name_match: compute_exact_name_match(self.ctx.completion, &local_name),
247247
is_local: true,
248248
..CompletionRelevance::default()
249249
});
@@ -319,8 +319,7 @@ fn compute_exact_type_match(ctx: &CompletionContext, completion_ty: &hir::Type)
319319

320320
fn compute_exact_name_match(ctx: &CompletionContext, completion_name: impl Into<String>) -> bool {
321321
let completion_name = completion_name.into();
322-
323-
Some(&completion_name) == ctx.expected_name.as_ref()
322+
ctx.expected_name.as_ref().map_or(false, |name| name.text() == completion_name)
324323
}
325324

326325
fn compute_ref_match(ctx: &CompletionContext, completion_ty: &hir::Type) -> Option<Mutability> {

crates/ide_db/src/call_info.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use either::Either;
44
use hir::{HasAttrs, HirDisplay, Semantics, Type};
55
use stdx::format_to;
66
use syntax::{
7-
ast::{self, ArgListOwner},
7+
ast::{self, ArgListOwner, NameOwner},
88
match_ast, AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize,
99
};
1010

@@ -142,7 +142,7 @@ fn call_info_impl(
142142
#[derive(Debug)]
143143
pub struct ActiveParameter {
144144
pub ty: Type,
145-
pub name: String,
145+
pub pat: Either<ast::SelfParam, ast::Pat>,
146146
}
147147

148148
impl ActiveParameter {
@@ -165,8 +165,14 @@ impl ActiveParameter {
165165
return None;
166166
}
167167
let (pat, ty) = params.swap_remove(idx);
168-
let name = pat?.to_string();
169-
Some(ActiveParameter { ty, name })
168+
pat.map(|pat| ActiveParameter { ty, pat })
169+
}
170+
171+
pub fn ident(&self) -> Option<ast::Name> {
172+
self.pat.as_ref().right().and_then(|param| match param {
173+
ast::Pat::IdentPat(ident) => ident.name(),
174+
_ => None,
175+
})
170176
}
171177
}
172178

crates/syntax/src/ast/node_ext.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,15 @@ impl fmt::Display for NameOrNameRef {
380380
}
381381
}
382382

383+
impl NameOrNameRef {
384+
pub fn text(&self) -> &str {
385+
match self {
386+
NameOrNameRef::Name(name) => name.text(),
387+
NameOrNameRef::NameRef(name_ref) => name_ref.text(),
388+
}
389+
}
390+
}
391+
383392
impl ast::RecordPatField {
384393
pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> {
385394
let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?;

0 commit comments

Comments
 (0)