Deal with goals arising from unification
This commit is contained in:
parent
4bd446f5b3
commit
9716c0b949
@ -37,8 +37,8 @@ use syntax::SmolStr;
|
|||||||
use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty};
|
use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty};
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
|
db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
|
||||||
lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyExt,
|
lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Goal, Interner, TyBuilder,
|
||||||
TyKind,
|
TyExt, TyKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This lint has a false positive here. See the link below for details.
|
// This lint has a false positive here. See the link below for details.
|
||||||
@ -104,7 +104,7 @@ impl Default for BindingMode {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct InferOk {
|
pub(crate) struct InferOk {
|
||||||
// obligations
|
goals: Vec<InEnvironment<Goal>>,
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct TypeError;
|
pub(crate) struct TypeError;
|
||||||
|
@ -26,8 +26,8 @@ impl<'a> InferenceContext<'a> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
match self.coerce_inner(from_ty, &to_ty) {
|
match self.coerce_inner(from_ty, &to_ty) {
|
||||||
Ok(_result) => {
|
Ok(result) => {
|
||||||
// TODO deal with goals
|
self.table.register_infer_ok(result);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@ -67,8 +67,9 @@ impl<'a> InferenceContext<'a> {
|
|||||||
let target_ty = TyKind::Function(sig.to_fn_ptr()).intern(&Interner);
|
let target_ty = TyKind::Function(sig.to_fn_ptr()).intern(&Interner);
|
||||||
let result1 = self.coerce_inner(ty1.clone(), &target_ty);
|
let result1 = self.coerce_inner(ty1.clone(), &target_ty);
|
||||||
let result2 = self.coerce_inner(ty2.clone(), &target_ty);
|
let result2 = self.coerce_inner(ty2.clone(), &target_ty);
|
||||||
if let (Ok(_result1), Ok(_result2)) = (result1, result2) {
|
if let (Ok(result1), Ok(result2)) = (result1, result2) {
|
||||||
// TODO deal with the goals
|
self.table.register_infer_ok(result1);
|
||||||
|
self.table.register_infer_ok(result2);
|
||||||
return target_ty;
|
return target_ty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,7 +105,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
return Ok(InferOk {});
|
return Ok(InferOk { goals: Vec::new() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consider coercing the subtype to a DST
|
// Consider coercing the subtype to a DST
|
||||||
@ -416,10 +417,11 @@ impl<'a> InferenceContext<'a> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// FIXME: should we accept ambiguous results here?
|
||||||
_ => return Err(TypeError),
|
_ => 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) {
|
match (from, to) {
|
||||||
(Mutability::Mut, Mutability::Mut)
|
(Mutability::Mut, Mutability::Mut)
|
||||||
| (Mutability::Mut, Mutability::Not)
|
| (Mutability::Mut, Mutability::Not)
|
||||||
| (Mutability::Not, Mutability::Not) => Ok(InferOk {}),
|
| (Mutability::Not, Mutability::Not) => Ok(()),
|
||||||
(Mutability::Not, Mutability::Mut) => Err(TypeError),
|
(Mutability::Not, Mutability::Mut) => Err(TypeError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,12 +307,12 @@ impl<'a> InferenceTable<'a> {
|
|||||||
/// Unify two types and register new trait goals that arise from that.
|
/// Unify two types and register new trait goals that arise from that.
|
||||||
// TODO give these two functions better names
|
// TODO give these two functions better names
|
||||||
pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
|
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
|
r
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
// TODO deal with new goals
|
self.register_infer_ok(result);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,10 +327,7 @@ impl<'a> InferenceTable<'a> {
|
|||||||
t1,
|
t1,
|
||||||
t2,
|
t2,
|
||||||
) {
|
) {
|
||||||
Ok(_result) => {
|
Ok(result) => Ok(InferOk { goals: result.goals }),
|
||||||
// TODO deal with new goals
|
|
||||||
Ok(InferOk {})
|
|
||||||
}
|
|
||||||
Err(chalk_ir::NoSolution) => Err(TypeError),
|
Err(chalk_ir::NoSolution) => Err(TypeError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -353,6 +350,10 @@ impl<'a> InferenceTable<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
pub fn resolve_obligations_as_possible(&mut self) {
|
||||||
let _span = profile::span("resolve_obligations_as_possible");
|
let _span = profile::span("resolve_obligations_as_possible");
|
||||||
let mut changed = true;
|
let mut changed = true;
|
||||||
|
@ -758,7 +758,7 @@ fn issue_4885() {
|
|||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
136..139 'key': &K
|
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..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>
|
204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
|
||||||
208..211 'key': &K
|
208..211 'key': &K
|
||||||
|
Loading…
x
Reference in New Issue
Block a user