@@ -35,6 +35,7 @@ use rustc_hir::{ExprKind, QPath};
3535use  rustc_infer:: infer; 
3636use  rustc_infer:: infer:: type_variable:: { TypeVariableOrigin ,  TypeVariableOriginKind } ; 
3737use  rustc_infer:: infer:: InferOk ; 
38+ use  rustc_middle:: middle:: stability; 
3839use  rustc_middle:: ty:: adjustment:: { Adjust ,  Adjustment ,  AllowTwoPhase } ; 
3940use  rustc_middle:: ty:: error:: ExpectedFound ; 
4041use  rustc_middle:: ty:: error:: TypeError :: { FieldMisMatch ,  Sorts } ; 
@@ -1720,9 +1721,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17201721            _ => { 
17211722                // prevent all specified fields from being suggested 
17221723                let  skip_fields = skip_fields. iter ( ) . map ( |x| x. ident . name ) ; 
1723-                 if  let  Some ( field_name)  =
1724-                     Self :: suggest_field_name ( variant,  field. ident . name ,  skip_fields. collect ( ) ) 
1725-                 { 
1724+                 if  let  Some ( field_name)  = self . suggest_field_name ( 
1725+                     variant, 
1726+                     field. ident . name , 
1727+                     skip_fields. collect ( ) , 
1728+                     expr_span, 
1729+                 )  { 
17261730                    err. span_suggestion ( 
17271731                        field. ident . span , 
17281732                        "a field with a similar name exists" , 
@@ -1743,7 +1747,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17431747                                    format ! ( "`{}` does not have this field" ,  ty) , 
17441748                                ) ; 
17451749                            } 
1746-                             let  available_field_names = self . available_field_names ( variant) ; 
1750+                             let  available_field_names =
1751+                                 self . available_field_names ( variant,  expr_span) ; 
17471752                            if  !available_field_names. is_empty ( )  { 
17481753                                err. note ( & format ! ( 
17491754                                    "available fields are: {}" , 
@@ -1759,19 +1764,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17591764        err. emit ( ) ; 
17601765    } 
17611766
1762-     // Return an  hint about the closest match in field names 
1767+     // Return a  hint about the closest match in field names 
17631768    fn  suggest_field_name ( 
1769+         & self , 
17641770        variant :  & ' tcx  ty:: VariantDef , 
17651771        field :  Symbol , 
17661772        skip :  Vec < Symbol > , 
1773+         // The span where stability will be checked 
1774+         span :  Span , 
17671775    )  -> Option < Symbol >  { 
17681776        let  names = variant
17691777            . fields 
17701778            . iter ( ) 
17711779            . filter_map ( |field| { 
17721780                // ignore already set fields and private fields from non-local crates 
1781+                 // and unstable fields. 
17731782                if  skip. iter ( ) . any ( |& x| x == field. name ) 
17741783                    || ( !variant. def_id . is_local ( )  && !field. vis . is_public ( ) ) 
1784+                     || matches ! ( 
1785+                         self . tcx. eval_stability( field. did,  None ,  span,  None ) , 
1786+                         stability:: EvalResult :: Deny  {  .. } 
1787+                     ) 
17751788                { 
17761789                    None 
17771790                }  else  { 
@@ -1783,7 +1796,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17831796        find_best_match_for_name ( & names,  field,  None ) 
17841797    } 
17851798
1786-     fn  available_field_names ( & self ,  variant :  & ' tcx  ty:: VariantDef )  -> Vec < Symbol >  { 
1799+     fn  available_field_names ( 
1800+         & self , 
1801+         variant :  & ' tcx  ty:: VariantDef , 
1802+         access_span :  Span , 
1803+     )  -> Vec < Symbol >  { 
17871804        variant
17881805            . fields 
17891806            . iter ( ) 
@@ -1793,6 +1810,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17931810                    . adjust_ident_and_get_scope ( field. ident ( self . tcx ) ,  variant. def_id ,  self . body_id ) 
17941811                    . 1 ; 
17951812                field. vis . is_accessible_from ( def_scope,  self . tcx ) 
1813+                     && !matches ! ( 
1814+                         self . tcx. eval_stability( field. did,  None ,  access_span,  None ) , 
1815+                         stability:: EvalResult :: Deny  {  .. } 
1816+                     ) 
17961817            } ) 
17971818            . filter ( |field| !self . tcx . is_doc_hidden ( field. did ) ) 
17981819            . map ( |field| field. name ) 
@@ -1959,7 +1980,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19591980                self . suggest_first_deref_field ( & mut  err,  expr,  base,  field) ; 
19601981            } 
19611982            ty:: Adt ( def,  _)  if  !def. is_enum ( )  => { 
1962-                 self . suggest_fields_on_recordish ( & mut  err,  def,  field) ; 
1983+                 self . suggest_fields_on_recordish ( & mut  err,  def,  field,  expr . span ) ; 
19631984            } 
19641985            ty:: Param ( param_ty)  => { 
19651986                self . point_at_param_definition ( & mut  err,  param_ty) ; 
@@ -2122,9 +2143,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21222143        err :  & mut  DiagnosticBuilder < ' _ > , 
21232144        def :  & ' tcx  ty:: AdtDef , 
21242145        field :  Ident , 
2146+         access_span :  Span , 
21252147    )  { 
21262148        if  let  Some ( suggested_field_name)  =
2127-             Self :: suggest_field_name ( def. non_enum_variant ( ) ,  field. name ,  vec ! [ ] ) 
2149+             self . suggest_field_name ( def. non_enum_variant ( ) ,  field. name ,  vec ! [ ] ,  access_span ) 
21282150        { 
21292151            err. span_suggestion ( 
21302152                field. span , 
@@ -2135,7 +2157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21352157        }  else  { 
21362158            err. span_label ( field. span ,  "unknown field" ) ; 
21372159            let  struct_variant_def = def. non_enum_variant ( ) ; 
2138-             let  field_names = self . available_field_names ( struct_variant_def) ; 
2160+             let  field_names = self . available_field_names ( struct_variant_def,  access_span ) ; 
21392161            if  !field_names. is_empty ( )  { 
21402162                err. note ( & format ! ( 
21412163                    "available fields are: {}" , 
0 commit comments