@@ -34,7 +34,6 @@ use self::FieldName::*;
34
34
use std:: mem:: replace;
35
35
36
36
use rustc:: ast_map;
37
- use rustc:: metadata:: csearch;
38
37
use rustc:: middle:: def;
39
38
use rustc:: middle:: privacy:: ImportUse :: * ;
40
39
use rustc:: middle:: privacy:: LastPrivate :: * ;
@@ -688,29 +687,26 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
688
687
// Checks that a field is in scope.
689
688
fn check_field ( & mut self ,
690
689
span : Span ,
691
- id : ast:: DefId ,
690
+ def : & ' tcx ty:: ADTDef < ' tcx > ,
691
+ v : & ' tcx ty:: VariantDef < ' tcx > ,
692
692
name : FieldName ) {
693
- // TODO: refactor to variant API
694
- let fields = self . tcx . lookup_struct_fields ( id) ;
695
693
let field = match name {
696
694
NamedField ( f_name) => {
697
- debug ! ( "privacy - check named field {} in struct {:?}" , f_name, id ) ;
698
- fields . iter ( ) . find ( |f| f . name == f_name) . unwrap ( )
695
+ debug ! ( "privacy - check named field {} in struct {:?}" , f_name, def ) ;
696
+ v . field_named ( f_name)
699
697
}
700
- UnnamedField ( idx) => & fields[ idx]
698
+ UnnamedField ( idx) => & v . fields [ idx]
701
699
} ;
702
700
if field. vis == ast:: Public ||
703
- ( is_local ( field. id ) && self . private_accessible ( field. id . node ) ) {
701
+ ( is_local ( field. did ) && self . private_accessible ( field. did . node ) ) {
704
702
return
705
703
}
706
704
707
- let struct_type = self . tcx . lookup_item_type ( id) . ty ;
708
- let struct_desc = match struct_type. sty {
709
- ty:: TyStruct ( _, _) =>
710
- format ! ( "struct `{}`" , self . tcx. item_path_str( id) ) ,
705
+ let struct_desc = match def. adt_kind ( ) {
706
+ ty:: ADTKind :: Struct =>
707
+ format ! ( "struct `{}`" , self . tcx. item_path_str( def. did) ) ,
711
708
// struct variant fields have inherited visibility
712
- ty:: TyEnum ( ..) => return ,
713
- _ => self . tcx . sess . span_bug ( span, "can't find struct for field" )
709
+ ty:: ADTKind :: Enum => return
714
710
} ;
715
711
let msg = match name {
716
712
NamedField ( name) => format ! ( "field `{}` of {} is private" ,
@@ -885,12 +881,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
885
881
match expr. node {
886
882
ast:: ExprField ( ref base, ident) => {
887
883
if let ty:: TyStruct ( def, _) = self . tcx . expr_ty_adjusted ( & * * base) . sty {
888
- self . check_field ( expr. span , def. did , NamedField ( ident. node . name ) ) ;
884
+ self . check_field ( expr. span ,
885
+ def,
886
+ def. struct_variant ( ) ,
887
+ NamedField ( ident. node . name ) ) ;
889
888
}
890
889
}
891
890
ast:: ExprTupField ( ref base, idx) => {
892
891
if let ty:: TyStruct ( def, _) = self . tcx . expr_ty_adjusted ( & * * base) . sty {
893
- self . check_field ( expr. span , def. did , UnnamedField ( idx. node ) ) ;
892
+ self . check_field ( expr. span ,
893
+ def,
894
+ def. struct_variant ( ) ,
895
+ UnnamedField ( idx. node ) ) ;
894
896
}
895
897
}
896
898
ast:: ExprMethodCall ( ident, _, _) => {
@@ -899,67 +901,31 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
899
901
debug ! ( "(privacy checking) checking impl method" ) ;
900
902
self . check_method ( expr. span , method. def_id , ident. node . name ) ;
901
903
}
902
- ast:: ExprStruct ( _, ref fields, _) => {
903
- match self . tcx . expr_ty ( expr) . sty {
904
- ty:: TyStruct ( ctor_def, _) => {
905
- // RFC 736: ensure all unmentioned fields are visible.
906
- // Rather than computing the set of unmentioned fields
907
- // (i.e. `all_fields - fields`), just check them all.
908
- let all_fields = self . tcx . lookup_struct_fields ( ctor_def. did ) ;
909
- for field in all_fields {
910
- self . check_field ( expr. span , ctor_def. did ,
911
- NamedField ( field. name ) ) ;
912
- }
913
- }
914
- ty:: TyEnum ( _, _) => {
915
- match self . tcx . def_map . borrow ( ) . get ( & expr. id ) . unwrap ( ) . full_def ( ) {
916
- def:: DefVariant ( _, variant_id, _) => {
917
- for field in fields {
918
- self . check_field ( expr. span , variant_id,
919
- NamedField ( field. ident . node . name ) ) ;
920
- }
921
- }
922
- _ => self . tcx . sess . span_bug ( expr. span ,
923
- "resolve didn't \
924
- map enum struct \
925
- constructor to a \
926
- variant def") ,
927
- }
928
- }
929
- _ => self . tcx . sess . span_bug ( expr. span , "struct expr \
930
- didn't have \
931
- struct type?!") ,
904
+ ast:: ExprStruct ( ..) => {
905
+ let adt = self . tcx . expr_ty ( expr) . ty_adt_def ( ) . unwrap ( ) ;
906
+ let variant = adt. variant_of_def ( self . tcx . resolve_expr ( expr) ) ;
907
+ // RFC 736: ensure all unmentioned fields are visible.
908
+ // Rather than computing the set of unmentioned fields
909
+ // (i.e. `all_fields - fields`), just check them all.
910
+ for field in & variant. fields {
911
+ self . check_field ( expr. span , adt, variant, NamedField ( field. name ) ) ;
932
912
}
933
913
}
934
914
ast:: ExprPath ( ..) => {
935
- let guard = |did : ast:: DefId | {
936
- let fields = self . tcx . lookup_struct_fields ( did) ;
937
- let any_priv = fields. iter ( ) . any ( |f| {
938
- f. vis != ast:: Public && (
939
- !is_local ( f. id ) ||
940
- !self . private_accessible ( f. id . node ) )
941
- } ) ;
942
- if any_priv {
943
- self . tcx . sess . span_err ( expr. span ,
944
- "cannot invoke tuple struct constructor \
945
- with private fields") ;
946
- }
947
- } ;
948
- match self . tcx . def_map . borrow ( ) . get ( & expr. id ) . map ( |d| d. full_def ( ) ) {
949
- Some ( def:: DefStruct ( did) ) => {
950
- guard ( if is_local ( did) {
951
- local_def ( self . tcx . map . get_parent ( did. node ) )
952
- } else {
953
- // "tuple structs" with zero fields (such as
954
- // `pub struct Foo;`) don't have a ctor_id, hence
955
- // the unwrap_or to the same struct id.
956
- let maybe_did =
957
- csearch:: get_tuple_struct_definition_if_ctor (
958
- & self . tcx . sess . cstore , did) ;
959
- maybe_did. unwrap_or ( did)
960
- } )
915
+ if let def:: DefStruct ( _) = self . tcx . resolve_expr ( expr) {
916
+ if let ty:: TyStruct ( def, _) = self . tcx . expr_ty ( expr) . sty {
917
+ let fields = & def. struct_variant ( ) . fields ;
918
+ let any_priv = fields. iter ( ) . any ( |f| {
919
+ f. vis != ast:: Public && (
920
+ !is_local ( f. did ) ||
921
+ !self . private_accessible ( f. did . node ) )
922
+ } ) ;
923
+ if any_priv {
924
+ self . tcx . sess . span_err ( expr. span ,
925
+ "cannot invoke tuple struct constructor \
926
+ with private fields") ;
927
+ }
961
928
}
962
- _ => { }
963
929
}
964
930
}
965
931
_ => { }
@@ -977,31 +943,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
977
943
978
944
match pattern. node {
979
945
ast:: PatStruct ( _, ref fields, _) => {
980
- match self . tcx . pat_ty ( pattern) . sty {
981
- ty:: TyStruct ( def, _) => {
982
- for field in fields {
983
- self . check_field ( pattern. span , def. did ,
984
- NamedField ( field. node . ident . name ) ) ;
985
- }
986
- }
987
- ty:: TyEnum ( _, _) => {
988
- match self . tcx . def_map . borrow ( ) . get ( & pattern. id ) . map ( |d| d. full_def ( ) ) {
989
- Some ( def:: DefVariant ( _, variant_id, _) ) => {
990
- for field in fields {
991
- self . check_field ( pattern. span , variant_id,
992
- NamedField ( field. node . ident . name ) ) ;
993
- }
994
- }
995
- _ => self . tcx . sess . span_bug ( pattern. span ,
996
- "resolve didn't \
997
- map enum struct \
998
- pattern to a \
999
- variant def") ,
1000
- }
1001
- }
1002
- _ => self . tcx . sess . span_bug ( pattern. span ,
1003
- "struct pattern didn't have \
1004
- struct type?!") ,
946
+ let adt = self . tcx . pat_ty ( pattern) . ty_adt_def ( ) . unwrap ( ) ;
947
+ let def = self . tcx . def_map . borrow ( ) . get ( & pattern. id ) . unwrap ( ) . full_def ( ) ;
948
+ let variant = adt. variant_of_def ( def) ;
949
+ for field in fields {
950
+ self . check_field ( pattern. span , adt, variant,
951
+ NamedField ( field. node . ident . name ) ) ;
1005
952
}
1006
953
}
1007
954
@@ -1014,7 +961,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
1014
961
if let ast:: PatWild ( ..) = field. node {
1015
962
continue
1016
963
}
1017
- self . check_field ( field. span , def. did , UnnamedField ( i) ) ;
964
+ self . check_field ( field. span ,
965
+ def,
966
+ def. struct_variant ( ) ,
967
+ UnnamedField ( i) ) ;
1018
968
}
1019
969
}
1020
970
ty:: TyEnum ( ..) => {
0 commit comments