[docs.rs documentation]
This crate provides macros for creating [Dylint] libraries, and utilities for creating configurable libraries.
Contents
dylint_library!
]declare_late_lint!
, declare_early_lint!
, declare_pre_expansion_lint!
]impl_late_lint!
, impl_early_lint!
, impl_pre_expansion_lint!
]dylint_library!
The dylint_library!
macro expands to the following:
```rust
extern crate rustc_driver;
pub extern "C" fn dylintversion() -> *mut std::os::raw::cchar { std::ffi::CString::new($crate::DYLINTVERSION) .unwrap() .intoraw() } ```
If your library uses the dylint_library!
macro and the [dylint-link
] tool, then all you
should have to do is implement the [register_lints
] function. See the [examples] in this
repository.
declare_late_lint!
, etc.If your library contains just one lint, using declare_late_lint!
, etc. can make your code more
concise. Each of these macros requires the same arguments as [declare_lint!
], and wraps the
following:
dylint_library!
register_lints
functiondeclare_lint!
declare_lint_pass!
]For example, declare_late_lint!(vis NAME, Level, "description")
expands to the following:
```rust dylintlinting::dylintlibrary!();
extern crate rustclint; extern crate rustcsession;
pub fn registerlints(sess: &rustcsession::Session, lintstore: &mut rustclint::LintStore) { dylintlinting::initconfig(sess); lintstore.registerlints(&[NAME]); lintstore.registerlatepass(|| Box::new(Name)); }
rustcsession::declarelint!(vis NAME, Level, "description");
rustcsession::declarelint_pass!(Name => [NAME]); ```
declare_early_lint!
and declare_pre_expansion_lint!
are defined similarly.
impl_late_lint!
, etc.impl_late_lint!
, etc. are like declare_late_lint!
, etc. except:
impl_lint_pass!
] instead of declare_lint_pass!
;LintPass
]
structure.That is, impl_late_lint!
's additional argument is what goes here:
rust
lint_store.register_late_pass(|_| Box::new(...));
^^^
An example use of impl_pre_expansion_lint!
can be found in [env_cargo_path
] in this
repository.
Libraries can be configured by including a dylint.toml
file in the target workspace's root
directory. This crate provides the following functions for reading and parsing dylint.toml
files:
config_or_default
]config
]config_toml
]init_config
]try_init_config
]A configurable library containing just one lint will typically have a lib.rs
file of the
following form:
```rust dylintlinting::impllate_lint! { ..., LintName::new() }
// Lint configuration
struct Config {
boolean: bool,
strings: Vec
// Keep a copy of the configuration in the LintPass
structure.
struct LintName {
config: Config,
}
// Read the configuration from the dylint.toml
file, or use the default configuration if
// none is present.
impl LintName {
pub fn new() -> Self {
Self {
config: dylintlinting::configordefault(env!("CARGOPKG_NAME")),
}
}
}
```
For a concrete example of a lib.rs
file with this form, see the
[non_local_effect_before_error_return
] library in this repository.
A library containing more than one lint must implement the register_lints
function without
relying on the above macros. If the library is configurable, then its register_lints
function
should include a call to dylint_linting::init_config
, as in the following example:
```rust
pub fn registerlints(sess: &rustcsession::Session, lintstore: &mut rustclint::LintStore) {
// init_config
or try_init_config
must be called before config_or_default
, config
,
// or config_toml
is called.
dylintlinting::initconfig(sess);
lint_store.register_lints(&[FIRST_LINT_NAME, SECOND_LINT_NAME]);
lint_store.register_late_pass(|_| Box::new(LintPassName::new()));
} ```
Additional documentation on config_or_default
, etc. can be found on [docs.rs].