Skip to content

Commit a26d609

Browse files
committed
Check that #[pointee] is applied only to generic arguments
1 parent 842d6fc commit a26d609

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

compiler/rustc_builtin_macros/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ builtin_macros_non_exhaustive_default = default variant must be exhaustive
235235
.label = declared `#[non_exhaustive]` here
236236
.help = consider a manual implementation of `Default`
237237
238+
builtin_macros_non_generic_pointee = the `#[pointee]` attribute may only be used on generic parameters
239+
238240
builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants
239241
.help = consider a manual implementation of `Default`
240242

compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs

+25
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use rustc_span::symbol::{sym, Ident};
1313
use rustc_span::{Span, Symbol};
1414
use thin_vec::{thin_vec, ThinVec};
1515

16+
use crate::errors;
17+
1618
macro_rules! path {
1719
($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
1820
}
@@ -25,6 +27,8 @@ pub(crate) fn expand_deriving_smart_ptr(
2527
push: &mut dyn FnMut(Annotatable),
2628
_is_const: bool,
2729
) {
30+
item.visit_with(&mut DetectNonGenericPointeeAttr { cx });
31+
2832
let (name_ident, generics) = if let Annotatable::Item(aitem) = item
2933
&& let ItemKind::Struct(struct_data, g) = &aitem.kind
3034
{
@@ -396,3 +400,24 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
396400
}
397401
}
398402
}
403+
404+
struct DetectNonGenericPointeeAttr<'a, 'b> {
405+
cx: &'a ExtCtxt<'b>,
406+
}
407+
408+
impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonGenericPointeeAttr<'a, 'b> {
409+
fn visit_attribute(&mut self, attr: &'a rustc_ast::Attribute) -> Self::Result {
410+
if attr.has_name(sym::pointee) {
411+
self.cx.dcx().emit_err(errors::NonGenericPointee { span: attr.span });
412+
}
413+
}
414+
415+
fn visit_generic_param(&mut self, param: &'a rustc_ast::GenericParam) -> Self::Result {
416+
match param.kind {
417+
GenericParamKind::Type { .. } => return,
418+
GenericParamKind::Lifetime | GenericParamKind::Const { .. } => {
419+
rustc_ast::visit::walk_generic_param(self, param)
420+
}
421+
}
422+
}
423+
}

compiler/rustc_builtin_macros/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -937,3 +937,10 @@ pub(crate) struct NakedFunctionTestingAttribute {
937937
#[label]
938938
pub testing_span: Span,
939939
}
940+
941+
#[derive(Diagnostic)]
942+
#[diag(builtin_macros_non_generic_pointee)]
943+
pub(crate) struct NonGenericPointee {
944+
#[primary_span]
945+
pub span: Span,
946+
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ struct NoMaybeSized<'a, #[pointee] T> {
5353
ptr: &'a T,
5454
}
5555

56+
#[derive(SmartPointer)]
57+
#[repr(transparent)]
58+
struct PointeeOnField<'a, #[pointee] T: ?Sized> {
59+
#[pointee]
60+
//~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
61+
ptr: &'a T
62+
}
63+
5664
// However, reordering attributes should work nevertheless.
5765
#[repr(transparent)]
5866
#[derive(SmartPointer)]

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ error: `derive(SmartPointer)` requires T to be marked `?Sized`
5858
LL | struct NoMaybeSized<'a, #[pointee] T> {
5959
| ^
6060

61+
error: the `#[pointee]` attribute may only be used on generic parameters
62+
--> $DIR/deriving-smart-pointer-neg.rs:59:5
63+
|
64+
LL | #[pointee]
65+
| ^^^^^^^^^^
66+
6167
error[E0392]: lifetime parameter `'a` is never used
6268
--> $DIR/deriving-smart-pointer-neg.rs:15:16
6369
|
@@ -90,6 +96,6 @@ LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
9096
|
9197
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
9298

93-
error: aborting due to 12 previous errors
99+
error: aborting due to 13 previous errors
94100

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

0 commit comments

Comments
 (0)