<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Feature gating
//!
//! This module implements the gating necessary for preventing certain compiler
//! features from being used by default. This module will crawl a pre-expanded
//! AST to ensure that there are no features which are used that are not
//! enabled.
//!
//! Features are enabled in programs via the crate-level attributes of
//! `#![feature(...)]` with a comma-separated list of features.
//!
//! For the purpose of future feature-tracking, once code for detection of feature
//! gate usage is added, *do not remove it again* even once the feature
//! becomes stable.

use self::AttributeType::*;
use self::AttributeGate::*;

use abi::Abi;
use ast::{self, NodeId, PatKind, RangeEnd, RangeSyntax};
use attr;
use codemap::Spanned;
use syntax_pos::Span;
use errors::{DiagnosticBuilder, Handler, FatalError};
use visit::{self, FnKind, Visitor};
use parse::ParseSess;
use symbol::{keywords, Symbol};

use std::{env, path};

macro_rules! set {
    (proc_macro) => {{
        fn f(features: &mut Features, span: Span) {
            features.declared_lib_features.push((Symbol::intern("proc_macro"), span));
            features.proc_macro = true;
        }
        f as fn(&mut Features, Span)
    }};
    ($field: ident) => {{
        fn f(features: &mut Features, _: Span) {
            features.$field = true;
        }
        f as fn(&mut Features, Span)
    }}
}

macro_rules! declare_features {
    ($((active, $feature: ident, $ver: expr, $issue: expr),)+) => {
        /// Represents active features that are currently being implemented or
        /// currently being considered for addition/removal.
        const ACTIVE_FEATURES:
                &'static [(&'static str, &'static str, Option<u32>, fn(&mut Features, Span))] =
            &[$((stringify!($feature), $ver, $issue, set!($feature))),+];

        /// A set of features to be used by later passes.
        pub struct Features {
            /// `#![feature]` attrs for stable language features, for error reporting
            pub declared_stable_lang_features: Vec<(Symbol, Span)>,
            /// `#![feature]` attrs for non-language (library) features
            pub declared_lib_features: Vec<(Symbol, Span)>,
            $(pub $feature: bool),+
        }

        impl Features {
            pub fn new() -> Features {
                Features {
                    declared_stable_lang_features: Vec::new(),
                    declared_lib_features: Vec::new(),
                    $($feature: false),+
                }
            }
        }
    };

    ($((removed, $feature: ident, $ver: expr, $issue: expr),)+) => {
        /// Represents unstable features which have since been removed (it was once Active)
        const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
            $((stringify!($feature), $ver, $issue)),+
        ];
    };

    ($((stable_removed, $feature: ident, $ver: expr, $issue: expr),)+) => {
        /// Represents stable features which have since been removed (it was once Accepted)
        const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
            $((stringify!($feature), $ver, $issue)),+
        ];
    };

    ($((accepted, $feature: ident, $ver: expr, $issue: expr),)+) => {
        /// Those language feature has since been Accepted (it was once Active)
        const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
            $((stringify!($feature), $ver, $issue)),+
        ];
    }
}

// If you change this, please modify src/doc/unstable-book as well.
//
// Don't ever remove anything from this list; set them to 'Removed'.
//
// The version numbers here correspond to the version in which the current status
// was set. This is most important for knowing when a particular feature became
// stable (active).
//
// NB: tools/tidy/src/features.rs parses this information directly out of the
// source, so take care when modifying it.

declare_features! (
    (active, asm, "1.0.0", Some(29722)),
    (active, concat_idents, "1.0.0", Some(29599)),
    (active, link_args, "1.0.0", Some(29596)),
    (active, log_syntax, "1.0.0", Some(29598)),
    (active, non_ascii_idents, "1.0.0", Some(28979)),
    (active, plugin_registrar, "1.0.0", Some(29597)),
    (active, thread_local, "1.0.0", Some(29594)),
    (active, trace_macros, "1.0.0", Some(29598)),

    // rustc internal, for now:
    (active, intrinsics, "1.0.0", None),
    (active, lang_items, "1.0.0", None),

    (active, link_llvm_intrinsics, "1.0.0", Some(29602)),
    (active, linkage, "1.0.0", Some(29603)),
    (active, quote, "1.0.0", Some(29601)),


    // rustc internal
    (active, rustc_diagnostic_macros, "1.0.0", None),
    (active, rustc_const_unstable, "1.0.0", None),
    (active, advanced_slice_patterns, "1.0.0", Some(23121)),
    (active, box_syntax, "1.0.0", Some(27779)),
    (active, placement_in_syntax, "1.0.0", Some(27779)),
    (active, unboxed_closures, "1.0.0", Some(29625)),

    (active, fundamental, "1.0.0", Some(29635)),
    (active, main, "1.0.0", Some(29634)),
    (active, needs_allocator, "1.4.0", Some(27389)),
    (active, on_unimplemented, "1.0.0", Some(29628)),
    (active, plugin, "1.0.0", Some(29597)),
    (active, simd_ffi, "1.0.0", Some(27731)),
    (active, start, "1.0.0", Some(29633)),
    (active, structural_match, "1.8.0", Some(31434)),
    (active, panic_runtime, "1.10.0", Some(32837)),
    (active, needs_panic_runtime, "1.10.0", Some(32837)),

    // OIBIT specific features
    (active, optin_builtin_traits, "1.0.0", Some(13231)),

    // macro re-export needs more discussion and stabilization
    (active, macro_reexport, "1.0.0", Some(29638)),

    // Allows use of #[staged_api]
    // rustc internal
    (active, staged_api, "1.0.0", None),

    // Allows using #![no_core]
    (active, no_core, "1.3.0", Some(29639)),

    // Allows using `box` in patterns; RFC 469
    (active, box_patterns, "1.0.0", Some(29641)),

    // Allows using the unsafe_destructor_blind_to_params attribute;
    // RFC 1238
    (active, dropck_parametricity, "1.3.0", Some(28498)),

    // Allows using the may_dangle attribute; RFC 1327
    (active, dropck_eyepatch, "1.10.0", Some(34761)),

    // Allows the use of custom attributes; RFC 572
    (active, custom_attribute, "1.0.0", Some(29642)),

    // Allows the use of #[derive(Anything)] as sugar for
    // #[derive_Anything].
    (active, custom_derive, "1.0.0", Some(29644)),

    // Allows the use of rustc_* attributes; RFC 572
    (active, rustc_attrs, "1.0.0", Some(29642)),

    // Allows the use of non lexical lifetimes; RFC 2094
    (active, nll, "1.0.0", Some(44928)),

    // Allows the use of #[allow_internal_unstable]. This is an
    // attribute on macro_rules! and can't use the attribute handling
    // below (it has to be checked before expansion possibly makes
    // macros disappear).
    //
    // rustc internal
    (active, allow_internal_unstable, "1.0.0", None),

    // Allows the use of #[allow_internal_unsafe]. This is an
    // attribute on macro_rules! and can't use the attribute handling
    // below (it has to be checked before expansion possibly makes
    // macros disappear).
    //
    // rustc internal
    (active, allow_internal_unsafe, "1.0.0", None),

    // #23121. Array patterns have some hazards yet.<commit_msg>update tracking issue for nll<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Feature gating
//!
//! This module implements the gating necessary for preventing certain compiler
//! features from being used by default. This module will crawl a pre-expanded
//! AST to ensure that there are no features which are used that are not
//! enabled.
//!
//! Features are enabled in programs via the crate-level attributes of
//! `#![feature(...)]` with a comma-separated list of features.
//!
//! For the purpose of future feature-tracking, once code for detection of feature
//! gate usage is added, *do not remove it again* even once the feature
//! becomes stable.

use self::AttributeType::*;
use self::AttributeGate::*;

use abi::Abi;
use ast::{self, NodeId, PatKind, RangeEnd, RangeSyntax};
use attr;
use codemap::Spanned;
use syntax_pos::Span;
use errors::{DiagnosticBuilder, Handler, FatalError};
use visit::{self, FnKind, Visitor};
use parse::ParseSess;
use symbol::{keywords, Symbol};

use std::{env, path};

macro_rules! set {
    (proc_macro) => {{
        fn f(features: &mut Features, span: Span) {
            features.declared_lib_features.push((Symbol::intern("proc_macro"), span));
            features.proc_macro = true;
        }
        f as fn(&mut Features, Span)
    }};
    ($field: ident) => {{
        fn f(features: &mut Features, _: Span) {
            features.$field = true;
        }
        f as fn(&mut Features, Span)
    }}
}

macro_rules! declare_features {
    ($((active, $feature: ident, $ver: expr, $issue: expr),)+) => {
        /// Represents active features that are currently being implemented or
        /// currently being considered for addition/removal.
        const ACTIVE_FEATURES:
                &'static [(&'static str, &'static str, Option<u32>, fn(&mut Features, Span))] =
            &[$((stringify!($feature), $ver, $issue, set!($feature))),+];

        /// A set of features to be used by later passes.
        pub struct Features {
            /// `#![feature]` attrs for stable language features, for error reporting
            pub declared_stable_lang_features: Vec<(Symbol, Span)>,
            /// `#![feature]` attrs for non-language (library) features
            pub declared_lib_features: Vec<(Symbol, Span)>,
            $(pub $feature: bool),+
        }

        impl Features {
            pub fn new() -> Features {
                Features {
                    declared_stable_lang_features: Vec::new(),
                    declared_lib_features: Vec::new(),
                    $($feature: false),+
                }
            }
        }
    };

    ($((removed, $feature: ident, $ver: expr, $issue: expr),)+) => {
        /// Represents unstable features which have since been removed (it was once Active)
        const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
            $((stringify!($feature), $ver, $issue)),+
        ];
    };

    ($((stable_removed, $feature: ident, $ver: expr, $issue: expr),)+) => {
        /// Represents stable features which have since been removed (it was once Accepted)
        const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
            $((stringify!($feature), $ver, $issue)),+
        ];
    };

    ($((accepted, $feature: ident, $ver: expr, $issue: expr),)+) => {
        /// Those language feature has since been Accepted (it was once Active)
        const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
            $((stringify!($feature), $ver, $issue)),+
        ];
    }
}

// If you change this, please modify src/doc/unstable-book as well.
//
// Don't ever remove anything from this list; set them to 'Removed'.
//
// The version numbers here correspond to the version in which the current status
// was set. This is most important for knowing when a particular feature became
// stable (active).
//
// NB: tools/tidy/src/features.rs parses this information directly out of the
// source, so take care when modifying it.

declare_features! (
    (active, asm, "1.0.0", Some(29722)),
    (active, concat_idents, "1.0.0", Some(29599)),
    (active, link_args, "1.0.0", Some(29596)),
    (active, log_syntax, "1.0.0", Some(29598)),
    (active, non_ascii_idents, "1.0.0", Some(28979)),
    (active, plugin_registrar, "1.0.0", Some(29597)),
    (active, thread_local, "1.0.0", Some(29594)),
    (active, trace_macros, "1.0.0", Some(29598)),

    // rustc internal, for now:
    (active, intrinsics, "1.0.0", None),
    (active, lang_items, "1.0.0", None),

    (active, link_llvm_intrinsics, "1.0.0", Some(29602)),
    (active, linkage, "1.0.0", Some(29603)),
    (active, quote, "1.0.0", Some(29601)),


    // rustc internal
    (active, rustc_diagnostic_macros, "1.0.0", None),
    (active, rustc_const_unstable, "1.0.0", None),
    (active, advanced_slice_patterns, "1.0.0", Some(23121)),
    (active, box_syntax, "1.0.0", Some(27779)),
    (active, placement_in_syntax, "1.0.0", Some(27779)),
    (active, unboxed_closures, "1.0.0", Some(29625)),

    (active, fundamental, "1.0.0", Some(29635)),
    (active, main, "1.0.0", Some(29634)),
    (active, needs_allocator, "1.4.0", Some(27389)),
    (active, on_unimplemented, "1.0.0", Some(29628)),
    (active, plugin, "1.0.0", Some(29597)),
    (active, simd_ffi, "1.0.0", Some(27731)),
    (active, start, "1.0.0", Some(29633)),
    (active, structural_match, "1.8.0", Some(31434)),
    (active, panic_runtime, "1.10.0", Some(32837)),
    (active, needs_panic_runtime, "1.10.0", Some(32837)),

    // OIBIT specific features
    (active, optin_builtin_traits, "1.0.0", Some(13231)),

    // macro re-export needs more discussion and stabilization
    (active, macro_reexport, "1.0.0", Some(29638)),

    // Allows use of #[staged_api]
    // rustc internal
    (active, staged_api, "1.0.0", None),

    // Allows using #![no_core]
    (active, no_core, "1.3.0", Some(29639)),

    // Allows using `box` in patterns; RFC 469
    (active, box_patterns, "1.0.0", Some(29641)),

    // Allows using the unsafe_destructor_blind_to_params attribute;
    // RFC 1238
    (active, dropck_parametricity, "1.3.0", Some(28498)),

    // Allows using the may_dangle attribute; RFC 1327
    (active, dropck_eyepatch, "1.10.0", Some(34761)),

    // Allows the use of custom attributes; RFC 572
    (active, custom_attribute, "1.0.0", Some(29642)),

    // Allows the use of #[derive(Anything)] as sugar for
    // #[derive_Anything].
    (active, custom_derive, "1.0.0", Some(29644)),

    // Allows the use of rustc_* attributes; RFC 572
    (active, rustc_attrs, "1.0.0", Some(29642)),

    // Allows the use of non lexical lifetimes; RFC 2094
    (active, nll, "1.0.0", Some(43234)),

    // Allows the use of #[allow_internal_unstable]. This is an
    // attribute on macro_rules! and can't use the attribute handling
    // below (it has to be checked before expansion possibly makes
    // macros disappear).
    //
    // rustc internal
    (active, allow_internal_unstable, "1.0.0", None),

    // Allows the use of #[allow_internal_unsafe]. This is an
    // attribute on macro_rules! and can't use the attribute handling
    // below (it has to be checked before expansion possibly makes
    // macros disappear).
    //
    // rustc internal
    (active, allow_internal_unsafe, "1.0.0", None),

    // #23121. Array patterns have some hazards yet.
{'fraction_non_alphanumeric': 0.15702268671934744, 'fraction_numerical': 0.044098903900076473, 'mean_word_length': 2.9163963064636884, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5299021', 'n_tokens_mistral': 5397, 'n_tokens_neox': 5000, 'n_words': 1533}