summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_builtin_macros
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /compiler/rustc_builtin_macros
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_builtin_macros')
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/derive.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs61
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs90
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs3
23 files changed, 155 insertions, 73 deletions
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index 95e38e4b0..dcf500ddb 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -32,7 +32,7 @@ pub fn expand(
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else {
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "alloc_error_handler must be a function");
- return vec![orig_item.clone()];
+ return vec![orig_item];
};
// Generate a bunch of new items using the AllocFnFactory
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 900c44274..925392b50 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -352,7 +352,7 @@ pub fn parse_asm_args<'a>(
///
/// This function must be called immediately after the option token is parsed.
/// Otherwise, the suggestion will be incorrect.
-fn err_duplicate_option<'a>(p: &mut Parser<'a>, symbol: Symbol, span: Span) {
+fn err_duplicate_option(p: &mut Parser<'_>, symbol: Symbol, span: Span) {
let mut err = p
.sess
.span_diagnostic
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index e2d71825d..7da9bdc38 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -4,14 +4,12 @@ use rustc_expand::base::{self, DummyResult};
use rustc_session::errors::report_lit_error;
use rustc_span::symbol::Symbol;
-use std::string::String;
-
pub fn expand_concat(
cx: &mut base::ExtCtxt<'_>,
sp: rustc_span::Span,
tts: TokenStream,
) -> Box<dyn base::MacResult + 'static> {
- let Some(es) = base::get_exprs_from_tts(cx, sp, tts) else {
+ let Some(es) = base::get_exprs_from_tts(cx, tts) else {
return DummyResult::any(sp);
};
let mut accumulator = String::new();
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index d1124145d..4f1a7d709 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -69,7 +69,7 @@ fn invalid_type_err(
Ok(ast::LitKind::Int(_, _)) => {
cx.span_err(span, "numeric literal is not a `u8`");
}
- Ok(ast::LitKind::ByteStr(_) | ast::LitKind::Byte(_)) => unreachable!(),
+ Ok(ast::LitKind::ByteStr(..) | ast::LitKind::Byte(_)) => unreachable!(),
Err(err) => {
report_lit_error(&cx.sess.parse_sess, err, token_lit, span);
}
@@ -97,7 +97,7 @@ fn handle_array_element(
)) if val <= u8::MAX.into() => Some(val as u8),
Ok(ast::LitKind::Byte(val)) => Some(val),
- Ok(ast::LitKind::ByteStr(_)) => {
+ Ok(ast::LitKind::ByteStr(..)) => {
if !*has_errors {
cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
.note("byte strings are treated as arrays of bytes")
@@ -137,7 +137,7 @@ pub fn expand_concat_bytes(
sp: rustc_span::Span,
tts: TokenStream,
) -> Box<dyn base::MacResult + 'static> {
- let Some(es) = base::get_exprs_from_tts(cx, sp, tts) else {
+ let Some(es) = base::get_exprs_from_tts(cx, tts) else {
return DummyResult::any(sp);
};
let mut accumulator = Vec::new();
@@ -174,7 +174,7 @@ pub fn expand_concat_bytes(
Ok(ast::LitKind::Byte(val)) => {
accumulator.push(val);
}
- Ok(ast::LitKind::ByteStr(ref bytes)) => {
+ Ok(ast::LitKind::ByteStr(ref bytes, _)) => {
accumulator.extend_from_slice(&bytes);
}
_ => {
@@ -196,7 +196,7 @@ pub fn expand_concat_bytes(
}
}
if !missing_literals.is_empty() {
- let mut err = cx.struct_span_err(missing_literals.clone(), "expected a byte literal");
+ let mut err = cx.struct_span_err(missing_literals, "expected a byte literal");
err.note("only byte literals (like `b\"foo\"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`");
err.emit();
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index fa5a45730..2a8dc0284 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -1,7 +1,7 @@
use crate::cfg_eval::cfg_eval;
use rustc_ast as ast;
-use rustc_ast::{token, GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
+use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
use rustc_errors::{struct_span_err, Applicability};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
use rustc_feature::AttributeTemplate;
@@ -130,9 +130,11 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
}
fn report_unexpected_meta_item_lit(sess: &Session, lit: &ast::MetaItemLit) {
- let help_msg = match lit.token_lit.kind {
- token::Str if rustc_lexer::is_ident(lit.token_lit.symbol.as_str()) => {
- format!("try using `#[derive({})]`", lit.token_lit.symbol)
+ let help_msg = match lit.kind {
+ ast::LitKind::Str(_, ast::StrStyle::Cooked)
+ if rustc_lexer::is_ident(lit.symbol.as_str()) =>
+ {
+ format!("try using `#[derive({})]`", lit.symbol)
}
_ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
};
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index d59b3b8c8..ef5a75f42 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -20,7 +20,7 @@ pub fn expand_deriving_clone(
// some additional `AssertParamIsClone` assertions.
//
// We can use the simple form if either of the following are true.
- // - The type derives Copy and there are no generic parameters. (If we
+ // - The type derives Copy and there are no generic parameters. (If we
// used the simple form with generics, we'd have to bound the generics
// with Clone + Copy, and then there'd be no Clone impl at all if the
// user fills in something that is Clone but not Copy. After
@@ -82,7 +82,7 @@ pub fn expand_deriving_clone(
nonself_args: Vec::new(),
ret_ty: Self_,
attributes: attrs,
- unify_fieldless_variants: false,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
combine_substructure: substructure,
}],
associated_types: Vec::new(),
@@ -177,7 +177,9 @@ fn cs_clone(
all_fields = af;
vdata = &variant.data;
}
- EnumTag(..) => cx.span_bug(trait_span, &format!("enum tags in `derive({})`", name,)),
+ EnumTag(..) | AllFieldlessEnum(..) => {
+ cx.span_bug(trait_span, &format!("enum tags in `derive({})`", name,))
+ }
StaticEnum(..) | StaticStruct(..) => {
cx.span_bug(trait_span, &format!("associated function in `derive({})`", name))
}
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index f861d47ed..3e994f037 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -36,7 +36,7 @@ pub fn expand_deriving_eq(
nonself_args: vec![],
ret_ty: Unit,
attributes: attrs,
- unify_fieldless_variants: true,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
cs_total_eq_assert(a, b, c)
})),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 96d18c7af..a926fca4e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -29,7 +29,7 @@ pub fn expand_deriving_ord(
nonself_args: vec![(self_ref(), sym::other)],
ret_ty: Path(path_std!(cmp::Ordering)),
attributes: attrs,
- unify_fieldless_variants: true,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))),
}],
associated_types: Vec::new(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 7f95551fc..9051fe0b2 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -76,7 +76,7 @@ pub fn expand_deriving_partial_eq(
nonself_args: vec![(self_ref(), sym::other)],
ret_ty: Path(path_local!(bool)),
attributes: attrs,
- unify_fieldless_variants: true,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
combine_substructure: combine_substructure(Box::new(|a, b, c| cs_eq(a, b, c))),
}];
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 5c4e5b7f8..c9dc89212 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -28,7 +28,7 @@ pub fn expand_deriving_partial_ord(
nonself_args: vec![(self_ref(), sym::other)],
ret_ty,
attributes: attrs,
- unify_fieldless_variants: true,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
cs_partial_cmp(cx, span, substr)
})),
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index 544d971b2..e0f487e86 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -2,6 +2,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::path_std;
+use ast::EnumDef;
use rustc_ast::{self as ast, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol};
@@ -31,7 +32,8 @@ pub fn expand_deriving_debug(
nonself_args: vec![(fmtr, sym::f)],
ret_ty: Path(path_std!(fmt::Result)),
attributes: ast::AttrVec::new(),
- unify_fieldless_variants: false,
+ fieldless_variants_strategy:
+ FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
show_substructure(a, b, c)
})),
@@ -43,16 +45,18 @@ pub fn expand_deriving_debug(
}
fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
+ // We want to make sure we have the ctxt set so that we can use unstable methods
+ let span = cx.with_def_site_ctxt(span);
+
let (ident, vdata, fields) = match substr.fields {
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
EnumMatching(_, _, v, fields) => (v.ident, &v.data, fields),
+ AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, substr),
EnumTag(..) | StaticStruct(..) | StaticEnum(..) => {
cx.span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
}
};
- // We want to make sure we have the ctxt set so that we can use unstable methods
- let span = cx.with_def_site_ctxt(span);
let name = cx.expr_str(span, ident.name);
let fmt = substr.nonselflike_args[0].clone();
@@ -117,8 +121,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
// `let names: &'static _ = &["field1", "field2"];`
let names_let = if is_struct {
let lt_static = Some(cx.lifetime_static(span));
- let ty_static_ref =
- cx.ty_rptr(span, cx.ty_infer(span), lt_static, ast::Mutability::Not);
+ let ty_static_ref = cx.ty_ref(span, cx.ty_infer(span), lt_static, ast::Mutability::Not);
Some(cx.stmt_let_ty(
span,
false,
@@ -138,13 +141,13 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
);
let ty_slice = cx.ty(
span,
- ast::TyKind::Slice(cx.ty_rptr(span, ty_dyn_debug, None, ast::Mutability::Not)),
+ ast::TyKind::Slice(cx.ty_ref(span, ty_dyn_debug, None, ast::Mutability::Not)),
);
let values_let = cx.stmt_let_ty(
span,
false,
Ident::new(sym::values, span),
- Some(cx.ty_rptr(span, ty_slice, None, ast::Mutability::Not)),
+ Some(cx.ty_ref(span, ty_slice, None, ast::Mutability::Not)),
cx.expr_array_ref(span, value_exprs),
);
@@ -174,3 +177,47 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
BlockOrExpr::new_mixed(stmts, Some(expr))
}
}
+
+/// Special case for enums with no fields. Builds:
+/// ```text
+/// impl ::core::fmt::Debug for A {
+/// fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+/// ::core::fmt::Formatter::write_str(f,
+/// match self {
+/// A::A => "A",
+/// A::B() => "B",
+/// A::C {} => "C",
+/// })
+/// }
+/// }
+/// ```
+fn show_fieldless_enum(
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ def: &EnumDef,
+ substr: &Substructure<'_>,
+) -> BlockOrExpr {
+ let fmt = substr.nonselflike_args[0].clone();
+ let arms = def
+ .variants
+ .iter()
+ .map(|v| {
+ let variant_path = cx.path(span, vec![substr.type_ident, v.ident]);
+ let pat = match &v.data {
+ ast::VariantData::Tuple(fields, _) => {
+ debug_assert!(fields.is_empty());
+ cx.pat_tuple_struct(span, variant_path, vec![])
+ }
+ ast::VariantData::Struct(fields, _) => {
+ debug_assert!(fields.is_empty());
+ cx.pat_struct(span, variant_path, vec![])
+ }
+ ast::VariantData::Unit(_) => cx.pat_path(span, variant_path),
+ };
+ cx.arm(span, pat, cx.expr_str(span, v.ident.name))
+ })
+ .collect::<Vec<_>>();
+ let name = cx.expr_match(span, cx.expr_self(span), arms);
+ let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
+ BlockOrExpr::new_expr(cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]))
+}
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index 62af02c2b..5f9519dad 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -49,7 +49,7 @@ pub fn expand_deriving_rustc_decodable(
PathKind::Std,
)),
attributes: ast::AttrVec::new(),
- unify_fieldless_variants: false,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
decodable_substructure(a, b, c, krate)
})),
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index eb66c4a69..182707472 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -34,7 +34,7 @@ pub fn expand_deriving_default(
nonself_args: Vec::new(),
ret_ty: Self_,
attributes: attrs,
- unify_fieldless_variants: false,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
combine_substructure: combine_substructure(Box::new(|cx, trait_span, substr| {
match substr.fields {
StaticStruct(_, fields) => {
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index 68bc0ff2e..2afeed927 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -133,7 +133,7 @@ pub fn expand_deriving_rustc_encodable(
PathKind::Std,
)),
attributes: AttrVec::new(),
- unify_fieldless_variants: false,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
encodable_substructure(a, b, c, krate)
})),
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index beac591bf..17b7ac0eb 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -222,14 +222,27 @@ pub struct MethodDef<'a> {
pub attributes: ast::AttrVec,
- /// Can we combine fieldless variants for enums into a single match arm?
- /// If true, indicates that the trait operation uses the enum tag in some
- /// way.
- pub unify_fieldless_variants: bool,
+ pub fieldless_variants_strategy: FieldlessVariantsStrategy,
pub combine_substructure: RefCell<CombineSubstructureFunc<'a>>,
}
+/// How to handle fieldless enum variants.
+#[derive(PartialEq)]
+pub enum FieldlessVariantsStrategy {
+ /// Combine fieldless variants into a single match arm.
+ /// This assumes that relevant information has been handled
+ /// by looking at the enum's discriminant.
+ Unify,
+ /// Don't do anything special about fieldless variants. They are
+ /// handled like any other variant.
+ Default,
+ /// If all variants of the enum are fieldless, expand the special
+ /// `AllFieldLessEnum` substructure, so that the entire enum can be handled
+ /// at once.
+ SpecializeIfAllVariantsFieldless,
+}
+
/// All the data about the data structure/method being derived upon.
pub struct Substructure<'a> {
/// ident of self
@@ -264,9 +277,14 @@ pub enum StaticFields {
/// A summary of the possible sets of fields.
pub enum SubstructureFields<'a> {
- /// A non-static method with `Self` is a struct.
+ /// A non-static method where `Self` is a struct.
Struct(&'a ast::VariantData, Vec<FieldInfo>),
+ /// A non-static method handling the entire enum at once
+ /// (after it has been determined that none of the enum
+ /// variants has any fields).
+ AllFieldlessEnum(&'a ast::EnumDef),
+
/// Matching variants of the enum: variant index, variant count, ast::Variant,
/// fields: the field name is only non-`None` in the case of a struct
/// variant.
@@ -1086,8 +1104,8 @@ impl<'a> MethodDef<'a> {
/// ```
/// Creates a tag check combined with a match for a tuple of all
/// `selflike_args`, with an arm for each variant with fields, possibly an
- /// arm for each fieldless variant (if `!unify_fieldless_variants` is not
- /// true), and possibly a default arm.
+ /// arm for each fieldless variant (if `unify_fieldless_variants` is not
+ /// `Unify`), and possibly a default arm.
fn expand_enum_method_body<'b>(
&self,
cx: &mut ExtCtxt<'_>,
@@ -1101,7 +1119,8 @@ impl<'a> MethodDef<'a> {
let variants = &enum_def.variants;
// Traits that unify fieldless variants always use the tag(s).
- let uses_tags = self.unify_fieldless_variants;
+ let unify_fieldless_variants =
+ self.fieldless_variants_strategy == FieldlessVariantsStrategy::Unify;
// There is no sensible code to be generated for *any* deriving on a
// zero-variant enum. So we just generate a failing expression.
@@ -1161,23 +1180,35 @@ impl<'a> MethodDef<'a> {
// match is necessary.
let all_fieldless = variants.iter().all(|v| v.data.fields().is_empty());
if all_fieldless {
- if uses_tags && variants.len() > 1 {
- // If the type is fieldless and the trait uses the tag and
- // there are multiple variants, we need just an operation on
- // the tag(s).
- let (tag_field, mut tag_let_stmts) = get_tag_pieces(cx);
- let mut tag_check = self.call_substructure_method(
- cx,
- trait_,
- type_ident,
- nonselflike_args,
- &EnumTag(tag_field, None),
- );
- tag_let_stmts.append(&mut tag_check.0);
- return BlockOrExpr(tag_let_stmts, tag_check.1);
- }
-
- if variants.len() == 1 {
+ if variants.len() > 1 {
+ match self.fieldless_variants_strategy {
+ FieldlessVariantsStrategy::Unify => {
+ // If the type is fieldless and the trait uses the tag and
+ // there are multiple variants, we need just an operation on
+ // the tag(s).
+ let (tag_field, mut tag_let_stmts) = get_tag_pieces(cx);
+ let mut tag_check = self.call_substructure_method(
+ cx,
+ trait_,
+ type_ident,
+ nonselflike_args,
+ &EnumTag(tag_field, None),
+ );
+ tag_let_stmts.append(&mut tag_check.0);
+ return BlockOrExpr(tag_let_stmts, tag_check.1);
+ }
+ FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless => {
+ return self.call_substructure_method(
+ cx,
+ trait_,
+ type_ident,
+ nonselflike_args,
+ &AllFieldlessEnum(enum_def),
+ );
+ }
+ FieldlessVariantsStrategy::Default => (),
+ }
+ } else if variants.len() == 1 {
// If there is a single variant, we don't need an operation on
// the tag(s). Just use the most degenerate result.
return self.call_substructure_method(
@@ -1187,7 +1218,7 @@ impl<'a> MethodDef<'a> {
nonselflike_args,
&EnumMatching(0, 1, &variants[0], Vec::new()),
);
- };
+ }
}
// These arms are of the form:
@@ -1198,7 +1229,7 @@ impl<'a> MethodDef<'a> {
let mut match_arms: Vec<ast::Arm> = variants
.iter()
.enumerate()
- .filter(|&(_, v)| !(self.unify_fieldless_variants && v.data.fields().is_empty()))
+ .filter(|&(_, v)| !(unify_fieldless_variants && v.data.fields().is_empty()))
.map(|(index, variant)| {
// A single arm has form (&VariantK, &VariantK, ...) => BodyK
// (see "Final wrinkle" note below for why.)
@@ -1249,7 +1280,7 @@ impl<'a> MethodDef<'a> {
// Add a default arm to the match, if necessary.
let first_fieldless = variants.iter().find(|v| v.data.fields().is_empty());
let default = match first_fieldless {
- Some(v) if self.unify_fieldless_variants => {
+ Some(v) if unify_fieldless_variants => {
// We need a default case that handles all the fieldless
// variants. The index and actual variant aren't meaningful in
// this case, so just use dummy values.
@@ -1296,7 +1327,7 @@ impl<'a> MethodDef<'a> {
// If the trait uses the tag and there are multiple variants, we need
// to add a tag check operation before the match. Otherwise, the match
// is enough.
- if uses_tags && variants.len() > 1 {
+ if unify_fieldless_variants && variants.len() > 1 {
let (tag_field, mut tag_let_stmts) = get_tag_pieces(cx);
// Combine a tag check with the match.
@@ -1580,5 +1611,6 @@ where
}
}
StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"),
+ AllFieldlessEnum(..) => cx.span_bug(trait_span, "fieldless enum in `derive`"),
}
}
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index eaa488190..c6f5f5d08 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -97,7 +97,7 @@ impl Ty {
match self {
Ref(ty, mutbl) => {
let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
- cx.ty_rptr(span, raw_ty, None, *mutbl)
+ cx.ty_ref(span, raw_ty, None, *mutbl)
}
Path(p) => p.to_ty(cx, span, self_ty, self_generics),
Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index c136bb714..f8570d8f8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -33,7 +33,7 @@ pub fn expand_deriving_hash(
nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)],
ret_ty: Unit,
attributes: AttrVec::new(),
- unify_fieldless_variants: true,
+ fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
hash_substructure(a, b, c)
})),
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 0b4e545f7..e5a5e6069 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -1,4 +1,4 @@
-// The compiler code necessary to support the env! extension. Eventually this
+// The compiler code necessary to support the env! extension. Eventually this
// should all get sucked into either the compiler syntax extension plugin
// interface.
//
@@ -30,7 +30,7 @@ pub fn expand_option_env<'cx>(
sp,
true,
cx.std_path(&[sym::option, sym::Option, sym::None]),
- vec![GenericArg::Type(cx.ty_rptr(
+ vec![GenericArg::Type(cx.ty_ref(
sp,
cx.ty_ident(sp, Ident::new(sym::str, sp)),
Some(lt),
@@ -52,7 +52,7 @@ pub fn expand_env<'cx>(
sp: Span,
tts: TokenStream,
) -> Box<dyn base::MacResult + 'cx> {
- let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
+ let mut exprs = match get_exprs_from_tts(cx, tts) {
Some(exprs) if exprs.is_empty() => {
cx.span_err(sp, "env! takes 1 or 2 arguments");
return DummyResult::any(sp);
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 8b07c1106..9f4bbbc62 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -333,7 +333,7 @@ pub fn make_format_args(
parse::Piece::String(s) => {
unfinished_literal.push_str(s);
}
- parse::Piece::NextArgument(parse::Argument { position, position_span, format }) => {
+ parse::Piece::NextArgument(box parse::Argument { position, position_span, format }) => {
if !unfinished_literal.is_empty() {
template.push(FormatArgsPiece::Literal(Symbol::intern(&unfinished_literal)));
unfinished_literal.clear();
@@ -583,7 +583,7 @@ fn report_missing_placeholders(
if detect_foreign_fmt {
use super::format_foreign as foreign;
- // The set of foreign substitutions we've explained. This prevents spamming the user
+ // The set of foreign substitutions we've explained. This prevents spamming the user
// with `%d should be written as {}` over and over again.
let mut explained = FxHashSet::default();
@@ -638,7 +638,7 @@ fn report_missing_placeholders(
if show_doc_note {
diag.note(concat!(
stringify!($kind),
- " formatting not supported; see the documentation for `std::fmt`",
+ " formatting is not supported; see the documentation for `std::fmt`",
));
}
if suggestions.len() > 0 {
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index 6f7fc3a95..bd9e903b6 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -253,7 +253,7 @@ pub(crate) mod printf {
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Num {
// The range of these values is technically bounded by `NL_ARGMAX`... but, at least for GNU
- // libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
+ // libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
// is *vanishingly* unlikely that *anyone* is going to try formatting something wider, or
// with more precision, than 32 thousand positions which is so wide it couldn't possibly fit
// on a screen.
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 41531580c..f8761653b 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -35,7 +35,7 @@ pub fn expand(
(item, true, ecx.with_def_site_ctxt(ty.span))
} else {
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
- return vec![orig_item.clone()]
+ return vec![orig_item];
};
// Generate a bunch of new items using the AllocFnFactory
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index ece660cf6..21c8caa65 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -262,6 +262,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
// use proc_macro::bridge::client::ProcMacro;
//
// #[rustc_proc_macro_decls]
+// #[used]
// #[allow(deprecated)]
// static DECLS: &[ProcMacro] = &[
// ProcMacro::custom_derive($name_trait1, &[], ::$name1);
@@ -348,7 +349,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
.item_static(
span,
Ident::new(sym::_DECLS, span),
- cx.ty_rptr(
+ cx.ty_ref(
span,
cx.ty(
span,
@@ -364,6 +365,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
)
.map(|mut i| {
i.attrs.push(cx.attr_word(sym::rustc_proc_macro_decls, span));
+ i.attrs.push(cx.attr_word(sym::used, span));
i.attrs.push(cx.attr_nested_word(sym::allow, sym::deprecated, span));
i
});
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index f5f02fc77..729ae4071 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -239,8 +239,7 @@ pub fn expand_test_or_bench(
cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
// #[rustc_test_marker = "test_case_sort_key"]
cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
- ]
- .into(),
+ ],
// const $ident: test::TestDescAndFn =
ast::ItemKind::Const(
ast::Defaultness::Final,