about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2023-09-19 11:35:51 +0200
committerGitHub <noreply@github.com>2023-09-19 11:35:51 +0200
commitf1edecfaab9e0490e21bae162faade9df686901d (patch)
treebe32689f5a61f19899654082e1e4765dbc8671e9 /compiler
parent6cfc6a8705e42bb882b6493eacb6d02bc141b590 (diff)
parentfd36553aa7b23455ac8431293fbdb0d6b760161c (diff)
downloadrust-f1edecfaab9e0490e21bae162faade9df686901d.tar.gz
rust-f1edecfaab9e0490e21bae162faade9df686901d.zip
Rollup merge of #115924 - compiler-errors:non-exhaustive-1-zst, r=RalfJung
Don't complain on a single non-exhaustive 1-ZST

r? RalfJung, though you mentioned being busy, so feel free to reassign.

This doesn't actually attempt to make the diagnostic better, so when we have two non-exhaustive 1-ZSTs in a struct, we still just point to one. 🤷

Fixes #115922
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs48
1 files changed, 29 insertions, 19 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 1d381175c75..13826264a22 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1201,25 +1201,35 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
         );
         return;
     }
-    for (span, _trivial, non_exhaustive) in field_infos {
-        if let Some((descr, def_id, args, non_exhaustive)) = non_exhaustive {
-            tcx.struct_span_lint_hir(
-                REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
-                tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()),
-                span,
-                "zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types",
-                |lint| {
-                    let note = if non_exhaustive {
-                        "is marked with `#[non_exhaustive]`"
-                    } else {
-                        "contains private fields"
-                    };
-                    let field_ty = tcx.def_path_str_with_args(def_id, args);
-                    lint
-                        .note(format!("this {descr} contains `{field_ty}`, which {note}, \
-                            and makes it not a breaking change to become non-zero-sized in the future."))
-                },
-            )
+    let mut prev_non_exhaustive_1zst = false;
+    for (span, _trivial, non_exhaustive_1zst) in field_infos {
+        if let Some((descr, def_id, args, non_exhaustive)) = non_exhaustive_1zst {
+            // If there are any non-trivial fields, then there can be no non-exhaustive 1-zsts.
+            // Otherwise, it's only an issue if there's >1 non-exhaustive 1-zst.
+            if non_trivial_count > 0 || prev_non_exhaustive_1zst {
+                tcx.struct_span_lint_hir(
+                    REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
+                    tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()),
+                    span,
+                    "zero-sized fields in `repr(transparent)` cannot \
+                    contain external non-exhaustive types",
+                    |lint| {
+                        let note = if non_exhaustive {
+                            "is marked with `#[non_exhaustive]`"
+                        } else {
+                            "contains private fields"
+                        };
+                        let field_ty = tcx.def_path_str_with_args(def_id, args);
+                        lint.note(format!(
+                            "this {descr} contains `{field_ty}`, which {note}, \
+                                and makes it not a breaking change to become \
+                                non-zero-sized in the future."
+                        ))
+                    },
+                )
+            } else {
+                prev_non_exhaustive_1zst = true;
+            }
         }
     }
 }