@@ -2,10 +2,10 @@ use rustc_ast as ast;
22use rustc_ast:: visit:: { self , AssocCtxt , FnCtxt , FnKind , Visitor } ;
33use rustc_ast:: { AssocConstraint , AssocConstraintKind , NodeId } ;
44use rustc_ast:: { PatKind , RangeEnd , VariantData } ;
5- use rustc_errors:: { struct_span_err, Applicability } ;
5+ use rustc_errors:: { struct_span_err, Applicability , StashKey } ;
6+ use rustc_feature:: Features ;
67use rustc_feature:: { AttributeGate , BuiltinAttribute , BUILTIN_ATTRIBUTE_MAP } ;
7- use rustc_feature:: { Features , GateIssue } ;
8- use rustc_session:: parse:: { feature_err, feature_err_issue} ;
8+ use rustc_session:: parse:: { feature_err, feature_warn} ;
99use rustc_session:: Session ;
1010use rustc_span:: source_map:: Spanned ;
1111use rustc_span:: symbol:: sym;
@@ -20,9 +20,7 @@ macro_rules! gate_feature_fn {
2020 let has_feature: bool = has_feature( visitor. features) ;
2121 debug!( "gate_feature(feature = {:?}, span = {:?}); has? {}" , name, span, has_feature) ;
2222 if !has_feature && !span. allows_unstable( $name) {
23- feature_err_issue( & visitor. sess. parse_sess, name, span, GateIssue :: Language , explain)
24- . help( help)
25- . emit( ) ;
23+ feature_err( & visitor. sess. parse_sess, name, span, explain) . help( help) . emit( ) ;
2624 }
2725 } } ;
2826 ( $visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => { {
@@ -31,8 +29,19 @@ macro_rules! gate_feature_fn {
3129 let has_feature: bool = has_feature( visitor. features) ;
3230 debug!( "gate_feature(feature = {:?}, span = {:?}); has? {}" , name, span, has_feature) ;
3331 if !has_feature && !span. allows_unstable( $name) {
34- feature_err_issue( & visitor. sess. parse_sess, name, span, GateIssue :: Language , explain)
35- . emit( ) ;
32+ feature_err( & visitor. sess. parse_sess, name, span, explain) . emit( ) ;
33+ }
34+ } } ;
35+ ( future_incompatible; $visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => { {
36+ let ( visitor, has_feature, span, name, explain) =
37+ ( & * $visitor, $has_feature, $span, $name, $explain) ;
38+ let has_feature: bool = has_feature( visitor. features) ;
39+ debug!(
40+ "gate_feature(feature = {:?}, span = {:?}); has? {} (future_incompatible)" ,
41+ name, span, has_feature
42+ ) ;
43+ if !has_feature && !span. allows_unstable( $name) {
44+ feature_warn( & visitor. sess. parse_sess, name, span, explain) ;
3645 }
3746 } } ;
3847}
@@ -44,6 +53,9 @@ macro_rules! gate_feature_post {
4453 ( $visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
4554 gate_feature_fn!( $visitor, |x: & Features | x. $feature, $span, sym:: $feature, $explain)
4655 } ;
56+ ( future_incompatible; $visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
57+ gate_feature_fn!( future_incompatible; $visitor, |x: & Features | x. $feature, $span, sym:: $feature, $explain)
58+ } ;
4759}
4860
4961pub fn check_attribute ( attr : & ast:: Attribute , sess : & Session , features : & Features ) {
@@ -588,11 +600,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
588600 {
589601 // When we encounter a statement of the form `foo: Ty = val;`, this will emit a type
590602 // ascription error, but the likely intention was to write a `let` statement. (#78907).
591- feature_err_issue (
603+ feature_err (
592604 & self . sess . parse_sess ,
593605 sym:: type_ascription,
594606 lhs. span ,
595- GateIssue :: Language ,
596607 "type ascription is experimental" ,
597608 ) . span_suggestion_verbose (
598609 lhs. span . shrink_to_lo ( ) ,
@@ -615,15 +626,22 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
615626 ) ;
616627 }
617628 ast:: ExprKind :: Type ( ..) => {
618- // To avoid noise about type ascription in common syntax errors, only emit if it
619- // is the *only* error.
620629 if self . sess . parse_sess . span_diagnostic . err_count ( ) == 0 {
630+ // To avoid noise about type ascription in common syntax errors,
631+ // only emit if it is the *only* error.
621632 gate_feature_post ! (
622633 & self ,
623634 type_ascription,
624635 e. span,
625636 "type ascription is experimental"
626637 ) ;
638+ } else {
639+ // And if it isn't, cancel the early-pass warning.
640+ self . sess
641+ . parse_sess
642+ . span_diagnostic
643+ . steal_diagnostic ( e. span , StashKey :: EarlySyntaxWarning )
644+ . map ( |err| err. cancel ( ) ) ;
627645 }
628646 }
629647 ast:: ExprKind :: TryBlock ( _) => {
@@ -789,14 +807,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
789807
790808 // All uses of `gate_all!` below this point were added in #65742,
791809 // and subsequently disabled (with the non-early gating readded).
810+ // We emit an early future-incompatible warning for these.
811+ // New syntax gates should go above here to get a hard error gate.
792812 macro_rules! gate_all {
793813 ( $gate: ident, $msg: literal) => {
794- // FIXME(eddyb) do something more useful than always
795- // disabling these uses of early feature-gatings.
796- if false {
797- for span in spans. get( & sym:: $gate) . unwrap_or( & vec![ ] ) {
798- gate_feature_post!( & visitor, $gate, * span, $msg) ;
799- }
814+ for span in spans. get( & sym:: $gate) . unwrap_or( & vec![ ] ) {
815+ gate_feature_post!( future_incompatible; & visitor, $gate, * span, $msg) ;
800816 }
801817 } ;
802818 }
@@ -809,11 +825,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
809825 gate_all ! ( try_blocks, "`try` blocks are unstable" ) ;
810826 gate_all ! ( label_break_value, "labels on blocks are unstable" ) ;
811827 gate_all ! ( box_syntax, "box expression syntax is experimental; you can call `Box::new` instead" ) ;
812- // To avoid noise about type ascription in common syntax errors,
813- // only emit if it is the *only* error. (Also check it last.)
814- if sess. parse_sess . span_diagnostic . err_count ( ) == 0 {
815- gate_all ! ( type_ascription, "type ascription is experimental" ) ;
816- }
828+ gate_all ! ( type_ascription, "type ascription is experimental" ) ;
817829
818830 visit:: walk_crate ( & mut visitor, krate) ;
819831}
0 commit comments