Skip to content
Merged
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
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 @@ -794,9 +808,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 @@ -922,12 +937,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 @@ -970,6 +986,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 @@ -1005,17 +1022,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 @@ -1055,8 +1087,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 @@ -1068,8 +1101,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 @@ -1106,7 +1144,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
19 changes: 11 additions & 8 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span,
MethodCallOnDivergingInferenceVariable,
);
let root_ty = Ty::new_var(self.tcx, ty_id);
self.demand_eqtype(span, root_ty, self.tcx.types.never);
self.demand_eqtype(span, ty, self.tcx.types.never);
} else {
let guar = match *ty.kind() {
_ if let Some(guar) = self.tainted_by_errors() => guar,
Expand Down Expand Up @@ -2382,18 +2381,22 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
}

// They are all the same, so if any of them is ambiguous, we report the pick as ambiguous.
let is_ambiguously_imported = probes.iter().any(|(p, _)| match p.kind {
TraitCandidate { is_ambiguously_imported, .. } => is_ambiguously_imported,
_ => false,
// We try and find the ambiguous candidate in order to report the pick as ambiguous.
let ambiguous_candidate = probes.iter().find_map(|(p, _)| match p.kind {
TraitCandidate { is_ambiguously_imported: true, .. } => Some(p),
_ => None,
});

// If there isn't any, then we just use the first probe.
let (is_ambiguously_imported, candidate) =
ambiguous_candidate.map(|c| (true, *c)).unwrap_or_else(|| (false, probes[0].0));

// FIXME: check the return type here somehow.
// If so, just use this trait and call it a day.
Some(Pick {
item: probes[0].0.item,
item: candidate.item,
kind: TraitPick { is_ambiguously_imported },
import_ids: probes[0].0.import_ids,
import_ids: candidate.import_ids,
autoderefs: 0,
autoref_or_ptr_adjustment: None,
self_ty,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3024,7 +3024,7 @@ declare_lint! {
"trailing semicolon in macro body used as expression",
@future_incompatible = FutureIncompatibleInfo {
reason: fcw!(FutureReleaseError #79813),
report_in_deps: true,
report_in_deps: false,
};
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_target/src/callconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,9 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
// Only integers have signedness
if let BackendRepr::Scalar(scalar) = self.layout.backend_repr
&& let Primitive::Int(i, signed) = scalar.primitive()
&& i.size().bits() < bits
// bools are i1 but their primitive is i8. Unlike other types,
// bools can be extended to their primitive size.
&& (i.size().bits() < bits || self.layout.backend_repr.is_bool())
&& let PassMode::Direct(ref mut attrs) = self.mode
{
if signed {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_target/src/callconv/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ where
} else if is_arg || cx.target_spec().is_like_darwin {
arg.extend_integer_width_to(32);
}
// The x86_64 psABI requires bools to be zero-extended to 8-bits, with high bits unspecified.
// zeroext i1 has this behavior in the LLVM X86 backend.
if !is_arg && arg.layout.backend_repr.is_bool() {
arg.extend_integer_width_to(8);
}
}
}
};
Expand Down
10 changes: 9 additions & 1 deletion library/std/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,14 @@ use crate::{hint, mem, ptr};
/// }
/// ```
///
/// Note that this does *not* mean you can deallocate allocations from [`Global`]
/// with [`System`] (or vice-versa), as the [`Global`] allocator is special in
/// the compiler. For more details, see the relevant docs about
/// [`#[global_allocator]`][global_allocator].
///
/// You can also define your own wrapper around `System` if you'd like, such as
/// keeping track of the number of all bytes allocated:
/// keeping track of the number of all bytes allocated (note that due to
/// optimizations, this may not be accurate):
///
/// ```rust
/// use std::alloc::{System, GlobalAlloc, Layout};
Expand Down Expand Up @@ -140,6 +146,8 @@ use crate::{hint, mem, ptr};
/// global allocator has been selected for a Rust program. For example if a Rust
/// program opts in to using jemalloc as the global allocator, `System` will
/// still allocate memory using `malloc` and `HeapAlloc`.
///
/// [global_allocator]: GlobalAlloc#the-global_allocator-attribute
#[stable(feature = "alloc_system_type", since = "1.28.0")]
#[derive(Copy, Debug)]
#[derive_const(Clone, Default)]
Expand Down
Loading
Loading