rename the trait to validity and place a feature gate afront
This commit is contained in:
parent
de405dcb8f
commit
c067324637
10 changed files with 43 additions and 26 deletions
|
@ -110,10 +110,10 @@ pub(crate) fn expand_deriving_coerce_pointee(
|
||||||
// Declare helper function that adds implementation blocks.
|
// Declare helper function that adds implementation blocks.
|
||||||
// FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls
|
// 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),];
|
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 =
|
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);
|
let trait_ref = cx.trait_ref(trait_path);
|
||||||
push(Annotatable::Item(
|
push(Annotatable::Item(
|
||||||
cx.item(
|
cx.item(
|
||||||
|
|
|
@ -370,7 +370,7 @@ language_item_table! {
|
||||||
|
|
||||||
PointerLike, sym::pointer_like, pointer_like, Target::Trait, GenericRequirement::Exact(0);
|
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);
|
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);
|
UnsizedConstParamTy, sym::unsized_const_param_ty, unsized_const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||||
|
|
|
@ -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
|
.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
|
.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_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}`
|
hir_analysis_coerce_pointee_not_struct = `derive(CoercePointee)` is only applicable to `struct`, instead of `{$kind}`
|
||||||
|
|
|
@ -49,8 +49,8 @@ pub(super) fn check_trait<'tcx>(
|
||||||
.check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn)?;
|
.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.pointer_like(), visit_implementation_of_pointer_like)?;
|
||||||
checker.check(
|
checker.check(
|
||||||
lang_items.coerce_pointee_wellformed_trait(),
|
lang_items.coerce_pointee_validated_trait(),
|
||||||
visit_implementation_of_coerce_pointee_wellformed,
|
visit_implementation_of_coerce_pointee_validity,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -787,19 +787,21 @@ fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), Err
|
||||||
.emit())
|
.emit())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_implementation_of_coerce_pointee_wellformed(
|
fn visit_implementation_of_coerce_pointee_validity(
|
||||||
checker: &Checker<'_>,
|
checker: &Checker<'_>,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let tcx = checker.tcx;
|
let tcx = checker.tcx;
|
||||||
let self_ty = tcx.impl_trait_ref(checker.impl_def_id).unwrap().instantiate_identity().self_ty();
|
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 {
|
let ty::Adt(def, _args) = self_ty.kind() else {
|
||||||
return Err(tcx.dcx().emit_err(errors::CoercePointeeNotConcreteType {
|
return Err(tcx.dcx().emit_err(errors::CoercePointeeNotConcreteType { span }));
|
||||||
span: tcx.def_span(checker.impl_def_id),
|
|
||||||
}));
|
|
||||||
};
|
};
|
||||||
let did = def.did();
|
let did = def.did();
|
||||||
let span =
|
// Now get a more precise span of the `struct`.
|
||||||
if let Some(local) = did.as_local() { tcx.source_span(local) } else { tcx.def_span(did) };
|
let span = tcx.def_span(did);
|
||||||
if !def.is_struct() {
|
if !def.is_struct() {
|
||||||
return Err(tcx
|
return Err(tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
|
|
|
@ -1195,6 +1195,13 @@ pub(crate) struct CoercePointeeNotConcreteType {
|
||||||
pub span: Span,
|
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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_coerce_pointee_not_transparent, code = E0802)]
|
#[diag(hir_analysis_coerce_pointee_not_transparent, code = E0802)]
|
||||||
pub(crate) struct CoercePointeeNotTransparent {
|
pub(crate) struct CoercePointeeNotTransparent {
|
||||||
|
|
|
@ -193,7 +193,7 @@ symbols! {
|
||||||
Cleanup,
|
Cleanup,
|
||||||
Clone,
|
Clone,
|
||||||
CoercePointee,
|
CoercePointee,
|
||||||
CoercePointeeWellformed,
|
CoercePointeeValidated,
|
||||||
CoerceUnsized,
|
CoerceUnsized,
|
||||||
Command,
|
Command,
|
||||||
ConstParamTy,
|
ConstParamTy,
|
||||||
|
@ -620,7 +620,7 @@ symbols! {
|
||||||
cmp_partialord_lt,
|
cmp_partialord_lt,
|
||||||
cmpxchg16b_target_feature,
|
cmpxchg16b_target_feature,
|
||||||
cmse_nonsecure_entry,
|
cmse_nonsecure_entry,
|
||||||
coerce_pointee_wellformed,
|
coerce_pointee_validated,
|
||||||
coerce_unsized,
|
coerce_unsized,
|
||||||
cold,
|
cold,
|
||||||
cold_path,
|
cold_path,
|
||||||
|
|
|
@ -1284,14 +1284,23 @@ pub trait FnPtr: Copy + Clone {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[rustc_builtin_macro(CoercePointee, attributes(pointee))]
|
#[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")]
|
#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
|
||||||
pub macro CoercePointee($item:item) {
|
pub macro CoercePointee($item:item) {
|
||||||
/* compiler built-in */
|
/* 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))]
|
#[cfg(not(bootstrap))]
|
||||||
#[lang = "coerce_pointee_wellformed"]
|
#[lang = "coerce_pointee_validated"]
|
||||||
#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
|
#[unstable(feature = "coerce_pointee_validated", issue = "123430")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait CoercePointeeWellformed {}
|
pub trait CoercePointeeValidated {
|
||||||
|
/* compiler built-in */
|
||||||
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub struct Ptr<'a, #[pointee] T: ?Sized> {
|
||||||
data: &'a mut T,
|
data: &'a mut T,
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[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]
|
#[automatically_derived]
|
||||||
impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
|
impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
|
||||||
::core::ops::DispatchFromDyn<Ptr<'a, __S>> for Ptr<'a, T> {
|
::core::ops::DispatchFromDyn<Ptr<'a, __S>> for Ptr<'a, T> {
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct MyPointer<'a, #[pointee] T: ?Sized> {
|
||||||
ptr: &'a T,
|
ptr: &'a T,
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl<'a, T: ?Sized> ::core::marker::CoercePointeeWellformed for
|
impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for
|
||||||
MyPointer<'a, T> {
|
MyPointer<'a, T> {
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
|
@ -36,7 +36,7 @@ pub struct MyPointer2<'a, Y, Z: MyTrait<T>, #[pointee] T: ?Sized + MyTrait<T>,
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl<'a, Y, Z: MyTrait<T>, T: ?Sized + MyTrait<T>, X: MyTrait<T>>
|
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> {
|
where Y: MyTrait<T> {
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
|
@ -57,7 +57,7 @@ struct MyPointerWithoutPointee<'a, T: ?Sized> {
|
||||||
ptr: &'a T,
|
ptr: &'a T,
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl<'a, T: ?Sized> ::core::marker::CoercePointeeWellformed for
|
impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for
|
||||||
MyPointerWithoutPointee<'a, T> {
|
MyPointerWithoutPointee<'a, T> {
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
|
|
|
@ -117,11 +117,8 @@ LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
|
||||||
error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
|
error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
|
||||||
--> $DIR/deriving-coerce-pointee-neg.rs:140:1
|
--> $DIR/deriving-coerce-pointee-neg.rs:140:1
|
||||||
|
|
|
|
||||||
LL | / struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
||||||
LL | |
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
LL | | ptr: &'a T,
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
error: aborting due to 17 previous errors
|
error: aborting due to 17 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue