]> git.lizzy.rs Git - rust.git/blob - src/librustc_lint/lib.rs
Auto merge of #68067 - JohnTitor:rollup-vsj5won, r=JohnTitor
[rust.git] / src / librustc_lint / lib.rs
1 //! # Lints in the Rust compiler
2 //!
3 //! This currently only contains the definitions and implementations
4 //! of most of the lints that `rustc` supports directly, it does not
5 //! contain the infrastructure for defining/registering lints. That is
6 //! available in `rustc::lint` and `rustc_driver::plugin` respectively.
7 //!
8 //! ## Note
9 //!
10 //! This API is completely unstable and subject to change.
11
12 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
13 #![cfg_attr(test, feature(test))]
14 #![feature(bool_to_option)]
15 #![feature(box_patterns)]
16 #![feature(box_syntax)]
17 #![feature(nll)]
18 #![recursion_limit = "256"]
19
20 #[macro_use]
21 extern crate rustc;
22 #[macro_use]
23 extern crate rustc_session;
24
25 mod array_into_iter;
26 pub mod builtin;
27 mod early;
28 mod late;
29 mod levels;
30 mod non_ascii_idents;
31 mod nonstandard_style;
32 mod redundant_semicolon;
33 mod types;
34 mod unused;
35
36 use rustc::lint;
37 use rustc::lint::builtin::{
38     BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
39     INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS,
40 };
41 use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass};
42 use rustc::ty::query::Providers;
43 use rustc::ty::TyCtxt;
44 use rustc_hir as hir;
45 use rustc_hir::def_id::DefId;
46
47 use rustc_span::Span;
48 use syntax::ast;
49
50 use lint::LintId;
51
52 use array_into_iter::ArrayIntoIter;
53 use builtin::*;
54 use non_ascii_idents::*;
55 use nonstandard_style::*;
56 use redundant_semicolon::*;
57 use rustc::lint::internal::*;
58 use types::*;
59 use unused::*;
60
61 /// Useful for other parts of the compiler.
62 pub use builtin::SoftLints;
63 pub use early::check_ast_crate;
64 pub use late::check_crate;
65
66 pub fn provide(providers: &mut Providers<'_>) {
67     levels::provide(providers);
68     *providers = Providers { lint_mod, ..*providers };
69 }
70
71 fn lint_mod(tcx: TyCtxt<'_>, module_def_id: DefId) {
72     late::late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new());
73 }
74
75 macro_rules! pre_expansion_lint_passes {
76     ($macro:path, $args:tt) => {
77         $macro!($args, [KeywordIdents: KeywordIdents, UnusedDocComment: UnusedDocComment,]);
78     };
79 }
80
81 macro_rules! early_lint_passes {
82     ($macro:path, $args:tt) => {
83         $macro!(
84             $args,
85             [
86                 UnusedParens: UnusedParens,
87                 UnusedImportBraces: UnusedImportBraces,
88                 UnsafeCode: UnsafeCode,
89                 AnonymousParameters: AnonymousParameters,
90                 EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
91                 NonCamelCaseTypes: NonCamelCaseTypes,
92                 DeprecatedAttr: DeprecatedAttr::new(),
93                 WhileTrue: WhileTrue,
94                 NonAsciiIdents: NonAsciiIdents,
95                 IncompleteFeatures: IncompleteFeatures,
96                 RedundantSemicolon: RedundantSemicolon,
97             ]
98         );
99     };
100 }
101
102 macro_rules! declare_combined_early_pass {
103     ([$name:ident], $passes:tt) => (
104         early_lint_methods!(declare_combined_early_lint_pass, [pub $name, $passes]);
105     )
106 }
107
108 pre_expansion_lint_passes!(declare_combined_early_pass, [BuiltinCombinedPreExpansionLintPass]);
109 early_lint_passes!(declare_combined_early_pass, [BuiltinCombinedEarlyLintPass]);
110
111 macro_rules! late_lint_passes {
112     ($macro:path, $args:tt) => {
113         $macro!(
114             $args,
115             [
116                 // FIXME: Look into regression when this is used as a module lint
117                 // May Depend on constants elsewhere
118                 UnusedBrokenConst: UnusedBrokenConst,
119                 // Uses attr::is_used which is untracked, can't be an incremental module pass.
120                 UnusedAttributes: UnusedAttributes::new(),
121                 // Needs to run after UnusedAttributes as it marks all `feature` attributes as used.
122                 UnstableFeatures: UnstableFeatures,
123                 // Tracks state across modules
124                 UnnameableTestItems: UnnameableTestItems::new(),
125                 // Tracks attributes of parents
126                 MissingDoc: MissingDoc::new(),
127                 // Depends on access levels
128                 // FIXME: Turn the computation of types which implement Debug into a query
129                 // and change this to a module lint pass
130                 MissingDebugImplementations: MissingDebugImplementations::default(),
131                 ArrayIntoIter: ArrayIntoIter,
132             ]
133         );
134     };
135 }
136
137 macro_rules! late_lint_mod_passes {
138     ($macro:path, $args:tt) => {
139         $macro!(
140             $args,
141             [
142                 HardwiredLints: HardwiredLints,
143                 ImproperCTypes: ImproperCTypes,
144                 VariantSizeDifferences: VariantSizeDifferences,
145                 BoxPointers: BoxPointers,
146                 PathStatements: PathStatements,
147                 // Depends on referenced function signatures in expressions
148                 UnusedResults: UnusedResults,
149                 NonUpperCaseGlobals: NonUpperCaseGlobals,
150                 NonShorthandFieldPatterns: NonShorthandFieldPatterns,
151                 UnusedAllocation: UnusedAllocation,
152                 // Depends on types used in type definitions
153                 MissingCopyImplementations: MissingCopyImplementations,
154                 // Depends on referenced function signatures in expressions
155                 MutableTransmutes: MutableTransmutes,
156                 TypeAliasBounds: TypeAliasBounds,
157                 TrivialConstraints: TrivialConstraints,
158                 TypeLimits: TypeLimits::new(),
159                 NonSnakeCase: NonSnakeCase,
160                 InvalidNoMangleItems: InvalidNoMangleItems,
161                 // Depends on access levels
162                 UnreachablePub: UnreachablePub,
163                 ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
164                 InvalidValue: InvalidValue,
165             ]
166         );
167     };
168 }
169
170 macro_rules! declare_combined_late_pass {
171     ([$v:vis $name:ident], $passes:tt) => (
172         late_lint_methods!(declare_combined_late_lint_pass, [$v $name, $passes], ['tcx]);
173     )
174 }
175
176 // FIXME: Make a separate lint type which do not require typeck tables
177 late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass]);
178
179 late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]);
180
181 pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint::LintStore {
182     let mut lint_store = lint::LintStore::new();
183
184     register_builtins(&mut lint_store, no_interleave_lints);
185     if internal_lints {
186         register_internals(&mut lint_store);
187     }
188
189     lint_store
190 }
191
192 /// Tell the `LintStore` about all the built-in lints (the ones
193 /// defined in this crate and the ones defined in
194 /// `rustc::lint::builtin`).
195 fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) {
196     macro_rules! add_lint_group {
197         ($name:expr, $($lint:ident),*) => (
198             store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]);
199         )
200     }
201
202     macro_rules! register_pass {
203         ($method:ident, $ty:ident, $constructor:expr) => {
204             store.register_lints(&$ty::get_lints());
205             store.$method(|| box $constructor);
206         };
207     }
208
209     macro_rules! register_passes {
210         ($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
211             $(
212                 register_pass!($method, $passes, $constructor);
213             )*
214         )
215     }
216
217     if no_interleave_lints {
218         pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass);
219         early_lint_passes!(register_passes, register_early_pass);
220         late_lint_passes!(register_passes, register_late_pass);
221         late_lint_mod_passes!(register_passes, register_late_mod_pass);
222     } else {
223         store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
224         store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
225         store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints());
226         store.register_lints(&BuiltinCombinedLateLintPass::get_lints());
227     }
228
229     add_lint_group!(
230         "nonstandard_style",
231         NON_CAMEL_CASE_TYPES,
232         NON_SNAKE_CASE,
233         NON_UPPER_CASE_GLOBALS
234     );
235
236     add_lint_group!(
237         "unused",
238         UNUSED_IMPORTS,
239         UNUSED_VARIABLES,
240         UNUSED_ASSIGNMENTS,
241         DEAD_CODE,
242         UNUSED_MUT,
243         UNREACHABLE_CODE,
244         UNREACHABLE_PATTERNS,
245         OVERLAPPING_PATTERNS,
246         UNUSED_MUST_USE,
247         UNUSED_UNSAFE,
248         PATH_STATEMENTS,
249         UNUSED_ATTRIBUTES,
250         UNUSED_MACROS,
251         UNUSED_ALLOCATION,
252         UNUSED_DOC_COMMENTS,
253         UNUSED_EXTERN_CRATES,
254         UNUSED_FEATURES,
255         UNUSED_LABELS,
256         UNUSED_PARENS
257     );
258
259     add_lint_group!(
260         "rust_2018_idioms",
261         BARE_TRAIT_OBJECTS,
262         UNUSED_EXTERN_CRATES,
263         ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
264         ELIDED_LIFETIMES_IN_PATHS,
265         EXPLICIT_OUTLIVES_REQUIREMENTS // FIXME(#52665, #47816) not always applicable and not all
266                                        // macros are ready for this yet.
267                                        // UNREACHABLE_PUB,
268
269                                        // FIXME macro crates are not up for this yet, too much
270                                        // breakage is seen if we try to encourage this lint.
271                                        // MACRO_USE_EXTERN_CRATE
272     );
273
274     add_lint_group!(
275         "rustdoc",
276         INTRA_DOC_LINK_RESOLUTION_FAILURE,
277         MISSING_DOC_CODE_EXAMPLES,
278         PRIVATE_DOC_TESTS
279     );
280
281     // Register renamed and removed lints.
282     store.register_renamed("single_use_lifetime", "single_use_lifetimes");
283     store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");
284     store.register_renamed("bare_trait_object", "bare_trait_objects");
285     store.register_renamed("unstable_name_collision", "unstable_name_collisions");
286     store.register_renamed("unused_doc_comment", "unused_doc_comments");
287     store.register_renamed("async_idents", "keyword_idents");
288     store.register_removed("unknown_features", "replaced by an error");
289     store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
290     store.register_removed("negate_unsigned", "cast a signed value instead");
291     store.register_removed("raw_pointer_derive", "using derive with raw pointers is ok");
292     // Register lint group aliases.
293     store.register_group_alias("nonstandard_style", "bad_style");
294     // This was renamed to `raw_pointer_derive`, which was then removed,
295     // so it is also considered removed.
296     store.register_removed("raw_pointer_deriving", "using derive with raw pointers is ok");
297     store.register_removed("drop_with_repr_extern", "drop flags have been removed");
298     store.register_removed("fat_ptr_transmutes", "was accidentally removed back in 2014");
299     store.register_removed("deprecated_attr", "use `deprecated` instead");
300     store.register_removed(
301         "transmute_from_fn_item_types",
302         "always cast functions before transmuting them",
303     );
304     store.register_removed(
305         "hr_lifetime_in_assoc_type",
306         "converted into hard error, see https://github.com/rust-lang/rust/issues/33685",
307     );
308     store.register_removed(
309         "inaccessible_extern_crate",
310         "converted into hard error, see https://github.com/rust-lang/rust/issues/36886",
311     );
312     store.register_removed(
313         "super_or_self_in_global_path",
314         "converted into hard error, see https://github.com/rust-lang/rust/issues/36888",
315     );
316     store.register_removed(
317         "overlapping_inherent_impls",
318         "converted into hard error, see https://github.com/rust-lang/rust/issues/36889",
319     );
320     store.register_removed(
321         "illegal_floating_point_constant_pattern",
322         "converted into hard error, see https://github.com/rust-lang/rust/issues/36890",
323     );
324     store.register_removed(
325         "illegal_struct_or_enum_constant_pattern",
326         "converted into hard error, see https://github.com/rust-lang/rust/issues/36891",
327     );
328     store.register_removed(
329         "lifetime_underscore",
330         "converted into hard error, see https://github.com/rust-lang/rust/issues/36892",
331     );
332     store.register_removed(
333         "extra_requirement_in_impl",
334         "converted into hard error, see https://github.com/rust-lang/rust/issues/37166",
335     );
336     store.register_removed(
337         "legacy_imports",
338         "converted into hard error, see https://github.com/rust-lang/rust/issues/38260",
339     );
340     store.register_removed(
341         "coerce_never",
342         "converted into hard error, see https://github.com/rust-lang/rust/issues/48950",
343     );
344     store.register_removed(
345         "resolve_trait_on_defaulted_unit",
346         "converted into hard error, see https://github.com/rust-lang/rust/issues/48950",
347     );
348     store.register_removed(
349         "private_no_mangle_fns",
350         "no longer a warning, `#[no_mangle]` functions always exported",
351     );
352     store.register_removed(
353         "private_no_mangle_statics",
354         "no longer a warning, `#[no_mangle]` statics always exported",
355     );
356     store.register_removed("bad_repr", "replaced with a generic attribute input check");
357     store.register_removed(
358         "duplicate_matcher_binding_name",
359         "converted into hard error, see https://github.com/rust-lang/rust/issues/57742",
360     );
361     store.register_removed(
362         "incoherent_fundamental_impls",
363         "converted into hard error, see https://github.com/rust-lang/rust/issues/46205",
364     );
365     store.register_removed(
366         "legacy_constructor_visibility",
367         "converted into hard error, see https://github.com/rust-lang/rust/issues/39207",
368     );
369     store.register_removed(
370         "legacy_directory_ownership",
371         "converted into hard error, see https://github.com/rust-lang/rust/issues/37872",
372     );
373     store.register_removed(
374         "safe_extern_statics",
375         "converted into hard error, see https://github.com/rust-lang/rust/issues/36247",
376     );
377     store.register_removed(
378         "parenthesized_params_in_types_and_modules",
379         "converted into hard error, see https://github.com/rust-lang/rust/issues/42238",
380     );
381     store.register_removed(
382         "duplicate_macro_exports",
383         "converted into hard error, see https://github.com/rust-lang/rust/issues/35896",
384     );
385     store.register_removed(
386         "nested_impl_trait",
387         "converted into hard error, see https://github.com/rust-lang/rust/issues/59014",
388     );
389     store.register_removed("plugin_as_library", "plugins have been deprecated and retired");
390 }
391
392 fn register_internals(store: &mut lint::LintStore) {
393     store.register_lints(&DefaultHashTypes::get_lints());
394     store.register_early_pass(|| box DefaultHashTypes::new());
395     store.register_lints(&LintPassImpl::get_lints());
396     store.register_early_pass(|| box LintPassImpl);
397     store.register_lints(&TyTyKind::get_lints());
398     store.register_late_pass(|| box TyTyKind);
399     store.register_group(
400         false,
401         "rustc::internal",
402         None,
403         vec![
404             LintId::of(DEFAULT_HASH_TYPES),
405             LintId::of(USAGE_OF_TY_TYKIND),
406             LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
407             LintId::of(TY_PASS_BY_REFERENCE),
408             LintId::of(USAGE_OF_QUALIFIED_TY),
409         ],
410     );
411 }