summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-07-04 18:16:23 +0200
committerGitHub <noreply@github.com>2024-07-04 18:16:23 +0200
commitd27136fb2916bb2fda9bd732af8f0a18b966d0c9 (patch)
tree6e975cfb2d7e197367e0933a5b4aa16ad5fc1c94 /compiler
parente62956dea573c58010429788638d92d23f294d20 (diff)
parent0b4edb2487005d7db85a1261fcc77e26e1955553 (diff)
Rollup merge of #127283 - dingxiangfei2009:check-repr-transparent, r=davidtwco
Reject SmartPointer constructions not serving the purpose Tracking issue: #123430 With this PR we will reject a row of malformed `SmartPointer` implementor candidates. cc `@Darksonn` `@davidtwco` for context.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs39
1 files changed, 36 insertions, 3 deletions
diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
index ea054a7e355..bbc7cd39627 100644
--- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
@@ -3,8 +3,9 @@ use std::mem::swap;
use ast::HasAttrs;
use rustc_ast::{
self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem,
- TraitBoundModifiers,
+ TraitBoundModifiers, VariantData,
};
+use rustc_attr as attr;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
@@ -24,11 +25,43 @@ pub fn expand_deriving_smart_ptr(
_is_const: bool,
) {
let (name_ident, generics) = if let Annotatable::Item(aitem) = item
- && let ItemKind::Struct(_, g) = &aitem.kind
+ && let ItemKind::Struct(struct_data, g) = &aitem.kind
{
+ let is_transparent = aitem.attrs.iter().any(|attr| {
+ attr::find_repr_attrs(cx.sess, attr)
+ .into_iter()
+ .any(|r| matches!(r, attr::ReprTransparent))
+ });
+ if !is_transparent {
+ cx.dcx()
+ .struct_span_err(
+ span,
+ "`SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`",
+ )
+ .emit();
+ return;
+ }
+ if !matches!(
+ struct_data,
+ VariantData::Struct { fields, recovered: _ } | VariantData::Tuple(fields, _)
+ if !fields.is_empty())
+ {
+ cx.dcx()
+ .struct_span_err(
+ span,
+ "`SmartPointer` can only be derived on `struct`s with at least one field",
+ )
+ .emit();
+ return;
+ }
(aitem.ident, g)
} else {
- cx.dcx().struct_span_err(span, "`SmartPointer` can only be derived on `struct`s").emit();
+ cx.dcx()
+ .struct_span_err(
+ span,
+ "`SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`",
+ )
+ .emit();
return;
};