mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 14:31:55 +00:00
reject pointee without ?Sized
This commit is contained in:
parent
99322d84c4
commit
14a0963f96
@ -1,5 +1,3 @@
|
||||
use std::mem::swap;
|
||||
|
||||
use ast::ptr::P;
|
||||
use ast::HasAttrs;
|
||||
use rustc_ast::mut_visit::MutVisitor;
|
||||
@ -154,13 +152,28 @@ pub fn expand_deriving_smart_ptr(
|
||||
{
|
||||
let pointee = &mut impl_generics.params[pointee_param_idx];
|
||||
self_bounds = pointee.bounds.clone();
|
||||
if !contains_maybe_sized_bound(&self_bounds)
|
||||
&& !contains_maybe_sized_bound_on_pointee(
|
||||
&generics.where_clause.predicates,
|
||||
pointee_ty_ident.name,
|
||||
)
|
||||
{
|
||||
cx.dcx()
|
||||
.struct_span_err(
|
||||
pointee_ty_ident.span,
|
||||
format!(
|
||||
"`derive(SmartPointer)` requires {} to be marked `?Sized`",
|
||||
pointee_ty_ident.name
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
let arg = GenericArg::Type(s_ty.clone());
|
||||
let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]);
|
||||
pointee.bounds.push(cx.trait_bound(unsize, false));
|
||||
let mut attrs = thin_vec![];
|
||||
swap(&mut pointee.attrs, &mut attrs);
|
||||
// Drop `#[pointee]` attribute since it should not be recognized outside `derive(SmartPointer)`
|
||||
pointee.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect();
|
||||
pointee.attrs.retain(|attr| !attr.has_name(sym::pointee));
|
||||
}
|
||||
|
||||
// # Rewrite generic parameter bounds
|
||||
@ -169,14 +182,14 @@ pub fn expand_deriving_smart_ptr(
|
||||
// ```
|
||||
// struct<
|
||||
// U: Trait<T>,
|
||||
// #[pointee] T: Trait<T>,
|
||||
// #[pointee] T: Trait<T> + ?Sized,
|
||||
// V: Trait<T>> ...
|
||||
// ```
|
||||
// ... generates this `impl` generic parameters
|
||||
// ```
|
||||
// impl<
|
||||
// U: Trait<T> + Trait<__S>,
|
||||
// T: Trait<T> + Unsize<__S>, // (**)
|
||||
// T: Trait<T> + ?Sized + Unsize<__S>, // (**)
|
||||
// __S: Trait<__S> + ?Sized, // (*)
|
||||
// V: Trait<T> + Trait<__S>> ...
|
||||
// ```
|
||||
@ -218,23 +231,6 @@ pub fn expand_deriving_smart_ptr(
|
||||
//
|
||||
// We now insert `__S` with the missing bounds marked with (*) above.
|
||||
// We should also write the bounds from `#[pointee]` to `__S` as required by `Unsize<__S>`.
|
||||
let sized = cx.path_global(span, path!(span, core::marker::Sized));
|
||||
// For some reason, we are not allowed to write `?Sized` bound twice like `__S: ?Sized + ?Sized`.
|
||||
if !contains_maybe_sized_bound(&self_bounds)
|
||||
&& !contains_maybe_sized_bound_on_pointee(
|
||||
&generics.where_clause.predicates,
|
||||
pointee_ty_ident.name,
|
||||
)
|
||||
{
|
||||
self_bounds.push(GenericBound::Trait(
|
||||
cx.poly_trait_ref(span, sized),
|
||||
TraitBoundModifiers {
|
||||
polarity: ast::BoundPolarity::Maybe(span),
|
||||
constness: ast::BoundConstness::Never,
|
||||
asyncness: ast::BoundAsyncness::Normal,
|
||||
},
|
||||
));
|
||||
}
|
||||
{
|
||||
let mut substitution =
|
||||
TypeSubstitution { from_name: pointee_ty_ident.name, to_ty: &s_ty, rewritten: false };
|
||||
@ -252,7 +248,7 @@ pub fn expand_deriving_smart_ptr(
|
||||
// where
|
||||
// U: Trait<V> + Trait<T>,
|
||||
// Companion<T>: Trait<T>,
|
||||
// T: Trait<T>,
|
||||
// T: Trait<T> + ?Sized,
|
||||
// { .. }
|
||||
// ```
|
||||
// ... will have a impl prelude like so
|
||||
@ -263,8 +259,8 @@ pub fn expand_deriving_smart_ptr(
|
||||
// U: Trait<__S>,
|
||||
// Companion<T>: Trait<T>,
|
||||
// Companion<__S>: Trait<__S>,
|
||||
// T: Trait<T>,
|
||||
// __S: Trait<__S>,
|
||||
// T: Trait<T> + ?Sized,
|
||||
// __S: Trait<__S> + ?Sized,
|
||||
// ```
|
||||
//
|
||||
// We should also write a few new `where` bounds from `#[pointee] T` to `__S`
|
||||
|
@ -1,5 +1,6 @@
|
||||
#![feature(derive_smart_pointer, arbitrary_self_types)]
|
||||
|
||||
extern crate core;
|
||||
use std::marker::SmartPointer;
|
||||
|
||||
#[derive(SmartPointer)]
|
||||
@ -35,6 +36,13 @@ struct NotTransparent<'a, #[pointee] T: ?Sized> {
|
||||
ptr: &'a T,
|
||||
}
|
||||
|
||||
#[derive(SmartPointer)]
|
||||
#[repr(transparent)]
|
||||
struct NoMaybeSized<'a, #[pointee] T> {
|
||||
//~^ ERROR: `derive(SmartPointer)` requires T to be marked `?Sized`
|
||||
ptr: &'a T,
|
||||
}
|
||||
|
||||
// However, reordering attributes should work nevertheless.
|
||||
#[repr(transparent)]
|
||||
#[derive(SmartPointer)]
|
||||
@ -42,4 +50,26 @@ struct ThisIsAPossibleSmartPointer<'a, #[pointee] T: ?Sized> {
|
||||
ptr: &'a T,
|
||||
}
|
||||
|
||||
// Also, these paths to Sized should work
|
||||
#[derive(SmartPointer)]
|
||||
#[repr(transparent)]
|
||||
struct StdSized<'a, #[pointee] T: ?std::marker::Sized> {
|
||||
ptr: &'a T,
|
||||
}
|
||||
#[derive(SmartPointer)]
|
||||
#[repr(transparent)]
|
||||
struct CoreSized<'a, #[pointee] T: ?core::marker::Sized> {
|
||||
ptr: &'a T,
|
||||
}
|
||||
#[derive(SmartPointer)]
|
||||
#[repr(transparent)]
|
||||
struct GlobalStdSized<'a, #[pointee] T: ?::std::marker::Sized> {
|
||||
ptr: &'a T,
|
||||
}
|
||||
#[derive(SmartPointer)]
|
||||
#[repr(transparent)]
|
||||
struct GlobalCoreSized<'a, #[pointee] T: ?::core::marker::Sized> {
|
||||
ptr: &'a T,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:5:10
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:6:10
|
||||
|
|
||||
LL | #[derive(SmartPointer)]
|
||||
| ^^^^^^^^^^^^
|
||||
@ -7,7 +7,7 @@ LL | #[derive(SmartPointer)]
|
||||
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:11:10
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:12:10
|
||||
|
|
||||
LL | #[derive(SmartPointer)]
|
||||
| ^^^^^^^^^^^^
|
||||
@ -15,7 +15,7 @@ LL | #[derive(SmartPointer)]
|
||||
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: `SmartPointer` can only be derived on `struct`s with at least one field
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:18:10
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:19:10
|
||||
|
|
||||
LL | #[derive(SmartPointer)]
|
||||
| ^^^^^^^^^^^^
|
||||
@ -23,7 +23,7 @@ LL | #[derive(SmartPointer)]
|
||||
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: `SmartPointer` can only be derived on `struct`s with at least one field
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:25:10
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:26:10
|
||||
|
|
||||
LL | #[derive(SmartPointer)]
|
||||
| ^^^^^^^^^^^^
|
||||
@ -31,15 +31,21 @@ LL | #[derive(SmartPointer)]
|
||||
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:32:10
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:33:10
|
||||
|
|
||||
LL | #[derive(SmartPointer)]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: `derive(SmartPointer)` requires T to be marked `?Sized`
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:41:36
|
||||
|
|
||||
LL | struct NoMaybeSized<'a, #[pointee] T> {
|
||||
| ^
|
||||
|
||||
error[E0392]: lifetime parameter `'a` is never used
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:21:16
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:22:16
|
||||
|
|
||||
LL | struct NoField<'a, #[pointee] T: ?Sized> {}
|
||||
| ^^ unused lifetime parameter
|
||||
@ -47,7 +53,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-smart-pointer-neg.rs:21:31
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:22:31
|
||||
|
|
||||
LL | struct NoField<'a, #[pointee] T: ?Sized> {}
|
||||
| ^ unused type parameter
|
||||
@ -55,7 +61,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-smart-pointer-neg.rs:28:20
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:29:20
|
||||
|
|
||||
LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
|
||||
| ^^ unused lifetime parameter
|
||||
@ -63,13 +69,13 @@ 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-smart-pointer-neg.rs:28:35
|
||||
--> $DIR/deriving-smart-pointer-neg.rs:29: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 9 previous errors
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0392`.
|
||||
|
Loading…
Reference in New Issue
Block a user