) -> CompletionItem {
let is_deprecated = ctx.is_deprecated(field);
let name = field.name(ctx.db());
- let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+ let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
let mut item = CompletionItem::new(
SymbolKind::Field,
ctx.source_range(),
- receiver.map_or_else(|| name.clone(), |receiver| format!("{}.{}", receiver, name).into()),
+ field_with_receiver(receiver.as_ref(), &name),
);
item.set_relevance(CompletionRelevance {
type_match: compute_type_match(ctx.completion, ty),
.set_documentation(field.docs(ctx.db()))
.set_deprecated(is_deprecated)
.lookup_by(name.clone());
- item.insert_text(escaped_name);
+ item.insert_text(field_with_receiver(receiver.as_ref(), &escaped_name));
if let Some(receiver) = &dot_access.receiver {
if let Some(original) = ctx.completion.sema.original_ast_node(receiver.clone()) {
if let Some(ref_match) = compute_ref_match(ctx.completion, ty) {
item.build()
}
+fn field_with_receiver(receiver: Option<&hir::Name>, field_name: &str) -> SmolStr {
+ receiver
+ .map_or_else(|| field_name.into(), |receiver| format!("{}.{}", receiver, field_name).into())
+}
+
pub(crate) fn render_tuple_field(
ctx: RenderContext<'_>,
receiver: Option<hir::Name>,
let mut item = CompletionItem::new(
SymbolKind::Field,
ctx.source_range(),
- receiver.map_or_else(|| field.to_string(), |receiver| format!("{}.{}", receiver, field)),
+ field_with_receiver(receiver.as_ref(), &field.to_string()),
);
item.detail(ty.display(ctx.db()).to_string()).lookup_by(field.to_string());
item.build()
}
-pub(crate) fn render_type_inference(ty_string: String, ctx: &CompletionContext<'_>) -> CompletionItem {
+pub(crate) fn render_type_inference(
+ ty_string: String,
+ ctx: &CompletionContext<'_>,
+) -> CompletionItem {
let mut builder =
CompletionItem::new(CompletionItemKind::InferredType, ctx.source_range(), ty_string);
builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() });
let name = local_name.to_smol_str();
let mut item = render_resolution_simple_(ctx, &local_name, import_to_add, resolution);
- if local_name.escaped().is_escaped() {
- item.insert_text(local_name.escaped().to_smol_str());
+ if local_name.is_escaped() {
+ item.insert_text(local_name.to_smol_str());
}
// Add `<>` for generic types
let type_path_no_ty_args = matches!(
item.lookup_by(name.clone())
.label(SmolStr::from_iter([&name, "<…>"]))
.trigger_call_info()
- .insert_snippet(cap, format!("{}<$0>", local_name.escaped()));
+ .insert_snippet(cap, format!("{}<$0>", local_name));
}
}
}
let ctx = ctx.import_to_add(import_to_add);
let kind = res_to_kind(resolution);
- let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.to_smol_str());
+ let mut item =
+ CompletionItem::new(kind, ctx.source_range(), local_name.unescaped().to_smol_str());
item.set_relevance(ctx.completion_relevance())
.set_documentation(scope_def_docs(db, resolution))
.set_deprecated(scope_def_is_deprecated(&ctx, resolution));
kind: SymbolKind(
Variant,
),
+ lookup: "Foo{}",
detail: "Foo { x: i32, y: i32 }",
},
]
kind: SymbolKind(
Variant,
),
+ lookup: "Foo()",
detail: "Foo(i32, i32)",
},
]
kind: SymbolKind(
Variant,
),
- lookup: "Spam::Bar(…)",
+ lookup: "Spam::Bar()",
detail: "m::Spam::Bar(i32)",
relevance: CompletionRelevance {
exact_name_match: false,
st S []
st &mut S [type]
st S []
- fn main() []
fn foo(…) []
+ fn main() []
"#]],
);
check_relevance(
lc s [type+name+local]
st S [type]
st S []
- fn main() []
fn foo(…) []
+ fn main() []
"#]],
);
check_relevance(
lc ssss [type+local]
st S [type]
st S []
- fn main() []
fn foo(…) []
+ fn main() []
"#]],
);
}
lc &t [type+local]
st S []
st &S [type]
- st T []
st S []
- fn main() []
+ st T []
fn foo(…) []
+ fn main() []
md core []
- tt Sized []
"#]],
)
}
lc &mut t [type+local]
st S []
st &mut S [type]
- st T []
st S []
- fn main() []
+ st T []
fn foo(…) []
+ fn main() []
md core []
- tt Sized []
"#]],
)
}
expect![[r#"
st S []
st &S [type]
- st T []
st S []
- fn main() []
+ st T []
fn bar() []
fn &bar() [type]
fn foo(…) []
+ fn main() []
md core []
- tt Sized []
"#]],
)
}
ev Foo::B [type_could_unify]
fn foo() []
en Foo []
- fn baz() []
fn bar() []
+ fn baz() []
"#]],
);
}
}
"#,
expect![[r#"
- md std []
st Buffer []
fn f() []
+ md std []
tt BufRead (use std::io::BufRead) [requires_import]
st BufReader (use std::io::BufReader) [requires_import]
st BufWriter (use std::io::BufWriter) [requires_import]
struct r#struct {}
trait r#trait { type r#type; }
impl r#trait for r#struct { type r#type = $0; }
+"#,
+ )
+ }
+
+ #[test]
+ fn field_access_includes_self() {
+ check_edit(
+ "length",
+ r#"
+struct S {
+ length: i32
+}
+
+impl S {
+ fn some_fn(&self) {
+ let l = len$0
+ }
+}
+"#,
+ r#"
+struct S {
+ length: i32
+}
+
+impl S {
+ fn some_fn(&self) {
+ let l = self.length
+ }
+}
"#,
)
}