Squash all commits.
add test for issue 86507 add stderr for issue 86507 update issue-86507 UI test add comment for the expected error in UI test file add proper 'refers to <ref_type>' in suggestion update diagnostic phrasing; update test to match new phrasing; re-organize logic for checking T: Sync evaluate additional obligation to figure out if T is Sync run './x.py test tidy --bless' incorporate changes from review; reorganize logic for readability
This commit is contained in:
parent
5c0ca08c66
commit
831ac19639
3 changed files with 78 additions and 5 deletions
|
@ -1857,12 +1857,37 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GeneratorInteriorOrUpvar::Upvar(upvar_span) => {
|
GeneratorInteriorOrUpvar::Upvar(upvar_span) => {
|
||||||
let mut span = MultiSpan::from_span(upvar_span);
|
// `Some(ref_ty)` if `target_ty` is `&T` and `T` fails to impl `Sync`
|
||||||
span.push_span_label(
|
let refers_to_non_sync = match target_ty.kind() {
|
||||||
upvar_span,
|
ty::Ref(_, ref_ty, _) => match self.evaluate_obligation(&obligation) {
|
||||||
|
Ok(eval) if !eval.may_apply() => Some(ref_ty),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (span_label, span_note) = match refers_to_non_sync {
|
||||||
|
// if `target_ty` is `&T` and `T` fails to impl `Sync`,
|
||||||
|
// include suggestions to make `T: Sync` so that `&T: Send`
|
||||||
|
Some(ref_ty) => (
|
||||||
|
format!(
|
||||||
|
"has type `{}` which {}, because `{}` is not `Sync`",
|
||||||
|
target_ty, trait_explanation, ref_ty
|
||||||
|
),
|
||||||
|
format!(
|
||||||
|
"captured value {} because `&` references cannot be sent unless their referent is `Sync`",
|
||||||
|
trait_explanation
|
||||||
|
),
|
||||||
|
),
|
||||||
|
None => (
|
||||||
format!("has type `{}` which {}", target_ty, trait_explanation),
|
format!("has type `{}` which {}", target_ty, trait_explanation),
|
||||||
);
|
format!("captured value {}", trait_explanation),
|
||||||
err.span_note(span, &format!("captured value {}", trait_explanation));
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut span = MultiSpan::from_span(upvar_span);
|
||||||
|
span.push_span_label(upvar_span, span_label);
|
||||||
|
err.span_note(span, &span_note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
src/test/ui/async-await/issue-86507.rs
Normal file
25
src/test/ui/async-await/issue-86507.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
use ::core::pin::Pin;
|
||||||
|
use ::core::future::Future;
|
||||||
|
use ::core::marker::Send;
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn bar<'me, 'async_trait, T: Send>(x: &'me T)
|
||||||
|
-> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
|
||||||
|
where 'me: 'async_trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for () {
|
||||||
|
fn bar<'me, 'async_trait, T: Send>(x: &'me T)
|
||||||
|
-> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
|
||||||
|
where 'me:'async_trait {
|
||||||
|
Box::pin( //~ ERROR future cannot be sent between threads safely
|
||||||
|
async move {
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
23
src/test/ui/async-await/issue-86507.stderr
Normal file
23
src/test/ui/async-await/issue-86507.stderr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
error: future cannot be sent between threads safely
|
||||||
|
--> $DIR/issue-86507.rs:17:13
|
||||||
|
|
|
||||||
|
LL | / Box::pin(
|
||||||
|
LL | | async move {
|
||||||
|
LL | | let x = x;
|
||||||
|
LL | | }
|
||||||
|
LL | | )
|
||||||
|
| |_____________^ future created by async block is not `Send`
|
||||||
|
|
|
||||||
|
note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
|
||||||
|
--> $DIR/issue-86507.rs:19:29
|
||||||
|
|
|
||||||
|
LL | let x = x;
|
||||||
|
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
|
||||||
|
= note: required for the cast to the object type `dyn Future<Output = ()> + Send`
|
||||||
|
help: consider further restricting type parameter `T`
|
||||||
|
|
|
||||||
|
LL | where 'me:'async_trait, T: std::marker::Sync {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue