aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/traits
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-08-12 20:43:57 +0100
committerbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-08-12 20:43:57 +0100
commit2c65a059840dd2092a00e90337a8221cd832c456 (patch)
treefa1f8c46158271eb859928ed9da3eb389f861c09 /crates/ra_hir/src/ty/traits
parent0cf48e48d75d267bfa38ff1319e7f7c0468fb53f (diff)
parent5af9691dc9132db61b50c4e90cdeda6fea0c5dd9 (diff)
Merge #1677
1677: Associated types r=flodiebold a=flodiebold This implements basic support for (fully qualified) associated type projections: - handle fully qualified paths like `<T as Trait>::AssocType` (basically desugaring to something like `Trait<Self=T>::AssocType`) - lower these to a new `Ty::Projection` enum variant - also introduce `Ty::UnselectedProjection` for cases like `T::AssocType` where the trait from which the type comes isn't specified, but these aren't handled further so far - in inference, normalize these projections using Chalk: basically, when encountering a type e.g. from a type annotation or signature, we replace these `Ty::Projection`s by type variables and add obligations to normalize the associated type Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/traits')
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs51
1 files changed, 45 insertions, 6 deletions
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 9e7ae0724..6df7094c5 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -45,11 +45,33 @@ impl ToChalk for Ty {
45 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty { 45 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty {
46 match self { 46 match self {
47 Ty::Apply(apply_ty) => { 47 Ty::Apply(apply_ty) => {
48 let struct_id = apply_ty.ctor.to_chalk(db); 48 let name = match apply_ty.ctor {
49 let name = TypeName::TypeKindId(struct_id.into()); 49 TypeCtor::AssociatedType(type_alias) => {
50 let type_id = type_alias.to_chalk(db);
51 TypeName::AssociatedType(type_id)
52 }
53 _ => {
54 // other TypeCtors get interned and turned into a chalk StructId
55 let struct_id = apply_ty.ctor.to_chalk(db);
56 TypeName::TypeKindId(struct_id.into())
57 }
58 };
50 let parameters = apply_ty.parameters.to_chalk(db); 59 let parameters = apply_ty.parameters.to_chalk(db);
51 chalk_ir::ApplicationTy { name, parameters }.cast() 60 chalk_ir::ApplicationTy { name, parameters }.cast()
52 } 61 }
62 Ty::Projection(proj_ty) => {
63 let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
64 let parameters = proj_ty.parameters.to_chalk(db);
65 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast()
66 }
67 Ty::UnselectedProjection(proj_ty) => {
68 let type_name = lalrpop_intern::intern(&proj_ty.type_name.to_string());
69 let parameters = proj_ty.parameters.to_chalk(db);
70 chalk_ir::Ty::UnselectedProjection(chalk_ir::UnselectedProjectionTy {
71 type_name,
72 parameters,
73 })
74 }
53 Ty::Param { idx, .. } => { 75 Ty::Param { idx, .. } => {
54 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty() 76 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty()
55 } 77 }
@@ -66,15 +88,21 @@ impl ToChalk for Ty {
66 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self { 88 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self {
67 match chalk { 89 match chalk {
68 chalk_ir::Ty::Apply(apply_ty) => { 90 chalk_ir::Ty::Apply(apply_ty) => {
91 // FIXME this is kind of hacky due to the fact that
92 // TypeName::Placeholder is a Ty::Param on our side
69 match apply_ty.name { 93 match apply_ty.name {
70 TypeName::TypeKindId(TypeKindId::StructId(struct_id)) => { 94 TypeName::TypeKindId(TypeKindId::StructId(struct_id)) => {
71 let ctor = from_chalk(db, struct_id); 95 let ctor = from_chalk(db, struct_id);
72 let parameters = from_chalk(db, apply_ty.parameters); 96 let parameters = from_chalk(db, apply_ty.parameters);
73 Ty::Apply(ApplicationTy { ctor, parameters }) 97 Ty::Apply(ApplicationTy { ctor, parameters })
74 } 98 }
99 TypeName::AssociatedType(type_id) => {
100 let ctor = TypeCtor::AssociatedType(from_chalk(db, type_id));
101 let parameters = from_chalk(db, apply_ty.parameters);
102 Ty::Apply(ApplicationTy { ctor, parameters })
103 }
75 // FIXME handle TypeKindId::Trait/Type here 104 // FIXME handle TypeKindId::Trait/Type here
76 TypeName::TypeKindId(_) => unimplemented!(), 105 TypeName::TypeKindId(_) => unimplemented!(),
77 TypeName::AssociatedType(_) => unimplemented!(),
78 TypeName::Placeholder(idx) => { 106 TypeName::Placeholder(idx) => {
79 assert_eq!(idx.ui, UniverseIndex::ROOT); 107 assert_eq!(idx.ui, UniverseIndex::ROOT);
80 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() } 108 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() }
@@ -389,11 +417,12 @@ where
389 &self, 417 &self,
390 projection: &'p chalk_ir::ProjectionTy, 418 projection: &'p chalk_ir::ProjectionTy,
391 ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { 419 ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) {
392 debug!("split_projection {:?}", projection); 420 let proj_ty: ProjectionTy = from_chalk(self.db, projection.clone());
393 unimplemented!() 421 debug!("split_projection {:?} = {}", projection, proj_ty.display(self.db));
422 // we don't support GATs, so I think this should always be correct currently
423 (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[])
394 } 424 }
395 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause> { 425 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause> {
396 debug!("custom_clauses");
397 vec![] 426 vec![]
398 } 427 }
399 fn all_structs(&self) -> Vec<chalk_ir::StructId> { 428 fn all_structs(&self) -> Vec<chalk_ir::StructId> {
@@ -529,6 +558,16 @@ pub(crate) fn struct_datum_query(
529 adt.krate(db) != Some(krate), 558 adt.krate(db) != Some(krate),
530 ) 559 )
531 } 560 }
561 TypeCtor::AssociatedType(type_alias) => {
562 let generic_params = type_alias.generic_params(db);
563 let bound_vars = Substs::bound_vars(&generic_params);
564 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
565 (
566 generic_params.count_params_including_parent(),
567 where_clauses,
568 type_alias.krate(db) != Some(krate),
569 )
570 }
532 }; 571 };
533 let flags = chalk_rust_ir::StructFlags { 572 let flags = chalk_rust_ir::StructFlags {
534 upstream, 573 upstream,