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 } ;
@@ -44,15 +45,16 @@ pub struct Index {
44
45
// A private tree-walker for producing an Index.
45
46
struct Annotator < ' a > {
46
47
sess : & ' a Session ,
47
- index : Index ,
48
- parent : Option < Stability >
48
+ index : & ' a mut Index ,
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,14 @@ 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 . opts . test {
80
+ self . sess . span_err ( item_sp,
81
+ "This node does not have a stability attribute" ) ;
82
+ }
74
83
}
75
84
f ( self ) ;
76
85
}
@@ -93,11 +102,19 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
93
102
_ => true ,
94
103
} ;
95
104
96
- self . annotate ( i. id , use_parent, & i. attrs , i. span , |v| visit:: walk_item ( v, i) ) ;
105
+ // In case of a `pub use <mod>;`, we should not error since the stability
106
+ // is inherited from the module itself
107
+ let required = match i. node {
108
+ ast:: ItemUse ( _) => i. vis != ast:: Public ,
109
+ _ => true
110
+ } ;
111
+
112
+ self . annotate ( i. id , use_parent, & i. attrs , i. span ,
113
+ |v| visit:: walk_item ( v, i) , required) ;
97
114
98
115
if let ast:: ItemStruct ( ref sd, _) = i. node {
99
116
sd. ctor_id . map ( |id| {
100
- self . annotate ( id, true , & i. attrs , i. span , |_| { } )
117
+ self . annotate ( id, true , & i. attrs , i. span , |_| { } , true )
101
118
} ) ;
102
119
}
103
120
}
@@ -106,7 +123,7 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
106
123
_: & ' v Block , sp : Span , _: NodeId ) {
107
124
if let FkMethod ( _, _, meth) = fk {
108
125
// Methods are not already annotated, so we annotate it
109
- self . annotate ( meth. id , true , & meth. attrs , sp, |_| { } ) ;
126
+ self . annotate ( meth. id , true , & meth. attrs , sp, |_| { } , true ) ;
110
127
}
111
128
// Items defined in a function body have no reason to have
112
129
// a stability attribute, so we don't recurse.
@@ -126,27 +143,41 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
126
143
TypeTraitItem ( ref typedef) => ( typedef. ty_param . id , & typedef. attrs ,
127
144
typedef. ty_param . span ) ,
128
145
} ;
129
- self . annotate ( id, true , attrs, sp, |v| visit:: walk_trait_item ( v, t) ) ;
146
+ self . annotate ( id, true , attrs, sp, |v| visit:: walk_trait_item ( v, t) , true ) ;
130
147
}
131
148
132
149
fn visit_variant ( & mut self , var : & Variant , g : & ' v Generics ) {
133
150
self . annotate ( var. node . id , true , & var. node . attrs , var. span ,
134
- |v| visit:: walk_variant ( v, var, g) )
151
+ |v| visit:: walk_variant ( v, var, g) , true )
135
152
}
136
153
137
154
fn visit_struct_field ( & mut self , s : & StructField ) {
138
155
self . annotate ( s. node . id , true , & s. node . attrs , s. span ,
139
- |v| visit:: walk_struct_field ( v, s) ) ;
156
+ |v| visit:: walk_struct_field ( v, s) , true ) ;
140
157
}
141
158
142
159
fn visit_foreign_item ( & mut self , i : & ast:: ForeignItem ) {
143
- self . annotate ( i. id , true , & i. attrs , i. span , |_| { } ) ;
160
+ self . annotate ( i. id , true , & i. attrs , i. span , |_| { } , true ) ;
144
161
}
145
162
}
146
163
147
164
impl Index {
148
165
/// Construct the stability index for a crate being compiled.
149
- pub fn build ( sess : & Session , krate : & Crate ) -> Index {
166
+ pub fn build ( & mut self , sess : & Session , krate : & Crate , export_map : & PublicItems ) {
167
+ if !self . staged_api {
168
+ return ;
169
+ }
170
+ let mut annotator = Annotator {
171
+ sess : sess,
172
+ index : self ,
173
+ parent : None ,
174
+ export_map : export_map,
175
+ } ;
176
+ annotator. annotate ( ast:: CRATE_NODE_ID , true , & krate. attrs , krate. span ,
177
+ |v| visit:: walk_crate ( v, krate) , true ) ;
178
+ }
179
+
180
+ pub fn new ( krate : & Crate ) -> Index {
150
181
let mut staged_api = false ;
151
182
for attr in & krate. attrs {
152
183
if attr. name ( ) . get ( ) == "staged_api" {
@@ -159,22 +190,11 @@ impl Index {
159
190
}
160
191
}
161
192
}
162
- let index = Index {
193
+ Index {
163
194
staged_api : staged_api,
164
195
local : NodeMap ( ) ,
165
196
extern_cache : DefIdMap ( )
166
- } ;
167
- if !staged_api {
168
- return index;
169
197
}
170
- let mut annotator = Annotator {
171
- sess : sess,
172
- index : index,
173
- parent : None
174
- } ;
175
- annotator. annotate ( ast:: CRATE_NODE_ID , true , & krate. attrs , krate. span ,
176
- |v| visit:: walk_crate ( v, krate) ) ;
177
- annotator. index
178
198
}
179
199
}
180
200
@@ -234,10 +254,19 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
234
254
None => {
235
255
// This is an 'unmarked' API, which should not exist
236
256
// in the standard library.
237
- self . tcx . sess . span_err ( span, "use of unmarked library feature" ) ;
238
- self . tcx . sess . span_note ( span, "this is either a bug in the library you are \
239
- using or a bug in the compiler - there is \
240
- no way to use this feature") ;
257
+ if self . tcx . sess . features . borrow ( ) . unmarked_api {
258
+ self . tcx . sess . span_warn ( span, "use of unmarked library feature" ) ;
259
+ self . tcx . sess . span_note ( span, "this is either a bug in the library you are \
260
+ using and a bug in the compiler - please \
261
+ report it in both places") ;
262
+ } else {
263
+ self . tcx . sess . span_err ( span, "use of unmarked library feature" ) ;
264
+ self . tcx . sess . span_note ( span, "this is either a bug in the library you are \
265
+ using and a bug in the compiler - please \
266
+ report it in both places") ;
267
+ self . tcx . sess . span_note ( span, "use #![feature(unmarked_api)] in the \
268
+ crate attributes to override this") ;
269
+ }
241
270
}
242
271
}
243
272
}
0 commit comments