This commit is contained in:
Lukas Tobias Wirth 2021-05-05 22:55:12 +02:00
parent d26fb188c1
commit 3f796fea9f
6 changed files with 38 additions and 39 deletions

View file

@ -1744,6 +1744,10 @@ impl Type {
}
}
pub fn strip_references(&self) -> Type {
self.derived(self.ty.strip_references().clone())
}
pub fn is_unknown(&self) -> bool {
self.ty.is_unknown()
}

View file

@ -218,9 +218,7 @@ fn hint_iterator(
ty: &hir::Type,
) -> Option<SmolStr> {
let db = sema.db;
let strukt = std::iter::successors(Some(ty.clone()), |ty| ty.remove_ref())
.last()
.and_then(|strukt| strukt.as_adt())?;
let strukt = ty.strip_references().as_adt()?;
let krate = strukt.krate(db);
if krate != famous_defs.core()? {
return None;

View file

@ -203,41 +203,37 @@ impl Completions {
fn complete_enum_variants(
acc: &mut Completions,
ctx: &CompletionContext,
ty: &hir::Type,
enum_data: hir::Enum,
cb: impl Fn(&mut Completions, &CompletionContext, hir::Variant, hir::ModPath),
) {
if let Some(hir::Adt::Enum(enum_data)) =
iter::successors(Some(ty.clone()), |ty| ty.remove_ref()).last().and_then(|ty| ty.as_adt())
{
let variants = enum_data.variants(ctx.db);
let variants = enum_data.variants(ctx.db);
let module = if let Some(module) = ctx.scope.module() {
// Compute path from the completion site if available.
module
} else {
// Otherwise fall back to the enum's definition site.
enum_data.module(ctx.db)
};
let module = if let Some(module) = ctx.scope.module() {
// Compute path from the completion site if available.
module
} else {
// Otherwise fall back to the enum's definition site.
enum_data.module(ctx.db)
};
if let Some(impl_) = ctx.impl_def.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) {
if impl_.self_ty(ctx.db) == *ty {
for &variant in &variants {
let self_path = hir::ModPath::from_segments(
hir::PathKind::Plain,
iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))),
);
cb(acc, ctx, variant, self_path);
}
if let Some(impl_) = ctx.impl_def.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) {
if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_data)) {
for &variant in &variants {
let self_path = hir::ModPath::from_segments(
hir::PathKind::Plain,
iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))),
);
cb(acc, ctx, variant, self_path);
}
}
}
for variant in variants {
if let Some(path) = module.find_use_path(ctx.db, hir::ModuleDef::from(variant)) {
// Variants with trivial paths are already added by the existing completion logic,
// so we should avoid adding these twice
if path.segments().len() > 1 {
cb(acc, ctx, variant, path);
}
for variant in variants {
if let Some(path) = module.find_use_path(ctx.db, hir::ModuleDef::from(variant)) {
// Variants with trivial paths are already added by the existing completion logic,
// so we should avoid adding these twice
if path.segments().len() > 1 {
cb(acc, ctx, variant, path);
}
}
}

View file

@ -12,8 +12,10 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
}
if !ctx.is_irrefutable_pat_binding {
if let Some(ty) = ctx.expected_type.as_ref() {
super::complete_enum_variants(acc, ctx, ty, |acc, ctx, variant, path| {
if let Some(hir::Adt::Enum(e)) =
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
{
super::complete_enum_variants(acc, ctx, e, |acc, ctx, variant, path| {
acc.add_qualified_variant_pat(ctx, variant, path.clone());
acc.add_qualified_enum_variant(ctx, variant, path);
});

View file

@ -35,14 +35,11 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
None => return,
};
let ref_removed_ty =
std::iter::successors(Some(receiver_ty.clone()), |ty| ty.remove_ref()).last().unwrap();
let cap = match ctx.config.snippet_cap {
Some(it) => it,
None => return,
};
let try_enum = TryEnum::from_ty(&ctx.sema, &ref_removed_ty);
let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty.strip_references());
if let Some(try_enum) = &try_enum {
match try_enum {
TryEnum::Result => {

View file

@ -17,8 +17,10 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
return;
}
if let Some(ty) = &ctx.expected_type {
super::complete_enum_variants(acc, ctx, ty, |acc, ctx, variant, path| {
if let Some(hir::Adt::Enum(e)) =
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
{
super::complete_enum_variants(acc, ctx, e, |acc, ctx, variant, path| {
acc.add_qualified_enum_variant(ctx, variant, path)
});
}