diff options
author | Florian Diebold <[email protected]> | 2021-03-24 22:07:54 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-03-24 22:10:13 +0000 |
commit | b4c20e3589372ba1536cec1bfe7de6acd2f40a4d (patch) | |
tree | 18a40f362334376c31afbc41cdd8a304f6b6d23d /crates/hir_ty | |
parent | 4a1f5d367db3b5c6ec27d96c96c98b89988c0b3a (diff) |
Fix chalk_ir assertion
Fixes #8150.
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 33 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 11 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/utils.rs | 8 |
4 files changed, 42 insertions, 18 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 0f49dd39b..69265286f 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -538,12 +538,6 @@ impl<T: TypeWalk> Binders<T> { | |||
538 | assert_eq!(subst.len(), self.num_binders); | 538 | assert_eq!(subst.len(), self.num_binders); |
539 | self.value.subst_bound_vars(subst) | 539 | self.value.subst_bound_vars(subst) |
540 | } | 540 | } |
541 | |||
542 | /// Substitutes just a prefix of the variables (shifting the rest). | ||
543 | pub fn subst_prefix(self, subst: &Substitution) -> Binders<T> { | ||
544 | assert!(subst.len() < self.num_binders); | ||
545 | Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst)) | ||
546 | } | ||
547 | } | 541 | } |
548 | 542 | ||
549 | impl<T: TypeWalk> TypeWalk for Binders<T> { | 543 | impl<T: TypeWalk> TypeWalk for Binders<T> { |
@@ -698,7 +692,15 @@ impl CallableSig { | |||
698 | 692 | ||
699 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { | 693 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { |
700 | CallableSig { | 694 | CallableSig { |
701 | params_and_return: fn_ptr.substs.interned(&Interner).iter().cloned().collect(), | 695 | // FIXME: what to do about lifetime params? |
696 | params_and_return: fn_ptr | ||
697 | .substs | ||
698 | .clone() | ||
699 | .shift_bound_vars_out(DebruijnIndex::ONE) | ||
700 | .interned(&Interner) | ||
701 | .iter() | ||
702 | .cloned() | ||
703 | .collect(), | ||
702 | is_varargs: fn_ptr.sig.variadic, | 704 | is_varargs: fn_ptr.sig.variadic, |
703 | } | 705 | } |
704 | } | 706 | } |
@@ -1131,6 +1133,23 @@ pub trait TypeWalk { | |||
1131 | DebruijnIndex::INNERMOST, | 1133 | DebruijnIndex::INNERMOST, |
1132 | ) | 1134 | ) |
1133 | } | 1135 | } |
1136 | |||
1137 | /// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`. | ||
1138 | fn shift_bound_vars_out(self, n: DebruijnIndex) -> Self | ||
1139 | where | ||
1140 | Self: Sized + std::fmt::Debug, | ||
1141 | { | ||
1142 | self.fold_binders( | ||
1143 | &mut |ty, binders| match ty.interned(&Interner) { | ||
1144 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { | ||
1145 | TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone())) | ||
1146 | .intern(&Interner) | ||
1147 | } | ||
1148 | _ => ty, | ||
1149 | }, | ||
1150 | DebruijnIndex::INNERMOST, | ||
1151 | ) | ||
1152 | } | ||
1134 | } | 1153 | } |
1135 | 1154 | ||
1136 | impl TypeWalk for Ty { | 1155 | impl TypeWalk for Ty { |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 3153b5b74..c87789d45 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -828,14 +828,18 @@ pub fn associated_type_shorthand_candidates<R>( | |||
828 | let traits_from_env: Vec<_> = match res { | 828 | let traits_from_env: Vec<_> = match res { |
829 | TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) { | 829 | TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) { |
830 | None => vec![], | 830 | None => vec![], |
831 | Some(trait_ref) => vec![trait_ref.value], | 831 | // FIXME: how to correctly handle higher-ranked bounds here? |
832 | Some(trait_ref) => vec![trait_ref.value.shift_bound_vars_out(DebruijnIndex::ONE)], | ||
832 | }, | 833 | }, |
833 | TypeNs::GenericParam(param_id) => { | 834 | TypeNs::GenericParam(param_id) => { |
834 | let predicates = db.generic_predicates_for_param(param_id); | 835 | let predicates = db.generic_predicates_for_param(param_id); |
835 | let mut traits_: Vec<_> = predicates | 836 | let mut traits_: Vec<_> = predicates |
836 | .iter() | 837 | .iter() |
837 | .filter_map(|pred| match &pred.value.value { | 838 | .filter_map(|pred| match &pred.value.value { |
838 | WhereClause::Implemented(tr) => Some(tr.clone()), | 839 | // FIXME: how to correctly handle higher-ranked bounds here? |
840 | WhereClause::Implemented(tr) => { | ||
841 | Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) | ||
842 | } | ||
839 | _ => None, | 843 | _ => None, |
840 | }) | 844 | }) |
841 | .collect(); | 845 | .collect(); |
@@ -1156,10 +1160,9 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | |||
1156 | if db.type_alias_data(t).is_extern { | 1160 | if db.type_alias_data(t).is_extern { |
1157 | Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) | 1161 | Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) |
1158 | } else { | 1162 | } else { |
1159 | let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); | ||
1160 | let type_ref = &db.type_alias_data(t).type_ref; | 1163 | let type_ref = &db.type_alias_data(t).type_ref; |
1161 | let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error)); | 1164 | let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error)); |
1162 | Binders::new(substs.len(), inner) | 1165 | Binders::new(generics.len(), inner) |
1163 | } | 1166 | } |
1164 | } | 1167 | } |
1165 | 1168 | ||
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index 4019fdf17..011bef6f6 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -21,8 +21,8 @@ use crate::{ | |||
21 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | 21 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, |
22 | to_assoc_type_id, to_chalk_trait_id, | 22 | to_assoc_type_id, to_chalk_trait_id, |
23 | utils::generics, | 23 | utils::generics, |
24 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, ProjectionTy, | 24 | AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution, |
25 | Substitution, TraitRef, Ty, TyKind, WhereClause, | 25 | TraitRef, Ty, TyKind, WhereClause, |
26 | }; | 26 | }; |
27 | use mapping::{ | 27 | use mapping::{ |
28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, | 28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, |
@@ -288,9 +288,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
288 | ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { | 288 | ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { |
289 | let sig_ty: Ty = | 289 | let sig_ty: Ty = |
290 | from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); | 290 | from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); |
291 | let sig = CallableSig::from_substs( | 291 | let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr"); |
292 | &sig_ty.substs().expect("first closure param should be fn ptr"), | ||
293 | ); | ||
294 | let io = rust_ir::FnDefInputsAndOutputDatum { | 292 | let io = rust_ir::FnDefInputsAndOutputDatum { |
295 | argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), | 293 | argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), |
296 | return_type: sig.ret().clone().to_chalk(self.db), | 294 | return_type: sig.ret().clone().to_chalk(self.db), |
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index 19874e42b..42d7af146 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). | 2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). |
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use chalk_ir::DebruijnIndex; | ||
5 | use hir_def::{ | 6 | use hir_def::{ |
6 | adt::VariantData, | 7 | adt::VariantData, |
7 | db::DefDatabase, | 8 | db::DefDatabase, |
@@ -15,7 +16,7 @@ use hir_def::{ | |||
15 | }; | 16 | }; |
16 | use hir_expand::name::{name, Name}; | 17 | use hir_expand::name::{name, Name}; |
17 | 18 | ||
18 | use crate::{db::HirDatabase, TraitRef, WhereClause}; | 19 | use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause}; |
19 | 20 | ||
20 | fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { | 21 | fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { |
21 | let resolver = trait_.resolver(db); | 22 | let resolver = trait_.resolver(db); |
@@ -64,7 +65,10 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr | |||
64 | .iter() | 65 | .iter() |
65 | .filter_map(|pred| { | 66 | .filter_map(|pred| { |
66 | pred.as_ref().filter_map(|pred| match pred.skip_binders() { | 67 | pred.as_ref().filter_map(|pred| match pred.skip_binders() { |
67 | WhereClause::Implemented(tr) => Some(tr.clone()), | 68 | // FIXME: how to correctly handle higher-ranked bounds here? |
69 | WhereClause::Implemented(tr) => { | ||
70 | Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) | ||
71 | } | ||
68 | _ => None, | 72 | _ => None, |
69 | }) | 73 | }) |
70 | }) | 74 | }) |