about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDing Xiang Fei <dingxiangfei2009@protonmail.ch>2025-01-29 06:15:56 +0800
committerDing Xiang Fei <dingxiangfei2009@protonmail.ch>2025-02-09 20:40:42 +0800
commitc0673246371b1a5ecac940f1ea6418857f932d7c (patch)
tree67469e07d6909259ef45948d51ac2c312ba2bb17
parentde405dcb8fbcd0add1e60c75800dac9b8fbe4884 (diff)
downloadrust-c0673246371b1a5ecac940f1ea6418857f932d7c.tar.gz
rust-c0673246371b1a5ecac940f1ea6418857f932d7c.zip
rename the trait to validity and place a feature gate afront
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs4
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs7
-rw-r--r--compiler/rustc_span/src/symbol.rs4
-rw-r--r--library/core/src/marker.rs17
-rw-r--r--tests/ui/deriving/built-in-proc-macro-scope.stdout2
-rw-r--r--tests/ui/deriving/deriving-coerce-pointee-expanded.stdout6
-rw-r--r--tests/ui/deriving/deriving-coerce-pointee-neg.stderr7
10 files changed, 43 insertions, 26 deletions
diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
index 7e30cf327fc..e228095c97f 100644
--- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
@@ -110,10 +110,10 @@ pub(crate) fn expand_deriving_coerce_pointee(
     // Declare helper function that adds implementation blocks.
     // FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls
     let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),];
-    // # Wellformed-ness assertion
+    // # Validity assertion which will be checked later in `rustc_hir_analysis::coherence::builtins`.
     {
         let trait_path =
-            cx.path_all(span, true, path!(span, core::marker::CoercePointeeWellformed), vec![]);
+            cx.path_all(span, true, path!(span, core::marker::CoercePointeeValidated), vec![]);
         let trait_ref = cx.trait_ref(trait_path);
         push(Annotatable::Item(
             cx.item(
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index b18e96646b1..1852987b167 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -370,7 +370,7 @@ language_item_table! {
 
     PointerLike,             sym::pointer_like,        pointer_like,               Target::Trait,          GenericRequirement::Exact(0);
 
-    CoercePointeeWellformed, sym::coerce_pointee_wellformed, coerce_pointee_wellformed_trait, Target::Trait,     GenericRequirement::Exact(0);
+    CoercePointeeValidated, sym::coerce_pointee_validated, coerce_pointee_validated_trait, Target::Trait,     GenericRequirement::Exact(0);
 
     ConstParamTy,            sym::const_param_ty,      const_param_ty_trait,       Target::Trait,          GenericRequirement::Exact(0);
     UnsizedConstParamTy,     sym::unsized_const_param_ty, unsized_const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 2417ff3bb1a..9c38193c84e 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_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`
 
 hir_analysis_coerce_pointee_not_struct = `derive(CoercePointee)` is only applicable to `struct`, instead of `{$kind}`
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index a872bb72bef..c21576a5e7c 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -49,8 +49,8 @@ pub(super) fn check_trait<'tcx>(
         .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn)?;
     checker.check(lang_items.pointer_like(), visit_implementation_of_pointer_like)?;
     checker.check(
-        lang_items.coerce_pointee_wellformed_trait(),
-        visit_implementation_of_coerce_pointee_wellformed,
+        lang_items.coerce_pointee_validated_trait(),
+        visit_implementation_of_coerce_pointee_validity,
     )?;
     Ok(())
 }
@@ -787,19 +787,21 @@ fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), Err
         .emit())
 }
 
-fn visit_implementation_of_coerce_pointee_wellformed(
+fn visit_implementation_of_coerce_pointee_validity(
     checker: &Checker<'_>,
 ) -> Result<(), ErrorGuaranteed> {
     let tcx = checker.tcx;
     let self_ty = tcx.impl_trait_ref(checker.impl_def_id).unwrap().instantiate_identity().self_ty();
+    let span = tcx.def_span(checker.impl_def_id);
+    if !tcx.is_builtin_derived(checker.impl_def_id.into()) {
+        return Err(tcx.dcx().emit_err(errors::CoercePointeeNoUserValidityAssertion { span }));
+    }
     let ty::Adt(def, _args) = self_ty.kind() else {
-        return Err(tcx.dcx().emit_err(errors::CoercePointeeNotConcreteType {
-            span: tcx.def_span(checker.impl_def_id),
-        }));
+        return Err(tcx.dcx().emit_err(errors::CoercePointeeNotConcreteType { span }));
     };
     let did = def.did();
-    let span =
-        if let Some(local) = did.as_local() { tcx.source_span(local) } else { tcx.def_span(did) };
+    // Now get a more precise span of the `struct`.
+    let span = tcx.def_span(did);
     if !def.is_struct() {
         return Err(tcx
             .dcx()
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index a921022a112..c49e06d7448 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1196,6 +1196,13 @@ pub(crate) struct CoercePointeeNotConcreteType {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_pointee_no_user_validity_assertion, code = E0802)]
+pub(crate) struct CoercePointeeNoUserValidityAssertion {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_pointee_not_transparent, code = E0802)]
 pub(crate) struct CoercePointeeNotTransparent {
     #[primary_span]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 096a438906c..16015776697 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -193,7 +193,7 @@ symbols! {
         Cleanup,
         Clone,
         CoercePointee,
-        CoercePointeeWellformed,
+        CoercePointeeValidated,
         CoerceUnsized,
         Command,
         ConstParamTy,
@@ -620,7 +620,7 @@ symbols! {
         cmp_partialord_lt,
         cmpxchg16b_target_feature,
         cmse_nonsecure_entry,
-        coerce_pointee_wellformed,
+        coerce_pointee_validated,
         coerce_unsized,
         cold,
         cold_path,
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 62f569d37df..163c80ffe1d 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -1284,14 +1284,23 @@ pub trait FnPtr: Copy + Clone {
 /// }
 /// ```
 #[rustc_builtin_macro(CoercePointee, attributes(pointee))]
-#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize)]
+#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)]
 #[unstable(feature = "derive_coerce_pointee", issue = "123430")]
 pub macro CoercePointee($item:item) {
     /* compiler built-in */
 }
 
+/// A validation trait that is implemented on data with `derive(CoercePointee)`
+/// so that the compiler can enforce a set of rules that the target data must
+/// conform to in order for the derived behaviours are safe and useful for
+/// the purpose of the said macro.
+///
+/// This trait will not ever be exposed for use as public part of the library
+/// and shall not ever be stabilised.
 #[cfg(not(bootstrap))]
-#[lang = "coerce_pointee_wellformed"]
-#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
+#[lang = "coerce_pointee_validated"]
+#[unstable(feature = "coerce_pointee_validated", issue = "123430")]
 #[doc(hidden)]
-pub trait CoercePointeeWellformed {}
+pub trait CoercePointeeValidated {
+    /* compiler built-in */
+}
diff --git a/tests/ui/deriving/built-in-proc-macro-scope.stdout b/tests/ui/deriving/built-in-proc-macro-scope.stdout
index aa989ed2317..fa4e50968f4 100644
--- a/tests/ui/deriving/built-in-proc-macro-scope.stdout
+++ b/tests/ui/deriving/built-in-proc-macro-scope.stdout
@@ -20,7 +20,7 @@ pub struct Ptr<'a, #[pointee] T: ?Sized> {
     data: &'a mut T,
 }
 #[automatically_derived]
-impl<'a, T: ?Sized> ::core::marker::CoercePointeeWellformed for Ptr<'a, T> { }
+impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for Ptr<'a, T> { }
 #[automatically_derived]
 impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
     ::core::ops::DispatchFromDyn<Ptr<'a, __S>> for Ptr<'a, T> {
diff --git a/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout b/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout
index ea5ee60a0bb..a774efbbe35 100644
--- a/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout
+++ b/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout
@@ -16,7 +16,7 @@ struct MyPointer<'a, #[pointee] T: ?Sized> {
     ptr: &'a T,
 }
 #[automatically_derived]
-impl<'a, T: ?Sized> ::core::marker::CoercePointeeWellformed for
+impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for
     MyPointer<'a, T> {
 }
 #[automatically_derived]
@@ -36,7 +36,7 @@ pub struct MyPointer2<'a, Y, Z: MyTrait<T>, #[pointee] T: ?Sized + MyTrait<T>,
 }
 #[automatically_derived]
 impl<'a, Y, Z: MyTrait<T>, T: ?Sized + MyTrait<T>, X: MyTrait<T>>
-    ::core::marker::CoercePointeeWellformed for MyPointer2<'a, Y, Z, T, X>
+    ::core::marker::CoercePointeeValidated for MyPointer2<'a, Y, Z, T, X>
     where Y: MyTrait<T> {
 }
 #[automatically_derived]
@@ -57,7 +57,7 @@ struct MyPointerWithoutPointee<'a, T: ?Sized> {
     ptr: &'a T,
 }
 #[automatically_derived]
-impl<'a, T: ?Sized> ::core::marker::CoercePointeeWellformed for
+impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for
     MyPointerWithoutPointee<'a, T> {
 }
 #[automatically_derived]
diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr
index 2400a48456f..9e4d3657224 100644
--- a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr
+++ b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr
@@ -117,11 +117,8 @@ LL | struct NoFieldUnit<'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> {
-LL | |
-LL | |     ptr: &'a T,
-LL | | }
-   | |_^
+LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 17 previous errors