From 0a6a0e47d2efb207ad0e95c3eb67b543c8cbb2e6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 5 Dec 2024 05:00:01 +0000 Subject: [PATCH] Dont consider fields that are forced unstable due to -Zforce-unstable-if-unmarked to be uninhabited --- .../rustc_middle/src/ty/inhabitedness/mod.rs | 9 ++++++++- compiler/rustc_pattern_analysis/src/rustc.rs | 10 +++++----- tests/ui/uninhabited/uninhabited-pin-field.rs | 10 ++++++++++ .../uninhabited/uninhabited-pin-field.stderr | 19 +++++++++++++++++++ .../uninhabited-unstable-field.current.stderr | 2 +- 5 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 tests/ui/uninhabited/uninhabited-pin-field.rs create mode 100644 tests/ui/uninhabited/uninhabited-pin-field.stderr diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 329c5af4d1b..aec4b29d3fb 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -43,6 +43,7 @@ //! This code should only compile in modules where the uninhabitedness of `Foo` //! is visible. +use rustc_span::sym; use rustc_type_ir::TyKind::*; use tracing::instrument; @@ -90,7 +91,13 @@ impl<'tcx> VariantDef { // `let pred = pred.or(InhabitedPredicate::IsUnstable(field.did));` // but this is unnecessary for now, since it would only affect nightly-only // code or code within the standard library itself. - if tcx.lookup_stability(field.did).is_some_and(|stab| stab.is_unstable()) { + // HACK: We filter out `rustc_private` fields since with the flag + // `-Zforce-unstable-if-unmarked` we consider all unmarked fields to be + // unstable when building the compiler. + if tcx + .lookup_stability(field.did) + .is_some_and(|stab| stab.is_unstable() && stab.feature != sym::rustc_private) + { return InhabitedPredicate::True; } let pred = tcx.type_of(field.did).instantiate_identity().inhabited_predicate(tcx); diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 68d4d083a74..775befde395 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; -use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym}; use crate::constructor::Constructor::*; use crate::constructor::{ @@ -232,10 +232,10 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); let is_uninhabited = cx.is_uninhabited(*ty); - let is_unstable = cx - .tcx - .lookup_stability(field.did) - .is_some_and(|stab| stab.is_unstable()); + let is_unstable = + cx.tcx.lookup_stability(field.did).is_some_and(|stab| { + stab.is_unstable() && stab.feature != sym::rustc_private + }); let skip = is_uninhabited && (!is_visible || is_unstable); (ty, PrivateUninhabitedField(skip)) }); diff --git a/tests/ui/uninhabited/uninhabited-pin-field.rs b/tests/ui/uninhabited/uninhabited-pin-field.rs new file mode 100644 index 00000000000..3d0d9a7a4f8 --- /dev/null +++ b/tests/ui/uninhabited/uninhabited-pin-field.rs @@ -0,0 +1,10 @@ +use std::pin::Pin; + +enum Void {} + +fn demo(x: Pin) { + match x {} + //~^ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/tests/ui/uninhabited/uninhabited-pin-field.stderr b/tests/ui/uninhabited/uninhabited-pin-field.stderr new file mode 100644 index 00000000000..93254ca9b98 --- /dev/null +++ b/tests/ui/uninhabited/uninhabited-pin-field.stderr @@ -0,0 +1,19 @@ +error[E0004]: non-exhaustive patterns: type `Pin` is non-empty + --> $DIR/uninhabited-pin-field.rs:6:11 + | +LL | match x {} + | ^ + | +note: `Pin` defined here + --> $SRC_DIR/core/src/pin.rs:LL:COL + = note: the matched value is of type `Pin` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match x { +LL + _ => todo!(), +LL ~ } + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/uninhabited/uninhabited-unstable-field.current.stderr b/tests/ui/uninhabited/uninhabited-unstable-field.current.stderr index de9c2a6fcf7..9e0feb4c473 100644 --- a/tests/ui/uninhabited/uninhabited-unstable-field.current.stderr +++ b/tests/ui/uninhabited/uninhabited-unstable-field.current.stderr @@ -14,7 +14,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match x { LL + _ => todo!(), -LL + } +LL ~ } | error: aborting due to 1 previous error