1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use super::MessageLevel;
use std::hash::{Hash, Hasher};

pub type LintArray = Vec<&'static Lint>;

#[derive(Debug, Copy, Clone)]
pub struct Lint {
    pub name: &'static str,
    pub level: MessageLevel,
    pub desc: &'static str,
}

#[macro_export]
macro_rules! declare_lint {
    ($vis:vis $NAME:ident, $Level:ident, $desc:expr) => {
        $vis static $NAME: &::diagnostics::lint::Lint = &::diagnostics::lint::Lint {
            name: stringify!($NAME),
            level: ::diagnostics::MessageLevel::$Level,
            desc: $desc,
        };
    }
}

/// Declare a static `LintArray` and return it as an expression.
#[macro_export]
macro_rules! lint_array {
    ($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) };
    ($( $lint:expr ),*) => {{
        vec![$($lint),*]
    }}
}

#[derive(Debug, Copy, Clone)]
pub struct LintId {
    lint: &'static Lint,
}

impl PartialEq for LintId {
    fn eq(&self, other: &Self) -> bool {
        std::ptr::eq(self.lint, other.lint)
    }
}

impl Eq for LintId {}

impl Hash for LintId {
    fn hash<H: Hasher>(&self, state: &mut H) {
        let ptr = self.lint as *const Lint;
        ptr.hash(state);
    }
}

impl LintId {
    pub fn of(lint: &'static Lint) -> Self {
        Self { lint }
    }

    pub fn to_string(self) -> String {
        self.lint.name.to_ascii_lowercase()
    }
}