]> git.lizzy.rs Git - rust.git/blob - src/librustc/lint/builtin.rs
Auto merge of #56863 - arielb1:supertrait-self-4, r=nikomatsakis
[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::ast;
21 use syntax::source_map::Span;
22
23 declare_lint! {
24     pub EXCEEDING_BITSHIFTS,
25     Deny,
26     "shift exceeds the type's number of bits"
27 }
28
29 declare_lint! {
30     pub CONST_ERR,
31     Deny,
32     "constant evaluation detected erroneous expression"
33 }
34
35 declare_lint! {
36     pub UNUSED_IMPORTS,
37     Warn,
38     "imports that are never used"
39 }
40
41 declare_lint! {
42     pub UNUSED_EXTERN_CRATES,
43     Allow,
44     "extern crates that are never used"
45 }
46
47 declare_lint! {
48     pub UNUSED_QUALIFICATIONS,
49     Allow,
50     "detects unnecessarily qualified names"
51 }
52
53 declare_lint! {
54     pub UNKNOWN_LINTS,
55     Warn,
56     "unrecognized lint attribute"
57 }
58
59 declare_lint! {
60     pub UNUSED_VARIABLES,
61     Warn,
62     "detect variables which are not used in any way"
63 }
64
65 declare_lint! {
66     pub UNUSED_ASSIGNMENTS,
67     Warn,
68     "detect assignments that will never be read"
69 }
70
71 declare_lint! {
72     pub DEAD_CODE,
73     Warn,
74     "detect unused, unexported items"
75 }
76
77 declare_lint! {
78     pub UNREACHABLE_CODE,
79     Warn,
80     "detects unreachable code paths",
81     report_in_external_macro: true
82 }
83
84 declare_lint! {
85     pub UNREACHABLE_PATTERNS,
86     Warn,
87     "detects unreachable patterns"
88 }
89
90 declare_lint! {
91     pub UNUSED_MACROS,
92     Warn,
93     "detects macros that were not used"
94 }
95
96 declare_lint! {
97     pub WARNINGS,
98     Warn,
99     "mass-change the level for lints which produce warnings"
100 }
101
102 declare_lint! {
103     pub UNUSED_FEATURES,
104     Warn,
105     "unused features found in crate-level #[feature] directives"
106 }
107
108 declare_lint! {
109     pub STABLE_FEATURES,
110     Warn,
111     "stable features found in #[feature] directive"
112 }
113
114 declare_lint! {
115     pub UNKNOWN_CRATE_TYPES,
116     Deny,
117     "unknown crate type found in #[crate_type] directive"
118 }
119
120 declare_lint! {
121     pub TRIVIAL_CASTS,
122     Allow,
123     "detects trivial casts which could be removed"
124 }
125
126 declare_lint! {
127     pub TRIVIAL_NUMERIC_CASTS,
128     Allow,
129     "detects trivial casts of numeric types which could be removed"
130 }
131
132 declare_lint! {
133     pub PRIVATE_IN_PUBLIC,
134     Warn,
135     "detect private items in public interfaces not caught by the old implementation"
136 }
137
138 declare_lint! {
139     pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
140     Deny,
141     "detect public re-exports of private extern crates"
142 }
143
144 declare_lint! {
145     pub INVALID_TYPE_PARAM_DEFAULT,
146     Deny,
147     "type parameter default erroneously allowed in invalid location"
148 }
149
150 declare_lint! {
151     pub RENAMED_AND_REMOVED_LINTS,
152     Warn,
153     "lints that have been renamed or removed"
154 }
155
156 declare_lint! {
157     pub SAFE_EXTERN_STATICS,
158     Deny,
159     "safe access to extern statics was erroneously allowed"
160 }
161
162 declare_lint! {
163     pub SAFE_PACKED_BORROWS,
164     Warn,
165     "safe borrows of fields of packed structs were was erroneously allowed"
166 }
167
168 declare_lint! {
169     pub PATTERNS_IN_FNS_WITHOUT_BODY,
170     Warn,
171     "patterns in functions without body were erroneously allowed"
172 }
173
174 declare_lint! {
175     pub LEGACY_DIRECTORY_OWNERSHIP,
176     Deny,
177     "non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \
178      not named `mod.rs`"
179 }
180
181 declare_lint! {
182     pub LEGACY_CONSTRUCTOR_VISIBILITY,
183     Deny,
184     "detects use of struct constructors that would be invisible with new visibility rules"
185 }
186
187 declare_lint! {
188     pub MISSING_FRAGMENT_SPECIFIER,
189     Deny,
190     "detects missing fragment specifiers in unused `macro_rules!` patterns"
191 }
192
193 declare_lint! {
194     pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
195     Deny,
196     "detects parenthesized generic parameters in type and module names"
197 }
198
199 declare_lint! {
200     pub LATE_BOUND_LIFETIME_ARGUMENTS,
201     Warn,
202     "detects generic lifetime arguments in path segments with late bound lifetime parameters"
203 }
204
205 declare_lint! {
206     pub INCOHERENT_FUNDAMENTAL_IMPLS,
207     Deny,
208     "potentially-conflicting impls were erroneously allowed"
209 }
210
211 declare_lint! {
212     pub ORDER_DEPENDENT_TRAIT_OBJECTS,
213     Deny,
214     "trait-object types were treated as different depending on marker-trait order"
215 }
216
217 declare_lint! {
218     pub BAD_REPR,
219     Warn,
220     "detects incorrect use of `repr` attribute"
221 }
222
223 declare_lint! {
224     pub DEPRECATED,
225     Warn,
226     "detects use of deprecated items",
227     report_in_external_macro: true
228 }
229
230 declare_lint! {
231     pub UNUSED_UNSAFE,
232     Warn,
233     "unnecessary use of an `unsafe` block"
234 }
235
236 declare_lint! {
237     pub UNUSED_MUT,
238     Warn,
239     "detect mut variables which don't need to be mutable"
240 }
241
242 declare_lint! {
243     pub UNCONDITIONAL_RECURSION,
244     Warn,
245     "functions that cannot return without calling themselves"
246 }
247
248 declare_lint! {
249     pub SINGLE_USE_LIFETIMES,
250     Allow,
251     "detects lifetime parameters that are only used once"
252 }
253
254 declare_lint! {
255     pub UNUSED_LIFETIMES,
256     Allow,
257     "detects lifetime parameters that are never used"
258 }
259
260 declare_lint! {
261     pub TYVAR_BEHIND_RAW_POINTER,
262     Warn,
263     "raw pointer to an inference variable"
264 }
265
266 declare_lint! {
267     pub ELIDED_LIFETIMES_IN_PATHS,
268     Allow,
269     "hidden lifetime parameters in types are deprecated"
270 }
271
272 declare_lint! {
273     pub BARE_TRAIT_OBJECTS,
274     Allow,
275     "suggest using `dyn Trait` for trait objects"
276 }
277
278 declare_lint! {
279     pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
280     Allow,
281     "fully qualified paths that start with a module name \
282      instead of `crate`, `self`, or an extern crate name"
283 }
284
285 declare_lint! {
286     pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
287     Warn,
288     "floating-point literals cannot be used in patterns"
289 }
290
291 declare_lint! {
292     pub UNSTABLE_NAME_COLLISIONS,
293     Warn,
294     "detects name collision with an existing but unstable method"
295 }
296
297 declare_lint! {
298     pub IRREFUTABLE_LET_PATTERNS,
299     Deny,
300     "detects irrefutable patterns in if-let and while-let statements"
301 }
302
303 declare_lint! {
304     pub UNUSED_LABELS,
305     Allow,
306     "detects labels that are never used"
307 }
308
309 declare_lint! {
310     pub DUPLICATE_MACRO_EXPORTS,
311     Deny,
312     "detects duplicate macro exports"
313 }
314
315 declare_lint! {
316     pub INTRA_DOC_LINK_RESOLUTION_FAILURE,
317     Warn,
318     "warn about documentation intra links resolution failure"
319 }
320
321 declare_lint! {
322     pub MISSING_DOC_CODE_EXAMPLES,
323     Allow,
324     "warn about missing code example in an item's documentation"
325 }
326
327 declare_lint! {
328     pub PRIVATE_DOC_TESTS,
329     Allow,
330     "warn about doc test in private item"
331 }
332
333 declare_lint! {
334     pub WHERE_CLAUSES_OBJECT_SAFETY,
335     Warn,
336     "checks the object safety of where clauses"
337 }
338
339 declare_lint! {
340     pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
341     Warn,
342     "detects proc macro derives using inaccessible names from parent modules"
343 }
344
345 declare_lint! {
346     pub MACRO_USE_EXTERN_CRATE,
347     Allow,
348     "the `#[macro_use]` attribute is now deprecated in favor of using macros \
349      via the module system"
350 }
351
352 declare_lint! {
353     pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
354     Deny,
355     "macro-expanded `macro_export` macros from the current crate \
356      cannot be referred to by absolute paths"
357 }
358
359 declare_lint! {
360     pub EXPLICIT_OUTLIVES_REQUIREMENTS,
361     Allow,
362     "outlives requirements can be inferred"
363 }
364
365 /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
366 pub mod parser {
367     declare_lint! {
368         pub QUESTION_MARK_MACRO_SEP,
369         Allow,
370         "detects the use of `?` as a macro separator"
371     }
372 }
373
374 declare_lint! {
375     pub DEPRECATED_IN_FUTURE,
376     Allow,
377     "detects use of items that will be deprecated in a future version",
378     report_in_external_macro: true
379 }
380
381 /// Does nothing as a lint pass, but registers some `Lint`s
382 /// that are used by other parts of the compiler.
383 #[derive(Copy, Clone)]
384 pub struct HardwiredLints;
385
386 impl LintPass for HardwiredLints {
387     fn get_lints(&self) -> LintArray {
388         lint_array!(
389             ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
390             EXCEEDING_BITSHIFTS,
391             UNUSED_IMPORTS,
392             UNUSED_EXTERN_CRATES,
393             UNUSED_QUALIFICATIONS,
394             UNKNOWN_LINTS,
395             UNUSED_VARIABLES,
396             UNUSED_ASSIGNMENTS,
397             DEAD_CODE,
398             UNREACHABLE_CODE,
399             UNREACHABLE_PATTERNS,
400             UNUSED_MACROS,
401             WARNINGS,
402             UNUSED_FEATURES,
403             STABLE_FEATURES,
404             UNKNOWN_CRATE_TYPES,
405             TRIVIAL_CASTS,
406             TRIVIAL_NUMERIC_CASTS,
407             PRIVATE_IN_PUBLIC,
408             PUB_USE_OF_PRIVATE_EXTERN_CRATE,
409             INVALID_TYPE_PARAM_DEFAULT,
410             CONST_ERR,
411             RENAMED_AND_REMOVED_LINTS,
412             SAFE_EXTERN_STATICS,
413             SAFE_PACKED_BORROWS,
414             PATTERNS_IN_FNS_WITHOUT_BODY,
415             LEGACY_DIRECTORY_OWNERSHIP,
416             LEGACY_CONSTRUCTOR_VISIBILITY,
417             MISSING_FRAGMENT_SPECIFIER,
418             PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
419             LATE_BOUND_LIFETIME_ARGUMENTS,
420             INCOHERENT_FUNDAMENTAL_IMPLS,
421             ORDER_DEPENDENT_TRAIT_OBJECTS,
422             DEPRECATED,
423             UNUSED_UNSAFE,
424             UNUSED_MUT,
425             UNCONDITIONAL_RECURSION,
426             SINGLE_USE_LIFETIMES,
427             UNUSED_LIFETIMES,
428             UNUSED_LABELS,
429             TYVAR_BEHIND_RAW_POINTER,
430             ELIDED_LIFETIMES_IN_PATHS,
431             BARE_TRAIT_OBJECTS,
432             ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
433             UNSTABLE_NAME_COLLISIONS,
434             IRREFUTABLE_LET_PATTERNS,
435             DUPLICATE_MACRO_EXPORTS,
436             INTRA_DOC_LINK_RESOLUTION_FAILURE,
437             MISSING_DOC_CODE_EXAMPLES,
438             PRIVATE_DOC_TESTS,
439             WHERE_CLAUSES_OBJECT_SAFETY,
440             PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
441             MACRO_USE_EXTERN_CRATE,
442             MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
443             parser::QUESTION_MARK_MACRO_SEP,
444             DEPRECATED_IN_FUTURE,
445         )
446     }
447 }
448
449 // this could be a closure, but then implementing derive traits
450 // becomes hacky (and it gets allocated)
451 #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
452 pub enum BuiltinLintDiagnostics {
453     Normal,
454     BareTraitObject(Span, /* is_global */ bool),
455     AbsPathWithModule(Span),
456     DuplicatedMacroExports(ast::Ident, Span, Span),
457     ProcMacroDeriveResolutionFallback(Span),
458     MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
459     ElidedLifetimesInPaths(usize, Span, bool, Span, String),
460     UnknownCrateTypes(Span, String, String),
461 }
462
463 impl BuiltinLintDiagnostics {
464     pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder<'_>) {
465         match self {
466             BuiltinLintDiagnostics::Normal => (),
467             BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
468                 let (sugg, app) = match sess.source_map().span_to_snippet(span) {
469                     Ok(ref s) if is_global => (format!("dyn ({})", s),
470                                                Applicability::MachineApplicable),
471                     Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
472                     Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders)
473                 };
474                 db.span_suggestion_with_applicability(span, "use `dyn`", sugg, app);
475             }
476             BuiltinLintDiagnostics::AbsPathWithModule(span) => {
477                 let (sugg, app) = match sess.source_map().span_to_snippet(span) {
478                     Ok(ref s) => {
479                         // FIXME(Manishearth) ideally the emitting code
480                         // can tell us whether or not this is global
481                         let opt_colon = if s.trim_start().starts_with("::") {
482                             ""
483                         } else {
484                             "::"
485                         };
486
487                         (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
488                     }
489                     Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders)
490                 };
491                 db.span_suggestion_with_applicability(span, "use `crate`", sugg, app);
492             }
493             BuiltinLintDiagnostics::DuplicatedMacroExports(ident, earlier_span, later_span) => {
494                 db.span_label(later_span, format!("`{}` already exported", ident));
495                 db.span_note(earlier_span, "previous macro export is now shadowed");
496             }
497             BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
498                 db.span_label(span, "names from parent modules are not \
499                                      accessible without an explicit import");
500             }
501             BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
502                 db.span_note(span_def, "the macro is defined here");
503             }
504             BuiltinLintDiagnostics::ElidedLifetimesInPaths(
505                 n, path_span, incl_angl_brckt, insertion_span, anon_lts
506             ) => {
507                 let (replace_span, suggestion) = if incl_angl_brckt {
508                     (insertion_span, anon_lts)
509                 } else {
510                     // When possible, prefer a suggestion that replaces the whole
511                     // `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
512                     // at a point (which makes for an ugly/confusing label)
513                     if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
514                         // But our spans can get out of whack due to macros; if the place we think
515                         // we want to insert `'_` isn't even within the path expression's span, we
516                         // should bail out of making any suggestion rather than panicking on a
517                         // subtract-with-overflow or string-slice-out-out-bounds (!)
518                         // FIXME: can we do better?
519                         if insertion_span.lo().0 < path_span.lo().0 {
520                             return;
521                         }
522                         let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
523                         if insertion_index > snippet.len() {
524                             return;
525                         }
526                         let (before, after) = snippet.split_at(insertion_index);
527                         (path_span, format!("{}{}{}", before, anon_lts, after))
528                     } else {
529                         (insertion_span, anon_lts)
530                     }
531                 };
532                 db.span_suggestion_with_applicability(
533                     replace_span,
534                     &format!("indicate the anonymous lifetime{}", if n >= 2 { "s" } else { "" }),
535                     suggestion,
536                     Applicability::MachineApplicable
537                 );
538             }
539             BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
540                 db.span_suggestion_with_applicability(
541                     span,
542                     &note,
543                     sugg,
544                     Applicability::MaybeIncorrect
545                 );
546             }
547         }
548     }
549 }
550
551 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}