<commit_before>// Validate AST before lowering it to HIR
//
// This pass is supposed to catch things that fit into AST data structures,
// but not permitted by the language. It runs after expansion when AST is frozen,
// so it can check for erroneous constructions produced by syntax extensions.
// This pass is supposed to perform only simple checks not requiring name resolution
// or type checking or some other kind of complex analysis.

use std::mem;
use syntax::print::pprust;
use rustc::lint;
use rustc::lint::builtin::{BuiltinLintDiagnostics, NESTED_IMPL_TRAIT};
use rustc::session::Session;
use rustc_data_structures::fx::FxHashMap;
use syntax::ast::*;
use syntax::attr;
use syntax::source_map::Spanned;
use syntax::symbol::keywords;
use syntax::ptr::P;
use syntax::visit::{self, Visitor};
use syntax::{span_err, struct_span_err, walk_list};
use syntax_ext::proc_macro_decls::is_proc_macro_attr;
use syntax_pos::Span;
use errors::Applicability;
use log::debug;

#[derive(Copy, Clone, Debug)]
struct OuterImplTrait {
    span: Span,

    /// rust-lang/rust#57979: a bug in original implementation caused
    /// us to fail sometimes to record an outer `impl Trait`.
    /// Therefore, in order to reliably issue a warning (rather than
    /// an error) in the *precise* places where we are newly injecting
    /// the diagnostic, we have to distinguish between the places
    /// where the outer `impl Trait` has always been recorded, versus
    /// the places where it has only recently started being recorded.
    only_recorded_since_pull_request_57730: bool,
}

impl OuterImplTrait {
    /// This controls whether we should downgrade the nested impl
    /// trait diagnostic to a warning rather than an error, based on
    /// whether the outer impl trait had been improperly skipped in
    /// earlier implementations of the analysis on the stable
    /// compiler.
    fn should_warn_instead_of_error(&self) -> bool {
        self.only_recorded_since_pull_request_57730
    }
}

struct AstValidator<'a> {
    session: &'a Session,
    has_proc_macro_decls: bool,
    has_global_allocator: bool,

    // Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
    // Nested `impl Trait` _is_ allowed in associated type position,
    // e.g `impl Iterator<Item=impl Debug>`
    outer_impl_trait: Option<OuterImplTrait>,

    // Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
    // or `Foo::Bar<impl Trait>`
    is_impl_trait_banned: bool,

    // rust-lang/rust#57979: the ban of nested `impl Trait` was buggy
    // until sometime after PR #57730 landed: it would jump directly
    // to walk_ty rather than visit_ty (or skip recurring entirely for
    // impl trait in projections), and thus miss some cases. We track
    // whether we should downgrade to a warning for short-term via
    // these booleans.
    warning_period_57979_didnt_record_next_impl_trait: bool,
    warning_period_57979_impl_trait_in_proj: bool,
}

impl<'a> AstValidator<'a> {
    fn with_impl_trait_in_proj_warning<T>(&mut self, v: bool, f: impl FnOnce(&mut Self) -> T) -> T {
        let old = mem::replace(&mut self.warning_period_57979_impl_trait_in_proj, v);
        let ret = f(self);
        self.warning_period_57979_impl_trait_in_proj = old;
        ret
    }

    fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
        let old = mem::replace(&mut self.is_impl_trait_banned, true);
        f(self);
        self.is_impl_trait_banned = old;
    }

    fn with_impl_trait(&mut self, outer: Option<OuterImplTrait>, f: impl FnOnce(&mut Self)) {
        let old = mem::replace(&mut self.outer_impl_trait, outer);<commit_msg>Addressed review feedback regarding comment phrasing.<commit_after>// Validate AST before lowering it to HIR
//
// This pass is supposed to catch things that fit into AST data structures,
// but not permitted by the language. It runs after expansion when AST is frozen,
// so it can check for erroneous constructions produced by syntax extensions.
// This pass is supposed to perform only simple checks not requiring name resolution
// or type checking or some other kind of complex analysis.

use std::mem;
use syntax::print::pprust;
use rustc::lint;
use rustc::lint::builtin::{BuiltinLintDiagnostics, NESTED_IMPL_TRAIT};
use rustc::session::Session;
use rustc_data_structures::fx::FxHashMap;
use syntax::ast::*;
use syntax::attr;
use syntax::source_map::Spanned;
use syntax::symbol::keywords;
use syntax::ptr::P;
use syntax::visit::{self, Visitor};
use syntax::{span_err, struct_span_err, walk_list};
use syntax_ext::proc_macro_decls::is_proc_macro_attr;
use syntax_pos::Span;
use errors::Applicability;
use log::debug;

#[derive(Copy, Clone, Debug)]
struct OuterImplTrait {
    span: Span,

    /// rust-lang/rust#57979: a bug in original implementation caused
    /// us to fail sometimes to record an outer `impl Trait`.
    /// Therefore, in order to reliably issue a warning (rather than
    /// an error) in the *precise* places where we are newly injecting
    /// the diagnostic, we have to distinguish between the places
    /// where the outer `impl Trait` has always been recorded, versus
    /// the places where it has only recently started being recorded.
    only_recorded_since_pull_request_57730: bool,
}

impl OuterImplTrait {
    /// This controls whether we should downgrade the nested impl
    /// trait diagnostic to a warning rather than an error, based on
    /// whether the outer impl trait had been improperly skipped in
    /// earlier implementations of the analysis on the stable
    /// compiler.
    fn should_warn_instead_of_error(&self) -> bool {
        self.only_recorded_since_pull_request_57730
    }
}

struct AstValidator<'a> {
    session: &'a Session,
    has_proc_macro_decls: bool,
    has_global_allocator: bool,

    // Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
    // Nested `impl Trait` _is_ allowed in associated type position,
    // e.g `impl Iterator<Item=impl Debug>`
    outer_impl_trait: Option<OuterImplTrait>,

    // Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
    // or `Foo::Bar<impl Trait>`
    is_impl_trait_banned: bool,

    // rust-lang/rust#57979: the ban of nested `impl Trait` was buggy
    // until PRs #57730 and #57981 landed: it would jump directly to
    // walk_ty rather than visit_ty (or skip recurring entirely for
    // impl trait in projections), and thus miss some cases. We track
    // whether we should downgrade to a warning for short-term via
    // these booleans.
    warning_period_57979_didnt_record_next_impl_trait: bool,
    warning_period_57979_impl_trait_in_proj: bool,
}

impl<'a> AstValidator<'a> {
    fn with_impl_trait_in_proj_warning<T>(&mut self, v: bool, f: impl FnOnce(&mut Self) -> T) -> T {
        let old = mem::replace(&mut self.warning_period_57979_impl_trait_in_proj, v);
        let ret = f(self);
        self.warning_period_57979_impl_trait_in_proj = old;
        ret
    }

    fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
        let old = mem::replace(&mut self.is_impl_trait_banned, true);
        f(self);
        self.is_impl_trait_banned = old;
    }

    fn with_impl_trait(&mut self, outer: Option<OuterImplTrait>, f: impl FnOnce(&mut Self)) {
        let old = mem::replace(&mut self.outer_impl_trait, outer);
{'fraction_non_alphanumeric': 0.09922732818218788, 'fraction_numerical': 0.012877863630201979, 'mean_word_length': 3.7385998715478483, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4108409', 'n_tokens_mistral': 2326, 'n_tokens_neox': 2255, 'n_words': 778}