-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
we only need to prove things one way #754
Changes from 5 commits
f979cd1
d55a9a2
2e759c1
a5083eb
502d989
70b2fdb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,8 +46,16 @@ impl<I: Interner> AggregateOps<I> for SlgContextOps<'_, I> { | |
} | ||
}; | ||
|
||
// If the answer is trivially true and thus subsumes all others, then that's a unique-enough answer for us :) | ||
if subst.value.is_identity_subst_with_no_constraints(interner) { | ||
return Some(Solution::Unique(subst)); | ||
} | ||
|
||
tracing::debug!("subst = {:?}", subst); | ||
|
||
// Exactly 1 unconditional answer? | ||
let next_answer = answers.peek_answer(&should_continue); | ||
tracing::debug!("next_answer = {:?}", next_answer); | ||
if next_answer.is_quantum_exceeded() { | ||
if subst.value.subst.is_identity_subst(interner) { | ||
return Some(Solution::Ambig(Guidance::Unknown)); | ||
|
@@ -83,9 +91,11 @@ impl<I: Interner> AggregateOps<I> for SlgContextOps<'_, I> { | |
break Guidance::Unknown; | ||
} | ||
|
||
// FIXME: This may cause us to miss some "trivially true" answers maybe? Haven't investigated very deeply. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm guessing this is the cause of the test I pointed out. |
||
if !answers | ||
.any_future_answer(|ref mut new_subst| new_subst.may_invalidate(interner, &subst)) | ||
{ | ||
tracing::debug!("any_future_answer: false"); | ||
break Guidance::Definite(subst); | ||
} | ||
|
||
|
@@ -96,7 +106,17 @@ impl<I: Interner> AggregateOps<I> for SlgContextOps<'_, I> { | |
} | ||
|
||
let new_subst = match answers.next_answer(&should_continue) { | ||
AnswerResult::Answer(answer1) => answer1.subst, | ||
AnswerResult::Answer(answer1) => { | ||
if answer1 | ||
.subst | ||
.value | ||
.is_identity_subst_with_no_constraints(interner) | ||
{ | ||
// If the answer is trivially true and thus subsumes all others, then that's a unique-enough answer for us :) | ||
return Some(Solution::Unique(answer1.subst)); | ||
} | ||
answer1.subst | ||
} | ||
AnswerResult::Floundered => { | ||
// FIXME: this doesn't trigger for any current tests | ||
self.identity_constrained_subst(root_goal) | ||
|
@@ -108,6 +128,7 @@ impl<I: Interner> AggregateOps<I> for SlgContextOps<'_, I> { | |
break Guidance::Suggested(subst); | ||
} | ||
}; | ||
tracing::debug!("new_subst = {:?}", new_subst); | ||
subst = merge_into_guidance(interner, &root_goal.canonical, subst, &new_subst); | ||
num_answers += 1; | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
use super::*; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like I'd like to see these tests more properly categorized. But I don't know how strongly I feel about it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense-- but I'm not sure where to categorize them! |
||
|
||
#[test] | ||
fn issue_727_1() { | ||
test!( | ||
program { | ||
#[upstream] #[non_enumerable] #[lang(sized)] | ||
trait Sized {} | ||
|
||
#[non_enumerable] #[object_safe] | ||
trait Database {} | ||
|
||
#[non_enumerable] | ||
trait QueryGroup | ||
where | ||
Self: Sized, | ||
{ | ||
type DynDb: Database + HasQueryGroup<Self>; | ||
} | ||
|
||
#[non_enumerable] #[object_safe] | ||
trait HasQueryGroup<G> | ||
where | ||
Self: Database, | ||
G: QueryGroup, | ||
G: Sized, | ||
{ } | ||
|
||
#[non_enumerable] #[object_safe] | ||
trait HelloWorld | ||
where | ||
Self: HasQueryGroup<HelloWorldStorage>, | ||
{ } | ||
|
||
struct HelloWorldStorage {} | ||
|
||
impl QueryGroup for HelloWorldStorage { | ||
type DynDb = dyn HelloWorld + 'static; | ||
} | ||
impl<DB> HelloWorld for DB | ||
where | ||
DB: Database, | ||
DB: HasQueryGroup<HelloWorldStorage>, | ||
DB: Sized, | ||
{ } | ||
} | ||
|
||
goal { | ||
forall<T> { | ||
if (FromEnv(T: Database); FromEnv(T: HasQueryGroup<HelloWorldStorage>); FromEnv(T: Sized)) { | ||
T: HelloWorld | ||
} | ||
} | ||
} yields[SolverChoice::slg_default()] { // ok | ||
expect![["Unique"]] | ||
} yields[SolverChoice::recursive_default()] { // fails: "Ambiguous; no inference guidance" | ||
expect![["Unique"]] | ||
} | ||
); | ||
} | ||
|
||
#[test] | ||
fn issue_727_2() { | ||
test!( | ||
program { | ||
#[non_enumerable] #[object_safe] | ||
trait Database {} | ||
|
||
#[non_enumerable] | ||
trait QueryGroup | ||
{ | ||
type DynDb: Database + HasQueryGroup<Self>; | ||
} | ||
|
||
#[non_enumerable] #[object_safe] | ||
trait HasQueryGroup<G> | ||
where | ||
Self: Database, | ||
G: QueryGroup, | ||
{ } | ||
|
||
struct HelloWorldStorage {} | ||
|
||
impl QueryGroup for HelloWorldStorage { | ||
type DynDb = dyn HasQueryGroup<HelloWorldStorage> + 'static; | ||
} | ||
} | ||
|
||
goal { | ||
forall<T> { | ||
if (FromEnv(T: HasQueryGroup<HelloWorldStorage>)) { | ||
T: Database | ||
} | ||
} | ||
} yields[SolverChoice::slg_default()] { | ||
expect![["Unique"]] | ||
} yields[SolverChoice::recursive_default()] { | ||
expect![[r#"Ambiguous; no inference guidance"#]] // FIXME rust-lang/chalk#727 | ||
} | ||
); | ||
} | ||
|
||
#[test] | ||
fn issue_727_3() { | ||
test!( | ||
program { | ||
#[non_enumerable] | ||
trait Database {} | ||
|
||
#[non_enumerable] | ||
trait HasQueryGroup<G> | ||
where | ||
Self: Database, | ||
{ } | ||
|
||
struct HelloWorldStorage {} | ||
|
||
impl Database for HelloWorldStorage { } | ||
} | ||
|
||
goal { | ||
forall<T, S> { | ||
if (FromEnv(HelloWorldStorage: HasQueryGroup<T>); FromEnv(HelloWorldStorage: HasQueryGroup<S>)) { | ||
HelloWorldStorage: Database | ||
} | ||
} | ||
} yields[SolverChoice::slg_default()] { | ||
expect![["Unique"]] | ||
} yields[SolverChoice::recursive_default()] { | ||
expect![["Unique"]] | ||
} | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -749,7 +749,7 @@ fn empty_definite_guidance() { | |
} yields[SolverChoice::slg_default()] { | ||
expect![["Unique"]] | ||
} yields[SolverChoice::recursive_default()] { | ||
expect![["Ambiguous; suggested substitution []"]] | ||
expect![[r#"Unique"#]] | ||
} | ||
} | ||
} | ||
|
@@ -813,7 +813,7 @@ fn env_bound_vars() { | |
} | ||
} | ||
} yields { | ||
expect![["Ambiguous; definite substitution for<?U0> { [?0 := '^0.0] }"]] | ||
expect![[r#"Unique; for<?U0> { substitution [?0 := '^0.0] }"#]] | ||
} | ||
goal { | ||
exists<'a> { | ||
|
@@ -841,7 +841,7 @@ fn recursive_hang() { | |
} yields[SolverChoice::slg_default()] { | ||
expect![["Ambiguous; definite substitution for<?U0,?U0> { [?0 := ^0.0, ?1 := '^0.1] }"]] | ||
} yields[SolverChoice::recursive_default()] { | ||
expect![["Ambiguous; suggested substitution for<?U0,?U0> { [?0 := ^0.0, ?1 := '^0.1] }"]] | ||
expect![[r#"Ambiguous; no inference guidance"#]] | ||
} | ||
Comment on lines
843
to
847
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are, I believe, equivalent. That substitution is an "identity substitution", so it's not very useful guidance. I looked into why this was coming about -- it's because I removed the (erroneous) "early exit" that was causing us to bail out early. What we now do is bail out because we see
Comment on lines
843
to
847
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fact these are still different bothers me. Also, SLG is still given the identity solution as "ambiguous", which is somewhat at odds with what the aggregate hack is saying, right? |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe at least a comment that this is hacky would be nice.