Skip to content
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4339,6 +4339,7 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_hashes",
"rustc_hir",
"rustc_index",
"rustc_infer",
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_builtin_macros/src/deriving/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ fn cs_clone_simple(
&[sym::clone, sym::AssertParamIsCopy],
);
} else {
match substr {
match substr.fields {
StaticStruct(vdata, ..) => {
process_variant(vdata);
}
Expand All @@ -169,18 +169,17 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> Blo
cx.expr_call_global(field.span, fn_path.clone(), args)
};

let self_ident = Ident::new(kw::SelfUpper, trait_span);
let ctor_path;
let all_fields;
let vdata;
match substr {
match substr.fields {
Struct(vdata_, af) => {
ctor_path = cx.path(trait_span, vec![self_ident]);
ctor_path = cx.path(trait_span, vec![substr.type_ident]);
all_fields = af;
vdata = vdata_;
}
EnumMatching(.., variant, af) => {
ctor_path = cx.path(trait_span, vec![self_ident, variant.ident]);
ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]);
all_fields = af;
vdata = &variant.data;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn show_substructure(
return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new())));
}

let (ident, vdata, fields) = match substr {
let (ident, vdata, fields) = match substr.fields {
Struct(vdata, fields) => (type_ident, vdata, fields),
EnumMatching(v, fields) => (v.ident, &v.data, fields),
AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, type_ident),
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_builtin_macros/src/deriving/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ pub(crate) fn expand_deriving_default(
attributes: thin_vec![cx.attr_word(sym::inline, span)],
fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
combine_substructure: combine_substructure(|cx, trait_span, substr| {
match substr {
match substr.fields {
StaticStruct(variant_data) => {
default_struct_substructure(cx, trait_span, variant_data)
default_struct_substructure(cx, trait_span, variant_data, substr.type_ident)
}
StaticEnum(enum_def) => {
default_enum_substructure(cx, trait_span, enum_def, item.span)
Expand Down Expand Up @@ -67,15 +67,16 @@ fn default_struct_substructure(
cx: &ExtCtxt<'_>,
trait_span: Span,
variant_data: &VariantData,
type_ident: Ident,
) -> BlockOrExpr {
let expr = match variant_data {
VariantData::Unit(_) => cx.expr_ident(trait_span, Ident::new(kw::SelfUpper, trait_span)),
VariantData::Unit(_) => cx.expr_ident(trait_span, type_ident),
VariantData::Tuple(fields, _) => {
let exprs = fields
.iter()
.map(|field| default_call(cx, field.span.with_ctxt(trait_span.ctxt())))
.collect();
cx.expr_call_ident(trait_span, Ident::new(kw::SelfUpper, trait_span), exprs)
cx.expr_call_ident(trait_span, type_ident, exprs)
}
VariantData::Struct { fields, .. } => {
let default_fields = fields
Expand All @@ -95,7 +96,7 @@ fn default_struct_substructure(
cx.field_imm(span, field.ident.unwrap(), value)
})
.collect();
cx.expr_struct_ident(trait_span, Ident::new(kw::SelfUpper, trait_span), default_fields)
cx.expr_struct_ident(trait_span, type_ident, default_fields)
}
};
BlockOrExpr::new_expr(expr)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'
}
};

match substr {
match substr.fields {
StaticStruct(vdata, ..) => {
process_variant(vdata);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub(crate) fn expand_deriving_from(
};

let self_kw = Ident::new(kw::SelfUpper, span);
let expr: Box<ast::Expr> = match substructure {
let expr: Box<ast::Expr> = match substructure.fields {
StaticStruct(variant) => match variant {
// Self { field: value }
VariantData::Struct { .. } => cx.expr_struct_ident(
Expand Down
77 changes: 60 additions & 17 deletions compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
use std::ops::Not;
use std::vec;

pub(crate) use Substructure::*;
pub(crate) use SubstructureFields::*;
pub(crate) use rustc_ast as ast;
use rustc_ast::token::{IdentKind, LitKind, Token, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree};
Expand Down Expand Up @@ -281,8 +281,16 @@ pub(crate) struct FieldInfo {
pub maybe_scalar: bool,
}

pub(crate) struct Substructure<'a> {
pub fields: SubstructureFields<'a>,
// FIXME: this is currently required to avoid issues with attribute macros after derives,
// such as https://github.com/rust-lang/rust/issues/163800.
// Ideally we would just use `Self` instead.
pub type_ident: Ident,
}

/// A summary of the possible sets of fields.
pub(crate) enum Substructure<'a> {
pub(crate) enum SubstructureFields<'a> {
/// A non-static method where `Self` is a struct.
Struct(&'a ast::VariantData, Vec<FieldInfo>),

Expand Down Expand Up @@ -474,9 +482,15 @@ impl<'a> TraitDef<'a> {
let fields = struct_def.fields().iter();
let methods = self.methods.iter().filter_map(|method_def| {
let body = if from_scratch || method_def.is_static() {
method_def.call_substructure_method(cx, span, StaticStruct(struct_def))
method_def.call_substructure_method(
cx,
span,
StaticStruct(struct_def),
*ident,
)
} else {
method_def.expand_struct_method_body(cx, span, struct_def, is_packed)
method_def
.expand_struct_method_body(cx, span, struct_def, is_packed, *ident)
};

method_def.create_method(cx, span, body)
Expand All @@ -494,9 +508,9 @@ impl<'a> TraitDef<'a> {
let fields = enum_def.variants.iter().flat_map(|variant| variant.data.fields());
let methods = self.methods.iter().filter_map(|method_def| {
let body = if from_scratch || method_def.is_static() {
method_def.call_substructure_method(cx, span, StaticEnum(enum_def))
method_def.call_substructure_method(cx, span, StaticEnum(enum_def), *ident)
} else {
method_def.expand_enum_method_body(cx, span, enum_def)
method_def.expand_enum_method_body(cx, span, enum_def, *ident)
};

method_def.create_method(cx, span, body)
Expand Down Expand Up @@ -778,9 +792,10 @@ impl<'a> MethodDef<'a> {
&self,
cx: &ExtCtxt<'_>,
span: Span,
substructure: Substructure<'_>,
fields: SubstructureFields<'_>,
type_ident: Ident,
) -> BlockOrExpr {
(self.combine_substructure)(cx, span, substructure)
(self.combine_substructure)(cx, span, Substructure { fields, type_ident })
}

fn is_static(&self) -> bool {
Expand Down Expand Up @@ -906,12 +921,13 @@ impl<'a> MethodDef<'a> {
span: Span,
struct_def: &'b VariantData,
is_packed: bool,
type_ident: Ident,
) -> BlockOrExpr {
let selflike_args = self.get_selflike_args(cx, span);

let selflike_fields =
create_struct_field_access_fields(span, cx, &selflike_args, struct_def, is_packed);
self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields))
self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields), type_ident)
}

/// ```
Expand Down Expand Up @@ -954,6 +970,7 @@ impl<'a> MethodDef<'a> {
cx: &ExtCtxt<'_>,
span: Span,
enum_def: &'b EnumDef,
type_ident: Ident,
) -> BlockOrExpr {
let variants = &enum_def.variants;

Expand Down Expand Up @@ -989,17 +1006,32 @@ impl<'a> MethodDef<'a> {
// If the type is fieldless and the trait uses the discriminant and
// there are multiple variants, we need just an operation on
// the discriminant(s).
return self.call_substructure_method(cx, span, EnumDiscr(None));
return self.call_substructure_method(
cx,
span,
EnumDiscr(None),
type_ident,
);
}
FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless => {
return self.call_substructure_method(cx, span, AllFieldlessEnum(enum_def));
return self.call_substructure_method(
cx,
span,
AllFieldlessEnum(enum_def),
type_ident,
);
}
FieldlessVariantsStrategy::Default => (),
}
} else if let [variant] = variants.as_slice() {
// If there is a single variant, we don't need an operation on
// the discriminant(s). Just use the most degenerate result.
return self.call_substructure_method(cx, span, EnumMatching(variant, Vec::new()));
return self.call_substructure_method(
cx,
span,
EnumMatching(variant, Vec::new()),
type_ident,
);
}
}

Expand Down Expand Up @@ -1039,8 +1071,9 @@ impl<'a> MethodDef<'a> {
// Self arg, assuming all are instances of VariantK.
// Build up code associated with such a case.
let substructure = EnumMatching(variant, fields);
let arm_expr =
self.call_substructure_method(cx, span, substructure).into_expr(cx, span);
let arm_expr = self
.call_substructure_method(cx, span, substructure, type_ident)
.into_expr(cx, span);

cx.arm(span, single_pat, arm_expr)
})
Expand All @@ -1052,8 +1085,13 @@ impl<'a> MethodDef<'a> {
Some(v) if unify_fieldless_variants => {
// We need a default case that handles all the fieldless variants.
Some(
self.call_substructure_method(cx, span, EnumMatching(v, Vec::new()))
.into_expr(cx, span),
self.call_substructure_method(
cx,
span,
EnumMatching(v, Vec::new()),
type_ident,
)
.into_expr(cx, span),
)
}
_ if variants.len() > 1 && selflike_args.len() > 1 => {
Expand Down Expand Up @@ -1090,7 +1128,12 @@ impl<'a> MethodDef<'a> {
// is enough.
if unify_fieldless_variants && variants.len() > 1 {
// Combine a discriminant check with the match.
self.call_substructure_method(cx, span, EnumDiscr(Some(get_match_expr(selflike_args))))
self.call_substructure_method(
cx,
span,
EnumDiscr(Some(get_match_expr(selflike_args))),
type_ident,
)
} else {
BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args)))
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn hash_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) ->
cx.stmt_expr(expr)
};

let (stmts, match_expr) = match substr {
let (stmts, match_expr) = match substr.fields {
Struct(_, fields) | EnumMatching(.., fields) => {
let stmts =
fields.into_iter().map(|field| call_hash(field.span, field.self_expr)).collect();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/partial_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fn get_substructure_equality_expr(
span: Span,
substructure: Substructure<'_>,
) -> BlockOrExpr {
BlockOrExpr::new_expr(match substructure {
BlockOrExpr::new_expr(match substructure.fields {
EnumMatching(.., fields) | Struct(.., fields) => {
let combine = move |acc, field: &FieldInfo| {
let rhs = field
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/partial_ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ pub(crate) fn cmp_body(
}
};

match substructure {
match substructure.fields {
EnumMatching(.., all_fields) | Struct(_, all_fields) => {
let op = |old, field: FieldInfo| {
// The basic case: a field expression for one or more selflike args. E.g.
Expand Down
13 changes: 5 additions & 8 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ use crate::back::profiling::{
};
use crate::builder::SBuilder;
use crate::builder::gpu_offload::scalar_width;
use crate::common::AsCCharPtr;
use crate::context::SimpleCx;
use crate::diagnostics::{
CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, ParseTargetMachineConfig,
Expand Down Expand Up @@ -548,9 +547,7 @@ pub(crate) unsafe fn llvm_optimize(
} else {
None
};
let passes_after_enzyme_ptr =
passes_after_enzyme.map_or(std::ptr::null(), |s| s.as_c_char_ptr());
let passes_after_enzyme_len = passes_after_enzyme.map_or(0, |s| s.len());

let merge_functions;
let unroll_loops;
let vectorize_slp;
Expand Down Expand Up @@ -788,11 +785,11 @@ pub(crate) unsafe fn llvm_optimize(
llvm_selfprofiler,
selfprofile_before_pass_callback,
selfprofile_after_pass_callback,
passes_after_enzyme_ptr,
passes_after_enzyme_len,
extra_passes.as_c_char_ptr(),
passes_after_enzyme.map(|s| s.as_ptr()).unwrap_or(std::ptr::null()),
passes_after_enzyme.map(|s| s.len()).unwrap_or(0),
extra_passes.as_ptr(),
extra_passes.len(),
llvm_plugins.as_c_char_ptr(),
llvm_plugins.as_ptr(),
llvm_plugins.len(),
)
};
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use super::CodegenUnitDebugContext;
use super::namespace::mangled_name_of_instance;
use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name};
use super::utils::{DIB, debug_context, get_namespace_for_item, is_node_local_to_unit};
use crate::common::{AsCCharPtr, CodegenCx};
use crate::common::CodegenCx;
use crate::debuginfo::metadata::type_map::build_type_with_children;
use crate::debuginfo::utils::{WidePtrKind, create_DIArray, wide_pointer_kind};
use crate::debuginfo::{DIBuilderExt, dwarf_const};
Expand Down Expand Up @@ -651,14 +651,14 @@ fn create_file<'ll>(
unsafe {
llvm::LLVMRustDIBuilderCreateFile(
builder,
file_name.as_c_char_ptr(),
file_name.as_ptr(),
file_name.len(),
directory.as_c_char_ptr(),
directory.as_ptr(),
directory.len(),
hash_kind,
hash_value.as_c_char_ptr(),
hash_value.as_ptr(),
hash_value.len(),
source.map_or(ptr::null(), |x| x.as_c_char_ptr()),
source.map_or(ptr::null(), |x| x.as_ptr()),
source.map_or(0, |x| x.len()),
)
}
Expand Down Expand Up @@ -949,20 +949,21 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
llvm::ChecksumKind::None,
None,
);
let flags = c"";

let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
debug_context.builder.as_ref(),
dwarf_const::DW_LANG_Rust,
compile_unit_file,
producer.as_c_char_ptr(),
producer.as_ptr(),
producer.len(),
tcx.sess.opts.optimize != config::OptLevel::No,
c"".as_ptr(),
flags.as_ptr(),
0,
// NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead
// put the path supplied to `MCSplitDwarfFile` into the debug info of the final
// output(s).
split_name.as_c_char_ptr(),
split_name.as_ptr(),
split_name.len(),
kind,
0,
Expand Down
Loading
Loading