]> git.lizzy.rs Git - rust.git/blob - src/librustc/lint/builtin.rs
Auto merge of #50763 - KyleStach1678:unused-loop-label, r=petrochenkov
[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     Deny,
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_CONSTRUCTOR_VISIBILITY,
181     Deny,
182     "detects use of struct constructors that would be invisible with new visibility rules"
183 }
184
185 declare_lint! {
186     pub MISSING_FRAGMENT_SPECIFIER,
187     Deny,
188     "detects missing fragment specifiers in unused `macro_rules!` patterns"
189 }
190
191 declare_lint! {
192     pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
193     Deny,
194     "detects parenthesized generic parameters in type and module names"
195 }
196
197 declare_lint! {
198     pub LATE_BOUND_LIFETIME_ARGUMENTS,
199     Warn,
200     "detects generic lifetime arguments in path segments with late bound lifetime parameters"
201 }
202
203 declare_lint! {
204     pub INCOHERENT_FUNDAMENTAL_IMPLS,
205     Deny,
206     "potentially-conflicting impls were erroneously allowed"
207 }
208
209 declare_lint! {
210     pub DEPRECATED,
211     Warn,
212     "detects use of deprecated items"
213 }
214
215 declare_lint! {
216     pub UNUSED_UNSAFE,
217     Warn,
218     "unnecessary use of an `unsafe` block"
219 }
220
221 declare_lint! {
222     pub UNUSED_MUT,
223     Warn,
224     "detect mut variables which don't need to be mutable"
225 }
226
227 declare_lint! {
228     pub SINGLE_USE_LIFETIME,
229     Allow,
230     "detects lifetime parameters that are only used once"
231 }
232
233 declare_lint! {
234     pub UNUSED_LIFETIME,
235     Allow,
236     "detects lifetime parameters that are never used"
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_NOT_STARTING_WITH_CRATE,
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 declare_lint! {
277     pub UNUSED_LABELS,
278     Allow,
279     "detects labels that are never used"
280 }
281
282 /// Does nothing as a lint pass, but registers some `Lint`s
283 /// which are used by other parts of the compiler.
284 #[derive(Copy, Clone)]
285 pub struct HardwiredLints;
286
287 impl LintPass for HardwiredLints {
288     fn get_lints(&self) -> LintArray {
289         lint_array!(
290             ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
291             EXCEEDING_BITSHIFTS,
292             UNUSED_IMPORTS,
293             UNUSED_EXTERN_CRATES,
294             UNUSED_QUALIFICATIONS,
295             UNKNOWN_LINTS,
296             UNUSED_VARIABLES,
297             UNUSED_ASSIGNMENTS,
298             DEAD_CODE,
299             UNREACHABLE_CODE,
300             UNREACHABLE_PATTERNS,
301             UNUSED_MACROS,
302             WARNINGS,
303             UNUSED_FEATURES,
304             STABLE_FEATURES,
305             UNKNOWN_CRATE_TYPES,
306             TRIVIAL_CASTS,
307             TRIVIAL_NUMERIC_CASTS,
308             PRIVATE_IN_PUBLIC,
309             PUB_USE_OF_PRIVATE_EXTERN_CRATE,
310             INVALID_TYPE_PARAM_DEFAULT,
311             CONST_ERR,
312             RENAMED_AND_REMOVED_LINTS,
313             SAFE_EXTERN_STATICS,
314             SAFE_PACKED_BORROWS,
315             PATTERNS_IN_FNS_WITHOUT_BODY,
316             LEGACY_DIRECTORY_OWNERSHIP,
317             LEGACY_CONSTRUCTOR_VISIBILITY,
318             MISSING_FRAGMENT_SPECIFIER,
319             PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
320             LATE_BOUND_LIFETIME_ARGUMENTS,
321             INCOHERENT_FUNDAMENTAL_IMPLS,
322             DEPRECATED,
323             UNUSED_UNSAFE,
324             UNUSED_MUT,
325             SINGLE_USE_LIFETIME,
326             UNUSED_LIFETIME,
327             UNUSED_LABELS,
328             TYVAR_BEHIND_RAW_POINTER,
329             ELIDED_LIFETIME_IN_PATH,
330             BARE_TRAIT_OBJECT,
331             ABSOLUTE_PATH_NOT_STARTING_WITH_CRATE,
332             UNSTABLE_NAME_COLLISION,
333         )
334     }
335 }
336
337 // this could be a closure, but then implementing derive traits
338 // becomes hacky (and it gets allocated)
339 #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
340 pub enum BuiltinLintDiagnostics {
341     Normal,
342     BareTraitObject(Span, /* is_global */ bool),
343     AbsPathWithModule(Span),
344 }
345
346 impl BuiltinLintDiagnostics {
347     pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder) {
348         match self {
349             BuiltinLintDiagnostics::Normal => (),
350             BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
351                 let (sugg, app) = match sess.codemap().span_to_snippet(span) {
352                     Ok(ref s) if is_global => (format!("dyn ({})", s),
353                                                Applicability::MachineApplicable),
354                     Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
355                     Err(_) => (format!("dyn <type>"), Applicability::HasPlaceholders)
356                 };
357                 db.span_suggestion_with_applicability(span, "use `dyn`", sugg, app);
358             }
359             BuiltinLintDiagnostics::AbsPathWithModule(span) => {
360                 let (sugg, app) = match sess.codemap().span_to_snippet(span) {
361                     Ok(ref s) => {
362                         // FIXME(Manishearth) ideally the emitting code
363                         // can tell us whether or not this is global
364                         let opt_colon = if s.trim_left().starts_with("::") {
365                             ""
366                         } else {
367                             "::"
368                         };
369
370                         (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
371                     }
372                     Err(_) => (format!("crate::<path>"), Applicability::HasPlaceholders)
373                 };
374                 db.span_suggestion_with_applicability(span, "use `crate`", sugg, app);
375             }
376         }
377     }
378 }
379
380 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}