@@ -3594,52 +3594,64 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
3594
3594
trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
3595
3595
span : Span ,
3596
3596
) {
3597
- if let Some ( hir:: CoroutineKind :: Desugared ( hir:: CoroutineDesugaring :: Async , _) ) =
3598
- self . tcx . coroutine_kind ( obligation. cause . body_id )
3599
- {
3600
- let future_trait = self . tcx . require_lang_item ( LangItem :: Future , None ) ;
3597
+ let future_trait = self . tcx . require_lang_item ( LangItem :: Future , None ) ;
3601
3598
3602
- let self_ty = self . resolve_vars_if_possible ( trait_pred. self_ty ( ) ) ;
3603
- let impls_future = self . type_implements_trait (
3604
- future_trait,
3605
- [ self . tcx . instantiate_bound_regions_with_erased ( self_ty) ] ,
3606
- obligation. param_env ,
3607
- ) ;
3608
- if !impls_future. must_apply_modulo_regions ( ) {
3609
- return ;
3610
- }
3599
+ let self_ty = self . resolve_vars_if_possible ( trait_pred. self_ty ( ) ) ;
3600
+ let impls_future = self . type_implements_trait (
3601
+ future_trait,
3602
+ [ self . tcx . instantiate_bound_regions_with_erased ( self_ty) ] ,
3603
+ obligation. param_env ,
3604
+ ) ;
3605
+ if !impls_future. must_apply_modulo_regions ( ) {
3606
+ return ;
3607
+ }
3611
3608
3612
- let item_def_id = self . tcx . associated_item_def_ids ( future_trait) [ 0 ] ;
3613
- // `<T as Future>::Output`
3614
- let projection_ty = trait_pred. map_bound ( |trait_pred| {
3615
- Ty :: new_projection (
3616
- self . tcx ,
3617
- item_def_id,
3618
- // Future::Output has no args
3619
- [ trait_pred. self_ty ( ) ] ,
3620
- )
3621
- } ) ;
3622
- let InferOk { value : projection_ty, .. } =
3623
- self . at ( & obligation. cause , obligation. param_env ) . normalize ( projection_ty) ;
3609
+ let item_def_id = self . tcx . associated_item_def_ids ( future_trait) [ 0 ] ;
3610
+ // `<T as Future>::Output`
3611
+ let projection_ty = trait_pred. map_bound ( |trait_pred| {
3612
+ Ty :: new_projection (
3613
+ self . tcx ,
3614
+ item_def_id,
3615
+ // Future::Output has no args
3616
+ [ trait_pred. self_ty ( ) ] ,
3617
+ )
3618
+ } ) ;
3619
+ let InferOk { value : projection_ty, .. } =
3620
+ self . at ( & obligation. cause , obligation. param_env ) . normalize ( projection_ty) ;
3624
3621
3625
- debug ! (
3626
- normalized_projection_type = ?self . resolve_vars_if_possible( projection_ty)
3627
- ) ;
3628
- let try_obligation = self . mk_trait_obligation_with_new_self_ty (
3629
- obligation. param_env ,
3630
- trait_pred. map_bound ( |trait_pred| ( trait_pred, projection_ty. skip_binder ( ) ) ) ,
3631
- ) ;
3632
- debug ! ( try_trait_obligation = ?try_obligation) ;
3633
- if self . predicate_may_hold ( & try_obligation)
3634
- && let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span)
3635
- && snippet. ends_with ( '?' )
3636
- {
3637
- err. span_suggestion_verbose (
3638
- span. with_hi ( span. hi ( ) - BytePos ( 1 ) ) . shrink_to_hi ( ) ,
3639
- "consider `await`ing on the `Future`" ,
3640
- ".await" ,
3641
- Applicability :: MaybeIncorrect ,
3642
- ) ;
3622
+ debug ! (
3623
+ normalized_projection_type = ?self . resolve_vars_if_possible( projection_ty)
3624
+ ) ;
3625
+ let try_obligation = self . mk_trait_obligation_with_new_self_ty (
3626
+ obligation. param_env ,
3627
+ trait_pred. map_bound ( |trait_pred| ( trait_pred, projection_ty. skip_binder ( ) ) ) ,
3628
+ ) ;
3629
+ debug ! ( try_trait_obligation = ?try_obligation) ;
3630
+ if self . predicate_may_hold ( & try_obligation)
3631
+ && let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span)
3632
+ && snippet. ends_with ( '?' )
3633
+ {
3634
+ match self . tcx . coroutine_kind ( obligation. cause . body_id ) {
3635
+ Some ( hir:: CoroutineKind :: Desugared ( hir:: CoroutineDesugaring :: Async , _) ) => {
3636
+ err. span_suggestion_verbose (
3637
+ span. with_hi ( span. hi ( ) - BytePos ( 1 ) ) . shrink_to_hi ( ) ,
3638
+ "consider `await`ing on the `Future`" ,
3639
+ ".await" ,
3640
+ Applicability :: MaybeIncorrect ,
3641
+ ) ;
3642
+ }
3643
+ _ => {
3644
+ let mut span: MultiSpan = span. with_lo ( span. hi ( ) - BytePos ( 1 ) ) . into ( ) ;
3645
+ span. push_span_label (
3646
+ self . tcx . def_span ( obligation. cause . body_id ) ,
3647
+ "this is not `async`" ,
3648
+ ) ;
3649
+ err. span_note (
3650
+ span,
3651
+ "this implements `Future` and its output type supports \
3652
+ `?`, but the future cannot be awaited in a synchronous function",
3653
+ ) ;
3654
+ }
3643
3655
}
3644
3656
}
3645
3657
}
0 commit comments