Fix HIR expecting errors to unify with anything
This commit is contained in:
parent
48c492af7e
commit
8397734cfe
@ -2051,11 +2051,7 @@ pub fn iterate_path_candidates<T>(
|
||||
name: Option<&Name>,
|
||||
mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
|
||||
) -> Option<T> {
|
||||
// There should be no inference vars in types passed here
|
||||
// FIXME check that?
|
||||
// FIXME replace Unknown by bound vars here
|
||||
let canonical =
|
||||
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
|
||||
let canonical = hir_ty::replace_errors_with_variables(self.ty.clone());
|
||||
|
||||
let env = self.env.clone();
|
||||
let krate = krate.id;
|
||||
@ -2224,7 +2220,8 @@ fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
|
||||
}
|
||||
|
||||
pub fn could_unify_with(&self, db: &dyn HirDatabase, other: &Type) -> bool {
|
||||
could_unify(db, self.env.clone(), &self.ty, &other.ty)
|
||||
let tys = hir_ty::replace_errors_with_variables((self.ty.clone(), other.ty.clone()));
|
||||
could_unify(db, self.env.clone(), &tys)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,8 +86,12 @@ pub(super) fn apply_solution(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn could_unify(db: &dyn HirDatabase, env: Arc<TraitEnvironment>, t1: &Ty, t2: &Ty) -> bool {
|
||||
InferenceTable::new(db, env).unify(t1, t2)
|
||||
pub fn could_unify(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
tys: &Canonical<(Ty, Ty)>,
|
||||
) -> bool {
|
||||
unify(db, env, tys).is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn unify(
|
||||
|
@ -43,6 +43,7 @@ macro_rules! eprintln {
|
||||
type_ref::{ConstScalar, Rawness},
|
||||
TypeParamId,
|
||||
};
|
||||
use stdx::always;
|
||||
|
||||
use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
|
||||
|
||||
@ -326,3 +327,58 @@ fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> {
|
||||
}
|
||||
t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly")
|
||||
}
|
||||
|
||||
pub fn replace_errors_with_variables<T>(t: T) -> Canonical<T::Result>
|
||||
where
|
||||
T: HasInterner<Interner = Interner> + Fold<Interner>,
|
||||
T::Result: HasInterner<Interner = Interner>,
|
||||
{
|
||||
use chalk_ir::{
|
||||
fold::{Folder, SuperFold},
|
||||
Fallible,
|
||||
};
|
||||
struct ErrorReplacer {
|
||||
vars: usize,
|
||||
}
|
||||
impl<'i> Folder<'i, Interner> for ErrorReplacer {
|
||||
fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> {
|
||||
self
|
||||
}
|
||||
|
||||
fn interner(&self) -> &'i Interner {
|
||||
&Interner
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> {
|
||||
if let TyKind::Error = ty.kind(&Interner) {
|
||||
let index = self.vars;
|
||||
self.vars += 1;
|
||||
Ok(TyKind::BoundVar(BoundVar::new(outer_binder, index)).intern(&Interner))
|
||||
} else {
|
||||
let ty = ty.super_fold_with(self.as_dyn(), outer_binder)?;
|
||||
Ok(ty)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_inference_ty(
|
||||
&mut self,
|
||||
var: InferenceVar,
|
||||
kind: TyVariableKind,
|
||||
_outer_binder: DebruijnIndex,
|
||||
) -> Fallible<Ty> {
|
||||
always!(false);
|
||||
Ok(TyKind::InferenceVar(var, kind).intern(&Interner))
|
||||
}
|
||||
}
|
||||
let mut error_replacer = ErrorReplacer { vars: 0 };
|
||||
let value = t
|
||||
.fold_with(&mut error_replacer, DebruijnIndex::INNERMOST)
|
||||
.expect("fold failed unexpectedly");
|
||||
let kinds = (0..error_replacer.vars).map(|_| {
|
||||
chalk_ir::CanonicalVarKind::new(
|
||||
chalk_ir::VariableKind::Ty(TyVariableKind::General),
|
||||
chalk_ir::UniverseIndex::ROOT,
|
||||
)
|
||||
});
|
||||
Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user