@@ -36,6 +36,7 @@ use parse::ParseSess;
36
36
use parse:: token:: InternedString ;
37
37
38
38
use std:: ascii:: AsciiExt ;
39
+ use std:: env;
39
40
40
41
macro_rules! setter {
41
42
( $field: ident) => { {
@@ -679,16 +680,15 @@ impl GatedCfg {
679
680
pub fn check_and_emit ( & self , sess : & ParseSess , features : & Features ) {
680
681
let ( cfg, feature, has_feature) = GATED_CFGS [ self . index ] ;
681
682
if !has_feature ( features) && !sess. codemap ( ) . span_allows_unstable ( self . span ) {
682
- let diagnostic = & sess. span_diagnostic ;
683
683
let explain = format ! ( "`cfg({})` is experimental and subject to change" , cfg) ;
684
- emit_feature_err ( diagnostic , feature, self . span , GateIssue :: Language , & explain) ;
684
+ emit_feature_err ( sess , feature, self . span , GateIssue :: Language , & explain) ;
685
685
}
686
686
}
687
687
}
688
688
689
689
struct Context < ' a > {
690
690
features : & ' a Features ,
691
- span_handler : & ' a Handler ,
691
+ parse_sess : & ' a ParseSess ,
692
692
cm : & ' a CodeMap ,
693
693
plugin_attributes : & ' a [ ( String , AttributeType ) ] ,
694
694
}
@@ -699,7 +699,7 @@ macro_rules! gate_feature_fn {
699
699
let has_feature: bool = has_feature( & $cx. features) ;
700
700
debug!( "gate_feature(feature = {:?}, span = {:?}); has? {}" , name, span, has_feature) ;
701
701
if !has_feature && !cx. cm. span_allows_unstable( span) {
702
- emit_feature_err( cx. span_handler , name, span, GateIssue :: Language , explain) ;
702
+ emit_feature_err( cx. parse_sess , name, span, GateIssue :: Language , explain) ;
703
703
}
704
704
} }
705
705
}
@@ -756,10 +756,10 @@ impl<'a> Context<'a> {
756
756
}
757
757
}
758
758
759
- pub fn check_attribute ( attr : & ast:: Attribute , handler : & Handler ,
759
+ pub fn check_attribute ( attr : & ast:: Attribute , parse_sess : & ParseSess ,
760
760
cm : & CodeMap , features : & Features ) {
761
761
let cx = Context {
762
- features : features, span_handler : handler ,
762
+ features : features, parse_sess : parse_sess ,
763
763
cm : cm, plugin_attributes : & [ ]
764
764
} ;
765
765
cx. check_attribute ( attr, true ) ;
@@ -788,8 +788,10 @@ pub enum GateIssue {
788
788
Library ( Option < u32 > )
789
789
}
790
790
791
- pub fn emit_feature_err ( diag : & Handler , feature : & str , span : Span , issue : GateIssue ,
791
+ pub fn emit_feature_err ( sess : & ParseSess , feature : & str , span : Span , issue : GateIssue ,
792
792
explain : & str ) {
793
+ let diag = & sess. span_diagnostic ;
794
+
793
795
let issue = match issue {
794
796
GateIssue :: Language => find_lang_feature_issue ( feature) ,
795
797
GateIssue :: Library ( lib) => lib,
@@ -802,13 +804,12 @@ pub fn emit_feature_err(diag: &Handler, feature: &str, span: Span, issue: GateIs
802
804
} ;
803
805
804
806
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
805
- if option_env ! ( "CFG_DISABLE_UNSTABLE_FEATURES" ) . is_some ( ) {
806
- err. emit ( ) ;
807
- return ;
807
+ if sess. unstable_features . is_nightly_build ( ) {
808
+ err. help ( & format ! ( "add #![feature({})] to the \
809
+ crate attributes to enable",
810
+ feature) ) ;
808
811
}
809
- err. help ( & format ! ( "add #![feature({})] to the \
810
- crate attributes to enable",
811
- feature) ) ;
812
+
812
813
err. emit ( ) ;
813
814
}
814
815
@@ -962,9 +963,10 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
962
963
if attr:: contains_name ( & i. attrs [ ..] , "simd" ) {
963
964
gate_feature_post ! ( & self , simd, i. span,
964
965
"SIMD types are experimental and possibly buggy" ) ;
965
- self . context . span_handler . span_warn ( i. span ,
966
- "the `#[simd]` attribute is deprecated, \
967
- use `#[repr(simd)]` instead") ;
966
+ self . context . parse_sess . span_diagnostic . span_warn ( i. span ,
967
+ "the `#[simd]` attribute \
968
+ is deprecated, use \
969
+ `#[repr(simd)]` instead") ;
968
970
}
969
971
for attr in & i. attrs {
970
972
if attr. name ( ) == "repr" {
@@ -1273,7 +1275,7 @@ pub fn check_crate(krate: &ast::Crate,
1273
1275
maybe_stage_features ( & sess. span_diagnostic , krate, unstable) ;
1274
1276
let ctx = Context {
1275
1277
features : features,
1276
- span_handler : & sess. span_diagnostic ,
1278
+ parse_sess : sess,
1277
1279
cm : sess. codemap ( ) ,
1278
1280
plugin_attributes : plugin_attributes,
1279
1281
} ;
@@ -1294,6 +1296,30 @@ pub enum UnstableFeatures {
1294
1296
Cheat
1295
1297
}
1296
1298
1299
+ impl UnstableFeatures {
1300
+ pub fn from_environment ( ) -> UnstableFeatures {
1301
+ // Whether this is a feature-staged build, i.e. on the beta or stable channel
1302
+ let disable_unstable_features = option_env ! ( "CFG_DISABLE_UNSTABLE_FEATURES" ) . is_some ( ) ;
1303
+ // The secret key needed to get through the rustc build itself by
1304
+ // subverting the unstable features lints
1305
+ let bootstrap_secret_key = option_env ! ( "CFG_BOOTSTRAP_KEY" ) ;
1306
+ // The matching key to the above, only known by the build system
1307
+ let bootstrap_provided_key = env:: var ( "RUSTC_BOOTSTRAP_KEY" ) . ok ( ) ;
1308
+ match ( disable_unstable_features, bootstrap_secret_key, bootstrap_provided_key) {
1309
+ ( _, Some ( ref s) , Some ( ref p) ) if s == p => UnstableFeatures :: Cheat ,
1310
+ ( true , _, _) => UnstableFeatures :: Disallow ,
1311
+ ( false , _, _) => UnstableFeatures :: Allow
1312
+ }
1313
+ }
1314
+
1315
+ pub fn is_nightly_build ( & self ) -> bool {
1316
+ match * self {
1317
+ UnstableFeatures :: Allow | UnstableFeatures :: Cheat => true ,
1318
+ _ => false ,
1319
+ }
1320
+ }
1321
+ }
1322
+
1297
1323
fn maybe_stage_features ( span_handler : & Handler , krate : & ast:: Crate ,
1298
1324
unstable : UnstableFeatures ) {
1299
1325
let allow_features = match unstable {
0 commit comments