aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/traits
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/traits')
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs68
1 files changed, 55 insertions, 13 deletions
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 8b77d21b4..2772a0432 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -11,7 +11,7 @@ use ra_db::salsa::{InternId, InternKey};
11use crate::{ 11use crate::{
12 Trait, HasGenericParams, ImplBlock, 12 Trait, HasGenericParams, ImplBlock,
13 db::HirDatabase, 13 db::HirDatabase,
14 ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs}, 14 ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef,
15}; 15};
16use super::ChalkContext; 16use super::ChalkContext;
17 17
@@ -146,6 +146,27 @@ impl ToChalk for ImplBlock {
146 } 146 }
147} 147}
148 148
149impl ToChalk for GenericPredicate {
150 type Chalk = chalk_ir::QuantifiedWhereClause;
151
152 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause {
153 match self {
154 GenericPredicate::Implemented(trait_ref) => {
155 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
156 }
157 GenericPredicate::Error => panic!("Trying to pass errored where clause to Chalk"),
158 }
159 }
160
161 fn from_chalk(
162 _db: &impl HirDatabase,
163 _where_clause: chalk_ir::QuantifiedWhereClause,
164 ) -> GenericPredicate {
165 // This should never need to be called
166 unimplemented!()
167 }
168}
169
149fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { 170fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
150 chalk_ir::Binders { 171 chalk_ir::Binders {
151 value, 172 value,
@@ -153,6 +174,25 @@ fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
153 } 174 }
154} 175}
155 176
177fn convert_where_clauses(
178 db: &impl HirDatabase,
179 def: GenericDef,
180 substs: &Substs,
181) -> (Vec<chalk_ir::QuantifiedWhereClause>, bool) {
182 let generic_predicates = db.generic_predicates(def);
183 let mut result = Vec::with_capacity(generic_predicates.len());
184 let mut has_error = false;
185 for pred in generic_predicates.iter() {
186 // FIXME: it would probably be nicer if we could just convert errored predicates to a where clause that is never true...
187 if pred.is_error() {
188 has_error = true;
189 } else {
190 result.push(pred.clone().subst(substs).to_chalk(db));
191 }
192 }
193 (result, has_error)
194}
195
156impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB> 196impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB>
157where 197where
158 DB: HirDatabase, 198 DB: HirDatabase,
@@ -173,7 +213,7 @@ where
173 upstream: trait_.module(self.db).krate(self.db) != Some(self.krate), 213 upstream: trait_.module(self.db).krate(self.db) != Some(self.krate),
174 fundamental: false, 214 fundamental: false,
175 }; 215 };
176 let where_clauses = Vec::new(); // FIXME add where clauses 216 let (where_clauses, _) = convert_where_clauses(self.db, trait_.into(), &bound_vars);
177 let associated_ty_ids = Vec::new(); // FIXME add associated tys 217 let associated_ty_ids = Vec::new(); // FIXME add associated tys
178 let trait_datum_bound = 218 let trait_datum_bound =
179 chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids }; 219 chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids };
@@ -185,21 +225,26 @@ where
185 let type_ctor = from_chalk(self.db, struct_id); 225 let type_ctor = from_chalk(self.db, struct_id);
186 // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor 226 // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor
187 // FIXME extract this to a method on Ty 227 // FIXME extract this to a method on Ty
188 let (num_params, upstream) = match type_ctor { 228 let (num_params, where_clauses, upstream) = match type_ctor {
189 TypeCtor::Bool 229 TypeCtor::Bool
190 | TypeCtor::Char 230 | TypeCtor::Char
191 | TypeCtor::Int(_) 231 | TypeCtor::Int(_)
192 | TypeCtor::Float(_) 232 | TypeCtor::Float(_)
193 | TypeCtor::Never 233 | TypeCtor::Never
194 | TypeCtor::Str => (0, true), 234 | TypeCtor::Str => (0, vec![], true),
195 TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => (1, true), 235 TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => {
196 TypeCtor::FnPtr { num_args } => (num_args as usize + 1, true), 236 (1, vec![], true)
197 TypeCtor::Tuple { cardinality } => (cardinality as usize, true), 237 }
238 TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true),
239 TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true),
198 TypeCtor::FnDef(_) => unimplemented!(), 240 TypeCtor::FnDef(_) => unimplemented!(),
199 TypeCtor::Adt(adt) => { 241 TypeCtor::Adt(adt) => {
200 let generic_params = adt.generic_params(self.db); 242 let generic_params = adt.generic_params(self.db);
243 let bound_vars = Substs::bound_vars(&generic_params);
244 let (where_clauses, _) = convert_where_clauses(self.db, adt.into(), &bound_vars);
201 ( 245 (
202 generic_params.count_params_including_parent(), 246 generic_params.count_params_including_parent(),
247 where_clauses,
203 adt.krate(self.db) != Some(self.krate), 248 adt.krate(self.db) != Some(self.krate),
204 ) 249 )
205 } 250 }
@@ -209,7 +254,6 @@ where
209 // FIXME set fundamental flag correctly 254 // FIXME set fundamental flag correctly
210 fundamental: false, 255 fundamental: false,
211 }; 256 };
212 let where_clauses = Vec::new(); // FIXME add where clauses
213 let self_ty = chalk_ir::ApplicationTy { 257 let self_ty = chalk_ir::ApplicationTy {
214 name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()), 258 name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()),
215 parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(), 259 parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(),
@@ -237,10 +281,12 @@ where
237 } else { 281 } else {
238 chalk_rust_ir::ImplType::External 282 chalk_rust_ir::ImplType::External
239 }; 283 };
284 let (where_clauses, where_clause_error) =
285 convert_where_clauses(self.db, impl_block.into(), &bound_vars);
240 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { 286 let impl_datum_bound = chalk_rust_ir::ImplDatumBound {
241 // FIXME handle negative impls (impl !Sync for Foo) 287 // FIXME handle negative impls (impl !Sync for Foo)
242 trait_ref: chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref.to_chalk(self.db)), 288 trait_ref: chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref.to_chalk(self.db)),
243 where_clauses: Vec::new(), // FIXME add where clauses 289 where_clauses,
244 associated_ty_values: Vec::new(), // FIXME add associated type values 290 associated_ty_values: Vec::new(), // FIXME add associated type values
245 impl_type, 291 impl_type,
246 }; 292 };
@@ -253,10 +299,6 @@ where
253 self.db 299 self.db
254 .impls_for_trait(self.krate, trait_) 300 .impls_for_trait(self.krate, trait_)
255 .iter() 301 .iter()
256 // FIXME temporary hack -- as long as we're not lowering where clauses
257 // correctly, ignore impls with them completely so as to not treat
258 // impl<T> Trait for T where T: ... as a blanket impl on all types
259 .filter(|impl_block| impl_block.generic_params(self.db).where_predicates.is_empty())
260 .map(|impl_block| impl_block.to_chalk(self.db)) 302 .map(|impl_block| impl_block.to_chalk(self.db))
261 .collect() 303 .collect()
262 } 304 }