use rustc_ast::ptr::P;
use rustc_ast::visit::{self as ast_visit, Visitor};
use rustc_ast::{self as ast, walk_list, HasAttrs};
+use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_middle::ty::RegisteredTools;
use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
use rustc_session::Session;
$cx.pass.$f(&$cx.context, $($args),*);
}) }
-/// Implements the AST traversal for early lint passes. `T` provides the the
+/// Implements the AST traversal for early lint passes. `T` provides the
/// `check_*` methods.
pub struct EarlyContextAndPass<'a, T: EarlyLintPass> {
context: EarlyContext<'a>,
impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
// This always-inlined function is for the hot call site.
#[inline(always)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
fn inlined_check_id(&mut self, id: ast::NodeId) {
for early_lint in self.context.buffered.take(id) {
let BufferedEarlyLint { span, msg, node_id: _, lint_id, diagnostic } = early_lint;
self.inlined_check_id(id);
debug!("early context: enter_attrs({:?})", attrs);
lint_callback!(self, enter_lint_attrs, attrs);
- f(self);
+ ensure_sufficient_stack(|| f(self));
debug!("early context: exit_attrs({:?})", attrs);
lint_callback!(self, exit_lint_attrs, attrs);
self.context.builder.pop(push);
}
fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
+ lint_callback!(self, enter_where_predicate, p);
ast_visit::walk_where_predicate(self, p);
+ lint_callback!(self, exit_where_predicate, p);
}
fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) {