diff options
| author | Yuki Okushi <jtitor@2k36.org> | 2021-07-24 04:31:11 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-24 04:31:11 +0900 |
| commit | 3fc79fde63cfa8472e8c867c0a54de58cffb5cd0 (patch) | |
| tree | 3c2fd5582b70f542e5fb60d4826cb78097efd37a /compiler | |
| parent | 82a14e57e7754310dd78c08386d801a33555d2f6 (diff) | |
| parent | a1518f091552afdf370c699a359af0b7d34e402d (diff) | |
| download | rust-3fc79fde63cfa8472e8c867c0a54de58cffb5cd0.tar.gz rust-3fc79fde63cfa8472e8c867c0a54de58cffb5cd0.zip | |
Rollup merge of #87322 - chazkiker2:fix/suggestion-ref-sync-send, r=estebank
fix: clarify suggestion that `&T` must refer to `T: Sync` for `&T: Send` ### Description - [x] fix #86507 - [x] add UI test for relevant code from issue - [x] change `rustc_trait_selection/src/traits/error_reporting/suggestions.rs` to include a more clear suggestion when `&T` fails to satisfy `Send` bounds due to the fact that `T` fails to implement `Sync` - [x] update UI test in Clippy: `src/tools/tests/ui/future_not_send.stderr`
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs | 35 |
1 files changed, 30 insertions, 5 deletions
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 1c6a83b5783..9a33875d6e4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -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); } } |
