aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/chalk.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-03-04 22:00:44 +0000
committerFlorian Diebold <[email protected]>2020-06-05 16:08:27 +0100
commit02962b374ecefd6f2a75956f4fb18806531d1d51 (patch)
tree7c807d6a09db7e485ea39c3e67331b99829a364c /crates/ra_hir_ty/src/traits/chalk.rs
parent9c52f527a1cef7d39c2b1c55b49dc5459d392a4d (diff)
Implement return position impl trait / opaque type support
This is working, but I'm not that happy with how the lowering works. We might need an additional representation between `TypeRef` and `Ty` where names are resolved and `impl Trait` bounds are separated out, but things like inference variables don't exist and `impl Trait` is always represented the same way. Also note that this doesn't implement correct handling of RPIT *inside* the function (which involves turning the `impl Trait`s into variables and creating obligations for them). That intermediate representation might help there as well.
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs52
1 files changed, 42 insertions, 10 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 61de3cc30..a72a82f5a 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -4,7 +4,7 @@ use std::sync::Arc;
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; 6use chalk_ir::{fold::shift::Shift, GenericArg, TypeName};
7use chalk_solve::rust_ir::{self, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use hir_def::{ 9use hir_def::{
10 lang_item::{lang_attr, LangItemTarget}, 10 lang_item::{lang_attr, LangItemTarget},
@@ -100,6 +100,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
100 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { 100 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
101 self.db.associated_ty_value(self.krate, id) 101 self.db.associated_ty_value(self.krate, id)
102 } 102 }
103
103 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> { 104 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> {
104 vec![] 105 vec![]
105 } 106 }
@@ -130,11 +131,34 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
130 self.db.program_clauses_for_chalk_env(self.krate, environment.clone()) 131 self.db.program_clauses_for_chalk_env(self.krate, environment.clone())
131 } 132 }
132 133
133 fn opaque_ty_data( 134 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
134 &self, 135 let interned_id = crate::db::InternedOpaqueTyId::from(id);
135 _id: chalk_ir::OpaqueTyId<Interner>, 136 let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
136 ) -> Arc<rust_ir::OpaqueTyDatum<Interner>> { 137 let (func, idx) = match full_id {
137 unimplemented!() 138 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => (func, idx),
139 };
140 let datas =
141 self.db.return_type_impl_traits(func).expect("impl trait id without impl traits");
142 let data = &datas.value.impl_traits[idx as usize];
143 let bound = OpaqueTyDatumBound {
144 bounds: make_binders(
145 data.bounds
146 .value
147 .iter()
148 .cloned()
149 .filter(|b| !b.is_error())
150 .map(|b| b.to_chalk(self.db))
151 .collect(),
152 1,
153 ),
154 };
155 let num_vars = datas.num_binders;
156 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) })
157 }
158
159 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
160 // FIXME: actually provide the hidden type; it is relevant for auto traits
161 Ty::Unknown.to_chalk(self.db)
138 } 162 }
139 163
140 fn force_impl_for( 164 fn force_impl_for(
@@ -150,10 +174,6 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
150 // FIXME: implement actual object safety 174 // FIXME: implement actual object safety
151 true 175 true
152 } 176 }
153
154 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
155 Ty::Unknown.to_chalk(self.db)
156 }
157} 177}
158 178
159pub(crate) fn program_clauses_for_chalk_env_query( 179pub(crate) fn program_clauses_for_chalk_env_query(
@@ -460,6 +480,18 @@ impl From<crate::traits::GlobalImplId> for ImplId {
460 } 480 }
461} 481}
462 482
483impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
484 fn from(id: OpaqueTyId) -> Self {
485 InternKey::from_intern_id(id.0)
486 }
487}
488
489impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
490 fn from(id: crate::db::InternedOpaqueTyId) -> Self {
491 chalk_ir::OpaqueTyId(id.as_intern_id())
492 }
493}
494
463impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { 495impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId {
464 fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self { 496 fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self {
465 Self::from_intern_id(id.0) 497 Self::from_intern_id(id.0)