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.
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.
11 //! Some lints that are built in to the compiler.
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`.
17 use errors::{Applicability, DiagnosticBuilder};
18 use lint::{LintPass, LateLintPass, LintArray};
21 use syntax::source_map::Span;
24 pub EXCEEDING_BITSHIFTS,
26 "shift exceeds the type's number of bits"
32 "constant evaluation detected erroneous expression"
38 "imports that are never used"
42 pub UNUSED_EXTERN_CRATES,
44 "extern crates that are never used"
48 pub UNUSED_QUALIFICATIONS,
50 "detects unnecessarily qualified names"
56 "unrecognized lint attribute"
62 "detect variables which are not used in any way"
66 pub UNUSED_ASSIGNMENTS,
68 "detect assignments that will never be read"
74 "detect unused, unexported items"
80 "detects unreachable code paths",
81 report_in_external_macro: true
85 pub UNREACHABLE_PATTERNS,
87 "detects unreachable patterns"
93 "detects macros that were not used"
99 "mass-change the level for lints which produce warnings"
105 "unused features found in crate-level #[feature] directives"
111 "stable features found in #[feature] directive"
115 pub UNKNOWN_CRATE_TYPES,
117 "unknown crate type found in #[crate_type] directive"
123 "detects trivial casts which could be removed"
127 pub TRIVIAL_NUMERIC_CASTS,
129 "detects trivial casts of numeric types which could be removed"
133 pub PRIVATE_IN_PUBLIC,
135 "detect private items in public interfaces not caught by the old implementation"
139 pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
141 "detect public re-exports of private extern crates"
145 pub INVALID_TYPE_PARAM_DEFAULT,
147 "type parameter default erroneously allowed in invalid location"
151 pub RENAMED_AND_REMOVED_LINTS,
153 "lints that have been renamed or removed"
157 pub SAFE_EXTERN_STATICS,
159 "safe access to extern statics was erroneously allowed"
163 pub SAFE_PACKED_BORROWS,
165 "safe borrows of fields of packed structs were was erroneously allowed"
169 pub PATTERNS_IN_FNS_WITHOUT_BODY,
171 "patterns in functions without body were erroneously allowed"
175 pub LEGACY_DIRECTORY_OWNERSHIP,
177 "non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \
182 pub LEGACY_CONSTRUCTOR_VISIBILITY,
184 "detects use of struct constructors that would be invisible with new visibility rules"
188 pub MISSING_FRAGMENT_SPECIFIER,
190 "detects missing fragment specifiers in unused `macro_rules!` patterns"
194 pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
196 "detects parenthesized generic parameters in type and module names"
200 pub LATE_BOUND_LIFETIME_ARGUMENTS,
202 "detects generic lifetime arguments in path segments with late bound lifetime parameters"
206 pub INCOHERENT_FUNDAMENTAL_IMPLS,
208 "potentially-conflicting impls were erroneously allowed"
212 pub ORDER_DEPENDENT_TRAIT_OBJECTS,
214 "trait-object types were treated as different depending on marker-trait order"
220 "detects incorrect use of `repr` attribute"
226 "detects use of deprecated items",
227 report_in_external_macro: true
233 "unnecessary use of an `unsafe` block"
239 "detect mut variables which don't need to be mutable"
243 pub UNCONDITIONAL_RECURSION,
245 "functions that cannot return without calling themselves"
249 pub SINGLE_USE_LIFETIMES,
251 "detects lifetime parameters that are only used once"
255 pub UNUSED_LIFETIMES,
257 "detects lifetime parameters that are never used"
261 pub TYVAR_BEHIND_RAW_POINTER,
263 "raw pointer to an inference variable"
267 pub ELIDED_LIFETIMES_IN_PATHS,
269 "hidden lifetime parameters in types are deprecated"
273 pub BARE_TRAIT_OBJECTS,
275 "suggest using `dyn Trait` for trait objects"
279 pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
281 "fully qualified paths that start with a module name \
282 instead of `crate`, `self`, or an extern crate name"
286 pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
288 "floating-point literals cannot be used in patterns"
292 pub UNSTABLE_NAME_COLLISIONS,
294 "detects name collision with an existing but unstable method"
298 pub IRREFUTABLE_LET_PATTERNS,
300 "detects irrefutable patterns in if-let and while-let statements"
306 "detects labels that are never used"
310 pub DUPLICATE_MACRO_EXPORTS,
312 "detects duplicate macro exports"
316 pub INTRA_DOC_LINK_RESOLUTION_FAILURE,
318 "warn about documentation intra links resolution failure"
322 pub MISSING_DOC_CODE_EXAMPLES,
324 "warn about missing code example in an item's documentation"
328 pub PRIVATE_DOC_TESTS,
330 "warn about doc test in private item"
334 pub WHERE_CLAUSES_OBJECT_SAFETY,
336 "checks the object safety of where clauses"
340 pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
342 "detects proc macro derives using inaccessible names from parent modules"
346 pub MACRO_USE_EXTERN_CRATE,
348 "the `#[macro_use]` attribute is now deprecated in favor of using macros \
349 via the module system"
353 pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
355 "macro-expanded `macro_export` macros from the current crate \
356 cannot be referred to by absolute paths"
360 pub EXPLICIT_OUTLIVES_REQUIREMENTS,
362 "outlives requirements can be inferred"
365 /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
368 pub QUESTION_MARK_MACRO_SEP,
370 "detects the use of `?` as a macro separator"
375 pub DEPRECATED_IN_FUTURE,
377 "detects use of items that will be deprecated in a future version",
378 report_in_external_macro: true
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;
386 impl LintPass for HardwiredLints {
387 fn get_lints(&self) -> LintArray {
389 ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
392 UNUSED_EXTERN_CRATES,
393 UNUSED_QUALIFICATIONS,
399 UNREACHABLE_PATTERNS,
406 TRIVIAL_NUMERIC_CASTS,
408 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
409 INVALID_TYPE_PARAM_DEFAULT,
411 RENAMED_AND_REMOVED_LINTS,
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,
425 UNCONDITIONAL_RECURSION,
426 SINGLE_USE_LIFETIMES,
429 TYVAR_BEHIND_RAW_POINTER,
430 ELIDED_LIFETIMES_IN_PATHS,
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,
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,
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 {
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),
463 impl BuiltinLintDiagnostics {
464 pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder<'_>) {
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)
474 db.span_suggestion_with_applicability(span, "use `dyn`", sugg, app);
476 BuiltinLintDiagnostics::AbsPathWithModule(span) => {
477 let (sugg, app) = match sess.source_map().span_to_snippet(span) {
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("::") {
487 (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
489 Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders)
491 db.span_suggestion_with_applicability(span, "use `crate`", sugg, app);
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");
497 BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
498 db.span_label(span, "names from parent modules are not \
499 accessible without an explicit import");
501 BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
502 db.span_note(span_def, "the macro is defined here");
504 BuiltinLintDiagnostics::ElidedLifetimesInPaths(
505 n, path_span, incl_angl_brckt, insertion_span, anon_lts
507 let (replace_span, suggestion) = if incl_angl_brckt {
508 (insertion_span, anon_lts)
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 {
522 let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
523 if insertion_index > snippet.len() {
526 let (before, after) = snippet.split_at(insertion_index);
527 (path_span, format!("{}{}{}", before, anon_lts, after))
529 (insertion_span, anon_lts)
532 db.span_suggestion_with_applicability(
534 &format!("indicate the anonymous lifetime{}", if n >= 2 { "s" } else { "" }),
536 Applicability::MachineApplicable
539 BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
540 db.span_suggestion_with_applicability(
544 Applicability::MaybeIncorrect
551 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}