@@ -34,6 +34,7 @@ use rustc::util::nodemap::NodeSet;
3434use syntax:: ast:: { self , CRATE_NODE_ID , Ident } ;
3535use syntax:: symbol:: keywords;
3636use syntax_pos:: Span ;
37+ use syntax_pos:: hygiene:: SyntaxContext ;
3738
3839use std:: cmp;
3940use std:: mem:: replace;
@@ -491,9 +492,13 @@ struct NamePrivacyVisitor<'a, 'tcx: 'a> {
491492}
492493
493494impl < ' a , ' tcx > NamePrivacyVisitor < ' a , ' tcx > {
494- // Checks that a field is accessible.
495- fn check_field ( & mut self , span : Span , def : & ' tcx ty:: AdtDef , field : & ' tcx ty:: FieldDef ) {
496- let ident = Ident { ctxt : span. ctxt ( ) . modern ( ) , ..keywords:: Invalid . ident ( ) } ;
495+ // Checks that a field in a struct constructor (expression or pattern) is accessible.
496+ fn check_field ( & mut self ,
497+ use_ctxt : SyntaxContext , // Syntax context of the field name at the use site
498+ span : Span , // Span of the field pattern, e.g. `x: 0`
499+ def : & ' tcx ty:: AdtDef , // Definition of the struct or enum
500+ field : & ' tcx ty:: FieldDef ) { // Definition of the field
501+ let ident = Ident { ctxt : use_ctxt. modern ( ) , ..keywords:: Invalid . ident ( ) } ;
497502 let def_id = self . tcx . adjust_ident ( ident, def. did , self . current_item ) . 1 ;
498503 if !def. is_enum ( ) && !field. vis . is_accessible_from ( def_id, self . tcx ) {
499504 struct_span_err ! ( self . tcx. sess, span, E0451 , "field `{}` of {} `{}` is private" ,
@@ -566,12 +571,17 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
566571 // unmentioned fields, just check them all.
567572 for variant_field in & variant. fields {
568573 let field = fields. iter ( ) . find ( |f| f. name . node == variant_field. name ) ;
569- let span = if let Some ( f) = field { f. span } else { base. span } ;
570- self . check_field ( span, adt, variant_field) ;
574+ let ( use_ctxt, span) = match field {
575+ Some ( field) => ( field. name . node . to_ident ( ) . ctxt , field. span ) ,
576+ None => ( base. span . ctxt ( ) , base. span ) ,
577+ } ;
578+ self . check_field ( use_ctxt, span, adt, variant_field) ;
571579 }
572580 } else {
573581 for field in fields {
574- self . check_field ( field. span , adt, variant. field_named ( field. name . node ) ) ;
582+ let use_ctxt = field. name . node . to_ident ( ) . ctxt ;
583+ let field_def = variant. field_named ( field. name . node ) ;
584+ self . check_field ( use_ctxt, field. span , adt, field_def) ;
575585 }
576586 }
577587 }
@@ -588,7 +598,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
588598 let adt = self . tables . pat_ty ( pat) . ty_adt_def ( ) . unwrap ( ) ;
589599 let variant = adt. variant_of_def ( def) ;
590600 for field in fields {
591- self . check_field ( field. span , adt, variant. field_named ( field. node . name ) ) ;
601+ let use_ctxt = field. node . name . to_ident ( ) . ctxt ;
602+ let field_def = variant. field_named ( field. node . name ) ;
603+ self . check_field ( use_ctxt, field. span , adt, field_def) ;
592604 }
593605 }
594606 _ => { }
0 commit comments