1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
//@ 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)]
//~^ ERROR: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
enum NotStruct<'a, T: ?Sized> {
Variant(&'a T),
}
#[derive(CoercePointee)]
//~^ ERROR: `CoercePointee` can only be derived on `struct`s with at least one field
#[repr(transparent)]
struct NoField<'a, #[pointee] T: ?Sized> {}
//~^ ERROR: lifetime parameter `'a` is never used
//~| ERROR: type parameter `T` is never used
#[derive(CoercePointee)]
//~^ ERROR: `CoercePointee` can only be derived on `struct`s with at least one field
#[repr(transparent)]
struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
//~^ ERROR: lifetime parameter `'a` is never used
//~| ERROR: type parameter `T` is never used
#[derive(CoercePointee)]
//~^ ERROR: `CoercePointee` can only be derived on `struct`s that are generic over at least one type
#[repr(transparent)]
struct NoGeneric<'a>(&'a u8);
#[derive(CoercePointee)]
//~^ ERROR: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
#[repr(transparent)]
struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
a: (&'a T1, &'a T2),
}
#[derive(CoercePointee)]
#[repr(transparent)]
struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
//~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
#[derive(CoercePointee)]
struct NotTransparent<'a, #[pointee] T: ?Sized> {
//~^ ERROR: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
ptr: &'a T,
}
#[derive(CoercePointee)]
#[repr(transparent)]
struct NoMaybeSized<'a, #[pointee] T> {
//~^ ERROR: `derive(CoercePointee)` requires `T` to be marked `?Sized`
ptr: &'a T,
}
#[derive(CoercePointee)]
#[repr(transparent)]
struct PointeeOnField<'a, #[pointee] T: ?Sized> {
#[pointee]
//~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
ptr: &'a T,
}
#[derive(CoercePointee)]
#[repr(transparent)]
struct PointeeInTypeConstBlock<
'a,
T: ?Sized = [u32; const {
struct UhOh<#[pointee] T>(T);
//~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
10
}],
> {
ptr: &'a T,
}
#[derive(CoercePointee)]
#[repr(transparent)]
struct PointeeInConstConstBlock<
'a,
T: ?Sized,
const V: u32 = {
struct UhOh<#[pointee] T>(T);
//~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
10
},
> {
ptr: &'a T,
}
#[derive(CoercePointee)]
#[repr(transparent)]
struct PointeeInAnotherTypeConstBlock<'a, #[pointee] T: ?Sized> {
ptr: PointeeInConstConstBlock<
'a,
T,
{
struct UhOh<#[pointee] T>(T);
//~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
0
},
>,
}
// However, reordering attributes should work nevertheless.
#[repr(transparent)]
#[derive(CoercePointee)]
struct ThisIsAPossibleCoercePointee<'a, #[pointee] T: ?Sized> {
ptr: &'a T,
}
// Also, these paths to Sized should work
#[derive(CoercePointee)]
#[repr(transparent)]
struct StdSized<'a, #[pointee] T: ?std::marker::Sized> {
ptr: &'a T,
}
#[derive(CoercePointee)]
#[repr(transparent)]
struct CoreSized<'a, #[pointee] T: ?core::marker::Sized> {
ptr: &'a T,
}
#[derive(CoercePointee)]
#[repr(transparent)]
struct GlobalStdSized<'a, #[pointee] T: ?::std::marker::Sized> {
ptr: &'a T,
}
#[derive(CoercePointee)]
#[repr(transparent)]
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,
}
#[repr(transparent)]
#[derive(CoercePointee)]
//~^ ERROR for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
struct RcWithId<T: ?Sized> {
inner: std::rc::Rc<(i32, Box<T>)>,
}
#[repr(transparent)]
#[derive(CoercePointee)]
//~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced
struct MoreThanOneField<T: ?Sized> {
//~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2
inner1: Box<T>,
inner2: Box<T>,
}
struct NotCoercePointeeData<T: ?Sized>(T);
#[repr(transparent)]
#[derive(CoercePointee)]
//~^ ERROR for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
fn main() {}
|