8000 Introduce CoercePointeeValidated for coherence checks at typeck stage by dingxiangfei2009 · Pull Request #136107 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Introduce CoercePointeeValidated for coherence checks at typeck stage #136107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rename the trait to validity and place a feature gate afront
  • Loading branch information
dingxiangfei2009 committed Feb 9, 2025
commit c0673246371b1a5ecac940f1ea6418857f932d7c
4 changes: 2 additions & 2 deletions compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand Down Expand Up @@ -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()
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,13 @@ pub(crate) struct CoercePointeeNotConcreteType {
pub span: Span,
}

#[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 {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ symbols! {
Cleanup,
Clone,
CoercePointee,
CoercePointeeWellformed,
CoercePointeeValidated,
CoerceUnsized,
Command,
ConstParamTy,
Expand Down Expand Up @@ -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,
Expand Down
17 changes: 13 additions & 4 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't need a tracking issue since it's never going to be stabilized. Just put issue = "none" I think.

#[doc(hidden)]
pub trait CoercePointeeWellformed {}
pub trait CoercePointeeValidated {
/* compiler built-in */
}
2 changes: 1 addition & 1 deletion tests/ui/deriving/built-in-proc-macro-scope.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/deriving/deriving-coerce-pointee-expanded.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand Down
7 changes: 2 additions & 5 deletions tests/ui/deriving/deriving-coerce-pointee-neg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
0