14
14
use session:: Session ;
15
15
use lint;
16
16
use middle:: ty;
17
+ use middle:: privacy:: PublicItems ;
17
18
use metadata:: csearch;
18
19
use syntax:: parse:: token:: InternedString ;
19
20
use syntax:: codemap:: { Span , DUMMY_SP } ;
@@ -45,14 +46,15 @@ pub struct Index {
45
46
struct Annotator < ' a > {
46
47
sess : & ' a Session ,
47
48
index : & ' a mut Index ,
48
- parent : Option < Stability >
49
+ parent : Option < Stability > ,
50
+ export_map : & ' a PublicItems ,
49
51
}
50
52
51
53
impl < ' a > Annotator < ' a > {
52
54
// Determine the stability for a node based on its attributes and inherited
53
55
// stability. The stability is recorded in the index and used as the parent.
54
56
fn annotate < F > ( & mut self , id : NodeId , use_parent : bool ,
55
- attrs : & Vec < Attribute > , item_sp : Span , f : F ) where
57
+ attrs : & Vec < Attribute > , item_sp : Span , f : F , required : bool ) where
56
58
F : FnOnce ( & mut Annotator ) ,
57
59
{
58
60
match attr:: find_stability ( self . sess . diagnostic ( ) , attrs. as_slice ( ) , item_sp) {
@@ -70,7 +72,13 @@ impl<'a> Annotator<'a> {
70
72
}
71
73
None => {
72
74
if use_parent {
73
- self . parent . clone ( ) . map ( |stab| self . index . local . insert ( id, stab) ) ;
75
+ if let Some ( stab) = self . parent . clone ( ) {
76
+ self . index . local . insert ( id, stab) ;
77
+ } else if self . index . staged_api && required
78
+ && self . export_map . contains ( & id) {
79
+ self . sess . span_err ( item_sp,
80
+ "This node does not have a stability attribute" ) ;
81
+ }
74
82
}
75
83
f ( self ) ;
76
84
}
@@ -93,11 +101,19 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
93
101
_ => true ,
94
102
} ;
95
103
96
- self . annotate ( i. id , use_parent, & i. attrs , i. span , |v| visit:: walk_item ( v, i) ) ;
104
+ // In case of a `pub use <mod>;`, we should not error since the stability
105
+ // is inherited from the module itself
106
+ let required = match i. node {
107
+ ast:: ItemUse ( _) => i. vis != ast:: Public ,
108
+ _ => true
109
+ } ;
110
+
111
+ self . annotate ( i. id , use_parent, & i. attrs , i. span ,
112
+ |v| visit:: walk_item ( v, i) , required) ;
97
113
98
114
if let ast:: ItemStruct ( ref sd, _) = i. node {
99
115
sd. ctor_id . map ( |id| {
100
- self . annotate ( id, true , & i. attrs , i. span , |_| { } )
116
+ self . annotate ( id, true , & i. attrs , i. span , |_| { } , true )
101
117
} ) ;
102
118
}
103
119
}
@@ -106,7 +122,7 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
106
122
_: & ' v Block , sp : Span , _: NodeId ) {
107
123
if let FkMethod ( _, _, meth) = fk {
108
124
// Methods are not already annotated, so we annotate it
109
- self . annotate ( meth. id , true , & meth. attrs , sp, |_| { } ) ;
125
+ self . annotate ( meth. id , true , & meth. attrs , sp, |_| { } , true ) ;
110
126
}
111
127
// Items defined in a function body have no reason to have
112
128
// a stability attribute, so we don't recurse.
@@ -126,37 +142,38 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
126
142
TypeTraitItem ( ref typedef) => ( typedef. ty_param . id , & typedef. attrs ,
127
143
typedef. ty_param . span ) ,
128
144
} ;
129
- self . annotate ( id, true , attrs, sp, |v| visit:: walk_trait_item ( v, t) ) ;
145
+ self . annotate ( id, true , attrs, sp, |v| visit:: walk_trait_item ( v, t) , true ) ;
130
146
}
131
147
132
148
fn visit_variant ( & mut self , var : & Variant , g : & ' v Generics ) {
133
149
self . annotate ( var. node . id , true , & var. node . attrs , var. span ,
134
- |v| visit:: walk_variant ( v, var, g) )
150
+ |v| visit:: walk_variant ( v, var, g) , true )
135
151
}
136
152
137
153
fn visit_struct_field ( & mut self , s : & StructField ) {
138
154
self . annotate ( s. node . id , true , & s. node . attrs , s. span ,
139
- |v| visit:: walk_struct_field ( v, s) ) ;
155
+ |v| visit:: walk_struct_field ( v, s) , true ) ;
140
156
}
141
157
142
158
fn visit_foreign_item ( & mut self , i : & ast:: ForeignItem ) {
143
- self . annotate ( i. id , true , & i. attrs , i. span , |_| { } ) ;
159
+ self . annotate ( i. id , true , & i. attrs , i. span , |_| { } , true ) ;
144
160
}
145
161
}
146
162
147
163
impl Index {
148
164
/// Construct the stability index for a crate being compiled.
149
- pub fn build ( & mut self , sess : & Session , krate : & Crate ) {
165
+ pub fn build ( & mut self , sess : & Session , krate : & Crate , export_map : & PublicItems ) {
150
166
if !self . staged_api {
151
167
return ;
152
168
}
153
169
let mut annotator = Annotator {
154
170
sess : sess,
155
171
index : self ,
156
- parent : None
172
+ parent : None ,
173
+ export_map : export_map,
157
174
} ;
158
175
annotator. annotate ( ast:: CRATE_NODE_ID , true , & krate. attrs , krate. span ,
159
- |v| visit:: walk_crate ( v, krate) ) ;
176
+ |v| visit:: walk_crate ( v, krate) , true ) ;
160
177
}
161
178
162
179
pub fn new ( krate : & Crate ) -> Index {
0 commit comments