Skip to content

Commit 9d81618

Browse files
Merge #8190
8190: Fix chalk_ir assertion r=flodiebold a=flodiebold Fixes #8150. I implemented a validator that catches this in the tests, but it'd need to get merged in Chalk first. Co-authored-by: Florian Diebold <[email protected]>
2 parents aac6285 + b4c20e3 commit 9d81618

File tree

4 files changed

+42
-18
lines changed

4 files changed

+42
-18
lines changed

crates/hir_ty/src/lib.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -538,12 +538,6 @@ impl<T: TypeWalk> Binders<T> {
538538
assert_eq!(subst.len(), self.num_binders);
539539
self.value.subst_bound_vars(subst)
540540
}
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-
}
547541
}
548542

549543
impl<T: TypeWalk> TypeWalk for Binders<T> {
@@ -698,7 +692,15 @@ impl CallableSig {
698692

699693
pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
700694
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(),
702704
is_varargs: fn_ptr.sig.variadic,
703705
}
704706
}
@@ -1131,6 +1133,23 @@ pub trait TypeWalk {
11311133
DebruijnIndex::INNERMOST,
11321134
)
11331135
}
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+
}
11341153
}
11351154

11361155
impl TypeWalk for Ty {

crates/hir_ty/src/lower.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -828,14 +828,18 @@ pub fn associated_type_shorthand_candidates<R>(
828828
let traits_from_env: Vec<_> = match res {
829829
TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) {
830830
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)],
832833
},
833834
TypeNs::GenericParam(param_id) => {
834835
let predicates = db.generic_predicates_for_param(param_id);
835836
let mut traits_: Vec<_> = predicates
836837
.iter()
837838
.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+
}
839843
_ => None,
840844
})
841845
.collect();
@@ -1156,10 +1160,9 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
11561160
if db.type_alias_data(t).is_extern {
11571161
Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
11581162
} else {
1159-
let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
11601163
let type_ref = &db.type_alias_data(t).type_ref;
11611164
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)
11631166
}
11641167
}
11651168

crates/hir_ty/src/traits/chalk.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use crate::{
2121
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
2222
to_assoc_type_id, to_chalk_trait_id,
2323
utils::generics,
24-
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, ProjectionTy,
25-
Substitution, TraitRef, Ty, TyKind, WhereClause,
24+
AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution,
25+
TraitRef, Ty, TyKind, WhereClause,
2626
};
2727
use mapping::{
2828
convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
@@ -288,9 +288,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
288288
) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
289289
let sig_ty: Ty =
290290
from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
291-
let sig = CallableSig::from_substs(
292-
&sig_ty.substs().expect("first closure param should be fn ptr"),
293-
);
291+
let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr");
294292
let io = rust_ir::FnDefInputsAndOutputDatum {
295293
argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
296294
return_type: sig.ret().clone().to_chalk(self.db),

crates/hir_ty/src/utils.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
33
use std::sync::Arc;
44

5+
use chalk_ir::DebruijnIndex;
56
use hir_def::{
67
adt::VariantData,
78
db::DefDatabase,
@@ -15,7 +16,7 @@ use hir_def::{
1516
};
1617
use hir_expand::name::{name, Name};
1718

18-
use crate::{db::HirDatabase, TraitRef, WhereClause};
19+
use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause};
1920

2021
fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
2122
let resolver = trait_.resolver(db);
@@ -64,7 +65,10 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
6465
.iter()
6566
.filter_map(|pred| {
6667
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+
}
6872
_ => None,
6973
})
7074
})

0 commit comments

Comments
 (0)