1 #![forbid(unsafe_code)]
2 #![warn(nonstandard_style, rust_2018_idioms, rustdoc, unused)]
3 // Note: This does not guarantee compatibility with forbidding these lints in the future.
4 // If rustc adds a new lint, we may not be able to keep this.
5 #![forbid(future_incompatible, rust_2018_compatibility)]
6 #![allow(unknown_lints)] // for old compilers
7 #![warn(
8     box_pointers,
9     deprecated_in_future,
10     elided_lifetimes_in_paths,
11     explicit_outlives_requirements,
12     macro_use_extern_crate,
13     meta_variable_misuse,
14     missing_copy_implementations,
15     missing_crate_level_docs,
16     missing_debug_implementations,
17     missing_docs,
18     non_ascii_idents,
19     single_use_lifetimes,
20     trivial_casts,
21     trivial_numeric_casts,
22     unaligned_references,
23     unreachable_pub,
24     unused_extern_crates,
25     unused_import_braces,
26     unused_lifetimes,
27     unused_qualifications,
28     unused_results,
29     variant_size_differences
30 )]
31 // absolute_paths_not_starting_with_crate, anonymous_parameters, keyword_idents, pointer_structural_match: forbidden as a part of future_incompatible
32 // missing_doc_code_examples, private_doc_tests, invalid_html_tags: warned as a part of rustdoc
33 // unsafe_block_in_unsafe_fn: unstable
34 // unsafe_code: forbidden
35 // unstable_features: deprecated: https://doc.rust-lang.org/beta/rustc/lints/listing/allowed-by-default.html#unstable-features
36 // unused_crate_dependencies: unrelated
37 #![warn(clippy::all, clippy::pedantic, clippy::nursery)]
38 #![warn(clippy::restriction)]
39 #![allow(clippy::blanket_clippy_restriction_lints)] // this is a test, so enable all restriction lints intentionally.
40 
41 // Check interoperability with rustc and clippy lints.
42 
43 pub mod basic {
44     include!("include/basic.rs");
45 }
46 
47 pub mod box_pointers {
48     use pin_project_lite::pin_project;
49 
50     pin_project! {
51         #[derive(Debug)]
52         pub struct Struct {
53             #[pin]
54             pub p: Box<isize>,
55             pub u: Box<isize>,
56         }
57     }
58 }
59 
60 pub mod explicit_outlives_requirements {
61     use pin_project_lite::pin_project;
62 
63     pin_project! {
64         #[derive(Debug)]
65         pub struct Struct<'a, T, U>
66         where
67             T: ?Sized,
68             U: ?Sized,
69         {
70             #[pin]
71             pub pinned: &'a mut T,
72             pub unpinned: &'a mut U,
73         }
74     }
75 }
76 
77 pub mod clippy_mut_mut {
78     use pin_project_lite::pin_project;
79 
80     pin_project! {
81         #[derive(Debug)]
82         pub struct Struct<'a, T, U> {
83             #[pin]
84             pub pinned: &'a mut T,
85             pub unpinned: &'a mut U,
86         }
87     }
88 }
89 
90 #[allow(unreachable_pub)]
91 mod clippy_redundant_pub_crate {
92     use pin_project_lite::pin_project;
93 
94     pin_project! {
95         #[derive(Debug)]
96         pub struct Struct<T, U> {
97             #[pin]
98             pub pinned: T,
99             pub unpinned: U,
100         }
101     }
102 }
103 
104 pub mod clippy_type_repetition_in_bounds {
105     use pin_project_lite::pin_project;
106 
107     pin_project! {
108         #[derive(Debug)]
109         pub struct Struct<T, U>
110         where
111             Struct<T, U>: Sized,
112         {
113             #[pin]
114             pub pinned: T,
115             pub unpinned: U,
116         }
117     }
118 }
119 
120 pub mod clippy_used_underscore_binding {
121     use pin_project_lite::pin_project;
122 
123     pin_project! {
124         #[derive(Debug)]
125         pub struct Struct<T, U> {
126             #[pin]
127             pub _pinned: T,
128             pub _unpinned: U,
129         }
130     }
131 }
132 
133 #[allow(box_pointers)]
134 #[allow(clippy::restriction)]
135 #[rustversion::attr(not(nightly), ignore)]
136 #[test]
check_lint_list()137 fn check_lint_list() {
138     use std::{env, fs, path::PathBuf, process::Command, str};
139 
140     type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
141 
142     fn assert_eq(expected_path: &str, actual: &str) -> Result<()> {
143         let manifest_dir = env::var_os("CARGO_MANIFEST_DIR")
144             .map(PathBuf::from)
145             .expect("CARGO_MANIFEST_DIR not set");
146         let expected_path = manifest_dir.join(expected_path);
147         let expected = fs::read_to_string(&expected_path)?;
148         if expected != actual {
149             if env::var_os("CI").map_or(false, |v| v == "true") {
150                 panic!(
151                     "assertion failed:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
152                     "-".repeat(60),
153                     expected,
154                     actual,
155                 );
156             } else {
157                 fs::write(&expected_path, actual)?;
158             }
159         }
160         Ok(())
161     }
162 
163     (|| -> Result<()> {
164         let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
165         let output = Command::new(rustc).args(&["-W", "help"]).output()?;
166         let new = str::from_utf8(&output.stdout)?;
167         assert_eq("tests/lint.txt", new)
168     })()
169     .unwrap_or_else(|e| panic!("{}", e));
170 }
171