Skip to content

Commit a9a3699

Browse files
reject pointee without ?Sized
1 parent e7f89a7 commit a9a3699

File tree

3 files changed

+63
-27
lines changed

3 files changed

+63
-27
lines changed

compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,23 @@ pub fn expand_deriving_smart_ptr(
154154
{
155155
let pointee = &mut impl_generics.params[pointee_param_idx];
156156
self_bounds = pointee.bounds.clone();
157+
if !contains_maybe_sized_bound(&self_bounds)
158+
&& !contains_maybe_sized_bound_on_pointee(
159+
&generics.where_clause.predicates,
160+
pointee_ty_ident.name,
161+
)
162+
{
163+
cx.dcx()
164+
.struct_span_err(
165+
pointee_ty_ident.span,
166+
format!(
167+
"`derive(SmartPointer)` requires the use of `{}: ?Sized`",
168+
pointee_ty_ident.name
169+
),
170+
)
171+
.emit();
172+
return;
173+
}
157174
let arg = GenericArg::Type(s_ty.clone());
158175
let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]);
159176
pointee.bounds.push(cx.trait_bound(unsize, false));
@@ -218,23 +235,6 @@ pub fn expand_deriving_smart_ptr(
218235
//
219236
// We now insert `__S` with the missing bounds marked with (*) above.
220237
// We should also write the bounds from `#[pointee]` to `__S` as required by `Unsize<__S>`.
221-
let sized = cx.path_global(span, path!(span, core::marker::Sized));
222-
// For some reason, we are not allowed to write `?Sized` bound twice like `__S: ?Sized + ?Sized`.
223-
if !contains_maybe_sized_bound(&self_bounds)
224-
&& !contains_maybe_sized_bound_on_pointee(
225-
&generics.where_clause.predicates,
226-
pointee_ty_ident.name,
227-
)
228-
{
229-
self_bounds.push(GenericBound::Trait(
230-
cx.poly_trait_ref(span, sized),
231-
TraitBoundModifiers {
232-
polarity: ast::BoundPolarity::Maybe(span),
233-
constness: ast::BoundConstness::Never,
234-
asyncness: ast::BoundAsyncness::Normal,
235-
},
236-
));
237-
}
238238
{
239239
let mut substitution =
240240
TypeSubstitution { from_name: pointee_ty_ident.name, to_ty: &s_ty, rewritten: false };

tests/ui/deriving/deriving-smart-pointer-neg.rs

+30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![feature(derive_smart_pointer, arbitrary_self_types)]
22

3+
extern crate core;
34
use std::marker::SmartPointer;
45

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

39+
#[derive(SmartPointer)]
40+
#[repr(transparent)]
41+
struct NoMaybeSized<'a, #[pointee] T> {
42+
//~^ ERROR: SmartPointer` is meaningless because `T` is not `?Sized
43+
ptr: &'a T,
44+
}
45+
3846
// However, reordering attributes should work nevertheless.
3947
#[repr(transparent)]
4048
#[derive(SmartPointer)]
4149
struct ThisIsAPossibleSmartPointer<'a, #[pointee] T: ?Sized> {
4250
ptr: &'a T,
4351
}
4452

53+
// Also, these paths to Sized should work
54+
#[derive(SmartPointer)]
55+
#[repr(transparent)]
56+
struct StdSized<'a, #[pointee] T: ?std::marker::Sized> {
57+
ptr: &'a T,
58+
}
59+
#[derive(SmartPointer)]
60+
#[repr(transparent)]
61+
struct CoreSized<'a, #[pointee] T: ?core::marker::Sized> {
62+
ptr: &'a T,
63+
}
64+
#[derive(SmartPointer)]
65+
#[repr(transparent)]
66+
struct GlobalStdSized<'a, #[pointee] T: ?::std::marker::Sized> {
67+
ptr: &'a T,
68+
}
69+
#[derive(SmartPointer)]
70+
#[repr(transparent)]
71+
struct GlobalCoreSized<'a, #[pointee] T: ?::core::marker::Sized> {
72+
ptr: &'a T,
73+
}
74+
4575
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,81 @@
11
error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
2-
--> $DIR/deriving-smart-pointer-neg.rs:5:10
2+
--> $DIR/deriving-smart-pointer-neg.rs:6:10
33
|
44
LL | #[derive(SmartPointer)]
55
| ^^^^^^^^^^^^
66
|
77
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
88

99
error: At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits
10-
--> $DIR/deriving-smart-pointer-neg.rs:11:10
10+
--> $DIR/deriving-smart-pointer-neg.rs:12:10
1111
|
1212
LL | #[derive(SmartPointer)]
1313
| ^^^^^^^^^^^^
1414
|
1515
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
1616

1717
error: `SmartPointer` can only be derived on `struct`s with at least one field
18-
--> $DIR/deriving-smart-pointer-neg.rs:18:10
18+
--> $DIR/deriving-smart-pointer-neg.rs:19:10
1919
|
2020
LL | #[derive(SmartPointer)]
2121
| ^^^^^^^^^^^^
2222
|
2323
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
2424

2525
error: `SmartPointer` can only be derived on `struct`s with at least one field
26-
--> $DIR/deriving-smart-pointer-neg.rs:25:10
26+
--> $DIR/deriving-smart-pointer-neg.rs:26:10
2727
|
2828
LL | #[derive(SmartPointer)]
2929
| ^^^^^^^^^^^^
3030
|
3131
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
3232

3333
error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
34-
--> $DIR/deriving-smart-pointer-neg.rs:32:10
34+
--> $DIR/deriving-smart-pointer-neg.rs:33:10
3535
|
3636
LL | #[derive(SmartPointer)]
3737
| ^^^^^^^^^^^^
3838
|
3939
= note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
4040

41+
error: `SmartPointer` is meaningless because `T` is not `?Sized`
42+
--> $DIR/deriving-smart-pointer-neg.rs:41:36
43+
|
44+
LL | struct NoMaybeSized<'a, #[pointee] T> {
45+
| ^
46+
4147
error[E0392]: lifetime parameter `'a` is never used
42-
--> $DIR/deriving-smart-pointer-neg.rs:21:16
48+
--> $DIR/deriving-smart-pointer-neg.rs:22:16
4349
|
4450
LL | struct NoField<'a, #[pointee] T: ?Sized> {}
4551
| ^^ unused lifetime parameter
4652
|
4753
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
4854

4955
error[E0392]: type parameter `T` is never used
50-
--> $DIR/deriving-smart-pointer-neg.rs:21:31
56+
--> $DIR/deriving-smart-pointer-neg.rs:22:31
5157
|
5258
LL | struct NoField<'a, #[pointee] T: ?Sized> {}
5359
| ^ unused type parameter
5460
|
5561
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
5662

5763
error[E0392]: lifetime parameter `'a` is never used
58-
--> $DIR/deriving-smart-pointer-neg.rs:28:20
64+
--> $DIR/deriving-smart-pointer-neg.rs:29:20
5965
|
6066
LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
6167
| ^^ unused lifetime parameter
6268
|
6369
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
6470

6571
error[E0392]: type parameter `T` is never used
66-
--> $DIR/deriving-smart-pointer-neg.rs:28:35
72+
--> $DIR/deriving-smart-pointer-neg.rs:29:35
6773
|
6874
LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
6975
| ^ unused type parameter
7076
|
7177
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
7278

73-
error: aborting due to 9 previous errors
79+
error: aborting due to 10 previous errors
7480

7581
For more information about this error, try `rustc --explain E0392`.

0 commit comments

Comments
 (0)