use std::ascii::AsciiExt;
use syntax::codemap::Span;
use rustc_front::visit::FnKind;
+use syntax::visit as ast_visit;
use syntax::ast;
use rustc_front::hir;
-pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate, gather_attrs,
+pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
+ raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
GatherNodeLevels};
/// Specification of a single lint.
/// Declare a static item of type `&'static Lint`.
#[macro_export]
macro_rules! declare_lint {
- // FIXME(#14660): deduplicate
(pub $name:ident, $level:ident, $desc:expr) => (
pub static $name: &'static ::rustc::lint::Lint
= &lint_initializer!($name, $level, $desc);
pub type LintArray = &'static [&'static &'static Lint];
-/// Trait for types providing lint checks.
-///
-/// Each `check` method checks a single syntax node, and should not
-/// invoke methods recursively (unlike `Visitor`). By default they
-/// do nothing.
-//
-// FIXME: eliminate the duplication with `Visitor`. But this also
-// contains a few lint-specific methods with no equivalent in `Visitor`.
pub trait LintPass {
/// Get descriptions of the lints this `LintPass` object can emit.
///
/// parts of the compiler. If you want enforced access restrictions for your
/// `Lint`, make it a private `static` item in its own module.
fn get_lints(&self) -> LintArray;
+}
+
- fn check_crate(&mut self, _: &Context, _: &hir::Crate) { }
- fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) { }
- fn check_mod(&mut self, _: &Context, _: &hir::Mod, _: Span, _: ast::NodeId) { }
- fn check_foreign_item(&mut self, _: &Context, _: &hir::ForeignItem) { }
- fn check_item(&mut self, _: &Context, _: &hir::Item) { }
- fn check_local(&mut self, _: &Context, _: &hir::Local) { }
- fn check_block(&mut self, _: &Context, _: &hir::Block) { }
- fn check_stmt(&mut self, _: &Context, _: &hir::Stmt) { }
- fn check_arm(&mut self, _: &Context, _: &hir::Arm) { }
- fn check_pat(&mut self, _: &Context, _: &hir::Pat) { }
- fn check_decl(&mut self, _: &Context, _: &hir::Decl) { }
- fn check_expr(&mut self, _: &Context, _: &hir::Expr) { }
- fn check_expr_post(&mut self, _: &Context, _: &hir::Expr) { }
- fn check_ty(&mut self, _: &Context, _: &hir::Ty) { }
- fn check_generics(&mut self, _: &Context, _: &hir::Generics) { }
- fn check_fn(&mut self, _: &Context,
+/// Trait for types providing lint checks.
+///
+/// Each `check` method checks a single syntax node, and should not
+/// invoke methods recursively (unlike `Visitor`). By default they
+/// do nothing.
+//
+// FIXME: eliminate the duplication with `Visitor`. But this also
+// contains a few lint-specific methods with no equivalent in `Visitor`.
+pub trait LateLintPass: LintPass {
+ fn check_name(&mut self, _: &LateContext, _: Span, _: ast::Name) { }
+ fn check_crate(&mut self, _: &LateContext, _: &hir::Crate) { }
+ fn check_mod(&mut self, _: &LateContext, _: &hir::Mod, _: Span, _: ast::NodeId) { }
+ fn check_foreign_item(&mut self, _: &LateContext, _: &hir::ForeignItem) { }
+ fn check_item(&mut self, _: &LateContext, _: &hir::Item) { }
+ fn check_local(&mut self, _: &LateContext, _: &hir::Local) { }
+ fn check_block(&mut self, _: &LateContext, _: &hir::Block) { }
+ fn check_stmt(&mut self, _: &LateContext, _: &hir::Stmt) { }
+ fn check_arm(&mut self, _: &LateContext, _: &hir::Arm) { }
+ fn check_pat(&mut self, _: &LateContext, _: &hir::Pat) { }
+ fn check_decl(&mut self, _: &LateContext, _: &hir::Decl) { }
+ fn check_expr(&mut self, _: &LateContext, _: &hir::Expr) { }
+ fn check_expr_post(&mut self, _: &LateContext, _: &hir::Expr) { }
+ fn check_ty(&mut self, _: &LateContext, _: &hir::Ty) { }
+ fn check_generics(&mut self, _: &LateContext, _: &hir::Generics) { }
+ fn check_fn(&mut self, _: &LateContext,
_: FnKind, _: &hir::FnDecl, _: &hir::Block, _: Span, _: ast::NodeId) { }
- fn check_trait_item(&mut self, _: &Context, _: &hir::TraitItem) { }
- fn check_impl_item(&mut self, _: &Context, _: &hir::ImplItem) { }
- fn check_struct_def(&mut self, _: &Context,
- _: &hir::StructDef, _: ast::Ident, _: &hir::Generics, _: ast::NodeId) { }
- fn check_struct_def_post(&mut self, _: &Context,
- _: &hir::StructDef, _: ast::Ident, _: &hir::Generics, _: ast::NodeId) { }
- fn check_struct_field(&mut self, _: &Context, _: &hir::StructField) { }
- fn check_variant(&mut self, _: &Context, _: &hir::Variant, _: &hir::Generics) { }
- fn check_variant_post(&mut self, _: &Context, _: &hir::Variant, _: &hir::Generics) { }
- fn check_opt_lifetime_ref(&mut self, _: &Context, _: Span, _: &Option<hir::Lifetime>) { }
- fn check_lifetime_ref(&mut self, _: &Context, _: &hir::Lifetime) { }
- fn check_lifetime_def(&mut self, _: &Context, _: &hir::LifetimeDef) { }
- fn check_explicit_self(&mut self, _: &Context, _: &hir::ExplicitSelf) { }
- fn check_mac(&mut self, _: &Context, _: &ast::Mac) { }
- fn check_path(&mut self, _: &Context, _: &hir::Path, _: ast::NodeId) { }
- fn check_attribute(&mut self, _: &Context, _: &ast::Attribute) { }
+ fn check_trait_item(&mut self, _: &LateContext, _: &hir::TraitItem) { }
+ fn check_impl_item(&mut self, _: &LateContext, _: &hir::ImplItem) { }
+ fn check_struct_def(&mut self, _: &LateContext,
+ _: &hir::StructDef, _: ast::Name, _: &hir::Generics, _: ast::NodeId) { }
+ fn check_struct_def_post(&mut self, _: &LateContext,
+ _: &hir::StructDef, _: ast::Name, _: &hir::Generics, _: ast::NodeId) { }
+ fn check_struct_field(&mut self, _: &LateContext, _: &hir::StructField) { }
+ fn check_variant(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
+ fn check_variant_post(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
+ fn check_lifetime(&mut self, _: &LateContext, _: &hir::Lifetime) { }
+ fn check_lifetime_def(&mut self, _: &LateContext, _: &hir::LifetimeDef) { }
+ fn check_explicit_self(&mut self, _: &LateContext, _: &hir::ExplicitSelf) { }
+ fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { }
+ fn check_path_list_item(&mut self, _: &LateContext, _: &hir::PathListItem) { }
+ fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { }
+
+ /// Called when entering a syntax node that can have lint attributes such
+ /// as `#[allow(...)]`. Called with *all* the attributes of that node.
+ fn enter_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) { }
+
+ /// Counterpart to `enter_lint_attrs`.
+ fn exit_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) { }
+}
+
+pub trait EarlyLintPass: LintPass {
+ fn check_ident(&mut self, _: &EarlyContext, _: Span, _: ast::Ident) { }
+ fn check_crate(&mut self, _: &EarlyContext, _: &ast::Crate) { }
+ fn check_mod(&mut self, _: &EarlyContext, _: &ast::Mod, _: Span, _: ast::NodeId) { }
+ fn check_foreign_item(&mut self, _: &EarlyContext, _: &ast::ForeignItem) { }
+ fn check_item(&mut self, _: &EarlyContext, _: &ast::Item) { }
+ fn check_local(&mut self, _: &EarlyContext, _: &ast::Local) { }
+ fn check_block(&mut self, _: &EarlyContext, _: &ast::Block) { }
+ fn check_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { }
+ fn check_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { }
+ fn check_pat(&mut self, _: &EarlyContext, _: &ast::Pat) { }
+ fn check_decl(&mut self, _: &EarlyContext, _: &ast::Decl) { }
+ fn check_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
+ fn check_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
+ fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
+ fn check_generics(&mut self, _: &EarlyContext, _: &ast::Generics) { }
+ fn check_fn(&mut self, _: &EarlyContext,
+ _: ast_visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
+ fn check_trait_item(&mut self, _: &EarlyContext, _: &ast::TraitItem) { }
+ fn check_impl_item(&mut self, _: &EarlyContext, _: &ast::ImplItem) { }
+ fn check_struct_def(&mut self, _: &EarlyContext,
+ _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
+ fn check_struct_def_post(&mut self, _: &EarlyContext,
+ _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
+ fn check_struct_field(&mut self, _: &EarlyContext, _: &ast::StructField) { }
+ fn check_variant(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
+ fn check_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
+ fn check_lifetime(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
+ fn check_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { }
+ fn check_explicit_self(&mut self, _: &EarlyContext, _: &ast::ExplicitSelf) { }
+ fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
+ fn check_path_list_item(&mut self, _: &EarlyContext, _: &ast::PathListItem) { }
+ fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }
/// Called when entering a syntax node that can have lint attributes such
/// as `#[allow(...)]`. Called with *all* the attributes of that node.
- fn enter_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) { }
+ fn enter_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }
/// Counterpart to `enter_lint_attrs`.
- fn exit_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) { }
+ fn exit_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }
}
/// A lint pass boxed up as a trait object.
-pub type LintPassObject = Box<LintPass + 'static>;
+pub type EarlyLintPassObject = Box<EarlyLintPass + 'static>;
+pub type LateLintPassObject = Box<LateLintPass + 'static>;
/// Identifies a lint known to the compiler.
#[derive(Clone, Copy)]