Skip to content
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

Create a canonical trait query for evaluate_obligation #48995

Merged
merged 8 commits into from
Apr 27, 2018

Conversation

aravind-pg
Copy link
Contributor

This builds on the canonical query machinery introduced in #48411 to introduce a new canonical trait query for evaluate_obligation in the trait selector. Also ports most callers of the original evaluate_obligation to the new system (except in coherence, which requires support for intercrate mode). Closes #48537.

r? @nikomatsakis

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 13, 2018
@@ -617,6 +625,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
})
}

/// Evaluates whether the obligation `obligation` can be satisfied and returns
/// an `EvaluationResult`.
pub fn evaluate_obligation_recursively(&mut self,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if exposing this new API is a good thing to have done, but it was the cleanest way without also exposing TraitObligationStackList (which is even more of an implementation detail).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems OK -- I might prefer to remove evaluate_obligation_conservatively and evaluation_obligation in favor of just offering this, though. Or at least have them invoke it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. The only caller of the originals now is in coherence, so I'll just switch that to use this and remove both the originals. And rename this to just evaluate_obligation to boot.

@nikomatsakis
Copy link
Contributor

Hmm, travis is unhappy

@aravind-pg
Copy link
Contributor Author

aravind-pg commented Mar 15, 2018

The Travis error is unrelated, hopefully it'll go away on a retry:

[00:52:40]  Documenting core v0.0.0 (file:///checkout/src/libcore)
[00:52:40]    Compiling core v0.0.0 (file:///checkout/src/libcore)
[00:52:52] error: internal compiler error: librustc/ich/impls_ty.rs:907: ty::TypeVariants::hash_stable() - Unexpected variant TyInfer(?0).
[00:52:52] 
[00:52:52] thread 'rustc' panicked at 'Box<Any>', librustc_errors/lib.rs:538:9

Edit: was wrong, see below

@bors
Copy link
Contributor

bors commented Mar 15, 2018

☔ The latest upstream changes (presumably #47630) made this pull request unmergeable. Please resolve the merge conflicts.

@aravind-pg aravind-pg force-pushed the canonical-query branch 3 times, most recently from 3da95d7 to 87ce396 Compare March 15, 2018 03:54
@aravind-pg
Copy link
Contributor Author

aravind-pg commented Mar 15, 2018

Heads up: this breaks clippy, but the following diff should fix it once this lands (haven't tested though). cc @Manishearth, @llogiq

--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -306,11 +306,10 @@ pub fn implements_trait<'a, 'tcx>(
     ty_params: &[Ty<'tcx>],
 ) -> bool {
     let ty = cx.tcx.erase_regions(&ty);
-    let obligation =
-        cx.tcx
-            .predicate_for_trait_def(cx.param_env, traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params);
+    let trait_ref = ty::TraitRef::new(trait_id,
+                                      cx.tcx.mk_substs_trait(ty, ty_params);
     cx.tcx.infer_ctxt().enter(|infcx| {
-        traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation)
+        infcx.predicate_must_hold(cx.param_env, trait_ref.to_predicate())
     })
 }

@Manishearth
Copy link
Member

Manishearth commented Mar 15, 2018 via email

@aravind-pg
Copy link
Contributor Author

Ah so the Travis error isn't spurious. It looks like somehow I've introduced a codepath that causes incr.comp. to attempt (and fail) to hash type inference variables, i.e. we're hitting

TyInfer(..) => {
bug!("ty::TypeVariants::hash_stable() - Unexpected variant {:?}.", *self)
}
Unfortunately won't have time to debug this properly right now since I'm away the next 2ish days. @nikomatsakis, any pointers would be very helpful for when I get back!

@llogiq
Copy link
Contributor

llogiq commented Mar 15, 2018

I may look into it in a few hours.

@nikomatsakis
Copy link
Contributor

@aravind-pg very curious. Might be a bug in the canonicalizer.

@bors
Copy link
Contributor

bors commented Mar 18, 2018

☔ The latest upstream changes (presumably #48985) made this pull request unmergeable. Please resolve the merge conflicts.

@aravind-pg
Copy link
Contributor Author

Rebased to pick up #49091.

@@ -73,6 +73,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::normalize_ty_after_erasing_region
}
}

impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> {
fn describe(_tcx: TyCtxt, goal: CanonicalPredicateGoal<'tcx>) -> String {
format!("evaluating trait selection obligation `{:?}`", goal)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the failing test impl-trait/auto-trait-leak.rs is now including this message in its output. In general, {:?} should be avoided here, as this a message that may be shown to the user. That said, nicely formatting this message could be kind of annoying. I guess something like this might be good enough for now:

format!("evaluating trait selection obligation `{}`", goal.value.value)

I'm trying this locally. This will just skip over the canonical binders and the param-env.

@nikomatsakis nikomatsakis changed the title Create a canonical trait query for evaluate_obligation [WIP] Create a canonical trait query for evaluate_obligation Mar 19, 2018
@nikomatsakis
Copy link
Contributor

I pushed a commit that should fix the travis errors for now, but one of the fixes is not something I am yet comfortable landing (hence the update on the PR title to prevent accidental landing).

I just wanted to see if there are further errors, and measure perf impact.

@nikomatsakis nikomatsakis force-pushed the canonical-query branch 2 times, most recently from 4f250a6 to f37a1d2 Compare March 19, 2018 22:19
@nikomatsakis
Copy link
Contributor

@bors try

@bors
Copy link
Contributor

bors commented Mar 20, 2018

⌛ Trying commit f37a1d2 with merge 0fdc38f...

bors added a commit that referenced this pull request Mar 20, 2018
[WIP] Create a canonical trait query for `evaluate_obligation`

This builds on the canonical query machinery introduced in #48411 to introduce a new canonical trait query for `evaluate_obligation` in the trait selector. Also ports most callers of the original `evaluate_obligation` to the new system (except in coherence, which requires support for intercrate mode). Closes #48537.

r? @nikomatsakis
@bors
Copy link
Contributor

bors commented Mar 20, 2018

💔 Test failed - status-travis

@aravind-pg
Copy link
Contributor Author

I implemented the query mode idea and our error messages are back in good shape -- modulo this slightly unfortunate situation. Overall I think the trait selection error reporting setup has definitely gotten a little hairier, sadly, but it's the best we could think of. Later refactoring might be able to clean things up. Anyhow, ready for a re-review.

@aravind-pg aravind-pg changed the title [WIP] Create a canonical trait query for evaluate_obligation Create a canonical trait query for evaluate_obligation Apr 23, 2018
@bors
Copy link
Contributor

bors commented Apr 24, 2018

☔ The latest upstream changes (presumably #49837) made this pull request unmergeable. Please resolve the merge conflicts.

@nikomatsakis
Copy link
Contributor

r=me post rebase

@bors delegate=aravind-pg

@bors
Copy link
Contributor

bors commented Apr 26, 2018

✌️ @aravind-pg can now approve this pull request

@nikomatsakis
Copy link
Contributor

@sgrif didn't seem too terrified of the error regression. =) And it's hopefully a corner case.

@sgrif
Copy link
Contributor

sgrif commented Apr 26, 2018

Oh I'm sure I have code that hits it

…stead of aborting eagerly

We store the obligation that caused the overflow as part of the OverflowError, and report it at the public API endpoints (rather than in the implementation internals).
…rait query

Except the one in coherence, which needs support for intercrate mode.
We will shortly refactor things so that it is no longer needed
This is slightly hacky and hopefully only a somewhat temporary solution.
@aravind-pg
Copy link
Contributor Author

@bors r=nikomatsakis

Let's land for now, and if any annoyances come up then we can gate this setup with -Zchalk later.

@bors
Copy link
Contributor

bors commented Apr 27, 2018

📌 Commit e423dcc has been approved by nikomatsakis

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 27, 2018
@bors
Copy link
Contributor

bors commented Apr 27, 2018

⌛ Testing commit e423dcc with merge 8a09bc6...

bors added a commit that referenced this pull request Apr 27, 2018
Create a canonical trait query for `evaluate_obligation`

This builds on the canonical query machinery introduced in #48411 to introduce a new canonical trait query for `evaluate_obligation` in the trait selector. Also ports most callers of the original `evaluate_obligation` to the new system (except in coherence, which requires support for intercrate mode). Closes #48537.

r? @nikomatsakis
@bors
Copy link
Contributor

bors commented Apr 27, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 8a09bc6 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.