aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/lib.rs31
-rw-r--r--crates/hir_ty/src/autoderef.rs9
-rw-r--r--crates/hir_ty/src/chalk_cast.rs22
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs4
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs5
-rw-r--r--crates/hir_ty/src/display.rs61
-rw-r--r--crates/hir_ty/src/infer/coerce.rs2
-rw-r--r--crates/hir_ty/src/infer/expr.rs24
-rw-r--r--crates/hir_ty/src/infer/pat.rs17
-rw-r--r--crates/hir_ty/src/infer/path.rs6
-rw-r--r--crates/hir_ty/src/infer/unify.rs55
-rw-r--r--crates/hir_ty/src/lib.rs173
-rw-r--r--crates/hir_ty/src/lower.rs17
-rw-r--r--crates/hir_ty/src/method_resolution.rs7
-rw-r--r--crates/hir_ty/src/traits.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk.rs10
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs39
17 files changed, 323 insertions, 161 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 06fd6542d..fcc577384 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1829,9 +1829,11 @@ impl Type {
1829 ); 1829 );
1830 1830
1831 match db.trait_solve(self.krate, goal)? { 1831 match db.trait_solve(self.krate, goal)? {
1832 Solution::Unique(SolutionVariables(subst)) => { 1832 Solution::Unique(SolutionVariables(subst)) => subst
1833 subst.value.first().map(|ty| self.derived(ty.clone())) 1833 .value
1834 } 1834 .interned(&Interner)
1835 .first()
1836 .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())),
1835 Solution::Ambig(_) => None, 1837 Solution::Ambig(_) => None,
1836 } 1838 }
1837 } 1839 }
@@ -1889,7 +1891,9 @@ impl Type {
1889 | TyKind::Tuple(_, substs) 1891 | TyKind::Tuple(_, substs)
1890 | TyKind::OpaqueType(_, substs) 1892 | TyKind::OpaqueType(_, substs)
1891 | TyKind::FnDef(_, substs) 1893 | TyKind::FnDef(_, substs)
1892 | TyKind::Closure(_, substs) => substs.iter().any(go), 1894 | TyKind::Closure(_, substs) => {
1895 substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go)
1896 }
1893 1897
1894 TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { 1898 TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => {
1895 go(ty) 1899 go(ty)
@@ -1928,7 +1932,10 @@ impl Type {
1928 1932
1929 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1933 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1930 if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) { 1934 if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) {
1931 substs.iter().map(|ty| self.derived(ty.clone())).collect() 1935 substs
1936 .iter(&Interner)
1937 .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone()))
1938 .collect()
1932 } else { 1939 } else {
1933 Vec::new() 1940 Vec::new()
1934 } 1941 }
@@ -1973,8 +1980,9 @@ impl Type {
1973 .strip_references() 1980 .strip_references()
1974 .substs() 1981 .substs()
1975 .into_iter() 1982 .into_iter()
1976 .flat_map(|substs| substs.iter()) 1983 .flat_map(|substs| substs.iter(&Interner))
1977 .map(move |ty| self.derived(ty.clone())) 1984 .filter_map(|arg| arg.ty(&Interner).cloned())
1985 .map(move |ty| self.derived(ty))
1978 } 1986 }
1979 1987
1980 pub fn iterate_method_candidates<T>( 1988 pub fn iterate_method_candidates<T>(
@@ -2080,7 +2088,7 @@ impl Type {
2080 substs: &Substitution, 2088 substs: &Substitution,
2081 cb: &mut impl FnMut(Type), 2089 cb: &mut impl FnMut(Type),
2082 ) { 2090 ) {
2083 for ty in substs.iter() { 2091 for ty in substs.iter(&Interner).filter_map(|a| a.ty(&Interner)) {
2084 walk_type(db, &type_.derived(ty.clone()), cb); 2092 walk_type(db, &type_.derived(ty.clone()), cb);
2085 } 2093 }
2086 } 2094 }
@@ -2096,7 +2104,12 @@ impl Type {
2096 WhereClause::Implemented(trait_ref) => { 2104 WhereClause::Implemented(trait_ref) => {
2097 cb(type_.clone()); 2105 cb(type_.clone());
2098 // skip the self type. it's likely the type we just got the bounds from 2106 // skip the self type. it's likely the type we just got the bounds from
2099 for ty in trait_ref.substitution.iter().skip(1) { 2107 for ty in trait_ref
2108 .substitution
2109 .iter(&Interner)
2110 .skip(1)
2111 .filter_map(|a| a.ty(&Interner))
2112 {
2100 walk_type(db, &type_.derived(ty.clone()), cb); 2113 walk_type(db, &type_.derived(ty.clone()), cb);
2101 } 2114 }
2102 } 2115 }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index dc5fc759a..5e3c018a8 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -131,7 +131,7 @@ fn deref_by_trait(
131 // new variables in that case 131 // new variables in that case
132 132
133 for i in 1..vars.0.binders.len(&Interner) { 133 for i in 1..vars.0.binders.len(&Interner) {
134 if vars.0.value[i - 1].interned(&Interner) 134 if vars.0.value.at(&Interner, i - 1).assert_ty_ref(&Interner).interned(&Interner)
135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
136 { 136 {
137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); 137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
@@ -139,7 +139,12 @@ fn deref_by_trait(
139 } 139 }
140 } 140 }
141 Some(Canonical { 141 Some(Canonical {
142 value: vars.0.value[vars.0.value.len() - 1].clone(), 142 value: vars
143 .0
144 .value
145 .at(&Interner, vars.0.value.len(&Interner) - 1)
146 .assert_ty_ref(&Interner)
147 .clone(),
143 binders: vars.0.binders.clone(), 148 binders: vars.0.binders.clone(),
144 }) 149 })
145 } 150 }
diff --git a/crates/hir_ty/src/chalk_cast.rs b/crates/hir_ty/src/chalk_cast.rs
index bf884ae15..df6492113 100644
--- a/crates/hir_ty/src/chalk_cast.rs
+++ b/crates/hir_ty/src/chalk_cast.rs
@@ -5,7 +5,7 @@ use chalk_ir::{
5 interner::HasInterner, 5 interner::HasInterner,
6}; 6};
7 7
8use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause}; 8use crate::{AliasEq, DomainGoal, GenericArg, GenericArgData, Interner, TraitRef, Ty, WhereClause};
9 9
10macro_rules! has_interner { 10macro_rules! has_interner {
11 ($t:ty) => { 11 ($t:ty) => {
@@ -17,6 +17,8 @@ macro_rules! has_interner {
17 17
18has_interner!(WhereClause); 18has_interner!(WhereClause);
19has_interner!(DomainGoal); 19has_interner!(DomainGoal);
20has_interner!(GenericArg);
21has_interner!(Ty);
20 22
21impl CastTo<WhereClause> for TraitRef { 23impl CastTo<WhereClause> for TraitRef {
22 fn cast_to(self, _interner: &Interner) -> WhereClause { 24 fn cast_to(self, _interner: &Interner) -> WhereClause {
@@ -36,6 +38,12 @@ impl CastTo<DomainGoal> for WhereClause {
36 } 38 }
37} 39}
38 40
41impl CastTo<GenericArg> for Ty {
42 fn cast_to(self, interner: &Interner) -> GenericArg {
43 GenericArg::new(interner, GenericArgData::Ty(self))
44 }
45}
46
39macro_rules! transitive_impl { 47macro_rules! transitive_impl {
40 ($a:ty, $b:ty, $c:ty) => { 48 ($a:ty, $b:ty, $c:ty) => {
41 impl CastTo<$c> for $a { 49 impl CastTo<$c> for $a {
@@ -51,3 +59,15 @@ macro_rules! transitive_impl {
51 59
52transitive_impl!(TraitRef, WhereClause, DomainGoal); 60transitive_impl!(TraitRef, WhereClause, DomainGoal);
53transitive_impl!(AliasEq, WhereClause, DomainGoal); 61transitive_impl!(AliasEq, WhereClause, DomainGoal);
62
63macro_rules! reflexive_impl {
64 ($a:ty) => {
65 impl CastTo<$a> for $a {
66 fn cast_to(self, _interner: &Interner) -> $a {
67 self
68 }
69 }
70 };
71}
72
73reflexive_impl!(GenericArg);
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index 3909ad354..373d1cb74 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -392,7 +392,9 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
392 _ => return, 392 _ => return,
393 }; 393 };
394 394
395 if params.len() > 0 && params[0] == mismatch.actual { 395 if params.len(&Interner) > 0
396 && params.at(&Interner, 0).ty(&Interner) == Some(&mismatch.actual)
397 {
396 let (_, source_map) = db.body_with_source_map(self.owner); 398 let (_, source_map) = db.body_with_source_map(self.owner);
397 399
398 if let Ok(source_ptr) = source_map.expr_syntax(id) { 400 if let Ok(source_ptr) = source_map.expr_syntax(id) {
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 9cb472b51..85ba58c44 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -792,7 +792,10 @@ fn pat_constructor(cx: &MatchCheckCtx, pat: PatIdOrWild) -> MatchCheckResult<Opt
792 Pat::Tuple { .. } => { 792 Pat::Tuple { .. } => {
793 let pat_id = pat.as_id().expect("we already know this pattern is not a wild"); 793 let pat_id = pat.as_id().expect("we already know this pattern is not a wild");
794 Some(Constructor::Tuple { 794 Some(Constructor::Tuple {
795 arity: cx.infer.type_of_pat[pat_id].as_tuple().ok_or(MatchCheckErr::Unknown)?.len(), 795 arity: cx.infer.type_of_pat[pat_id]
796 .as_tuple()
797 .ok_or(MatchCheckErr::Unknown)?
798 .len(&Interner),
796 }) 799 })
797 } 800 }
798 Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] { 801 Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] {
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 51480304b..59fd18c2a 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -8,7 +8,7 @@ use hir_def::{
8 find_path, 8 find_path,
9 generics::TypeParamProvenance, 9 generics::TypeParamProvenance,
10 item_scope::ItemInNs, 10 item_scope::ItemInNs,
11 path::{GenericArg, Path, PathKind}, 11 path::{Path, PathKind},
12 type_ref::{TypeBound, TypeRef}, 12 type_ref::{TypeBound, TypeRef},
13 visibility::Visibility, 13 visibility::Visibility,
14 AssocContainerId, Lookup, ModuleId, TraitId, 14 AssocContainerId, Lookup, ModuleId, TraitId,
@@ -18,7 +18,7 @@ use hir_expand::name::Name;
18use crate::{ 18use crate::{
19 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, 19 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
20 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, 20 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
21 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, 21 CallableDefId, CallableSig, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, OpaqueTy,
22 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, 22 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
23}; 23};
24 24
@@ -251,16 +251,16 @@ impl HirDisplay for ProjectionTy {
251 } 251 }
252 252
253 let trait_ = f.db.trait_data(self.trait_(f.db)); 253 let trait_ = f.db.trait_data(self.trait_(f.db));
254 let first_parameter = self.substitution[0].into_displayable( 254 let first_parameter = self.self_type_parameter().into_displayable(
255 f.db, 255 f.db,
256 f.max_size, 256 f.max_size,
257 f.omit_verbose_types, 257 f.omit_verbose_types,
258 f.display_target, 258 f.display_target,
259 ); 259 );
260 write!(f, "<{} as {}", first_parameter, trait_.name)?; 260 write!(f, "<{} as {}", first_parameter, trait_.name)?;
261 if self.substitution.len() > 1 { 261 if self.substitution.len(&Interner) > 1 {
262 write!(f, "<")?; 262 write!(f, "<")?;
263 f.write_joined(&self.substitution[1..], ", ")?; 263 f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?;
264 write!(f, ">")?; 264 write!(f, ">")?;
265 } 265 }
266 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; 266 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
@@ -274,7 +274,15 @@ impl HirDisplay for OpaqueTy {
274 return write!(f, "{}", TYPE_HINT_TRUNCATION); 274 return write!(f, "{}", TYPE_HINT_TRUNCATION);
275 } 275 }
276 276
277 self.substitution[0].hir_fmt(f) 277 self.substitution.at(&Interner, 0).hir_fmt(f)
278 }
279}
280
281impl HirDisplay for GenericArg {
282 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
283 match self.interned() {
284 crate::GenericArgData::Ty(ty) => ty.hir_fmt(f),
285 }
278 } 286 }
279} 287}
280 288
@@ -373,9 +381,9 @@ impl HirDisplay for Ty {
373 } 381 }
374 } 382 }
375 TyKind::Tuple(_, substs) => { 383 TyKind::Tuple(_, substs) => {
376 if substs.len() == 1 { 384 if substs.len(&Interner) == 1 {
377 write!(f, "(")?; 385 write!(f, "(")?;
378 substs[0].hir_fmt(f)?; 386 substs.at(&Interner, 0).hir_fmt(f)?;
379 write!(f, ",)")?; 387 write!(f, ",)")?;
380 } else { 388 } else {
381 write!(f, "(")?; 389 write!(f, "(")?;
@@ -399,7 +407,7 @@ impl HirDisplay for Ty {
399 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 407 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
400 } 408 }
401 }; 409 };
402 if parameters.len() > 0 { 410 if parameters.len(&Interner) > 0 {
403 let generics = generics(f.db.upcast(), def.into()); 411 let generics = generics(f.db.upcast(), def.into());
404 let (parent_params, self_param, type_params, _impl_trait_params) = 412 let (parent_params, self_param, type_params, _impl_trait_params) =
405 generics.provenance_split(); 413 generics.provenance_split();
@@ -451,7 +459,7 @@ impl HirDisplay for Ty {
451 } 459 }
452 } 460 }
453 461
454 if parameters.len() > 0 { 462 if parameters.len(&Interner) > 0 {
455 let parameters_to_write = if f.display_target.is_source_code() 463 let parameters_to_write = if f.display_target.is_source_code()
456 || f.omit_verbose_types() 464 || f.omit_verbose_types()
457 { 465 {
@@ -463,9 +471,11 @@ impl HirDisplay for Ty {
463 None => parameters.0.as_ref(), 471 None => parameters.0.as_ref(),
464 Some(default_parameters) => { 472 Some(default_parameters) => {
465 let mut default_from = 0; 473 let mut default_from = 0;
466 for (i, parameter) in parameters.iter().enumerate() { 474 for (i, parameter) in parameters.iter(&Interner).enumerate() {
467 match (parameter.interned(&Interner), default_parameters.get(i)) 475 match (
468 { 476 parameter.assert_ty_ref(&Interner).interned(&Interner),
477 default_parameters.get(i),
478 ) {
469 (&TyKind::Unknown, _) | (_, None) => { 479 (&TyKind::Unknown, _) | (_, None) => {
470 default_from = i + 1; 480 default_from = i + 1;
471 } 481 }
@@ -473,7 +483,8 @@ impl HirDisplay for Ty {
473 let actual_default = default_parameter 483 let actual_default = default_parameter
474 .clone() 484 .clone()
475 .subst(&parameters.prefix(i)); 485 .subst(&parameters.prefix(i));
476 if parameter != &actual_default { 486 if parameter.assert_ty_ref(&Interner) != &actual_default
487 {
477 default_from = i + 1; 488 default_from = i + 1;
478 } 489 }
479 } 490 }
@@ -504,7 +515,7 @@ impl HirDisplay for Ty {
504 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 515 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
505 if f.display_target.is_test() { 516 if f.display_target.is_test() {
506 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 517 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
507 if parameters.len() > 0 { 518 if parameters.len(&Interner) > 0 {
508 write!(f, "<")?; 519 write!(f, "<")?;
509 f.write_joined(&*parameters.0, ", ")?; 520 f.write_joined(&*parameters.0, ", ")?;
510 write!(f, ">")?; 521 write!(f, ">")?;
@@ -537,7 +548,7 @@ impl HirDisplay for Ty {
537 } 548 }
538 ImplTraitId::AsyncBlockTypeImplTrait(..) => { 549 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
539 write!(f, "impl Future<Output = ")?; 550 write!(f, "impl Future<Output = ")?;
540 parameters[0].hir_fmt(f)?; 551 parameters.at(&Interner, 0).hir_fmt(f)?;
541 write!(f, ">")?; 552 write!(f, ">")?;
542 } 553 }
543 } 554 }
@@ -548,7 +559,7 @@ impl HirDisplay for Ty {
548 DisplaySourceCodeError::Closure, 559 DisplaySourceCodeError::Closure,
549 )); 560 ));
550 } 561 }
551 let sig = substs[0].callable_sig(f.db); 562 let sig = substs.at(&Interner, 0).assert_ty_ref(&Interner).callable_sig(f.db);
552 if let Some(sig) = sig { 563 if let Some(sig) = sig {
553 if sig.params().is_empty() { 564 if sig.params().is_empty() {
554 write!(f, "||")?; 565 write!(f, "||")?;
@@ -718,7 +729,9 @@ fn write_bounds_like_dyn_trait(
718 write!(f, "{}", f.db.trait_data(trait_).name)?; 729 write!(f, "{}", f.db.trait_data(trait_).name)?;
719 if let [_, params @ ..] = &*trait_ref.substitution.0 { 730 if let [_, params @ ..] = &*trait_ref.substitution.0 {
720 if is_fn_trait { 731 if is_fn_trait {
721 if let Some(args) = params.first().and_then(|it| it.as_tuple()) { 732 if let Some(args) =
733 params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple())
734 {
722 write!(f, "(")?; 735 write!(f, "(")?;
723 f.write_joined(&*args.0, ", ")?; 736 f.write_joined(&*args.0, ", ")?;
724 write!(f, ")")?; 737 write!(f, ")")?;
@@ -767,16 +780,16 @@ impl TraitRef {
767 return write!(f, "{}", TYPE_HINT_TRUNCATION); 780 return write!(f, "{}", TYPE_HINT_TRUNCATION);
768 } 781 }
769 782
770 self.substitution[0].hir_fmt(f)?; 783 self.self_type_parameter().hir_fmt(f)?;
771 if use_as { 784 if use_as {
772 write!(f, " as ")?; 785 write!(f, " as ")?;
773 } else { 786 } else {
774 write!(f, ": ")?; 787 write!(f, ": ")?;
775 } 788 }
776 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?; 789 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?;
777 if self.substitution.len() > 1 { 790 if self.substitution.len(&Interner) > 1 {
778 write!(f, "<")?; 791 write!(f, "<")?;
779 f.write_joined(&self.substitution[1..], ", ")?; 792 f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?;
780 write!(f, ">")?; 793 write!(f, ">")?;
781 } 794 }
782 Ok(()) 795 Ok(())
@@ -1016,11 +1029,11 @@ impl HirDisplay for Path {
1016 } 1029 }
1017} 1030}
1018 1031
1019impl HirDisplay for GenericArg { 1032impl HirDisplay for hir_def::path::GenericArg {
1020 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 1033 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1021 match self { 1034 match self {
1022 GenericArg::Type(ty) => ty.hir_fmt(f), 1035 hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f),
1023 GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), 1036 hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1024 } 1037 }
1025 } 1038 }
1026} 1039}
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 9c62932b1..8f7322b36 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -100,7 +100,7 @@ impl<'a> InferenceContext<'a> {
100 }, 100 },
101 101
102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => { 102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => {
103 from_ty = substs[0].clone(); 103 from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
104 } 104 }
105 105
106 _ => {} 106 _ => {}
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 25ab3ea4c..b99b6cd21 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -266,7 +266,7 @@ impl<'a> InferenceContext<'a> {
266 let sig_ty = TyKind::Function(FnPointer { 266 let sig_ty = TyKind::Function(FnPointer {
267 num_args: sig_tys.len() - 1, 267 num_args: sig_tys.len() - 1,
268 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 268 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
269 substs: Substitution(sig_tys.clone().into()), 269 substs: Substitution::from_iter(&Interner, sig_tys.clone()),
270 }) 270 })
271 .intern(&Interner); 271 .intern(&Interner);
272 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 272 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
@@ -406,7 +406,7 @@ impl<'a> InferenceContext<'a> {
406 406
407 self.unify(&ty, &expected.ty); 407 self.unify(&ty, &expected.ty);
408 408
409 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 409 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
410 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 410 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
411 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 411 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
412 for field in fields.iter() { 412 for field in fields.iter() {
@@ -456,9 +456,13 @@ impl<'a> InferenceContext<'a> {
456 .unwrap_or(true) 456 .unwrap_or(true)
457 }; 457 };
458 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { 458 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) {
459 TyKind::Tuple(_, substs) => { 459 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
460 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 460 substs
461 } 461 .interned(&Interner)
462 .get(idx)
463 .map(|a| a.assert_ty_ref(&Interner))
464 .cloned()
465 }),
462 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 466 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
463 let local_id = self.db.struct_data(*s).variant_data.field(name)?; 467 let local_id = self.db.struct_data(*s).variant_data.field(name)?;
464 let field = FieldId { parent: (*s).into(), local_id }; 468 let field = FieldId { parent: (*s).into(), local_id };
@@ -635,7 +639,7 @@ impl<'a> InferenceContext<'a> {
635 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 639 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
636 match (range_type, lhs_ty, rhs_ty) { 640 match (range_type, lhs_ty, rhs_ty) {
637 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 641 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
638 Some(adt) => Ty::adt_ty(adt, Substitution::empty()), 642 Some(adt) => Ty::adt_ty(adt, Substitution::empty(&Interner)),
639 None => self.err_ty(), 643 None => self.err_ty(),
640 }, 644 },
641 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 645 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
@@ -694,8 +698,8 @@ impl<'a> InferenceContext<'a> {
694 Expr::Tuple { exprs } => { 698 Expr::Tuple { exprs } => {
695 let mut tys = match expected.ty.interned(&Interner) { 699 let mut tys = match expected.ty.interned(&Interner) {
696 TyKind::Tuple(_, substs) => substs 700 TyKind::Tuple(_, substs) => substs
697 .iter() 701 .iter(&Interner)
698 .cloned() 702 .map(|a| a.assert_ty_ref(&Interner).clone())
699 .chain(repeat_with(|| self.table.new_type_var())) 703 .chain(repeat_with(|| self.table.new_type_var()))
700 .take(exprs.len()) 704 .take(exprs.len())
701 .collect::<Vec<_>>(), 705 .collect::<Vec<_>>(),
@@ -706,7 +710,7 @@ impl<'a> InferenceContext<'a> {
706 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 710 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
707 } 711 }
708 712
709 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) 713 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
710 } 714 }
711 Expr::Array(array) => { 715 Expr::Array(array) => {
712 let elem_ty = match expected.ty.interned(&Interner) { 716 let elem_ty = match expected.ty.interned(&Interner) {
@@ -953,7 +957,7 @@ impl<'a> InferenceContext<'a> {
953 substs.push(self.err_ty()); 957 substs.push(self.err_ty());
954 } 958 }
955 assert_eq!(substs.len(), total_len); 959 assert_eq!(substs.len(), total_len);
956 Substitution(substs.into()) 960 Substitution::from_iter(&Interner, substs)
957 } 961 }
958 962
959 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 963 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 474363709..f1316415f 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -35,7 +35,7 @@ impl<'a> InferenceContext<'a> {
35 } 35 }
36 self.unify(&ty, expected); 36 self.unify(&ty, expected);
37 37
38 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 38 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
39 39
40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
41 let (pre, post) = match ellipsis { 41 let (pre, post) = match ellipsis {
@@ -74,7 +74,7 @@ impl<'a> InferenceContext<'a> {
74 74
75 self.unify(&ty, expected); 75 self.unify(&ty, expected);
76 76
77 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 77 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
78 78
79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
80 for subpat in subpats { 80 for subpat in subpats {
@@ -134,7 +134,8 @@ impl<'a> InferenceContext<'a> {
134 }; 134 };
135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
136 let err_ty = self.err_ty(); 136 let err_ty = self.err_ty();
137 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); 137 let mut expectations_iter =
138 expectations.iter().map(|a| a.assert_ty_ref(&Interner)).chain(repeat(&err_ty));
138 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); 139 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
139 140
140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 141 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -142,7 +143,8 @@ impl<'a> InferenceContext<'a> {
142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 143 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 144 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
144 145
145 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) 146 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
147 .intern(&Interner)
146 } 148 }
147 Pat::Or(ref pats) => { 149 Pat::Or(ref pats) => {
148 if let Some((first_pat, rest)) = pats.split_first() { 150 if let Some((first_pat, rest)) = pats.split_first() {
@@ -236,9 +238,10 @@ impl<'a> InferenceContext<'a> {
236 Pat::Box { inner } => match self.resolve_boxed_box() { 238 Pat::Box { inner } => match self.resolve_boxed_box() {
237 Some(box_adt) => { 239 Some(box_adt) => {
238 let (inner_ty, alloc_ty) = match expected.as_adt() { 240 let (inner_ty, alloc_ty) = match expected.as_adt() {
239 Some((adt, subst)) if adt == box_adt => { 241 Some((adt, subst)) if adt == box_adt => (
240 (subst[0].clone(), subst.get(1).cloned()) 242 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
241 } 243 subst.interned(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()),
244 ),
242 _ => (self.result.standard_types.unknown.clone(), None), 245 _ => (self.result.standard_types.unknown.clone(), None),
243 }; 246 };
244 247
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index 717738789..b96391776 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -97,12 +97,12 @@ impl<'a> InferenceContext<'a> {
97 97
98 let ty = self.db.value_ty(typable); 98 let ty = self.db.value_ty(typable);
99 // self_subst is just for the parent 99 // self_subst is just for the parent
100 let parent_substs = self_subst.unwrap_or_else(Substitution::empty); 100 let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner));
101 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 101 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
102 let substs = ctx.substs_from_path(path, typable, true); 102 let substs = ctx.substs_from_path(path, typable, true);
103 let full_substs = Substitution::builder(substs.len()) 103 let full_substs = Substitution::builder(substs.len(&Interner))
104 .use_parent_substs(&parent_substs) 104 .use_parent_substs(&parent_substs)
105 .fill(substs.0[parent_substs.len()..].iter().cloned()) 105 .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
106 .build(); 106 .build();
107 let ty = ty.subst(&full_substs); 107 let ty = ty.subst(&full_substs);
108 Some(ty) 108 Some(ty)
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 5ea4b7481..0efc62e53 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -129,29 +129,28 @@ impl<T> Canonicalized<T> {
129 solution: Canonical<Substitution>, 129 solution: Canonical<Substitution>,
130 ) { 130 ) {
131 // the solution may contain new variables, which we need to convert to new inference vars 131 // the solution may contain new variables, which we need to convert to new inference vars
132 let new_vars = Substitution( 132 let new_vars = Substitution::from_iter(
133 solution 133 &Interner,
134 .binders 134 solution.binders.iter(&Interner).map(|k| match k.kind {
135 .iter(&Interner) 135 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
136 .map(|k| match k.kind { 136 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 137 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 138 // HACK: Chalk can sometimes return new lifetime variables. We
139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 139 // want to just skip them, but to not mess up the indices of
140 // HACK: Chalk can sometimes return new lifetime variables. We 140 // other variables, we'll just create a new type variable in
141 // want to just skip them, but to not mess up the indices of 141 // their place instead. This should not matter (we never see the
142 // other variables, we'll just create a new type variable in 142 // actual *uses* of the lifetime variable).
143 // their place instead. This should not matter (we never see the 143 VariableKind::Lifetime => ctx.table.new_type_var(),
144 // actual *uses* of the lifetime variable). 144 _ => panic!("const variable in solution"),
145 VariableKind::Lifetime => ctx.table.new_type_var(), 145 }),
146 _ => panic!("const variable in solution"),
147 })
148 .collect(),
149 ); 146 );
150 for (i, ty) in solution.value.into_iter().enumerate() { 147 for (i, ty) in solution.value.iter(&Interner).enumerate() {
151 let (v, k) = self.free_vars[i]; 148 let (v, k) = self.free_vars[i];
152 // eagerly replace projections in the type; we may be getting types 149 // eagerly replace projections in the type; we may be getting types
153 // e.g. from where clauses where this hasn't happened yet 150 // e.g. from where clauses where this hasn't happened yet
154 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 151 let ty = ctx.normalize_associated_types_in(
152 ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars),
153 );
155 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 154 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
156 } 155 }
157 } 156 }
@@ -163,13 +162,13 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
163 162
164pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 163pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
165 let mut table = InferenceTable::new(); 164 let mut table = InferenceTable::new();
166 let vars = Substitution( 165 let vars = Substitution::from_iter(
166 &Interner,
167 tys.binders 167 tys.binders
168 .iter(&Interner) 168 .iter(&Interner)
169 // we always use type vars here because we want everything to 169 // we always use type vars here because we want everything to
170 // fallback to Unknown in the end (kind of hacky, as below) 170 // fallback to Unknown in the end (kind of hacky, as below)
171 .map(|_| table.new_type_var()) 171 .map(|_| table.new_type_var()),
172 .collect(),
173 ); 172 );
174 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 173 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars);
175 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 174 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars);
@@ -178,7 +177,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
178 } 177 }
179 // default any type vars that weren't unified back to their original bound vars 178 // default any type vars that weren't unified back to their original bound vars
180 // (kind of hacky) 179 // (kind of hacky)
181 for (i, var) in vars.iter().enumerate() { 180 for (i, var) in vars.iter(&Interner).enumerate() {
181 let var = var.assert_ty_ref(&Interner);
182 if &*table.resolve_ty_shallow(var) == var { 182 if &*table.resolve_ty_shallow(var) == var {
183 table.unify( 183 table.unify(
184 var, 184 var,
@@ -188,7 +188,10 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
188 } 188 }
189 Some( 189 Some(
190 Substitution::builder(tys.binders.len(&Interner)) 190 Substitution::builder(tys.binders.len(&Interner))
191 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 191 .fill(
192 vars.iter(&Interner)
193 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
194 )
192 .build(), 195 .build(),
193 ) 196 )
194} 197}
@@ -284,7 +287,9 @@ impl InferenceTable {
284 substs2: &Substitution, 287 substs2: &Substitution,
285 depth: usize, 288 depth: usize,
286 ) -> bool { 289 ) -> bool {
287 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 290 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| {
291 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
292 })
288 } 293 }
289 294
290 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 295 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 6f9c698e6..c927ed973 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -24,9 +24,10 @@ mod tests;
24#[cfg(test)] 24#[cfg(test)]
25mod test_db; 25mod test_db;
26 26
27use std::{iter, mem, ops::Deref, sync::Arc}; 27use std::{iter, mem, sync::Arc};
28 28
29use base_db::salsa; 29use base_db::salsa;
30use chalk_ir::cast::{CastTo, Caster};
30use hir_def::{ 31use hir_def::{
31 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, 32 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId,
32 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, 33 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
@@ -109,7 +110,7 @@ impl ProjectionTy {
109 } 110 }
110 111
111 pub fn self_type_parameter(&self) -> &Ty { 112 pub fn self_type_parameter(&self) -> &Ty {
112 &self.substitution[0] 113 &self.substitution.interned(&Interner)[0].assert_ty_ref(&Interner)
113 } 114 }
114 115
115 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 116 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
@@ -324,9 +325,72 @@ impl Ty {
324 } 325 }
325} 326}
326 327
328#[derive(Clone, PartialEq, Eq, Debug, Hash)]
329pub struct GenericArg {
330 interned: GenericArgData,
331}
332
333#[derive(Clone, PartialEq, Eq, Debug, Hash)]
334pub enum GenericArgData {
335 Ty(Ty),
336}
337
338impl GenericArg {
339 /// Constructs a generic argument using `GenericArgData`.
340 pub fn new(_interner: &Interner, data: GenericArgData) -> Self {
341 GenericArg { interned: data }
342 }
343
344 /// Gets the interned value.
345 pub fn interned(&self) -> &GenericArgData {
346 &self.interned
347 }
348
349 /// Asserts that this is a type argument.
350 pub fn assert_ty_ref(&self, interner: &Interner) -> &Ty {
351 self.ty(interner).unwrap()
352 }
353
354 /// Checks whether the generic argument is a type.
355 pub fn is_ty(&self, _interner: &Interner) -> bool {
356 match self.interned() {
357 GenericArgData::Ty(_) => true,
358 }
359 }
360
361 /// Returns the type if it is one, `None` otherwise.
362 pub fn ty(&self, _interner: &Interner) -> Option<&Ty> {
363 match self.interned() {
364 GenericArgData::Ty(t) => Some(t),
365 }
366 }
367}
368
369impl TypeWalk for GenericArg {
370 fn walk(&self, f: &mut impl FnMut(&Ty)) {
371 match &self.interned {
372 GenericArgData::Ty(ty) => {
373 ty.walk(f);
374 }
375 }
376 }
377
378 fn walk_mut_binders(
379 &mut self,
380 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
381 binders: DebruijnIndex,
382 ) {
383 match &mut self.interned {
384 GenericArgData::Ty(ty) => {
385 ty.walk_mut_binders(f, binders);
386 }
387 }
388 }
389}
390
327/// A list of substitutions for generic parameters. 391/// A list of substitutions for generic parameters.
328#[derive(Clone, PartialEq, Eq, Debug, Hash)] 392#[derive(Clone, PartialEq, Eq, Debug, Hash)]
329pub struct Substitution(SmallVec<[Ty; 2]>); 393pub struct Substitution(SmallVec<[GenericArg; 2]>);
330 394
331impl TypeWalk for Substitution { 395impl TypeWalk for Substitution {
332 fn walk(&self, f: &mut impl FnMut(&Ty)) { 396 fn walk(&self, f: &mut impl FnMut(&Ty)) {
@@ -347,18 +411,34 @@ impl TypeWalk for Substitution {
347} 411}
348 412
349impl Substitution { 413impl Substitution {
350 pub fn interned(&self, _: &Interner) -> &[Ty] { 414 pub fn interned(&self, _: &Interner) -> &[GenericArg] {
351 &self.0 415 &self.0
352 } 416 }
353 417
354 pub fn empty() -> Substitution { 418 pub fn len(&self, _: &Interner) -> usize {
419 self.0.len()
420 }
421
422 pub fn is_empty(&self, _: &Interner) -> bool {
423 self.0.is_empty()
424 }
425
426 pub fn at(&self, _: &Interner, i: usize) -> &GenericArg {
427 &self.0[i]
428 }
429
430 pub fn empty(_: &Interner) -> Substitution {
355 Substitution(SmallVec::new()) 431 Substitution(SmallVec::new())
356 } 432 }
357 433
434 pub fn iter(&self, _: &Interner) -> std::slice::Iter<'_, GenericArg> {
435 self.0.iter()
436 }
437
358 pub fn single(ty: Ty) -> Substitution { 438 pub fn single(ty: Ty) -> Substitution {
359 Substitution({ 439 Substitution({
360 let mut v = SmallVec::new(); 440 let mut v = SmallVec::new();
361 v.push(ty); 441 v.push(ty.cast(&Interner));
362 v 442 v
363 }) 443 })
364 } 444 }
@@ -371,15 +451,11 @@ impl Substitution {
371 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into()) 451 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into())
372 } 452 }
373 453
374 pub fn as_single(&self) -> &Ty { 454 pub fn from_iter(
375 if self.0.len() != 1 { 455 interner: &Interner,
376 panic!("expected substs of len 1, got {:?}", self); 456 elements: impl IntoIterator<Item = impl CastTo<GenericArg>>,
377 } 457 ) -> Self {
378 &self.0[0] 458 Substitution(elements.into_iter().casted(interner).collect())
379 }
380
381 pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self {
382 Substitution(elements.into_iter().collect())
383 } 459 }
384 460
385 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 461 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
@@ -387,11 +463,11 @@ impl Substitution {
387 db: &dyn HirDatabase, 463 db: &dyn HirDatabase,
388 generic_params: &Generics, 464 generic_params: &Generics,
389 ) -> Substitution { 465 ) -> Substitution {
390 Substitution( 466 Substitution::from_iter(
467 &Interner,
391 generic_params 468 generic_params
392 .iter() 469 .iter()
393 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)) 470 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)),
394 .collect(),
395 ) 471 )
396 } 472 }
397 473
@@ -403,12 +479,12 @@ impl Substitution {
403 479
404 /// Return Substs that replace each parameter by a bound variable. 480 /// Return Substs that replace each parameter by a bound variable.
405 pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substitution { 481 pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substitution {
406 Substitution( 482 Substitution::from_iter(
483 &Interner,
407 generic_params 484 generic_params
408 .iter() 485 .iter()
409 .enumerate() 486 .enumerate()
410 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)) 487 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
411 .collect(),
412 ) 488 )
413 } 489 }
414 490
@@ -435,18 +511,18 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
435 511
436#[derive(Debug, Clone)] 512#[derive(Debug, Clone)]
437pub struct SubstsBuilder { 513pub struct SubstsBuilder {
438 vec: Vec<Ty>, 514 vec: Vec<GenericArg>,
439 param_count: usize, 515 param_count: usize,
440} 516}
441 517
442impl SubstsBuilder { 518impl SubstsBuilder {
443 pub fn build(self) -> Substitution { 519 pub fn build(self) -> Substitution {
444 assert_eq!(self.vec.len(), self.param_count); 520 assert_eq!(self.vec.len(), self.param_count);
445 Substitution(self.vec.into()) 521 Substitution::from_iter(&Interner, self.vec)
446 } 522 }
447 523
448 pub fn push(mut self, ty: Ty) -> Self { 524 pub fn push(mut self, ty: impl CastTo<GenericArg>) -> Self {
449 self.vec.push(ty); 525 self.vec.push(ty.cast(&Interner));
450 self 526 self
451 } 527 }
452 528
@@ -465,28 +541,20 @@ impl SubstsBuilder {
465 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner))) 541 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
466 } 542 }
467 543
468 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { 544 pub fn fill(mut self, filler: impl Iterator<Item = impl CastTo<GenericArg>>) -> Self {
469 self.vec.extend(filler.take(self.remaining())); 545 self.vec.extend(filler.take(self.remaining()).casted(&Interner));
470 assert_eq!(self.remaining(), 0); 546 assert_eq!(self.remaining(), 0);
471 self 547 self
472 } 548 }
473 549
474 pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self { 550 pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self {
475 assert!(self.vec.is_empty()); 551 assert!(self.vec.is_empty());
476 assert!(parent_substs.len() <= self.param_count); 552 assert!(parent_substs.len(&Interner) <= self.param_count);
477 self.vec.extend(parent_substs.iter().cloned()); 553 self.vec.extend(parent_substs.iter(&Interner).cloned());
478 self 554 self
479 } 555 }
480} 556}
481 557
482impl Deref for Substitution {
483 type Target = [Ty];
484
485 fn deref(&self) -> &[Ty] {
486 &self.0
487 }
488}
489
490#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 558#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
491pub struct Binders<T> { 559pub struct Binders<T> {
492 pub num_binders: usize, 560 pub num_binders: usize,
@@ -535,7 +603,7 @@ impl<T: Clone> Binders<&T> {
535impl<T: TypeWalk> Binders<T> { 603impl<T: TypeWalk> Binders<T> {
536 /// Substitutes all variables. 604 /// Substitutes all variables.
537 pub fn subst(self, subst: &Substitution) -> T { 605 pub fn subst(self, subst: &Substitution) -> T {
538 assert_eq!(subst.len(), self.num_binders); 606 assert_eq!(subst.len(&Interner), self.num_binders);
539 self.value.subst_bound_vars(subst) 607 self.value.subst_bound_vars(subst)
540 } 608 }
541} 609}
@@ -563,7 +631,7 @@ pub struct TraitRef {
563 631
564impl TraitRef { 632impl TraitRef {
565 pub fn self_type_parameter(&self) -> &Ty { 633 pub fn self_type_parameter(&self) -> &Ty {
566 &self.substitution[0] 634 &self.substitution.at(&Interner, 0).assert_ty_ref(&Interner)
567 } 635 }
568 636
569 pub fn hir_trait_id(&self) -> TraitId { 637 pub fn hir_trait_id(&self) -> TraitId {
@@ -699,14 +767,20 @@ impl CallableSig {
699 .shift_bound_vars_out(DebruijnIndex::ONE) 767 .shift_bound_vars_out(DebruijnIndex::ONE)
700 .interned(&Interner) 768 .interned(&Interner)
701 .iter() 769 .iter()
702 .cloned() 770 .map(|arg| arg.assert_ty_ref(&Interner).clone())
703 .collect(), 771 .collect(),
704 is_varargs: fn_ptr.sig.variadic, 772 is_varargs: fn_ptr.sig.variadic,
705 } 773 }
706 } 774 }
707 775
708 pub fn from_substs(substs: &Substitution) -> CallableSig { 776 pub fn from_substs(substs: &Substitution) -> CallableSig {
709 CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false } 777 CallableSig {
778 params_and_return: substs
779 .iter(&Interner)
780 .map(|arg| arg.assert_ty_ref(&Interner).clone())
781 .collect(),
782 is_varargs: false,
783 }
710 } 784 }
711 785
712 pub fn params(&self) -> &[Ty] { 786 pub fn params(&self) -> &[Ty] {
@@ -738,7 +812,7 @@ impl TypeWalk for CallableSig {
738 812
739impl Ty { 813impl Ty {
740 pub fn unit() -> Self { 814 pub fn unit() -> Self {
741 TyKind::Tuple(0, Substitution::empty()).intern(&Interner) 815 TyKind::Tuple(0, Substitution::empty(&Interner)).intern(&Interner)
742 } 816 }
743 817
744 pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty { 818 pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty {
@@ -908,7 +982,7 @@ impl Ty {
908 Some(sig.subst(&parameters)) 982 Some(sig.subst(&parameters))
909 } 983 }
910 TyKind::Closure(.., substs) => { 984 TyKind::Closure(.., substs) => {
911 let sig_param = &substs[0]; 985 let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner);
912 sig_param.callable_sig(db) 986 sig_param.callable_sig(db)
913 } 987 }
914 _ => None, 988 _ => None,
@@ -960,7 +1034,7 @@ impl Ty {
960 0, 1034 0,
961 WhereClause::Implemented(TraitRef { 1035 WhereClause::Implemented(TraitRef {
962 trait_id: to_chalk_trait_id(future_trait), 1036 trait_id: to_chalk_trait_id(future_trait),
963 substitution: Substitution::empty(), 1037 substitution: Substitution::empty(&Interner),
964 }), 1038 }),
965 ); 1039 );
966 Some(vec![impl_bound]) 1040 Some(vec![impl_bound])
@@ -1109,7 +1183,10 @@ pub trait TypeWalk {
1109 &mut |ty, binders| { 1183 &mut |ty, binders| {
1110 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { 1184 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() {
1111 if bound.debruijn >= binders { 1185 if bound.debruijn >= binders {
1112 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 1186 *ty = substs.0[bound.index]
1187 .assert_ty_ref(&Interner)
1188 .clone()
1189 .shift_bound_vars(binders);
1113 } 1190 }
1114 } 1191 }
1115 }, 1192 },
@@ -1156,12 +1233,12 @@ impl TypeWalk for Ty {
1156 fn walk(&self, f: &mut impl FnMut(&Ty)) { 1233 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1157 match self.interned(&Interner) { 1234 match self.interned(&Interner) {
1158 TyKind::Alias(AliasTy::Projection(p_ty)) => { 1235 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1159 for t in p_ty.substitution.iter() { 1236 for t in p_ty.substitution.iter(&Interner) {
1160 t.walk(f); 1237 t.walk(f);
1161 } 1238 }
1162 } 1239 }
1163 TyKind::Alias(AliasTy::Opaque(o_ty)) => { 1240 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1164 for t in o_ty.substitution.iter() { 1241 for t in o_ty.substitution.iter(&Interner) {
1165 t.walk(f); 1242 t.walk(f);
1166 } 1243 }
1167 } 1244 }
@@ -1175,7 +1252,7 @@ impl TypeWalk for Ty {
1175 } 1252 }
1176 _ => { 1253 _ => {
1177 if let Some(substs) = self.substs() { 1254 if let Some(substs) = self.substs() {
1178 for t in substs.iter() { 1255 for t in substs.iter(&Interner) {
1179 t.walk(f); 1256 t.walk(f);
1180 } 1257 }
1181 } 1258 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 72ee060e0..f595683e5 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -178,9 +178,10 @@ impl<'a> TyLoweringContext<'a> {
178 } 178 }
179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner), 179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner),
180 TypeRef::Fn(params, is_varargs) => { 180 TypeRef::Fn(params, is_varargs) => {
181 let substs = Substitution(params.iter().map(|tr| self.lower_ty(tr)).collect()); 181 let substs =
182 Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr)));
182 TyKind::Function(FnPointer { 183 TyKind::Function(FnPointer {
183 num_args: substs.len() - 1, 184 num_args: substs.len(&Interner) - 1,
184 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, 185 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
185 substs, 186 substs,
186 }) 187 })
@@ -625,7 +626,7 @@ impl<'a> TyLoweringContext<'a> {
625 626
626 for default_ty in defaults.iter().skip(substs.len()) { 627 for default_ty in defaults.iter().skip(substs.len()) {
627 // each default can depend on the previous parameters 628 // each default can depend on the previous parameters
628 let substs_so_far = Substitution(substs.clone().into()); 629 let substs_so_far = Substitution::from_iter(&Interner, substs.clone());
629 substs.push(default_ty.clone().subst(&substs_so_far)); 630 substs.push(default_ty.clone().subst(&substs_so_far));
630 } 631 }
631 } 632 }
@@ -638,7 +639,7 @@ impl<'a> TyLoweringContext<'a> {
638 } 639 }
639 assert_eq!(substs.len(), total_len); 640 assert_eq!(substs.len(), total_len);
640 641
641 Substitution(substs.into()) 642 Substitution::from_iter(&Interner, substs)
642 } 643 }
643 644
644 fn lower_trait_ref_from_path( 645 fn lower_trait_ref_from_path(
@@ -1062,7 +1063,7 @@ fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1062 let generics = generics(db.upcast(), def.into()); 1063 let generics = generics(db.upcast(), def.into());
1063 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1064 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1064 Binders::new( 1065 Binders::new(
1065 substs.len(), 1066 substs.len(&Interner),
1066 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), 1067 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
1067 ) 1068 )
1068} 1069}
@@ -1107,7 +1108,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1107 let generics = generics(db.upcast(), def.into()); 1108 let generics = generics(db.upcast(), def.into());
1108 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1109 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1109 Binders::new( 1110 Binders::new(
1110 substs.len(), 1111 substs.len(&Interner),
1111 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), 1112 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
1112 ) 1113 )
1113} 1114}
@@ -1134,7 +1135,7 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1134 let generics = generics(db.upcast(), def.parent.into()); 1135 let generics = generics(db.upcast(), def.parent.into());
1135 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1136 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1136 Binders::new( 1137 Binders::new(
1137 substs.len(), 1138 substs.len(&Interner),
1138 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), 1139 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
1139 ) 1140 )
1140} 1141}
@@ -1142,7 +1143,7 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1142fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1143fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1143 let generics = generics(db.upcast(), adt.into()); 1144 let generics = generics(db.upcast(), adt.into());
1144 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1145 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1145 Binders::new(substs.len(), Ty::adt_ty(adt, substs)) 1146 Binders::new(substs.len(&Interner), Ty::adt_ty(adt, substs))
1146} 1147}
1147 1148
1148fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1149fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index bf7d5eded..054896475 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -720,7 +720,7 @@ pub(crate) fn inherent_impl_substs(
720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
721 UniverseIndex::ROOT, 721 UniverseIndex::ROOT,
722 )) 722 ))
723 .take(vars.len()), 723 .take(vars.len(&Interner)),
724 ); 724 );
725 let tys = Canonical { 725 let tys = Canonical {
726 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 726 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
@@ -732,7 +732,8 @@ pub(crate) fn inherent_impl_substs(
732 // Unknown. I think this can only really happen if self_ty contained 732 // Unknown. I think this can only really happen if self_ty contained
733 // Unknown, and in that case we want the result to contain Unknown in those 733 // Unknown, and in that case we want the result to contain Unknown in those
734 // places again. 734 // places again.
735 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner))) 735 substs
736 .map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner)))
736} 737}
737 738
738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 739/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -821,7 +822,7 @@ fn generic_implements_goal(
821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 822 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
822 UniverseIndex::ROOT, 823 UniverseIndex::ROOT,
823 )) 824 ))
824 .take(substs.len() - 1), 825 .take(substs.len(&Interner) - 1),
825 ); 826 );
826 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }; 827 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
827 let obligation = trait_ref.cast(&Interner); 828 let obligation = trait_ref.cast(&Interner);
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index ccee0e5ad..a15b6486e 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -138,7 +138,7 @@ pub(crate) fn trait_solve_query(
138 .. 138 ..
139 })) = &goal.value.goal 139 })) = &goal.value.goal
140 { 140 {
141 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { 141 if let TyKind::BoundVar(_) = projection_ty.self_type_parameter().interned(&Interner) {
142 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 142 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
143 return Some(Solution::Ambig(Guidance::Unknown)); 143 return Some(Solution::Ambig(Guidance::Unknown));
144 } 144 }
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 011bef6f6..cf7ed1e11 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg}; 6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds};
7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use base_db::{salsa::InternKey, CrateId}; 9use base_db::{salsa::InternKey, CrateId};
@@ -80,7 +80,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
80 fn impls_for_trait( 80 fn impls_for_trait(
81 &self, 81 &self,
82 trait_id: TraitId, 82 trait_id: TraitId,
83 parameters: &[GenericArg<Interner>], 83 parameters: &[chalk_ir::GenericArg<Interner>],
84 binders: &CanonicalVarKinds<Interner>, 84 binders: &CanonicalVarKinds<Interner>,
85 ) -> Vec<ImplId> { 85 ) -> Vec<ImplId> {
86 debug!("impls_for_trait {:?}", trait_id); 86 debug!("impls_for_trait {:?}", trait_id);
@@ -308,7 +308,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
308 _closure_id: chalk_ir::ClosureId<Interner>, 308 _closure_id: chalk_ir::ClosureId<Interner>,
309 _substs: &chalk_ir::Substitution<Interner>, 309 _substs: &chalk_ir::Substitution<Interner>,
310 ) -> chalk_ir::Substitution<Interner> { 310 ) -> chalk_ir::Substitution<Interner> {
311 Substitution::empty().to_chalk(self.db) 311 Substitution::empty(&Interner).to_chalk(self.db)
312 } 312 }
313 313
314 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String { 314 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
@@ -439,7 +439,7 @@ pub(crate) fn trait_datum_query(
439 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); 439 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
440 let trait_datum = TraitDatum { 440 let trait_datum = TraitDatum {
441 id: trait_id, 441 id: trait_id,
442 binders: make_binders(trait_datum_bound, bound_vars.len()), 442 binders: make_binders(trait_datum_bound, bound_vars.len(&Interner)),
443 flags, 443 flags,
444 associated_ty_ids, 444 associated_ty_ids,
445 well_known, 445 well_known,
@@ -577,7 +577,7 @@ fn impl_def_datum(
577 .collect(); 577 .collect();
578 debug!("impl_datum: {:?}", impl_datum_bound); 578 debug!("impl_datum: {:?}", impl_datum_bound);
579 let impl_datum = ImplDatum { 579 let impl_datum = ImplDatum {
580 binders: make_binders(impl_datum_bound, bound_vars.len()), 580 binders: make_binders(impl_datum_bound, bound_vars.len(&Interner)),
581 impl_type, 581 impl_type,
582 polarity, 582 polarity,
583 associated_ty_value_ids, 583 associated_ty_value_ids,
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index aef6b8a15..452b357e8 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -13,7 +13,7 @@ use crate::{
13 db::HirDatabase, 13 db::HirDatabase,
14 primitive::UintTy, 14 primitive::UintTy,
15 traits::{Canonical, DomainGoal}, 15 traits::{Canonical, DomainGoal},
16 AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy, 16 AliasTy, CallableDefId, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy,
17 QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause, 17 QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
18}; 18};
19 19
@@ -137,7 +137,7 @@ impl ToChalk for Ty {
137 db, 137 db,
138 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 138 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
139 ); 139 );
140 TyKind::Function(FnPointer { num_args: (substs.len() - 1), sig, substs }) 140 TyKind::Function(FnPointer { num_args: (substs.len(&Interner) - 1), sig, substs })
141 } 141 }
142 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx), 142 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
143 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown, 143 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
@@ -216,24 +216,39 @@ fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> {
216 chalk_ir::TyKind::Array(arg, const_).intern(&Interner) 216 chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
217} 217}
218 218
219impl ToChalk for GenericArg {
220 type Chalk = chalk_ir::GenericArg<Interner>;
221
222 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
223 match self.interned {
224 crate::GenericArgData::Ty(ty) => ty.to_chalk(db).cast(&Interner),
225 }
226 }
227
228 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
229 match chalk.interned() {
230 chalk_ir::GenericArgData::Ty(ty) => Ty::from_chalk(db, ty.clone()).cast(&Interner),
231 chalk_ir::GenericArgData::Lifetime(_) => unimplemented!(),
232 chalk_ir::GenericArgData::Const(_) => unimplemented!(),
233 }
234 }
235}
236
219impl ToChalk for Substitution { 237impl ToChalk for Substitution {
220 type Chalk = chalk_ir::Substitution<Interner>; 238 type Chalk = chalk_ir::Substitution<Interner>;
221 239
222 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 240 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
223 chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db))) 241 chalk_ir::Substitution::from_iter(
242 &Interner,
243 self.iter(&Interner).map(|ty| ty.clone().to_chalk(db)),
244 )
224 } 245 }
225 246
226 fn from_chalk( 247 fn from_chalk(
227 db: &dyn HirDatabase, 248 db: &dyn HirDatabase,
228 parameters: chalk_ir::Substitution<Interner>, 249 parameters: chalk_ir::Substitution<Interner>,
229 ) -> Substitution { 250 ) -> Substitution {
230 let tys = parameters 251 let tys = parameters.iter(&Interner).map(|p| from_chalk(db, p.clone())).collect();
231 .iter(&Interner)
232 .map(|p| match p.ty(&Interner) {
233 Some(ty) => from_chalk(db, ty.clone()),
234 None => unimplemented!(),
235 })
236 .collect();
237 Substitution(tys) 252 Substitution(tys)
238 } 253 }
239} 254}
@@ -531,7 +546,7 @@ pub(super) fn generic_predicate_to_inline_bound(
531 // have the expected self type 546 // have the expected self type
532 return None; 547 return None;
533 } 548 }
534 let args_no_self = trait_ref.substitution[1..] 549 let args_no_self = trait_ref.substitution.interned(&Interner)[1..]
535 .iter() 550 .iter()
536 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 551 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
537 .collect(); 552 .collect();
@@ -543,7 +558,7 @@ pub(super) fn generic_predicate_to_inline_bound(
543 return None; 558 return None;
544 } 559 }
545 let trait_ = projection_ty.trait_(db); 560 let trait_ = projection_ty.trait_(db);
546 let args_no_self = projection_ty.substitution[1..] 561 let args_no_self = projection_ty.substitution.interned(&Interner)[1..]
547 .iter() 562 .iter()
548 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 563 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
549 .collect(); 564 .collect();