Deal with goals arising from unification

This commit is contained in:
Florian Diebold 2021-05-16 18:27:17 +02:00
parent 4bd446f5b3
commit 9716c0b949
4 changed files with 21 additions and 18 deletions

View File

@ -37,8 +37,8 @@
use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty};
use crate::{
db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyExt,
TyKind,
lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Goal, Interner, TyBuilder,
TyExt, TyKind,
};
// This lint has a false positive here. See the link below for details.
@ -104,7 +104,7 @@ fn default() -> Self {
#[derive(Debug)]
pub(crate) struct InferOk {
// obligations
goals: Vec<InEnvironment<Goal>>,
}
#[derive(Debug)]
pub(crate) struct TypeError;

View File

@ -26,8 +26,8 @@ pub(super) fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool {
return true;
}
match self.coerce_inner(from_ty, &to_ty) {
Ok(_result) => {
// TODO deal with goals
Ok(result) => {
self.table.register_infer_ok(result);
true
}
Err(_) => {
@ -67,8 +67,9 @@ pub(super) fn coerce_merge_branch(&mut self, ty1: &Ty, ty2: &Ty) -> Ty {
let target_ty = TyKind::Function(sig.to_fn_ptr()).intern(&Interner);
let result1 = self.coerce_inner(ty1.clone(), &target_ty);
let result2 = self.coerce_inner(ty2.clone(), &target_ty);
if let (Ok(_result1), Ok(_result2)) = (result1, result2) {
// TODO deal with the goals
if let (Ok(result1), Ok(result2)) = (result1, result2) {
self.table.register_infer_ok(result1);
self.table.register_infer_ok(result2);
return target_ty;
}
}
@ -104,7 +105,7 @@ fn coerce_inner(&mut self, from_ty: Ty, to_ty: &Ty) -> InferResult {
}
_ => {}
}
return Ok(InferOk {});
return Ok(InferOk { goals: Vec::new() });
}
// Consider coercing the subtype to a DST
@ -416,10 +417,11 @@ fn try_coerce_unsized(&mut self, from_ty: &Ty, to_ty: &Ty) -> InferResult {
},
);
}
// FIXME: should we accept ambiguous results here?
_ => return Err(TypeError),
};
Ok(InferOk {})
Ok(InferOk { goals: Vec::new() })
}
}
@ -444,11 +446,11 @@ fn safe_to_unsafe_fn_ty(fn_ty: FnPointer) -> FnPointer {
}
}
fn coerce_mutabilities(from: Mutability, to: Mutability) -> InferResult {
fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError> {
match (from, to) {
(Mutability::Mut, Mutability::Mut)
| (Mutability::Mut, Mutability::Not)
| (Mutability::Not, Mutability::Not) => Ok(InferOk {}),
| (Mutability::Not, Mutability::Not) => Ok(()),
(Mutability::Not, Mutability::Mut) => Err(TypeError),
}
}

View File

@ -307,12 +307,12 @@ pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
/// Unify two types and register new trait goals that arise from that.
// TODO give these two functions better names
pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
let _result = if let Ok(r) = self.unify_inner(ty1, ty2) {
let result = if let Ok(r) = self.unify_inner(ty1, ty2) {
r
} else {
return false;
};
// TODO deal with new goals
self.register_infer_ok(result);
true
}
@ -327,10 +327,7 @@ pub(crate) fn unify_inner<T: Zip<Interner>>(&mut self, t1: &T, t2: &T) -> InferR
t1,
t2,
) {
Ok(_result) => {
// TODO deal with new goals
Ok(InferOk {})
}
Ok(result) => Ok(InferOk { goals: result.goals }),
Err(chalk_ir::NoSolution) => Err(TypeError),
}
}
@ -353,6 +350,10 @@ fn register_obligation_in_env(&mut self, goal: InEnvironment<Goal>) {
}
}
pub fn register_infer_ok(&mut self, infer_ok: InferOk) {
infer_ok.goals.into_iter().for_each(|goal| self.register_obligation_in_env(goal));
}
pub fn resolve_obligations_as_possible(&mut self) {
let _span = profile::span("resolve_obligations_as_possible");
let mut changed = true;

View File

@ -758,7 +758,7 @@ fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar>
"#,
expect![[r#"
136..139 'key': &K
198..214 '{ ...key) }': {unknown}
198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
208..211 'key': &K