-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Await on mismatched future types #72784
Conversation
07a8393
to
70811bb
Compare
☔ The latest upstream changes (presumably #75666) made this pull request unmergeable. Please resolve the merge conflicts. |
b33a812
to
305c09f
Compare
@csmoe sorry, this fell through the cracks of my queue. Love the changes. Left some nitpicks but otherwise it LGTM! |
r? @estebank |
src/librustc_typeck/check/expr.rs
Outdated
let future_trait = self.tcx.require_lang_item(LangItem::Future, None); | ||
// Future::Output | ||
let item_def_id = | ||
self.tcx.associated_items(future_trait).in_definition_order().next().unwrap().def_id; | ||
|
||
let mut projection_ty = None; | ||
for (predicate, _) in self.tcx.predicates_of(def_id).predicates { | ||
if let ty::PredicateAtom::Projection(projection_predicate) = predicate.skip_binders() { | ||
if item_def_id == projection_predicate.projection_ty.item_def_id { | ||
projection_ty = Some(projection_predicate.projection_ty); | ||
break; | ||
} | ||
} | ||
} | ||
debug!("suggest_await_on_field_access: projection_ty={:?}", projection_ty); | ||
|
||
let cause = self.misc(expr.span); | ||
let mut selcx = SelectionContext::new(&self.infcx); | ||
|
||
let mut obligations = vec![]; | ||
if let Some(projection_ty) = projection_ty { | ||
let normalized_ty = rustc_trait_selection::traits::normalize_projection_type( | ||
&mut selcx, | ||
param_env, | ||
projection_ty, | ||
cause, | ||
0, | ||
&mut obligations, | ||
); |
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.
Is there a central place somewhere that we could define a helper to do this? I'd rather not duplicate it in all these places.
(If we can't extract the normalizing code that's fine, I'd prefer to, but we could just extract the parts before it.)
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.
Having a src/librustc_typeck/check/diagnostics.rs
would make sense, and would follow the pattern in other parts of the compiler.
I made a quick search for SelectionContext::new(
as I would imagine that any code doing this same thing would be using it, but I couldn't find any diagnostics use in typeck
.
@bors r+ |
📌 Commit 7cfcefd has been approved by |
☀️ Test successful - checks-actions, checks-azure |
These suggestions became dead code at some point (😩), but will be emitted again after #78214, except for the tuple field access and method calling ones. To avoid these kind of suggestion regressions it is best to annotate with |
When encountering a failing method or field resolution on a `Future`, look at the `Output` and try the same operation on it. If successful, suggest calling `.await` on the `Future`. This had already been introduced in rust-lang#72784, but at some point they stopped working.
When encountering a failing method or field resolution on a `Future`, look at the `Output` and try the same operation on it. If successful, suggest calling `.await` on the `Future`. This had already been introduced in rust-lang#72784, but at some point they stopped working.
Suggest calling await on method call and field access When encountering a failing method or field resolution on a `Future`, look at the `Output` and try the same operation on it. If successful, suggest calling `.await` on the `Future`. This had already been introduced in rust-lang#72784, but at some point they stopped working. Built on top of rust-lang#78214, only last commit is relevant. r? @oli-obk
Closes #61076
This PR suggests to
await
on:async_fn().bar() => async_fn().await.bar()
async_fn().field => async_fn().await.field
if let x = async() {} => if let x = async().await {}
r? @tmandry @estebank