From d6195fa21f09aa3f987e09d847c156e1788ec834 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 13 Mar 2020 11:45:58 +0100 Subject: Fix completion of HashMap::new The `ty` function in code_model returned the type with placeholders for type parameters. That's nice for printing, but not good for completion, because placeholders won't unify with anything else: So the type we got for `HashMap` was `HashMap`, which doesn't unify with `HashMap`, so the `new` method wasn't shown. Now we instead return `HashMap<{unknown}, {unknown}, {unknown}>`, which does unify with the impl type. Maybe we should just expose this properly as variables though, i.e. we'd return something like `exists HashMap` (in Chalk notation). It'll make the API more complicated, but harder to misuse. (And it would handle cases like `type TypeAlias = HashMap` more correctly.) --- crates/ra_hir/src/code_model.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 2854631c6..ff041150b 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -311,7 +311,11 @@ impl StructField { self.parent.variant_data(db).fields()[self.id].name.clone() } - pub fn ty(&self, db: &impl HirDatabase) -> Type { + /// Returns the type as in the signature of the struct (i.e., with + /// placeholder types for type parameters). This is good for showing + /// signature help, but not so good to actually get the type of the field + /// when you actually have a variable of the struct. + pub fn signature_ty(&self, db: &impl HirDatabase) -> Type { let var_id = self.parent.into(); let generic_def_id: GenericDefId = match self.parent { VariantDef::Struct(it) => it.id.into(), @@ -485,6 +489,10 @@ impl Adt { let subst = db.generic_defaults(self.into()); subst.iter().any(|ty| ty == &Ty::Unknown) } + + /// Turns this ADT into a type. Any type parameters of the ADT will be + /// turned into unknown types, which is good for e.g. finding the most + /// general set of completions, but will not look very nice when printed. pub fn ty(self, db: &impl HirDatabase) -> Type { let id = AdtId::from(self); Type::from_def(db, id.module(db).krate, id) @@ -1031,7 +1039,7 @@ impl Type { krate: CrateId, def: impl HasResolver + Into + Into, ) -> Type { - let substs = Substs::type_params(db, def); + let substs = Substs::build_for_def(db, def).fill_with_unknown().build(); let ty = db.ty(def.into()).subst(&substs); Type::new(db, krate, def, ty) } -- cgit v1.2.3