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::{LintPass, LateLintPass, LintArray};
8 use crate::session::Session;
9 use errors::{Applicability, DiagnosticBuilder};
11 use syntax::source_map::Span;
14 pub EXCEEDING_BITSHIFTS,
16 "shift exceeds the type's number of bits"
22 "constant evaluation detected erroneous expression"
28 "imports that are never used"
32 pub UNUSED_EXTERN_CRATES,
34 "extern crates that are never used"
38 pub UNUSED_QUALIFICATIONS,
40 "detects unnecessarily qualified names"
46 "unrecognized lint attribute"
52 "detect variables which are not used in any way"
56 pub UNUSED_ASSIGNMENTS,
58 "detect assignments that will never be read"
64 "detect unused, unexported items"
70 "detects unreachable code paths",
71 report_in_external_macro: true
75 pub UNREACHABLE_PATTERNS,
77 "detects unreachable patterns"
83 "detects macros that were not used"
89 "mass-change the level for lints which produce warnings"
95 "unused features found in crate-level #[feature] directives"
101 "stable features found in #[feature] directive"
105 pub UNKNOWN_CRATE_TYPES,
107 "unknown crate type found in #[crate_type] directive"
113 "detects trivial casts which could be removed"
117 pub TRIVIAL_NUMERIC_CASTS,
119 "detects trivial casts of numeric types which could be removed"
123 pub PRIVATE_IN_PUBLIC,
125 "detect private items in public interfaces not caught by the old implementation"
129 pub EXPORTED_PRIVATE_DEPENDENCIES,
131 "public interface leaks type from a private dependency"
135 pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
137 "detect public re-exports of private extern crates"
141 pub INVALID_TYPE_PARAM_DEFAULT,
143 "type parameter default erroneously allowed in invalid location"
147 pub RENAMED_AND_REMOVED_LINTS,
149 "lints that have been renamed or removed"
153 pub SAFE_EXTERN_STATICS,
155 "safe access to extern statics was erroneously allowed"
159 pub SAFE_PACKED_BORROWS,
161 "safe borrows of fields of packed structs were was erroneously allowed"
165 pub PATTERNS_IN_FNS_WITHOUT_BODY,
167 "patterns in functions without body were erroneously allowed"
171 pub LEGACY_DIRECTORY_OWNERSHIP,
173 "non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \
178 pub LEGACY_CONSTRUCTOR_VISIBILITY,
180 "detects use of struct constructors that would be invisible with new visibility rules"
184 pub MISSING_FRAGMENT_SPECIFIER,
186 "detects missing fragment specifiers in unused `macro_rules!` patterns"
190 pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
192 "detects parenthesized generic parameters in type and module names"
196 pub LATE_BOUND_LIFETIME_ARGUMENTS,
198 "detects generic lifetime arguments in path segments with late bound lifetime parameters"
202 pub INCOHERENT_FUNDAMENTAL_IMPLS,
204 "potentially-conflicting impls were erroneously allowed"
208 pub ORDER_DEPENDENT_TRAIT_OBJECTS,
210 "trait-object types were treated as different depending on marker-trait order"
216 "detects use of deprecated items",
217 report_in_external_macro: true
223 "unnecessary use of an `unsafe` block"
229 "detect mut variables which don't need to be mutable"
233 pub UNCONDITIONAL_RECURSION,
235 "functions that cannot return without calling themselves"
239 pub SINGLE_USE_LIFETIMES,
241 "detects lifetime parameters that are only used once"
245 pub UNUSED_LIFETIMES,
247 "detects lifetime parameters that are never used"
251 pub TYVAR_BEHIND_RAW_POINTER,
253 "raw pointer to an inference variable"
257 pub ELIDED_LIFETIMES_IN_PATHS,
259 "hidden lifetime parameters in types are deprecated"
263 pub BARE_TRAIT_OBJECTS,
265 "suggest using `dyn Trait` for trait objects"
269 pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
271 "fully qualified paths that start with a module name \
272 instead of `crate`, `self`, or an extern crate name"
276 pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
278 "floating-point literals cannot be used in patterns"
282 pub UNSTABLE_NAME_COLLISIONS,
284 "detects name collision with an existing but unstable method"
288 pub IRREFUTABLE_LET_PATTERNS,
290 "detects irrefutable patterns in if-let and while-let statements"
296 "detects labels that are never used"
300 pub DUPLICATE_MACRO_EXPORTS,
302 "detects duplicate macro exports"
306 pub INTRA_DOC_LINK_RESOLUTION_FAILURE,
308 "failures in resolving intra-doc link targets"
312 pub MISSING_DOC_CODE_EXAMPLES,
314 "detects publicly-exported items without code samples in their documentation"
318 pub PRIVATE_DOC_TESTS,
320 "detects code samples in docs of private items not documented by rustdoc"
324 pub WHERE_CLAUSES_OBJECT_SAFETY,
326 "checks the object safety of where clauses"
330 pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
332 "detects proc macro derives using inaccessible names from parent modules"
336 pub MACRO_USE_EXTERN_CRATE,
338 "the `#[macro_use]` attribute is now deprecated in favor of using macros \
339 via the module system"
343 pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
345 "macro-expanded `macro_export` macros from the current crate \
346 cannot be referred to by absolute paths"
350 pub EXPLICIT_OUTLIVES_REQUIREMENTS,
352 "outlives requirements can be inferred"
355 /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
358 pub QUESTION_MARK_MACRO_SEP,
360 "detects the use of `?` as a macro separator"
364 pub ILL_FORMED_ATTRIBUTE_INPUT,
366 "ill-formed attribute inputs that were previously accepted and used in practice"
371 pub DEPRECATED_IN_FUTURE,
373 "detects use of items that will be deprecated in a future version",
374 report_in_external_macro: true
378 pub AMBIGUOUS_ASSOCIATED_ITEMS,
380 "ambiguous associated items"
384 pub NESTED_IMPL_TRAIT,
386 "nested occurrence of `impl Trait` type"
390 pub MUTABLE_BORROW_RESERVATION_CONFLICT,
392 "reservation of a two-phased borrow conflicts with other shared borrows"
396 /// Does nothing as a lint pass, but registers some `Lint`s
397 /// that are used by other parts of the compiler.
399 ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
402 UNUSED_EXTERN_CRATES,
403 UNUSED_QUALIFICATIONS,
409 UNREACHABLE_PATTERNS,
416 TRIVIAL_NUMERIC_CASTS,
418 EXPORTED_PRIVATE_DEPENDENCIES,
419 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
420 INVALID_TYPE_PARAM_DEFAULT,
422 RENAMED_AND_REMOVED_LINTS,
425 PATTERNS_IN_FNS_WITHOUT_BODY,
426 LEGACY_DIRECTORY_OWNERSHIP,
427 LEGACY_CONSTRUCTOR_VISIBILITY,
428 MISSING_FRAGMENT_SPECIFIER,
429 PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
430 LATE_BOUND_LIFETIME_ARGUMENTS,
431 INCOHERENT_FUNDAMENTAL_IMPLS,
432 ORDER_DEPENDENT_TRAIT_OBJECTS,
436 UNCONDITIONAL_RECURSION,
437 SINGLE_USE_LIFETIMES,
440 TYVAR_BEHIND_RAW_POINTER,
441 ELIDED_LIFETIMES_IN_PATHS,
443 ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
444 UNSTABLE_NAME_COLLISIONS,
445 IRREFUTABLE_LET_PATTERNS,
446 DUPLICATE_MACRO_EXPORTS,
447 INTRA_DOC_LINK_RESOLUTION_FAILURE,
448 MISSING_DOC_CODE_EXAMPLES,
450 WHERE_CLAUSES_OBJECT_SAFETY,
451 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
452 MACRO_USE_EXTERN_CRATE,
453 MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
454 parser::QUESTION_MARK_MACRO_SEP,
455 parser::ILL_FORMED_ATTRIBUTE_INPUT,
456 DEPRECATED_IN_FUTURE,
457 AMBIGUOUS_ASSOCIATED_ITEMS,
459 MUTABLE_BORROW_RESERVATION_CONFLICT,
463 // this could be a closure, but then implementing derive traits
464 // becomes hacky (and it gets allocated)
465 #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
466 pub enum BuiltinLintDiagnostics {
468 BareTraitObject(Span, /* is_global */ bool),
469 AbsPathWithModule(Span),
470 DuplicatedMacroExports(ast::Ident, Span, Span),
471 ProcMacroDeriveResolutionFallback(Span),
472 MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
473 ElidedLifetimesInPaths(usize, Span, bool, Span, String),
474 UnknownCrateTypes(Span, String, String),
475 UnusedImports(String, Vec<(Span, String)>),
476 NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span },
477 RedundantImport(Vec<(Span, bool)>, ast::Ident),
480 pub(crate) fn add_elided_lifetime_in_path_suggestion(
482 db: &mut DiagnosticBuilder<'_>,
485 incl_angl_brckt: bool,
486 insertion_span: Span,
489 let (replace_span, suggestion) = if incl_angl_brckt {
490 (insertion_span, anon_lts)
492 // When possible, prefer a suggestion that replaces the whole
493 // `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
494 // at a point (which makes for an ugly/confusing label)
495 if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
496 // But our spans can get out of whack due to macros; if the place we think
497 // we want to insert `'_` isn't even within the path expression's span, we
498 // should bail out of making any suggestion rather than panicking on a
499 // subtract-with-overflow or string-slice-out-out-bounds (!)
500 // FIXME: can we do better?
501 if insertion_span.lo().0 < path_span.lo().0 {
504 let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
505 if insertion_index > snippet.len() {
508 let (before, after) = snippet.split_at(insertion_index);
509 (path_span, format!("{}{}{}", before, anon_lts, after))
511 (insertion_span, anon_lts)
516 &format!("indicate the anonymous lifetime{}", if n >= 2 { "s" } else { "" }),
518 Applicability::MachineApplicable
522 impl BuiltinLintDiagnostics {
523 pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder<'_>) {
525 BuiltinLintDiagnostics::Normal => (),
526 BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
527 let (sugg, app) = match sess.source_map().span_to_snippet(span) {
528 Ok(ref s) if is_global => (format!("dyn ({})", s),
529 Applicability::MachineApplicable),
530 Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
531 Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders)
533 db.span_suggestion(span, "use `dyn`", sugg, app);
535 BuiltinLintDiagnostics::AbsPathWithModule(span) => {
536 let (sugg, app) = match sess.source_map().span_to_snippet(span) {
538 // FIXME(Manishearth) ideally the emitting code
539 // can tell us whether or not this is global
540 let opt_colon = if s.trim_start().starts_with("::") {
546 (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
548 Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders)
550 db.span_suggestion(span, "use `crate`", sugg, app);
552 BuiltinLintDiagnostics::DuplicatedMacroExports(ident, earlier_span, later_span) => {
553 db.span_label(later_span, format!("`{}` already exported", ident));
554 db.span_note(earlier_span, "previous macro export is now shadowed");
556 BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
557 db.span_label(span, "names from parent modules are not \
558 accessible without an explicit import");
560 BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
561 db.span_note(span_def, "the macro is defined here");
563 BuiltinLintDiagnostics::ElidedLifetimesInPaths(
564 n, path_span, incl_angl_brckt, insertion_span, anon_lts
566 add_elided_lifetime_in_path_suggestion(
576 BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
577 db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect);
579 BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
580 if !replaces.is_empty() {
581 db.tool_only_multipart_suggestion(
584 Applicability::MachineApplicable,
588 BuiltinLintDiagnostics::NestedImplTrait {
589 outer_impl_trait_span, inner_impl_trait_span
591 db.span_label(outer_impl_trait_span, "outer `impl Trait`");
592 db.span_label(inner_impl_trait_span, "nested `impl Trait` here");
594 BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
595 for (span, is_imported) in spans {
596 let introduced = if is_imported { "imported" } else { "defined" };
599 format!("the item `{}` is already {} here", ident, introduced)
607 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}