aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/lower.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-05-04 19:07:09 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-05-04 19:07:09 +0100
commit9c49f6c36e1e097f938946811d1e2f5eb70edca9 (patch)
tree544bfd290a08475b1d5250bcc5e0717779b53758 /crates/ra_hir/src/ty/lower.rs
parentb6ffb1d2a3bcc94e41c95c7a086117e11ce487e5 (diff)
parenta4eb1a546c7623f65823c5e249cd3c6d8c90fd8c (diff)
Merge #1216
1216: Basic Chalk integration r=matklad a=flodiebold This replaces the ad-hoc `implements` check by Chalk. It doesn't yet any new functionality (e.g. where clauses aren't passed to Chalk yet). The tests that exist actually work, but it needs some refactoring, currently crashes when running analysis on the RA repo, and depends on rust-lang/chalk#216 which isn't merged yet :smile: The main work here is converting stuff back and forth and providing Chalk with the information it needs, and the canonicalization logic. Since canonicalization depends a lot on the inference table, I don't think we can currently reuse the logic from Chalk, so we need to implement it ourselves; it's not actually that complicated anyway ;) I realized that we need a `Ty::Bound` variant separate from `Ty::Param` -- these are two different things, and I think type parameters inside a function actually need to be represented in Chalk as `Placeholder` types. ~~Currently this crashes in the 'real' world because we don't yet do canonicalization when filtering method candidates. Proper canonicalization needs the inference table (to collapse different inference variables that have already been unified), but we need to be able to call the method candidate selection from the completion code... So I'm currently thinking how to best handle that :smile:~~ Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r--crates/ra_hir/src/ty/lower.rs37
1 files changed, 17 insertions, 20 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 7fac084ce..8bab7e54b 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -29,7 +29,10 @@ impl Ty {
29 TypeRef::Tuple(inner) => { 29 TypeRef::Tuple(inner) => {
30 let inner_tys = 30 let inner_tys =
31 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); 31 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
32 Ty::apply(TypeCtor::Tuple, Substs(inner_tys.into())) 32 Ty::apply(
33 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
34 Substs(inner_tys.into()),
35 )
33 } 36 }
34 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), 37 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path),
35 TypeRef::RawPtr(inner, mutability) => { 38 TypeRef::RawPtr(inner, mutability) => {
@@ -53,7 +56,7 @@ impl Ty {
53 let inner_tys = 56 let inner_tys =
54 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); 57 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
55 let sig = Substs(inner_tys.into()); 58 let sig = Substs(inner_tys.into());
56 Ty::apply(TypeCtor::FnPtr, sig) 59 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig)
57 } 60 }
58 TypeRef::Error => Ty::Unknown, 61 TypeRef::Error => Ty::Unknown,
59 } 62 }
@@ -238,6 +241,11 @@ impl TraitRef {
238 let segment = path.segments.last().expect("path should have at least one segment"); 241 let segment = path.segments.last().expect("path should have at least one segment");
239 substs_from_path_segment(db, resolver, segment, &resolved.generic_params(db), true) 242 substs_from_path_segment(db, resolver, segment, &resolved.generic_params(db), true)
240 } 243 }
244
245 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef {
246 let substs = Substs::identity(&trait_.generic_params(db));
247 TraitRef { trait_, substs }
248 }
241} 249}
242 250
243/// Build the declared type of an item. This depends on the namespace; e.g. for 251/// Build the declared type of an item. This depends on the namespace; e.g. for
@@ -299,7 +307,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
299/// function body. 307/// function body.
300fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 308fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
301 let generics = def.generic_params(db); 309 let generics = def.generic_params(db);
302 let substs = make_substs(&generics); 310 let substs = Substs::identity(&generics);
303 Ty::apply(TypeCtor::FnDef(def.into()), substs) 311 Ty::apply(TypeCtor::FnDef(def.into()), substs)
304} 312}
305 313
@@ -341,7 +349,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
341 return type_for_struct(db, def); // Unit struct 349 return type_for_struct(db, def); // Unit struct
342 } 350 }
343 let generics = def.generic_params(db); 351 let generics = def.generic_params(db);
344 let substs = make_substs(&generics); 352 let substs = Substs::identity(&generics);
345 Ty::apply(TypeCtor::FnDef(def.into()), substs) 353 Ty::apply(TypeCtor::FnDef(def.into()), substs)
346} 354}
347 355
@@ -357,7 +365,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
357 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 365 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
358 .collect::<Vec<_>>(); 366 .collect::<Vec<_>>();
359 let generics = def.parent_enum(db).generic_params(db); 367 let generics = def.parent_enum(db).generic_params(db);
360 let substs = make_substs(&generics); 368 let substs = Substs::identity(&generics);
361 let ret = type_for_enum(db, def.parent_enum(db)).subst(&substs); 369 let ret = type_for_enum(db, def.parent_enum(db)).subst(&substs);
362 FnSig::from_params_and_return(params, ret) 370 FnSig::from_params_and_return(params, ret)
363} 371}
@@ -369,36 +377,25 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) ->
369 return type_for_enum(db, def.parent_enum(db)); // Unit variant 377 return type_for_enum(db, def.parent_enum(db)); // Unit variant
370 } 378 }
371 let generics = def.parent_enum(db).generic_params(db); 379 let generics = def.parent_enum(db).generic_params(db);
372 let substs = make_substs(&generics); 380 let substs = Substs::identity(&generics);
373 Ty::apply(TypeCtor::FnDef(def.into()), substs) 381 Ty::apply(TypeCtor::FnDef(def.into()), substs)
374} 382}
375 383
376fn make_substs(generics: &GenericParams) -> Substs {
377 Substs(
378 generics
379 .params_including_parent()
380 .into_iter()
381 .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() })
382 .collect::<Vec<_>>()
383 .into(),
384 )
385}
386
387fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { 384fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
388 let generics = s.generic_params(db); 385 let generics = s.generic_params(db);
389 Ty::apply(TypeCtor::Adt(s.into()), make_substs(&generics)) 386 Ty::apply(TypeCtor::Adt(s.into()), Substs::identity(&generics))
390} 387}
391 388
392fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { 389fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
393 let generics = s.generic_params(db); 390 let generics = s.generic_params(db);
394 Ty::apply(TypeCtor::Adt(s.into()), make_substs(&generics)) 391 Ty::apply(TypeCtor::Adt(s.into()), Substs::identity(&generics))
395} 392}
396 393
397fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 394fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
398 let generics = t.generic_params(db); 395 let generics = t.generic_params(db);
399 let resolver = t.resolver(db); 396 let resolver = t.resolver(db);
400 let type_ref = t.type_ref(db); 397 let type_ref = t.type_ref(db);
401 let substs = make_substs(&generics); 398 let substs = Substs::identity(&generics);
402 let inner = Ty::from_hir(db, &resolver, &type_ref); 399 let inner = Ty::from_hir(db, &resolver, &type_ref);
403 inner.subst(&substs) 400 inner.subst(&substs)
404} 401}