@@ -15,13 +15,13 @@ use crate::errors;
15
15
/// The common case.
16
16
macro_rules! gate {
17
17
( $visitor: expr, $feature: ident, $span: expr, $explain: expr) => { {
18
- if !$visitor. features. $feature && !$span. allows_unstable( sym:: $feature) {
18
+ if !$visitor. features. $feature( ) && !$span. allows_unstable( sym:: $feature) {
19
19
#[ allow( rustc:: untranslatable_diagnostic) ] // FIXME: make this translatable
20
20
feature_err( & $visitor. sess, sym:: $feature, $span, $explain) . emit( ) ;
21
21
}
22
22
} } ;
23
23
( $visitor: expr, $feature: ident, $span: expr, $explain: expr, $help: expr) => { {
24
- if !$visitor. features. $feature && !$span. allows_unstable( sym:: $feature) {
24
+ if !$visitor. features. $feature( ) && !$span. allows_unstable( sym:: $feature) {
25
25
// FIXME: make this translatable
26
26
#[ allow( rustc:: diagnostic_outside_of_impl) ]
27
27
#[ allow( rustc:: untranslatable_diagnostic) ]
@@ -43,7 +43,7 @@ macro_rules! gate_alt {
43
43
/// The case involving a multispan.
44
44
macro_rules! gate_multi {
45
45
( $visitor: expr, $feature: ident, $spans: expr, $explain: expr) => { {
46
- if !$visitor. features. $feature {
46
+ if !$visitor. features. $feature( ) {
47
47
let spans: Vec <_> =
48
48
$spans. filter( |span| !span. allows_unstable( sym:: $feature) ) . collect( ) ;
49
49
if !spans. is_empty( ) {
@@ -56,7 +56,7 @@ macro_rules! gate_multi {
56
56
/// The legacy case.
57
57
macro_rules! gate_legacy {
58
58
( $visitor: expr, $feature: ident, $span: expr, $explain: expr) => { {
59
- if !$visitor. features. $feature && !$span. allows_unstable( sym:: $feature) {
59
+ if !$visitor. features. $feature( ) && !$span. allows_unstable( sym:: $feature) {
60
60
feature_warn( & $visitor. sess, sym:: $feature, $span, $explain) ;
61
61
}
62
62
} } ;
@@ -150,7 +150,7 @@ impl<'a> PostExpansionVisitor<'a> {
150
150
151
151
// FIXME(non_lifetime_binders): Const bound params are pretty broken.
152
152
// Let's keep users from using this feature accidentally.
153
- if self . features . non_lifetime_binders {
153
+ if self . features . non_lifetime_binders ( ) {
154
154
let const_param_spans: Vec < _ > = params
155
155
. iter ( )
156
156
. filter_map ( |param| match param. kind {
@@ -210,7 +210,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
210
210
}
211
211
212
212
// Emit errors for non-staged-api crates.
213
- if !self . features . staged_api {
213
+ if !self . features . staged_api ( ) {
214
214
if attr. has_name ( sym:: unstable)
215
215
|| attr. has_name ( sym:: stable)
216
216
|| attr. has_name ( sym:: rustc_const_unstable)
@@ -470,7 +470,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
470
470
// Limit `min_specialization` to only specializing functions.
471
471
gate_alt ! (
472
472
& self ,
473
- self . features. specialization || ( is_fn && self . features. min_specialization) ,
473
+ self . features. specialization( ) || ( is_fn && self . features. min_specialization( ) ) ,
474
474
sym:: specialization,
475
475
i. span,
476
476
"specialization is unstable"
@@ -548,7 +548,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
548
548
gate_all ! ( global_registration, "global registration is experimental" ) ;
549
549
gate_all ! ( return_type_notation, "return type notation is experimental" ) ;
550
550
551
- if !visitor. features . never_patterns {
551
+ if !visitor. features . never_patterns ( ) {
552
552
if let Some ( spans) = spans. get ( & sym:: never_patterns) {
553
553
for & span in spans {
554
554
if span. allows_unstable ( sym:: never_patterns) {
@@ -572,7 +572,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
572
572
}
573
573
}
574
574
575
- if !visitor. features . negative_bounds {
575
+ if !visitor. features . negative_bounds ( ) {
576
576
for & span in spans. get ( & sym:: negative_bounds) . iter ( ) . copied ( ) . flatten ( ) {
577
577
sess. dcx ( ) . emit_err ( errors:: NegativeBoundUnsupported { span } ) ;
578
578
}
@@ -600,59 +600,61 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
600
600
}
601
601
602
602
fn maybe_stage_features ( sess : & Session , features : & Features , krate : & ast:: Crate ) {
603
- // checks if `#![feature]` has been used to enable any lang feature
604
- // does not check the same for lib features unless there's at least one
605
- // declared lang feature
606
- if !sess. opts . unstable_features . is_nightly_build ( ) {
607
- if features. declared_features . is_empty ( ) {
608
- return ;
609
- }
610
- for attr in krate. attrs . iter ( ) . filter ( |attr| attr. has_name ( sym:: feature) ) {
611
- let mut err = errors:: FeatureOnNonNightly {
612
- span : attr. span ,
613
- channel : option_env ! ( "CFG_RELEASE_CHANNEL" ) . unwrap_or ( "(unknown)" ) ,
614
- stable_features : vec ! [ ] ,
615
- sugg : None ,
616
- } ;
617
-
618
- let mut all_stable = true ;
619
- for ident in
620
- attr. meta_item_list ( ) . into_iter ( ) . flatten ( ) . flat_map ( |nested| nested. ident ( ) )
621
- {
622
- let name = ident. name ;
623
- let stable_since = features
624
- . declared_lang_features
625
- . iter ( )
626
- . flat_map ( |& ( feature, _, since) | if feature == name { since } else { None } )
627
- . next ( ) ;
628
- if let Some ( since) = stable_since {
629
- err. stable_features . push ( errors:: StableFeature { name, since } ) ;
630
- } else {
631
- all_stable = false ;
632
- }
633
- }
634
- if all_stable {
635
- err. sugg = Some ( attr. span ) ;
603
+ // checks if `#![feature]` has been used to enable any feature.
604
+ if sess. opts . unstable_features . is_nightly_build ( ) {
605
+ return ;
606
+ }
607
+ if features. enabled_features ( ) . is_empty ( ) {
608
+ return ;
609
+ }
610
+ let mut errored = false ;
611
+ for attr in krate. attrs . iter ( ) . filter ( |attr| attr. has_name ( sym:: feature) ) {
612
+ // `feature(...)` used on non-nightly. This is definitely an error.
613
+ let mut err = errors:: FeatureOnNonNightly {
614
+ span : attr. span ,
615
+ channel : option_env ! ( "CFG_RELEASE_CHANNEL" ) . unwrap_or ( "(unknown)" ) ,
616
+ stable_features : vec ! [ ] ,
617
+ sugg : None ,
618
+ } ;
619
+
620
+ let mut all_stable = true ;
621
+ for ident in attr. meta_item_list ( ) . into_iter ( ) . flatten ( ) . flat_map ( |nested| nested. ident ( ) ) {
622
+ let name = ident. name ;
623
+ let stable_since = features
624
+ . enabled_lang_features ( )
625
+ . iter ( )
626
+ . flat_map ( |& ( feature, _, since) | if feature == name { since } else { None } )
627
+ . next ( ) ;
628
+ if let Some ( since) = stable_since {
629
+ err. stable_features . push ( errors:: StableFeature { name, since } ) ;
630
+ } else {
631
+ all_stable = false ;
636
632
}
637
- sess. dcx ( ) . emit_err ( err) ;
638
633
}
634
+ if all_stable {
635
+ err. sugg = Some ( attr. span ) ;
636
+ }
637
+ sess. dcx ( ) . emit_err ( err) ;
638
+ errored = true ;
639
639
}
640
+ // Just make sure we actually error if anything is listed in `enabled_features`.
641
+ assert ! ( errored) ;
640
642
}
641
643
642
644
fn check_incompatible_features ( sess : & Session , features : & Features ) {
643
- let declared_features = features
644
- . declared_lang_features
645
+ let enabled_features = features
646
+ . enabled_lang_features ( )
645
647
. iter ( )
646
648
. copied ( )
647
649
. map ( |( name, span, _) | ( name, span) )
648
- . chain ( features. declared_lib_features . iter ( ) . copied ( ) ) ;
650
+ . chain ( features. enabled_lib_features ( ) . iter ( ) . copied ( ) ) ;
649
651
650
652
for ( f1, f2) in rustc_feature:: INCOMPATIBLE_FEATURES
651
653
. iter ( )
652
- . filter ( |& & ( f1, f2) | features. active ( f1) && features. active ( f2) )
654
+ . filter ( |& & ( f1, f2) | features. enabled ( f1) && features. enabled ( f2) )
653
655
{
654
- if let Some ( ( f1_name, f1_span) ) = declared_features . clone ( ) . find ( |( name, _) | name == f1) {
655
- if let Some ( ( f2_name, f2_span) ) = declared_features . clone ( ) . find ( |( name, _) | name == f2)
656
+ if let Some ( ( f1_name, f1_span) ) = enabled_features . clone ( ) . find ( |( name, _) | name == f1) {
657
+ if let Some ( ( f2_name, f2_span) ) = enabled_features . clone ( ) . find ( |( name, _) | name == f2)
656
658
{
657
659
let spans = vec ! [ f1_span, f2_span] ;
658
660
sess. dcx ( ) . emit_err ( errors:: IncompatibleFeatures {
@@ -672,7 +674,7 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) {
672
674
673
675
// Ban GCE with the new solver, because it does not implement GCE correctly.
674
676
if let Some ( & ( _, gce_span, _) ) = features
675
- . declared_lang_features
677
+ . enabled_lang_features ( )
676
678
. iter ( )
677
679
. find ( |& & ( feat, _, _) | feat == sym:: generic_const_exprs)
678
680
{
0 commit comments