diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 1aaf02646c794..9aaf34a0fd1c6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2331,7 +2331,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys); - } else if adt_kind != AdtKind::Union && !remaining_fields.is_empty() { + } else if adt_kind != AdtKind::Union + && !remaining_fields.is_empty() + //~ non_exhaustive already reported, which will only happen for extern modules + && !variant.field_list_has_applicable_non_exhaustive() + { debug!(?remaining_fields); let private_fields: Vec<&ty::FieldDef> = variant .fields diff --git a/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs b/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs new file mode 100644 index 0000000000000..18e63db0cdd11 --- /dev/null +++ b/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs @@ -0,0 +1,13 @@ +// Auxiliary crate for testing non-exhaustive struct with private fields + +#[non_exhaustive] +pub struct Foo { + pub my_field: u32, + private_field: i32, +} + +#[non_exhaustive] +pub struct Bar { + pub my_field: u32, + pub missing_field: i32, +} diff --git a/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs new file mode 100644 index 0000000000000..0553ff6c781e9 --- /dev/null +++ b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs @@ -0,0 +1,17 @@ +//@ aux-build:non_exhaustive_with_private.rs + +extern crate non_exhaustive_with_private; + +use non_exhaustive_with_private::{Bar, Foo}; + +fn main() { + let foo = Foo { + //~^ ERROR cannot create non-exhaustive struct using struct expression + my_field: 10, + }; + + let bar = Bar { + //~^ ERROR cannot create non-exhaustive struct using struct expression + my_field: 10, + }; +} diff --git a/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr new file mode 100644 index 0000000000000..85bf7e4847d73 --- /dev/null +++ b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr @@ -0,0 +1,23 @@ +error[E0639]: cannot create non-exhaustive struct using struct expression + --> $DIR/non-exhaustive-with-private-fields-147513.rs:8:15 + | +LL | let foo = Foo { + | _______________^ +LL | | +LL | | my_field: 10, +LL | | }; + | |_____^ + +error[E0639]: cannot create non-exhaustive struct using struct expression + --> $DIR/non-exhaustive-with-private-fields-147513.rs:13:15 + | +LL | let bar = Bar { + | _______________^ +LL | | +LL | | my_field: 10, +LL | | }; + | |_____^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0639`.