introduce CoercePointeeWellformed for coherence checks at typeck stage
This commit is contained in:
parent
43ca9d18e3
commit
de405dcb8f
15 changed files with 337 additions and 36 deletions
|
@ -3,11 +3,12 @@ use ast::ptr::P;
|
|||
use rustc_ast::mut_visit::MutVisitor;
|
||||
use rustc_ast::visit::BoundKind;
|
||||
use rustc_ast::{
|
||||
self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem,
|
||||
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};
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_span::{Ident, Span, Symbol, sym};
|
||||
|
@ -88,8 +89,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
|
|||
} else {
|
||||
let mut pointees = type_params
|
||||
.iter()
|
||||
.filter_map(|&(idx, span, is_pointee)| is_pointee.then_some((idx, span)))
|
||||
.fuse();
|
||||
.filter_map(|&(idx, span, is_pointee)| is_pointee.then_some((idx, span)));
|
||||
match (pointees.next(), pointees.next()) {
|
||||
(Some((idx, _span)), None) => idx,
|
||||
(None, _) => {
|
||||
|
@ -110,6 +110,52 @@ 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
|
||||
{
|
||||
let trait_path =
|
||||
cx.path_all(span, true, path!(span, core::marker::CoercePointeeWellformed), vec![]);
|
||||
let trait_ref = cx.trait_ref(trait_path);
|
||||
push(Annotatable::Item(
|
||||
cx.item(
|
||||
span,
|
||||
Ident::empty(),
|
||||
attrs.clone(),
|
||||
ast::ItemKind::Impl(Box::new(ast::Impl {
|
||||
safety: ast::Safety::Default,
|
||||
polarity: ast::ImplPolarity::Positive,
|
||||
defaultness: ast::Defaultness::Final,
|
||||
constness: ast::Const::No,
|
||||
generics: Generics {
|
||||
params: generics
|
||||
.params
|
||||
.iter()
|
||||
.map(|p| match &p.kind {
|
||||
GenericParamKind::Lifetime => {
|
||||
cx.lifetime_param(p.span(), p.ident, p.bounds.clone())
|
||||
}
|
||||
GenericParamKind::Type { default: _ } => {
|
||||
cx.typaram(p.span(), p.ident, p.bounds.clone(), None)
|
||||
}
|
||||
GenericParamKind::Const { ty, kw_span: _, default: _ } => cx
|
||||
.const_param(
|
||||
p.span(),
|
||||
p.ident,
|
||||
p.bounds.clone(),
|
||||
ty.clone(),
|
||||
None,
|
||||
),
|
||||
})
|
||||
.collect(),
|
||||
where_clause: generics.where_clause.clone(),
|
||||
span: generics.span,
|
||||
},
|
||||
of_trait: Some(trait_ref),
|
||||
self_ty: self_type.clone(),
|
||||
items: ThinVec::new(),
|
||||
})),
|
||||
),
|
||||
));
|
||||
}
|
||||
let mut add_impl_block = |generics, trait_symbol, trait_args| {
|
||||
let mut parts = path!(span, core::ops);
|
||||
parts.push(Ident::new(trait_symbol, span));
|
||||
|
@ -430,35 +476,35 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for AlwaysErrorOnGenericParam<'a, 'b>
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_transparent)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_transparent, code = E0802)]
|
||||
struct RequireTransparent {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_one_field)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_one_field, code = E0802)]
|
||||
struct RequireOneField {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_one_generic)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_one_generic, code = E0802)]
|
||||
struct RequireOneGeneric {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_one_pointee)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_one_pointee, code = E0802)]
|
||||
struct RequireOnePointee {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_coerce_pointee_too_many_pointees)]
|
||||
#[diag(builtin_macros_coerce_pointee_too_many_pointees, code = E0802)]
|
||||
struct TooManyPointees {
|
||||
#[primary_span]
|
||||
one: Span,
|
||||
|
@ -467,7 +513,7 @@ struct TooManyPointees {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_maybe_sized)]
|
||||
#[diag(builtin_macros_coerce_pointee_requires_maybe_sized, code = E0802)]
|
||||
struct RequiresMaybeSized {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
|
|
80
compiler/rustc_error_codes/src/error_codes/E0802.md
Normal file
80
compiler/rustc_error_codes/src/error_codes/E0802.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
The target of `derive(CoercePointee)` macro has inadmissible specification for
|
||||
a meaningful use.
|
||||
|
||||
Erroneous code examples:
|
||||
|
||||
The target data is not a `struct`.
|
||||
|
||||
```compile_fail,E0802
|
||||
#[derive(CoercePointee)]
|
||||
enum NotStruct<'a, T: ?Sized> {
|
||||
Variant(&'a T),
|
||||
}
|
||||
```
|
||||
|
||||
The target data has a layout that is not transparent, or `repr(transparent)`
|
||||
in other words.
|
||||
|
||||
```compile_fail,E0802
|
||||
#[derive(CoercePointee)]
|
||||
struct NotTransparent<'a, #[pointee] T: ?Sized> {
|
||||
ptr: &'a T,
|
||||
}
|
||||
```
|
||||
|
||||
The target data has no data field.
|
||||
|
||||
```compile_fail,E0802
|
||||
#[derive(CoercePointee)]
|
||||
#[repr(transparent)]
|
||||
struct NoField<'a, #[pointee] T: ?Sized> {}
|
||||
```
|
||||
|
||||
The target data is not generic over any data, or has no generic type parameter.
|
||||
|
||||
```compile_fail,E0802
|
||||
#[derive(CoercePointee)]
|
||||
#[repr(transparent)]
|
||||
struct NoGeneric<'a>(&'a u8);
|
||||
```
|
||||
|
||||
The target data has multiple generic type parameters, but none is designated as
|
||||
a pointee for coercion.
|
||||
|
||||
```compile_fail,E0802
|
||||
#[derive(CoercePointee)]
|
||||
#[repr(transparent)]
|
||||
struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
|
||||
a: (&'a T1, &'a T2),
|
||||
}
|
||||
```
|
||||
|
||||
The target data has multiple generic type parameters that are designated as
|
||||
pointees for coercion.
|
||||
|
||||
```compile_fail,E0802
|
||||
#[derive(CoercePointee)]
|
||||
#[repr(transparent)]
|
||||
struct TooManyPointees<
|
||||
'a,
|
||||
#[pointee] A: ?Sized,
|
||||
#[pointee] B: ?Sized>
|
||||
((&'a A, &'a B));
|
||||
```
|
||||
|
||||
The type parameter that is designated as a pointee is not marked `?Sized`.
|
||||
|
||||
```compile_fail,E0802
|
||||
#[derive(CoercePointee)]
|
||||
#[repr(transparent)]
|
||||
struct NoMaybeSized<'a, #[pointee] T> {
|
||||
ptr: &'a T,
|
||||
}
|
||||
```
|
||||
|
||||
In summary, the `CoercePointee` macro demands the type to be a `struct` that is
|
||||
generic over at least one type or over more types, one of which is marked with
|
||||
`#[pointee]`, and has at least one data field and adopts a `repr(transparent)`
|
||||
layout.
|
||||
The only generic type or the type marked with `#[pointee]` has to be also
|
||||
marked as `?Sized`.
|
|
@ -545,6 +545,7 @@ E0798: 0798,
|
|||
E0799: 0799,
|
||||
E0800: 0800,
|
||||
E0801: 0801,
|
||||
E0802: 0802,
|
||||
);
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::util::literal;
|
||||
use rustc_ast::{
|
||||
self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp, attr, token,
|
||||
self as ast, AnonConst, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp,
|
||||
attr, token,
|
||||
};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
|
||||
|
@ -138,6 +139,42 @@ impl<'a> ExtCtxt<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn lifetime_param(
|
||||
&self,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
bounds: ast::GenericBounds,
|
||||
) -> ast::GenericParam {
|
||||
ast::GenericParam {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: ident.with_span_pos(span),
|
||||
attrs: AttrVec::new(),
|
||||
bounds,
|
||||
is_placeholder: false,
|
||||
kind: ast::GenericParamKind::Lifetime,
|
||||
colon_span: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn const_param(
|
||||
&self,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
bounds: ast::GenericBounds,
|
||||
ty: P<ast::Ty>,
|
||||
default: Option<AnonConst>,
|
||||
) -> ast::GenericParam {
|
||||
ast::GenericParam {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: ident.with_span_pos(span),
|
||||
attrs: AttrVec::new(),
|
||||
bounds,
|
||||
is_placeholder: false,
|
||||
kind: ast::GenericParamKind::Const { ty, kw_span: DUMMY_SP, default },
|
||||
colon_span: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef {
|
||||
ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID }
|
||||
}
|
||||
|
|
|
@ -370,6 +370,8 @@ 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);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -429,9 +431,13 @@ language_item_table! {
|
|||
ContractCheckRequires, sym::contract_check_requires, contract_check_requires_fn, Target::Fn, GenericRequirement::None;
|
||||
}
|
||||
|
||||
/// The requirement imposed on the generics of a lang item
|
||||
pub enum GenericRequirement {
|
||||
/// No restriction on the generics
|
||||
None,
|
||||
/// A minimum number of generics that is demanded on a lang item
|
||||
Minimum(usize),
|
||||
/// The number of generics must match precisely as stipulated
|
||||
Exact(usize),
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,12 @@ 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_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_transparent = `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
|
||||
|
||||
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
||||
|
||||
hir_analysis_coerce_unsized_multi = implementing the trait `CoerceUnsized` requires multiple coercions
|
||||
|
|
|
@ -48,6 +48,10 @@ pub(super) fn check_trait<'tcx>(
|
|||
checker
|
||||
.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,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -782,3 +786,27 @@ fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), Err
|
|||
.with_note(why_disqualified)
|
||||
.emit())
|
||||
}
|
||||
|
||||
fn visit_implementation_of_coerce_pointee_wellformed(
|
||||
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 ty::Adt(def, _args) = self_ty.kind() else {
|
||||
return Err(tcx.dcx().emit_err(errors::CoercePointeeNotConcreteType {
|
||||
span: tcx.def_span(checker.impl_def_id),
|
||||
}));
|
||||
};
|
||||
let did = def.did();
|
||||
let span =
|
||||
if let Some(local) = did.as_local() { tcx.source_span(local) } else { tcx.def_span(did) };
|
||||
if !def.is_struct() {
|
||||
return Err(tcx
|
||||
.dcx()
|
||||
.emit_err(errors::CoercePointeeNotStruct { span, kind: def.descr().into() }));
|
||||
}
|
||||
if !def.repr().transparent() {
|
||||
return Err(tcx.dcx().emit_err(errors::CoercePointeeNotTransparent { span }));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1180,6 +1180,28 @@ pub(crate) struct DispatchFromDynRepr {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_pointee_not_struct, code = E0802)]
|
||||
pub(crate) struct CoercePointeeNotStruct {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_pointee_not_concrete_ty, code = E0802)]
|
||||
pub(crate) struct CoercePointeeNotConcreteType {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_pointee_not_transparent, code = E0802)]
|
||||
pub(crate) struct CoercePointeeNotTransparent {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_inherent_ty_outside_relevant, code = E0390)]
|
||||
#[help]
|
||||
|
|
|
@ -193,6 +193,7 @@ symbols! {
|
|||
Cleanup,
|
||||
Clone,
|
||||
CoercePointee,
|
||||
CoercePointeeWellformed,
|
||||
CoerceUnsized,
|
||||
Command,
|
||||
ConstParamTy,
|
||||
|
@ -619,6 +620,7 @@ symbols! {
|
|||
cmp_partialord_lt,
|
||||
cmpxchg16b_target_feature,
|
||||
cmse_nonsecure_entry,
|
||||
coerce_pointee_wellformed,
|
||||
coerce_unsized,
|
||||
cold,
|
||||
cold_path,
|
||||
|
|
|
@ -1289,3 +1289,9 @@ pub trait FnPtr: Copy + Clone {
|
|||
pub macro CoercePointee($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[lang = "coerce_pointee_wellformed"]
|
||||
#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
|
||||
#[doc(hidden)]
|
||||
pub trait CoercePointeeWellformed {}
|
||||
|
|
31
tests/ui/deriving/auxiliary/malicious-macro.rs
Normal file
31
tests/ui/deriving/auxiliary/malicious-macro.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
#![feature(let_chains)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::{Delimiter, TokenStream, TokenTree};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn norepr(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let mut tokens = vec![];
|
||||
let mut tts = input.into_iter().fuse().peekable();
|
||||
loop {
|
||||
let Some(token) = tts.next() else { break };
|
||||
if let TokenTree::Punct(punct) = &token
|
||||
&& punct.as_char() == '#'
|
||||
{
|
||||
if let Some(TokenTree::Group(group)) = tts.peek()
|
||||
&& let Delimiter::Bracket = group.delimiter()
|
||||
&& let Some(TokenTree::Ident(ident)) = group.stream().into_iter().next()
|
||||
&& ident.to_string() == "repr"
|
||||
{
|
||||
let _ = tts.next();
|
||||
// skip '#' and '[repr(..)]
|
||||
} else {
|
||||
tokens.push(token);
|
||||
}
|
||||
} else {
|
||||
tokens.push(token);
|
||||
}
|
||||
}
|
||||
tokens.into_iter().collect()
|
||||
}
|
|
@ -20,6 +20,8 @@ pub struct Ptr<'a, #[pointee] T: ?Sized> {
|
|||
data: &'a mut T,
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl<'a, T: ?Sized> ::core::marker::CoercePointeeWellformed 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> {
|
||||
}
|
||||
|
|
|
@ -16,6 +16,10 @@ struct MyPointer<'a, #[pointee] T: ?Sized> {
|
|||
ptr: &'a T,
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl<'a, T: ?Sized> ::core::marker::CoercePointeeWellformed for
|
||||
MyPointer<'a, T> {
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
|
||||
::core::ops::DispatchFromDyn<MyPointer<'a, __S>> for MyPointer<'a, T> {
|
||||
}
|
||||
|
@ -31,6 +35,11 @@ pub struct MyPointer2<'a, Y, Z: MyTrait<T>, #[pointee] T: ?Sized + MyTrait<T>,
|
|||
x: core::marker::PhantomData<X>,
|
||||
}
|
||||
#[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>
|
||||
where Y: MyTrait<T> {
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl<'a, Y, Z: MyTrait<T> + MyTrait<__S>, T: ?Sized + MyTrait<T> +
|
||||
::core::marker::Unsize<__S>, __S: ?Sized + MyTrait<__S>, X: MyTrait<T> +
|
||||
MyTrait<__S>> ::core::ops::DispatchFromDyn<MyPointer2<'a, Y, Z, __S, X>>
|
||||
|
@ -48,6 +57,10 @@ struct MyPointerWithoutPointee<'a, T: ?Sized> {
|
|||
ptr: &'a T,
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl<'a, T: ?Sized> ::core::marker::CoercePointeeWellformed for
|
||||
MyPointerWithoutPointee<'a, T> {
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
|
||||
::core::ops::DispatchFromDyn<MyPointerWithoutPointee<'a, __S>> for
|
||||
MyPointerWithoutPointee<'a, T> {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
//@ proc-macro: malicious-macro.rs
|
||||
#![feature(derive_coerce_pointee, arbitrary_self_types)]
|
||||
|
||||
extern crate core;
|
||||
extern crate malicious_macro;
|
||||
|
||||
use std::marker::CoercePointee;
|
||||
|
||||
#[derive(CoercePointee)]
|
||||
|
@ -131,4 +134,12 @@ struct GlobalCoreSized<'a, #[pointee] T: ?::core::marker::Sized> {
|
|||
ptr: &'a T,
|
||||
}
|
||||
|
||||
#[derive(CoercePointee)]
|
||||
#[malicious_macro::norepr]
|
||||
#[repr(transparent)]
|
||||
struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
||||
//~^ ERROR: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout [E0802]
|
||||
ptr: &'a T,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,89 +1,89 @@
|
|||
error: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:6:10
|
||||
error[E0802]: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:9: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: `CoercePointee` can only be derived on `struct`s with at least one field
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:12:10
|
||||
error[E0802]: `CoercePointee` can only be derived on `struct`s with at least one field
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:15: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: `CoercePointee` can only be derived on `struct`s with at least one field
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:19:10
|
||||
error[E0802]: `CoercePointee` can only be derived on `struct`s with at least one field
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:22: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: `CoercePointee` can only be derived on `struct`s that are generic over at least one type
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:26:10
|
||||
error[E0802]: `CoercePointee` can only be derived on `struct`s that are generic over at least one type
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:29: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: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:31:10
|
||||
error[E0802]: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:34: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: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:40:39
|
||||
error[E0802]: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:43:39
|
||||
|
|
||||
LL | struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
|
||||
| ^ - here another type parameter is marked as `#[pointee]`
|
||||
|
||||
error: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:43:10
|
||||
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: `derive(CoercePointee)` requires `T` to be marked `?Sized`
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:51:36
|
||||
error[E0802]: `derive(CoercePointee)` requires `T` to be marked `?Sized`
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:54:36
|
||||
|
|
||||
LL | struct NoMaybeSized<'a, #[pointee] T> {
|
||||
| ^
|
||||
|
||||
error: the `#[pointee]` attribute may only be used on generic parameters
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:59:5
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:62:5
|
||||
|
|
||||
LL | #[pointee]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: the `#[pointee]` attribute may only be used on generic parameters
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:69:33
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:72:33
|
||||
|
|
||||
LL | struct UhOh<#[pointee] T>(T);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: the `#[pointee]` attribute may only be used on generic parameters
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:83:21
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:86:21
|
||||
|
|
||||
LL | struct UhOh<#[pointee] T>(T);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: the `#[pointee]` attribute may only be used on generic parameters
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:98:25
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:101:25
|
||||
|
|
||||
LL | struct UhOh<#[pointee] T>(T);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0392]: lifetime parameter `'a` is never used
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:15:16
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:18:16
|
||||
|
|
||||
LL | struct NoField<'a, #[pointee] T: ?Sized> {}
|
||||
| ^^ unused lifetime parameter
|
||||
|
@ -91,7 +91,7 @@ LL | struct NoField<'a, #[pointee] T: ?Sized> {}
|
|||
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
|
||||
error[E0392]: type parameter `T` is never used
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:15:31
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:18:31
|
||||
|
|
||||
LL | struct NoField<'a, #[pointee] T: ?Sized> {}
|
||||
| ^ unused type parameter
|
||||
|
@ -99,7 +99,7 @@ LL | struct NoField<'a, #[pointee] T: ?Sized> {}
|
|||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
|
||||
error[E0392]: lifetime parameter `'a` is never used
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:22:20
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:25:20
|
||||
|
|
||||
LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
|
||||
| ^^ unused lifetime parameter
|
||||
|
@ -107,13 +107,23 @@ LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
|
|||
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
|
||||
error[E0392]: type parameter `T` is never used
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:22:35
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:25:35
|
||||
|
|
||||
LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
|
||||
| ^ unused type parameter
|
||||
|
|
||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
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 | | }
|
||||
| |_^
|
||||
|
||||
For more information about this error, try `rustc --explain E0392`.
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0392, E0802.
|
||||
For more information about an error, try `rustc --explain E0392`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue