Skip to content

Commit

Permalink
reject pointee without ?Sized
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Jul 31, 2024
1 parent e7f89a7 commit a9a3699
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 27 deletions.
34 changes: 17 additions & 17 deletions compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,23 @@ 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 the use of `{}: ?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));
Expand Down Expand Up @@ -218,23 +235,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 };
Expand Down
30 changes: 30 additions & 0 deletions tests/ui/deriving/deriving-smart-pointer-neg.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![feature(derive_smart_pointer, arbitrary_self_types)]

extern crate core;
use std::marker::SmartPointer;

#[derive(SmartPointer)]
Expand Down Expand Up @@ -35,11 +36,40 @@ struct NotTransparent<'a, #[pointee] T: ?Sized> {
ptr: &'a T,
}

#[derive(SmartPointer)]
#[repr(transparent)]
struct NoMaybeSized<'a, #[pointee] T> {
//~^ ERROR: SmartPointer` is meaningless because `T` is not `?Sized
ptr: &'a T,
}

// However, reordering attributes should work nevertheless.
#[repr(transparent)]
#[derive(SmartPointer)]
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() {}
26 changes: 16 additions & 10 deletions tests/ui/deriving/deriving-smart-pointer-neg.stderr
Original file line number Diff line number Diff line change
@@ -1,75 +1,81 @@
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)]
| ^^^^^^^^^^^^
|
= 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)]
| ^^^^^^^^^^^^
|
= 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)]
| ^^^^^^^^^^^^
|
= 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)]
| ^^^^^^^^^^^^
|
= 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: `SmartPointer` is meaningless because `T` is not `?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
|
= 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
|
= 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
|
= 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`.

0 comments on commit a9a3699

Please sign in to comment.