@@ -91,40 +91,46 @@ future-compatibility warnings. These are a special category of lint warning.
9191Adding a new future-compatibility warning can be done as follows.
9292
9393``` rust
94- // 1. Define the lint in `compiler/rustc_middle/src/lint/builtin.rs`:
94+ // 1. Define the lint in `compiler/rustc_lint/src/builtin.rs` and
95+ // add the metadata for the future incompatibility:
9596declare_lint! {
96- pub YOUR_ERROR_HERE ,
97+ pub YOUR_LINT_HERE ,
9798 Warn ,
9899 " illegal use of foo bar baz"
100+ @ future_incompatible = FutureIncompatibleInfo {
101+ reason : fcw! (FutureReleaseError #1234 ) // your tracking issue here!
102+ },
103+ }
104+
105+ // 2. Add a decidacted lint pass for it.
106+ // This step can be skipped if you emit the lint as part of an existing pass.
107+
108+ #[derive(Default )]
109+ pub struct MyLintPass {
110+ ...
99111}
100112
101- // 2. Add to the list of HardwiredLints in the same file:
102- impl LintPass for HardwiredLints {
103- fn get_lints (& self ) -> LintArray {
104- lint_array! (
105- .. ,
106- YOUR_ERROR_HERE
107- )
108- }
113+ impl {Early ,Late }LintPass for MyLintPass {
114+ ...
109115}
110116
111- // 3. Register the lint in `compiler/rustc_lint/src/lib.rs`:
112- store . register_future_incompatible (sess , vec! [
113- ... ,
114- FutureIncompatibleInfo {
115- id : LintId :: of (YOUR_ERROR_HERE ),
116- reason : fcw! (FutureReleaseError #1234 ) // your tracking issue here!
117+ impl_lint_pass! (MyLintPass => [YOUR_LINT_HERE ]);
118+
119+ // 3. emit the lint somewhere in your lint pass:
120+ cx . emit_span_lint (
121+ YOUR_LINT_HERE ,
122+ pat . span,
123+ // some diagnostic struct
124+ MyDiagnostic {
125+ ...
117126 },
118- ]);
119-
120- // 4. Report the lint:
121- tcx . lint_node (
122- lint :: builtin :: YOUR_ERROR_HERE ,
123- path_id ,
124- binding . span,
125- format! (" some helper message here" ));
127+ );
128+
126129```
127130
131+ Finally, register the lint in ` compiler/rustc_lint/src/lib.rs ` .
132+ There are many examples in that file that already show how to do so.
133+
128134#### Helpful techniques
129135
130136It can often be challenging to filter out new warnings from older, pre-existing
@@ -221,7 +227,10 @@ The first reference you will likely find is the lint definition [in
221227declare_lint! {
222228 pub OVERLAPPING_INHERENT_IMPLS ,
223229 Deny , // this may also say Warning
224- " two overlapping inherent impls define an item with the same name were erroneously allowed"
230+ " two overlapping inherent impls define an item with the same name were erroneously allowed" ,
231+ @ future_incompatible = FutureIncompatibleInfo {
232+ reason : fcw! (FutureReleaseError #1234 ), // your tracking issue here!
233+ },
225234}
226235```
227236
@@ -231,19 +240,6 @@ the file as [part of a `lint_array!`][lintarraysource]; remove it too.
231240
232241[ lintarraysource ] : https://github.com/rust-lang/rust/blob/085d71c3efe453863739c1fb68fd9bd1beff214f/src/librustc/lint/builtin.rs#L252-L290
233242
234- Next, you see [ a reference to ` OVERLAPPING_INHERENT_IMPLS ` in
235- ` rustc_lint/src/lib.rs ` ] [ futuresource ] . This is defining the lint as a "future
236- compatibility lint":
237-
238- ``` rust
239- FutureIncompatibleInfo {
240- id : LintId :: of (OVERLAPPING_INHERENT_IMPLS ),
241- reason : fcw! (FutureReleaseError #1234 ), // your tracking issue here!
242- },
243- ```
244-
245- Remove this too.
246-
247243#### Add the lint to the list of removed lints.
248244
249245In ` compiler/rustc_lint/src/lib.rs ` there is a list of "renamed and removed lints".
@@ -269,6 +265,8 @@ self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS,
269265 msg );
270266```
271267
268+ You'll also often find ` node_span_lint ` used for this.
269+
272270We want to convert this into an error. In some cases, there may be an
273271existing error for this scenario. In others, we will need to allocate a
274272fresh diagnostic code. [ Instructions for allocating a fresh diagnostic
@@ -285,6 +283,17 @@ struct_span_code_err!(self.dcx(), self.tcx.span_of_impl(item1).unwrap(), E0592,
285283 . emit ();
286284```
287285
286+ Or better: a structured diagnostic like this:
287+
288+ ``` rust
289+ #[derive(Diagnostic )]
290+ struct MyDiagnostic {
291+ #[label]
292+ span : Span ,
293+ ...
294+ }
295+ ```
296+
288297#### Update tests
289298
290299Finally, run the test suite. These should be some tests that used to reference
0 commit comments