aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/assists/add_derive.rs18
-rw-r--r--crates/ra_assists/src/assists/add_explicit_type.rs16
-rw-r--r--crates/ra_assists/src/assists/add_impl.rs19
-rw-r--r--crates/ra_assists/src/assists/add_missing_impl_members.rs58
-rw-r--r--crates/ra_assists/src/assists/apply_demorgan.rs26
-rw-r--r--crates/ra_assists/src/doc_tests.rs6
-rw-r--r--crates/ra_assists/src/doc_tests/generated.rs139
-rw-r--r--crates/ra_hir/Cargo.toml6
-rw-r--r--crates/ra_hir/src/ty/traits.rs6
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs110
10 files changed, 338 insertions, 66 deletions
diff --git a/crates/ra_assists/src/assists/add_derive.rs b/crates/ra_assists/src/assists/add_derive.rs
index 77ecc33c9..d3ba634c4 100644
--- a/crates/ra_assists/src/assists/add_derive.rs
+++ b/crates/ra_assists/src/assists/add_derive.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use hir::db::HirDatabase; 1use hir::db::HirDatabase;
4use ra_syntax::{ 2use ra_syntax::{
5 ast::{self, AstNode, AttrsOwner}, 3 ast::{self, AstNode, AttrsOwner},
@@ -9,6 +7,22 @@ use ra_syntax::{
9 7
10use crate::{Assist, AssistCtx, AssistId}; 8use crate::{Assist, AssistCtx, AssistId};
11 9
10// Assist: add_derive
11// Adds a new `#[derive()]` clause to a struct or enum.
12// ```
13// struct Point {
14// x: u32,
15// y: u32,<|>
16// }
17// ```
18// ->
19// ```
20// #[derive()]
21// struct Point {
22// x: u32,
23// y: u32,
24// }
25// ```
12pub(crate) fn add_derive(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 26pub(crate) fn add_derive(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
13 let nominal = ctx.node_at_offset::<ast::NominalDef>()?; 27 let nominal = ctx.node_at_offset::<ast::NominalDef>()?;
14 let node_start = derive_insertion_offset(&nominal)?; 28 let node_start = derive_insertion_offset(&nominal)?;
diff --git a/crates/ra_assists/src/assists/add_explicit_type.rs b/crates/ra_assists/src/assists/add_explicit_type.rs
index 8c83dc987..33b7bea7f 100644
--- a/crates/ra_assists/src/assists/add_explicit_type.rs
+++ b/crates/ra_assists/src/assists/add_explicit_type.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use hir::{db::HirDatabase, HirDisplay, Ty}; 1use hir::{db::HirDatabase, HirDisplay, Ty};
4use ra_syntax::{ 2use ra_syntax::{
5 ast::{self, AstNode, LetStmt, NameOwner}, 3 ast::{self, AstNode, LetStmt, NameOwner},
@@ -8,7 +6,19 @@ use ra_syntax::{
8 6
9use crate::{Assist, AssistCtx, AssistId}; 7use crate::{Assist, AssistCtx, AssistId};
10 8
11/// Add explicit type assist. 9// Assist: add_explicit_type
10// Specify type for a let binding
11// ```
12// fn main() {
13// let x<|> = 92;
14// }
15// ```
16// ->
17// ```
18// fn main() {
19// let x: i32 = 92;
20// }
21// ```
12pub(crate) fn add_explicit_type(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 22pub(crate) fn add_explicit_type(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
13 let stmt = ctx.node_at_offset::<LetStmt>()?; 23 let stmt = ctx.node_at_offset::<LetStmt>()?;
14 let expr = stmt.initializer()?; 24 let expr = stmt.initializer()?;
diff --git a/crates/ra_assists/src/assists/add_impl.rs b/crates/ra_assists/src/assists/add_impl.rs
index 94801fbc9..40bc5c464 100644
--- a/crates/ra_assists/src/assists/add_impl.rs
+++ b/crates/ra_assists/src/assists/add_impl.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use format_buf::format; 1use format_buf::format;
4use hir::db::HirDatabase; 2use hir::db::HirDatabase;
5use join_to_string::join; 3use join_to_string::join;
@@ -10,6 +8,23 @@ use ra_syntax::{
10 8
11use crate::{Assist, AssistCtx, AssistId}; 9use crate::{Assist, AssistCtx, AssistId};
12 10
11// Assist: add_impl
12// Adds a new inherent impl for a type
13// ```
14// struct Ctx<T: Clone> {
15// data: T,<|>
16// }
17// ```
18// ->
19// ```
20// struct Ctx<T: Clone> {
21// data: T,
22// }
23//
24// impl<T: Clone> Ctx<T> {
25//
26// }
27// ```
13pub(crate) fn add_impl(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 28pub(crate) fn add_impl(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
14 let nominal = ctx.node_at_offset::<ast::NominalDef>()?; 29 let nominal = ctx.node_at_offset::<ast::NominalDef>()?;
15 let name = nominal.name()?; 30 let name = nominal.name()?;
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs
index 565b96fb5..36fa6f9ea 100644
--- a/crates/ra_assists/src/assists/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use hir::{db::HirDatabase, HasSource}; 1use hir::{db::HirDatabase, HasSource};
4use ra_syntax::{ 2use ra_syntax::{
5 ast::{self, edit, make, AstNode, NameOwner}, 3 ast::{self, edit, make, AstNode, NameOwner},
@@ -14,6 +12,32 @@ enum AddMissingImplMembersMode {
14 NoDefaultMethods, 12 NoDefaultMethods,
15} 13}
16 14
15// Assist: add_impl_missing_members
16// Adds scaffold for required impl members
17// ```
18// trait T {
19// Type X;
20// fn foo(&self);
21// fn bar(&self) {}
22// }
23//
24// impl T for () {<|>
25//
26// }
27// ```
28// ->
29// ```
30// trait T {
31// Type X;
32// fn foo(&self);
33// fn bar(&self) {}
34// }
35//
36// impl T for () {
37// fn foo(&self) { unimplemented!() }
38//
39// }
40// ```
17pub(crate) fn add_missing_impl_members(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 41pub(crate) fn add_missing_impl_members(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
18 add_missing_impl_members_inner( 42 add_missing_impl_members_inner(
19 ctx, 43 ctx,
@@ -23,6 +47,36 @@ pub(crate) fn add_missing_impl_members(ctx: AssistCtx<impl HirDatabase>) -> Opti
23 ) 47 )
24} 48}
25 49
50// Assist: add_impl_default_members
51// Adds scaffold for overriding default impl members
52// ```
53// trait T {
54// Type X;
55// fn foo(&self);
56// fn bar(&self) {}
57// }
58//
59// impl T for () {
60// Type X = ();
61// fn foo(&self) {}<|>
62//
63// }
64// ```
65// ->
66// ```
67// trait T {
68// Type X;
69// fn foo(&self);
70// fn bar(&self) {}
71// }
72//
73// impl T for () {
74// Type X = ();
75// fn foo(&self) {}
76// fn bar(&self) {}
77//
78// }
79// ```
26pub(crate) fn add_missing_default_members(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 80pub(crate) fn add_missing_default_members(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
27 add_missing_impl_members_inner( 81 add_missing_impl_members_inner(
28 ctx, 82 ctx,
diff --git a/crates/ra_assists/src/assists/apply_demorgan.rs b/crates/ra_assists/src/assists/apply_demorgan.rs
index 5f2b0dd18..a072f63e7 100644
--- a/crates/ra_assists/src/assists/apply_demorgan.rs
+++ b/crates/ra_assists/src/assists/apply_demorgan.rs
@@ -1,18 +1,26 @@
1//! This contains the functions associated with the demorgan assist.
2//! This assist transforms boolean expressions of the form `!a || !b` into
3//! `!(a && b)`.
4use hir::db::HirDatabase; 1use hir::db::HirDatabase;
5use ra_syntax::ast::{self, AstNode}; 2use ra_syntax::ast::{self, AstNode};
6use ra_syntax::SyntaxNode; 3use ra_syntax::SyntaxNode;
7 4
8use crate::{Assist, AssistCtx, AssistId}; 5use crate::{Assist, AssistCtx, AssistId};
9 6
10/// Assist for applying demorgan's law 7// Assist: apply_demorgan
11/// 8// Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws).
12/// This transforms expressions of the form `!l || !r` into `!(l && r)`. 9// This transforms expressions of the form `!l || !r` into `!(l && r)`.
13/// This also works with `&&`. This assist can only be applied with the cursor 10// This also works with `&&`. This assist can only be applied with the cursor
14/// on either `||` or `&&`, with both operands being a negation of some kind. 11// on either `||` or `&&`, with both operands being a negation of some kind.
15/// This means something of the form `!x` or `x != y`. 12// This means something of the form `!x` or `x != y`.
13// ```
14// fn main() {
15// if x != 4 ||<|> !y {}
16// }
17// ```
18// ->
19// ```
20// fn main() {
21// if !(x == 4 && y) {}
22// }
23// ```
16pub(crate) fn apply_demorgan(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 24pub(crate) fn apply_demorgan(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
17 let expr = ctx.node_at_offset::<ast::BinExpr>()?; 25 let expr = ctx.node_at_offset::<ast::BinExpr>()?;
18 let op = expr.op_kind()?; 26 let op = expr.op_kind()?;
diff --git a/crates/ra_assists/src/doc_tests.rs b/crates/ra_assists/src/doc_tests.rs
index 88e901517..872bbdf17 100644
--- a/crates/ra_assists/src/doc_tests.rs
+++ b/crates/ra_assists/src/doc_tests.rs
@@ -15,8 +15,10 @@ fn check(assist_id: &str, before: &str, after: &str) {
15 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); 15 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before);
16 let frange = FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; 16 let frange = FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) };
17 17
18 let (_assist_id, action) = 18 let (_assist_id, action) = crate::assists(&db, frange)
19 crate::assists(&db, frange).into_iter().find(|(id, _)| id.id.0 == assist_id).unwrap(); 19 .into_iter()
20 .find(|(id, _)| id.id.0 == assist_id)
21 .unwrap_or_else(|| panic!("Assist {:?} is not applicable", assist_id));
20 22
21 let actual = action.edit.apply(&before); 23 let actual = action.edit.apply(&before);
22 assert_eq_text!(after, &actual); 24 assert_eq_text!(after, &actual);
diff --git a/crates/ra_assists/src/doc_tests/generated.rs b/crates/ra_assists/src/doc_tests/generated.rs
index e5f6910f1..76d86b93d 100644
--- a/crates/ra_assists/src/doc_tests/generated.rs
+++ b/crates/ra_assists/src/doc_tests/generated.rs
@@ -3,6 +3,145 @@
3use super::check; 3use super::check;
4 4
5#[test] 5#[test]
6fn doctest_add_derive() {
7 check(
8 "add_derive",
9 r#####"
10struct Point {
11 x: u32,
12 y: u32,<|>
13}
14"#####,
15 r#####"
16#[derive()]
17struct Point {
18 x: u32,
19 y: u32,
20}
21"#####,
22 )
23}
24
25#[test]
26fn doctest_add_explicit_type() {
27 check(
28 "add_explicit_type",
29 r#####"
30fn main() {
31 let x<|> = 92;
32}
33"#####,
34 r#####"
35fn main() {
36 let x: i32 = 92;
37}
38"#####,
39 )
40}
41
42#[test]
43fn doctest_add_impl() {
44 check(
45 "add_impl",
46 r#####"
47struct Ctx<T: Clone> {
48 data: T,<|>
49}
50"#####,
51 r#####"
52struct Ctx<T: Clone> {
53 data: T,
54}
55
56impl<T: Clone> Ctx<T> {
57
58}
59"#####,
60 )
61}
62
63#[test]
64fn doctest_add_impl_default_members() {
65 check(
66 "add_impl_default_members",
67 r#####"
68trait T {
69 Type X;
70 fn foo(&self);
71 fn bar(&self) {}
72}
73
74impl T for () {
75 Type X = ();
76 fn foo(&self) {}<|>
77
78}
79"#####,
80 r#####"
81trait T {
82 Type X;
83 fn foo(&self);
84 fn bar(&self) {}
85}
86
87impl T for () {
88 Type X = ();
89 fn foo(&self) {}
90 fn bar(&self) {}
91
92}
93"#####,
94 )
95}
96
97#[test]
98fn doctest_add_impl_missing_members() {
99 check(
100 "add_impl_missing_members",
101 r#####"
102trait T {
103 Type X;
104 fn foo(&self);
105 fn bar(&self) {}
106}
107
108impl T for () {<|>
109
110}
111"#####,
112 r#####"
113trait T {
114 Type X;
115 fn foo(&self);
116 fn bar(&self) {}
117}
118
119impl T for () {
120 fn foo(&self) { unimplemented!() }
121
122}
123"#####,
124 )
125}
126
127#[test]
128fn doctest_apply_demorgan() {
129 check(
130 "apply_demorgan",
131 r#####"
132fn main() {
133 if x != 4 ||<|> !y {}
134}
135"#####,
136 r#####"
137fn main() {
138 if !(x == 4 && y) {}
139}
140"#####,
141 )
142}
143
144#[test]
6fn doctest_convert_to_guarded_return() { 145fn doctest_convert_to_guarded_return() {
7 check( 146 check(
8 "convert_to_guarded_return", 147 "convert_to_guarded_return",
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index dce897d30..f05ec0b8a 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -22,9 +22,9 @@ tt = { path = "../ra_tt", package = "ra_tt" }
22test_utils = { path = "../test_utils" } 22test_utils = { path = "../test_utils" }
23ra_prof = { path = "../ra_prof" } 23ra_prof = { path = "../ra_prof" }
24 24
25chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "13303bb0067c6ed0572322080ae367ee38f9e7c9" } 25chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "1e5c1929364dfbb7c0c7ac0956b8250abe7c2cae" }
26chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "13303bb0067c6ed0572322080ae367ee38f9e7c9" } 26chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "1e5c1929364dfbb7c0c7ac0956b8250abe7c2cae" }
27chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "13303bb0067c6ed0572322080ae367ee38f9e7c9" } 27chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "1e5c1929364dfbb7c0c7ac0956b8250abe7c2cae" }
28lalrpop-intern = "0.15.1" 28lalrpop-intern = "0.15.1"
29 29
30[dev-dependencies] 30[dev-dependencies]
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs
index 0cb5c3798..4f1eab150 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir/src/ty/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; 4use chalk_ir::{cast::Cast, family::ChalkIr};
5use log::debug; 5use log::debug;
6use ra_db::salsa; 6use ra_db::salsa;
7use ra_prof::profile; 7use ra_prof::profile;
@@ -33,7 +33,7 @@ impl TraitSolver {
33 fn solve( 33 fn solve(
34 &self, 34 &self,
35 db: &impl HirDatabase, 35 db: &impl HirDatabase,
36 goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal>>, 36 goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<ChalkIr>>>,
37 ) -> Option<chalk_solve::Solution> { 37 ) -> Option<chalk_solve::Solution> {
38 let context = ChalkContext { db, krate: self.krate }; 38 let context = ChalkContext { db, krate: self.krate };
39 debug!("solve goal: {:?}", goal); 39 debug!("solve goal: {:?}", goal);
@@ -196,7 +196,7 @@ pub(crate) fn trait_solve_query(
196} 196}
197 197
198fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution { 198fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution {
199 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution>| { 199 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<ChalkIr>>| {
200 let value = subst 200 let value = subst
201 .value 201 .value
202 .parameters 202 .parameters
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 00aaf65d9..ad7c11a5a 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -4,8 +4,8 @@ use std::sync::Arc;
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId, TypeKindId, TypeName, 7 cast::Cast, family::ChalkIr, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId,
8 UniverseIndex, 8 TypeKindId, TypeName, UniverseIndex,
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum};
11 11
@@ -38,8 +38,8 @@ where
38} 38}
39 39
40impl ToChalk for Ty { 40impl ToChalk for Ty {
41 type Chalk = chalk_ir::Ty; 41 type Chalk = chalk_ir::Ty<ChalkIr>;
42 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty { 42 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<ChalkIr> {
43 match self { 43 match self {
44 Ty::Apply(apply_ty) => { 44 Ty::Apply(apply_ty) => {
45 let name = match apply_ty.ctor { 45 let name = match apply_ty.ctor {
@@ -62,21 +62,21 @@ impl ToChalk for Ty {
62 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast() 62 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast()
63 } 63 }
64 Ty::Param { idx, .. } => { 64 Ty::Param { idx, .. } => {
65 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty() 65 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty::<ChalkIr>()
66 } 66 }
67 Ty::Bound(idx) => chalk_ir::Ty::BoundVar(idx as usize), 67 Ty::Bound(idx) => chalk_ir::Ty::BoundVar(idx as usize),
68 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 68 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
69 // FIXME this is clearly incorrect, but probably not too incorrect 69 // FIXME this is clearly incorrect, but probably not too incorrect
70 // and I'm not sure what to actually do with Ty::Unknown 70 // and I'm not sure what to actually do with Ty::Unknown
71 // maybe an alternative would be `for<T> T`? (meaningless in rust, but expressible in chalk's Ty) 71 // maybe an alternative would be `for<T> T`? (meaningless in rust, but expressible in chalk's Ty)
72 // 72 // FIXME use Chalk's Dyn/Opaque once the bugs with that are fixed
73 // FIXME also dyn and impl Trait are currently handled like Unknown because Chalk doesn't have them yet
74 Ty::Unknown | Ty::Dyn(_) | Ty::Opaque(_) => { 73 Ty::Unknown | Ty::Dyn(_) | Ty::Opaque(_) => {
75 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::max_value() }.to_ty() 74 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::max_value() }
75 .to_ty::<ChalkIr>()
76 } 76 }
77 } 77 }
78 } 78 }
79 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self { 79 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<ChalkIr>) -> Self {
80 match chalk { 80 match chalk {
81 chalk_ir::Ty::Apply(apply_ty) => { 81 chalk_ir::Ty::Apply(apply_ty) => {
82 // FIXME this is kind of hacky due to the fact that 82 // FIXME this is kind of hacky due to the fact that
@@ -108,18 +108,30 @@ impl ToChalk for Ty {
108 chalk_ir::Ty::ForAll(_) => unimplemented!(), 108 chalk_ir::Ty::ForAll(_) => unimplemented!(),
109 chalk_ir::Ty::BoundVar(idx) => Ty::Bound(idx as u32), 109 chalk_ir::Ty::BoundVar(idx) => Ty::Bound(idx as u32),
110 chalk_ir::Ty::InferenceVar(_iv) => Ty::Unknown, 110 chalk_ir::Ty::InferenceVar(_iv) => Ty::Unknown,
111 chalk_ir::Ty::Dyn(where_clauses) => {
112 assert_eq!(where_clauses.binders.len(), 1);
113 let predicates =
114 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect();
115 Ty::Dyn(predicates)
116 }
117 chalk_ir::Ty::Opaque(where_clauses) => {
118 assert_eq!(where_clauses.binders.len(), 1);
119 let predicates =
120 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect();
121 Ty::Opaque(predicates)
122 }
111 } 123 }
112 } 124 }
113} 125}
114 126
115impl ToChalk for Substs { 127impl ToChalk for Substs {
116 type Chalk = Vec<chalk_ir::Parameter>; 128 type Chalk = Vec<chalk_ir::Parameter<ChalkIr>>;
117 129
118 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter> { 130 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<ChalkIr>> {
119 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() 131 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect()
120 } 132 }
121 133
122 fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter>) -> Substs { 134 fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter<ChalkIr>>) -> Substs {
123 let tys = parameters 135 let tys = parameters
124 .into_iter() 136 .into_iter()
125 .map(|p| match p { 137 .map(|p| match p {
@@ -132,15 +144,15 @@ impl ToChalk for Substs {
132} 144}
133 145
134impl ToChalk for TraitRef { 146impl ToChalk for TraitRef {
135 type Chalk = chalk_ir::TraitRef; 147 type Chalk = chalk_ir::TraitRef<ChalkIr>;
136 148
137 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef { 149 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<ChalkIr> {
138 let trait_id = self.trait_.to_chalk(db); 150 let trait_id = self.trait_.to_chalk(db);
139 let parameters = self.substs.to_chalk(db); 151 let parameters = self.substs.to_chalk(db);
140 chalk_ir::TraitRef { trait_id, parameters } 152 chalk_ir::TraitRef { trait_id, parameters }
141 } 153 }
142 154
143 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef) -> Self { 155 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<ChalkIr>) -> Self {
144 let trait_ = from_chalk(db, trait_ref.trait_id); 156 let trait_ = from_chalk(db, trait_ref.trait_id);
145 let substs = from_chalk(db, trait_ref.parameters); 157 let substs = from_chalk(db, trait_ref.parameters);
146 TraitRef { trait_, substs } 158 TraitRef { trait_, substs }
@@ -196,9 +208,9 @@ impl ToChalk for TypeAlias {
196} 208}
197 209
198impl ToChalk for GenericPredicate { 210impl ToChalk for GenericPredicate {
199 type Chalk = chalk_ir::QuantifiedWhereClause; 211 type Chalk = chalk_ir::QuantifiedWhereClause<ChalkIr>;
200 212
201 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause { 213 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<ChalkIr> {
202 match self { 214 match self {
203 GenericPredicate::Implemented(trait_ref) => { 215 GenericPredicate::Implemented(trait_ref) => {
204 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 216 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
@@ -221,25 +233,40 @@ impl ToChalk for GenericPredicate {
221 } 233 }
222 234
223 fn from_chalk( 235 fn from_chalk(
224 _db: &impl HirDatabase, 236 db: &impl HirDatabase,
225 _where_clause: chalk_ir::QuantifiedWhereClause, 237 where_clause: chalk_ir::QuantifiedWhereClause<ChalkIr>,
226 ) -> GenericPredicate { 238 ) -> GenericPredicate {
227 // This should never need to be called 239 match where_clause.value {
228 unimplemented!() 240 chalk_ir::WhereClause::Implemented(tr) => {
241 if tr.trait_id == UNKNOWN_TRAIT {
242 // FIXME we need an Error enum on the Chalk side to avoid this
243 return GenericPredicate::Error;
244 }
245 GenericPredicate::Implemented(from_chalk(db, tr))
246 }
247 chalk_ir::WhereClause::ProjectionEq(projection_eq) => {
248 let projection_ty = from_chalk(db, projection_eq.projection);
249 let ty = from_chalk(db, projection_eq.ty);
250 GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty })
251 }
252 }
229 } 253 }
230} 254}
231 255
232impl ToChalk for ProjectionTy { 256impl ToChalk for ProjectionTy {
233 type Chalk = chalk_ir::ProjectionTy; 257 type Chalk = chalk_ir::ProjectionTy<ChalkIr>;
234 258
235 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy { 259 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<ChalkIr> {
236 chalk_ir::ProjectionTy { 260 chalk_ir::ProjectionTy {
237 associated_ty_id: self.associated_ty.to_chalk(db), 261 associated_ty_id: self.associated_ty.to_chalk(db),
238 parameters: self.parameters.to_chalk(db), 262 parameters: self.parameters.to_chalk(db),
239 } 263 }
240 } 264 }
241 265
242 fn from_chalk(db: &impl HirDatabase, projection_ty: chalk_ir::ProjectionTy) -> ProjectionTy { 266 fn from_chalk(
267 db: &impl HirDatabase,
268 projection_ty: chalk_ir::ProjectionTy<ChalkIr>,
269 ) -> ProjectionTy {
243 ProjectionTy { 270 ProjectionTy {
244 associated_ty: from_chalk(db, projection_ty.associated_ty_id), 271 associated_ty: from_chalk(db, projection_ty.associated_ty_id),
245 parameters: from_chalk(db, projection_ty.parameters), 272 parameters: from_chalk(db, projection_ty.parameters),
@@ -248,31 +275,31 @@ impl ToChalk for ProjectionTy {
248} 275}
249 276
250impl ToChalk for super::ProjectionPredicate { 277impl ToChalk for super::ProjectionPredicate {
251 type Chalk = chalk_ir::Normalize; 278 type Chalk = chalk_ir::Normalize<ChalkIr>;
252 279
253 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize { 280 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<ChalkIr> {
254 chalk_ir::Normalize { 281 chalk_ir::Normalize {
255 projection: self.projection_ty.to_chalk(db), 282 projection: self.projection_ty.to_chalk(db),
256 ty: self.ty.to_chalk(db), 283 ty: self.ty.to_chalk(db),
257 } 284 }
258 } 285 }
259 286
260 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self { 287 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<ChalkIr>) -> Self {
261 unimplemented!() 288 unimplemented!()
262 } 289 }
263} 290}
264 291
265impl ToChalk for Obligation { 292impl ToChalk for Obligation {
266 type Chalk = chalk_ir::DomainGoal; 293 type Chalk = chalk_ir::DomainGoal<ChalkIr>;
267 294
268 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal { 295 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<ChalkIr> {
269 match self { 296 match self {
270 Obligation::Trait(tr) => tr.to_chalk(db).cast(), 297 Obligation::Trait(tr) => tr.to_chalk(db).cast(),
271 Obligation::Projection(pr) => pr.to_chalk(db).cast(), 298 Obligation::Projection(pr) => pr.to_chalk(db).cast(),
272 } 299 }
273 } 300 }
274 301
275 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal) -> Self { 302 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<ChalkIr>) -> Self {
276 unimplemented!() 303 unimplemented!()
277 } 304 }
278} 305}
@@ -296,16 +323,16 @@ where
296} 323}
297 324
298impl ToChalk for Arc<super::TraitEnvironment> { 325impl ToChalk for Arc<super::TraitEnvironment> {
299 type Chalk = Arc<chalk_ir::Environment>; 326 type Chalk = Arc<chalk_ir::Environment<ChalkIr>>;
300 327
301 fn to_chalk(self, db: &impl HirDatabase) -> Arc<chalk_ir::Environment> { 328 fn to_chalk(self, db: &impl HirDatabase) -> Arc<chalk_ir::Environment<ChalkIr>> {
302 let mut clauses = Vec::new(); 329 let mut clauses = Vec::new();
303 for pred in &self.predicates { 330 for pred in &self.predicates {
304 if pred.is_error() { 331 if pred.is_error() {
305 // for env, we just ignore errors 332 // for env, we just ignore errors
306 continue; 333 continue;
307 } 334 }
308 let program_clause: chalk_ir::ProgramClause = pred.clone().to_chalk(db).cast(); 335 let program_clause: chalk_ir::ProgramClause<ChalkIr> = pred.clone().to_chalk(db).cast();
309 clauses.push(program_clause.into_from_env_clause()); 336 clauses.push(program_clause.into_from_env_clause());
310 } 337 }
311 chalk_ir::Environment::new().add_clauses(clauses) 338 chalk_ir::Environment::new().add_clauses(clauses)
@@ -313,13 +340,16 @@ impl ToChalk for Arc<super::TraitEnvironment> {
313 340
314 fn from_chalk( 341 fn from_chalk(
315 _db: &impl HirDatabase, 342 _db: &impl HirDatabase,
316 _env: Arc<chalk_ir::Environment>, 343 _env: Arc<chalk_ir::Environment<ChalkIr>>,
317 ) -> Arc<super::TraitEnvironment> { 344 ) -> Arc<super::TraitEnvironment> {
318 unimplemented!() 345 unimplemented!()
319 } 346 }
320} 347}
321 348
322impl<T: ToChalk> ToChalk for super::InEnvironment<T> { 349impl<T: ToChalk> ToChalk for super::InEnvironment<T>
350where
351 T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = ChalkIr>,
352{
323 type Chalk = chalk_ir::InEnvironment<T::Chalk>; 353 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
324 354
325 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { 355 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
@@ -351,7 +381,7 @@ fn convert_where_clauses(
351 db: &impl HirDatabase, 381 db: &impl HirDatabase,
352 def: GenericDef, 382 def: GenericDef,
353 substs: &Substs, 383 substs: &Substs,
354) -> Vec<chalk_ir::QuantifiedWhereClause> { 384) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> {
355 let generic_predicates = db.generic_predicates(def); 385 let generic_predicates = db.generic_predicates(def);
356 let mut result = Vec::with_capacity(generic_predicates.len()); 386 let mut result = Vec::with_capacity(generic_predicates.len());
357 for pred in generic_predicates.iter() { 387 for pred in generic_predicates.iter() {
@@ -384,7 +414,7 @@ where
384 fn impls_for_trait( 414 fn impls_for_trait(
385 &self, 415 &self,
386 trait_id: chalk_ir::TraitId, 416 trait_id: chalk_ir::TraitId,
387 parameters: &[Parameter], 417 parameters: &[Parameter<ChalkIr>],
388 ) -> Vec<ImplId> { 418 ) -> Vec<ImplId> {
389 debug!("impls_for_trait {:?}", trait_id); 419 debug!("impls_for_trait {:?}", trait_id);
390 if trait_id == UNKNOWN_TRAIT { 420 if trait_id == UNKNOWN_TRAIT {
@@ -430,13 +460,13 @@ where
430 } 460 }
431 fn split_projection<'p>( 461 fn split_projection<'p>(
432 &self, 462 &self,
433 projection: &'p chalk_ir::ProjectionTy, 463 projection: &'p chalk_ir::ProjectionTy<ChalkIr>,
434 ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { 464 ) -> (Arc<AssociatedTyDatum>, &'p [Parameter<ChalkIr>], &'p [Parameter<ChalkIr>]) {
435 debug!("split_projection {:?}", projection); 465 debug!("split_projection {:?}", projection);
436 // we don't support GATs, so I think this should always be correct currently 466 // we don't support GATs, so I think this should always be correct currently
437 (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[]) 467 (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[])
438 } 468 }
439 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause> { 469 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> {
440 vec![] 470 vec![]
441 } 471 }
442 fn local_impls_to_coherence_check( 472 fn local_impls_to_coherence_check(