dylint_linting

[docs.rs documentation]

This crate provides macros for creating [Dylint] libraries, and utilities for creating configurable libraries.

Contents

dylint_library!

The dylint_library! macro expands to the following:

```rust

[allow(unusedexterncrates)]

extern crate rustc_driver;

[no_mangle]

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:

For example, declare_late_lint!(vis NAME, Level, "description") expands to the following:

```rust dylintlinting::dylintlibrary!();

extern crate rustclint; extern crate rustcsession;

[no_mangle]

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:

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.

constituent feature

Enabling the package-level constituent feature changes the way the above macros work. Specifically, it causes them to exclude:

Such changes facilitate inclusion of a lint declared with one of the above macros into a larger library. That is:

The [general-purpose] and [supplementary] lints in this repository employ this technique. That is, each general-purpose lint can be built as a library by itself, or as part of the [general library]. An analogous statement applies to the supplementary lints and the [supplementary library]. The constituent feature is the underlying mechanism that makes this work.

Configurable libraries

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:

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

[derive(Default, serde::Deserialize)]

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

[no_mangle]

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].