aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/traits
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-09 08:50:18 +0100
committerbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-09 08:50:18 +0100
commitf59cd1a4a0d6c369025a7014e838d25f91d478e4 (patch)
tree2c4b9dc868a87507ed63e9dc46530cc60f38ae64 /crates/ra_hir/src/ty/traits
parent35f28c538a9b9f461bb4db1a78d02e9f02a3d296 (diff)
parent9afbf2dff43dee3227358f10162d4c77d192ce7a (diff)
Merge #1515
1515: Trait environment r=matklad a=flodiebold This adds the environment, i.e. the set of `where` clauses in scope, when solving trait goals. That means that e.g. in ```rust fn foo<T: SomeTrait>(t: T) {} ``` , we are able to complete methods of `SomeTrait` on the `t`. This affects the trait APIs quite a bit (since every method that needs to be able to solve for some trait needs to get this environment somehow), so I thought I'd do it rather sooner than later ;) 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.rs99
1 files changed, 98 insertions, 1 deletions
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 4c3744b44..2df4dd13f 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -12,7 +12,7 @@ use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum};
12use ra_db::salsa::{InternId, InternKey}; 12use ra_db::salsa::{InternId, InternKey};
13use test_utils::tested_by; 13use test_utils::tested_by;
14 14
15use super::ChalkContext; 15use super::{Canonical, ChalkContext, Obligation};
16use crate::{ 16use crate::{
17 db::HirDatabase, 17 db::HirDatabase,
18 generics::GenericDef, 18 generics::GenericDef,
@@ -218,6 +218,103 @@ impl ToChalk for ProjectionTy {
218 } 218 }
219} 219}
220 220
221impl ToChalk for super::ProjectionPredicate {
222 type Chalk = chalk_ir::Normalize;
223
224 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize {
225 chalk_ir::Normalize {
226 projection: self.projection_ty.to_chalk(db),
227 ty: self.ty.to_chalk(db),
228 }
229 }
230
231 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self {
232 unimplemented!()
233 }
234}
235
236impl ToChalk for Obligation {
237 type Chalk = chalk_ir::DomainGoal;
238
239 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal {
240 match self {
241 Obligation::Trait(tr) => tr.to_chalk(db).cast(),
242 Obligation::Projection(pr) => pr.to_chalk(db).cast(),
243 }
244 }
245
246 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal) -> Self {
247 unimplemented!()
248 }
249}
250
251impl<T> ToChalk for Canonical<T>
252where
253 T: ToChalk,
254{
255 type Chalk = chalk_ir::Canonical<T::Chalk>;
256
257 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
258 let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT);
259 let value = self.value.to_chalk(db);
260 let canonical = chalk_ir::Canonical { value, binders: vec![parameter; self.num_vars] };
261 canonical
262 }
263
264 fn from_chalk(db: &impl HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
265 Canonical { num_vars: canonical.binders.len(), value: from_chalk(db, canonical.value) }
266 }
267}
268
269impl ToChalk for Arc<super::Environment> {
270 type Chalk = Arc<chalk_ir::Environment>;
271
272 fn to_chalk(self, db: &impl HirDatabase) -> Arc<chalk_ir::Environment> {
273 let mut clauses = Vec::new();
274 for pred in &self.predicates {
275 if pred.is_error() {
276 // for env, we just ignore errors
277 continue;
278 }
279 if let GenericPredicate::Implemented(trait_ref) = pred {
280 if blacklisted_trait(db, trait_ref.trait_) {
281 continue;
282 }
283 }
284 clauses.push(pred.clone().to_chalk(db).cast());
285 }
286 chalk_ir::Environment::new().add_clauses(clauses)
287 }
288
289 fn from_chalk(
290 _db: &impl HirDatabase,
291 _env: Arc<chalk_ir::Environment>,
292 ) -> Arc<super::Environment> {
293 unimplemented!()
294 }
295}
296
297impl<T: ToChalk> ToChalk for super::InEnvironment<T> {
298 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
299
300 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
301 chalk_ir::InEnvironment {
302 environment: self.environment.to_chalk(db),
303 goal: self.value.to_chalk(db),
304 }
305 }
306
307 fn from_chalk(
308 db: &impl HirDatabase,
309 in_env: chalk_ir::InEnvironment<T::Chalk>,
310 ) -> super::InEnvironment<T> {
311 super::InEnvironment {
312 environment: from_chalk(db, in_env.environment),
313 value: from_chalk(db, in_env.goal),
314 }
315 }
316}
317
221fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { 318fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
222 chalk_ir::Binders { 319 chalk_ir::Binders {
223 value, 320 value,