]> git.lizzy.rs Git - rust.git/blob - src/librustc/lint/builtin.rs
Rollup merge of #50525 - nnethercote:lit_token, r=michaelwoerister
[rust.git] / src / librustc / lint / builtin.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Some lints that are built in to the compiler.
12 //!
13 //! These are the built-in lints that are emitted direct in the main
14 //! compiler code, rather than using their own custom pass. Those
15 //! lints are all available in `rustc_lint::builtin`.
16
17 use errors::{Applicability, DiagnosticBuilder};
18 use lint::{LintPass, LateLintPass, LintArray};
19 use session::Session;
20 use syntax::codemap::Span;
21
22 declare_lint! {
23     pub EXCEEDING_BITSHIFTS,
24     Deny,
25     "shift exceeds the type's number of bits"
26 }
27
28 declare_lint! {
29     pub CONST_ERR,
30     Warn,
31     "constant evaluation detected erroneous expression"
32 }
33
34 declare_lint! {
35     pub UNUSED_IMPORTS,
36     Warn,
37     "imports that are never used"
38 }
39
40 declare_lint! {
41     pub UNUSED_EXTERN_CRATES,
42     Allow,
43     "extern crates that are never used"
44 }
45
46 declare_lint! {
47     pub UNUSED_QUALIFICATIONS,
48     Allow,
49     "detects unnecessarily qualified names"
50 }
51
52 declare_lint! {
53     pub UNKNOWN_LINTS,
54     Warn,
55     "unrecognized lint attribute"
56 }
57
58 declare_lint! {
59     pub UNUSED_VARIABLES,
60     Warn,
61     "detect variables which are not used in any way"
62 }
63
64 declare_lint! {
65     pub UNUSED_ASSIGNMENTS,
66     Warn,
67     "detect assignments that will never be read"
68 }
69
70 declare_lint! {
71     pub DEAD_CODE,
72     Warn,
73     "detect unused, unexported items"
74 }
75
76 declare_lint! {
77     pub UNREACHABLE_CODE,
78     Warn,
79     "detects unreachable code paths"
80 }
81
82 declare_lint! {
83     pub UNREACHABLE_PATTERNS,
84     Warn,
85     "detects unreachable patterns"
86 }
87
88 declare_lint! {
89     pub UNUSED_MACROS,
90     Warn,
91     "detects macros that were not used"
92 }
93
94 declare_lint! {
95     pub WARNINGS,
96     Warn,
97     "mass-change the level for lints which produce warnings"
98 }
99
100 declare_lint! {
101     pub UNUSED_FEATURES,
102     Warn,
103     "unused or unknown features found in crate-level #[feature] directives"
104 }
105
106 declare_lint! {
107     pub STABLE_FEATURES,
108     Warn,
109     "stable features found in #[feature] directive"
110 }
111
112 declare_lint! {
113     pub UNKNOWN_CRATE_TYPES,
114     Deny,
115     "unknown crate type found in #[crate_type] directive"
116 }
117
118 declare_lint! {
119     pub TRIVIAL_CASTS,
120     Allow,
121     "detects trivial casts which could be removed"
122 }
123
124 declare_lint! {
125     pub TRIVIAL_NUMERIC_CASTS,
126     Allow,
127     "detects trivial casts of numeric types which could be removed"
128 }
129
130 declare_lint! {
131     pub PRIVATE_IN_PUBLIC,
132     Warn,
133     "detect private items in public interfaces not caught by the old implementation"
134 }
135
136 declare_lint! {
137     pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
138     Deny,
139     "detect public re-exports of private extern crates"
140 }
141
142 declare_lint! {
143     pub INVALID_TYPE_PARAM_DEFAULT,
144     Deny,
145     "type parameter default erroneously allowed in invalid location"
146 }
147
148 declare_lint! {
149     pub RENAMED_AND_REMOVED_LINTS,
150     Warn,
151     "lints that have been renamed or removed"
152 }
153
154 declare_lint! {
155     pub SAFE_EXTERN_STATICS,
156     Deny,
157     "safe access to extern statics was erroneously allowed"
158 }
159
160 declare_lint! {
161     pub SAFE_PACKED_BORROWS,
162     Warn,
163     "safe borrows of fields of packed structs were was erroneously allowed"
164 }
165
166 declare_lint! {
167     pub PATTERNS_IN_FNS_WITHOUT_BODY,
168     Warn,
169     "patterns in functions without body were erroneously allowed"
170 }
171
172 declare_lint! {
173     pub LEGACY_DIRECTORY_OWNERSHIP,
174     Deny,
175     "non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files \
176      not named `mod.rs`"
177 }
178
179 declare_lint! {
180     pub LEGACY_IMPORTS,
181     Deny,
182     "detects names that resolve to ambiguous glob imports with RFC 1560"
183 }
184
185 declare_lint! {
186     pub LEGACY_CONSTRUCTOR_VISIBILITY,
187     Deny,
188     "detects use of struct constructors that would be invisible with new visibility rules"
189 }
190
191 declare_lint! {
192     pub MISSING_FRAGMENT_SPECIFIER,
193     Deny,
194     "detects missing fragment specifiers in unused `macro_rules!` patterns"
195 }
196
197 declare_lint! {
198     pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
199     Deny,
200     "detects parenthesized generic parameters in type and module names"
201 }
202
203 declare_lint! {
204     pub LATE_BOUND_LIFETIME_ARGUMENTS,
205     Warn,
206     "detects generic lifetime arguments in path segments with late bound lifetime parameters"
207 }
208
209 declare_lint! {
210     pub INCOHERENT_FUNDAMENTAL_IMPLS,
211     Deny,
212     "potentially-conflicting impls were erroneously allowed"
213 }
214
215 declare_lint! {
216     pub DEPRECATED,
217     Warn,
218     "detects use of deprecated items"
219 }
220
221 declare_lint! {
222     pub UNUSED_UNSAFE,
223     Warn,
224     "unnecessary use of an `unsafe` block"
225 }
226
227 declare_lint! {
228     pub UNUSED_MUT,
229     Warn,
230     "detect mut variables which don't need to be mutable"
231 }
232
233 declare_lint! {
234     pub SINGLE_USE_LIFETIME,
235     Allow,
236    "detects single use lifetimes"
237 }
238
239 declare_lint! {
240     pub TYVAR_BEHIND_RAW_POINTER,
241     Warn,
242     "raw pointer to an inference variable"
243 }
244
245 declare_lint! {
246     pub ELIDED_LIFETIME_IN_PATH,
247     Allow,
248     "hidden lifetime parameters are deprecated, try `Foo<'_>`"
249 }
250
251 declare_lint! {
252     pub BARE_TRAIT_OBJECT,
253     Allow,
254     "suggest using `dyn Trait` for trait objects"
255 }
256
257 declare_lint! {
258     pub ABSOLUTE_PATH_STARTING_WITH_MODULE,
259     Allow,
260     "fully qualified paths that start with a module name \
261      instead of `crate`, `self`, or an extern crate name"
262 }
263
264 declare_lint! {
265     pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
266     Warn,
267     "floating-point literals cannot be used in patterns"
268 }
269
270 declare_lint! {
271     pub UNSTABLE_NAME_COLLISION,
272     Warn,
273     "detects name collision with an existing but unstable method"
274 }
275
276 /// Does nothing as a lint pass, but registers some `Lint`s
277 /// which are used by other parts of the compiler.
278 #[derive(Copy, Clone)]
279 pub struct HardwiredLints;
280
281 impl LintPass for HardwiredLints {
282     fn get_lints(&self) -> LintArray {
283         lint_array!(
284             ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
285             EXCEEDING_BITSHIFTS,
286             UNUSED_IMPORTS,
287             UNUSED_EXTERN_CRATES,
288             UNUSED_QUALIFICATIONS,
289             UNKNOWN_LINTS,
290             UNUSED_VARIABLES,
291             UNUSED_ASSIGNMENTS,
292             DEAD_CODE,
293             UNREACHABLE_CODE,
294             UNREACHABLE_PATTERNS,
295             UNUSED_MACROS,
296             WARNINGS,
297             UNUSED_FEATURES,
298             STABLE_FEATURES,
299             UNKNOWN_CRATE_TYPES,
300             TRIVIAL_CASTS,
301             TRIVIAL_NUMERIC_CASTS,
302             PRIVATE_IN_PUBLIC,
303             PUB_USE_OF_PRIVATE_EXTERN_CRATE,
304             INVALID_TYPE_PARAM_DEFAULT,
305             CONST_ERR,
306             RENAMED_AND_REMOVED_LINTS,
307             SAFE_EXTERN_STATICS,
308             SAFE_PACKED_BORROWS,
309             PATTERNS_IN_FNS_WITHOUT_BODY,
310             LEGACY_DIRECTORY_OWNERSHIP,
311             LEGACY_IMPORTS,
312             LEGACY_CONSTRUCTOR_VISIBILITY,
313             MISSING_FRAGMENT_SPECIFIER,
314             PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
315             LATE_BOUND_LIFETIME_ARGUMENTS,
316             INCOHERENT_FUNDAMENTAL_IMPLS,
317             DEPRECATED,
318             UNUSED_UNSAFE,
319             UNUSED_MUT,
320             SINGLE_USE_LIFETIME,
321             TYVAR_BEHIND_RAW_POINTER,
322             ELIDED_LIFETIME_IN_PATH,
323             BARE_TRAIT_OBJECT,
324             ABSOLUTE_PATH_STARTING_WITH_MODULE,
325             UNSTABLE_NAME_COLLISION,
326         )
327     }
328 }
329
330 // this could be a closure, but then implementing derive traits
331 // becomes hacky (and it gets allocated)
332 #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
333 pub enum BuiltinLintDiagnostics {
334     Normal,
335     BareTraitObject(Span, /* is_global */ bool),
336     AbsPathWithModule(Span),
337 }
338
339 impl BuiltinLintDiagnostics {
340     pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder) {
341         match self {
342             BuiltinLintDiagnostics::Normal => (),
343             BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
344                 let (sugg, app) = match sess.codemap().span_to_snippet(span) {
345                     Ok(ref s) if is_global => (format!("dyn ({})", s),
346                                                Applicability::MachineApplicable),
347                     Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
348                     Err(_) => (format!("dyn <type>"), Applicability::HasPlaceholders)
349                 };
350                 db.span_suggestion_with_applicability(span, "use `dyn`", sugg, app);
351             }
352             BuiltinLintDiagnostics::AbsPathWithModule(span) => {
353                 let (sugg, app) = match sess.codemap().span_to_snippet(span) {
354                     Ok(ref s) => {
355                         // FIXME(Manishearth) ideally the emitting code
356                         // can tell us whether or not this is global
357                         let opt_colon = if s.trim_left().starts_with("::") {
358                             ""
359                         } else {
360                             "::"
361                         };
362
363                         (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
364                     }
365                     Err(_) => (format!("crate::<path>"), Applicability::HasPlaceholders)
366                 };
367                 db.span_suggestion_with_applicability(span, "use `crate`", sugg, app);
368             }
369         }
370     }
371 }
372
373 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}