From b052d76586988040c6ae8aef609794ae16cc28dc Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 21 Jun 2022 19:43:46 -0500 Subject: [PATCH] Address review comments from #98259 It got merged so fast I didn't have time to make changes xD --- compiler/rustc_middle/src/ty/context.rs | 16 +++++++++++- .../src/traits/error_reporting/suggestions.rs | 26 +++---------------- src/test/ui/async-await/issue-68112.stderr | 4 +-- ...e-70935-complex-spans.drop_tracking.stderr | 4 +-- .../async-await/issue-70935-complex-spans.rs | 4 +-- .../partial-drop-partial-reinit.rs | 2 +- .../partial-drop-partial-reinit.stderr | 2 +- 7 files changed, 27 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c43cf07b3ad0a..0765928e9b95c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -74,7 +74,7 @@ use std::mem; use std::ops::{Bound, Deref}; use std::sync::Arc; -use super::RvalueScopes; +use super::{ImplPolarity, RvalueScopes}; pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { /// Creates a new `OnDiskCache` instance from the serialized data in `data`. @@ -2224,6 +2224,20 @@ impl<'tcx> TyCtxt<'tcx> { }) } + /// Given a `ty`, return whether it's an `impl Future<...>`. + pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { + let ty::Opaque(def_id, _) = ty.kind() else { return false }; + let future_trait = self.lang_items().future_trait().unwrap(); + + self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { + let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { + return false; + }; + trait_predicate.trait_ref.def_id == future_trait + && trait_predicate.polarity == ImplPolarity::Positive + }) + } + /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used /// to identify which traits may define a given associated type to help avoid cycle errors. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 159fcf932a1da..19318a85a0125 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -8,7 +8,6 @@ use crate::infer::InferCtxt; use crate::traits::normalize_to; use hir::HirId; -use rustc_ast::Movability; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ @@ -2406,19 +2405,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } }; - let future_trait = self.tcx.lang_items().future_trait().unwrap(); - let opaque_ty_is_future = |def_id| { - self.tcx.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { - if let ty::PredicateKind::Trait(trait_predicate) = - predicate.kind().skip_binder() - { - trait_predicate.trait_ref.def_id == future_trait - } else { - false - } - }) - }; - let from_generator = tcx.lang_items().from_generator_fn().unwrap(); // Don't print the tuple of capture types @@ -2444,13 +2430,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // If the previous type is `from_generator`, this is the future generated by the body of an async function. // Avoid printing it twice (it was already printed in the `ty::Generator` arm below). - let is_future = opaque_ty_is_future(def_id); + let is_future = tcx.ty_is_opaque_future(ty); debug!( ?obligated_types, ?is_future, "note_obligation_cause_code: check for async fn" ); - if opaque_ty_is_future(def_id) + if is_future && obligated_types.last().map_or(false, |ty| match ty.kind() { ty::Opaque(last_def_id, _) => { tcx.parent(*last_def_id) == from_generator @@ -2475,15 +2461,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } err.note(msg.trim_end_matches(", ")) } - ty::Generator(def_id, _, movability) => { + ty::Generator(def_id, _, _) => { let sp = self.tcx.def_span(def_id); // Special-case this to say "async block" instead of `[static generator]`. - let kind = if *movability == Movability::Static { - "async block" - } else { - "generator" - }; + let kind = tcx.generator_kind(def_id).unwrap(); err.span_note( sp, &format!("required because it's used within this {}", kind), diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr index b8d3e1540d8a9..4285fbbeceb60 100644 --- a/src/test/ui/async-await/issue-68112.stderr +++ b/src/test/ui/async-await/issue-68112.stderr @@ -42,7 +42,7 @@ LL | require_send(send_fut); | = help: the trait `Sync` is not implemented for `RefCell` = note: required because of the requirements on the impl of `Send` for `Arc>` -note: required because it's used within this async block +note: required because it's used within this `async fn` body --> $DIR/issue-68112.rs:47:31 | LL | async fn ready2(t: T) -> T { t } @@ -53,7 +53,7 @@ note: required because it appears within the type `impl Future impl Future>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: required because it captures the following types: `ResumeTy`, `impl Future>>`, `()`, `i32`, `Ready` -note: required because it's used within this async block +note: required because it's used within this `async` block --> $DIR/issue-68112.rs:55:26 | LL | let send_fut = async { diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr index 19fd5eb7c73fb..43b7cb8cece36 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr @@ -14,7 +14,7 @@ LL | baz(|| async{ LL | | foo(tx.clone()); LL | | }).await; | |_________^ -note: required because it's used within this async block +note: required because it's used within this `async fn` body --> $DIR/issue-70935-complex-spans.rs:9:67 | LL | async fn baz(_c: impl FnMut() -> T) where T: Future { @@ -23,7 +23,7 @@ LL | | LL | | } | |_^ = note: required because it captures the following types: `ResumeTy`, `impl Future`, `()` -note: required because it's used within this async block +note: required because it's used within this `async` block --> $DIR/issue-70935-complex-spans.rs:23:16 | LL | async move { diff --git a/src/test/ui/async-await/issue-70935-complex-spans.rs b/src/test/ui/async-await/issue-70935-complex-spans.rs index 4bf94fe342c1d..f45ce1f25efa0 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.rs +++ b/src/test/ui/async-await/issue-70935-complex-spans.rs @@ -7,7 +7,7 @@ use std::future::Future; async fn baz(_c: impl FnMut() -> T) where T: Future { -//[drop_tracking]~^ within this async block +//[drop_tracking]~^ within this `async fn` body } fn foo(tx: std::sync::mpsc::Sender) -> impl Future + Send { @@ -21,7 +21,7 @@ fn foo(tx: std::sync::mpsc::Sender) -> impl Future + Send { //[drop_tracking]~| NOTE: in this expansion //[drop_tracking]~| NOTE: in this expansion async move { - //[drop_tracking]~^ within this async block + //[drop_tracking]~^ within this `async` block baz(|| async{ //[drop_tracking]~ NOTE: used within this closure foo(tx.clone()); }).await; diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.rs b/src/test/ui/async-await/partial-drop-partial-reinit.rs index 4fcfacea3f886..fe0fce7afd9f9 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.rs +++ b/src/test/ui/async-await/partial-drop-partial-reinit.rs @@ -26,7 +26,7 @@ impl Drop for NotSend { impl !Send for NotSend {} async fn foo() { -//~^ NOTE used within this async block +//~^ NOTE used within this `async fn` body //~| NOTE within this `impl Future let mut x = (NotSend {},); drop(x.0); diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.stderr index 96d0c71f103fb..05f5358340a98 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.stderr +++ b/src/test/ui/async-await/partial-drop-partial-reinit.stderr @@ -12,7 +12,7 @@ LL | async fn foo() { = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` = note: required because it appears within the type `(NotSend,)` = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future`, `()` -note: required because it's used within this async block +note: required because it's used within this `async fn` body --> $DIR/partial-drop-partial-reinit.rs:28:16 | LL | async fn foo() {