Deal with goals arising from unification
This commit is contained in:
parent
4bd446f5b3
commit
9716c0b949
@ -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;
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user