diff options
author | Florian Diebold <[email protected]> | 2021-04-01 20:04:02 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-04-03 10:17:13 +0100 |
commit | e480d81988fc0c0e4f80f1c54058b95b9aaf1ebf (patch) | |
tree | 079dabc4e0de72e30d2bd04bd50427ff6950b348 /crates | |
parent | 327f3a0a3017e047be58b8312f8bf3ac690db3fd (diff) |
Introduce `GenericArg` like in Chalk
Plus some more adaptations to Substitution.
Lots of `assert_ty_ref` that we should revisit when introducing
lifetime/const parameters.
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/lib.rs | 31 | ||||
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 9 | ||||
-rw-r--r-- | crates/hir_ty/src/chalk_cast.rs | 22 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/match_check.rs | 5 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 61 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 24 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 17 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 55 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 173 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 17 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 10 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 39 |
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 | ||
8 | use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause}; | 8 | use crate::{AliasEq, DomainGoal, GenericArg, GenericArgData, Interner, TraitRef, Ty, WhereClause}; |
9 | 9 | ||
10 | macro_rules! has_interner { | 10 | macro_rules! has_interner { |
11 | ($t:ty) => { | 11 | ($t:ty) => { |
@@ -17,6 +17,8 @@ macro_rules! has_interner { | |||
17 | 17 | ||
18 | has_interner!(WhereClause); | 18 | has_interner!(WhereClause); |
19 | has_interner!(DomainGoal); | 19 | has_interner!(DomainGoal); |
20 | has_interner!(GenericArg); | ||
21 | has_interner!(Ty); | ||
20 | 22 | ||
21 | impl CastTo<WhereClause> for TraitRef { | 23 | impl 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 | ||
41 | impl CastTo<GenericArg> for Ty { | ||
42 | fn cast_to(self, interner: &Interner) -> GenericArg { | ||
43 | GenericArg::new(interner, GenericArgData::Ty(self)) | ||
44 | } | ||
45 | } | ||
46 | |||
39 | macro_rules! transitive_impl { | 47 | macro_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 | ||
52 | transitive_impl!(TraitRef, WhereClause, DomainGoal); | 60 | transitive_impl!(TraitRef, WhereClause, DomainGoal); |
53 | transitive_impl!(AliasEq, WhereClause, DomainGoal); | 61 | transitive_impl!(AliasEq, WhereClause, DomainGoal); |
62 | |||
63 | macro_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 | |||
73 | reflexive_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; | |||
18 | use crate::{ | 18 | use 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 | |||
281 | impl 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(¶meters.prefix(i)); | 485 | .subst(¶meters.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 | ||
1019 | impl HirDisplay for GenericArg { | 1032 | impl 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 | ||
164 | pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | 163 | pub(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)] |
25 | mod test_db; | 25 | mod test_db; |
26 | 26 | ||
27 | use std::{iter, mem, ops::Deref, sync::Arc}; | 27 | use std::{iter, mem, sync::Arc}; |
28 | 28 | ||
29 | use base_db::salsa; | 29 | use base_db::salsa; |
30 | use chalk_ir::cast::{CastTo, Caster}; | ||
30 | use hir_def::{ | 31 | use 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)] | ||
329 | pub struct GenericArg { | ||
330 | interned: GenericArgData, | ||
331 | } | ||
332 | |||
333 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
334 | pub enum GenericArgData { | ||
335 | Ty(Ty), | ||
336 | } | ||
337 | |||
338 | impl 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 | |||
369 | impl 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)] |
329 | pub struct Substitution(SmallVec<[Ty; 2]>); | 393 | pub struct Substitution(SmallVec<[GenericArg; 2]>); |
330 | 394 | ||
331 | impl TypeWalk for Substitution { | 395 | impl 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 | ||
349 | impl Substitution { | 413 | impl 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)] |
437 | pub struct SubstsBuilder { | 513 | pub struct SubstsBuilder { |
438 | vec: Vec<Ty>, | 514 | vec: Vec<GenericArg>, |
439 | param_count: usize, | 515 | param_count: usize, |
440 | } | 516 | } |
441 | 517 | ||
442 | impl SubstsBuilder { | 518 | impl 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 | ||
482 | impl 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)] |
491 | pub struct Binders<T> { | 559 | pub struct Binders<T> { |
492 | pub num_binders: usize, | 560 | pub num_binders: usize, |
@@ -535,7 +603,7 @@ impl<T: Clone> Binders<&T> { | |||
535 | impl<T: TypeWalk> Binders<T> { | 603 | impl<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 | ||
564 | impl TraitRef { | 632 | impl 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 | ||
739 | impl Ty { | 813 | impl 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(¶meters)) | 982 | Some(sig.subst(¶meters)) |
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) - | |||
1142 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { | 1143 | fn 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 | ||
1148 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | 1149 | fn 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 | ||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg}; | 6 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds}; |
7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; | 7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; |
8 | 8 | ||
9 | use base_db::{salsa::InternKey, CrateId}; | 9 | use 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 | ||
219 | impl 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 | |||
219 | impl ToChalk for Substitution { | 237 | impl 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(); |