@@ -3,8 +3,12 @@ use super::accepted::ACCEPTED_FEATURES;
33use super :: removed:: { REMOVED_FEATURES , STABLE_REMOVED_FEATURES } ;
44use super :: builtin_attrs:: { AttributeGate , BUILTIN_ATTRIBUTE_MAP } ;
55
6- use crate :: ast:: { self , NodeId , PatKind , VariantData } ;
6+ use crate :: ast:: {
7+ self , AssocTyConstraint , AssocTyConstraintKind , NodeId , GenericParam , GenericParamKind ,
8+ PatKind , RangeEnd , VariantData ,
9+ } ;
710use crate :: attr:: { self , check_builtin_attribute} ;
11+ use crate :: source_map:: Spanned ;
812use crate :: edition:: { ALL_EDITIONS , Edition } ;
913use crate :: visit:: { self , FnKind , Visitor } ;
1014use crate :: parse:: token;
@@ -153,6 +157,9 @@ fn leveled_feature_err<'a, S: Into<MultiSpan>>(
153157
154158}
155159
160+ const EXPLAIN_BOX_SYNTAX : & str =
161+ "box expression syntax is experimental; you can call `Box::new` instead" ;
162+
156163pub const EXPLAIN_STMT_ATTR_SYNTAX : & str =
157164 "attributes on expressions are experimental" ;
158165
@@ -439,6 +446,20 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
439446 "auto traits are experimental and possibly buggy" ) ;
440447 }
441448
449+ ast:: ItemKind :: TraitAlias ( ..) => {
450+ gate_feature_post ! (
451+ & self ,
452+ trait_alias,
453+ i. span,
454+ "trait aliases are experimental"
455+ ) ;
456+ }
457+
458+ ast:: ItemKind :: MacroDef ( ast:: MacroDef { legacy : false , .. } ) => {
459+ let msg = "`macro` is experimental" ;
460+ gate_feature_post ! ( & self , decl_macro, i. span, msg) ;
461+ }
462+
442463 ast:: ItemKind :: OpaqueTy ( ..) => {
443464 gate_feature_post ! (
444465 & self ,
@@ -502,6 +523,37 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
502523 }
503524 }
504525
526+ fn visit_expr ( & mut self , e : & ' a ast:: Expr ) {
527+ match e. kind {
528+ ast:: ExprKind :: Box ( _) => {
529+ gate_feature_post ! ( & self , box_syntax, e. span, EXPLAIN_BOX_SYNTAX ) ;
530+ }
531+ ast:: ExprKind :: Type ( ..) => {
532+ // To avoid noise about type ascription in common syntax errors, only emit if it
533+ // is the *only* error.
534+ if self . parse_sess . span_diagnostic . err_count ( ) == 0 {
535+ gate_feature_post ! ( & self , type_ascription, e. span,
536+ "type ascription is experimental" ) ;
537+ }
538+ }
539+ ast:: ExprKind :: TryBlock ( _) => {
540+ gate_feature_post ! ( & self , try_blocks, e. span, "`try` expression is experimental" ) ;
541+ }
542+ ast:: ExprKind :: Block ( _, opt_label) => {
543+ if let Some ( label) = opt_label {
544+ gate_feature_post ! ( & self , label_break_value, label. ident. span,
545+ "labels on blocks are unstable" ) ;
546+ }
547+ }
548+ _ => { }
549+ }
550+ visit:: walk_expr ( self , e)
551+ }
552+
553+ fn visit_arm ( & mut self , arm : & ' a ast:: Arm ) {
554+ visit:: walk_arm ( self , arm)
555+ }
556+
505557 fn visit_pat ( & mut self , pattern : & ' a ast:: Pat ) {
506558 match & pattern. kind {
507559 PatKind :: Slice ( pats) => {
@@ -521,12 +573,25 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
521573 }
522574 }
523575 }
576+ PatKind :: Box ( ..) => {
577+ gate_feature_post ! ( & self , box_patterns,
578+ pattern. span,
579+ "box pattern syntax is experimental" ) ;
580+ }
581+ PatKind :: Range ( _, _, Spanned { node : RangeEnd :: Excluded , .. } ) => {
582+ gate_feature_post ! ( & self , exclusive_range_pattern, pattern. span,
583+ "exclusive range pattern syntax is experimental" ) ;
584+ }
524585 _ => { }
525586 }
526587 visit:: walk_pat ( self , pattern)
527588 }
528589
529- fn visit_fn ( & mut self , fn_kind : FnKind < ' a > , fn_decl : & ' a ast:: FnDecl , span : Span , _: NodeId ) {
590+ fn visit_fn ( & mut self ,
591+ fn_kind : FnKind < ' a > ,
592+ fn_decl : & ' a ast:: FnDecl ,
593+ span : Span ,
594+ _node_id : NodeId ) {
530595 if let Some ( header) = fn_kind. header ( ) {
531596 // Stability of const fn methods are covered in
532597 // `visit_trait_item` and `visit_impl_item` below; this is
@@ -541,6 +606,26 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
541606 visit:: walk_fn ( self , fn_kind, fn_decl, span)
542607 }
543608
609+ fn visit_generic_param ( & mut self , param : & ' a GenericParam ) {
610+ match param. kind {
611+ GenericParamKind :: Const { .. } =>
612+ gate_feature_post ! ( & self , const_generics, param. ident. span,
613+ "const generics are unstable" ) ,
614+ _ => { }
615+ }
616+ visit:: walk_generic_param ( self , param)
617+ }
618+
619+ fn visit_assoc_ty_constraint ( & mut self , constraint : & ' a AssocTyConstraint ) {
620+ match constraint. kind {
621+ AssocTyConstraintKind :: Bound { .. } =>
622+ gate_feature_post ! ( & self , associated_type_bounds, constraint. span,
623+ "associated type bounds are unstable" ) ,
624+ _ => { }
625+ }
626+ visit:: walk_assoc_ty_constraint ( self , constraint)
627+ }
628+
544629 fn visit_trait_item ( & mut self , ti : & ' a ast:: TraitItem ) {
545630 match ti. kind {
546631 ast:: TraitItemKind :: Method ( ref sig, ref block) => {
@@ -598,6 +683,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
598683 }
599684 visit:: walk_impl_item ( self , ii)
600685 }
686+
687+ fn visit_vis ( & mut self , vis : & ' a ast:: Visibility ) {
688+ if let ast:: VisibilityKind :: Crate ( ast:: CrateSugar :: JustCrate ) = vis. node {
689+ gate_feature_post ! ( & self , crate_visibility_modifier, vis. span,
690+ "`crate` visibility modifier is experimental" ) ;
691+ }
692+ visit:: walk_vis ( self , vis)
693+ }
601694}
602695
603696pub fn get_features ( span_handler : & Handler , krate_attrs : & [ ast:: Attribute ] ,
@@ -783,6 +876,21 @@ pub fn check_crate(krate: &ast::Crate,
783876 gate_all ! ( yields, generators, "yield syntax is experimental" ) ;
784877 gate_all ! ( or_patterns, "or-patterns syntax is experimental" ) ;
785878 gate_all ! ( const_extern_fn, "`const extern fn` definitions are unstable" ) ;
879+
880+ // All uses of `gate_all!` below this point were added in #65742,
881+ // and subsequently disabled (with the non-early gating readded).
882+ macro_rules! gate_all {
883+ ( $gate: ident, $msg: literal) => {
884+ // FIXME(eddyb) do something more useful than always
885+ // disabling these uses of early feature-gatings.
886+ if false {
887+ for span in & * parse_sess. gated_spans. $gate. borrow( ) {
888+ gate_feature!( & visitor, $gate, * span, $msg) ;
889+ }
890+ }
891+ }
892+ }
893+
786894 gate_all ! ( trait_alias, "trait aliases are experimental" ) ;
787895 gate_all ! ( associated_type_bounds, "associated type bounds are unstable" ) ;
788896 gate_all ! ( crate_visibility_modifier, "`crate` visibility modifier is experimental" ) ;
0 commit comments