aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock35
-rw-r--r--crates/ra_hir_ty/Cargo.toml6
-rw-r--r--crates/ra_hir_ty/src/autoderef.rs19
-rw-r--r--crates/ra_hir_ty/src/display.rs2
-rw-r--r--crates/ra_hir_ty/src/infer/unify.rs28
-rw-r--r--crates/ra_hir_ty/src/lib.rs103
-rw-r--r--crates/ra_hir_ty/src/lower.rs28
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs16
-rw-r--r--crates/ra_hir_ty/src/traits.rs16
-rw-r--r--crates/ra_hir_ty/src/traits/builtin.rs53
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs153
-rw-r--r--crates/ra_hir_ty/src/utils.rs6
12 files changed, 307 insertions, 158 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d277d6cfd..504db0c72 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -114,7 +114,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
114[[package]] 114[[package]]
115name = "chalk-derive" 115name = "chalk-derive"
116version = "0.1.0" 116version = "0.1.0"
117source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179" 117source = "git+https://github.com/rust-lang/chalk.git?rev=039fc904a05f8cb3d0c682c9a57a63dda7a35356#039fc904a05f8cb3d0c682c9a57a63dda7a35356"
118dependencies = [ 118dependencies = [
119 "proc-macro2", 119 "proc-macro2",
120 "quote", 120 "quote",
@@ -124,7 +124,7 @@ dependencies = [
124[[package]] 124[[package]]
125name = "chalk-engine" 125name = "chalk-engine"
126version = "0.9.0" 126version = "0.9.0"
127source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179" 127source = "git+https://github.com/rust-lang/chalk.git?rev=039fc904a05f8cb3d0c682c9a57a63dda7a35356#039fc904a05f8cb3d0c682c9a57a63dda7a35356"
128dependencies = [ 128dependencies = [
129 "chalk-macros", 129 "chalk-macros",
130 "rustc-hash", 130 "rustc-hash",
@@ -133,7 +133,7 @@ dependencies = [
133[[package]] 133[[package]]
134name = "chalk-ir" 134name = "chalk-ir"
135version = "0.1.0" 135version = "0.1.0"
136source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179" 136source = "git+https://github.com/rust-lang/chalk.git?rev=039fc904a05f8cb3d0c682c9a57a63dda7a35356#039fc904a05f8cb3d0c682c9a57a63dda7a35356"
137dependencies = [ 137dependencies = [
138 "chalk-derive", 138 "chalk-derive",
139 "chalk-engine", 139 "chalk-engine",
@@ -143,7 +143,7 @@ dependencies = [
143[[package]] 143[[package]]
144name = "chalk-macros" 144name = "chalk-macros"
145version = "0.1.1" 145version = "0.1.1"
146source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179" 146source = "git+https://github.com/rust-lang/chalk.git?rev=039fc904a05f8cb3d0c682c9a57a63dda7a35356#039fc904a05f8cb3d0c682c9a57a63dda7a35356"
147dependencies = [ 147dependencies = [
148 "lazy_static", 148 "lazy_static",
149] 149]
@@ -151,7 +151,7 @@ dependencies = [
151[[package]] 151[[package]]
152name = "chalk-rust-ir" 152name = "chalk-rust-ir"
153version = "0.1.0" 153version = "0.1.0"
154source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179" 154source = "git+https://github.com/rust-lang/chalk.git?rev=039fc904a05f8cb3d0c682c9a57a63dda7a35356#039fc904a05f8cb3d0c682c9a57a63dda7a35356"
155dependencies = [ 155dependencies = [
156 "chalk-derive", 156 "chalk-derive",
157 "chalk-engine", 157 "chalk-engine",
@@ -162,7 +162,7 @@ dependencies = [
162[[package]] 162[[package]]
163name = "chalk-solve" 163name = "chalk-solve"
164version = "0.1.0" 164version = "0.1.0"
165source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179" 165source = "git+https://github.com/rust-lang/chalk.git?rev=039fc904a05f8cb3d0c682c9a57a63dda7a35356#039fc904a05f8cb3d0c682c9a57a63dda7a35356"
166dependencies = [ 166dependencies = [
167 "chalk-derive", 167 "chalk-derive",
168 "chalk-engine", 168 "chalk-engine",
@@ -170,7 +170,7 @@ dependencies = [
170 "chalk-macros", 170 "chalk-macros",
171 "chalk-rust-ir", 171 "chalk-rust-ir",
172 "ena", 172 "ena",
173 "itertools 0.8.2", 173 "itertools",
174 "petgraph", 174 "petgraph",
175 "rustc-hash", 175 "rustc-hash",
176] 176]
@@ -507,15 +507,6 @@ dependencies = [
507 507
508[[package]] 508[[package]]
509name = "itertools" 509name = "itertools"
510version = "0.8.2"
511source = "registry+https://github.com/rust-lang/crates.io-index"
512checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
513dependencies = [
514 "either",
515]
516
517[[package]]
518name = "itertools"
519version = "0.9.0" 510version = "0.9.0"
520source = "registry+https://github.com/rust-lang/crates.io-index" 511source = "registry+https://github.com/rust-lang/crates.io-index"
521checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" 512checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
@@ -873,7 +864,7 @@ name = "ra_assists"
873version = "0.1.0" 864version = "0.1.0"
874dependencies = [ 865dependencies = [
875 "either", 866 "either",
876 "itertools 0.9.0", 867 "itertools",
877 "ra_db", 868 "ra_db",
878 "ra_fmt", 869 "ra_fmt",
879 "ra_hir", 870 "ra_hir",
@@ -927,7 +918,7 @@ dependencies = [
927name = "ra_fmt" 918name = "ra_fmt"
928version = "0.1.0" 919version = "0.1.0"
929dependencies = [ 920dependencies = [
930 "itertools 0.9.0", 921 "itertools",
931 "ra_syntax", 922 "ra_syntax",
932] 923]
933 924
@@ -937,7 +928,7 @@ version = "0.1.0"
937dependencies = [ 928dependencies = [
938 "arrayvec", 929 "arrayvec",
939 "either", 930 "either",
940 "itertools 0.9.0", 931 "itertools",
941 "log", 932 "log",
942 "ra_db", 933 "ra_db",
943 "ra_hir_def", 934 "ra_hir_def",
@@ -1015,7 +1006,7 @@ dependencies = [
1015 "either", 1006 "either",
1016 "indexmap", 1007 "indexmap",
1017 "insta", 1008 "insta",
1018 "itertools 0.9.0", 1009 "itertools",
1019 "log", 1010 "log",
1020 "ra_assists", 1011 "ra_assists",
1021 "ra_cfg", 1012 "ra_cfg",
@@ -1127,7 +1118,7 @@ name = "ra_syntax"
1127version = "0.1.0" 1118version = "0.1.0"
1128dependencies = [ 1119dependencies = [
1129 "arrayvec", 1120 "arrayvec",
1130 "itertools 0.9.0", 1121 "itertools",
1131 "once_cell", 1122 "once_cell",
1132 "ra_parser", 1123 "ra_parser",
1133 "ra_text_edit", 1124 "ra_text_edit",
@@ -1305,7 +1296,7 @@ dependencies = [
1305 "crossbeam-channel", 1296 "crossbeam-channel",
1306 "env_logger", 1297 "env_logger",
1307 "globset", 1298 "globset",
1308 "itertools 0.9.0", 1299 "itertools",
1309 "jod-thread", 1300 "jod-thread",
1310 "log", 1301 "log",
1311 "lsp-server", 1302 "lsp-server",
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 5a58d70cf..45be08430 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -23,9 +23,9 @@ ra_prof = { path = "../ra_prof" }
23ra_syntax = { path = "../ra_syntax" } 23ra_syntax = { path = "../ra_syntax" }
24test_utils = { path = "../test_utils" } 24test_utils = { path = "../test_utils" }
25 25
26chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "177d71340acc7a7204a33115fc63075d86452179" } 26chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "039fc904a05f8cb3d0c682c9a57a63dda7a35356" }
27chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "177d71340acc7a7204a33115fc63075d86452179" } 27chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "039fc904a05f8cb3d0c682c9a57a63dda7a35356" }
28chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "177d71340acc7a7204a33115fc63075d86452179" } 28chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "039fc904a05f8cb3d0c682c9a57a63dda7a35356" }
29 29
30[dev-dependencies] 30[dev-dependencies]
31insta = "0.15.0" 31insta = "0.15.0"
diff --git a/crates/ra_hir_ty/src/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs
index 53e81e85d..d91c21e24 100644
--- a/crates/ra_hir_ty/src/autoderef.rs
+++ b/crates/ra_hir_ty/src/autoderef.rs
@@ -14,7 +14,7 @@ use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 traits::{InEnvironment, Solution}, 15 traits::{InEnvironment, Solution},
16 utils::generics, 16 utils::generics,
17 Canonical, Substs, Ty, TypeWalk, 17 BoundVar, Canonical, DebruijnIndex, Substs, Ty,
18}; 18};
19 19
20const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -61,14 +61,13 @@ fn deref_by_trait(
61 return None; 61 return None;
62 } 62 }
63 63
64 // FIXME make the Canonical handling nicer 64 // FIXME make the Canonical / bound var handling nicer
65 65
66 let parameters = Substs::build_for_generics(&generic_params) 66 let parameters =
67 .push(ty.value.value.clone().shift_bound_vars(1)) 67 Substs::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
68 .build();
69 68
70 let projection = super::traits::ProjectionPredicate { 69 let projection = super::traits::ProjectionPredicate {
71 ty: Ty::Bound(0), 70 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.num_vars)),
72 projection_ty: super::ProjectionTy { associated_ty: target, parameters }, 71 projection_ty: super::ProjectionTy { associated_ty: target, parameters },
73 }; 72 };
74 73
@@ -93,12 +92,16 @@ fn deref_by_trait(
93 // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be 92 // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be
94 // the case. 93 // the case.
95 for i in 1..vars.0.num_vars { 94 for i in 1..vars.0.num_vars {
96 if vars.0.value[i] != Ty::Bound((i - 1) as u32) { 95 if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
96 {
97 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 97 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
98 return None; 98 return None;
99 } 99 }
100 } 100 }
101 Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars }) 101 Some(Canonical {
102 value: vars.0.value[vars.0.value.len() - 1].clone(),
103 num_vars: vars.0.num_vars,
104 })
102 } 105 }
103 Solution::Ambig(_) => { 106 Solution::Ambig(_) => {
104 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); 107 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution);
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs
index 1665e25e4..0e9313aa1 100644
--- a/crates/ra_hir_ty/src/display.rs
+++ b/crates/ra_hir_ty/src/display.rs
@@ -311,7 +311,7 @@ impl HirDisplay for Ty {
311 } 311 }
312 } 312 }
313 } 313 }
314 Ty::Bound(idx) => write!(f, "?{}", idx)?, 314 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
315 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 315 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
316 match self { 316 match self {
317 Ty::Dyn(_) => write!(f, "dyn ")?, 317 Ty::Dyn(_) => write!(f, "dyn ")?,
diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs
index 0bf8fbd63..ac25f8a80 100644
--- a/crates/ra_hir_ty/src/infer/unify.rs
+++ b/crates/ra_hir_ty/src/infer/unify.rs
@@ -7,7 +7,9 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7use test_utils::tested_by; 7use test_utils::tested_by;
8 8
9use super::{InferenceContext, Obligation}; 9use super::{InferenceContext, Obligation};
10use crate::{Canonical, InEnvironment, InferTy, Substs, Ty, TypeCtor, TypeWalk}; 10use crate::{
11 BoundVar, Canonical, DebruijnIndex, InEnvironment, InferTy, Substs, Ty, TypeCtor, TypeWalk,
12};
11 13
12impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
13 pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b> 15 pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b>
@@ -47,7 +49,7 @@ where
47 }) 49 })
48 } 50 }
49 51
50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: usize) -> T { 52 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T {
51 t.fold_binders( 53 t.fold_binders(
52 &mut |ty, binders| match ty { 54 &mut |ty, binders| match ty {
53 Ty::Infer(tv) => { 55 Ty::Infer(tv) => {
@@ -72,7 +74,7 @@ where
72 InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root), 74 InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root),
73 }; 75 };
74 let position = self.add(free_var); 76 let position = self.add(free_var);
75 Ty::Bound((position + binders) as u32) 77 Ty::Bound(BoundVar::new(binders, position))
76 } 78 }
77 } 79 }
78 _ => ty, 80 _ => ty,
@@ -89,7 +91,7 @@ where
89 } 91 }
90 92
91 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { 93 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> {
92 let result = self.do_canonicalize(ty, 0); 94 let result = self.do_canonicalize(ty, DebruijnIndex::INNERMOST);
93 self.into_canonicalized(result) 95 self.into_canonicalized(result)
94 } 96 }
95 97
@@ -98,8 +100,12 @@ where
98 obligation: InEnvironment<Obligation>, 100 obligation: InEnvironment<Obligation>,
99 ) -> Canonicalized<InEnvironment<Obligation>> { 101 ) -> Canonicalized<InEnvironment<Obligation>> {
100 let result = match obligation.value { 102 let result = match obligation.value {
101 Obligation::Trait(tr) => Obligation::Trait(self.do_canonicalize(tr, 0)), 103 Obligation::Trait(tr) => {
102 Obligation::Projection(pr) => Obligation::Projection(self.do_canonicalize(pr, 0)), 104 Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST))
105 }
106 Obligation::Projection(pr) => {
107 Obligation::Projection(self.do_canonicalize(pr, DebruijnIndex::INNERMOST))
108 }
103 }; 109 };
104 self.into_canonicalized(InEnvironment { 110 self.into_canonicalized(InEnvironment {
105 value: result, 111 value: result,
@@ -112,13 +118,13 @@ impl<T> Canonicalized<T> {
112 pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 118 pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
113 ty.walk_mut_binders( 119 ty.walk_mut_binders(
114 &mut |ty, binders| { 120 &mut |ty, binders| {
115 if let &mut Ty::Bound(idx) = ty { 121 if let &mut Ty::Bound(bound) = ty {
116 if idx as usize >= binders && (idx as usize - binders) < self.free_vars.len() { 122 if bound.debruijn >= binders {
117 *ty = Ty::Infer(self.free_vars[idx as usize - binders]); 123 *ty = Ty::Infer(self.free_vars[bound.index]);
118 } 124 }
119 } 125 }
120 }, 126 },
121 0, 127 DebruijnIndex::INNERMOST,
122 ); 128 );
123 ty 129 ty
124 } 130 }
@@ -150,7 +156,7 @@ pub fn unify(ty1: &Canonical<Ty>, ty2: &Canonical<Ty>) -> Option<Substs> {
150 // (kind of hacky) 156 // (kind of hacky)
151 for (i, var) in vars.iter().enumerate() { 157 for (i, var) in vars.iter().enumerate() {
152 if &*table.resolve_ty_shallow(var) == var { 158 if &*table.resolve_ty_shallow(var) == var {
153 table.unify(var, &Ty::Bound(i as u32)); 159 table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i)));
154 } 160 }
155 } 161 }
156 Some( 162 Some(
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 6c5469ecd..a9022dee7 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -64,6 +64,8 @@ pub use lower::{
64}; 64};
65pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 65pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
66 66
67pub use chalk_ir::{BoundVar, DebruijnIndex};
68
67/// A type constructor or type name: this might be something like the primitive 69/// A type constructor or type name: this might be something like the primitive
68/// type `bool`, a struct like `Vec`, or things like function pointers or 70/// type `bool`, a struct like `Vec`, or things like function pointers or
69/// tuples. 71/// tuples.
@@ -265,7 +267,11 @@ impl TypeWalk for ProjectionTy {
265 self.parameters.walk(f); 267 self.parameters.walk(f);
266 } 268 }
267 269
268 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { 270 fn walk_mut_binders(
271 &mut self,
272 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
273 binders: DebruijnIndex,
274 ) {
269 self.parameters.walk_mut_binders(f, binders); 275 self.parameters.walk_mut_binders(f, binders);
270 } 276 }
271} 277}
@@ -299,7 +305,7 @@ pub enum Ty {
299 /// parameters get turned into variables; during trait resolution, inference 305 /// parameters get turned into variables; during trait resolution, inference
300 /// variables get turned into bound variables and back; and in `Dyn` the 306 /// variables get turned into bound variables and back; and in `Dyn` the
301 /// `Self` type is represented with a bound variable as well. 307 /// `Self` type is represented with a bound variable as well.
302 Bound(u32), 308 Bound(BoundVar),
303 309
304 /// A type variable used during type checking. 310 /// A type variable used during type checking.
305 Infer(InferTy), 311 Infer(InferTy),
@@ -337,7 +343,11 @@ impl TypeWalk for Substs {
337 } 343 }
338 } 344 }
339 345
340 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { 346 fn walk_mut_binders(
347 &mut self,
348 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
349 binders: DebruijnIndex,
350 ) {
341 for t in make_mut_slice(&mut self.0) { 351 for t in make_mut_slice(&mut self.0) {
342 t.walk_mut_binders(f, binders); 352 t.walk_mut_binders(f, binders);
343 } 353 }
@@ -381,7 +391,13 @@ impl Substs {
381 391
382 /// Return Substs that replace each parameter by a bound variable. 392 /// Return Substs that replace each parameter by a bound variable.
383 pub(crate) fn bound_vars(generic_params: &Generics) -> Substs { 393 pub(crate) fn bound_vars(generic_params: &Generics) -> Substs {
384 Substs(generic_params.iter().enumerate().map(|(idx, _)| Ty::Bound(idx as u32)).collect()) 394 Substs(
395 generic_params
396 .iter()
397 .enumerate()
398 .map(|(idx, _)| Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx)))
399 .collect(),
400 )
385 } 401 }
386 402
387 pub fn build_for_def(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { 403 pub fn build_for_def(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
@@ -425,8 +441,8 @@ impl SubstsBuilder {
425 self.param_count - self.vec.len() 441 self.param_count - self.vec.len()
426 } 442 }
427 443
428 pub fn fill_with_bound_vars(self, starting_from: u32) -> Self { 444 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
429 self.fill((starting_from..).map(Ty::Bound)) 445 self.fill((starting_from..).map(|idx| Ty::Bound(BoundVar::new(debruijn, idx))))
430 } 446 }
431 447
432 pub fn fill_with_unknown(self) -> Self { 448 pub fn fill_with_unknown(self) -> Self {
@@ -507,7 +523,11 @@ impl TypeWalk for TraitRef {
507 self.substs.walk(f); 523 self.substs.walk(f);
508 } 524 }
509 525
510 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { 526 fn walk_mut_binders(
527 &mut self,
528 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
529 binders: DebruijnIndex,
530 ) {
511 self.substs.walk_mut_binders(f, binders); 531 self.substs.walk_mut_binders(f, binders);
512 } 532 }
513} 533}
@@ -558,7 +578,11 @@ impl TypeWalk for GenericPredicate {
558 } 578 }
559 } 579 }
560 580
561 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { 581 fn walk_mut_binders(
582 &mut self,
583 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
584 binders: DebruijnIndex,
585 ) {
562 match self { 586 match self {
563 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), 587 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
564 GenericPredicate::Projection(projection_pred) => { 588 GenericPredicate::Projection(projection_pred) => {
@@ -616,7 +640,11 @@ impl TypeWalk for FnSig {
616 } 640 }
617 } 641 }
618 642
619 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { 643 fn walk_mut_binders(
644 &mut self,
645 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
646 binders: DebruijnIndex,
647 ) {
620 for t in make_mut_slice(&mut self.params_and_return) { 648 for t in make_mut_slice(&mut self.params_and_return) {
621 t.walk_mut_binders(f, binders); 649 t.walk_mut_binders(f, binders);
622 } 650 }
@@ -755,7 +783,7 @@ impl Ty {
755pub trait TypeWalk { 783pub trait TypeWalk {
756 fn walk(&self, f: &mut impl FnMut(&Ty)); 784 fn walk(&self, f: &mut impl FnMut(&Ty));
757 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { 785 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
758 self.walk_mut_binders(&mut |ty, _binders| f(ty), 0); 786 self.walk_mut_binders(&mut |ty, _binders| f(ty), DebruijnIndex::INNERMOST);
759 } 787 }
760 /// Walk the type, counting entered binders. 788 /// Walk the type, counting entered binders.
761 /// 789 ///
@@ -767,9 +795,17 @@ pub trait TypeWalk {
767 /// that. Currently, the only thing that introduces bound variables on our 795 /// that. Currently, the only thing that introduces bound variables on our
768 /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound 796 /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound
769 /// variable for the self type. 797 /// variable for the self type.
770 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize); 798 fn walk_mut_binders(
771 799 &mut self,
772 fn fold_binders(mut self, f: &mut impl FnMut(Ty, usize) -> Ty, binders: usize) -> Self 800 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
801 binders: DebruijnIndex,
802 );
803
804 fn fold_binders(
805 mut self,
806 f: &mut impl FnMut(Ty, DebruijnIndex) -> Ty,
807 binders: DebruijnIndex,
808 ) -> Self
773 where 809 where
774 Self: Sized, 810 Self: Sized,
775 { 811 {
@@ -795,40 +831,43 @@ pub trait TypeWalk {
795 } 831 }
796 832
797 /// Substitutes `Ty::Bound` vars with the given substitution. 833 /// Substitutes `Ty::Bound` vars with the given substitution.
798 fn subst_bound_vars(mut self, substs: &Substs) -> Self 834 fn subst_bound_vars(self, substs: &Substs) -> Self
835 where
836 Self: Sized,
837 {
838 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST)
839 }
840
841 /// Substitutes `Ty::Bound` vars with the given substitution.
842 fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self
799 where 843 where
800 Self: Sized, 844 Self: Sized,
801 { 845 {
802 self.walk_mut_binders( 846 self.walk_mut_binders(
803 &mut |ty, binders| { 847 &mut |ty, binders| {
804 if let &mut Ty::Bound(idx) = ty { 848 if let &mut Ty::Bound(bound) = ty {
805 if idx as usize >= binders && (idx as usize - binders) < substs.len() { 849 if bound.debruijn >= binders {
806 *ty = substs.0[idx as usize - binders].clone(); 850 *ty = substs.0[bound.index].clone();
807 } else if idx as usize >= binders + substs.len() {
808 // shift free binders
809 *ty = Ty::Bound(idx - substs.len() as u32);
810 } 851 }
811 } 852 }
812 }, 853 },
813 0, 854 depth,
814 ); 855 );
815 self 856 self
816 } 857 }
817 858 // /// Shifts up debruijn indices of `Ty::Bound` vars by `n`.
818 /// Shifts up `Ty::Bound` vars by `n`. 859 fn shift_bound_vars(self, n: DebruijnIndex) -> Self
819 fn shift_bound_vars(self, n: i32) -> Self
820 where 860 where
821 Self: Sized, 861 Self: Sized,
822 { 862 {
823 self.fold_binders( 863 self.fold_binders(
824 &mut |ty, binders| match ty { 864 &mut |ty, binders| match ty {
825 Ty::Bound(idx) if idx as usize >= binders => { 865 Ty::Bound(bound) if bound.debruijn >= binders => {
826 assert!(idx as i32 >= -n); 866 Ty::Bound(bound.shifted_in_from(n))
827 Ty::Bound((idx as i32 + n) as u32)
828 } 867 }
829 ty => ty, 868 ty => ty,
830 }, 869 },
831 0, 870 DebruijnIndex::INNERMOST,
832 ) 871 )
833 } 872 }
834} 873}
@@ -856,7 +895,11 @@ impl TypeWalk for Ty {
856 f(self); 895 f(self);
857 } 896 }
858 897
859 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { 898 fn walk_mut_binders(
899 &mut self,
900 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
901 binders: DebruijnIndex,
902 ) {
860 match self { 903 match self {
861 Ty::Apply(a_ty) => { 904 Ty::Apply(a_ty) => {
862 a_ty.parameters.walk_mut_binders(f, binders); 905 a_ty.parameters.walk_mut_binders(f, binders);
@@ -866,7 +909,7 @@ impl TypeWalk for Ty {
866 } 909 }
867 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 910 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
868 for p in make_mut_slice(predicates) { 911 for p in make_mut_slice(predicates) {
869 p.walk_mut_binders(f, binders + 1); 912 p.walk_mut_binders(f, binders.shifted_in());
870 } 913 }
871 } 914 }
872 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 915 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index d7f250783..6c7bbc448 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -29,8 +29,8 @@ use crate::{
29 all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice, 29 all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice,
30 variant_data, 30 variant_data,
31 }, 31 },
32 Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs, 32 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate,
33 TraitEnvironment, TraitRef, Ty, TypeCtor, 33 ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
34}; 34};
35 35
36#[derive(Debug)] 36#[derive(Debug)]
@@ -131,7 +131,7 @@ impl Ty {
131 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) 131 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig)
132 } 132 }
133 TypeRef::DynTrait(bounds) => { 133 TypeRef::DynTrait(bounds) => {
134 let self_ty = Ty::Bound(0); 134 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
135 let predicates = bounds 135 let predicates = bounds
136 .iter() 136 .iter()
137 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) 137 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
@@ -141,7 +141,7 @@ impl Ty {
141 TypeRef::ImplTrait(bounds) => { 141 TypeRef::ImplTrait(bounds) => {
142 match ctx.impl_trait_mode { 142 match ctx.impl_trait_mode {
143 ImplTraitLoweringMode::Opaque => { 143 ImplTraitLoweringMode::Opaque => {
144 let self_ty = Ty::Bound(0); 144 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
145 let predicates = bounds 145 let predicates = bounds
146 .iter() 146 .iter()
147 .flat_map(|b| { 147 .flat_map(|b| {
@@ -177,12 +177,10 @@ impl Ty {
177 } else { 177 } else {
178 (0, 0, 0, 0) 178 (0, 0, 0, 0)
179 }; 179 };
180 Ty::Bound( 180 Ty::Bound(BoundVar::new(
181 idx as u32 181 DebruijnIndex::INNERMOST,
182 + parent_params as u32 182 idx as usize + parent_params + self_params + list_params,
183 + self_params as u32 183 ))
184 + list_params as u32,
185 )
186 } 184 }
187 ImplTraitLoweringMode::Disallowed => { 185 ImplTraitLoweringMode::Disallowed => {
188 // FIXME: report error 186 // FIXME: report error
@@ -249,7 +247,11 @@ impl Ty {
249 let ty = match resolution { 247 let ty = match resolution {
250 TypeNs::TraitId(trait_) => { 248 TypeNs::TraitId(trait_) => {
251 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there 249 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there
252 let self_ty = if remaining_segments.len() == 0 { Some(Ty::Bound(0)) } else { None }; 250 let self_ty = if remaining_segments.len() == 0 {
251 Some(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
252 } else {
253 None
254 };
253 let trait_ref = 255 let trait_ref =
254 TraitRef::from_resolved_path(ctx, trait_, resolved_segment, self_ty); 256 TraitRef::from_resolved_path(ctx, trait_, resolved_segment, self_ty);
255 let ty = if remaining_segments.len() == 1 { 257 let ty = if remaining_segments.len() == 1 {
@@ -289,7 +291,7 @@ impl Ty {
289 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 291 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
290 TypeParamLoweringMode::Variable => { 292 TypeParamLoweringMode::Variable => {
291 let idx = generics.param_idx(param_id).expect("matching generics"); 293 let idx = generics.param_idx(param_id).expect("matching generics");
292 Ty::Bound(idx) 294 Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx))
293 } 295 }
294 } 296 }
295 } 297 }
@@ -558,7 +560,7 @@ impl GenericPredicate {
558 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 560 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
559 TypeParamLoweringMode::Variable => { 561 TypeParamLoweringMode::Variable => {
560 let idx = generics.param_idx(param_id).expect("matching generics"); 562 let idx = generics.param_idx(param_id).expect("matching generics");
561 Ty::Bound(idx) 563 Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx))
562 } 564 }
563 } 565 }
564 } 566 }
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 533c6ccfb..74a0bc7db 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -20,7 +20,8 @@ use crate::{
20 db::HirDatabase, 20 db::HirDatabase,
21 primitive::{FloatBitness, Uncertain}, 21 primitive::{FloatBitness, Uncertain},
22 utils::all_super_traits, 22 utils::all_super_traits,
23 ApplicationTy, Canonical, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 23 ApplicationTy, Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty,
24 TypeCtor, TypeWalk,
24}; 25};
25 26
26/// This is used as a key for indexing impls. 27/// This is used as a key for indexing impls.
@@ -507,8 +508,9 @@ pub(crate) fn inherent_impl_substs(
507) -> Option<Substs> { 508) -> Option<Substs> {
508 // we create a var for each type parameter of the impl; we need to keep in 509 // we create a var for each type parameter of the impl; we need to keep in
509 // mind here that `self_ty` might have vars of its own 510 // mind here that `self_ty` might have vars of its own
510 let vars = 511 let vars = Substs::build_for_def(db, impl_id)
511 Substs::build_for_def(db, impl_id).fill_with_bound_vars(self_ty.num_vars as u32).build(); 512 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.num_vars)
513 .build();
512 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 514 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
513 let self_ty_with_vars = 515 let self_ty_with_vars =
514 Canonical { num_vars: vars.len() + self_ty.num_vars, value: self_ty_with_vars }; 516 Canonical { num_vars: vars.len() + self_ty.num_vars, value: self_ty_with_vars };
@@ -526,8 +528,8 @@ pub(crate) fn inherent_impl_substs(
526fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { 528fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs {
527 s.fold_binders( 529 s.fold_binders(
528 &mut |ty, binders| { 530 &mut |ty, binders| {
529 if let Ty::Bound(idx) = &ty { 531 if let Ty::Bound(bound) = &ty {
530 if *idx >= binders as u32 { 532 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
531 Ty::Unknown 533 Ty::Unknown
532 } else { 534 } else {
533 ty 535 ty
@@ -536,7 +538,7 @@ fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs {
536 ty 538 ty
537 } 539 }
538 }, 540 },
539 num_vars_to_keep, 541 DebruijnIndex::INNERMOST,
540 ) 542 )
541} 543}
542 544
@@ -586,7 +588,7 @@ fn generic_implements_goal(
586 let num_vars = self_ty.num_vars; 588 let num_vars = self_ty.num_vars;
587 let substs = super::Substs::build_for_def(db, trait_) 589 let substs = super::Substs::build_for_def(db, trait_)
588 .push(self_ty.value) 590 .push(self_ty.value)
589 .fill_with_bound_vars(num_vars as u32) 591 .fill_with_bound_vars(DebruijnIndex::INNERMOST, num_vars)
590 .build(); 592 .build();
591 let num_vars = substs.len() - 1 + self_ty.num_vars; 593 let num_vars = substs.len() - 1 + self_ty.num_vars;
592 let trait_ref = TraitRef { trait_, substs }; 594 let trait_ref = TraitRef { trait_, substs };
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index a1ca33c98..07854a062 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -7,7 +7,7 @@ use ra_db::{impl_intern_key, salsa, CrateId};
7use ra_prof::profile; 7use ra_prof::profile;
8use rustc_hash::FxHashSet; 8use rustc_hash::FxHashSet;
9 9
10use crate::db::HirDatabase; 10use crate::{db::HirDatabase, DebruijnIndex};
11 11
12use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 12use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
13 13
@@ -128,7 +128,11 @@ impl TypeWalk for ProjectionPredicate {
128 self.ty.walk(f); 128 self.ty.walk(f);
129 } 129 }
130 130
131 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { 131 fn walk_mut_binders(
132 &mut self,
133 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
134 binders: DebruijnIndex,
135 ) {
132 self.projection_ty.walk_mut_binders(f, binders); 136 self.projection_ty.walk_mut_binders(f, binders);
133 self.ty.walk_mut_binders(f, binders); 137 self.ty.walk_mut_binders(f, binders);
134 } 138 }
@@ -144,7 +148,7 @@ pub(crate) fn trait_solve_query(
144 Obligation::Trait(it) => db.trait_data(it.trait_).name.to_string(), 148 Obligation::Trait(it) => db.trait_data(it.trait_).name.to_string(),
145 Obligation::Projection(_) => "projection".to_string(), 149 Obligation::Projection(_) => "projection".to_string(),
146 }); 150 });
147 log::debug!("trait_solve_query({})", goal.value.value.display(db)); 151 eprintln!("trait_solve_query({})", goal.value.value.display(db));
148 152
149 if let Obligation::Projection(pred) = &goal.value.value { 153 if let Obligation::Projection(pred) = &goal.value.value {
150 if let Ty::Bound(_) = &pred.projection_ty.parameters[0] { 154 if let Ty::Bound(_) = &pred.projection_ty.parameters[0] {
@@ -153,7 +157,7 @@ pub(crate) fn trait_solve_query(
153 } 157 }
154 } 158 }
155 159
156 let canonical = goal.to_chalk(db).cast(); 160 let canonical = goal.to_chalk(db).cast(&Interner);
157 161
158 // We currently don't deal with universes (I think / hope they're not yet 162 // We currently don't deal with universes (I think / hope they're not yet
159 // relevant for our use cases?) 163 // relevant for our use cases?)
@@ -194,8 +198,8 @@ fn solution_from_chalk(
194 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<Interner>>| { 198 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<Interner>>| {
195 let value = subst 199 let value = subst
196 .value 200 .value
197 .into_iter() 201 .iter(&Interner)
198 .map(|p| match p.ty() { 202 .map(|p| match p.ty(&Interner) {
199 Some(ty) => from_chalk(db, ty.clone()), 203 Some(ty) => from_chalk(db, ty.clone()),
200 None => unimplemented!(), 204 None => unimplemented!(),
201 }) 205 })
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs
index 73e3c5c78..ccab246bf 100644
--- a/crates/ra_hir_ty/src/traits/builtin.rs
+++ b/crates/ra_hir_ty/src/traits/builtin.rs
@@ -8,7 +8,8 @@ use super::{AssocTyValue, Impl, UnsizeToSuperTraitObjectData};
8use crate::{ 8use crate::{
9 db::HirDatabase, 9 db::HirDatabase,
10 utils::{all_super_traits, generics}, 10 utils::{all_super_traits, generics},
11 ApplicationTy, Binders, GenericPredicate, Substs, TraitRef, Ty, TypeCtor, 11 ApplicationTy, Binders, BoundVar, DebruijnIndex, GenericPredicate, Substs, TraitRef, Ty,
12 TypeCtor, TypeWalk,
12}; 13};
13 14
14pub(super) struct BuiltinImplData { 15pub(super) struct BuiltinImplData {
@@ -164,11 +165,15 @@ fn closure_fn_trait_impl_datum(
164 165
165 let arg_ty = Ty::apply( 166 let arg_ty = Ty::apply(
166 TypeCtor::Tuple { cardinality: num_args }, 167 TypeCtor::Tuple { cardinality: num_args },
167 Substs::builder(num_args as usize).fill_with_bound_vars(0).build(), 168 Substs::builder(num_args as usize)
169 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
170 .build(),
168 ); 171 );
169 let sig_ty = Ty::apply( 172 let sig_ty = Ty::apply(
170 TypeCtor::FnPtr { num_args }, 173 TypeCtor::FnPtr { num_args },
171 Substs::builder(num_args as usize + 1).fill_with_bound_vars(0).build(), 174 Substs::builder(num_args as usize + 1)
175 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
176 .build(),
172 ); 177 );
173 178
174 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty); 179 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty);
@@ -203,7 +208,7 @@ fn closure_fn_trait_output_assoc_ty_value(
203 } 208 }
204 }; 209 };
205 210
206 let output_ty = Ty::Bound(num_args.into()); 211 let output_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, num_args.into()));
207 212
208 let fn_once_trait = 213 let fn_once_trait =
209 get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist"); 214 get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist");
@@ -241,7 +246,7 @@ fn array_unsize_impl_datum(db: &dyn HirDatabase, krate: CrateId) -> BuiltinImplD
241 // the existence of the Unsize trait has been checked before 246 // the existence of the Unsize trait has been checked before
242 .expect("Unsize trait missing"); 247 .expect("Unsize trait missing");
243 248
244 let var = Ty::Bound(0); 249 let var = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
245 let substs = Substs::builder(2) 250 let substs = Substs::builder(2)
246 .push(Ty::apply_one(TypeCtor::Array, var.clone())) 251 .push(Ty::apply_one(TypeCtor::Array, var.clone()))
247 .push(Ty::apply_one(TypeCtor::Slice, var)) 252 .push(Ty::apply_one(TypeCtor::Slice, var))
@@ -270,19 +275,18 @@ fn trait_object_unsize_impl_datum(
270 // the existence of the Unsize trait has been checked before 275 // the existence of the Unsize trait has been checked before
271 .expect("Unsize trait missing"); 276 .expect("Unsize trait missing");
272 277
273 let self_ty = Ty::Bound(0); 278 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
274 279
275 let target_substs = Substs::build_for_def(db, trait_) 280 let target_substs = Substs::build_for_def(db, trait_)
276 .push(Ty::Bound(0)) 281 .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
277 // starting from ^2 because we want to start with ^1 outside of the 282 .fill_with_bound_vars(DebruijnIndex::ONE, 1)
278 // `dyn`, which is ^2 inside
279 .fill_with_bound_vars(2)
280 .build(); 283 .build();
281 let num_vars = target_substs.len(); 284 let num_vars = target_substs.len();
282 let target_trait_ref = TraitRef { trait_, substs: target_substs }; 285 let target_trait_ref = TraitRef { trait_, substs: target_substs };
283 let target_bounds = vec![GenericPredicate::Implemented(target_trait_ref)]; 286 let target_bounds = vec![GenericPredicate::Implemented(target_trait_ref)];
284 287
285 let self_substs = Substs::build_for_def(db, trait_).fill_with_bound_vars(0).build(); 288 let self_substs =
289 Substs::build_for_def(db, trait_).fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
286 let self_trait_ref = TraitRef { trait_, substs: self_substs }; 290 let self_trait_ref = TraitRef { trait_, substs: self_substs };
287 let where_clauses = vec![GenericPredicate::Implemented(self_trait_ref)]; 291 let where_clauses = vec![GenericPredicate::Implemented(self_trait_ref)];
288 292
@@ -305,24 +309,26 @@ fn super_trait_object_unsize_impl_datum(
305 // the existence of the Unsize trait has been checked before 309 // the existence of the Unsize trait has been checked before
306 .expect("Unsize trait missing"); 310 .expect("Unsize trait missing");
307 311
308 let self_substs = Substs::build_for_def(db, data.trait_).fill_with_bound_vars(0).build(); 312 let self_substs = Substs::build_for_def(db, data.trait_)
313 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
314 .build();
315 let self_trait_ref = TraitRef { trait_: data.trait_, substs: self_substs.clone() };
309 316
310 let num_vars = self_substs.len() - 1; 317 let num_vars = self_substs.len() - 1;
311 318
312 let self_trait_ref = TraitRef { trait_: data.trait_, substs: self_substs.clone() };
313 let self_bounds = vec![GenericPredicate::Implemented(self_trait_ref.clone())];
314
315 // we need to go from our trait to the super trait, substituting type parameters 319 // we need to go from our trait to the super trait, substituting type parameters
316 let path = crate::utils::find_super_trait_path(db.upcast(), data.trait_, data.super_trait); 320 let path = crate::utils::find_super_trait_path(db.upcast(), data.trait_, data.super_trait);
317 321
318 let mut current_trait_ref = self_trait_ref; 322 let mut current_trait_ref = self_trait_ref.clone();
319 for t in path.into_iter().skip(1) { 323 for t in path.into_iter().skip(1) {
320 let bounds = db.generic_predicates(current_trait_ref.trait_.into()); 324 let bounds = db.generic_predicates(current_trait_ref.trait_.into());
321 let super_trait_ref = bounds 325 let super_trait_ref = bounds
322 .iter() 326 .iter()
323 .find_map(|b| match &b.value { 327 .find_map(|b| match &b.value {
324 GenericPredicate::Implemented(tr) 328 GenericPredicate::Implemented(tr)
325 if tr.trait_ == t && tr.substs[0] == Ty::Bound(0) => 329 if tr.trait_ == t
330 && tr.substs[0]
331 == Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)) =>
326 { 332 {
327 Some(Binders { value: tr, num_binders: b.num_binders }) 333 Some(Binders { value: tr, num_binders: b.num_binders })
328 } 334 }
@@ -332,7 +338,18 @@ fn super_trait_object_unsize_impl_datum(
332 current_trait_ref = super_trait_ref.cloned().subst(&current_trait_ref.substs); 338 current_trait_ref = super_trait_ref.cloned().subst(&current_trait_ref.substs);
333 } 339 }
334 340
335 let super_bounds = vec![GenericPredicate::Implemented(current_trait_ref)]; 341 // We need to renumber the variables a bit now: from ^0.0, ^0.1, ^0.2, ...
342 // to ^0.0, ^1.0, ^1.1. The reason for this is that the first variable comes
343 // from the dyn Trait binder, while the other variables come from the impl.
344 let new_substs = Substs::builder(num_vars + 1)
345 .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
346 .fill_with_bound_vars(DebruijnIndex::ONE, 0)
347 .build();
348
349 let self_bounds =
350 vec![GenericPredicate::Implemented(self_trait_ref.subst_bound_vars(&new_substs))];
351 let super_bounds =
352 vec![GenericPredicate::Implemented(current_trait_ref.subst_bound_vars(&new_substs))];
336 353
337 let substs = Substs::builder(2) 354 let substs = Substs::builder(2)
338 .push(Ty::Dyn(self_bounds.into())) 355 .push(Ty::Dyn(self_bounds.into()))
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 943d5f125..53ce362ea 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -3,7 +3,10 @@ use std::{fmt, sync::Arc};
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{cast::Cast, Goal, GoalData, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, Goal, GoalData, Parameter, PlaceholderIndex, TypeName,
8 UniverseIndex,
9};
7 10
8use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; 11use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
9use ra_db::{ 12use ra_db::{
@@ -59,53 +62,126 @@ impl chalk_ir::interner::Interner for Interner {
59 None 62 None
60 } 63 }
61 64
65 fn debug_ty(_ty: &chalk_ir::Ty<Self>, _fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
66 None
67 }
68
69 fn debug_lifetime(
70 _lifetime: &chalk_ir::Lifetime<Self>,
71 _fmt: &mut fmt::Formatter<'_>,
72 ) -> Option<fmt::Result> {
73 None
74 }
75
76 fn debug_parameter(
77 _parameter: &Parameter<Self>,
78 _fmt: &mut fmt::Formatter<'_>,
79 ) -> Option<fmt::Result> {
80 None
81 }
82
83 fn debug_goal(_goal: &Goal<Self>, _fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
84 None
85 }
86
87 fn debug_goals(
88 _goals: &chalk_ir::Goals<Self>,
89 _fmt: &mut fmt::Formatter<'_>,
90 ) -> Option<fmt::Result> {
91 None
92 }
93
94 fn debug_program_clause_implication(
95 _pci: &chalk_ir::ProgramClauseImplication<Self>,
96 _fmt: &mut fmt::Formatter<'_>,
97 ) -> Option<fmt::Result> {
98 None
99 }
100
101 fn debug_application_ty(
102 _application_ty: &chalk_ir::ApplicationTy<Self>,
103 _fmt: &mut fmt::Formatter<'_>,
104 ) -> Option<fmt::Result> {
105 None
106 }
107
108 fn debug_substitution(
109 _substitution: &chalk_ir::Substitution<Self>,
110 _fmt: &mut fmt::Formatter<'_>,
111 ) -> Option<fmt::Result> {
112 None
113 }
114
115 fn debug_separator_trait_ref(
116 _separator_trait_ref: &chalk_ir::SeparatorTraitRef<Self>,
117 _fmt: &mut fmt::Formatter<'_>,
118 ) -> Option<fmt::Result> {
119 None
120 }
121
62 fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> { 122 fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> {
63 Box::new(ty) 123 Box::new(ty)
64 } 124 }
65 125
66 fn ty_data(ty: &Box<chalk_ir::TyData<Self>>) -> &chalk_ir::TyData<Self> { 126 fn ty_data<'a>(&self, ty: &'a Box<chalk_ir::TyData<Self>>) -> &'a chalk_ir::TyData<Self> {
67 ty 127 ty
68 } 128 }
69 129
70 fn intern_lifetime(lifetime: chalk_ir::LifetimeData<Self>) -> chalk_ir::LifetimeData<Self> { 130 fn intern_lifetime(
131 &self,
132 lifetime: chalk_ir::LifetimeData<Self>,
133 ) -> chalk_ir::LifetimeData<Self> {
71 lifetime 134 lifetime
72 } 135 }
73 136
74 fn lifetime_data(lifetime: &chalk_ir::LifetimeData<Self>) -> &chalk_ir::LifetimeData<Self> { 137 fn lifetime_data<'a>(
138 &self,
139 lifetime: &'a chalk_ir::LifetimeData<Self>,
140 ) -> &'a chalk_ir::LifetimeData<Self> {
75 lifetime 141 lifetime
76 } 142 }
77 143
78 fn intern_parameter(parameter: chalk_ir::ParameterData<Self>) -> chalk_ir::ParameterData<Self> { 144 fn intern_parameter(
145 &self,
146 parameter: chalk_ir::ParameterData<Self>,
147 ) -> chalk_ir::ParameterData<Self> {
79 parameter 148 parameter
80 } 149 }
81 150
82 fn parameter_data(parameter: &chalk_ir::ParameterData<Self>) -> &chalk_ir::ParameterData<Self> { 151 fn parameter_data<'a>(
152 &self,
153 parameter: &'a chalk_ir::ParameterData<Self>,
154 ) -> &'a chalk_ir::ParameterData<Self> {
83 parameter 155 parameter
84 } 156 }
85 157
86 fn intern_goal(goal: GoalData<Self>) -> Arc<GoalData<Self>> { 158 fn intern_goal(&self, goal: GoalData<Self>) -> Arc<GoalData<Self>> {
87 Arc::new(goal) 159 Arc::new(goal)
88 } 160 }
89 161
90 fn intern_goals(data: impl IntoIterator<Item = Goal<Self>>) -> Self::InternedGoals { 162 fn intern_goals(&self, data: impl IntoIterator<Item = Goal<Self>>) -> Self::InternedGoals {
91 data.into_iter().collect() 163 data.into_iter().collect()
92 } 164 }
93 165
94 fn goal_data(goal: &Arc<GoalData<Self>>) -> &GoalData<Self> { 166 fn goal_data<'a>(&self, goal: &'a Arc<GoalData<Self>>) -> &'a GoalData<Self> {
95 goal 167 goal
96 } 168 }
97 169
98 fn goals_data(goals: &Vec<Goal<Interner>>) -> &[Goal<Interner>] { 170 fn goals_data<'a>(&self, goals: &'a Vec<Goal<Interner>>) -> &'a [Goal<Interner>] {
99 goals 171 goals
100 } 172 }
101 173
102 fn intern_substitution<E>( 174 fn intern_substitution<E>(
175 &self,
103 data: impl IntoIterator<Item = Result<Parameter<Self>, E>>, 176 data: impl IntoIterator<Item = Result<Parameter<Self>, E>>,
104 ) -> Result<Vec<Parameter<Self>>, E> { 177 ) -> Result<Vec<Parameter<Self>>, E> {
105 data.into_iter().collect() 178 data.into_iter().collect()
106 } 179 }
107 180
108 fn substitution_data(substitution: &Vec<Parameter<Self>>) -> &[Parameter<Self>] { 181 fn substitution_data<'a>(
182 &self,
183 substitution: &'a Vec<Parameter<Self>>,
184 ) -> &'a [Parameter<Self>] {
109 substitution 185 substitution
110 } 186 }
111} 187}
@@ -145,12 +221,14 @@ impl ToChalk for Ty {
145 Ty::Apply(apply_ty) => { 221 Ty::Apply(apply_ty) => {
146 let name = apply_ty.ctor.to_chalk(db); 222 let name = apply_ty.ctor.to_chalk(db);
147 let substitution = apply_ty.parameters.to_chalk(db); 223 let substitution = apply_ty.parameters.to_chalk(db);
148 chalk_ir::ApplicationTy { name, substitution }.cast().intern(&Interner) 224 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
149 } 225 }
150 Ty::Projection(proj_ty) => { 226 Ty::Projection(proj_ty) => {
151 let associated_ty_id = proj_ty.associated_ty.to_chalk(db); 227 let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
152 let substitution = proj_ty.parameters.to_chalk(db); 228 let substitution = proj_ty.parameters.to_chalk(db);
153 chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern(&Interner) 229 chalk_ir::AliasTy { associated_ty_id, substitution }
230 .cast(&Interner)
231 .intern(&Interner)
154 } 232 }
155 Ty::Placeholder(id) => { 233 Ty::Placeholder(id) => {
156 let interned_id = db.intern_type_param_id(id); 234 let interned_id = db.intern_type_param_id(id);
@@ -160,7 +238,7 @@ impl ToChalk for Ty {
160 } 238 }
161 .to_ty::<Interner>(&Interner) 239 .to_ty::<Interner>(&Interner)
162 } 240 }
163 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(&Interner), 241 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner),
164 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 242 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
165 Ty::Dyn(predicates) => { 243 Ty::Dyn(predicates) => {
166 let where_clauses = predicates 244 let where_clauses = predicates
@@ -173,14 +251,14 @@ impl ToChalk for Ty {
173 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 251 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
174 } 252 }
175 Ty::Opaque(_) | Ty::Unknown => { 253 Ty::Opaque(_) | Ty::Unknown => {
176 let substitution = chalk_ir::Substitution::empty(); 254 let substitution = chalk_ir::Substitution::empty(&Interner);
177 let name = TypeName::Error; 255 let name = TypeName::Error;
178 chalk_ir::ApplicationTy { name, substitution }.cast().intern(&Interner) 256 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
179 } 257 }
180 } 258 }
181 } 259 }
182 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 260 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
183 match chalk.data().clone() { 261 match chalk.data(&Interner).clone() {
184 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 262 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
185 TypeName::Error => Ty::Unknown, 263 TypeName::Error => Ty::Unknown,
186 _ => { 264 _ => {
@@ -202,7 +280,7 @@ impl ToChalk for Ty {
202 Ty::Projection(ProjectionTy { associated_ty, parameters }) 280 Ty::Projection(ProjectionTy { associated_ty, parameters })
203 } 281 }
204 chalk_ir::TyData::Function(_) => unimplemented!(), 282 chalk_ir::TyData::Function(_) => unimplemented!(),
205 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32), 283 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx),
206 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, 284 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
207 chalk_ir::TyData::Dyn(where_clauses) => { 285 chalk_ir::TyData::Dyn(where_clauses) => {
208 assert_eq!(where_clauses.bounds.binders.len(), 1); 286 assert_eq!(where_clauses.bounds.binders.len(), 1);
@@ -218,13 +296,13 @@ impl ToChalk for Substs {
218 type Chalk = chalk_ir::Substitution<Interner>; 296 type Chalk = chalk_ir::Substitution<Interner>;
219 297
220 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 298 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
221 chalk_ir::Substitution::from(self.iter().map(|ty| ty.clone().to_chalk(db))) 299 chalk_ir::Substitution::from(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
222 } 300 }
223 301
224 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs { 302 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs {
225 let tys = parameters 303 let tys = parameters
226 .into_iter() 304 .iter(&Interner)
227 .map(|p| match p.ty() { 305 .map(|p| match p.ty(&Interner) {
228 Some(ty) => from_chalk(db, ty.clone()), 306 Some(ty) => from_chalk(db, ty.clone()),
229 None => unimplemented!(), 307 None => unimplemented!(),
230 }) 308 })
@@ -332,15 +410,15 @@ impl ToChalk for GenericPredicate {
332 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> { 410 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> {
333 match self { 411 match self {
334 GenericPredicate::Implemented(trait_ref) => { 412 GenericPredicate::Implemented(trait_ref) => {
335 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 413 let chalk_trait_ref = trait_ref.to_chalk(db);
414 let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner);
415 make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0)
416 }
417 GenericPredicate::Projection(projection_pred) => {
418 let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner);
419 let alias = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner);
420 make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0)
336 } 421 }
337 GenericPredicate::Projection(projection_pred) => make_binders(
338 chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq {
339 alias: projection_pred.projection_ty.to_chalk(db),
340 ty: projection_pred.ty.to_chalk(db),
341 }),
342 0,
343 ),
344 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), 422 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
345 } 423 }
346 } 424 }
@@ -400,8 +478,8 @@ impl ToChalk for Obligation {
400 478
401 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { 479 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
402 match self { 480 match self {
403 Obligation::Trait(tr) => tr.to_chalk(db).cast(), 481 Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner),
404 Obligation::Projection(pr) => pr.to_chalk(db).cast(), 482 Obligation::Projection(pr) => pr.to_chalk(db).cast(&Interner),
405 } 483 }
406 } 484 }
407 485
@@ -438,8 +516,8 @@ impl ToChalk for Arc<super::TraitEnvironment> {
438 continue; 516 continue;
439 } 517 }
440 let program_clause: chalk_ir::ProgramClause<Interner> = 518 let program_clause: chalk_ir::ProgramClause<Interner> =
441 pred.clone().to_chalk(db).cast(); 519 pred.clone().to_chalk(db).cast(&Interner);
442 clauses.push(program_clause.into_from_env_clause()); 520 clauses.push(program_clause.into_from_env_clause(&Interner));
443 } 521 }
444 chalk_ir::Environment::new().add_clauses(clauses) 522 chalk_ir::Environment::new().add_clauses(clauses)
445 } 523 }
@@ -504,7 +582,8 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData {
504 type Chalk = AssociatedTyValue; 582 type Chalk = AssociatedTyValue;
505 583
506 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue { 584 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue {
507 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: self.value.to_chalk(db) }; 585 let ty = self.value.to_chalk(db);
586 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty };
508 587
509 chalk_rust_ir::AssociatedTyValue { 588 chalk_rust_ir::AssociatedTyValue {
510 associated_ty_id: self.assoc_ty_id.to_chalk(db), 589 associated_ty_id: self.assoc_ty_id.to_chalk(db),
@@ -578,9 +657,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
578 .map(|impl_| impl_.to_chalk(self.db)) 657 .map(|impl_| impl_.to_chalk(self.db))
579 .collect(); 658 .collect();
580 659
581 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref().clone()); 660 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
582 let arg: Option<Ty> = 661 let arg: Option<Ty> =
583 parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref().clone())); 662 parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone()));
584 663
585 builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| { 664 builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| {
586 result.push(i.to_chalk(self.db)) 665 result.push(i.to_chalk(self.db))
@@ -663,11 +742,13 @@ pub(crate) fn trait_datum_query(
663 let associated_ty_ids = 742 let associated_ty_ids =
664 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); 743 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
665 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses }; 744 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
745 let well_known = None; // FIXME set this (depending on lang items)
666 let trait_datum = TraitDatum { 746 let trait_datum = TraitDatum {
667 id: trait_id, 747 id: trait_id,
668 binders: make_binders(trait_datum_bound, bound_vars.len()), 748 binders: make_binders(trait_datum_bound, bound_vars.len()),
669 flags, 749 flags,
670 associated_ty_ids, 750 associated_ty_ids,
751 well_known,
671 }; 752 };
672 Arc::new(trait_datum) 753 Arc::new(trait_datum)
673} 754}
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs
index b40d4eb73..1e5022fa4 100644
--- a/crates/ra_hir_ty/src/utils.rs
+++ b/crates/ra_hir_ty/src/utils.rs
@@ -201,11 +201,11 @@ impl Generics {
201 (parent, self_params, list_params, impl_trait_params) 201 (parent, self_params, list_params, impl_trait_params)
202 } 202 }
203 203
204 pub(crate) fn param_idx(&self, param: TypeParamId) -> Option<u32> { 204 pub(crate) fn param_idx(&self, param: TypeParamId) -> Option<usize> {
205 Some(self.find_param(param)?.0) 205 Some(self.find_param(param)?.0)
206 } 206 }
207 207
208 fn find_param(&self, param: TypeParamId) -> Option<(u32, &TypeParamData)> { 208 fn find_param(&self, param: TypeParamId) -> Option<(usize, &TypeParamData)> {
209 if param.parent == self.def { 209 if param.parent == self.def {
210 let (idx, (_local_id, data)) = self 210 let (idx, (_local_id, data)) = self
211 .params 211 .params
@@ -215,7 +215,7 @@ impl Generics {
215 .find(|(_, (idx, _))| *idx == param.local_id) 215 .find(|(_, (idx, _))| *idx == param.local_id)
216 .unwrap(); 216 .unwrap();
217 let (_total, parent_len, _child) = self.len_split(); 217 let (_total, parent_len, _child) = self.len_split();
218 Some(((parent_len + idx) as u32, data)) 218 Some((parent_len + idx, data))
219 } else { 219 } else {
220 self.parent_generics.as_ref().and_then(|g| g.find_param(param)) 220 self.parent_generics.as_ref().and_then(|g| g.find_param(param))
221 } 221 }