about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDing Xiang Fei <dingxiangfei2009@protonmail.ch>2025-01-29 06:48:28 +0800
committerDing Xiang Fei <dingxiangfei2009@protonmail.ch>2025-02-09 20:40:43 +0800
commitb9435056a7e152e1d455b404061240b964a39584 (patch)
tree30ec9211977f60915dca62454c6132fa8c3ee177
parentc0673246371b1a5ecac940f1ea6418857f932d7c (diff)
downloadrust-b9435056a7e152e1d455b404061240b964a39584.tar.gz
rust-b9435056a7e152e1d455b404061240b964a39584.zip
move repr(transparent) checks to coherence
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs10
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs7
-rw-r--r--tests/ui/deriving/deriving-coerce-pointee-neg.rs2
-rw-r--r--tests/ui/deriving/deriving-coerce-pointee-neg.stderr14
6 files changed, 19 insertions, 19 deletions
diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
index e228095c97f..5aed9f76f14 100644
--- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
@@ -6,7 +6,6 @@ use rustc_ast::{
     self as ast, GenericArg, GenericBound, GenericParamKind, Generics, ItemKind, MetaItem,
     TraitBoundModifiers, VariantData, WherePredicate,
 };
-use rustc_attr_parsing as attr;
 use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_errors::E0802;
 use rustc_expand::base::{Annotatable, ExtCtxt};
@@ -33,15 +32,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
     let (name_ident, generics) = if let Annotatable::Item(aitem) = item
         && let ItemKind::Struct(struct_data, g) = &aitem.kind
     {
-        let is_transparent = aitem.attrs.iter().any(|attr| {
-            attr::find_repr_attrs(cx.sess, attr)
-                .into_iter()
-                .any(|r| matches!(r, attr::ReprTransparent))
-        });
-        if !is_transparent {
-            cx.dcx().emit_err(RequireTransparent { span });
-            return;
-        }
         if !matches!(
             struct_data,
             VariantData::Struct { fields, recovered: _ } | VariantData::Tuple(fields, _)
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 9c38193c84e..258267c5ca9 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -85,6 +85,8 @@ hir_analysis_cmse_output_stack_spill =
     .note1 = functions with the `"{$abi_name}"` ABI must pass their result via the available return registers
     .note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
 
+hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
+
 hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden
 
 hir_analysis_coerce_pointee_not_concrete_ty = `derive(CoercePointee)` is only applicable to `struct`
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index c21576a5e7c..c5aee60117b 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -810,5 +810,8 @@ fn visit_implementation_of_coerce_pointee_validity(
     if !def.repr().transparent() {
         return Err(tcx.dcx().emit_err(errors::CoercePointeeNotTransparent { span }));
     }
+    if def.all_fields().next().is_none() {
+        return Err(tcx.dcx().emit_err(errors::CoercePointeeNoField { span }));
+    }
     Ok(())
 }
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index c49e06d7448..12750543f4b 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1210,6 +1210,13 @@ pub(crate) struct CoercePointeeNotTransparent {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_pointee_no_field, code = E0802)]
+pub(crate) struct CoercePointeeNoField {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_ty_outside_relevant, code = E0390)]
 #[help]
 pub(crate) struct InherentTyOutsideRelevant {
diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.rs b/tests/ui/deriving/deriving-coerce-pointee-neg.rs
index 0a23538cd4a..6577500d8eb 100644
--- a/tests/ui/deriving/deriving-coerce-pointee-neg.rs
+++ b/tests/ui/deriving/deriving-coerce-pointee-neg.rs
@@ -44,8 +44,8 @@ struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &
 //~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
 
 #[derive(CoercePointee)]
-//~^ ERROR: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
 struct NotTransparent<'a, #[pointee] T: ?Sized> {
+    //~^ ERROR: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
     ptr: &'a T,
 }
 
diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr
index 9e4d3657224..999214bfa9f 100644
--- a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr
+++ b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr
@@ -44,14 +44,6 @@ error[E0802]: only one type parameter can be marked as `#[pointee]` when derivin
 LL | struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
    |                                       ^                     - here another type parameter is marked as `#[pointee]`
 
-error[E0802]: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
-  --> $DIR/deriving-coerce-pointee-neg.rs:46:10
-   |
-LL | #[derive(CoercePointee)]
-   |          ^^^^^^^^^^^^^
-   |
-   = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error[E0802]: `derive(CoercePointee)` requires `T` to be marked `?Sized`
   --> $DIR/deriving-coerce-pointee-neg.rs:54:36
    |
@@ -115,6 +107,12 @@ LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
 
 error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
+  --> $DIR/deriving-coerce-pointee-neg.rs:47:1
+   |
+LL | struct NotTransparent<'a, #[pointee] T: ?Sized> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
   --> $DIR/deriving-coerce-pointee-neg.rs:140:1
    |
 LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {