@@ -3594,52 +3594,64 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
35943594 trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
35953595 span : Span ,
35963596 ) {
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 ) ;
36013598
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+ }
36113608
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) ;
36243621
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+ }
36433655 }
36443656 }
36453657 }
0 commit comments