1 //! Some lints that are built in to the compiler.
3 //! These are the built-in lints that are emitted direct in the main
4 //! compiler code, rather than using their own custom pass. Those
5 //! lints are all available in `rustc_lint::builtin`.
7 use crate::lint::{FutureIncompatibleInfo, LateLintPass, LintArray, LintPass};
8 use crate::middle::stability;
9 use crate::session::Session;
10 use errors::{pluralize, Applicability, DiagnosticBuilder};
11 use rustc_session::declare_lint;
13 use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
14 use syntax::edition::Edition;
15 use syntax::source_map::Span;
16 use syntax::symbol::Symbol;
19 pub EXCEEDING_BITSHIFTS,
21 "shift exceeds the type's number of bits"
27 "constant evaluation detected erroneous expression",
28 report_in_external_macro
34 "imports that are never used"
38 pub UNUSED_EXTERN_CRATES,
40 "extern crates that are never used"
44 pub UNUSED_QUALIFICATIONS,
46 "detects unnecessarily qualified names"
52 "unrecognized lint attribute"
58 "detect variables which are not used in any way"
62 pub UNUSED_ASSIGNMENTS,
64 "detect assignments that will never be read"
70 "detect unused, unexported items"
74 pub UNUSED_ATTRIBUTES,
76 "detects attributes that were not used by the compiler"
82 "detects unreachable code paths",
83 report_in_external_macro
87 pub UNREACHABLE_PATTERNS,
89 "detects unreachable patterns"
93 pub OVERLAPPING_PATTERNS,
95 "detects overlapping patterns"
101 "detects macros that were not used"
107 "mass-change the level for lints which produce warnings"
113 "unused features found in crate-level `#[feature]` directives"
119 "stable features found in `#[feature]` directive"
123 pub UNKNOWN_CRATE_TYPES,
125 "unknown crate type found in `#[crate_type]` directive"
131 "detects trivial casts which could be removed"
135 pub TRIVIAL_NUMERIC_CASTS,
137 "detects trivial casts of numeric types which could be removed"
141 pub PRIVATE_IN_PUBLIC,
143 "detect private items in public interfaces not caught by the old implementation",
144 @future_incompatible = FutureIncompatibleInfo {
145 reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
151 pub EXPORTED_PRIVATE_DEPENDENCIES,
153 "public interface leaks type from a private dependency"
157 pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
159 "detect public re-exports of private extern crates",
160 @future_incompatible = FutureIncompatibleInfo {
161 reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
167 pub INVALID_TYPE_PARAM_DEFAULT,
169 "type parameter default erroneously allowed in invalid location",
170 @future_incompatible = FutureIncompatibleInfo {
171 reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
177 pub RENAMED_AND_REMOVED_LINTS,
179 "lints that have been renamed or removed"
183 pub SAFE_PACKED_BORROWS,
185 "safe borrows of fields of packed structs were was erroneously allowed",
186 @future_incompatible = FutureIncompatibleInfo {
187 reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
193 pub PATTERNS_IN_FNS_WITHOUT_BODY,
195 "patterns in functions without body were erroneously allowed",
196 @future_incompatible = FutureIncompatibleInfo {
197 reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
203 pub MISSING_FRAGMENT_SPECIFIER,
205 "detects missing fragment specifiers in unused `macro_rules!` patterns",
206 @future_incompatible = FutureIncompatibleInfo {
207 reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
213 pub LATE_BOUND_LIFETIME_ARGUMENTS,
215 "detects generic lifetime arguments in path segments with late bound lifetime parameters",
216 @future_incompatible = FutureIncompatibleInfo {
217 reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
223 pub ORDER_DEPENDENT_TRAIT_OBJECTS,
225 "trait-object types were treated as different depending on marker-trait order",
226 @future_incompatible = FutureIncompatibleInfo {
227 reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
235 "detects use of deprecated items",
236 report_in_external_macro
242 "unnecessary use of an `unsafe` block"
248 "detect mut variables which don't need to be mutable"
252 pub UNCONDITIONAL_RECURSION,
254 "functions that cannot return without calling themselves"
258 pub SINGLE_USE_LIFETIMES,
260 "detects lifetime parameters that are only used once"
264 pub UNUSED_LIFETIMES,
266 "detects lifetime parameters that are never used"
270 pub TYVAR_BEHIND_RAW_POINTER,
272 "raw pointer to an inference variable",
273 @future_incompatible = FutureIncompatibleInfo {
274 reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
275 edition: Some(Edition::Edition2018),
280 pub ELIDED_LIFETIMES_IN_PATHS,
282 "hidden lifetime parameters in types are deprecated"
286 pub BARE_TRAIT_OBJECTS,
288 "suggest using `dyn Trait` for trait objects"
292 pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
294 "fully qualified paths that start with a module name \
295 instead of `crate`, `self`, or an extern crate name",
296 @future_incompatible = FutureIncompatibleInfo {
297 reference: "issue #53130 <https://github.com/rust-lang/rust/issues/53130>",
298 edition: Some(Edition::Edition2018),
303 pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
305 "floating-point literals cannot be used in patterns",
306 @future_incompatible = FutureIncompatibleInfo {
307 reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
313 pub UNSTABLE_NAME_COLLISIONS,
315 "detects name collision with an existing but unstable method",
316 @future_incompatible = FutureIncompatibleInfo {
317 reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>",
319 // Note: this item represents future incompatibility of all unstable functions in the
320 // standard library, and thus should never be removed or changed to an error.
325 pub IRREFUTABLE_LET_PATTERNS,
327 "detects irrefutable patterns in if-let and while-let statements"
333 "detects labels that are never used"
337 pub INTRA_DOC_LINK_RESOLUTION_FAILURE,
339 "failures in resolving intra-doc link targets"
343 pub MISSING_DOC_CODE_EXAMPLES,
345 "detects publicly-exported items without code samples in their documentation"
349 pub PRIVATE_DOC_TESTS,
351 "detects code samples in docs of private items not documented by rustdoc"
355 pub WHERE_CLAUSES_OBJECT_SAFETY,
357 "checks the object safety of where clauses",
358 @future_incompatible = FutureIncompatibleInfo {
359 reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
365 pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
367 "detects proc macro derives using inaccessible names from parent modules",
368 @future_incompatible = FutureIncompatibleInfo {
369 reference: "issue #50504 <https://github.com/rust-lang/rust/issues/50504>",
375 pub MACRO_USE_EXTERN_CRATE,
377 "the `#[macro_use]` attribute is now deprecated in favor of using macros \
378 via the module system"
382 pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
384 "macro-expanded `macro_export` macros from the current crate \
385 cannot be referred to by absolute paths",
386 @future_incompatible = FutureIncompatibleInfo {
387 reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>",
393 pub EXPLICIT_OUTLIVES_REQUIREMENTS,
395 "outlives requirements can be inferred"
399 pub INDIRECT_STRUCTURAL_MATCH,
400 // defaulting to allow until rust-lang/rust#62614 is fixed.
402 "pattern with const indirectly referencing non-`#[structural_match]` type",
403 @future_incompatible = FutureIncompatibleInfo {
404 reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
410 pub DEPRECATED_IN_FUTURE,
412 "detects use of items that will be deprecated in a future version",
413 report_in_external_macro
417 pub AMBIGUOUS_ASSOCIATED_ITEMS,
419 "ambiguous associated items",
420 @future_incompatible = FutureIncompatibleInfo {
421 reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>",
427 pub MUTABLE_BORROW_RESERVATION_CONFLICT,
429 "reservation of a two-phased borrow conflicts with other shared borrows",
430 @future_incompatible = FutureIncompatibleInfo {
431 reference: "issue #59159 <https://github.com/rust-lang/rust/issues/59159>",
439 "a feature gate that doesn't break dependent crates",
440 @future_incompatible = FutureIncompatibleInfo {
441 reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>",
447 /// Does nothing as a lint pass, but registers some `Lint`s
448 /// that are used by other parts of the compiler.
450 ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
453 UNUSED_EXTERN_CRATES,
454 UNUSED_QUALIFICATIONS,
460 UNREACHABLE_PATTERNS,
461 OVERLAPPING_PATTERNS,
468 TRIVIAL_NUMERIC_CASTS,
470 EXPORTED_PRIVATE_DEPENDENCIES,
471 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
472 INVALID_TYPE_PARAM_DEFAULT,
474 RENAMED_AND_REMOVED_LINTS,
476 PATTERNS_IN_FNS_WITHOUT_BODY,
477 MISSING_FRAGMENT_SPECIFIER,
478 LATE_BOUND_LIFETIME_ARGUMENTS,
479 ORDER_DEPENDENT_TRAIT_OBJECTS,
483 UNCONDITIONAL_RECURSION,
484 SINGLE_USE_LIFETIMES,
487 TYVAR_BEHIND_RAW_POINTER,
488 ELIDED_LIFETIMES_IN_PATHS,
490 ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
491 UNSTABLE_NAME_COLLISIONS,
492 IRREFUTABLE_LET_PATTERNS,
493 INTRA_DOC_LINK_RESOLUTION_FAILURE,
494 MISSING_DOC_CODE_EXAMPLES,
496 WHERE_CLAUSES_OBJECT_SAFETY,
497 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
498 MACRO_USE_EXTERN_CRATE,
499 MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
500 ILL_FORMED_ATTRIBUTE_INPUT,
501 META_VARIABLE_MISUSE,
502 DEPRECATED_IN_FUTURE,
503 AMBIGUOUS_ASSOCIATED_ITEMS,
504 MUTABLE_BORROW_RESERVATION_CONFLICT,
505 INDIRECT_STRUCTURAL_MATCH,
510 // this could be a closure, but then implementing derive traits
511 // becomes hacky (and it gets allocated)
512 #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
513 pub enum BuiltinLintDiagnostics {
515 BareTraitObject(Span, /* is_global */ bool),
516 AbsPathWithModule(Span),
517 ProcMacroDeriveResolutionFallback(Span),
518 MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
519 ElidedLifetimesInPaths(usize, Span, bool, Span, String),
520 UnknownCrateTypes(Span, String, String),
521 UnusedImports(String, Vec<(Span, String)>),
522 RedundantImport(Vec<(Span, bool)>, ast::Ident),
523 DeprecatedMacro(Option<Symbol>, Span),
526 pub(crate) fn add_elided_lifetime_in_path_suggestion(
528 db: &mut DiagnosticBuilder<'_>,
531 incl_angl_brckt: bool,
532 insertion_span: Span,
535 let (replace_span, suggestion) = if incl_angl_brckt {
536 (insertion_span, anon_lts)
538 // When possible, prefer a suggestion that replaces the whole
539 // `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
540 // at a point (which makes for an ugly/confusing label)
541 if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
542 // But our spans can get out of whack due to macros; if the place we think
543 // we want to insert `'_` isn't even within the path expression's span, we
544 // should bail out of making any suggestion rather than panicking on a
545 // subtract-with-overflow or string-slice-out-out-bounds (!)
546 // FIXME: can we do better?
547 if insertion_span.lo().0 < path_span.lo().0 {
550 let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
551 if insertion_index > snippet.len() {
554 let (before, after) = snippet.split_at(insertion_index);
555 (path_span, format!("{}{}{}", before, anon_lts, after))
557 (insertion_span, anon_lts)
562 &format!("indicate the anonymous lifetime{}", pluralize!(n)),
564 Applicability::MachineApplicable,
568 impl BuiltinLintDiagnostics {
569 pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder<'_>) {
571 BuiltinLintDiagnostics::Normal => (),
572 BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
573 let (sugg, app) = match sess.source_map().span_to_snippet(span) {
574 Ok(ref s) if is_global => {
575 (format!("dyn ({})", s), Applicability::MachineApplicable)
577 Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
578 Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
580 db.span_suggestion(span, "use `dyn`", sugg, app);
582 BuiltinLintDiagnostics::AbsPathWithModule(span) => {
583 let (sugg, app) = match sess.source_map().span_to_snippet(span) {
585 // FIXME(Manishearth) ideally the emitting code
586 // can tell us whether or not this is global
587 let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
589 (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
591 Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
593 db.span_suggestion(span, "use `crate`", sugg, app);
595 BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
598 "names from parent modules are not \
599 accessible without an explicit import",
602 BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
603 db.span_note(span_def, "the macro is defined here");
605 BuiltinLintDiagnostics::ElidedLifetimesInPaths(
612 add_elided_lifetime_in_path_suggestion(
622 BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
623 db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect);
625 BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
626 if !replaces.is_empty() {
627 db.tool_only_multipart_suggestion(
630 Applicability::MachineApplicable,
634 BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
635 for (span, is_imported) in spans {
636 let introduced = if is_imported { "imported" } else { "defined" };
639 format!("the item `{}` is already {} here", ident, introduced),
643 BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
644 stability::deprecation_suggestion(db, suggestion, span)
650 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}