aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-03-24 22:07:54 +0000
committerFlorian Diebold <[email protected]>2021-03-24 22:10:13 +0000
commitb4c20e3589372ba1536cec1bfe7de6acd2f40a4d (patch)
tree18a40f362334376c31afbc41cdd8a304f6b6d23d /crates
parent4a1f5d367db3b5c6ec27d96c96c98b89988c0b3a (diff)
Fix chalk_ir assertion
Fixes #8150.
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/lib.rs33
-rw-r--r--crates/hir_ty/src/lower.rs11
-rw-r--r--crates/hir_ty/src/traits/chalk.rs8
-rw-r--r--crates/hir_ty/src/utils.rs8
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
549impl<T: TypeWalk> TypeWalk for Binders<T> { 543impl<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
1136impl TypeWalk for Ty { 1155impl 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};
27use mapping::{ 27use 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`).
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use chalk_ir::DebruijnIndex;
5use hir_def::{ 6use hir_def::{
6 adt::VariantData, 7 adt::VariantData,
7 db::DefDatabase, 8 db::DefDatabase,
@@ -15,7 +16,7 @@ use hir_def::{
15}; 16};
16use hir_expand::name::{name, Name}; 17use hir_expand::name::{name, Name};
17 18
18use crate::{db::HirDatabase, TraitRef, WhereClause}; 19use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause};
19 20
20fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { 21fn 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 })