Skip to content

Commit 3cac327

Browse files
deduplicate warnings
Co-authored-by: Waffle Lapkin <[email protected]>
1 parent b22f0a7 commit 3cac327

File tree

5 files changed

+76
-29
lines changed

5 files changed

+76
-29
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
575575
// as the rest of the type. As such, we ignore missing
576576
// stability attributes.
577577
},
578+
None,
578579
);
579580
}
580581
self.lowerer.lower_ty(ty).into()

compiler/rustc_middle/src/middle/stability.rs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
//! propagating default levels lexically from parent to children ast nodes.
33
44
use std::num::NonZero;
5+
use std::ops::ControlFlow;
56

67
use rustc_ast::NodeId;
8+
use rustc_data_structures::fx::FxHashSet;
79
use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer};
810
use rustc_feature::GateIssue;
911
use rustc_hir::attrs::{DeprecatedSince, Deprecation};
12+
use rustc_hir::def::{CtorOf, DefKind};
1013
use rustc_hir::def_id::{DefId, LocalDefId};
1114
use rustc_hir::{self as hir, ConstStability, DefaultBodyStability, HirId, Stability};
1215
use rustc_macros::{Decodable, Encodable, HashStable, Subdiagnostic};
@@ -191,6 +194,33 @@ pub fn early_report_macro_deprecation(
191194
};
192195
lint_buffer.buffer_lint(deprecation_lint(is_in_effect), node_id, span, diag);
193196
}
197+
/// supress duplicate warning when importing unit or tuple structs
198+
/// (which have resolutions in multiple namespaces)
199+
fn check_already_linted(
200+
tcx: TyCtxt<'_>,
201+
hir_id: HirId,
202+
def_id: DefId,
203+
already_linted_paths: Option<&mut FxHashSet<(HirId, DefId)>>,
204+
) -> ControlFlow<()> {
205+
let Some(already_linted_paths) = already_linted_paths else {
206+
return ControlFlow::Continue(());
207+
};
208+
209+
let def_id = match tcx.def_kind(def_id) {
210+
// parent so the defid matches that of the struct
211+
DefKind::Ctor(CtorOf::Struct, _) => tcx.parent(def_id),
212+
// just the defid of the struct
213+
DefKind::Struct => def_id,
214+
// otherwise, we don't care
215+
_ => return ControlFlow::Continue(()),
216+
};
217+
218+
if already_linted_paths.insert((hir_id, def_id)) {
219+
return ControlFlow::Continue(());
220+
}
221+
222+
ControlFlow::Break(())
223+
}
194224

195225
fn late_report_deprecation(
196226
tcx: TyCtxt<'_>,
@@ -199,6 +229,7 @@ fn late_report_deprecation(
199229
method_span: Option<Span>,
200230
hir_id: HirId,
201231
def_id: DefId,
232+
already_linted_paths: Option<&mut FxHashSet<(HirId, DefId)>>,
202233
) {
203234
if span.in_derive_expansion() {
204235
return;
@@ -214,6 +245,10 @@ fn late_report_deprecation(
214245
return;
215246
}
216247

248+
if check_already_linted(tcx, hir_id, def_id, already_linted_paths).is_break() {
249+
return;
250+
}
251+
217252
let def_path = with_no_trimmed_paths!(tcx.def_path_str(def_id));
218253
let def_kind = tcx.def_descr(def_id);
219254

@@ -303,7 +338,7 @@ impl<'tcx> TyCtxt<'tcx> {
303338
span: Span,
304339
method_span: Option<Span>,
305340
) -> EvalResult {
306-
self.eval_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
341+
self.eval_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No, None)
307342
}
308343

309344
/// Evaluates the stability of an item.
@@ -324,6 +359,7 @@ impl<'tcx> TyCtxt<'tcx> {
324359
span: Span,
325360
method_span: Option<Span>,
326361
allow_unstable: AllowUnstable,
362+
already_linted_paths: Option<&mut FxHashSet<(HirId, DefId)>>,
327363
) -> EvalResult {
328364
// Deprecated attributes apply in-crate and cross-crate.
329365
if let Some(id) = id {
@@ -341,7 +377,15 @@ impl<'tcx> TyCtxt<'tcx> {
341377
// hierarchy.
342378
let depr_attr = &depr_entry.attr;
343379
if !skip || depr_attr.is_since_rustc_version() {
344-
late_report_deprecation(self, depr_attr, span, method_span, id, def_id);
380+
late_report_deprecation(
381+
self,
382+
depr_attr,
383+
span,
384+
method_span,
385+
id,
386+
def_id,
387+
already_linted_paths,
388+
);
345389
}
346390
};
347391
}
@@ -492,7 +536,7 @@ impl<'tcx> TyCtxt<'tcx> {
492536
span: Span,
493537
method_span: Option<Span>,
494538
) -> bool {
495-
self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
539+
self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No, None)
496540
}
497541

498542
/// Checks if an item is stable or error out.
@@ -513,6 +557,7 @@ impl<'tcx> TyCtxt<'tcx> {
513557
span: Span,
514558
method_span: Option<Span>,
515559
allow_unstable: AllowUnstable,
560+
already_linted_paths: Option<&mut FxHashSet<(HirId, DefId)>>,
516561
) -> bool {
517562
self.check_optional_stability(
518563
def_id,
@@ -525,6 +570,7 @@ impl<'tcx> TyCtxt<'tcx> {
525570
// was referenced.
526571
self.dcx().span_delayed_bug(span, format!("encountered unmarked API: {def_id:?}"));
527572
},
573+
already_linted_paths,
528574
)
529575
}
530576

@@ -542,14 +588,21 @@ impl<'tcx> TyCtxt<'tcx> {
542588
method_span: Option<Span>,
543589
allow_unstable: AllowUnstable,
544590
unmarked: impl FnOnce(Span, DefId),
591+
already_linted_paths: Option<&mut FxHashSet<(HirId, DefId)>>,
545592
) -> bool {
546593
let soft_handler = |lint, span, msg: String| {
547594
self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
548595
lint.primary_message(msg);
549596
})
550597
};
551-
let eval_result =
552-
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
598+
let eval_result = self.eval_stability_allow_unstable(
599+
def_id,
600+
id,
601+
span,
602+
method_span,
603+
allow_unstable,
604+
already_linted_paths,
605+
);
553606
let is_allowed = matches!(eval_result, EvalResult::Allow);
554607
match eval_result {
555608
EvalResult::Allow => {}

compiler/rustc_passes/src/stability.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
use std::num::NonZero;
55

66
use rustc_ast_lowering::stability::extern_abi_stability;
7-
use rustc_data_structures::fx::FxIndexMap;
7+
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
88
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
99
use rustc_feature::{EnabledLangFeature, EnabledLibFeature};
1010
use rustc_hir::attrs::{AttributeKind, DeprecatedSince};
1111
use rustc_hir::def::{DefKind, Res};
12-
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId};
12+
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
1313
use rustc_hir::intravisit::{self, Visitor, VisitorExt};
1414
use rustc_hir::{
15-
self as hir, AmbigArg, ConstStability, DefaultBodyStability, FieldDef, Item, ItemKind,
15+
self as hir, AmbigArg, ConstStability, DefaultBodyStability, FieldDef, HirId, Item, ItemKind,
1616
Stability, StabilityLevel, StableSince, TraitRef, Ty, TyKind, UnstableReason,
1717
VERSION_PLACEHOLDER, Variant, find_attr,
1818
};
@@ -526,7 +526,10 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
526526
/// Cross-references the feature names of unstable APIs with enabled
527527
/// features and possibly prints errors.
528528
fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
529-
tcx.hir_visit_item_likes_in_module(module_def_id, &mut Checker { tcx });
529+
tcx.hir_visit_item_likes_in_module(
530+
module_def_id,
531+
&mut Checker { tcx, already_linted_paths: FxHashSet::default() },
532+
);
530533

531534
let is_staged_api =
532535
tcx.sess.opts.unstable_opts.force_unstable_if_unmarked || tcx.features().staged_api();
@@ -558,6 +561,7 @@ pub(crate) fn provide(providers: &mut Providers) {
558561

559562
struct Checker<'tcx> {
560563
tcx: TyCtxt<'tcx>,
564+
already_linted_paths: FxHashSet<(HirId, DefId)>,
561565
}
562566

563567
impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
@@ -752,6 +756,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
752756
} else {
753757
AllowUnstable::No
754758
},
759+
Some(&mut self.already_linted_paths),
755760
);
756761

757762
if item_is_allowed {
@@ -793,6 +798,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
793798
} else {
794799
AllowUnstable::No
795800
},
801+
Some(&mut self.already_linted_paths),
796802
);
797803
}
798804
Some(deprecation) => {
@@ -808,6 +814,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
808814
} else {
809815
AllowUnstable::No
810816
},
817+
Some(&mut self.already_linted_paths),
811818
);
812819
let is_allowed = matches!(eval_result, EvalResult::Allow);
813820
if !is_allowed {

tests/ui/deprecation/unit_and_tuple_struct.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ pub mod a {
1111

1212
use a::Foo;
1313
//~^ ERROR use of deprecated struct `a::Foo`
14-
//~| ERROR use of deprecated unit struct `a::Foo`
1514
use a::Bar;
1615
//~^ ERROR use of deprecated struct `a::Bar`
17-
//~| ERROR use of deprecated tuple struct `a::Bar`
1816
use a::Baz;
1917
//~^ ERROR use of deprecated struct `a::Baz`
2018

tests/ui/deprecation/unit_and_tuple_struct.stderr

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,47 +10,35 @@ note: the lint level is defined here
1010
LL | #![deny(deprecated)]
1111
| ^^^^^^^^^^
1212

13-
error: use of deprecated unit struct `a::Foo`
14-
--> $DIR/unit_and_tuple_struct.rs:12:8
15-
|
16-
LL | use a::Foo;
17-
| ^^^
18-
1913
error: use of deprecated struct `a::Bar`
20-
--> $DIR/unit_and_tuple_struct.rs:15:8
21-
|
22-
LL | use a::Bar;
23-
| ^^^
24-
25-
error: use of deprecated tuple struct `a::Bar`
26-
--> $DIR/unit_and_tuple_struct.rs:15:8
14+
--> $DIR/unit_and_tuple_struct.rs:14:8
2715
|
2816
LL | use a::Bar;
2917
| ^^^
3018

3119
error: use of deprecated struct `a::Baz`
32-
--> $DIR/unit_and_tuple_struct.rs:18:8
20+
--> $DIR/unit_and_tuple_struct.rs:16:8
3321
|
3422
LL | use a::Baz;
3523
| ^^^
3624

3725
error: use of deprecated unit struct `a::Foo`
38-
--> $DIR/unit_and_tuple_struct.rs:22:6
26+
--> $DIR/unit_and_tuple_struct.rs:20:6
3927
|
4028
LL | a::Foo;
4129
| ^^^
4230

4331
error: use of deprecated tuple struct `a::Bar`
44-
--> $DIR/unit_and_tuple_struct.rs:24:6
32+
--> $DIR/unit_and_tuple_struct.rs:22:6
4533
|
4634
LL | a::Bar();
4735
| ^^^
4836

4937
error: use of deprecated struct `a::Baz`
50-
--> $DIR/unit_and_tuple_struct.rs:26:6
38+
--> $DIR/unit_and_tuple_struct.rs:24:6
5139
|
5240
LL | a::Baz {};
5341
| ^^^
5442

55-
error: aborting due to 8 previous errors
43+
error: aborting due to 6 previous errors
5644

0 commit comments

Comments
 (0)