From 9773b01c186fc5d57c6566a576d1898504d485dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 20 Jan 2020 12:05:06 -0800 Subject: [PATCH] When an ADT field is missing a stability attribute, look at its parent This will allow us to remove stability attributes in fields in the stdlib which are shown in user visible output unnecessarily, obscuring the meaning of the span. --- src/librustc_passes/stability.rs | 22 ++++++++++++++++++- .../stability-attribute-issue-43027.rs | 3 ++- .../stability-attribute-issue-43027.stderr | 8 ------- 3 files changed, 23 insertions(+), 10 deletions(-) delete mode 100644 src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index b649f36f2fc58..d96a23d84191c 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -286,7 +286,27 @@ struct MissingStabilityAnnotations<'a, 'tcx> { impl<'a, 'tcx> MissingStabilityAnnotations<'a, 'tcx> { fn check_missing_stability(&self, hir_id: HirId, span: Span, name: &str) { - let stab = self.tcx.stability().local_stability(hir_id); + let stability = self.tcx.stability(); + // Get the stability attribute of the current node, if it has none and it is part of an + // ADT, climb up until the item's def to get the whole's ADT's stability if present. + let stab = stability.local_stability(hir_id).or_else(|| { + let parent_id = self.tcx.hir().get_parent_node(hir_id); + let node = self.tcx.hir().find(parent_id); + match node { + // For enum/union variants we check first the variant's stability and if none, we + // check the whole ADT. + Some(hir::Node::Variant(_)) => stability.local_stability(parent_id).or_else(|| { + let parent_id = self.tcx.hir().get_parent_node(hir_id); + stability.local_stability(parent_id) + }), + Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Struct(..), .. })) + | Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(..), .. })) + | Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Union(..), .. })) => { + stability.local_stability(parent_id) + } + _ => None, + } + }); let is_error = !self.tcx.sess.opts.test && stab.is_none() && self.access_levels.is_reachable(hir_id); if is_error { diff --git a/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs b/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs index 0b243bb52119b..0187a181b84f9 100644 --- a/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs +++ b/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs @@ -1,8 +1,9 @@ +// check-pass #![feature(staged_api)] #![stable(feature = "test", since = "0")] #[stable(feature = "test", since = "0")] -pub struct Reverse(pub T); //~ ERROR field has missing stability attribute +pub struct Reverse(pub T); // if the field has no stability, we check its parent fn main() { // Make sure the field is used to fill the stability cache diff --git a/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr b/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr deleted file mode 100644 index 280c72acccb18..0000000000000 --- a/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: field has missing stability attribute - --> $DIR/stability-attribute-issue-43027.rs:5:23 - | -LL | pub struct Reverse(pub T); - | ^^^^^ - -error: aborting due to previous error -