aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/Cargo.toml7
-rw-r--r--crates/ra_hir_ty/src/db.rs35
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs4
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs17
-rw-r--r--crates/ra_hir_ty/src/traits.rs24
-rw-r--r--crates/ra_hir_ty/src/traits/builtin.rs49
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs468
7 files changed, 326 insertions, 278 deletions
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index d277bf2bc..60793db44 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -21,10 +21,9 @@ ra_prof = { path = "../ra_prof" }
21ra_syntax = { path = "../ra_syntax" } 21ra_syntax = { path = "../ra_syntax" }
22test_utils = { path = "../test_utils" } 22test_utils = { path = "../test_utils" }
23 23
24# https://github.com/rust-lang/chalk/pull/294 24chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" }
25chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" } 25chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" }
26chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" } 26chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" }
27chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" }
28 27
29lalrpop-intern = "0.15.1" 28lalrpop-intern = "0.15.1"
30 29
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index 222a36a9f..d52f65b83 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -10,7 +10,7 @@ use ra_db::{salsa, CrateId};
10 10
11use crate::{ 11use crate::{
12 method_resolution::CrateImplBlocks, 12 method_resolution::CrateImplBlocks,
13 traits::{AssocTyValue, Impl}, 13 traits::{chalk, AssocTyValue, Impl},
14 CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor, 14 CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor,
15 ValueTyDefId, 15 ValueTyDefId,
16}; 16};
@@ -77,39 +77,24 @@ pub trait HirDatabase: DefDatabase {
77 #[salsa::interned] 77 #[salsa::interned]
78 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId; 78 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId;
79 79
80 #[salsa::invoke(crate::traits::chalk::associated_ty_data_query)] 80 #[salsa::invoke(chalk::associated_ty_data_query)]
81 fn associated_ty_data( 81 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>;
82 &self,
83 id: chalk_ir::TypeId,
84 ) -> Arc<chalk_rust_ir::AssociatedTyDatum<chalk_ir::family::ChalkIr>>;
85 82
86 #[salsa::invoke(crate::traits::chalk::trait_datum_query)] 83 #[salsa::invoke(chalk::trait_datum_query)]
87 fn trait_datum( 84 fn trait_datum(&self, krate: CrateId, trait_id: chalk::TraitId) -> Arc<chalk::TraitDatum>;
88 &self,
89 krate: CrateId,
90 trait_id: chalk_ir::TraitId,
91 ) -> Arc<chalk_rust_ir::TraitDatum<chalk_ir::family::ChalkIr>>;
92 85
93 #[salsa::invoke(crate::traits::chalk::struct_datum_query)] 86 #[salsa::invoke(chalk::struct_datum_query)]
94 fn struct_datum( 87 fn struct_datum(&self, krate: CrateId, struct_id: chalk::StructId) -> Arc<chalk::StructDatum>;
95 &self,
96 krate: CrateId,
97 struct_id: chalk_ir::StructId,
98 ) -> Arc<chalk_rust_ir::StructDatum<chalk_ir::family::ChalkIr>>;
99 88
100 #[salsa::invoke(crate::traits::chalk::impl_datum_query)] 89 #[salsa::invoke(crate::traits::chalk::impl_datum_query)]
101 fn impl_datum( 90 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>;
102 &self,
103 krate: CrateId,
104 impl_id: chalk_ir::ImplId,
105 ) -> Arc<chalk_rust_ir::ImplDatum<chalk_ir::family::ChalkIr>>;
106 91
107 #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)] 92 #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)]
108 fn associated_ty_value( 93 fn associated_ty_value(
109 &self, 94 &self,
110 krate: CrateId, 95 krate: CrateId,
111 id: chalk_rust_ir::AssociatedTyValueId, 96 id: chalk::AssociatedTyValueId,
112 ) -> Arc<chalk_rust_ir::AssociatedTyValue<chalk_ir::family::ChalkIr>>; 97 ) -> Arc<chalk::AssociatedTyValue>;
113 98
114 #[salsa::invoke(crate::traits::trait_solve_query)] 99 #[salsa::invoke(crate::traits::trait_solve_query)]
115 fn trait_solve( 100 fn trait_solve(
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index 45164c9e9..ce9a06fde 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -865,7 +865,7 @@ mod foo {
865 865
866#[test] 866#[test]
867fn method_resolution_where_clause_for_unknown_trait() { 867fn method_resolution_where_clause_for_unknown_trait() {
868 // The blanket impl shouldn't apply because we can't even resolve UnknownTrait 868 // The blanket impl currently applies because we ignore the unresolved where clause
869 let t = type_at( 869 let t = type_at(
870 r#" 870 r#"
871//- /main.rs 871//- /main.rs
@@ -875,7 +875,7 @@ impl<T> Trait for T where T: UnknownTrait {}
875fn test() { (&S).foo()<|>; } 875fn test() { (&S).foo()<|>; }
876"#, 876"#,
877 ); 877 );
878 assert_eq!(t, "{unknown}"); 878 assert_eq!(t, "u128");
879} 879}
880 880
881#[test] 881#[test]
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 76e2198b6..ae316922b 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -959,6 +959,23 @@ fn test() {
959} 959}
960 960
961#[test] 961#[test]
962fn error_bound_chalk() {
963 let t = type_at(
964 r#"
965//- /main.rs
966trait Trait {
967 fn foo(&self) -> u32 {}
968}
969
970fn test(x: (impl Trait + UnknownTrait)) {
971 x.foo()<|>;
972}
973"#,
974 );
975 assert_eq!(t, "u32");
976}
977
978#[test]
962fn assoc_type_bindings() { 979fn assoc_type_bindings() {
963 assert_snapshot!( 980 assert_snapshot!(
964 infer(r#" 981 infer(r#"
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index d49f8fb4b..c4dc857bc 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -1,7 +1,7 @@
1//! Trait solving using Chalk. 1//! Trait solving using Chalk.
2use std::sync::{Arc, Mutex}; 2use std::sync::{Arc, Mutex};
3 3
4use chalk_ir::{cast::Cast, family::ChalkIr}; 4use chalk_ir::cast::Cast;
5use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId}; 5use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId};
6use log::debug; 6use log::debug;
7use ra_db::{impl_intern_key, salsa, CrateId}; 7use ra_db::{impl_intern_key, salsa, CrateId};
@@ -12,7 +12,7 @@ use crate::db::HirDatabase;
12 12
13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
14 14
15use self::chalk::{from_chalk, ToChalk}; 15use self::chalk::{from_chalk, ToChalk, TypeFamily};
16 16
17pub(crate) mod chalk; 17pub(crate) mod chalk;
18mod builtin; 18mod builtin;
@@ -20,7 +20,7 @@ mod builtin;
20#[derive(Debug, Clone)] 20#[derive(Debug, Clone)]
21pub struct TraitSolver { 21pub struct TraitSolver {
22 krate: CrateId, 22 krate: CrateId,
23 inner: Arc<Mutex<chalk_solve::Solver<ChalkIr>>>, 23 inner: Arc<Mutex<chalk_solve::Solver<TypeFamily>>>,
24} 24}
25 25
26/// We need eq for salsa 26/// We need eq for salsa
@@ -36,8 +36,8 @@ impl TraitSolver {
36 fn solve( 36 fn solve(
37 &self, 37 &self,
38 db: &impl HirDatabase, 38 db: &impl HirDatabase,
39 goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<ChalkIr>>>, 39 goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<TypeFamily>>>,
40 ) -> Option<chalk_solve::Solution<ChalkIr>> { 40 ) -> Option<chalk_solve::Solution<TypeFamily>> {
41 let context = ChalkContext { db, krate: self.krate }; 41 let context = ChalkContext { db, krate: self.krate };
42 debug!("solve goal: {:?}", goal); 42 debug!("solve goal: {:?}", goal);
43 let mut solver = match self.inner.lock() { 43 let mut solver = match self.inner.lock() {
@@ -201,17 +201,17 @@ pub(crate) fn trait_solve_query(
201 201
202fn solution_from_chalk( 202fn solution_from_chalk(
203 db: &impl HirDatabase, 203 db: &impl HirDatabase,
204 solution: chalk_solve::Solution<ChalkIr>, 204 solution: chalk_solve::Solution<TypeFamily>,
205) -> Solution { 205) -> Solution {
206 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<ChalkIr>>| { 206 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<TypeFamily>>| {
207 let value = subst 207 let value = subst
208 .value 208 .value
209 .parameters 209 .parameters
210 .into_iter() 210 .into_iter()
211 .map(|p| { 211 .map(|p| {
212 let ty = match p { 212 let ty = match p.ty() {
213 chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty), 213 Some(ty) => from_chalk(db, ty.clone()),
214 chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(), 214 None => unimplemented!(),
215 }; 215 };
216 ty 216 ty
217 }) 217 })
@@ -291,7 +291,7 @@ impl FnTrait {
291 } 291 }
292} 292}
293 293
294#[derive(Debug, Clone, PartialEq, Eq, Hash)] 294#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
295pub struct ClosureFnTraitImplData { 295pub struct ClosureFnTraitImplData {
296 def: DefWithBodyId, 296 def: DefWithBodyId,
297 expr: ExprId, 297 expr: ExprId,
@@ -300,7 +300,7 @@ pub struct ClosureFnTraitImplData {
300 300
301/// An impl. Usually this comes from an impl block, but some built-in types get 301/// An impl. Usually this comes from an impl block, but some built-in types get
302/// synthetic impls. 302/// synthetic impls.
303#[derive(Debug, Clone, PartialEq, Eq, Hash)] 303#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
304pub enum Impl { 304pub enum Impl {
305 /// A normal impl from an impl block. 305 /// A normal impl from an impl block.
306 ImplBlock(ImplId), 306 ImplBlock(ImplId),
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs
index cd587a338..dd41176f0 100644
--- a/crates/ra_hir_ty/src/traits/builtin.rs
+++ b/crates/ra_hir_ty/src/traits/builtin.rs
@@ -28,24 +28,24 @@ pub(super) fn get_builtin_impls(
28 trait_: TraitId, 28 trait_: TraitId,
29 mut callback: impl FnMut(Impl), 29 mut callback: impl FnMut(Impl),
30) { 30) {
31 // Note: since impl_datum needs to be infallible, we need to make sure here
32 // that we have all prerequisites to build the respective impls.
31 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty { 33 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty {
32 for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() 34 for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter()
33 { 35 {
34 if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) { 36 if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) {
35 if trait_ == actual_trait { 37 if trait_ == actual_trait {
36 let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait }; 38 let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait };
37 callback(Impl::ClosureFnTraitImpl(impl_)); 39 if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) {
40 callback(Impl::ClosureFnTraitImpl(impl_));
41 }
38 } 42 }
39 } 43 }
40 } 44 }
41 } 45 }
42} 46}
43 47
44pub(super) fn impl_datum( 48pub(super) fn impl_datum(db: &impl HirDatabase, krate: CrateId, impl_: Impl) -> BuiltinImplData {
45 db: &impl HirDatabase,
46 krate: CrateId,
47 impl_: Impl,
48) -> Option<BuiltinImplData> {
49 match impl_ { 49 match impl_ {
50 Impl::ImplBlock(_) => unreachable!(), 50 Impl::ImplBlock(_) => unreachable!(),
51 Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), 51 Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data),
@@ -65,21 +65,38 @@ pub(super) fn associated_ty_value(
65 } 65 }
66} 66}
67 67
68fn check_closure_fn_trait_impl_prerequisites(
69 db: &impl HirDatabase,
70 krate: CrateId,
71 data: super::ClosureFnTraitImplData,
72) -> bool {
73 // the respective Fn/FnOnce/FnMut trait needs to exist
74 if get_fn_trait(db, krate, data.fn_trait).is_none() {
75 return false;
76 }
77
78 // FIXME: there are more assumptions that we should probably check here:
79 // the traits having no type params, FnOnce being a supertrait
80
81 // the FnOnce trait needs to exist and have an assoc type named Output
82 let fn_once_trait = match get_fn_trait(db, krate, super::FnTrait::FnOnce) {
83 Some(t) => t,
84 None => return false,
85 };
86 db.trait_data(fn_once_trait).associated_type_by_name(&name![Output]).is_some()
87}
88
68fn closure_fn_trait_impl_datum( 89fn closure_fn_trait_impl_datum(
69 db: &impl HirDatabase, 90 db: &impl HirDatabase,
70 krate: CrateId, 91 krate: CrateId,
71 data: super::ClosureFnTraitImplData, 92 data: super::ClosureFnTraitImplData,
72) -> Option<BuiltinImplData> { 93) -> BuiltinImplData {
73 // for some closure |X, Y| -> Z: 94 // for some closure |X, Y| -> Z:
74 // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V } 95 // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V }
75 96
76 let trait_ = get_fn_trait(db, krate, data.fn_trait)?; // get corresponding fn trait 97 let trait_ = get_fn_trait(db, krate, data.fn_trait) // get corresponding fn trait
77 98 // the existence of the Fn trait has been checked before
78 // validate FnOnce trait, since we need it in the assoc ty value definition 99 .expect("fn trait for closure impl missing");
79 // and don't want to return a valid value only to find out later that FnOnce
80 // is broken
81 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
82 let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
83 100
84 let num_args: u16 = match &db.body(data.def.into())[data.expr] { 101 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
85 Expr::Lambda { args, .. } => args.len() as u16, 102 Expr::Lambda { args, .. } => args.len() as u16,
@@ -107,12 +124,12 @@ fn closure_fn_trait_impl_datum(
107 124
108 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()); 125 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone());
109 126
110 Some(BuiltinImplData { 127 BuiltinImplData {
111 num_vars: num_args as usize + 1, 128 num_vars: num_args as usize + 1,
112 trait_ref, 129 trait_ref,
113 where_clauses: Vec::new(), 130 where_clauses: Vec::new(),
114 assoc_ty_values: vec![output_ty_id], 131 assoc_ty_values: vec![output_ty_id],
115 }) 132 }
116} 133}
117 134
118fn closure_fn_trait_output_assoc_ty_value( 135fn closure_fn_trait_output_assoc_ty_value(
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 5eb032d86..555930c9b 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -1,17 +1,11 @@
1//! Conversion code from/to Chalk. 1//! Conversion code from/to Chalk.
2use std::sync::Arc; 2use std::{fmt, sync::Arc};
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{ 6use chalk_ir::{cast::Cast, Parameter, PlaceholderIndex, TypeName, UniverseIndex};
7 cast::Cast, family::ChalkIr, Identifier, Parameter, PlaceholderIndex, TypeId, TypeKindId,
8 TypeName, UniverseIndex,
9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11 7
12use hir_def::{ 8use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
13 AssocContainerId, AssocItemId, GenericDefId, HasModule, ImplId, Lookup, TraitId, TypeAliasId,
14};
15use ra_db::{ 9use ra_db::{
16 salsa::{InternId, InternKey}, 10 salsa::{InternId, InternKey},
17 CrateId, 11 CrateId,
@@ -23,9 +17,83 @@ use crate::{
23 ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 17 ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
24}; 18};
25 19
26/// This represents a trait whose name we could not resolve. 20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
27const UNKNOWN_TRAIT: chalk_ir::TraitId = 21pub struct TypeFamily {}
28 chalk_ir::TraitId(chalk_ir::RawId { index: u32::max_value() }); 22
23impl chalk_ir::family::TypeFamily for TypeFamily {
24 type InternedType = Box<chalk_ir::TyData<Self>>;
25 type InternedLifetime = chalk_ir::LifetimeData<Self>;
26 type InternedParameter = chalk_ir::ParameterData<Self>;
27 type DefId = InternId;
28
29 // FIXME: implement these
30 fn debug_struct_id(
31 _type_kind_id: chalk_ir::StructId<Self>,
32 _fmt: &mut fmt::Formatter<'_>,
33 ) -> Option<fmt::Result> {
34 None
35 }
36
37 fn debug_trait_id(
38 _type_kind_id: chalk_ir::TraitId<Self>,
39 _fmt: &mut fmt::Formatter<'_>,
40 ) -> Option<fmt::Result> {
41 None
42 }
43
44 fn debug_assoc_type_id(
45 _id: chalk_ir::AssocTypeId<Self>,
46 _fmt: &mut fmt::Formatter<'_>,
47 ) -> Option<fmt::Result> {
48 None
49 }
50
51 fn debug_projection(
52 _projection: &chalk_ir::ProjectionTy<Self>,
53 _fmt: &mut fmt::Formatter<'_>,
54 ) -> Option<fmt::Result> {
55 None
56 }
57
58 fn intern_ty(ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> {
59 Box::new(ty)
60 }
61
62 fn ty_data(ty: &Box<chalk_ir::TyData<Self>>) -> &chalk_ir::TyData<Self> {
63 ty
64 }
65
66 fn intern_lifetime(lifetime: chalk_ir::LifetimeData<Self>) -> chalk_ir::LifetimeData<Self> {
67 lifetime
68 }
69
70 fn lifetime_data(lifetime: &chalk_ir::LifetimeData<Self>) -> &chalk_ir::LifetimeData<Self> {
71 lifetime
72 }
73
74 fn intern_parameter(parameter: chalk_ir::ParameterData<Self>) -> chalk_ir::ParameterData<Self> {
75 parameter
76 }
77
78 fn parameter_data(parameter: &chalk_ir::ParameterData<Self>) -> &chalk_ir::ParameterData<Self> {
79 parameter
80 }
81}
82
83impl chalk_ir::family::HasTypeFamily for TypeFamily {
84 type TypeFamily = Self;
85}
86
87pub type AssocTypeId = chalk_ir::AssocTypeId<TypeFamily>;
88pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<TypeFamily>;
89pub type TraitId = chalk_ir::TraitId<TypeFamily>;
90pub type TraitDatum = chalk_rust_ir::TraitDatum<TypeFamily>;
91pub type StructId = chalk_ir::StructId<TypeFamily>;
92pub type StructDatum = chalk_rust_ir::StructDatum<TypeFamily>;
93pub type ImplId = chalk_ir::ImplId<TypeFamily>;
94pub type ImplDatum = chalk_rust_ir::ImplDatum<TypeFamily>;
95pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId;
96pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<TypeFamily>;
29 97
30pub(super) trait ToChalk { 98pub(super) trait ToChalk {
31 type Chalk; 99 type Chalk;
@@ -41,21 +109,11 @@ where
41} 109}
42 110
43impl ToChalk for Ty { 111impl ToChalk for Ty {
44 type Chalk = chalk_ir::Ty<ChalkIr>; 112 type Chalk = chalk_ir::Ty<TypeFamily>;
45 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<ChalkIr> { 113 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<TypeFamily> {
46 match self { 114 match self {
47 Ty::Apply(apply_ty) => { 115 Ty::Apply(apply_ty) => {
48 let name = match apply_ty.ctor { 116 let name = apply_ty.ctor.to_chalk(db);
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 };
59 let parameters = apply_ty.parameters.to_chalk(db); 117 let parameters = apply_ty.parameters.to_chalk(db);
60 chalk_ir::ApplicationTy { name, parameters }.cast().intern() 118 chalk_ir::ApplicationTy { name, parameters }.cast().intern()
61 } 119 }
@@ -65,17 +123,30 @@ impl ToChalk for Ty {
65 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast().intern() 123 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast().intern()
66 } 124 }
67 Ty::Param { idx, .. } => { 125 Ty::Param { idx, .. } => {
68 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty::<ChalkIr>() 126 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }
127 .to_ty::<TypeFamily>()
69 } 128 }
70 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), 129 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(),
71 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 130 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
72 Ty::Dyn(predicates) => { 131 Ty::Dyn(predicates) => {
73 let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); 132 let where_clauses = predicates
74 chalk_ir::TyData::Dyn(make_binders(where_clauses, 1)).intern() 133 .iter()
134 .filter(|p| !p.is_error())
135 .cloned()
136 .map(|p| p.to_chalk(db))
137 .collect();
138 let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) };
139 chalk_ir::TyData::Dyn(bounded_ty).intern()
75 } 140 }
76 Ty::Opaque(predicates) => { 141 Ty::Opaque(predicates) => {
77 let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); 142 let where_clauses = predicates
78 chalk_ir::TyData::Opaque(make_binders(where_clauses, 1)).intern() 143 .iter()
144 .filter(|p| !p.is_error())
145 .cloned()
146 .map(|p| p.to_chalk(db))
147 .collect();
148 let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) };
149 chalk_ir::TyData::Opaque(bounded_ty).intern()
79 } 150 }
80 Ty::Unknown => { 151 Ty::Unknown => {
81 let parameters = Vec::new(); 152 let parameters = Vec::new();
@@ -84,30 +155,19 @@ impl ToChalk for Ty {
84 } 155 }
85 } 156 }
86 } 157 }
87 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<ChalkIr>) -> Self { 158 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<TypeFamily>) -> Self {
88 match chalk.data().clone() { 159 match chalk.data().clone() {
89 chalk_ir::TyData::Apply(apply_ty) => { 160 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
90 // FIXME this is kind of hacky due to the fact that 161 TypeName::Error => Ty::Unknown,
91 // TypeName::Placeholder is a Ty::Param on our side 162 _ => {
92 match apply_ty.name { 163 let ctor = from_chalk(db, apply_ty.name);
93 TypeName::TypeKindId(TypeKindId::StructId(struct_id)) => { 164 let parameters = from_chalk(db, apply_ty.parameters);
94 let ctor = from_chalk(db, struct_id); 165 Ty::Apply(ApplicationTy { ctor, parameters })
95 let parameters = from_chalk(db, apply_ty.parameters);
96 Ty::Apply(ApplicationTy { ctor, parameters })
97 }
98 TypeName::AssociatedType(type_id) => {
99 let ctor = TypeCtor::AssociatedType(from_chalk(db, type_id));
100 let parameters = from_chalk(db, apply_ty.parameters);
101 Ty::Apply(ApplicationTy { ctor, parameters })
102 }
103 TypeName::Error => Ty::Unknown,
104 // FIXME handle TypeKindId::Trait/Type here
105 TypeName::TypeKindId(_) => unimplemented!(),
106 TypeName::Placeholder(idx) => {
107 assert_eq!(idx.ui, UniverseIndex::ROOT);
108 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() }
109 }
110 } 166 }
167 },
168 chalk_ir::TyData::Placeholder(idx) => {
169 assert_eq!(idx.ui, UniverseIndex::ROOT);
170 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() }
111 } 171 }
112 chalk_ir::TyData::Projection(proj) => { 172 chalk_ir::TyData::Projection(proj) => {
113 let associated_ty = from_chalk(db, proj.associated_ty_id); 173 let associated_ty = from_chalk(db, proj.associated_ty_id);
@@ -118,15 +178,15 @@ impl ToChalk for Ty {
118 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32), 178 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32),
119 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, 179 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
120 chalk_ir::TyData::Dyn(where_clauses) => { 180 chalk_ir::TyData::Dyn(where_clauses) => {
121 assert_eq!(where_clauses.binders.len(), 1); 181 assert_eq!(where_clauses.bounds.binders.len(), 1);
122 let predicates = 182 let predicates =
123 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); 183 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect();
124 Ty::Dyn(predicates) 184 Ty::Dyn(predicates)
125 } 185 }
126 chalk_ir::TyData::Opaque(where_clauses) => { 186 chalk_ir::TyData::Opaque(where_clauses) => {
127 assert_eq!(where_clauses.binders.len(), 1); 187 assert_eq!(where_clauses.bounds.binders.len(), 1);
128 let predicates = 188 let predicates =
129 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); 189 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect();
130 Ty::Opaque(predicates) 190 Ty::Opaque(predicates)
131 } 191 }
132 } 192 }
@@ -134,18 +194,21 @@ impl ToChalk for Ty {
134} 194}
135 195
136impl ToChalk for Substs { 196impl ToChalk for Substs {
137 type Chalk = Vec<chalk_ir::Parameter<ChalkIr>>; 197 type Chalk = Vec<chalk_ir::Parameter<TypeFamily>>;
138 198
139 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<ChalkIr>> { 199 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<TypeFamily>> {
140 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() 200 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect()
141 } 201 }
142 202
143 fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter<ChalkIr>>) -> Substs { 203 fn from_chalk(
204 db: &impl HirDatabase,
205 parameters: Vec<chalk_ir::Parameter<TypeFamily>>,
206 ) -> Substs {
144 let tys = parameters 207 let tys = parameters
145 .into_iter() 208 .into_iter()
146 .map(|p| match p { 209 .map(|p| match p.ty() {
147 chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty), 210 Some(ty) => from_chalk(db, ty.clone()),
148 chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(), 211 None => unimplemented!(),
149 }) 212 })
150 .collect(); 213 .collect();
151 Substs(tys) 214 Substs(tys)
@@ -153,88 +216,102 @@ impl ToChalk for Substs {
153} 216}
154 217
155impl ToChalk for TraitRef { 218impl ToChalk for TraitRef {
156 type Chalk = chalk_ir::TraitRef<ChalkIr>; 219 type Chalk = chalk_ir::TraitRef<TypeFamily>;
157 220
158 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<ChalkIr> { 221 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<TypeFamily> {
159 let trait_id = self.trait_.to_chalk(db); 222 let trait_id = self.trait_.to_chalk(db);
160 let parameters = self.substs.to_chalk(db); 223 let parameters = self.substs.to_chalk(db);
161 chalk_ir::TraitRef { trait_id, parameters } 224 chalk_ir::TraitRef { trait_id, parameters }
162 } 225 }
163 226
164 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<ChalkIr>) -> Self { 227 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<TypeFamily>) -> Self {
165 let trait_ = from_chalk(db, trait_ref.trait_id); 228 let trait_ = from_chalk(db, trait_ref.trait_id);
166 let substs = from_chalk(db, trait_ref.parameters); 229 let substs = from_chalk(db, trait_ref.parameters);
167 TraitRef { trait_, substs } 230 TraitRef { trait_, substs }
168 } 231 }
169} 232}
170 233
171impl ToChalk for TraitId { 234impl ToChalk for hir_def::TraitId {
172 type Chalk = chalk_ir::TraitId; 235 type Chalk = TraitId;
173 236
174 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { 237 fn to_chalk(self, _db: &impl HirDatabase) -> TraitId {
175 chalk_ir::TraitId(id_to_chalk(self)) 238 chalk_ir::TraitId(self.as_intern_id())
176 } 239 }
177 240
178 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId { 241 fn from_chalk(_db: &impl HirDatabase, trait_id: TraitId) -> hir_def::TraitId {
179 id_from_chalk(trait_id.0) 242 InternKey::from_intern_id(trait_id.0)
180 } 243 }
181} 244}
182 245
183impl ToChalk for TypeCtor { 246impl ToChalk for TypeCtor {
184 type Chalk = chalk_ir::StructId; 247 type Chalk = TypeName<TypeFamily>;
185 248
186 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::StructId { 249 fn to_chalk(self, db: &impl HirDatabase) -> TypeName<TypeFamily> {
187 db.intern_type_ctor(self).into() 250 match self {
251 TypeCtor::AssociatedType(type_alias) => {
252 let type_id = type_alias.to_chalk(db);
253 TypeName::AssociatedType(type_id)
254 }
255 _ => {
256 // other TypeCtors get interned and turned into a chalk StructId
257 let struct_id = db.intern_type_ctor(self).into();
258 TypeName::Struct(struct_id)
259 }
260 }
188 } 261 }
189 262
190 fn from_chalk(db: &impl HirDatabase, struct_id: chalk_ir::StructId) -> TypeCtor { 263 fn from_chalk(db: &impl HirDatabase, type_name: TypeName<TypeFamily>) -> TypeCtor {
191 db.lookup_intern_type_ctor(struct_id.into()) 264 match type_name {
265 TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
266 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
267 TypeName::Error => {
268 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
269 unreachable!()
270 }
271 }
192 } 272 }
193} 273}
194 274
195impl ToChalk for Impl { 275impl ToChalk for Impl {
196 type Chalk = chalk_ir::ImplId; 276 type Chalk = ImplId;
197 277
198 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ImplId { 278 fn to_chalk(self, db: &impl HirDatabase) -> ImplId {
199 db.intern_chalk_impl(self).into() 279 db.intern_chalk_impl(self).into()
200 } 280 }
201 281
202 fn from_chalk(db: &impl HirDatabase, impl_id: chalk_ir::ImplId) -> Impl { 282 fn from_chalk(db: &impl HirDatabase, impl_id: ImplId) -> Impl {
203 db.lookup_intern_chalk_impl(impl_id.into()) 283 db.lookup_intern_chalk_impl(impl_id.into())
204 } 284 }
205} 285}
206 286
207impl ToChalk for TypeAliasId { 287impl ToChalk for TypeAliasId {
208 type Chalk = chalk_ir::TypeId; 288 type Chalk = AssocTypeId;
209 289
210 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { 290 fn to_chalk(self, _db: &impl HirDatabase) -> AssocTypeId {
211 chalk_ir::TypeId(id_to_chalk(self)) 291 chalk_ir::AssocTypeId(self.as_intern_id())
212 } 292 }
213 293
214 fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAliasId { 294 fn from_chalk(_db: &impl HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId {
215 id_from_chalk(type_alias_id.0) 295 InternKey::from_intern_id(type_alias_id.0)
216 } 296 }
217} 297}
218 298
219impl ToChalk for AssocTyValue { 299impl ToChalk for AssocTyValue {
220 type Chalk = chalk_rust_ir::AssociatedTyValueId; 300 type Chalk = AssociatedTyValueId;
221 301
222 fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::AssociatedTyValueId { 302 fn to_chalk(self, db: &impl HirDatabase) -> AssociatedTyValueId {
223 db.intern_assoc_ty_value(self).into() 303 db.intern_assoc_ty_value(self).into()
224 } 304 }
225 305
226 fn from_chalk( 306 fn from_chalk(db: &impl HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue {
227 db: &impl HirDatabase,
228 assoc_ty_value_id: chalk_rust_ir::AssociatedTyValueId,
229 ) -> AssocTyValue {
230 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into()) 307 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into())
231 } 308 }
232} 309}
233 310
234impl ToChalk for GenericPredicate { 311impl ToChalk for GenericPredicate {
235 type Chalk = chalk_ir::QuantifiedWhereClause<ChalkIr>; 312 type Chalk = chalk_ir::QuantifiedWhereClause<TypeFamily>;
236 313
237 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<ChalkIr> { 314 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<TypeFamily> {
238 match self { 315 match self {
239 GenericPredicate::Implemented(trait_ref) => { 316 GenericPredicate::Implemented(trait_ref) => {
240 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 317 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
@@ -246,26 +323,16 @@ impl ToChalk for GenericPredicate {
246 }), 323 }),
247 0, 324 0,
248 ), 325 ),
249 GenericPredicate::Error => { 326 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
250 let impossible_trait_ref = chalk_ir::TraitRef {
251 trait_id: UNKNOWN_TRAIT,
252 parameters: vec![Ty::Unknown.to_chalk(db).cast()],
253 };
254 make_binders(chalk_ir::WhereClause::Implemented(impossible_trait_ref), 0)
255 }
256 } 327 }
257 } 328 }
258 329
259 fn from_chalk( 330 fn from_chalk(
260 db: &impl HirDatabase, 331 db: &impl HirDatabase,
261 where_clause: chalk_ir::QuantifiedWhereClause<ChalkIr>, 332 where_clause: chalk_ir::QuantifiedWhereClause<TypeFamily>,
262 ) -> GenericPredicate { 333 ) -> GenericPredicate {
263 match where_clause.value { 334 match where_clause.value {
264 chalk_ir::WhereClause::Implemented(tr) => { 335 chalk_ir::WhereClause::Implemented(tr) => {
265 if tr.trait_id == UNKNOWN_TRAIT {
266 // FIXME we need an Error enum on the Chalk side to avoid this
267 return GenericPredicate::Error;
268 }
269 GenericPredicate::Implemented(from_chalk(db, tr)) 336 GenericPredicate::Implemented(from_chalk(db, tr))
270 } 337 }
271 chalk_ir::WhereClause::ProjectionEq(projection_eq) => { 338 chalk_ir::WhereClause::ProjectionEq(projection_eq) => {
@@ -278,9 +345,9 @@ impl ToChalk for GenericPredicate {
278} 345}
279 346
280impl ToChalk for ProjectionTy { 347impl ToChalk for ProjectionTy {
281 type Chalk = chalk_ir::ProjectionTy<ChalkIr>; 348 type Chalk = chalk_ir::ProjectionTy<TypeFamily>;
282 349
283 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<ChalkIr> { 350 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<TypeFamily> {
284 chalk_ir::ProjectionTy { 351 chalk_ir::ProjectionTy {
285 associated_ty_id: self.associated_ty.to_chalk(db), 352 associated_ty_id: self.associated_ty.to_chalk(db),
286 parameters: self.parameters.to_chalk(db), 353 parameters: self.parameters.to_chalk(db),
@@ -289,7 +356,7 @@ impl ToChalk for ProjectionTy {
289 356
290 fn from_chalk( 357 fn from_chalk(
291 db: &impl HirDatabase, 358 db: &impl HirDatabase,
292 projection_ty: chalk_ir::ProjectionTy<ChalkIr>, 359 projection_ty: chalk_ir::ProjectionTy<TypeFamily>,
293 ) -> ProjectionTy { 360 ) -> ProjectionTy {
294 ProjectionTy { 361 ProjectionTy {
295 associated_ty: from_chalk(db, projection_ty.associated_ty_id), 362 associated_ty: from_chalk(db, projection_ty.associated_ty_id),
@@ -299,31 +366,31 @@ impl ToChalk for ProjectionTy {
299} 366}
300 367
301impl ToChalk for super::ProjectionPredicate { 368impl ToChalk for super::ProjectionPredicate {
302 type Chalk = chalk_ir::Normalize<ChalkIr>; 369 type Chalk = chalk_ir::Normalize<TypeFamily>;
303 370
304 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<ChalkIr> { 371 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<TypeFamily> {
305 chalk_ir::Normalize { 372 chalk_ir::Normalize {
306 projection: self.projection_ty.to_chalk(db), 373 projection: self.projection_ty.to_chalk(db),
307 ty: self.ty.to_chalk(db), 374 ty: self.ty.to_chalk(db),
308 } 375 }
309 } 376 }
310 377
311 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<ChalkIr>) -> Self { 378 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<TypeFamily>) -> Self {
312 unimplemented!() 379 unimplemented!()
313 } 380 }
314} 381}
315 382
316impl ToChalk for Obligation { 383impl ToChalk for Obligation {
317 type Chalk = chalk_ir::DomainGoal<ChalkIr>; 384 type Chalk = chalk_ir::DomainGoal<TypeFamily>;
318 385
319 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<ChalkIr> { 386 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<TypeFamily> {
320 match self { 387 match self {
321 Obligation::Trait(tr) => tr.to_chalk(db).cast(), 388 Obligation::Trait(tr) => tr.to_chalk(db).cast(),
322 Obligation::Projection(pr) => pr.to_chalk(db).cast(), 389 Obligation::Projection(pr) => pr.to_chalk(db).cast(),
323 } 390 }
324 } 391 }
325 392
326 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<ChalkIr>) -> Self { 393 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<TypeFamily>) -> Self {
327 unimplemented!() 394 unimplemented!()
328 } 395 }
329} 396}
@@ -347,16 +414,17 @@ where
347} 414}
348 415
349impl ToChalk for Arc<super::TraitEnvironment> { 416impl ToChalk for Arc<super::TraitEnvironment> {
350 type Chalk = chalk_ir::Environment<ChalkIr>; 417 type Chalk = chalk_ir::Environment<TypeFamily>;
351 418
352 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<ChalkIr> { 419 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<TypeFamily> {
353 let mut clauses = Vec::new(); 420 let mut clauses = Vec::new();
354 for pred in &self.predicates { 421 for pred in &self.predicates {
355 if pred.is_error() { 422 if pred.is_error() {
356 // for env, we just ignore errors 423 // for env, we just ignore errors
357 continue; 424 continue;
358 } 425 }
359 let program_clause: chalk_ir::ProgramClause<ChalkIr> = pred.clone().to_chalk(db).cast(); 426 let program_clause: chalk_ir::ProgramClause<TypeFamily> =
427 pred.clone().to_chalk(db).cast();
360 clauses.push(program_clause.into_from_env_clause()); 428 clauses.push(program_clause.into_from_env_clause());
361 } 429 }
362 chalk_ir::Environment::new().add_clauses(clauses) 430 chalk_ir::Environment::new().add_clauses(clauses)
@@ -364,7 +432,7 @@ impl ToChalk for Arc<super::TraitEnvironment> {
364 432
365 fn from_chalk( 433 fn from_chalk(
366 _db: &impl HirDatabase, 434 _db: &impl HirDatabase,
367 _env: chalk_ir::Environment<ChalkIr>, 435 _env: chalk_ir::Environment<TypeFamily>,
368 ) -> Arc<super::TraitEnvironment> { 436 ) -> Arc<super::TraitEnvironment> {
369 unimplemented!() 437 unimplemented!()
370 } 438 }
@@ -372,7 +440,7 @@ impl ToChalk for Arc<super::TraitEnvironment> {
372 440
373impl<T: ToChalk> ToChalk for super::InEnvironment<T> 441impl<T: ToChalk> ToChalk for super::InEnvironment<T>
374where 442where
375 T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = ChalkIr>, 443 T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = TypeFamily>,
376{ 444{
377 type Chalk = chalk_ir::InEnvironment<T::Chalk>; 445 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
378 446
@@ -395,9 +463,9 @@ where
395} 463}
396 464
397impl ToChalk for builtin::BuiltinImplData { 465impl ToChalk for builtin::BuiltinImplData {
398 type Chalk = chalk_rust_ir::ImplDatum<ChalkIr>; 466 type Chalk = ImplDatum;
399 467
400 fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::ImplDatum<ChalkIr> { 468 fn to_chalk(self, db: &impl HirDatabase) -> ImplDatum {
401 let impl_type = chalk_rust_ir::ImplType::External; 469 let impl_type = chalk_rust_ir::ImplType::External;
402 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect(); 470 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect();
403 471
@@ -413,15 +481,15 @@ impl ToChalk for builtin::BuiltinImplData {
413 } 481 }
414 } 482 }
415 483
416 fn from_chalk(_db: &impl HirDatabase, _data: chalk_rust_ir::ImplDatum<ChalkIr>) -> Self { 484 fn from_chalk(_db: &impl HirDatabase, _data: ImplDatum) -> Self {
417 unimplemented!() 485 unimplemented!()
418 } 486 }
419} 487}
420 488
421impl ToChalk for builtin::BuiltinImplAssocTyValueData { 489impl ToChalk for builtin::BuiltinImplAssocTyValueData {
422 type Chalk = chalk_rust_ir::AssociatedTyValue<ChalkIr>; 490 type Chalk = AssociatedTyValue;
423 491
424 fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::AssociatedTyValue<ChalkIr> { 492 fn to_chalk(self, db: &impl HirDatabase) -> AssociatedTyValue {
425 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: self.value.to_chalk(db) }; 493 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: self.value.to_chalk(db) };
426 494
427 chalk_rust_ir::AssociatedTyValue { 495 chalk_rust_ir::AssociatedTyValue {
@@ -433,7 +501,7 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData {
433 501
434 fn from_chalk( 502 fn from_chalk(
435 _db: &impl HirDatabase, 503 _db: &impl HirDatabase,
436 _data: chalk_rust_ir::AssociatedTyValue<ChalkIr>, 504 _data: AssociatedTyValue,
437 ) -> builtin::BuiltinImplAssocTyValueData { 505 ) -> builtin::BuiltinImplAssocTyValueData {
438 unimplemented!() 506 unimplemented!()
439 } 507 }
@@ -450,46 +518,46 @@ fn convert_where_clauses(
450 db: &impl HirDatabase, 518 db: &impl HirDatabase,
451 def: GenericDefId, 519 def: GenericDefId,
452 substs: &Substs, 520 substs: &Substs,
453) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> { 521) -> Vec<chalk_ir::QuantifiedWhereClause<TypeFamily>> {
454 let generic_predicates = db.generic_predicates(def); 522 let generic_predicates = db.generic_predicates(def);
455 let mut result = Vec::with_capacity(generic_predicates.len()); 523 let mut result = Vec::with_capacity(generic_predicates.len());
456 for pred in generic_predicates.iter() { 524 for pred in generic_predicates.iter() {
457 if pred.is_error() { 525 if pred.is_error() {
458 // HACK: Return just the single predicate (which is always false 526 // skip errored predicates completely
459 // anyway), otherwise Chalk can easily get into slow situations 527 continue;
460 return vec![pred.clone().subst(substs).to_chalk(db)];
461 } 528 }
462 result.push(pred.clone().subst(substs).to_chalk(db)); 529 result.push(pred.clone().subst(substs).to_chalk(db));
463 } 530 }
464 result 531 result
465} 532}
466 533
467impl<'a, DB> chalk_solve::RustIrDatabase<ChalkIr> for ChalkContext<'a, DB> 534impl<'a, DB> chalk_solve::RustIrDatabase<TypeFamily> for ChalkContext<'a, DB>
468where 535where
469 DB: HirDatabase, 536 DB: HirDatabase,
470{ 537{
471 fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum<ChalkIr>> { 538 fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> {
472 self.db.associated_ty_data(id) 539 self.db.associated_ty_data(id)
473 } 540 }
474 fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum<ChalkIr>> { 541 fn trait_datum(&self, trait_id: TraitId) -> Arc<TraitDatum> {
475 self.db.trait_datum(self.krate, trait_id) 542 self.db.trait_datum(self.krate, trait_id)
476 } 543 }
477 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum<ChalkIr>> { 544 fn struct_datum(&self, struct_id: StructId) -> Arc<StructDatum> {
478 self.db.struct_datum(self.krate, struct_id) 545 self.db.struct_datum(self.krate, struct_id)
479 } 546 }
480 fn impl_datum(&self, impl_id: chalk_ir::ImplId) -> Arc<ImplDatum<ChalkIr>> { 547 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
481 self.db.impl_datum(self.krate, impl_id) 548 self.db.impl_datum(self.krate, impl_id)
482 } 549 }
483 fn impls_for_trait( 550 fn impls_for_trait(
484 &self, 551 &self,
485 trait_id: chalk_ir::TraitId, 552 trait_id: TraitId,
486 parameters: &[Parameter<ChalkIr>], 553 parameters: &[Parameter<TypeFamily>],
487 ) -> Vec<chalk_ir::ImplId> { 554 ) -> Vec<ImplId> {
488 debug!("impls_for_trait {:?}", trait_id); 555 debug!("impls_for_trait {:?}", trait_id);
489 if trait_id == UNKNOWN_TRAIT { 556 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
490 return Vec::new(); 557
491 } 558 // Note: Since we're using impls_for_trait, only impls where the trait
492 let trait_: TraitId = from_chalk(self.db, trait_id); 559 // can be resolved should ever reach Chalk. `impl_datum` relies on that
560 // and will panic if the trait can't be resolved.
493 let mut result: Vec<_> = self 561 let mut result: Vec<_> = self
494 .db 562 .db
495 .impls_for_trait(self.krate, trait_.into()) 563 .impls_for_trait(self.krate, trait_.into())
@@ -508,39 +576,32 @@ where
508 debug!("impls_for_trait returned {} impls", result.len()); 576 debug!("impls_for_trait returned {} impls", result.len());
509 result 577 result
510 } 578 }
511 fn impl_provided_for( 579 fn impl_provided_for(&self, auto_trait_id: TraitId, struct_id: StructId) -> bool {
512 &self,
513 auto_trait_id: chalk_ir::TraitId,
514 struct_id: chalk_ir::StructId,
515 ) -> bool {
516 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id); 580 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id);
517 false // FIXME 581 false // FIXME
518 } 582 }
519 fn type_name(&self, _id: TypeKindId) -> Identifier { 583 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
520 unimplemented!()
521 }
522 fn associated_ty_value(
523 &self,
524 id: chalk_rust_ir::AssociatedTyValueId,
525 ) -> Arc<AssociatedTyValue<ChalkIr>> {
526 self.db.associated_ty_value(self.krate.into(), id) 584 self.db.associated_ty_value(self.krate.into(), id)
527 } 585 }
528 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> { 586 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<TypeFamily>> {
529 vec![] 587 vec![]
530 } 588 }
531 fn local_impls_to_coherence_check( 589 fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec<ImplId> {
532 &self,
533 _trait_id: chalk_ir::TraitId,
534 ) -> Vec<chalk_ir::ImplId> {
535 // We don't do coherence checking (yet) 590 // We don't do coherence checking (yet)
536 unimplemented!() 591 unimplemented!()
537 } 592 }
593 fn as_struct_id(&self, id: &TypeName<TypeFamily>) -> Option<StructId> {
594 match id {
595 TypeName::Struct(struct_id) => Some(*struct_id),
596 _ => None,
597 }
598 }
538} 599}
539 600
540pub(crate) fn associated_ty_data_query( 601pub(crate) fn associated_ty_data_query(
541 db: &impl HirDatabase, 602 db: &impl HirDatabase,
542 id: TypeId, 603 id: AssocTypeId,
543) -> Arc<AssociatedTyDatum<ChalkIr>> { 604) -> Arc<AssociatedTyDatum> {
544 debug!("associated_ty_data {:?}", id); 605 debug!("associated_ty_data {:?}", id);
545 let type_alias: TypeAliasId = from_chalk(db, id); 606 let type_alias: TypeAliasId = from_chalk(db, id);
546 let trait_ = match type_alias.lookup(db).container { 607 let trait_ = match type_alias.lookup(db).container {
@@ -565,28 +626,10 @@ pub(crate) fn associated_ty_data_query(
565pub(crate) fn trait_datum_query( 626pub(crate) fn trait_datum_query(
566 db: &impl HirDatabase, 627 db: &impl HirDatabase,
567 krate: CrateId, 628 krate: CrateId,
568 trait_id: chalk_ir::TraitId, 629 trait_id: TraitId,
569) -> Arc<TraitDatum<ChalkIr>> { 630) -> Arc<TraitDatum> {
570 debug!("trait_datum {:?}", trait_id); 631 debug!("trait_datum {:?}", trait_id);
571 if trait_id == UNKNOWN_TRAIT { 632 let trait_: hir_def::TraitId = from_chalk(db, trait_id);
572 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses: Vec::new() };
573
574 let flags = chalk_rust_ir::TraitFlags {
575 auto: false,
576 marker: false,
577 upstream: true,
578 fundamental: false,
579 non_enumerable: true,
580 coinductive: false,
581 };
582 return Arc::new(TraitDatum {
583 id: trait_id,
584 binders: make_binders(trait_datum_bound, 1),
585 flags,
586 associated_ty_ids: vec![],
587 });
588 }
589 let trait_: TraitId = from_chalk(db, trait_id);
590 let trait_data = db.trait_data(trait_); 633 let trait_data = db.trait_data(trait_);
591 debug!("trait {:?} = {:?}", trait_id, trait_data.name); 634 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
592 let generic_params = generics(db, trait_.into()); 635 let generic_params = generics(db, trait_.into());
@@ -616,10 +659,10 @@ pub(crate) fn trait_datum_query(
616pub(crate) fn struct_datum_query( 659pub(crate) fn struct_datum_query(
617 db: &impl HirDatabase, 660 db: &impl HirDatabase,
618 krate: CrateId, 661 krate: CrateId,
619 struct_id: chalk_ir::StructId, 662 struct_id: StructId,
620) -> Arc<StructDatum<ChalkIr>> { 663) -> Arc<StructDatum> {
621 debug!("struct_datum {:?}", struct_id); 664 debug!("struct_datum {:?}", struct_id);
622 let type_ctor: TypeCtor = from_chalk(db, struct_id); 665 let type_ctor: TypeCtor = from_chalk(db, TypeName::Struct(struct_id));
623 debug!("struct {:?} = {:?}", struct_id, type_ctor); 666 debug!("struct {:?} = {:?}", struct_id, type_ctor);
624 let num_params = type_ctor.num_ty_params(db); 667 let num_params = type_ctor.num_ty_params(db);
625 let upstream = type_ctor.krate(db) != Some(krate); 668 let upstream = type_ctor.krate(db) != Some(krate);
@@ -648,25 +691,27 @@ pub(crate) fn struct_datum_query(
648pub(crate) fn impl_datum_query( 691pub(crate) fn impl_datum_query(
649 db: &impl HirDatabase, 692 db: &impl HirDatabase,
650 krate: CrateId, 693 krate: CrateId,
651 impl_id: chalk_ir::ImplId, 694 impl_id: ImplId,
652) -> Arc<ImplDatum<ChalkIr>> { 695) -> Arc<ImplDatum> {
653 let _p = ra_prof::profile("impl_datum"); 696 let _p = ra_prof::profile("impl_datum");
654 debug!("impl_datum {:?}", impl_id); 697 debug!("impl_datum {:?}", impl_id);
655 let impl_: Impl = from_chalk(db, impl_id); 698 let impl_: Impl = from_chalk(db, impl_id);
656 match impl_ { 699 match impl_ {
657 Impl::ImplBlock(impl_block) => impl_block_datum(db, krate, impl_id, impl_block), 700 Impl::ImplBlock(impl_block) => impl_block_datum(db, krate, impl_id, impl_block),
658 _ => builtin::impl_datum(db, krate, impl_).map(|d| Arc::new(d.to_chalk(db))), 701 _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)),
659 } 702 }
660 .unwrap_or_else(invalid_impl_datum)
661} 703}
662 704
663fn impl_block_datum( 705fn impl_block_datum(
664 db: &impl HirDatabase, 706 db: &impl HirDatabase,
665 krate: CrateId, 707 krate: CrateId,
666 chalk_id: chalk_ir::ImplId, 708 chalk_id: ImplId,
667 impl_id: ImplId, 709 impl_id: hir_def::ImplId,
668) -> Option<Arc<ImplDatum<ChalkIr>>> { 710) -> Arc<ImplDatum> {
669 let trait_ref = db.impl_trait(impl_id)?; 711 let trait_ref = db
712 .impl_trait(impl_id)
713 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk
714 .expect("invalid impl passed to Chalk");
670 let impl_data = db.impl_data(impl_id); 715 let impl_data = db.impl_data(impl_id);
671 716
672 let generic_params = generics(db, impl_id.into()); 717 let generic_params = generics(db, impl_id.into());
@@ -718,29 +763,14 @@ fn impl_block_datum(
718 polarity, 763 polarity,
719 associated_ty_value_ids, 764 associated_ty_value_ids,
720 }; 765 };
721 Some(Arc::new(impl_datum))
722}
723
724fn invalid_impl_datum() -> Arc<ImplDatum<ChalkIr>> {
725 let trait_ref = chalk_ir::TraitRef {
726 trait_id: UNKNOWN_TRAIT,
727 parameters: vec![chalk_ir::TyData::BoundVar(0).cast().intern().cast()],
728 };
729 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses: Vec::new() };
730 let impl_datum = ImplDatum {
731 binders: make_binders(impl_datum_bound, 1),
732 impl_type: chalk_rust_ir::ImplType::External,
733 polarity: chalk_rust_ir::Polarity::Positive,
734 associated_ty_value_ids: Vec::new(),
735 };
736 Arc::new(impl_datum) 766 Arc::new(impl_datum)
737} 767}
738 768
739pub(crate) fn associated_ty_value_query( 769pub(crate) fn associated_ty_value_query(
740 db: &impl HirDatabase, 770 db: &impl HirDatabase,
741 krate: CrateId, 771 krate: CrateId,
742 id: chalk_rust_ir::AssociatedTyValueId, 772 id: AssociatedTyValueId,
743) -> Arc<chalk_rust_ir::AssociatedTyValue<ChalkIr>> { 773) -> Arc<AssociatedTyValue> {
744 let data: AssocTyValue = from_chalk(db, id); 774 let data: AssocTyValue = from_chalk(db, id);
745 match data { 775 match data {
746 AssocTyValue::TypeAlias(type_alias) => { 776 AssocTyValue::TypeAlias(type_alias) => {
@@ -754,7 +784,7 @@ fn type_alias_associated_ty_value(
754 db: &impl HirDatabase, 784 db: &impl HirDatabase,
755 _krate: CrateId, 785 _krate: CrateId,
756 type_alias: TypeAliasId, 786 type_alias: TypeAliasId,
757) -> Arc<AssociatedTyValue<ChalkIr>> { 787) -> Arc<AssociatedTyValue> {
758 let type_alias_data = db.type_alias_data(type_alias); 788 let type_alias_data = db.type_alias_data(type_alias);
759 let impl_id = match type_alias.lookup(db).container { 789 let impl_id = match type_alias.lookup(db).container {
760 AssocContainerId::ImplId(it) => it, 790 AssocContainerId::ImplId(it) => it,
@@ -786,27 +816,27 @@ fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId {
786 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } 816 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() }
787} 817}
788 818
789impl From<chalk_ir::StructId> for crate::TypeCtorId { 819impl From<StructId> for crate::TypeCtorId {
790 fn from(struct_id: chalk_ir::StructId) -> Self { 820 fn from(struct_id: StructId) -> Self {
791 id_from_chalk(struct_id.0) 821 InternKey::from_intern_id(struct_id.0)
792 } 822 }
793} 823}
794 824
795impl From<crate::TypeCtorId> for chalk_ir::StructId { 825impl From<crate::TypeCtorId> for StructId {
796 fn from(type_ctor_id: crate::TypeCtorId) -> Self { 826 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
797 chalk_ir::StructId(id_to_chalk(type_ctor_id)) 827 chalk_ir::StructId(type_ctor_id.as_intern_id())
798 } 828 }
799} 829}
800 830
801impl From<chalk_ir::ImplId> for crate::traits::GlobalImplId { 831impl From<ImplId> for crate::traits::GlobalImplId {
802 fn from(impl_id: chalk_ir::ImplId) -> Self { 832 fn from(impl_id: ImplId) -> Self {
803 id_from_chalk(impl_id.0) 833 InternKey::from_intern_id(impl_id.0)
804 } 834 }
805} 835}
806 836
807impl From<crate::traits::GlobalImplId> for chalk_ir::ImplId { 837impl From<crate::traits::GlobalImplId> for ImplId {
808 fn from(impl_id: crate::traits::GlobalImplId) -> Self { 838 fn from(impl_id: crate::traits::GlobalImplId) -> Self {
809 chalk_ir::ImplId(id_to_chalk(impl_id)) 839 chalk_ir::ImplId(impl_id.as_intern_id())
810 } 840 }
811} 841}
812 842