diff options
Diffstat (limited to 'crates/hir_ty/src/traits')
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 26 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 107 |
2 files changed, 79 insertions, 54 deletions
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index bef6e7e9c..080764e76 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -19,10 +19,10 @@ use crate::{ | |||
19 | display::HirDisplay, | 19 | display::HirDisplay, |
20 | from_assoc_type_id, | 20 | from_assoc_type_id, |
21 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | 21 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, |
22 | to_assoc_type_id, | 22 | to_assoc_type_id, to_chalk_trait_id, |
23 | utils::generics, | 23 | utils::generics, |
24 | BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate, | 24 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, |
25 | ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind, | 25 | GenericPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind, |
26 | }; | 26 | }; |
27 | use mapping::{ | 27 | use mapping::{ |
28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, | 28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, |
@@ -219,9 +219,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
219 | // for<T> <Self> [Future<Self>, Future::Output<Self> = T] | 219 | // for<T> <Self> [Future<Self>, Future::Output<Self> = T] |
220 | // ^1 ^0 ^0 ^0 ^1 | 220 | // ^1 ^0 ^0 ^0 ^1 |
221 | let impl_bound = GenericPredicate::Implemented(TraitRef { | 221 | let impl_bound = GenericPredicate::Implemented(TraitRef { |
222 | trait_: future_trait, | 222 | trait_id: to_chalk_trait_id(future_trait), |
223 | // Self type as the first parameter. | 223 | // Self type as the first parameter. |
224 | substs: Substitution::single( | 224 | substitution: Substitution::single( |
225 | TyKind::BoundVar(BoundVar { | 225 | TyKind::BoundVar(BoundVar { |
226 | debruijn: DebruijnIndex::INNERMOST, | 226 | debruijn: DebruijnIndex::INNERMOST, |
227 | index: 0, | 227 | index: 0, |
@@ -229,18 +229,18 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
229 | .intern(&Interner), | 229 | .intern(&Interner), |
230 | ), | 230 | ), |
231 | }); | 231 | }); |
232 | let proj_bound = GenericPredicate::Projection(ProjectionPredicate { | 232 | let proj_bound = GenericPredicate::AliasEq(AliasEq { |
233 | // The parameter of the opaque type. | 233 | alias: AliasTy::Projection(ProjectionTy { |
234 | ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }) | ||
235 | .intern(&Interner), | ||
236 | projection_ty: ProjectionTy { | ||
237 | associated_ty_id: to_assoc_type_id(future_output), | 234 | associated_ty_id: to_assoc_type_id(future_output), |
238 | // Self type as the first parameter. | 235 | // Self type as the first parameter. |
239 | substitution: Substitution::single( | 236 | substitution: Substitution::single( |
240 | TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) | 237 | TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) |
241 | .intern(&Interner), | 238 | .intern(&Interner), |
242 | ), | 239 | ), |
243 | }, | 240 | }), |
241 | // The parameter of the opaque type. | ||
242 | ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }) | ||
243 | .intern(&Interner), | ||
244 | }); | 244 | }); |
245 | let bound = OpaqueTyDatumBound { | 245 | let bound = OpaqueTyDatumBound { |
246 | bounds: make_binders( | 246 | bounds: make_binders( |
@@ -546,7 +546,7 @@ fn impl_def_datum( | |||
546 | 546 | ||
547 | let generic_params = generics(db.upcast(), impl_id.into()); | 547 | let generic_params = generics(db.upcast(), impl_id.into()); |
548 | let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); | 548 | let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); |
549 | let trait_ = trait_ref.trait_; | 549 | let trait_ = trait_ref.hir_trait_id(); |
550 | let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate { | 550 | let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate { |
551 | rust_ir::ImplType::Local | 551 | rust_ir::ImplType::Local |
552 | } else { | 552 | } else { |
@@ -614,7 +614,7 @@ fn type_alias_associated_ty_value( | |||
614 | let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved | 614 | let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved |
615 | 615 | ||
616 | let assoc_ty = db | 616 | let assoc_ty = db |
617 | .trait_data(trait_ref.trait_) | 617 | .trait_data(trait_ref.hir_trait_id()) |
618 | .associated_type_by_name(&type_alias_data.name) | 618 | .associated_type_by_name(&type_alias_data.name) |
619 | .expect("assoc ty value should not exist"); // validated when building the impl data as well | 619 | .expect("assoc ty value should not exist"); // validated when building the impl data as well |
620 | let ty = db.ty(type_alias.into()); | 620 | let ty = db.ty(type_alias.into()); |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index d969527dc..62b779008 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -14,8 +14,8 @@ use crate::{ | |||
14 | from_assoc_type_id, | 14 | from_assoc_type_id, |
15 | primitive::UintTy, | 15 | primitive::UintTy, |
16 | traits::{Canonical, Obligation}, | 16 | traits::{Canonical, Obligation}, |
17 | AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, | 17 | AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, ProjectionTy, |
18 | ProjectionPredicate, ProjectionTy, Scalar, Substitution, TraitRef, Ty, | 18 | Scalar, Substitution, TraitRef, Ty, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | use super::interner::*; | 21 | use super::interner::*; |
@@ -239,15 +239,15 @@ impl ToChalk for TraitRef { | |||
239 | type Chalk = chalk_ir::TraitRef<Interner>; | 239 | type Chalk = chalk_ir::TraitRef<Interner>; |
240 | 240 | ||
241 | fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> { | 241 | fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> { |
242 | let trait_id = self.trait_.to_chalk(db); | 242 | let trait_id = self.trait_id; |
243 | let substitution = self.substs.to_chalk(db); | 243 | let substitution = self.substitution.to_chalk(db); |
244 | chalk_ir::TraitRef { trait_id, substitution } | 244 | chalk_ir::TraitRef { trait_id, substitution } |
245 | } | 245 | } |
246 | 246 | ||
247 | fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self { | 247 | fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self { |
248 | let trait_ = from_chalk(db, trait_ref.trait_id); | 248 | let trait_id = trait_ref.trait_id; |
249 | let substs = from_chalk(db, trait_ref.substitution); | 249 | let substs = from_chalk(db, trait_ref.substitution); |
250 | TraitRef { trait_, substs } | 250 | TraitRef { trait_id, substitution: substs } |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
@@ -314,12 +314,10 @@ impl ToChalk for GenericPredicate { | |||
314 | let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner); | 314 | let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner); |
315 | make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0) | 315 | make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0) |
316 | } | 316 | } |
317 | GenericPredicate::Projection(projection_pred) => { | 317 | GenericPredicate::AliasEq(alias_eq) => make_binders( |
318 | let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner); | 318 | chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db).shifted_in(&Interner)), |
319 | let projection = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner); | 319 | 0, |
320 | let alias = chalk_ir::AliasTy::Projection(projection); | 320 | ), |
321 | make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0) | ||
322 | } | ||
323 | GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), | 321 | GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), |
324 | } | 322 | } |
325 | } | 323 | } |
@@ -338,16 +336,8 @@ impl ToChalk for GenericPredicate { | |||
338 | chalk_ir::WhereClause::Implemented(tr) => { | 336 | chalk_ir::WhereClause::Implemented(tr) => { |
339 | GenericPredicate::Implemented(from_chalk(db, tr)) | 337 | GenericPredicate::Implemented(from_chalk(db, tr)) |
340 | } | 338 | } |
341 | chalk_ir::WhereClause::AliasEq(projection_eq) => { | 339 | chalk_ir::WhereClause::AliasEq(alias_eq) => { |
342 | let projection_ty = from_chalk( | 340 | GenericPredicate::AliasEq(from_chalk(db, alias_eq)) |
343 | db, | ||
344 | match projection_eq.alias { | ||
345 | chalk_ir::AliasTy::Projection(p) => p, | ||
346 | _ => unimplemented!(), | ||
347 | }, | ||
348 | ); | ||
349 | let ty = from_chalk(db, projection_eq.ty); | ||
350 | GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty }) | ||
351 | } | 341 | } |
352 | 342 | ||
353 | chalk_ir::WhereClause::LifetimeOutlives(_) => { | 343 | chalk_ir::WhereClause::LifetimeOutlives(_) => { |
@@ -383,19 +373,55 @@ impl ToChalk for ProjectionTy { | |||
383 | } | 373 | } |
384 | } | 374 | } |
385 | } | 375 | } |
376 | impl ToChalk for OpaqueTy { | ||
377 | type Chalk = chalk_ir::OpaqueTy<Interner>; | ||
378 | |||
379 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk { | ||
380 | chalk_ir::OpaqueTy { | ||
381 | opaque_ty_id: self.opaque_ty_id, | ||
382 | substitution: self.substitution.to_chalk(db), | ||
383 | } | ||
384 | } | ||
385 | |||
386 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { | ||
387 | OpaqueTy { | ||
388 | opaque_ty_id: chalk.opaque_ty_id, | ||
389 | substitution: from_chalk(db, chalk.substitution), | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | |||
394 | impl ToChalk for AliasTy { | ||
395 | type Chalk = chalk_ir::AliasTy<Interner>; | ||
396 | |||
397 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk { | ||
398 | match self { | ||
399 | AliasTy::Projection(projection_ty) => { | ||
400 | chalk_ir::AliasTy::Projection(projection_ty.to_chalk(db)) | ||
401 | } | ||
402 | AliasTy::Opaque(opaque_ty) => chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)), | ||
403 | } | ||
404 | } | ||
405 | |||
406 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { | ||
407 | match chalk { | ||
408 | chalk_ir::AliasTy::Projection(projection_ty) => { | ||
409 | AliasTy::Projection(from_chalk(db, projection_ty)) | ||
410 | } | ||
411 | chalk_ir::AliasTy::Opaque(opaque_ty) => AliasTy::Opaque(from_chalk(db, opaque_ty)), | ||
412 | } | ||
413 | } | ||
414 | } | ||
386 | 415 | ||
387 | impl ToChalk for ProjectionPredicate { | 416 | impl ToChalk for AliasEq { |
388 | type Chalk = chalk_ir::AliasEq<Interner>; | 417 | type Chalk = chalk_ir::AliasEq<Interner>; |
389 | 418 | ||
390 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> { | 419 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> { |
391 | chalk_ir::AliasEq { | 420 | chalk_ir::AliasEq { alias: self.alias.to_chalk(db), ty: self.ty.to_chalk(db) } |
392 | alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)), | ||
393 | ty: self.ty.to_chalk(db), | ||
394 | } | ||
395 | } | 421 | } |
396 | 422 | ||
397 | fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self { | 423 | fn from_chalk(db: &dyn HirDatabase, alias_eq: chalk_ir::AliasEq<Interner>) -> Self { |
398 | unimplemented!() | 424 | AliasEq { alias: from_chalk(db, alias_eq.alias), ty: from_chalk(db, alias_eq.ty) } |
399 | } | 425 | } |
400 | } | 426 | } |
401 | 427 | ||
@@ -405,7 +431,7 @@ impl ToChalk for Obligation { | |||
405 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { | 431 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { |
406 | match self { | 432 | match self { |
407 | Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner), | 433 | Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner), |
408 | Obligation::Projection(pr) => pr.to_chalk(db).cast(&Interner), | 434 | Obligation::AliasEq(alias_eq) => alias_eq.to_chalk(db).cast(&Interner), |
409 | } | 435 | } |
410 | } | 436 | } |
411 | 437 | ||
@@ -515,42 +541,41 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
515 | // We don't have a special type for this, but Chalk does. | 541 | // We don't have a special type for this, but Chalk does. |
516 | match pred { | 542 | match pred { |
517 | GenericPredicate::Implemented(trait_ref) => { | 543 | GenericPredicate::Implemented(trait_ref) => { |
518 | if &trait_ref.substs[0] != self_ty { | 544 | if &trait_ref.substitution[0] != self_ty { |
519 | // we can only convert predicates back to type bounds if they | 545 | // we can only convert predicates back to type bounds if they |
520 | // have the expected self type | 546 | // have the expected self type |
521 | return None; | 547 | return None; |
522 | } | 548 | } |
523 | let args_no_self = trait_ref.substs[1..] | 549 | let args_no_self = trait_ref.substitution[1..] |
524 | .iter() | 550 | .iter() |
525 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | 551 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) |
526 | .collect(); | 552 | .collect(); |
527 | let trait_bound = | 553 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; |
528 | rust_ir::TraitBound { trait_id: trait_ref.trait_.to_chalk(db), args_no_self }; | ||
529 | Some(rust_ir::InlineBound::TraitBound(trait_bound)) | 554 | Some(rust_ir::InlineBound::TraitBound(trait_bound)) |
530 | } | 555 | } |
531 | GenericPredicate::Projection(proj) => { | 556 | GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { |
532 | if &proj.projection_ty.substitution[0] != self_ty { | 557 | if &projection_ty.substitution[0] != self_ty { |
533 | return None; | 558 | return None; |
534 | } | 559 | } |
535 | let trait_ = match from_assoc_type_id(proj.projection_ty.associated_ty_id) | 560 | let trait_ = match from_assoc_type_id(projection_ty.associated_ty_id) |
536 | .lookup(db.upcast()) | 561 | .lookup(db.upcast()) |
537 | .container | 562 | .container |
538 | { | 563 | { |
539 | AssocContainerId::TraitId(t) => t, | 564 | AssocContainerId::TraitId(t) => t, |
540 | _ => panic!("associated type not in trait"), | 565 | _ => panic!("associated type not in trait"), |
541 | }; | 566 | }; |
542 | let args_no_self = proj.projection_ty.substitution[1..] | 567 | let args_no_self = projection_ty.substitution[1..] |
543 | .iter() | 568 | .iter() |
544 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | 569 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) |
545 | .collect(); | 570 | .collect(); |
546 | let alias_eq_bound = rust_ir::AliasEqBound { | 571 | let alias_eq_bound = rust_ir::AliasEqBound { |
547 | value: proj.ty.clone().to_chalk(db), | 572 | value: ty.clone().to_chalk(db), |
548 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | 573 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, |
549 | associated_ty_id: proj.projection_ty.associated_ty_id, | 574 | associated_ty_id: projection_ty.associated_ty_id, |
550 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | 575 | parameters: Vec::new(), // FIXME we don't support generic associated types yet |
551 | }; | 576 | }; |
552 | Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) | 577 | Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) |
553 | } | 578 | } |
554 | GenericPredicate::Error => None, | 579 | _ => None, |
555 | } | 580 | } |
556 | } | 581 | } |