1414use session:: Session ;
1515use lint;
1616use middle:: ty;
17+ use middle:: privacy:: PublicItems ;
1718use metadata:: csearch;
1819use syntax:: parse:: token:: InternedString ;
1920use syntax:: codemap:: { Span , DUMMY_SP } ;
@@ -44,15 +45,16 @@ pub struct Index {
4445// A private tree-walker for producing an Index.
4546struct Annotator < ' a > {
4647 sess : & ' a Session ,
47- index : Index ,
48- parent : Option < Stability >
48+ index : & ' a mut Index ,
49+ parent : Option < Stability > ,
50+ export_map : & ' a PublicItems ,
4951}
5052
5153impl < ' a > Annotator < ' a > {
5254 // Determine the stability for a node based on its attributes and inherited
5355 // stability. The stability is recorded in the index and used as the parent.
5456 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
5658 F : FnOnce ( & mut Annotator ) ,
5759 {
5860 match attr:: find_stability ( self . sess . diagnostic ( ) , attrs. as_slice ( ) , item_sp) {
@@ -70,7 +72,14 @@ impl<'a> Annotator<'a> {
7072 }
7173 None => {
7274 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+ }
7483 }
7584 f ( self ) ;
7685 }
@@ -93,11 +102,19 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
93102 _ => true ,
94103 } ;
95104
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) ;
97114
98115 if let ast:: ItemStruct ( ref sd, _) = i. node {
99116 sd. ctor_id . map ( |id| {
100- self . annotate ( id, true , & i. attrs , i. span , |_| { } )
117+ self . annotate ( id, true , & i. attrs , i. span , |_| { } , true )
101118 } ) ;
102119 }
103120 }
@@ -106,7 +123,7 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
106123 _: & ' v Block , sp : Span , _: NodeId ) {
107124 if let FkMethod ( _, _, meth) = fk {
108125 // 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 ) ;
110127 }
111128 // Items defined in a function body have no reason to have
112129 // a stability attribute, so we don't recurse.
@@ -126,27 +143,41 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
126143 TypeTraitItem ( ref typedef) => ( typedef. ty_param . id , & typedef. attrs ,
127144 typedef. ty_param . span ) ,
128145 } ;
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 ) ;
130147 }
131148
132149 fn visit_variant ( & mut self , var : & Variant , g : & ' v Generics ) {
133150 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 )
135152 }
136153
137154 fn visit_struct_field ( & mut self , s : & StructField ) {
138155 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 ) ;
140157 }
141158
142159 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 ) ;
144161 }
145162}
146163
147164impl Index {
148165 /// 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 {
150181 let mut staged_api = false ;
151182 for attr in & krate. attrs {
152183 if attr. name ( ) . get ( ) == "staged_api" {
@@ -159,22 +190,11 @@ impl Index {
159190 }
160191 }
161192 }
162- let index = Index {
193+ Index {
163194 staged_api : staged_api,
164195 local : NodeMap ( ) ,
165196 extern_cache : DefIdMap ( )
166- } ;
167- if !staged_api {
168- return index;
169197 }
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
178198 }
179199}
180200
@@ -234,10 +254,19 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
234254 None => {
235255 // This is an 'unmarked' API, which should not exist
236256 // 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+ }
241270 }
242271 }
243272 }
0 commit comments