Skip to content

Commit 53683ed

Browse files
committed
Add some comments
1 parent 81dd67a commit 53683ed

File tree

2 files changed

+74
-23
lines changed

2 files changed

+74
-23
lines changed

clippy_lints/src/std_instead_of_core.rs

Lines changed: 71 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
use std::hash::{Hash, Hasher};
21
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
32
use clippy_utils::is_from_proc_macro;
43
use rustc_ast::Attribute;
54
use rustc_data_structures::fx::FxIndexSet;
65
use rustc_errors::Applicability;
76
use rustc_hir::def::Res;
87
use rustc_hir::def_id::DefId;
9-
use rustc_hir::{Arm, Block, Body, Expr, FieldDef, FnDecl, ForeignItem, GenericParam, Generics, HirId, ImplItem, Item, ItemKind, Local, Mod, Pat, Path, PathSegment, PolyTraitRef, Stmt, TraitItem, Ty, UseKind, Variant, VariantData};
108
use rustc_hir::intravisit::FnKind;
9+
use rustc_hir::{
10+
Arm, Block, Body, Expr, FieldDef, FnDecl, ForeignItem, GenericParam, Generics, HirId, ImplItem, Item, ItemKind,
11+
Local, Mod, Pat, Path, PathSegment, PolyTraitRef, Stmt, TraitItem, Ty, UseKind, Variant, VariantData,
12+
};
1113
use rustc_lint::{LateContext, LateLintPass, LintContext};
1214
use rustc_middle::lint::in_external_macro;
1315
use rustc_session::impl_lint_pass;
16+
use rustc_span::def_id::LocalDefId;
1417
use rustc_span::symbol::kw;
1518
use rustc_span::{sym, Span};
16-
use rustc_span::def_id::LocalDefId;
19+
use std::hash::{Hash, Hasher};
1720

1821
declare_clippy_lint! {
1922
/// ### What it does
@@ -98,15 +101,21 @@ pub struct StdReexports {
98101
// twice. First for the mod, second for the macro. This is used to avoid the lint reporting for the macro
99102
// when the path could be also be used to access the module.
100103
prev_span: Span,
101-
open_use: Option<OpenUseSpan>
104+
// When inside of a UseKind::ListStem the previous check
105+
// isn't enough to ensure correct parsing
106+
open_use: Option<OpenUseSpan>,
102107
}
103108

104109
impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]);
105110

111+
/// Save all members of a UseKind::ListStem `use std::fmt::{Debug, Result};`
112+
/// Lint when the ListStem closes. However, since there's no look-ahead (that I know of).
113+
/// Close whenever something is encountered that's outside of the container `Span`.
106114
#[derive(Debug)]
107115
struct OpenUseSpan {
108116
container: Span,
109-
members: FxIndexSet<UseSpanMember>
117+
// Preserve insert order on iteration, so that lints come out in 'source order'
118+
members: FxIndexSet<UseSpanMember>,
110119
}
111120

112121
#[derive(Debug, Copy, Clone)]
@@ -152,37 +161,51 @@ impl StdReexports {
152161
self.open_use = Some(collected_use);
153162
return;
154163
}
164+
// Short circuit
155165
if collected_use.members.is_empty() {
156166
return;
157167
}
158168
let mut place_holder_unique_check: Option<(Span, ReplaceLintData)> = None;
159-
let mut can_chunk = true;
169+
// If true after checking all members, the lint is 'fixable'.
170+
// Otherwise, just warn
171+
let mut all_same_valid_lint = true;
160172
for member in collected_use.members.iter() {
161173
match &member.lint_data {
162174
LintData::CanReplace(lint_data) => {
163175
if let Some((_span, prev_lint_data)) = place_holder_unique_check.take() {
164-
if prev_lint_data.lint.name == lint_data.lint.name && prev_lint_data.used_mod == lint_data.used_mod && prev_lint_data.replace_with == lint_data.replace_with {
176+
if prev_lint_data.lint.name == lint_data.lint.name
177+
&& prev_lint_data.used_mod == lint_data.used_mod
178+
&& prev_lint_data.replace_with == lint_data.replace_with
179+
{
165180
place_holder_unique_check = Some((member.first_seg_ident_span, *lint_data));
166181
} else {
167182
// Will have to warn for individual entries
168-
can_chunk = false;
183+
all_same_valid_lint = false;
169184
break;
170185
}
171186
} else {
172187
place_holder_unique_check = Some((member.first_seg_ident_span, *lint_data));
173188
}
174-
}
189+
},
175190
LintData::NoReplace => {
176191
// Will have to warn for individual entries
177-
can_chunk = false;
192+
all_same_valid_lint = false;
178193
break;
179-
}
194+
},
180195
}
181196
}
182197
// If they can all be replaced with the same thing, just lint and suggest, then
183198
// clippy-fix works as well
184-
if can_chunk {
185-
if let Some((first_segment_ident_span, ReplaceLintData { lint, used_mod, replace_with })) = place_holder_unique_check {
199+
if all_same_valid_lint {
200+
if let Some((
201+
first_segment_ident_span,
202+
ReplaceLintData {
203+
lint,
204+
used_mod,
205+
replace_with,
206+
},
207+
)) = place_holder_unique_check
208+
{
186209
span_lint_and_sugg(
187210
cx,
188211
lint,
@@ -195,10 +218,23 @@ impl StdReexports {
195218
}
196219
} else {
197220
for member in collected_use.members {
198-
if let LintData::CanReplace(ReplaceLintData { lint, used_mod, replace_with }) = member.lint_data {
199-
span_lint_hir_and_then(cx, lint, member.hir_id, member.inner, &format!("used import from `{used_mod}` instead of `{replace_with}`"), |diag| {
200-
diag.help(format!("consider importing the item from `{replace_with}`"));
201-
})
221+
if let LintData::CanReplace(ReplaceLintData {
222+
lint,
223+
used_mod,
224+
replace_with,
225+
}) = member.lint_data
226+
{
227+
// Just lint, don't suggest a change
228+
span_lint_hir_and_then(
229+
cx,
230+
lint,
231+
member.hir_id,
232+
member.inner,
233+
&format!("used import from `{used_mod}` instead of `{replace_with}`"),
234+
|diag| {
235+
diag.help(format!("consider importing the item from `{replace_with}`"));
236+
},
237+
)
202238
}
203239
}
204240
}
@@ -217,12 +253,12 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
217253
{
218254
let lint_data = match first_segment.ident.name {
219255
sym::std => match cx.tcx.crate_name(def_id.krate) {
220-
sym::core => LintData::CanReplace(ReplaceLintData{
256+
sym::core => LintData::CanReplace(ReplaceLintData {
221257
lint: STD_INSTEAD_OF_CORE,
222258
used_mod: "std",
223259
replace_with: "core",
224260
}),
225-
sym::alloc => LintData::CanReplace(ReplaceLintData{
261+
sym::alloc => LintData::CanReplace(ReplaceLintData {
226262
lint: STD_INSTEAD_OF_ALLOC,
227263
used_mod: "std",
228264
replace_with: "alloc",
@@ -234,7 +270,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
234270
},
235271
sym::alloc => {
236272
if cx.tcx.crate_name(def_id.krate) == sym::core {
237-
LintData::CanReplace(ReplaceLintData{
273+
LintData::CanReplace(ReplaceLintData {
238274
lint: ALLOC_INSTEAD_OF_CORE,
239275
used_mod: "alloc",
240276
replace_with: "core",
@@ -255,7 +291,12 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
255291
});
256292
return;
257293
}
258-
if let LintData::CanReplace(ReplaceLintData { lint, used_mod, replace_with }) = lint_data {
294+
if let LintData::CanReplace(ReplaceLintData {
295+
lint,
296+
used_mod,
297+
replace_with,
298+
}) = lint_data
299+
{
259300
if first_segment.ident.span != self.prev_span {
260301
span_lint_and_sugg(
261302
cx,
@@ -280,7 +321,6 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
280321
members: FxIndexSet::default(),
281322
})
282323
}
283-
284324
}
285325

286326
// Essentially, check every other parsable thing's start (except for attributes),
@@ -358,7 +398,15 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
358398
}
359399

360400
#[inline]
361-
fn check_fn(&mut self, cx: &LateContext<'tcx>, _: FnKind<'tcx>, _: &'tcx FnDecl<'tcx>, _: &'tcx Body<'tcx>, s: Span, _: LocalDefId) {
401+
fn check_fn(
402+
&mut self,
403+
cx: &LateContext<'tcx>,
404+
_: FnKind<'tcx>,
405+
_: &'tcx FnDecl<'tcx>,
406+
_: &'tcx Body<'tcx>,
407+
s: Span,
408+
_: LocalDefId,
409+
) {
362410
self.suggest_for_open_use_item_if_after(cx, s);
363411
}
364412

tests/ui/std_instead_of_core.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,17 @@ fn std_instead_of_core() {
3333
};
3434

3535
// Multiple import, some not in core/alloc, first pos
36+
#[rustfmt::skip]
3637
use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _};
3738
//~^ ERROR: used import from `std` instead of `core`
3839

3940
// Second pos
41+
#[rustfmt::skip]
4042
use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _};
4143
//~^ ERROR: used import from `std` instead of `core`
4244

4345
// Third pos
46+
#[rustfmt::skip]
4447
use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _};
4548
//~^ ERROR: used import from `std` instead of `core`
4649

0 commit comments

Comments
 (0)