@@ -15,13 +15,13 @@ use crate::errors;
1515/// The common case.
1616macro_rules! gate {
1717 ( $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) {
1919 #[ allow( rustc:: untranslatable_diagnostic) ] // FIXME: make this translatable
2020 feature_err( & $visitor. sess, sym:: $feature, $span, $explain) . emit( ) ;
2121 }
2222 } } ;
2323 ( $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) {
2525 // FIXME: make this translatable
2626 #[ allow( rustc:: diagnostic_outside_of_impl) ]
2727 #[ allow( rustc:: untranslatable_diagnostic) ]
@@ -43,7 +43,7 @@ macro_rules! gate_alt {
4343/// The case involving a multispan.
4444macro_rules! gate_multi {
4545 ( $visitor: expr, $feature: ident, $spans: expr, $explain: expr) => { {
46- if !$visitor. features. $feature {
46+ if !$visitor. features. $feature( ) {
4747 let spans: Vec <_> =
4848 $spans. filter( |span| !span. allows_unstable( sym:: $feature) ) . collect( ) ;
4949 if !spans. is_empty( ) {
@@ -56,7 +56,7 @@ macro_rules! gate_multi {
5656/// The legacy case.
5757macro_rules! gate_legacy {
5858 ( $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) {
6060 feature_warn( & $visitor. sess, sym:: $feature, $span, $explain) ;
6161 }
6262 } } ;
@@ -150,7 +150,7 @@ impl<'a> PostExpansionVisitor<'a> {
150150
151151 // FIXME(non_lifetime_binders): Const bound params are pretty broken.
152152 // Let's keep users from using this feature accidentally.
153- if self . features . non_lifetime_binders {
153+ if self . features . non_lifetime_binders ( ) {
154154 let const_param_spans: Vec < _ > = params
155155 . iter ( )
156156 . filter_map ( |param| match param. kind {
@@ -210,7 +210,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
210210 }
211211
212212 // Emit errors for non-staged-api crates.
213- if !self . features . staged_api {
213+ if !self . features . staged_api ( ) {
214214 if attr. has_name ( sym:: unstable)
215215 || attr. has_name ( sym:: stable)
216216 || attr. has_name ( sym:: rustc_const_unstable)
@@ -470,7 +470,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
470470 // Limit `min_specialization` to only specializing functions.
471471 gate_alt ! (
472472 & self ,
473- self . features. specialization || ( is_fn && self . features. min_specialization) ,
473+ self . features. specialization( ) || ( is_fn && self . features. min_specialization( ) ) ,
474474 sym:: specialization,
475475 i. span,
476476 "specialization is unstable"
@@ -548,7 +548,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
548548 gate_all ! ( global_registration, "global registration is experimental" ) ;
549549 gate_all ! ( return_type_notation, "return type notation is experimental" ) ;
550550
551- if !visitor. features . never_patterns {
551+ if !visitor. features . never_patterns ( ) {
552552 if let Some ( spans) = spans. get ( & sym:: never_patterns) {
553553 for & span in spans {
554554 if span. allows_unstable ( sym:: never_patterns) {
@@ -572,7 +572,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
572572 }
573573 }
574574
575- if !visitor. features . negative_bounds {
575+ if !visitor. features . negative_bounds ( ) {
576576 for & span in spans. get ( & sym:: negative_bounds) . iter ( ) . copied ( ) . flatten ( ) {
577577 sess. dcx ( ) . emit_err ( errors:: NegativeBoundUnsupported { span } ) ;
578578 }
@@ -600,59 +600,61 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
600600}
601601
602602fn 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 ;
636632 }
637- sess. dcx ( ) . emit_err ( err) ;
638633 }
634+ if all_stable {
635+ err. sugg = Some ( attr. span ) ;
636+ }
637+ sess. dcx ( ) . emit_err ( err) ;
638+ errored = true ;
639639 }
640+ // Just make sure we actually error if anything is listed in `enabled_features`.
641+ assert ! ( errored) ;
640642}
641643
642644fn 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 ( )
645647 . iter ( )
646648 . copied ( )
647649 . map ( |( name, span, _) | ( name, span) )
648- . chain ( features. declared_lib_features . iter ( ) . copied ( ) ) ;
650+ . chain ( features. enabled_lib_features ( ) . iter ( ) . copied ( ) ) ;
649651
650652 for ( f1, f2) in rustc_feature:: INCOMPATIBLE_FEATURES
651653 . iter ( )
652- . filter ( |& & ( f1, f2) | features. active ( f1) && features. active ( f2) )
654+ . filter ( |& & ( f1, f2) | features. enabled ( f1) && features. enabled ( f2) )
653655 {
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)
656658 {
657659 let spans = vec ! [ f1_span, f2_span] ;
658660 sess. dcx ( ) . emit_err ( errors:: IncompatibleFeatures {
@@ -672,7 +674,7 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) {
672674
673675 // Ban GCE with the new solver, because it does not implement GCE correctly.
674676 if let Some ( & ( _, gce_span, _) ) = features
675- . declared_lang_features
677+ . enabled_lang_features ( )
676678 . iter ( )
677679 . find ( |& & ( feat, _, _) | feat == sym:: generic_const_exprs)
678680 {
0 commit comments