Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Be stricter about combining repr(packed) with derive. #99197

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions compiler/rustc_builtin_macros/src/deriving/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ fn cs_clone_simple(
),
}
}
BlockOrExpr::new_mixed(stmts, cx.expr_deref(trait_span, cx.expr_self(trait_span)))
BlockOrExpr::new_mixed(stmts, Some(cx.expr_deref(trait_span, cx.expr_self(trait_span))))
}

fn cs_clone(
Expand All @@ -161,7 +161,7 @@ fn cs_clone(
let all_fields;
let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]);
let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo| {
let args = vec![cx.expr_addr_of(field.span, field.self_expr.clone())];
let args = vec![field.self_expr.clone()];
cx.expr_call_global(field.span, fn_path.clone(), args)
};

Expand All @@ -177,9 +177,7 @@ fn cs_clone(
all_fields = af;
vdata = &variant.data;
}
EnumNonMatchingCollapsed(..) => {
cx.span_bug(trait_span, &format!("non-matching enum variants in `derive({})`", name,))
}
EnumTag(..) => cx.span_bug(trait_span, &format!("enum tags in `derive({})`", name,)),
StaticEnum(..) | StaticStruct(..) => {
cx.span_bug(trait_span, &format!("associated function in `derive({})`", name))
}
Expand Down
15 changes: 1 addition & 14 deletions compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
};
let args = vec![
cx.expr_addr_of(field.span, field.self_expr.clone()),
cx.expr_addr_of(field.span, other_expr.clone()),
];
let args = vec![field.self_expr.clone(), other_expr.clone()];
cx.expr_call_global(field.span, cmp_path.clone(), args)
}
CsFold::Combine(span, expr1, expr2) => {
Expand All @@ -76,16 +73,6 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
}
CsFold::Fieldless => cx.expr_path(equal_path.clone()),
CsFold::EnumNonMatching(span, tag_tuple) => {
if tag_tuple.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`")
} else {
let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
let fn_cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
cx.expr_call_global(span, fn_cmp_path, vec![lft, rgt])
}
}
},
);
BlockOrExpr::new_expr(expr)
Expand Down
20 changes: 17 additions & 3 deletions compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_local, path_std};

use rustc_ast::{BinOpKind, MetaItem};
use rustc_ast::ptr::P;
use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
Expand Down Expand Up @@ -32,11 +33,24 @@ pub fn expand_deriving_partial_eq(
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.span_bug(field.span, "not exactly 2 arguments in `derive(PartialEq)`");
};
cx.expr_binary(field.span, op, field.self_expr.clone(), other_expr.clone())

// We received `&T` arguments. Convert them to `T` by
// stripping `&` or adding `*`. This isn't necessary for
// type checking, but it results in much better error
// messages if something goes wrong.
let convert = |expr: &P<Expr>| {
if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) =
&expr.kind
{
inner.clone()
} else {
cx.expr_deref(field.span, expr.clone())
}
};
cx.expr_binary(field.span, op, convert(&field.self_expr), convert(other_expr))
}
CsFold::Combine(span, expr1, expr2) => cx.expr_binary(span, combiner, expr1, expr2),
CsFold::Fieldless => cx.expr_bool(span, base),
CsFold::EnumNonMatching(span, _tag_tuple) => cx.expr_bool(span, !base),
},
);
BlockOrExpr::new_expr(expr)
Expand Down
16 changes: 1 addition & 15 deletions compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
};
let args = vec![
cx.expr_addr_of(field.span, field.self_expr.clone()),
cx.expr_addr_of(field.span, other_expr.clone()),
];
let args = vec![field.self_expr.clone(), other_expr.clone()];
cx.expr_call_global(field.span, partial_cmp_path.clone(), args)
}
CsFold::Combine(span, expr1, expr2) => {
Expand All @@ -85,17 +82,6 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
}
CsFold::Fieldless => cx.expr_some(span, cx.expr_path(equal_path.clone())),
CsFold::EnumNonMatching(span, tag_tuple) => {
if tag_tuple.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
} else {
let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
let fn_partial_cmp_path =
cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]);
cx.expr_call_global(span, fn_partial_cmp_path, vec![lft, rgt])
}
}
},
);
BlockOrExpr::new_expr(expr)
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
let (ident, vdata, fields) = match substr.fields {
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
EnumMatching(_, _, v, fields) => (v.ident, &v.data, fields),
EnumNonMatchingCollapsed(..) | StaticStruct(..) | StaticEnum(..) => {
EnumTag(..) | StaticStruct(..) | StaticEnum(..) => {
cx.span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
}
};
Expand Down Expand Up @@ -95,9 +95,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
);
args.push(name);
}
// Use double indirection to make sure this works for unsized types
// Use an extra indirection to make sure this works for unsized types.
let field = cx.expr_addr_of(field.span, field.self_expr.clone());
let field = cx.expr_addr_of(field.span, field);
args.push(field);
}
let expr = cx.expr_call_global(span, fn_path_debug, args);
Expand All @@ -115,9 +114,9 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
));
}

// Use double indirection to make sure this works for unsized types
let value_ref = cx.expr_addr_of(field.span, field.self_expr.clone());
value_exprs.push(cx.expr_addr_of(field.span, value_ref));
// Use an extra indirection to make sure this works for unsized types.
let field = cx.expr_addr_of(field.span, field.self_expr.clone());
value_exprs.push(field);
}

// `let names: &'static _ = &["field1", "field2"];`
Expand Down Expand Up @@ -177,6 +176,6 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
stmts.push(names_let.unwrap());
}
stmts.push(values_let);
BlockOrExpr::new_mixed(stmts, expr)
BlockOrExpr::new_mixed(stmts, Some(expr))
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/encodable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ fn encodable_substructure(
fn_emit_enum_path,
vec![encoder, cx.expr_str(trait_span, substr.type_ident.name), blk],
);
BlockOrExpr::new_mixed(vec![me], expr)
BlockOrExpr::new_mixed(vec![me], Some(expr))
}

_ => cx.bug("expected Struct or EnumMatching in derive(Encodable)"),
Expand Down
Loading