Skip to content

Commit fcdb5f0

Browse files
committed
Check that #[pointee] is applied only to generic arguments
1 parent 4d5b3b1 commit fcdb5f0

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
@@ -14,6 +14,8 @@ use rustc_span::{Span, Symbol};
1414
use smallvec::{smallvec, SmallVec};
1515
use thin_vec::{thin_vec, ThinVec};
1616

17+
use crate::errors;
18+
1719
macro_rules! path {
1820
($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
1921
}
@@ -26,6 +28,8 @@ pub fn expand_deriving_smart_ptr(
2628
push: &mut dyn FnMut(Annotatable),
2729
_is_const: bool,
2830
) {
31+
item.visit_with(&mut DetectNonGenericPointeeAttr { cx });
32+
2933
let (name_ident, generics) = if let Annotatable::Item(aitem) = item
3034
&& let ItemKind::Struct(struct_data, g) = &aitem.kind
3135
{
@@ -377,3 +381,24 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
377381
}
378382
}
379383
}
384+
385+
struct DetectNonGenericPointeeAttr<'a, 'b> {
386+
cx: &'a ExtCtxt<'b>,
387+
}
388+
389+
impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonGenericPointeeAttr<'a, 'b> {
390+
fn visit_attribute(&mut self, attr: &'a rustc_ast::Attribute) -> Self::Result {
391+
if attr.has_name(sym::pointee) {
392+
self.cx.dcx().emit_err(errors::NonGenericPointee { span: attr.span });
393+
}
394+
}
395+
396+
fn visit_generic_param(&mut self, param: &'a rustc_ast::GenericParam) -> Self::Result {
397+
match param.kind {
398+
GenericParamKind::Type { .. } => return,
399+
GenericParamKind::Lifetime | GenericParamKind::Const { .. } => {
400+
rustc_ast::visit::walk_generic_param(self, param)
401+
}
402+
}
403+
}
404+
}

compiler/rustc_builtin_macros/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -937,3 +937,10 @@ pub struct NakedFunctionTestingAttribute {
937937
#[label]
938938
pub testing_span: Span,
939939
}
940+
941+
#[derive(Diagnostic)]
942+
#[diag(builtin_macros_non_generic_pointee)]
943+
pub 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
@@ -43,6 +43,14 @@ struct NoMaybeSized<'a, #[pointee] T> {
4343
ptr: &'a T,
4444
}
4545

46+
#[derive(SmartPointer)]
47+
#[repr(transparent)]
48+
struct PointeeOnField<'a, #[pointee] T: ?Sized> {
49+
#[pointee]
50+
//~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
51+
ptr: &'a T
52+
}
53+
4654
// However, reordering attributes should work nevertheless.
4755
#[repr(transparent)]
4856
#[derive(SmartPointer)]

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

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

47+
error: the `#[pointee]` attribute may only be used on generic parameters
48+
--> $DIR/deriving-smart-pointer-neg.rs:49:5
49+
|
50+
LL | #[pointee]
51+
| ^^^^^^^^^^
52+
4753
error[E0392]: lifetime parameter `'a` is never used
4854
--> $DIR/deriving-smart-pointer-neg.rs:22:16
4955
|
@@ -76,6 +82,6 @@ LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
7682
|
7783
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
7884

79-
error: aborting due to 10 previous errors
85+
error: aborting due to 11 previous errors
8086

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

0 commit comments

Comments
 (0)