@@ -42,7 +42,7 @@ use rustc_middle::ty::{AdtKind, Visibility};
4242use rustc_span:: hygiene:: DesugaringKind ;
4343use rustc_span:: source_map:: Span ;
4444use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
45- use rustc_trait_selection:: traits:: { self , ObligationCauseCode , SelectionContext } ;
45+ use rustc_trait_selection:: traits:: { self , ObligationCauseCode } ;
4646
4747use std:: fmt:: Display ;
4848
@@ -1583,51 +1583,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15831583 err : & mut DiagnosticBuilder < ' _ > ,
15841584 field_ident : Ident ,
15851585 base : & ' tcx hir:: Expr < ' tcx > ,
1586- expr : & ' tcx hir:: Expr < ' tcx > ,
1587- def_id : DefId ,
1586+ ty : Ty < ' tcx > ,
15881587 ) {
1589- let param_env = self . tcx ( ) . param_env ( def_id) ;
1590- let future_trait = self . tcx . require_lang_item ( LangItem :: Future , None ) ;
1591- // Future::Output
1592- let item_def_id =
1593- self . tcx . associated_items ( future_trait) . in_definition_order ( ) . next ( ) . unwrap ( ) . def_id ;
1594-
1595- let projection_ty = self . tcx . projection_ty_from_predicates ( ( def_id, item_def_id) ) ;
1596- debug ! ( "suggest_await_on_field_access: projection_ty={:?}" , projection_ty) ;
1597-
1598- let cause = self . misc ( expr. span ) ;
1599- let mut selcx = SelectionContext :: new ( & self . infcx ) ;
1600-
1601- let mut obligations = vec ! [ ] ;
1602- if let Some ( projection_ty) = projection_ty {
1603- let normalized_ty = rustc_trait_selection:: traits:: normalize_projection_type (
1604- & mut selcx,
1605- param_env,
1606- projection_ty,
1607- cause,
1608- 0 ,
1609- & mut obligations,
1610- ) ;
1611- debug ! (
1612- "suggest_await_on_field_access: normalized_ty={:?}, ty_kind={:?}" ,
1613- self . resolve_vars_if_possible( & normalized_ty) ,
1614- normalized_ty. kind( ) ,
1615- ) ;
1616- if let ty:: Adt ( def, _) = normalized_ty. kind ( ) {
1617- // no field access on enum type
1618- if !def. is_enum ( ) {
1619- if def. non_enum_variant ( ) . fields . iter ( ) . any ( |field| field. ident == field_ident)
1620- {
1621- err. span_suggestion_verbose (
1622- base. span . shrink_to_hi ( ) ,
1623- "consider awaiting before field access" ,
1624- ".await" . to_string ( ) ,
1625- Applicability :: MaybeIncorrect ,
1626- ) ;
1627- }
1588+ let output_ty = match self . infcx . get_impl_future_output_ty ( ty) {
1589+ Some ( output_ty) => self . resolve_vars_if_possible ( & output_ty) ,
1590+ _ => return ,
1591+ } ;
1592+ let mut add_label = true ;
1593+ if let ty:: Adt ( def, _) = output_ty. kind ( ) {
1594+ // no field access on enum type
1595+ if !def. is_enum ( ) {
1596+ if def. non_enum_variant ( ) . fields . iter ( ) . any ( |field| field. ident == field_ident) {
1597+ add_label = false ;
1598+ err. span_label (
1599+ field_ident. span ,
1600+ "field not available in `impl Future`, but it is available in its `Output`" ,
1601+ ) ;
1602+ err. span_suggestion_verbose (
1603+ base. span . shrink_to_hi ( ) ,
1604+ "consider `await`ing on the `Future` and access the field of its `Output`" ,
1605+ ".await" . to_string ( ) ,
1606+ Applicability :: MaybeIncorrect ,
1607+ ) ;
16281608 }
16291609 }
16301610 }
1611+ if add_label {
1612+ err. span_label ( field_ident. span , & format ! ( "field not found in `{}`" , ty) ) ;
1613+ }
16311614 }
16321615
16331616 fn ban_nonexisting_field (
@@ -1656,8 +1639,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16561639 ty:: Param ( param_ty) => {
16571640 self . point_at_param_definition ( & mut err, param_ty) ;
16581641 }
1659- ty:: Opaque ( def_id , _) => {
1660- self . suggest_await_on_field_access ( & mut err, field, base, expr , def_id ) ;
1642+ ty:: Opaque ( _ , _) => {
1643+ self . suggest_await_on_field_access ( & mut err, field, base, expr_t . peel_refs ( ) ) ;
16611644 }
16621645 _ => { }
16631646 }
0 commit comments