Skip to content

Commit

Permalink
Squash all commits.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
chazkiker2 committed Jul 22, 2021
1 parent 5c0ca08 commit 831ac19
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1857,12 +1857,37 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
GeneratorInteriorOrUpvar::Upvar(upvar_span) => {
// `Some(ref_ty)` if `target_ty` is `&T` and `T` fails to impl `Sync`
let refers_to_non_sync = match target_ty.kind() {
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!("captured value {}", trait_explanation),
),
};

let mut span = MultiSpan::from_span(upvar_span);
span.push_span_label(
upvar_span,
format!("has type `{}` which {}", target_ty, trait_explanation),
);
err.span_note(span, &format!("captured value {}", trait_explanation));
span.push_span_label(upvar_span, span_label);
err.span_note(span, &span_note);
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/test/ui/async-await/issue-86507.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions src/test/ui/async-await/issue-86507.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 831ac19

Please sign in to comment.