]> git.lizzy.rs Git - rust.git/blob - src/librustc_lint/lib.rs
Simplify SaveHandler trait
[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_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
14 #![cfg_attr(test, feature(test))]
15 #![feature(box_patterns)]
16 #![feature(box_syntax)]
17 #![feature(nll)]
18 #![feature(rustc_diagnostic_macros)]
19
20 #![recursion_limit="256"]
21
22 #![deny(rust_2018_idioms)]
23 #![deny(unused_lifetimes)]
24
25 #[macro_use]
26 extern crate rustc;
27
28 mod error_codes;
29 mod nonstandard_style;
30 pub mod builtin;
31 mod types;
32 mod unused;
33 mod non_ascii_idents;
34
35 use rustc::lint;
36 use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray};
37 use rustc::lint::builtin::{
38     BARE_TRAIT_OBJECTS,
39     ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
40     ELIDED_LIFETIMES_IN_PATHS,
41     EXPLICIT_OUTLIVES_REQUIREMENTS,
42     INTRA_DOC_LINK_RESOLUTION_FAILURE,
43     MISSING_DOC_CODE_EXAMPLES,
44     PRIVATE_DOC_TESTS,
45     parser::ILL_FORMED_ATTRIBUTE_INPUT,
46 };
47 use rustc::session;
48 use rustc::hir;
49 use rustc::hir::def_id::DefId;
50 use rustc::ty::query::Providers;
51 use rustc::ty::TyCtxt;
52
53 use syntax::ast;
54 use syntax::edition::Edition;
55 use syntax_pos::Span;
56
57 use session::Session;
58 use lint::LintId;
59 use lint::FutureIncompatibleInfo;
60
61 use nonstandard_style::*;
62 use builtin::*;
63 use types::*;
64 use unused::*;
65 use non_ascii_idents::*;
66 use rustc::lint::internal::*;
67
68 /// Useful for other parts of the compiler.
69 pub use builtin::SoftLints;
70
71 pub fn provide(providers: &mut Providers<'_>) {
72     *providers = Providers {
73         lint_mod,
74         ..*providers
75     };
76 }
77
78 fn lint_mod(tcx: TyCtxt<'_>, module_def_id: DefId) {
79     lint::late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new());
80 }
81
82 macro_rules! pre_expansion_lint_passes {
83     ($macro:path, $args:tt) => (
84         $macro!($args, [
85             KeywordIdents: KeywordIdents,
86             UnusedDocComment: UnusedDocComment,
87         ]);
88     )
89 }
90
91 macro_rules! early_lint_passes {
92     ($macro:path, $args:tt) => (
93         $macro!($args, [
94             UnusedParens: UnusedParens,
95             UnusedImportBraces: UnusedImportBraces,
96             UnsafeCode: UnsafeCode,
97             AnonymousParameters: AnonymousParameters,
98             EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
99             NonCamelCaseTypes: NonCamelCaseTypes,
100             DeprecatedAttr: DeprecatedAttr::new(),
101             WhileTrue: WhileTrue,
102             NonAsciiIdents: NonAsciiIdents,
103         ]);
104     )
105 }
106
107 macro_rules! declare_combined_early_pass {
108     ([$name:ident], $passes:tt) => (
109         early_lint_methods!(declare_combined_early_lint_pass, [pub $name, $passes]);
110     )
111 }
112
113 pre_expansion_lint_passes!(declare_combined_early_pass, [BuiltinCombinedPreExpansionLintPass]);
114 early_lint_passes!(declare_combined_early_pass, [BuiltinCombinedEarlyLintPass]);
115
116 macro_rules! late_lint_passes {
117     ($macro:path, $args:tt) => (
118         $macro!($args, [
119             // FIXME: Look into regression when this is used as a module lint
120             // May Depend on constants elsewhere
121             UnusedBrokenConst: UnusedBrokenConst,
122
123             // Uses attr::is_used which is untracked, can't be an incremental module pass.
124             UnusedAttributes: UnusedAttributes::new(),
125
126             // Needs to run after UnusedAttributes as it marks all `feature` attributes as used.
127             UnstableFeatures: UnstableFeatures,
128
129             // Tracks state across modules
130             UnnameableTestItems: UnnameableTestItems::new(),
131
132             // Tracks attributes of parents
133             MissingDoc: MissingDoc::new(),
134
135             // Depends on access levels
136             // FIXME: Turn the computation of types which implement Debug into a query
137             // and change this to a module lint pass
138             MissingDebugImplementations: MissingDebugImplementations::default(),
139         ]);
140     )
141 }
142
143 macro_rules! late_lint_mod_passes {
144     ($macro:path, $args:tt) => (
145         $macro!($args, [
146             HardwiredLints: HardwiredLints,
147             ImproperCTypes: ImproperCTypes,
148             VariantSizeDifferences: VariantSizeDifferences,
149             BoxPointers: BoxPointers,
150             PathStatements: PathStatements,
151
152             // Depends on referenced function signatures in expressions
153             UnusedResults: UnusedResults,
154
155             NonUpperCaseGlobals: NonUpperCaseGlobals,
156             NonShorthandFieldPatterns: NonShorthandFieldPatterns,
157             UnusedAllocation: UnusedAllocation,
158
159             // Depends on types used in type definitions
160             MissingCopyImplementations: MissingCopyImplementations,
161
162             PluginAsLibrary: PluginAsLibrary,
163
164             // Depends on referenced function signatures in expressions
165             MutableTransmutes: MutableTransmutes,
166
167             // Depends on types of fields, checks if they implement Drop
168             UnionsWithDropFields: UnionsWithDropFields,
169
170             TypeAliasBounds: TypeAliasBounds,
171
172             TrivialConstraints: TrivialConstraints,
173             TypeLimits: TypeLimits::new(),
174
175             NonSnakeCase: NonSnakeCase,
176             InvalidNoMangleItems: InvalidNoMangleItems,
177
178             // Depends on access levels
179             UnreachablePub: UnreachablePub,
180
181             ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
182         ]);
183     )
184 }
185
186 macro_rules! declare_combined_late_pass {
187     ([$v:vis $name:ident], $passes:tt) => (
188         late_lint_methods!(declare_combined_late_lint_pass, [$v $name, $passes], ['tcx]);
189     )
190 }
191
192 // FIXME: Make a separate lint type which do not require typeck tables
193 late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass]);
194
195 late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]);
196
197 /// Tell the `LintStore` about all the built-in lints (the ones
198 /// defined in this crate and the ones defined in
199 /// `rustc::lint::builtin`).
200 pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
201     macro_rules! add_lint_group {
202         ($sess:ident, $name:expr, $($lint:ident),*) => (
203             store.register_group($sess, false, $name, None, vec![$(LintId::of($lint)),*]);
204         )
205     }
206
207     macro_rules! register_pass {
208         ($method:ident, $constructor:expr, [$($args:expr),*]) => (
209             store.$method(sess, false, false, $($args,)* box $constructor);
210         )
211     }
212
213     macro_rules! register_passes {
214         ([$method:ident, $args:tt], [$($passes:ident: $constructor:expr,)*]) => (
215             $(
216                 register_pass!($method, $constructor, $args);
217             )*
218         )
219     }
220
221     if sess.map(|sess| sess.opts.debugging_opts.no_interleave_lints).unwrap_or(false) {
222         pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]);
223         early_lint_passes!(register_passes, [register_early_pass, []]);
224         late_lint_passes!(register_passes, [register_late_pass, [false]]);
225         late_lint_mod_passes!(register_passes, [register_late_pass, [true]]);
226     } else {
227         store.register_pre_expansion_pass(
228             sess,
229             false,
230             true,
231             box BuiltinCombinedPreExpansionLintPass::new()
232         );
233         store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new());
234         store.register_late_pass(
235             sess, false, true, true, box BuiltinCombinedModuleLateLintPass::new()
236         );
237         store.register_late_pass(
238             sess, false, true, false, box BuiltinCombinedLateLintPass::new()
239         );
240     }
241
242     add_lint_group!(sess,
243                     "nonstandard_style",
244                     NON_CAMEL_CASE_TYPES,
245                     NON_SNAKE_CASE,
246                     NON_UPPER_CASE_GLOBALS);
247
248     add_lint_group!(sess,
249                     "unused",
250                     UNUSED_IMPORTS,
251                     UNUSED_VARIABLES,
252                     UNUSED_ASSIGNMENTS,
253                     DEAD_CODE,
254                     UNUSED_MUT,
255                     UNREACHABLE_CODE,
256                     UNREACHABLE_PATTERNS,
257                     UNUSED_MUST_USE,
258                     UNUSED_UNSAFE,
259                     PATH_STATEMENTS,
260                     UNUSED_ATTRIBUTES,
261                     UNUSED_MACROS,
262                     UNUSED_ALLOCATION,
263                     UNUSED_DOC_COMMENTS,
264                     UNUSED_EXTERN_CRATES,
265                     UNUSED_FEATURES,
266                     UNUSED_LABELS,
267                     UNUSED_PARENS);
268
269     add_lint_group!(sess,
270                     "rust_2018_idioms",
271                     BARE_TRAIT_OBJECTS,
272                     UNUSED_EXTERN_CRATES,
273                     ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
274                     ELIDED_LIFETIMES_IN_PATHS,
275                     EXPLICIT_OUTLIVES_REQUIREMENTS
276
277                     // FIXME(#52665, #47816) not always applicable and not all
278                     // macros are ready for this yet.
279                     // UNREACHABLE_PUB,
280
281                     // FIXME macro crates are not up for this yet, too much
282                     // breakage is seen if we try to encourage this lint.
283                     // MACRO_USE_EXTERN_CRATE,
284                     );
285
286     add_lint_group!(sess,
287                     "rustdoc",
288                     INTRA_DOC_LINK_RESOLUTION_FAILURE,
289                     MISSING_DOC_CODE_EXAMPLES,
290                     PRIVATE_DOC_TESTS);
291
292     // Guidelines for creating a future incompatibility lint:
293     //
294     // - Create a lint defaulting to warn as normal, with ideally the same error
295     //   message you would normally give
296     // - Add a suitable reference, typically an RFC or tracking issue. Go ahead
297     //   and include the full URL, sort items in ascending order of issue numbers.
298     // - Later, change lint to error
299     // - Eventually, remove lint
300     store.register_future_incompatible(sess, vec![
301         FutureIncompatibleInfo {
302             id: LintId::of(PRIVATE_IN_PUBLIC),
303             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
304             edition: None,
305         },
306         FutureIncompatibleInfo {
307             id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE),
308             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
309             edition: None,
310         },
311         FutureIncompatibleInfo {
312             id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
313             reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
314             edition: None,
315         },
316         FutureIncompatibleInfo {
317             id: LintId::of(DUPLICATE_MACRO_EXPORTS),
318             reference: "issue #35896 <https://github.com/rust-lang/rust/issues/35896>",
319             edition: Some(Edition::Edition2018),
320         },
321         FutureIncompatibleInfo {
322             id: LintId::of(KEYWORD_IDENTS),
323             reference: "issue #49716 <https://github.com/rust-lang/rust/issues/49716>",
324             edition: Some(Edition::Edition2018),
325         },
326         FutureIncompatibleInfo {
327             id: LintId::of(SAFE_EXTERN_STATICS),
328             reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
329             edition: None,
330         },
331         FutureIncompatibleInfo {
332             id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
333             reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
334             edition: None,
335         },
336         FutureIncompatibleInfo {
337             id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP),
338             reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
339             edition: None,
340         },
341         FutureIncompatibleInfo {
342             id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY),
343             reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
344             edition: None,
345         },
346         FutureIncompatibleInfo {
347             id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
348             reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
349             edition: None,
350         },
351         FutureIncompatibleInfo {
352             id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN),
353             reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
354             edition: None,
355         },
356         FutureIncompatibleInfo {
357             id: LintId::of(ANONYMOUS_PARAMETERS),
358             reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
359             edition: Some(Edition::Edition2018),
360         },
361         FutureIncompatibleInfo {
362             id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES),
363             reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
364             edition: None,
365         },
366         FutureIncompatibleInfo {
367             id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS),
368             reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
369             edition: None,
370         },
371         FutureIncompatibleInfo {
372             id: LintId::of(SAFE_PACKED_BORROWS),
373             reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
374             edition: None,
375         },
376         FutureIncompatibleInfo {
377             id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS),
378             reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
379             edition: None,
380         },
381         FutureIncompatibleInfo {
382             id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
383             reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
384             edition: Some(Edition::Edition2018),
385         },
386         FutureIncompatibleInfo {
387             id: LintId::of(UNSTABLE_NAME_COLLISIONS),
388             reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>",
389             edition: None,
390             // Note: this item represents future incompatibility of all unstable functions in the
391             //       standard library, and thus should never be removed or changed to an error.
392         },
393         FutureIncompatibleInfo {
394             id: LintId::of(ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE),
395             reference: "issue #53130 <https://github.com/rust-lang/rust/issues/53130>",
396             edition: Some(Edition::Edition2018),
397         },
398         FutureIncompatibleInfo {
399             id: LintId::of(WHERE_CLAUSES_OBJECT_SAFETY),
400             reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
401             edition: None,
402         },
403         FutureIncompatibleInfo {
404             id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK),
405             reference: "issue #50504 <https://github.com/rust-lang/rust/issues/50504>",
406             edition: None,
407         },
408         FutureIncompatibleInfo {
409             id: LintId::of(MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS),
410             reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>",
411             edition: None,
412         },
413         FutureIncompatibleInfo {
414             id: LintId::of(ILL_FORMED_ATTRIBUTE_INPUT),
415             reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
416             edition: None,
417         },
418         FutureIncompatibleInfo {
419             id: LintId::of(AMBIGUOUS_ASSOCIATED_ITEMS),
420             reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>",
421             edition: None,
422         },
423         FutureIncompatibleInfo {
424             id: LintId::of(NESTED_IMPL_TRAIT),
425             reference: "issue #59014 <https://github.com/rust-lang/rust/issues/59014>",
426             edition: None,
427         },
428         FutureIncompatibleInfo {
429             id: LintId::of(MUTABLE_BORROW_RESERVATION_CONFLICT),
430             reference: "issue #59159 <https://github.com/rust-lang/rust/issues/59159>",
431             edition: None,
432         },
433         FutureIncompatibleInfo {
434             id: LintId::of(INDIRECT_STRUCTURAL_MATCH),
435             reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
436             edition: None,
437         }
438         ]);
439
440     // Register renamed and removed lints.
441     store.register_renamed("single_use_lifetime", "single_use_lifetimes");
442     store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");
443     store.register_renamed("bare_trait_object", "bare_trait_objects");
444     store.register_renamed("unstable_name_collision", "unstable_name_collisions");
445     store.register_renamed("unused_doc_comment", "unused_doc_comments");
446     store.register_renamed("async_idents", "keyword_idents");
447     store.register_removed("unknown_features", "replaced by an error");
448     store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
449     store.register_removed("negate_unsigned", "cast a signed value instead");
450     store.register_removed("raw_pointer_derive", "using derive with raw pointers is ok");
451     // Register lint group aliases.
452     store.register_group_alias("nonstandard_style", "bad_style");
453     // This was renamed to `raw_pointer_derive`, which was then removed,
454     // so it is also considered removed.
455     store.register_removed("raw_pointer_deriving", "using derive with raw pointers is ok");
456     store.register_removed("drop_with_repr_extern", "drop flags have been removed");
457     store.register_removed("fat_ptr_transmutes", "was accidentally removed back in 2014");
458     store.register_removed("deprecated_attr", "use `deprecated` instead");
459     store.register_removed("transmute_from_fn_item_types",
460         "always cast functions before transmuting them");
461     store.register_removed("hr_lifetime_in_assoc_type",
462         "converted into hard error, see https://github.com/rust-lang/rust/issues/33685");
463     store.register_removed("inaccessible_extern_crate",
464         "converted into hard error, see https://github.com/rust-lang/rust/issues/36886");
465     store.register_removed("super_or_self_in_global_path",
466         "converted into hard error, see https://github.com/rust-lang/rust/issues/36888");
467     store.register_removed("overlapping_inherent_impls",
468         "converted into hard error, see https://github.com/rust-lang/rust/issues/36889");
469     store.register_removed("illegal_floating_point_constant_pattern",
470         "converted into hard error, see https://github.com/rust-lang/rust/issues/36890");
471     store.register_removed("illegal_struct_or_enum_constant_pattern",
472         "converted into hard error, see https://github.com/rust-lang/rust/issues/36891");
473     store.register_removed("lifetime_underscore",
474         "converted into hard error, see https://github.com/rust-lang/rust/issues/36892");
475     store.register_removed("extra_requirement_in_impl",
476         "converted into hard error, see https://github.com/rust-lang/rust/issues/37166");
477     store.register_removed("legacy_imports",
478         "converted into hard error, see https://github.com/rust-lang/rust/issues/38260");
479     store.register_removed("coerce_never",
480         "converted into hard error, see https://github.com/rust-lang/rust/issues/48950");
481     store.register_removed("resolve_trait_on_defaulted_unit",
482         "converted into hard error, see https://github.com/rust-lang/rust/issues/48950");
483     store.register_removed("private_no_mangle_fns",
484         "no longer a warning, `#[no_mangle]` functions always exported");
485     store.register_removed("private_no_mangle_statics",
486         "no longer a warning, `#[no_mangle]` statics always exported");
487     store.register_removed("bad_repr",
488         "replaced with a generic attribute input check");
489     store.register_removed("duplicate_matcher_binding_name",
490         "converted into hard error, see https://github.com/rust-lang/rust/issues/57742");
491     store.register_removed("incoherent_fundamental_impls",
492         "converted into hard error, see https://github.com/rust-lang/rust/issues/46205");
493 }
494
495 pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
496     store.register_early_pass(sess, false, false, box DefaultHashTypes::new());
497     store.register_early_pass(sess, false, false, box LintPassImpl);
498     store.register_late_pass(sess, false, false, false, box TyTyKind);
499     store.register_group(
500         sess,
501         false,
502         "rustc::internal",
503         None,
504         vec![
505             LintId::of(DEFAULT_HASH_TYPES),
506             LintId::of(USAGE_OF_TY_TYKIND),
507             LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
508             LintId::of(TY_PASS_BY_REFERENCE),
509             LintId::of(USAGE_OF_QUALIFIED_TY),
510         ],
511     );
512 }