mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-16 09:48:10 +00:00
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 <flodiebold@gmail.com>
This commit is contained in:
commit
9d81618f11
4 changed files with 42 additions and 18 deletions
|
@ -538,12 +538,6 @@ impl<T: TypeWalk> Binders<T> {
|
||||||
assert_eq!(subst.len(), self.num_binders);
|
assert_eq!(subst.len(), self.num_binders);
|
||||||
self.value.subst_bound_vars(subst)
|
self.value.subst_bound_vars(subst)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Substitutes just a prefix of the variables (shifting the rest).
|
|
||||||
pub fn subst_prefix(self, subst: &Substitution) -> Binders<T> {
|
|
||||||
assert!(subst.len() < self.num_binders);
|
|
||||||
Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TypeWalk> TypeWalk for Binders<T> {
|
impl<T: TypeWalk> TypeWalk for Binders<T> {
|
||||||
|
@ -698,7 +692,15 @@ impl CallableSig {
|
||||||
|
|
||||||
pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
|
pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
|
||||||
CallableSig {
|
CallableSig {
|
||||||
params_and_return: fn_ptr.substs.interned(&Interner).iter().cloned().collect(),
|
// FIXME: what to do about lifetime params?
|
||||||
|
params_and_return: fn_ptr
|
||||||
|
.substs
|
||||||
|
.clone()
|
||||||
|
.shift_bound_vars_out(DebruijnIndex::ONE)
|
||||||
|
.interned(&Interner)
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
is_varargs: fn_ptr.sig.variadic,
|
is_varargs: fn_ptr.sig.variadic,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1131,6 +1133,23 @@ pub trait TypeWalk {
|
||||||
DebruijnIndex::INNERMOST,
|
DebruijnIndex::INNERMOST,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`.
|
||||||
|
fn shift_bound_vars_out(self, n: DebruijnIndex) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized + std::fmt::Debug,
|
||||||
|
{
|
||||||
|
self.fold_binders(
|
||||||
|
&mut |ty, binders| match ty.interned(&Interner) {
|
||||||
|
TyKind::BoundVar(bound) if bound.debruijn >= binders => {
|
||||||
|
TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone()))
|
||||||
|
.intern(&Interner)
|
||||||
|
}
|
||||||
|
_ => ty,
|
||||||
|
},
|
||||||
|
DebruijnIndex::INNERMOST,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeWalk for Ty {
|
impl TypeWalk for Ty {
|
||||||
|
|
|
@ -828,14 +828,18 @@ pub fn associated_type_shorthand_candidates<R>(
|
||||||
let traits_from_env: Vec<_> = match res {
|
let traits_from_env: Vec<_> = match res {
|
||||||
TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) {
|
TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
Some(trait_ref) => vec![trait_ref.value],
|
// FIXME: how to correctly handle higher-ranked bounds here?
|
||||||
|
Some(trait_ref) => vec![trait_ref.value.shift_bound_vars_out(DebruijnIndex::ONE)],
|
||||||
},
|
},
|
||||||
TypeNs::GenericParam(param_id) => {
|
TypeNs::GenericParam(param_id) => {
|
||||||
let predicates = db.generic_predicates_for_param(param_id);
|
let predicates = db.generic_predicates_for_param(param_id);
|
||||||
let mut traits_: Vec<_> = predicates
|
let mut traits_: Vec<_> = predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|pred| match &pred.value.value {
|
.filter_map(|pred| match &pred.value.value {
|
||||||
WhereClause::Implemented(tr) => Some(tr.clone()),
|
// FIXME: how to correctly handle higher-ranked bounds here?
|
||||||
|
WhereClause::Implemented(tr) => {
|
||||||
|
Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -1156,10 +1160,9 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
|
||||||
if db.type_alias_data(t).is_extern {
|
if db.type_alias_data(t).is_extern {
|
||||||
Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
|
Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
|
||||||
} else {
|
} else {
|
||||||
let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
|
|
||||||
let type_ref = &db.type_alias_data(t).type_ref;
|
let type_ref = &db.type_alias_data(t).type_ref;
|
||||||
let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error));
|
let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error));
|
||||||
Binders::new(substs.len(), inner)
|
Binders::new(generics.len(), inner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ use crate::{
|
||||||
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
|
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
|
||||||
to_assoc_type_id, to_chalk_trait_id,
|
to_assoc_type_id, to_chalk_trait_id,
|
||||||
utils::generics,
|
utils::generics,
|
||||||
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, ProjectionTy,
|
AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution,
|
||||||
Substitution, TraitRef, Ty, TyKind, WhereClause,
|
TraitRef, Ty, TyKind, WhereClause,
|
||||||
};
|
};
|
||||||
use mapping::{
|
use mapping::{
|
||||||
convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
|
convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
|
||||||
|
@ -288,9 +288,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
||||||
) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
|
) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
|
||||||
let sig_ty: Ty =
|
let sig_ty: Ty =
|
||||||
from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
|
from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
|
||||||
let sig = CallableSig::from_substs(
|
let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr");
|
||||||
&sig_ty.substs().expect("first closure param should be fn ptr"),
|
|
||||||
);
|
|
||||||
let io = rust_ir::FnDefInputsAndOutputDatum {
|
let io = rust_ir::FnDefInputsAndOutputDatum {
|
||||||
argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
|
argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
|
||||||
return_type: sig.ret().clone().to_chalk(self.db),
|
return_type: sig.ret().clone().to_chalk(self.db),
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
|
//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use chalk_ir::DebruijnIndex;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
adt::VariantData,
|
adt::VariantData,
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
|
@ -15,7 +16,7 @@ use hir_def::{
|
||||||
};
|
};
|
||||||
use hir_expand::name::{name, Name};
|
use hir_expand::name::{name, Name};
|
||||||
|
|
||||||
use crate::{db::HirDatabase, TraitRef, WhereClause};
|
use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause};
|
||||||
|
|
||||||
fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
|
fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
|
||||||
let resolver = trait_.resolver(db);
|
let resolver = trait_.resolver(db);
|
||||||
|
@ -64,7 +65,10 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|pred| {
|
.filter_map(|pred| {
|
||||||
pred.as_ref().filter_map(|pred| match pred.skip_binders() {
|
pred.as_ref().filter_map(|pred| match pred.skip_binders() {
|
||||||
WhereClause::Implemented(tr) => Some(tr.clone()),
|
// FIXME: how to correctly handle higher-ranked bounds here?
|
||||||
|
WhereClause::Implemented(tr) => {
|
||||||
|
Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue