completion relevance consider if types can be unified
This commit is contained in:
parent
20e32fc946
commit
957939292e
@ -51,7 +51,7 @@ use hir_def::{
|
|||||||
};
|
};
|
||||||
use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
|
use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
|
||||||
use hir_ty::{
|
use hir_ty::{
|
||||||
autoderef,
|
autoderef, could_unify,
|
||||||
method_resolution::{self, TyFingerprint},
|
method_resolution::{self, TyFingerprint},
|
||||||
primitive::UintTy,
|
primitive::UintTy,
|
||||||
to_assoc_type_id,
|
to_assoc_type_id,
|
||||||
@ -2154,6 +2154,10 @@ impl Type {
|
|||||||
|
|
||||||
walk_type(db, self, &mut cb);
|
walk_type(db, self, &mut cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn could_unify_with(&self, other: &Type) -> bool {
|
||||||
|
could_unify(&self.ty, &other.ty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: closures
|
// FIXME: closures
|
||||||
|
@ -45,6 +45,11 @@ use crate::{
|
|||||||
to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind,
|
to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This lint has a false positive here. See the link below for details.
|
||||||
|
//
|
||||||
|
// https://github.com/rust-lang/rust/issues/57411
|
||||||
|
#[allow(unreachable_pub)]
|
||||||
|
pub use unify::could_unify;
|
||||||
pub(crate) use unify::unify;
|
pub(crate) use unify::unify;
|
||||||
|
|
||||||
mod unify;
|
mod unify;
|
||||||
|
@ -157,6 +157,10 @@ impl<T> Canonicalized<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
|
||||||
|
InferenceTable::new().unify(t1, t2)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
|
pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
|
||||||
let mut table = InferenceTable::new();
|
let mut table = InferenceTable::new();
|
||||||
let vars = Substitution(
|
let vars = Substitution(
|
||||||
|
@ -41,7 +41,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub use autoderef::autoderef;
|
pub use autoderef::autoderef;
|
||||||
pub use infer::{InferenceResult, InferenceVar};
|
pub use infer::{could_unify, InferenceResult, InferenceVar};
|
||||||
pub use lower::{
|
pub use lower::{
|
||||||
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
|
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
|
||||||
TyDefId, TyLoweringContext, ValueTyDefId,
|
TyDefId, TyLoweringContext, ValueTyDefId,
|
||||||
|
@ -314,7 +314,8 @@ fn compute_exact_type_match(ctx: &CompletionContext, completion_ty: &hir::Type)
|
|||||||
Some(expected_type) => {
|
Some(expected_type) => {
|
||||||
// We don't ever consider unit type to be an exact type match, since
|
// We don't ever consider unit type to be an exact type match, since
|
||||||
// nearly always this is not meaningful to the user.
|
// nearly always this is not meaningful to the user.
|
||||||
completion_ty == expected_type && !expected_type.is_unit()
|
(completion_ty == expected_type || expected_type.could_unify_with(completion_ty))
|
||||||
|
&& !expected_type.is_unit()
|
||||||
}
|
}
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
@ -1353,4 +1354,34 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
|
|||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generic_enum() {
|
||||||
|
check_relevance(
|
||||||
|
r#"
|
||||||
|
enum Foo<T> { A(T), B }
|
||||||
|
// bar() should not be an exact type match
|
||||||
|
// because the generic parameters are different
|
||||||
|
fn bar() -> Foo<u8> { Foo::B }
|
||||||
|
// FIXME baz() should be an exact type match
|
||||||
|
// because the types could unify, but it currently
|
||||||
|
// is not. This is due to the T here being
|
||||||
|
// TyKind::Placeholder rather than TyKind::Missing.
|
||||||
|
fn baz<T>() -> Foo<T> { Foo::B }
|
||||||
|
fn foo() {
|
||||||
|
let foo: Foo<u32> = Foo::B;
|
||||||
|
let _: Foo<u32> = f$0;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
ev Foo::A(…) [type]
|
||||||
|
ev Foo::B [type]
|
||||||
|
lc foo [type+local]
|
||||||
|
en Foo []
|
||||||
|
fn baz() []
|
||||||
|
fn bar() []
|
||||||
|
fn foo() []
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user