Rollup merge of #98259 - jyn514:improve-obligation-errors, r=estebank
Greatly improve error reporting for futures and generators in `note_obligation_cause_code` Most futures don't go through this code path, because they're caught by `maybe_note_obligation_cause_for_async_await`. But all generators do, and `maybe_note` is imperfect and doesn't catch all futures. Improve the error message for those it misses. At some point, we may want to consider unifying this with the code for `maybe_note_async_await`, so that `async_await` notes all parent constraints, and `note_obligation` can point to yield points. But both functions are quite complicated, and it's not clear to me how to combine them; this seems like a good incremental improvement. Helps with https://github.com/rust-lang/rust/issues/97332. r? ``@estebank`` cc ``@eholk`` ``@compiler-errors``
This commit is contained in:
commit
413e350f87
21 changed files with 389 additions and 72 deletions
|
@ -8,6 +8,7 @@ use crate::infer::InferCtxt;
|
||||||
use crate::traits::normalize_to;
|
use crate::traits::normalize_to;
|
||||||
|
|
||||||
use hir::HirId;
|
use hir::HirId;
|
||||||
|
use rustc_ast::Movability;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
|
@ -2386,24 +2387,104 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
let parent_trait_ref =
|
let parent_trait_ref =
|
||||||
self.resolve_vars_if_possible(data.parent_trait_pred);
|
self.resolve_vars_if_possible(data.parent_trait_pred);
|
||||||
let ty = parent_trait_ref.skip_binder().self_ty();
|
let nested_ty = parent_trait_ref.skip_binder().self_ty();
|
||||||
matches!(ty.kind(), ty::Generator(..))
|
matches!(nested_ty.kind(), ty::Generator(..))
|
||||||
|| matches!(ty.kind(), ty::Closure(..))
|
|| matches!(nested_ty.kind(), ty::Closure(..))
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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
|
// Don't print the tuple of capture types
|
||||||
if !is_upvar_tys_infer_tuple {
|
'print: {
|
||||||
let msg = format!("required because it appears within the type `{}`", ty);
|
if !is_upvar_tys_infer_tuple {
|
||||||
match ty.kind() {
|
let msg = format!("required because it appears within the type `{}`", ty);
|
||||||
ty::Adt(def, _) => match self.tcx.opt_item_ident(def.did()) {
|
match ty.kind() {
|
||||||
Some(ident) => err.span_note(ident.span, &msg),
|
ty::Adt(def, _) => {
|
||||||
None => err.note(&msg),
|
// `gen_future` is used in all async functions; it doesn't add any additional info.
|
||||||
},
|
if self.tcx.is_diagnostic_item(sym::gen_future, def.did()) {
|
||||||
_ => err.note(&msg),
|
break 'print;
|
||||||
};
|
}
|
||||||
|
match self.tcx.opt_item_ident(def.did()) {
|
||||||
|
Some(ident) => err.span_note(ident.span, &msg),
|
||||||
|
None => err.note(&msg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::Opaque(def_id, _) => {
|
||||||
|
// Avoid printing the future from `core::future::from_generator`, it's not helpful
|
||||||
|
if tcx.parent(*def_id) == from_generator {
|
||||||
|
break 'print;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
debug!(
|
||||||
|
?obligated_types,
|
||||||
|
?is_future,
|
||||||
|
"note_obligation_cause_code: check for async fn"
|
||||||
|
);
|
||||||
|
if opaque_ty_is_future(def_id)
|
||||||
|
&& obligated_types.last().map_or(false, |ty| match ty.kind() {
|
||||||
|
ty::Opaque(last_def_id, _) => {
|
||||||
|
tcx.parent(*last_def_id) == from_generator
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
{
|
||||||
|
break 'print;
|
||||||
|
}
|
||||||
|
err.span_note(self.tcx.def_span(def_id), &msg)
|
||||||
|
}
|
||||||
|
ty::GeneratorWitness(bound_tys) => {
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
// FIXME: this is kind of an unusual format for rustc, can we make it more clear?
|
||||||
|
// Maybe we should just remove this note altogether?
|
||||||
|
// FIXME: only print types which don't meet the trait requirement
|
||||||
|
let mut msg =
|
||||||
|
"required because it captures the following types: ".to_owned();
|
||||||
|
for ty in bound_tys.skip_binder() {
|
||||||
|
write!(msg, "`{}`, ", ty).unwrap();
|
||||||
|
}
|
||||||
|
err.note(msg.trim_end_matches(", "))
|
||||||
|
}
|
||||||
|
ty::Generator(def_id, _, movability) => {
|
||||||
|
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"
|
||||||
|
};
|
||||||
|
err.span_note(
|
||||||
|
sp,
|
||||||
|
&format!("required because it's used within this {}", kind),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ty::Closure(def_id, _) => err.span_note(
|
||||||
|
self.tcx.def_span(def_id),
|
||||||
|
&format!("required because it's used within this closure"),
|
||||||
|
),
|
||||||
|
_ => err.note(&msg),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obligated_types.push(ty);
|
obligated_types.push(ty);
|
||||||
|
|
|
@ -42,15 +42,27 @@ LL | require_send(send_fut);
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
||||||
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
|
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
|
||||||
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]`
|
note: required because it's used within this async block
|
||||||
= note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>`
|
--> $DIR/issue-68112.rs:47:31
|
||||||
= note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
|
|
|
||||||
= note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
|
LL | async fn ready2<T>(t: T) -> T { t }
|
||||||
= note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
|
| ^^^^^
|
||||||
= note: required because it appears within the type `{ResumeTy, impl Future<Output = Arc<RefCell<i32>>>, (), i32, Ready<i32>}`
|
note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
|
||||||
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]`
|
--> $DIR/issue-68112.rs:48:31
|
||||||
= note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>`
|
|
|
||||||
= note: required because it appears within the type `impl Future<Output = ()>`
|
LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = Arc<RefCell<i32>>>`, `()`, `i32`, `Ready<i32>`
|
||||||
|
note: required because it's used within this async block
|
||||||
|
--> $DIR/issue-68112.rs:55:26
|
||||||
|
|
|
||||||
|
LL | let send_fut = async {
|
||||||
|
| __________________________^
|
||||||
|
LL | | let non_send_fut = make_non_send_future2();
|
||||||
|
LL | | let _ = non_send_fut.await;
|
||||||
|
LL | | ready(0).await;
|
||||||
|
LL | | };
|
||||||
|
| |_____^
|
||||||
note: required by a bound in `require_send`
|
note: required by a bound in `require_send`
|
||||||
--> $DIR/issue-68112.rs:11:25
|
--> $DIR/issue-68112.rs:11:25
|
||||||
|
|
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
error[E0277]: `Sender<i32>` cannot be shared between threads safely
|
||||||
|
--> $DIR/issue-70935-complex-spans.rs:13:45
|
||||||
|
|
|
||||||
|
LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ `Sender<i32>` cannot be shared between threads safely
|
||||||
|
|
|
||||||
|
= help: the trait `Sync` is not implemented for `Sender<i32>`
|
||||||
|
= note: required because of the requirements on the impl of `Send` for `&Sender<i32>`
|
||||||
|
note: required because it's used within this closure
|
||||||
|
--> $DIR/issue-70935-complex-spans.rs:25:13
|
||||||
|
|
|
||||||
|
LL | baz(|| async{
|
||||||
|
| _____________^
|
||||||
|
LL | | foo(tx.clone());
|
||||||
|
LL | | }).await;
|
||||||
|
| |_________^
|
||||||
|
note: required because it's used within this async block
|
||||||
|
--> $DIR/issue-70935-complex-spans.rs:9:67
|
||||||
|
|
|
||||||
|
LL | async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
|
||||||
|
| ___________________________________________________________________^
|
||||||
|
LL | |
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()`
|
||||||
|
note: required because it's used within this async block
|
||||||
|
--> $DIR/issue-70935-complex-spans.rs:23:16
|
||||||
|
|
|
||||||
|
LL | async move {
|
||||||
|
| ________________^
|
||||||
|
LL | |
|
||||||
|
LL | | baz(|| async{
|
||||||
|
LL | | foo(tx.clone());
|
||||||
|
LL | | }).await;
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -1,12 +1,12 @@
|
||||||
error: future cannot be sent between threads safely
|
error: future cannot be sent between threads safely
|
||||||
--> $DIR/issue-70935-complex-spans.rs:10:45
|
--> $DIR/issue-70935-complex-spans.rs:13:45
|
||||||
|
|
|
|
||||||
LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
|
LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
|
||||||
| ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
| ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `Sender<i32>`
|
= help: the trait `Sync` is not implemented for `Sender<i32>`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-70935-complex-spans.rs:15:11
|
--> $DIR/issue-70935-complex-spans.rs:27:11
|
||||||
|
|
|
|
||||||
LL | baz(|| async{
|
LL | baz(|| async{
|
||||||
| _____________-
|
| _____________-
|
||||||
|
@ -14,9 +14,9 @@ LL | | foo(tx.clone());
|
||||||
LL | | }).await;
|
LL | | }).await;
|
||||||
| | - ^^^^^^ await occurs here, with the value maybe used later
|
| | - ^^^^^^ await occurs here, with the value maybe used later
|
||||||
| |_________|
|
| |_________|
|
||||||
| has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send`
|
| has type `[closure@$DIR/issue-70935-complex-spans.rs:25:13: 27:10]` which is not `Send`
|
||||||
note: the value is later dropped here
|
note: the value is later dropped here
|
||||||
--> $DIR/issue-70935-complex-spans.rs:15:17
|
--> $DIR/issue-70935-complex-spans.rs:27:17
|
||||||
|
|
|
|
||||||
LL | }).await;
|
LL | }).await;
|
||||||
| ^
|
| ^
|
|
@ -1,16 +1,28 @@
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
// revisions: normal drop_tracking
|
||||||
|
// [drop_tracking]compile-flags:-Zdrop-tracking
|
||||||
// #70935: Check if we do not emit snippet
|
// #70935: Check if we do not emit snippet
|
||||||
// with newlines which lead complex diagnostics.
|
// with newlines which lead complex diagnostics.
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
|
async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
|
||||||
|
//[drop_tracking]~^ within this async block
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
|
fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
|
||||||
//~^ ERROR: future cannot be sent between threads safely
|
//[normal]~^ ERROR: future cannot be sent between threads safely
|
||||||
|
//[drop_tracking]~^^ ERROR: `Sender<i32>` cannot be shared
|
||||||
|
//[drop_tracking]~| NOTE: cannot be shared
|
||||||
|
//[drop_tracking]~| NOTE: requirements on the impl of `Send`
|
||||||
|
//[drop_tracking]~| NOTE: captures the following types
|
||||||
|
//[drop_tracking]~| NOTE: in this expansion
|
||||||
|
//[drop_tracking]~| NOTE: in this expansion
|
||||||
|
//[drop_tracking]~| NOTE: in this expansion
|
||||||
|
//[drop_tracking]~| NOTE: in this expansion
|
||||||
async move {
|
async move {
|
||||||
baz(|| async{
|
//[drop_tracking]~^ within this async block
|
||||||
|
baz(|| async{ //[drop_tracking]~ NOTE: used within this closure
|
||||||
foo(tx.clone());
|
foo(tx.clone());
|
||||||
}).await;
|
}).await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,15 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
gimme_send(foo());
|
gimme_send(foo());
|
||||||
//~^ ERROR cannot be sent between threads safely
|
//~^ ERROR cannot be sent between threads safely
|
||||||
|
//~| NOTE cannot be sent
|
||||||
|
//~| NOTE bound introduced by
|
||||||
|
//~| NOTE appears within the type
|
||||||
|
//~| NOTE captures the following types
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gimme_send<T: Send>(t: T) {
|
fn gimme_send<T: Send>(t: T) {
|
||||||
|
//~^ NOTE required by this bound
|
||||||
|
//~| NOTE required by a bound
|
||||||
drop(t);
|
drop(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +26,8 @@ impl Drop for NotSend {
|
||||||
impl !Send for NotSend {}
|
impl !Send for NotSend {}
|
||||||
|
|
||||||
async fn foo() {
|
async fn foo() {
|
||||||
|
//~^ NOTE used within this async block
|
||||||
|
//~| NOTE within this `impl Future
|
||||||
let mut x = (NotSend {},);
|
let mut x = (NotSend {},);
|
||||||
drop(x.0);
|
drop(x.0);
|
||||||
x.0 = NotSend {};
|
x.0 = NotSend {};
|
||||||
|
|
|
@ -11,13 +11,21 @@ LL | async fn foo() {
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend`
|
||||||
= note: required because it appears within the type `(NotSend,)`
|
= note: required because it appears within the type `(NotSend,)`
|
||||||
= note: required because it appears within the type `{ResumeTy, (NotSend,), impl Future<Output = ()>, ()}`
|
= note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future<Output = ()>`, `()`
|
||||||
= note: required because it appears within the type `[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]`
|
note: required because it's used within this async block
|
||||||
= note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]>`
|
--> $DIR/partial-drop-partial-reinit.rs:28:16
|
||||||
= note: required because it appears within the type `impl Future<Output = ()>`
|
|
|
||||||
= note: required because it appears within the type `impl Future<Output = ()>`
|
LL | async fn foo() {
|
||||||
|
| ________________^
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | let mut x = (NotSend {},);
|
||||||
|
... |
|
||||||
|
LL | | bar().await;
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
note: required by a bound in `gimme_send`
|
note: required by a bound in `gimme_send`
|
||||||
--> $DIR/partial-drop-partial-reinit.rs:10:18
|
--> $DIR/partial-drop-partial-reinit.rs:14:18
|
||||||
|
|
|
|
||||||
LL | fn gimme_send<T: Send>(t: T) {
|
LL | fn gimme_send<T: Send>(t: T) {
|
||||||
| ^^^^ required by this bound in `gimme_send`
|
| ^^^^ required by this bound in `gimme_send`
|
||||||
|
|
|
@ -6,7 +6,15 @@ LL | let t = thread::spawn(|| {
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
|
= help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
|
||||||
= note: required because of the requirements on the impl of `Send` for `&std::sync::mpsc::Receiver<()>`
|
= note: required because of the requirements on the impl of `Send` for `&std::sync::mpsc::Receiver<()>`
|
||||||
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6]`
|
note: required because it's used within this closure
|
||||||
|
--> $DIR/closure-move-sync.rs:6:27
|
||||||
|
|
|
||||||
|
LL | let t = thread::spawn(|| {
|
||||||
|
| ___________________________^
|
||||||
|
LL | | recv.recv().unwrap();
|
||||||
|
LL | |
|
||||||
|
LL | | });
|
||||||
|
| |_____^
|
||||||
note: required by a bound in `spawn`
|
note: required by a bound in `spawn`
|
||||||
--> $SRC_DIR/std/src/thread/mod.rs:LL:COL
|
--> $SRC_DIR/std/src/thread/mod.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
@ -21,7 +29,11 @@ LL | thread::spawn(|| tx.send(()).unwrap());
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `Sender<()>`
|
= help: the trait `Sync` is not implemented for `Sender<()>`
|
||||||
= note: required because of the requirements on the impl of `Send` for `&Sender<()>`
|
= note: required because of the requirements on the impl of `Send` for `&Sender<()>`
|
||||||
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:18:19: 18:42]`
|
note: required because it's used within this closure
|
||||||
|
--> $DIR/closure-move-sync.rs:18:19
|
||||||
|
|
|
||||||
|
LL | thread::spawn(|| tx.send(()).unwrap());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
note: required by a bound in `spawn`
|
note: required by a bound in `spawn`
|
||||||
--> $SRC_DIR/std/src/thread/mod.rs:LL:COL
|
--> $SRC_DIR/std/src/thread/mod.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
|
|
@ -20,6 +20,10 @@ pub fn make_gen1<T>(t: T) -> Ready<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn require_send(_: impl Send) {}
|
fn require_send(_: impl Send) {}
|
||||||
|
//~^ NOTE required by a bound
|
||||||
|
//~| NOTE required by a bound
|
||||||
|
//~| NOTE required by this bound
|
||||||
|
//~| NOTE required by this bound
|
||||||
|
|
||||||
fn make_non_send_generator() -> impl Generator<Return = Arc<RefCell<i32>>> {
|
fn make_non_send_generator() -> impl Generator<Return = Arc<RefCell<i32>>> {
|
||||||
make_gen1(Arc::new(RefCell::new(0)))
|
make_gen1(Arc::new(RefCell::new(0)))
|
||||||
|
@ -28,29 +32,39 @@ fn make_non_send_generator() -> impl Generator<Return = Arc<RefCell<i32>>> {
|
||||||
fn test1() {
|
fn test1() {
|
||||||
let send_gen = || {
|
let send_gen = || {
|
||||||
let _non_send_gen = make_non_send_generator();
|
let _non_send_gen = make_non_send_generator();
|
||||||
|
//~^ NOTE not `Send`
|
||||||
yield;
|
yield;
|
||||||
};
|
//~^ NOTE yield occurs here
|
||||||
|
//~| NOTE value is used across a yield
|
||||||
|
}; //~ NOTE later dropped here
|
||||||
require_send(send_gen);
|
require_send(send_gen);
|
||||||
//~^ ERROR generator cannot be sent between threads
|
//~^ ERROR generator cannot be sent between threads
|
||||||
|
//~| NOTE not `Send`
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
|
pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
|
||||||
|| {
|
//~^ NOTE appears within the type
|
||||||
|
//~| NOTE expansion of desugaring
|
||||||
|
|| { //~ NOTE used within this generator
|
||||||
yield;
|
yield;
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
|
fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> { //~ NOTE appears within the type
|
||||||
|
//~^ NOTE expansion of desugaring
|
||||||
make_gen2(Arc::new(RefCell::new(0)))
|
make_gen2(Arc::new(RefCell::new(0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test2() {
|
fn test2() {
|
||||||
let send_gen = || {
|
let send_gen = || { //~ NOTE used within this generator
|
||||||
let _non_send_gen = make_non_send_generator2();
|
let _non_send_gen = make_non_send_generator2();
|
||||||
yield;
|
yield;
|
||||||
};
|
};
|
||||||
require_send(send_gen);
|
require_send(send_gen);
|
||||||
//~^ ERROR `RefCell<i32>` cannot be shared between threads safely
|
//~^ ERROR `RefCell<i32>` cannot be shared between threads safely
|
||||||
|
//~| NOTE `RefCell<i32>` cannot be shared between threads safely
|
||||||
|
//~| NOTE requirements on the impl
|
||||||
|
//~| NOTE captures the following types
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
error: generator cannot be sent between threads safely
|
error: generator cannot be sent between threads safely
|
||||||
--> $DIR/issue-68112.rs:33:5
|
--> $DIR/issue-68112.rs:40:5
|
||||||
|
|
|
|
||||||
LL | require_send(send_gen);
|
LL | require_send(send_gen);
|
||||||
| ^^^^^^^^^^^^ generator is not `Send`
|
| ^^^^^^^^^^^^ generator is not `Send`
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
||||||
note: generator is not `Send` as this value is used across a yield
|
note: generator is not `Send` as this value is used across a yield
|
||||||
--> $DIR/issue-68112.rs:31:9
|
--> $DIR/issue-68112.rs:36:9
|
||||||
|
|
|
|
||||||
LL | let _non_send_gen = make_non_send_generator();
|
LL | let _non_send_gen = make_non_send_generator();
|
||||||
| ------------- has type `impl Generator<Return = Arc<RefCell<i32>>>` which is not `Send`
|
| ------------- has type `impl Generator<Return = Arc<RefCell<i32>>>` which is not `Send`
|
||||||
|
LL |
|
||||||
LL | yield;
|
LL | yield;
|
||||||
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
|
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
|
||||||
|
...
|
||||||
LL | };
|
LL | };
|
||||||
| - `_non_send_gen` is later dropped here
|
| - `_non_send_gen` is later dropped here
|
||||||
note: required by a bound in `require_send`
|
note: required by a bound in `require_send`
|
||||||
|
@ -21,18 +23,41 @@ LL | fn require_send(_: impl Send) {}
|
||||||
| ^^^^ required by this bound in `require_send`
|
| ^^^^ required by this bound in `require_send`
|
||||||
|
|
||||||
error[E0277]: `RefCell<i32>` cannot be shared between threads safely
|
error[E0277]: `RefCell<i32>` cannot be shared between threads safely
|
||||||
--> $DIR/issue-68112.rs:52:5
|
--> $DIR/issue-68112.rs:63:5
|
||||||
|
|
|
|
||||||
LL | require_send(send_gen);
|
LL | require_send(send_gen);
|
||||||
| ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
|
| ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
||||||
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
|
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
|
||||||
= note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6]`
|
note: required because it's used within this generator
|
||||||
= note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
|
--> $DIR/issue-68112.rs:48:5
|
||||||
= note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
|
|
|
||||||
= note: required because it appears within the type `{impl Generator<Return = Arc<RefCell<i32>>>, ()}`
|
LL | / || {
|
||||||
= note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6]`
|
LL | | yield;
|
||||||
|
LL | | t
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
|
||||||
|
--> $DIR/issue-68112.rs:45:30
|
||||||
|
|
|
||||||
|
LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
|
||||||
|
--> $DIR/issue-68112.rs:53:34
|
||||||
|
|
|
||||||
|
LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: required because it captures the following types: `impl Generator<Return = Arc<RefCell<i32>>>`, `()`
|
||||||
|
note: required because it's used within this generator
|
||||||
|
--> $DIR/issue-68112.rs:59:20
|
||||||
|
|
|
||||||
|
LL | let send_gen = || {
|
||||||
|
| ____________________^
|
||||||
|
LL | | let _non_send_gen = make_non_send_generator2();
|
||||||
|
LL | | yield;
|
||||||
|
LL | | };
|
||||||
|
| |_____^
|
||||||
note: required by a bound in `require_send`
|
note: required by a bound in `require_send`
|
||||||
--> $DIR/issue-68112.rs:22:25
|
--> $DIR/issue-68112.rs:22:25
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,7 +6,16 @@ LL | assert_send(|| {
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `Cell<i32>`
|
= help: the trait `Sync` is not implemented for `Cell<i32>`
|
||||||
= note: required because of the requirements on the impl of `Send` for `&Cell<i32>`
|
= note: required because of the requirements on the impl of `Send` for `&Cell<i32>`
|
||||||
= note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:16:17: 20:6]`
|
note: required because it's used within this generator
|
||||||
|
--> $DIR/not-send-sync.rs:16:17
|
||||||
|
|
|
||||||
|
LL | assert_send(|| {
|
||||||
|
| _________________^
|
||||||
|
LL | |
|
||||||
|
LL | | drop(&a);
|
||||||
|
LL | | yield;
|
||||||
|
LL | | });
|
||||||
|
| |_____^
|
||||||
note: required by a bound in `assert_send`
|
note: required by a bound in `assert_send`
|
||||||
--> $DIR/not-send-sync.rs:7:23
|
--> $DIR/not-send-sync.rs:7:23
|
||||||
|
|
|
|
||||||
|
|
|
@ -28,11 +28,34 @@ LL | require_send(send_gen);
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
||||||
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
|
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
|
||||||
= note: required because it appears within the type `[make_gen2<Arc<RefCell<i32>>>::{closure#0} upvar_tys=(Arc<RefCell<i32>>) {()}]`
|
note: required because it's used within this generator
|
||||||
= note: required because it appears within the type `Opaque(DefId(0:39 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
|
--> $DIR/generator-print-verbose-1.rs:42:5
|
||||||
= note: required because it appears within the type `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
|
|
|
||||||
= note: required because it appears within the type `{Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), []), ()}`
|
LL | / || {
|
||||||
= note: required because it appears within the type `[test2::{closure#0} upvar_tys=() {Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), []), ()}]`
|
LL | | yield;
|
||||||
|
LL | | t
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
note: required because it appears within the type `Opaque(DefId(0:39 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
|
||||||
|
--> $DIR/generator-print-verbose-1.rs:41:30
|
||||||
|
|
|
||||||
|
LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: required because it appears within the type `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
|
||||||
|
--> $DIR/generator-print-verbose-1.rs:47:34
|
||||||
|
|
|
||||||
|
LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: required because it captures the following types: `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
|
||||||
|
note: required because it's used within this generator
|
||||||
|
--> $DIR/generator-print-verbose-1.rs:52:20
|
||||||
|
|
|
||||||
|
LL | let send_gen = || {
|
||||||
|
| ____________________^
|
||||||
|
LL | | let _non_send_gen = make_non_send_generator2();
|
||||||
|
LL | | yield;
|
||||||
|
LL | | };
|
||||||
|
| |_____^
|
||||||
note: required by a bound in `require_send`
|
note: required by a bound in `require_send`
|
||||||
--> $DIR/generator-print-verbose-1.rs:26:25
|
--> $DIR/generator-print-verbose-1.rs:26:25
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,7 +6,16 @@ LL | assert_send(|| {
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `Cell<i32>`
|
= help: the trait `Sync` is not implemented for `Cell<i32>`
|
||||||
= note: required because of the requirements on the impl of `Send` for `&'_#4r Cell<i32>`
|
= note: required because of the requirements on the impl of `Send` for `&'_#4r Cell<i32>`
|
||||||
= note: required because it appears within the type `[main::{closure#1} upvar_tys=(&'_#4r Cell<i32>) _#17t]`
|
note: required because it's used within this generator
|
||||||
|
--> $DIR/generator-print-verbose-2.rs:19:17
|
||||||
|
|
|
||||||
|
LL | assert_send(|| {
|
||||||
|
| _________________^
|
||||||
|
LL | |
|
||||||
|
LL | | drop(&a);
|
||||||
|
LL | | yield;
|
||||||
|
LL | | });
|
||||||
|
| |_____^
|
||||||
note: required by a bound in `assert_send`
|
note: required by a bound in `assert_send`
|
||||||
--> $DIR/generator-print-verbose-2.rs:10:23
|
--> $DIR/generator-print-verbose-2.rs:10:23
|
||||||
|
|
|
|
||||||
|
|
|
@ -3,23 +3,37 @@ use std::rc::Rc;
|
||||||
|
|
||||||
// Fast path, main can see the concrete type returned.
|
// Fast path, main can see the concrete type returned.
|
||||||
fn before() -> impl Fn(i32) {
|
fn before() -> impl Fn(i32) {
|
||||||
|
//~^ NOTE within this `impl Fn
|
||||||
|
//~| NOTE within the type `impl Fn
|
||||||
|
//~| NOTE expansion of desugaring
|
||||||
let p = Rc::new(Cell::new(0));
|
let p = Rc::new(Cell::new(0));
|
||||||
move |x| p.set(x)
|
move |x| p.set(x) //~ NOTE used within this closure
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send<T: Send>(_: T) {}
|
fn send<T: Send>(_: T) {}
|
||||||
|
//~^ NOTE required by a bound
|
||||||
|
//~| NOTE required by a bound
|
||||||
|
//~| NOTE required by this bound
|
||||||
|
//~| NOTE required by this bound
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
send(before());
|
send(before());
|
||||||
//~^ ERROR `Rc<Cell<i32>>` cannot be sent between threads safely
|
//~^ ERROR `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||||
|
//~| NOTE `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||||
|
//~| NOTE required by a bound
|
||||||
|
|
||||||
send(after());
|
send(after());
|
||||||
//~^ ERROR `Rc<Cell<i32>>` cannot be sent between threads safely
|
//~^ ERROR `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||||
|
//~| NOTE `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||||
|
//~| NOTE required by a bound
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deferred path, main has to wait until typeck finishes,
|
// Deferred path, main has to wait until typeck finishes,
|
||||||
// to check if the return type of after is Send.
|
// to check if the return type of after is Send.
|
||||||
fn after() -> impl Fn(i32) {
|
fn after() -> impl Fn(i32) {
|
||||||
|
//~^ NOTE within this `impl Fn(i32)`
|
||||||
|
//~| NOTE in this expansion
|
||||||
|
//~| NOTE appears within the type
|
||||||
let p = Rc::new(Cell::new(0));
|
let p = Rc::new(Cell::new(0));
|
||||||
move |x| p.set(x)
|
move |x| p.set(x) //~ NOTE used within this closure
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0277]: `Rc<Cell<i32>>` cannot be sent between threads safely
|
error[E0277]: `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||||
--> $DIR/auto-trait-leak2.rs:13:10
|
--> $DIR/auto-trait-leak2.rs:20:10
|
||||||
|
|
|
|
||||||
LL | fn before() -> impl Fn(i32) {
|
LL | fn before() -> impl Fn(i32) {
|
||||||
| ------------ within this `impl Fn(i32)`
|
| ------------ within this `impl Fn(i32)`
|
||||||
|
@ -10,16 +10,24 @@ LL | send(before());
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
|
= help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
|
||||||
= note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22]`
|
note: required because it's used within this closure
|
||||||
= note: required because it appears within the type `impl Fn(i32)`
|
--> $DIR/auto-trait-leak2.rs:10:5
|
||||||
|
|
|
||||||
|
LL | move |x| p.set(x)
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
note: required because it appears within the type `impl Fn(i32)`
|
||||||
|
--> $DIR/auto-trait-leak2.rs:5:16
|
||||||
|
|
|
||||||
|
LL | fn before() -> impl Fn(i32) {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
note: required by a bound in `send`
|
note: required by a bound in `send`
|
||||||
--> $DIR/auto-trait-leak2.rs:10:12
|
--> $DIR/auto-trait-leak2.rs:13:12
|
||||||
|
|
|
|
||||||
LL | fn send<T: Send>(_: T) {}
|
LL | fn send<T: Send>(_: T) {}
|
||||||
| ^^^^ required by this bound in `send`
|
| ^^^^ required by this bound in `send`
|
||||||
|
|
||||||
error[E0277]: `Rc<Cell<i32>>` cannot be sent between threads safely
|
error[E0277]: `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||||
--> $DIR/auto-trait-leak2.rs:16:10
|
--> $DIR/auto-trait-leak2.rs:25:10
|
||||||
|
|
|
|
||||||
LL | send(after());
|
LL | send(after());
|
||||||
| ---- ^^^^^^^ `Rc<Cell<i32>>` cannot be sent between threads safely
|
| ---- ^^^^^^^ `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||||
|
@ -30,10 +38,18 @@ LL | fn after() -> impl Fn(i32) {
|
||||||
| ------------ within this `impl Fn(i32)`
|
| ------------ within this `impl Fn(i32)`
|
||||||
|
|
|
|
||||||
= help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
|
= help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
|
||||||
= note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22]`
|
note: required because it's used within this closure
|
||||||
= note: required because it appears within the type `impl Fn(i32)`
|
--> $DIR/auto-trait-leak2.rs:38:5
|
||||||
|
|
|
||||||
|
LL | move |x| p.set(x)
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
note: required because it appears within the type `impl Fn(i32)`
|
||||||
|
--> $DIR/auto-trait-leak2.rs:33:15
|
||||||
|
|
|
||||||
|
LL | fn after() -> impl Fn(i32) {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
note: required by a bound in `send`
|
note: required by a bound in `send`
|
||||||
--> $DIR/auto-trait-leak2.rs:10:12
|
--> $DIR/auto-trait-leak2.rs:13:12
|
||||||
|
|
|
|
||||||
LL | fn send<T: Send>(_: T) {}
|
LL | fn send<T: Send>(_: T) {}
|
||||||
| ^^^^ required by this bound in `send`
|
| ^^^^ required by this bound in `send`
|
||||||
|
|
|
@ -7,7 +7,11 @@ LL | catch_unwind(|| { x.set(23); });
|
||||||
= help: within `Cell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
|
= help: within `Cell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
|
||||||
= note: required because it appears within the type `Cell<i32>`
|
= note: required because it appears within the type `Cell<i32>`
|
||||||
= note: required because of the requirements on the impl of `UnwindSafe` for `&Cell<i32>`
|
= note: required because of the requirements on the impl of `UnwindSafe` for `&Cell<i32>`
|
||||||
= note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:5:18: 5:35]`
|
note: required because it's used within this closure
|
||||||
|
--> $DIR/interior-mutability.rs:5:18
|
||||||
|
|
|
||||||
|
LL | catch_unwind(|| { x.set(23); });
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
note: required by a bound in `catch_unwind`
|
note: required by a bound in `catch_unwind`
|
||||||
--> $SRC_DIR/std/src/panic.rs:LL:COL
|
--> $SRC_DIR/std/src/panic.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
|
|
@ -7,7 +7,11 @@ LL | bar(move|| foo(x));
|
||||||
| `Rc<usize>` cannot be sent between threads safely
|
| `Rc<usize>` cannot be sent between threads safely
|
||||||
|
|
|
|
||||||
= help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22]`, the trait `Send` is not implemented for `Rc<usize>`
|
= help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22]`, the trait `Send` is not implemented for `Rc<usize>`
|
||||||
= note: required because it appears within the type `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22]`
|
note: required because it's used within this closure
|
||||||
|
--> $DIR/kindck-nonsendable-1.rs:9:9
|
||||||
|
|
|
||||||
|
LL | bar(move|| foo(x));
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
note: required by a bound in `bar`
|
note: required by a bound in `bar`
|
||||||
--> $DIR/kindck-nonsendable-1.rs:5:21
|
--> $DIR/kindck-nonsendable-1.rs:5:21
|
||||||
|
|
|
|
||||||
|
|
|
@ -22,7 +22,16 @@ note: required because it appears within the type `Foo`
|
||||||
|
|
|
|
||||||
LL | struct Foo {
|
LL | struct Foo {
|
||||||
| ^^^
|
| ^^^
|
||||||
= note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6]`
|
note: required because it's used within this closure
|
||||||
|
--> $DIR/no-send-res-ports.rs:25:19
|
||||||
|
|
|
||||||
|
LL | thread::spawn(move|| {
|
||||||
|
| ___________________^
|
||||||
|
LL | |
|
||||||
|
LL | | let y = x;
|
||||||
|
LL | | println!("{:?}", y);
|
||||||
|
LL | | });
|
||||||
|
| |_____^
|
||||||
note: required by a bound in `spawn`
|
note: required by a bound in `spawn`
|
||||||
--> $SRC_DIR/std/src/thread/mod.rs:LL:COL
|
--> $SRC_DIR/std/src/thread/mod.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
|
|
@ -10,7 +10,14 @@ LL |
|
||||||
LL | let hello = hello.clone();
|
LL | let hello = hello.clone();
|
||||||
| ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 9:6]`, the trait `Clone` is not implemented for `S`
|
| ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 9:6]`, the trait `Clone` is not implemented for `S`
|
||||||
|
|
|
|
||||||
= note: required because it appears within the type `[closure@$DIR/not-clone-closure.rs:7:17: 9:6]`
|
note: required because it's used within this closure
|
||||||
|
--> $DIR/not-clone-closure.rs:7:17
|
||||||
|
|
|
||||||
|
LL | let hello = move || {
|
||||||
|
| _________________^
|
||||||
|
LL | | println!("Hello {}", a.0);
|
||||||
|
LL | | };
|
||||||
|
| |_____^
|
||||||
help: consider annotating `S` with `#[derive(Clone)]`
|
help: consider annotating `S` with `#[derive(Clone)]`
|
||||||
|
|
|
|
||||||
LL | #[derive(Clone)]
|
LL | #[derive(Clone)]
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
mod m {
|
mod m {
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
type Foo = impl std::fmt::Debug;
|
type Foo = impl std::fmt::Debug; //~ NOTE appears within the type
|
||||||
|
//~^ within this `Foo`
|
||||||
|
//~| expansion of desugaring
|
||||||
|
|
||||||
pub fn foo() -> Foo {
|
pub fn foo() -> Foo {
|
||||||
Rc::new(22_u32)
|
Rc::new(22_u32)
|
||||||
|
@ -12,8 +14,12 @@ mod m {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_send<T: Send>(_: T) {}
|
fn is_send<T: Send>(_: T) {}
|
||||||
|
//~^ required by this bound
|
||||||
|
//~| required by a bound
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
is_send(m::foo());
|
is_send(m::foo());
|
||||||
//~^ ERROR: `Rc<u32>` cannot be sent between threads safely [E0277]
|
//~^ ERROR: `Rc<u32>` cannot be sent between threads safely [E0277]
|
||||||
|
//~| NOTE cannot be sent
|
||||||
|
//~| NOTE required by a bound
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0277]: `Rc<u32>` cannot be sent between threads safely
|
error[E0277]: `Rc<u32>` cannot be sent between threads safely
|
||||||
--> $DIR/auto-trait-leakage2.rs:17:13
|
--> $DIR/auto-trait-leakage2.rs:21:13
|
||||||
|
|
|
|
||||||
LL | type Foo = impl std::fmt::Debug;
|
LL | type Foo = impl std::fmt::Debug;
|
||||||
| -------------------- within this `Foo`
|
| -------------------- within this `Foo`
|
||||||
|
@ -10,9 +10,13 @@ LL | is_send(m::foo());
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= help: within `Foo`, the trait `Send` is not implemented for `Rc<u32>`
|
= help: within `Foo`, the trait `Send` is not implemented for `Rc<u32>`
|
||||||
= note: required because it appears within the type `Foo`
|
note: required because it appears within the type `Foo`
|
||||||
|
--> $DIR/auto-trait-leakage2.rs:7:16
|
||||||
|
|
|
||||||
|
LL | type Foo = impl std::fmt::Debug;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
note: required by a bound in `is_send`
|
note: required by a bound in `is_send`
|
||||||
--> $DIR/auto-trait-leakage2.rs:14:15
|
--> $DIR/auto-trait-leakage2.rs:16:15
|
||||||
|
|
|
|
||||||
LL | fn is_send<T: Send>(_: T) {}
|
LL | fn is_send<T: Send>(_: T) {}
|
||||||
| ^^^^ required by this bound in `is_send`
|
| ^^^^ required by this bound in `is_send`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue