From b49de3dc5b526fc9f411c1d48cce5c923727bd16 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Wed, 31 Jul 2024 22:50:45 +0800 Subject: [PATCH] reject pointee without ?Sized --- .../src/deriving/smart_ptr.rs | 34 +++++++++---------- .../ui/deriving/deriving-smart-pointer-neg.rs | 7 ++++ .../deriving-smart-pointer-neg.stderr | 8 ++++- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs index 02555bd799c42..640c61b6ab00e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -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!( + "`SmartPointer` is meaningless because `{}` is not `?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)); @@ -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 }; diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.rs b/tests/ui/deriving/deriving-smart-pointer-neg.rs index bfb4e86b39601..10189b28c5792 100644 --- a/tests/ui/deriving/deriving-smart-pointer-neg.rs +++ b/tests/ui/deriving/deriving-smart-pointer-neg.rs @@ -35,6 +35,13 @@ 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)] diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.stderr b/tests/ui/deriving/deriving-smart-pointer-neg.stderr index d994a6ee376b0..0fdd65583d68c 100644 --- a/tests/ui/deriving/deriving-smart-pointer-neg.stderr +++ b/tests/ui/deriving/deriving-smart-pointer-neg.stderr @@ -38,6 +38,12 @@ 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:40:36 + | +LL | struct NoMaybeSized<'a, #[pointee] T> { + | ^ + error[E0392]: lifetime parameter `'a` is never used --> $DIR/deriving-smart-pointer-neg.rs:21:16 | @@ -70,6 +76,6 @@ LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>(); | = 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`.