1818//! Features are enabled in programs via the crate-level attributes of
1919//! `#![feature(...)]` with a comma-separated list of features.
2020
21- use lint;
21+ use abi:: RustIntrinsic ;
22+ use ast:: NodeId ;
23+ use ast;
24+ use attr;
25+ use attr:: AttrMetaMethods ;
26+ use codemap:: Span ;
27+ use diagnostic:: SpanHandler ;
28+ use visit;
29+ use visit:: Visitor ;
30+ use parse:: token;
2231
23- use syntax:: abi:: RustIntrinsic ;
24- use syntax:: ast:: NodeId ;
25- use syntax:: ast;
26- use syntax:: attr;
27- use syntax:: attr:: AttrMetaMethods ;
28- use syntax:: codemap:: Span ;
29- use syntax:: visit;
30- use syntax:: visit:: Visitor ;
31- use syntax:: parse:: token;
32-
33- use driver:: session:: Session ;
34-
35- use std:: cell:: Cell ;
3632use std:: slice;
3733
3834/// This is a list of all known features since the beginning of time. This list
@@ -99,35 +95,35 @@ enum Status {
9995
10096/// A set of features to be used by later passes.
10197pub struct Features {
102- pub default_type_params : Cell < bool > ,
103- pub overloaded_calls : Cell < bool > ,
104- pub rustc_diagnostic_macros : Cell < bool > ,
105- pub import_shadowing : Cell < bool > ,
98+ pub default_type_params : bool ,
99+ pub overloaded_calls : bool ,
100+ pub rustc_diagnostic_macros : bool ,
101+ pub import_shadowing : bool ,
106102}
107103
108104impl Features {
109105 pub fn new ( ) -> Features {
110106 Features {
111- default_type_params : Cell :: new ( false ) ,
112- overloaded_calls : Cell :: new ( false ) ,
113- rustc_diagnostic_macros : Cell :: new ( false ) ,
114- import_shadowing : Cell :: new ( false ) ,
107+ default_type_params : false ,
108+ overloaded_calls : false ,
109+ rustc_diagnostic_macros : false ,
110+ import_shadowing : false ,
115111 }
116112 }
117113}
118114
119115struct Context < ' a > {
120116 features : Vec < & ' static str > ,
121- sess : & ' a Session ,
117+ span_handler : & ' a SpanHandler ,
122118}
123119
124120impl < ' a > Context < ' a > {
125121 fn gate_feature ( & self , feature : & str , span : Span , explain : & str ) {
126122 if !self . has_feature ( feature) {
127- self . sess . span_err ( span, explain) ;
128- self . sess . span_note ( span, format ! ( "add #![feature({})] to the \
129- crate attributes to enable",
130- feature) . as_slice ( ) ) ;
123+ self . span_handler . span_err ( span, explain) ;
124+ self . span_handler . span_note ( span, format ! ( "add #![feature({})] to the \
125+ crate attributes to enable",
126+ feature) . as_slice ( ) ) ;
131127 }
132128 }
133129
@@ -404,48 +400,47 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
404400 }
405401}
406402
407- pub fn check_crate ( sess : & Session , krate : & ast:: Crate ) {
403+ pub fn check_crate ( span_handler : & SpanHandler , krate : & ast:: Crate ) -> ( Features , Vec < Span > ) {
408404 let mut cx = Context {
409405 features : Vec :: new ( ) ,
410- sess : sess ,
406+ span_handler : span_handler ,
411407 } ;
412408
409+ let mut unknown_features = Vec :: new ( ) ;
410+
413411 for attr in krate. attrs . iter ( ) {
414412 if !attr. check_name ( "feature" ) {
415413 continue
416414 }
417415
418416 match attr. meta_item_list ( ) {
419417 None => {
420- sess . span_err ( attr. span , "malformed feature attribute, \
421- expected #![feature(...)]") ;
418+ span_handler . span_err ( attr. span , "malformed feature attribute, \
419+ expected #![feature(...)]") ;
422420 }
423421 Some ( list) => {
424422 for mi in list. iter ( ) {
425423 let name = match mi. node {
426424 ast:: MetaWord ( ref word) => ( * word) . clone ( ) ,
427425 _ => {
428- sess . span_err ( mi. span ,
429- "malformed feature, expected just \
430- one word") ;
426+ span_handler . span_err ( mi. span ,
427+ "malformed feature, expected just \
428+ one word") ;
431429 continue
432430 }
433431 } ;
434432 match KNOWN_FEATURES . iter ( )
435433 . find ( |& & ( n, _) | name. equiv ( & n) ) {
436434 Some ( & ( name, Active ) ) => { cx. features . push ( name) ; }
437435 Some ( & ( _, Removed ) ) => {
438- sess . span_err ( mi. span , "feature has been removed" ) ;
436+ span_handler . span_err ( mi. span , "feature has been removed" ) ;
439437 }
440438 Some ( & ( _, Accepted ) ) => {
441- sess . span_warn ( mi. span , "feature has been added to Rust, \
442- directive not necessary") ;
439+ span_handler . span_warn ( mi. span , "feature has been added to Rust, \
440+ directive not necessary") ;
443441 }
444442 None => {
445- sess. add_lint ( lint:: builtin:: UNKNOWN_FEATURES ,
446- ast:: CRATE_NODE_ID ,
447- mi. span ,
448- "unknown feature" . to_string ( ) ) ;
443+ unknown_features. push ( mi. span ) ;
449444 }
450445 }
451446 }
@@ -455,11 +450,12 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
455450
456451 visit:: walk_crate ( & mut cx, krate) ;
457452
458- sess. abort_if_errors ( ) ;
459-
460- sess. features . default_type_params . set ( cx. has_feature ( "default_type_params" ) ) ;
461- sess. features . overloaded_calls . set ( cx. has_feature ( "overloaded_calls" ) ) ;
462- sess. features . rustc_diagnostic_macros . set ( cx. has_feature ( "rustc_diagnostic_macros" ) ) ;
463- sess. features . import_shadowing . set ( cx. has_feature ( "import_shadowing" ) ) ;
453+ ( Features {
454+ default_type_params : cx. has_feature ( "default_type_params" ) ,
455+ overloaded_calls : cx. has_feature ( "overloaded_calls" ) ,
456+ rustc_diagnostic_macros : cx. has_feature ( "rustc_diagnostic_macros" ) ,
457+ import_shadowing : cx. has_feature ( "import_shadowing" ) ,
458+ } ,
459+ unknown_features)
464460}
465461
0 commit comments