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 -