]> git.lizzy.rs Git - rust.git/blob - src/librustc_session/lint.rs
Move Lint to rustc_session
[rust.git] / src / librustc_session / lint.rs
1 use syntax_pos::{Symbol, sym};
2 use syntax_pos::edition::Edition;
3 pub use self::Level::*;
4
5 /// Setting for how to handle a lint.
6 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
7 pub enum Level {
8     Allow, Warn, Deny, Forbid,
9 }
10
11 rustc_data_structures::impl_stable_hash_via_hash!(Level);
12
13 impl Level {
14     /// Converts a level to a lower-case string.
15     pub fn as_str(self) -> &'static str {
16         match self {
17             Level::Allow => "allow",
18             Level::Warn => "warn",
19             Level::Deny => "deny",
20             Level::Forbid => "forbid",
21         }
22     }
23
24     /// Converts a lower-case string to a level.
25     pub fn from_str(x: &str) -> Option<Level> {
26         match x {
27             "allow" => Some(Level::Allow),
28             "warn" => Some(Level::Warn),
29             "deny" => Some(Level::Deny),
30             "forbid" => Some(Level::Forbid),
31             _ => None,
32         }
33     }
34
35     /// Converts a symbol to a level.
36     pub fn from_symbol(x: Symbol) -> Option<Level> {
37         match x {
38             sym::allow => Some(Level::Allow),
39             sym::warn => Some(Level::Warn),
40             sym::deny => Some(Level::Deny),
41             sym::forbid => Some(Level::Forbid),
42             _ => None,
43         }
44     }
45 }
46
47 /// Specification of a single lint.
48 #[derive(Copy, Clone, Debug)]
49 pub struct Lint {
50     /// A string identifier for the lint.
51     ///
52     /// This identifies the lint in attributes and in command-line arguments.
53     /// In those contexts it is always lowercase, but this field is compared
54     /// in a way which is case-insensitive for ASCII characters. This allows
55     /// `declare_lint!()` invocations to follow the convention of upper-case
56     /// statics without repeating the name.
57     ///
58     /// The name is written with underscores, e.g., "unused_imports".
59     /// On the command line, underscores become dashes.
60     pub name: &'static str,
61
62     /// Default level for the lint.
63     pub default_level: Level,
64
65     /// Description of the lint or the issue it detects.
66     ///
67     /// e.g., "imports that are never used"
68     pub desc: &'static str,
69
70     /// Starting at the given edition, default to the given lint level. If this is `None`, then use
71     /// `default_level`.
72     pub edition_lint_opts: Option<(Edition, Level)>,
73
74     /// `true` if this lint is reported even inside expansions of external macros.
75     pub report_in_external_macro: bool,
76
77     pub future_incompatible: Option<FutureIncompatibleInfo>,
78
79     pub is_plugin: bool,
80 }
81
82 /// Extra information for a future incompatibility lint.
83 #[derive(Copy, Clone, Debug)]
84 pub struct FutureIncompatibleInfo {
85     /// e.g., a URL for an issue/PR/RFC or error code
86     pub reference: &'static str,
87     /// If this is an edition fixing lint, the edition in which
88     /// this lint becomes obsolete
89     pub edition: Option<Edition>,
90 }
91
92 impl Lint {
93     pub const fn default_fields_for_macro() -> Self {
94         Lint {
95             name: "",
96             default_level: Level::Forbid,
97             desc: "",
98             edition_lint_opts: None,
99             is_plugin: false,
100             report_in_external_macro: false,
101             future_incompatible: None,
102         }
103     }
104
105     /// Gets the lint's name, with ASCII letters converted to lowercase.
106     pub fn name_lower(&self) -> String {
107         self.name.to_ascii_lowercase()
108     }
109
110     pub fn default_level(&self, edition: Edition) -> Level {
111         self.edition_lint_opts
112             .filter(|(e, _)| *e <= edition)
113             .map(|(_, l)| l)
114             .unwrap_or(self.default_level)
115     }
116 }