From fd36553aa7b23455ac8431293fbdb0d6b760161c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 18 Sep 2023 06:59:11 +0000 Subject: Don't complain on a single non-exhaustive 1-zst --- compiler/rustc_hir_analysis/src/check/check.rs | 48 ++++++++++++++++---------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'compiler') 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; + } } } } -- cgit 1.4.1-3-g733a5