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