Skip to content

Commit 3c22319

Browse files
authored
Unrolled build for rust-lang#128452
Rollup merge of rust-lang#128452 - dingxiangfei2009:smart-ptr-require-maybe-sized, r=compiler-errors derive(SmartPointer): require pointee to be maybe sized cc ``@Darksonn`` So `#[pointee]` has to be `?Sized` in order for deriving `SmartPointer` to be meaningful. cc ``@compiler-errors`` for suggestions in rust-lang#127681
2 parents 28a58f2 + 14a0963 commit 3c22319

File tree

3 files changed

+69
-37
lines changed

3 files changed

+69
-37
lines changed

compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs

+23-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::mem::swap;
2-
31
use ast::ptr::P;
42
use ast::HasAttrs;
53
use rustc_ast::mut_visit::MutVisitor;
@@ -154,13 +152,28 @@ pub fn expand_deriving_smart_ptr(
154152
{
155153
let pointee = &mut impl_generics.params[pointee_param_idx];
156154
self_bounds = pointee.bounds.clone();
155+
if !contains_maybe_sized_bound(&self_bounds)
156+
&& !contains_maybe_sized_bound_on_pointee(
157+
&generics.where_clause.predicates,
158+
pointee_ty_ident.name,
159+
)
160+
{
161+
cx.dcx()
162+
.struct_span_err(
163+
pointee_ty_ident.span,
164+
format!(
165+
"`derive(SmartPointer)` requires {} to be marked `?Sized`",
166+
pointee_ty_ident.name
167+
),
168+
)
169+
.emit();
170+
return;
171+
}
157172
let arg = GenericArg::Type(s_ty.clone());
158173
let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]);
159174
pointee.bounds.push(cx.trait_bound(unsize, false));
160-
let mut attrs = thin_vec![];
161-
swap(&mut pointee.attrs, &mut attrs);
162175
// Drop `#[pointee]` attribute since it should not be recognized outside `derive(SmartPointer)`
163-
pointee.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect();
176+
pointee.attrs.retain(|attr| !attr.has_name(sym::pointee));
164177
}
165178

166179
// # Rewrite generic parameter bounds
@@ -169,14 +182,14 @@ pub fn expand_deriving_smart_ptr(
169182
// ```
170183
// struct<
171184
// U: Trait<T>,
172-
// #[pointee] T: Trait<T>,
185+
// #[pointee] T: Trait<T> + ?Sized,
173186
// V: Trait<T>> ...
174187
// ```
175188
// ... generates this `impl` generic parameters
176189
// ```
177190
// impl<
178191
// U: Trait<T> + Trait<__S>,
179-
// T: Trait<T> + Unsize<__S>, // (**)
192+
// T: Trait<T> + ?Sized + Unsize<__S>, // (**)
180193
// __S: Trait<__S> + ?Sized, // (*)
181194
// V: Trait<T> + Trait<__S>> ...
182195
// ```
@@ -218,23 +231,6 @@ pub fn expand_deriving_smart_ptr(
218231
//
219232
// We now insert `__S` with the missing bounds marked with (*) above.
220233
// 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-
}
238234
{
239235
let mut substitution =
240236
TypeSubstitution { from_name: pointee_ty_ident.name, to_ty: &s_ty, rewritten: false };
@@ -252,7 +248,7 @@ pub fn expand_deriving_smart_ptr(
252248
// where
253249
// U: Trait<V> + Trait<T>,
254250
// Companion<T>: Trait<T>,
255-
// T: Trait<T>,
251+
// T: Trait<T> + ?Sized,
256252
// { .. }
257253
// ```
258254
// ... will have a impl prelude like so
@@ -263,8 +259,8 @@ pub fn expand_deriving_smart_ptr(
263259
// U: Trait<__S>,
264260
// Companion<T>: Trait<T>,
265261
// Companion<__S>: Trait<__S>,
266-
// T: Trait<T>,
267-
// __S: Trait<__S>,
262+
// T: Trait<T> + ?Sized,
263+
// __S: Trait<__S> + ?Sized,
268264
// ```
269265
//
270266
// We should also write a few new `where` bounds from `#[pointee] T` to `__S`

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: `derive(SmartPointer)` requires T to be marked `?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: `derive(SmartPointer)` requires T to be marked `?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)