diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 2a5bc58af3b3..0f1589903193 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -118,6 +118,8 @@ builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Un
builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments
+builtin_macros_expected_comma_in_list = expected token: `,`
+
builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
builtin_macros_expected_register_class_or_explicit_register = expected register class or explicit register
@@ -219,12 +221,16 @@ builtin_macros_non_exhaustive_default = default variant must be exhaustive
builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants
.help = consider a manual implementation of `Default`
+builtin_macros_only_one_argument = {$name} takes 1 argument
+
builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
builtin_macros_requires_cfg_pattern =
macro requires a cfg-pattern as an argument
.label = cfg-pattern required
+builtin_macros_takes_no_arguments = {$name} takes no arguments
+
builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
.label = `{$kind}` because of this
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index bc94e0b972b4..064cf7d7f0f8 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -9,7 +9,7 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
-pub fn expand(
+pub(crate) fn expand(
ecx: &mut ExtCtxt<'_>,
_span: Span,
meta_item: &ast::MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 137ac4415792..49b1b8cf9926 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -1,3 +1,5 @@
+use crate::errors;
+use crate::util::expr_to_spanned_string;
use ast::token::IdentIsRaw;
use rustc_ast as ast;
use rustc_ast::ptr::P;
@@ -16,8 +18,6 @@ use rustc_span::{ErrorGuaranteed, InnerSpan, Span};
use rustc_target::asm::InlineAsmArch;
use smallvec::smallvec;
-use crate::errors;
-
pub struct AsmArgs {
pub templates: Vec
>,
pub operands: Vec<(ast::InlineAsmOperand, Span)>,
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index d200179f3a0a..c75050f27018 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -15,7 +15,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use thin_vec::thin_vec;
-pub fn expand_assert<'cx>(
+pub(crate) fn expand_assert<'cx>(
cx: &'cx mut ExtCtxt<'_>,
span: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index 5dc9bbacd062..827719d79449 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -11,7 +11,7 @@ use rustc_errors::PResult;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_span::Span;
-pub fn expand_cfg(
+pub(crate) fn expand_cfg(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs
index 2f2a87fc9aa0..a08e8b2819b5 100644
--- a/compiler/rustc_builtin_macros/src/compile_error.rs
+++ b/compiler/rustc_builtin_macros/src/compile_error.rs
@@ -1,11 +1,11 @@
// The compiler code necessary to support the compile_error! extension.
+use crate::util::get_single_str_from_tts;
use rustc_ast::tokenstream::TokenStream;
-use rustc_expand::base::get_single_str_from_tts;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
use rustc_span::Span;
-pub fn expand_compile_error<'cx>(
+pub(crate) fn expand_compile_error<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index 93a7ac05a9be..15af79ef67d4 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -1,13 +1,12 @@
+use crate::errors;
+use crate::util::get_exprs_from_tts;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{ExprKind, LitKind, UnOp};
-use rustc_expand::base::get_exprs_from_tts;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_session::errors::report_lit_error;
use rustc_span::symbol::Symbol;
-use crate::errors;
-
-pub fn expand_concat(
+pub(crate) fn expand_concat(
cx: &mut ExtCtxt<'_>,
sp: rustc_span::Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index 45fec2945788..3130870df410 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -1,11 +1,10 @@
+use crate::errors;
+use crate::util::get_exprs_from_tts;
use rustc_ast::{ptr::P, token, tokenstream::TokenStream, ExprKind, LitIntType, LitKind, UintTy};
-use rustc_expand::base::get_exprs_from_tts;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_session::errors::report_lit_error;
use rustc_span::{ErrorGuaranteed, Span};
-use crate::errors;
-
/// Emits errors for literal expressions that are invalid inside and outside of an array.
fn invalid_type_err(
cx: &ExtCtxt<'_>,
@@ -108,7 +107,7 @@ fn handle_array_element(
None
}
-pub fn expand_concat_bytes(
+pub(crate) fn expand_concat_bytes(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs
index 3ddb0ae45b51..13729a9d250f 100644
--- a/compiler/rustc_builtin_macros/src/concat_idents.rs
+++ b/compiler/rustc_builtin_macros/src/concat_idents.rs
@@ -8,7 +8,7 @@ use rustc_span::Span;
use crate::errors;
-pub fn expand_concat_idents<'cx>(
+pub(crate) fn expand_concat_idents<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index 4f412cf79d91..d14858e5c1db 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -3,14 +3,18 @@ use crate::errors;
use rustc_ast as ast;
use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
-use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
+use rustc_expand::base::{
+ Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier,
+};
use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr;
use rustc_session::Session;
use rustc_span::symbol::{sym, Ident};
use rustc_span::{ErrorGuaranteed, Span};
-pub(crate) struct Expander(pub bool);
+pub(crate) struct Expander {
+ pub is_const: bool,
+}
impl MultiItemModifier for Expander {
fn expand(
@@ -58,7 +62,12 @@ impl MultiItemModifier for Expander {
report_path_args(sess, meta);
meta.path.clone()
})
- .map(|path| (path, dummy_annotatable(), None, self.0))
+ .map(|path| DeriveResolution {
+ path,
+ item: dummy_annotatable(),
+ exts: None,
+ is_const: self.is_const,
+ })
.collect()
}
_ => vec![],
@@ -67,15 +76,15 @@ impl MultiItemModifier for Expander {
// Do not configure or clone items unless necessary.
match &mut resolutions[..] {
[] => {}
- [(_, first_item, ..), others @ ..] => {
- *first_item = cfg_eval(
+ [first, others @ ..] => {
+ first.item = cfg_eval(
sess,
features,
item.clone(),
ecx.current_expansion.lint_node_id,
);
- for (_, item, _, _) in others {
- *item = first_item.clone();
+ for other in others {
+ other.item = first.item.clone();
}
}
}
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 26ef3da3a915..97e2344ff30e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -5,7 +5,7 @@ use rustc_ast::MetaItem;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::Span;
-pub fn expand_deriving_copy(
+pub(crate) fn expand_deriving_copy(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
@@ -28,7 +28,7 @@ pub fn expand_deriving_copy(
trait_def.expand(cx, mitem, item, push);
}
-pub fn expand_deriving_const_param_ty(
+pub(crate) fn expand_deriving_const_param_ty(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index cb1c9ef90bde..abcb402a46f8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
-pub fn expand_deriving_clone(
+pub(crate) fn expand_deriving_clone(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 45c4467a1097..53a151316054 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -9,7 +9,7 @@ use rustc_span::symbol::sym;
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
-pub fn expand_deriving_eq(
+pub(crate) fn expand_deriving_eq(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 1d7a69540ab8..8470d466a233 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -7,7 +7,7 @@ use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use thin_vec::thin_vec;
-pub fn expand_deriving_ord(
+pub(crate) fn expand_deriving_ord(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
@@ -39,7 +39,7 @@ pub fn expand_deriving_ord(
trait_def.expand(cx, mitem, item, push)
}
-pub fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
+pub(crate) fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
let test_id = Ident::new(sym::cmp, span);
let equal_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
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 234918ae4296..dc73caa4ad5b 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::sym;
use rustc_span::Span;
use thin_vec::thin_vec;
-pub fn expand_deriving_partial_eq(
+pub(crate) fn expand_deriving_partial_eq(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
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 63311c897aba..006e5a3d268a 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -7,7 +7,7 @@ use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use thin_vec::thin_vec;
-pub fn expand_deriving_partial_ord(
+pub(crate) fn expand_deriving_partial_ord(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index 8b681db96705..57ec0435e3e0 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
-pub fn expand_deriving_debug(
+pub(crate) fn expand_deriving_debug(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index 34798ab0a17b..e9851c87aeae 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -10,7 +10,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
-pub fn expand_deriving_rustc_decodable(
+pub(crate) fn expand_deriving_rustc_decodable(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 328770ce10d2..bf92ddb33701 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -12,7 +12,7 @@ use rustc_span::{ErrorGuaranteed, Span};
use smallvec::SmallVec;
use thin_vec::{thin_vec, ThinVec};
-pub fn expand_deriving_default(
+pub(crate) fn expand_deriving_default(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &ast::MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index 2e5f1173825a..3bd74d8d0198 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -94,7 +94,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
-pub fn expand_deriving_rustc_encodable(
+pub(crate) fn expand_deriving_rustc_encodable(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 85d54e9257d8..52c1ba1757b1 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -174,8 +174,8 @@
//! )
//! ```
-pub use StaticFields::*;
-pub use SubstructureFields::*;
+pub(crate) use StaticFields::*;
+pub(crate) use SubstructureFields::*;
use crate::{deriving, errors};
use rustc_ast::ptr::P;
@@ -195,9 +195,9 @@ use std::vec;
use thin_vec::{thin_vec, ThinVec};
use ty::{Bounds, Path, Ref, Self_, Ty};
-pub mod ty;
+pub(crate) mod ty;
-pub struct TraitDef<'a> {
+pub(crate) struct TraitDef<'a> {
/// The span for the current #[derive(Foo)] header.
pub span: Span,
@@ -224,7 +224,7 @@ pub struct TraitDef<'a> {
pub is_const: bool,
}
-pub struct MethodDef<'a> {
+pub(crate) struct MethodDef<'a> {
/// name of the method
pub name: Symbol,
/// List of generics, e.g., `R: rand::Rng`
@@ -248,7 +248,7 @@ pub struct MethodDef<'a> {
/// How to handle fieldless enum variants.
#[derive(PartialEq)]
-pub enum FieldlessVariantsStrategy {
+pub(crate) 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.
@@ -263,7 +263,7 @@ pub enum FieldlessVariantsStrategy {
}
/// All the data about the data structure/method being derived upon.
-pub struct Substructure<'a> {
+pub(crate) struct Substructure<'a> {
/// ident of self
pub type_ident: Ident,
/// Verbatim access to any non-selflike arguments, i.e. arguments that
@@ -273,7 +273,7 @@ pub struct Substructure<'a> {
}
/// Summary of the relevant parts of a struct/enum field.
-pub struct FieldInfo {
+pub(crate) struct FieldInfo {
pub span: Span,
/// None for tuple structs/normal enum variants, Some for normal
/// structs/struct enum variants.
@@ -287,13 +287,13 @@ pub struct FieldInfo {
}
#[derive(Copy, Clone)]
-pub enum IsTuple {
+pub(crate) enum IsTuple {
No,
Yes,
}
/// Fields for a static method
-pub enum StaticFields {
+pub(crate) enum StaticFields {
/// Tuple and unit structs/enum variants like this.
Unnamed(Vec, IsTuple),
/// Normal structs/struct variants.
@@ -301,7 +301,7 @@ pub enum StaticFields {
}
/// A summary of the possible sets of fields.
-pub enum SubstructureFields<'a> {
+pub(crate) enum SubstructureFields<'a> {
/// A non-static method where `Self` is a struct.
Struct(&'a ast::VariantData, Vec),
@@ -329,10 +329,10 @@ pub enum SubstructureFields<'a> {
/// Combine the values of all the fields together. The last argument is
/// all the fields of all the structures.
-pub type CombineSubstructureFunc<'a> =
+pub(crate) type CombineSubstructureFunc<'a> =
Box, Span, &Substructure<'_>) -> BlockOrExpr + 'a>;
-pub fn combine_substructure(
+pub(crate) fn combine_substructure(
f: CombineSubstructureFunc<'_>,
) -> RefCell> {
RefCell::new(f)
@@ -349,7 +349,7 @@ struct TypeParameter {
/// avoiding the insertion of any unnecessary blocks.
///
/// The statements come before the expression.
-pub struct BlockOrExpr(ThinVec, Option>);
+pub(crate) struct BlockOrExpr(ThinVec, Option>);
impl BlockOrExpr {
pub fn new_stmts(stmts: ThinVec) -> BlockOrExpr {
@@ -1647,7 +1647,7 @@ impl<'a> TraitDef<'a> {
/// The function passed to `cs_fold` is called repeatedly with a value of this
/// type. It describes one part of the code generation. The result is always an
/// expression.
-pub enum CsFold<'a> {
+pub(crate) enum CsFold<'a> {
/// The basic case: a field expression for one or more selflike args. E.g.
/// for `PartialEq::eq` this is something like `self.x == other.x`.
Single(&'a FieldInfo),
@@ -1662,7 +1662,7 @@ pub enum CsFold<'a> {
/// Folds over fields, combining the expressions for each field in a sequence.
/// Statics may not be folded over.
-pub fn cs_fold(
+pub(crate) fn cs_fold(
use_foldl: bool,
cx: &ExtCtxt<'_>,
trait_span: Span,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index 188833246832..f01d586033e0 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -1,7 +1,7 @@
//! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use
//! when specifying impls to be derived.
-pub use Ty::*;
+pub(crate) use Ty::*;
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
@@ -14,14 +14,14 @@ use thin_vec::ThinVec;
/// A path, e.g., `::std::option::Option::` (global). Has support
/// for type parameters.
#[derive(Clone)]
-pub struct Path {
+pub(crate) struct Path {
path: Vec,
params: Vec>,
kind: PathKind,
}
#[derive(Clone)]
-pub enum PathKind {
+pub(crate) enum PathKind {
Local,
Global,
Std,
@@ -72,7 +72,7 @@ impl Path {
/// A type. Supports pointers, Self, and literals.
#[derive(Clone)]
-pub enum Ty {
+pub(crate) enum Ty {
Self_,
/// A reference.
Ref(Box, ast::Mutability),
@@ -83,7 +83,7 @@ pub enum Ty {
Unit,
}
-pub fn self_ref() -> Ty {
+pub(crate) fn self_ref() -> Ty {
Ref(Box::new(Self_), ast::Mutability::Not)
}
@@ -163,7 +163,7 @@ fn mk_ty_param(
/// Bounds on type parameters.
#[derive(Clone)]
-pub struct Bounds {
+pub(crate) struct Bounds {
pub bounds: Vec<(Symbol, Vec)>,
}
@@ -196,7 +196,7 @@ impl Bounds {
}
}
-pub fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P, ast::ExplicitSelf) {
+pub(crate) fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P, ast::ExplicitSelf) {
// This constructs a fresh `self` path.
let self_path = cx.expr_self(span);
let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not));
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 41e27f655866..dcd928198651 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -7,7 +7,7 @@ use rustc_span::symbol::sym;
use rustc_span::Span;
use thin_vec::thin_vec;
-pub fn expand_deriving_hash(
+pub(crate) fn expand_deriving_hash(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index 9f786d22c932..d6e2d1d4d07f 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -20,24 +20,24 @@ macro path_std($($x:tt)*) {
generic::ty::Path::new( pathvec_std!( $($x)* ) )
}
-pub mod bounds;
-pub mod clone;
-pub mod debug;
-pub mod decodable;
-pub mod default;
-pub mod encodable;
-pub mod hash;
+pub(crate) mod bounds;
+pub(crate) mod clone;
+pub(crate) mod debug;
+pub(crate) mod decodable;
+pub(crate) mod default;
+pub(crate) mod encodable;
+pub(crate) mod hash;
#[path = "cmp/eq.rs"]
-pub mod eq;
+pub(crate) mod eq;
#[path = "cmp/ord.rs"]
-pub mod ord;
+pub(crate) mod ord;
#[path = "cmp/partial_eq.rs"]
-pub mod partial_eq;
+pub(crate) mod partial_eq;
#[path = "cmp/partial_ord.rs"]
-pub mod partial_ord;
+pub(crate) mod partial_ord;
-pub mod generic;
+pub(crate) mod generic;
pub(crate) type BuiltinDeriveFn =
fn(&ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool);
diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs
index bb3c83e8c0e3..cc385bade470 100644
--- a/compiler/rustc_builtin_macros/src/edition_panic.rs
+++ b/compiler/rustc_builtin_macros/src/edition_panic.rs
@@ -16,7 +16,7 @@ use rustc_span::Span;
///
/// `$crate` will refer to either the `std` or `core` crate depending on which
/// one we're expanding from.
-pub fn expand_panic<'cx>(
+pub(crate) fn expand_panic<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -29,7 +29,7 @@ pub fn expand_panic<'cx>(
/// - `$crate::panic::unreachable_2015!(...)` or
/// - `$crate::panic::unreachable_2021!(...)`
/// depending on the edition.
-pub fn expand_unreachable<'cx>(
+pub(crate) fn expand_unreachable<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -69,7 +69,7 @@ fn expand<'cx>(
))
}
-pub fn use_panic_2021(mut span: Span) -> bool {
+pub(crate) fn use_panic_2021(mut span: Span) -> bool {
// To determine the edition, we check the first span up the expansion
// stack that does not have #[allow_internal_unstable(edition_panic)].
// (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.)
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 938730459437..b03e14cf2630 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -3,10 +3,11 @@
// interface.
//
+use crate::errors;
+use crate::util::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts};
use rustc_ast::token::{self, LitKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{AstDeref, ExprKind, GenericArg, Mutability};
-use rustc_expand::base::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts};
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
@@ -14,8 +15,6 @@ use std::env;
use std::env::VarError;
use thin_vec::thin_vec;
-use crate::errors;
-
fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result {
let var = var.as_str();
if let Some(value) = cx.sess.opts.logical_env.get(var) {
@@ -26,7 +25,7 @@ fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result(
+pub(crate) fn expand_option_env<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -66,7 +65,7 @@ pub fn expand_option_env<'cx>(
ExpandResult::Ready(MacEager::expr(e))
}
-pub fn expand_env<'cx>(
+pub(crate) fn expand_env<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index 9078dc07a315..d157703723be 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -579,7 +579,7 @@ pub(crate) struct FormatUnknownTrait<'a> {
style = "tool-only",
applicability = "maybe-incorrect"
)]
-pub struct FormatUnknownTraitSugg {
+pub(crate) struct FormatUnknownTraitSugg {
#[primary_span]
pub span: Span,
pub fmt: &'static str,
@@ -842,3 +842,26 @@ pub(crate) struct ExpectedRegisterClassOrExplicitRegister {
#[primary_span]
pub(crate) span: Span,
}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_expected_comma_in_list)]
+pub(crate) struct ExpectedCommaInList {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_only_one_argument)]
+pub(crate) struct OnlyOneArgument<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub name: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_takes_no_arguments)]
+pub(crate) struct TakesNoArguments<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub name: &'a str,
+}
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 51d6058a744f..2c717661a1c4 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -1,3 +1,5 @@
+use crate::errors;
+use crate::util::expr_to_spanned_string;
use parse::Position::ArgumentNamed;
use rustc_ast::ptr::P;
use rustc_ast::tokenstream::TokenStream;
@@ -10,14 +12,13 @@ use rustc_ast::{
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans};
use rustc_expand::base::*;
+use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
+use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId};
use rustc_parse::parser::Recovered;
use rustc_parse_format as parse;
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span};
-use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
-use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId};
-
// The format_args!() macro is expanded in three steps:
// 1. First, `parse_args` will parse the `(literal, arg, arg, name=arg, name=arg)` syntax,
// but doesn't parse the template (the literal) itself.
@@ -38,8 +39,6 @@ enum PositionUsedAs {
}
use PositionUsedAs::*;
-use crate::errors;
-
#[derive(Debug)]
struct MacroInput {
fmtstr: P,
@@ -1001,7 +1000,7 @@ fn expand_format_args_impl<'cx>(
})
}
-pub fn expand_format_args<'cx>(
+pub(crate) fn expand_format_args<'cx>(
ecx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -1009,7 +1008,7 @@ pub fn expand_format_args<'cx>(
expand_format_args_impl(ecx, sp, tts, false)
}
-pub fn expand_format_args_nl<'cx>(
+pub(crate) fn expand_format_args_nl<'cx>(
ecx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 099defd511b5..a1630ad1379e 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -12,7 +12,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
-pub fn expand(
+pub(crate) fn expand(
ecx: &mut ExtCtxt<'_>,
_span: Span,
meta_item: &ast::MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 1b4c6041294f..7c7b9c2d65fb 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -50,13 +50,13 @@ mod pattern_type;
mod source_util;
mod test;
mod trace_macros;
-mod util;
pub mod asm;
pub mod cmdline_attrs;
pub mod proc_macro_harness;
pub mod standard_library_imports;
pub mod test_harness;
+pub mod util;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
@@ -109,8 +109,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
bench: test::expand_bench,
cfg_accessible: cfg_accessible::Expander,
cfg_eval: cfg_eval::expand,
- derive: derive::Expander(false),
- derive_const: derive::Expander(true),
+ derive: derive::Expander { is_const: false },
+ derive_const: derive::Expander { is_const: true },
global_allocator: global_allocator::expand,
test: test::expand_test,
test_case: test::expand_test_case,
diff --git a/compiler/rustc_builtin_macros/src/log_syntax.rs b/compiler/rustc_builtin_macros/src/log_syntax.rs
index 288a475ac241..205f21ae7c9d 100644
--- a/compiler/rustc_builtin_macros/src/log_syntax.rs
+++ b/compiler/rustc_builtin_macros/src/log_syntax.rs
@@ -2,7 +2,7 @@ use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
-pub fn expand_log_syntax<'cx>(
+pub(crate) fn expand_log_syntax<'cx>(
_cx: &'cx mut ExtCtxt<'_>,
sp: rustc_span::Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs
index 54039c2c5386..31f5656df135 100644
--- a/compiler/rustc_builtin_macros/src/pattern_type.rs
+++ b/compiler/rustc_builtin_macros/src/pattern_type.rs
@@ -3,7 +3,7 @@ use rustc_errors::PResult;
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
use rustc_span::{sym, Span};
-pub fn expand<'cx>(
+pub(crate) fn expand<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index c79ae716806c..47b2ee975ca8 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -1,3 +1,6 @@
+use crate::util::{
+ check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr,
+};
use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token;
@@ -5,11 +8,8 @@ use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust;
use rustc_data_structures::sync::Lrc;
use rustc_expand::base::{
- check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr,
- resolve_path,
+ resolve_path, DummyResult, ExpandResult, ExtCtxt, MacEager, MacResult, MacroExpanderResult,
};
-use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt};
-use rustc_expand::base::{MacEager, MacResult, MacroExpanderResult};
use rustc_expand::module::DirOwnership;
use rustc_parse::new_parser_from_file;
use rustc_parse::parser::{ForceCollect, Parser};
@@ -26,7 +26,7 @@ use std::rc::Rc;
// a given file into the current one.
/// line!(): expands to the current line number
-pub fn expand_line(
+pub(crate) fn expand_line(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -41,7 +41,7 @@ pub fn expand_line(
}
/* column!(): expands to the current column number */
-pub fn expand_column(
+pub(crate) fn expand_column(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -58,7 +58,7 @@ pub fn expand_column(
/// file!(): expands to the current filename */
/// The source_file (`loc.file`) contains a bunch more information we could spit
/// out if we wanted.
-pub fn expand_file(
+pub(crate) fn expand_file(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -78,7 +78,7 @@ pub fn expand_file(
)))
}
-pub fn expand_stringify(
+pub(crate) fn expand_stringify(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -88,7 +88,7 @@ pub fn expand_stringify(
ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&s))))
}
-pub fn expand_mod(
+pub(crate) fn expand_mod(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -104,7 +104,7 @@ pub fn expand_mod(
/// include! : parse the given file as an expr
/// This is generally a bad idea because it's going to behave
/// unhygienically.
-pub fn expand_include<'cx>(
+pub(crate) fn expand_include<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -181,7 +181,7 @@ pub fn expand_include<'cx>(
}
/// `include_str!`: read the given file, insert it as a literal string expr
-pub fn expand_include_str(
+pub(crate) fn expand_include_str(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
@@ -210,7 +210,7 @@ pub fn expand_include_str(
})
}
-pub fn expand_include_bytes(
+pub(crate) fn expand_include_bytes(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index c7568f1461c1..134d5451b9c1 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -20,7 +20,7 @@ use thin_vec::{thin_vec, ThinVec};
///
/// We mark item with an inert attribute "rustc_test_marker" which the test generation
/// logic will pick up on.
-pub fn expand_test_case(
+pub(crate) fn expand_test_case(
ecx: &mut ExtCtxt<'_>,
attr_sp: Span,
meta_item: &ast::MetaItem,
@@ -73,7 +73,7 @@ pub fn expand_test_case(
vec![ret]
}
-pub fn expand_test(
+pub(crate) fn expand_test(
cx: &mut ExtCtxt<'_>,
attr_sp: Span,
meta_item: &ast::MetaItem,
@@ -84,7 +84,7 @@ pub fn expand_test(
expand_test_or_bench(cx, attr_sp, item, false)
}
-pub fn expand_bench(
+pub(crate) fn expand_bench(
cx: &mut ExtCtxt<'_>,
attr_sp: Span,
meta_item: &ast::MetaItem,
@@ -95,7 +95,7 @@ pub fn expand_bench(
expand_test_or_bench(cx, attr_sp, item, true)
}
-pub fn expand_test_or_bench(
+pub(crate) fn expand_test_or_bench(
cx: &ExtCtxt<'_>,
attr_sp: Span,
item: Annotatable,
diff --git a/compiler/rustc_builtin_macros/src/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs
index 696d99004ba0..4833ec32f76e 100644
--- a/compiler/rustc_builtin_macros/src/trace_macros.rs
+++ b/compiler/rustc_builtin_macros/src/trace_macros.rs
@@ -4,7 +4,7 @@ use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult
use rustc_span::symbol::kw;
use rustc_span::Span;
-pub fn expand_trace_macros(
+pub(crate) fn expand_trace_macros(
cx: &mut ExtCtxt<'_>,
sp: Span,
tt: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs
index ad6b09ba5745..8dc7bc14ec3e 100644
--- a/compiler/rustc_builtin_macros/src/util.rs
+++ b/compiler/rustc_builtin_macros/src/util.rs
@@ -1,11 +1,16 @@
-use rustc_ast::{attr, AttrStyle, Attribute, MetaItem};
-use rustc_expand::base::{Annotatable, ExtCtxt};
+use crate::errors;
+use rustc_ast::tokenstream::TokenStream;
+use rustc_ast::{self as ast, attr, ptr::P, token, AttrStyle, Attribute, MetaItem};
+use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
+use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt};
+use rustc_expand::expand::AstFragment;
use rustc_feature::AttributeTemplate;
use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES;
-use rustc_parse::validate_attr;
-use rustc_span::Symbol;
+use rustc_parse::{parser, validate_attr};
+use rustc_session::errors::report_lit_error;
+use rustc_span::{BytePos, Span, Symbol};
-pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {
+pub(crate) fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {
// All the built-in macro attributes are "words" at the moment.
let template = AttributeTemplate { word: true, ..Default::default() };
validate_attr::check_builtin_meta_item(
@@ -19,7 +24,7 @@ pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, na
/// Emit a warning if the item is annotated with the given attribute. This is used to diagnose when
/// an attribute may have been mistakenly duplicated.
-pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) {
+pub(crate) fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) {
let attrs: Option<&[Attribute]> = match item {
Annotatable::Item(item) => Some(&item.attrs),
Annotatable::TraitItem(item) => Some(&item.attrs),
@@ -46,3 +51,178 @@ pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name:
}
}
}
+
+/// `Ok` represents successfully retrieving the string literal at the correct
+/// position, e.g., `println("abc")`.
+type ExprToSpannedStringResult<'a> = Result<(Symbol, ast::StrStyle, Span), UnexpectedExprKind<'a>>;
+
+/// - `Ok` is returned when the conversion to a string literal is unsuccessful,
+/// but another type of expression is obtained instead.
+/// - `Err` is returned when the conversion process fails.
+type UnexpectedExprKind<'a> = Result<(Diag<'a>, bool /* has_suggestions */), ErrorGuaranteed>;
+
+/// Extracts a string literal from the macro expanded version of `expr`,
+/// returning a diagnostic error of `err_msg` if `expr` is not a string literal.
+/// The returned bool indicates whether an applicable suggestion has already been
+/// added to the diagnostic to avoid emitting multiple suggestions. `Err(Err(ErrorGuaranteed))`
+/// indicates that an ast error was encountered.
+// FIXME(Nilstrieb) Make this function setup translatable
+#[allow(rustc::untranslatable_diagnostic)]
+pub(crate) fn expr_to_spanned_string<'a>(
+ cx: &'a mut ExtCtxt<'_>,
+ expr: P,
+ err_msg: &'static str,
+) -> ExpandResult, ()> {
+ if !cx.force_mode
+ && let ast::ExprKind::MacCall(m) = &expr.kind
+ && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err()
+ {
+ return ExpandResult::Retry(());
+ }
+
+ // Perform eager expansion on the expression.
+ // We want to be able to handle e.g., `concat!("foo", "bar")`.
+ let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
+
+ ExpandResult::Ready(Err(match expr.kind {
+ ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
+ Ok(ast::LitKind::Str(s, style)) => {
+ return ExpandResult::Ready(Ok((s, style, expr.span)));
+ }
+ Ok(ast::LitKind::ByteStr(..)) => {
+ let mut err = cx.dcx().struct_span_err(expr.span, err_msg);
+ let span = expr.span.shrink_to_lo();
+ err.span_suggestion(
+ span.with_hi(span.lo() + BytePos(1)),
+ "consider removing the leading `b`",
+ "",
+ Applicability::MaybeIncorrect,
+ );
+ Ok((err, true))
+ }
+ Ok(ast::LitKind::Err(guar)) => Err(guar),
+ Err(err) => Err(report_lit_error(&cx.sess.psess, err, token_lit, expr.span)),
+ _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
+ },
+ ast::ExprKind::Err(guar) => Err(guar),
+ ast::ExprKind::Dummy => {
+ cx.dcx().span_bug(expr.span, "tried to get a string literal from `ExprKind::Dummy`")
+ }
+ _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
+ }))
+}
+
+/// Extracts a string literal from the macro expanded version of `expr`,
+/// emitting `err_msg` if `expr` is not a string literal. This does not stop
+/// compilation on error, merely emits a non-fatal error and returns `Err`.
+pub(crate) fn expr_to_string(
+ cx: &mut ExtCtxt<'_>,
+ expr: P,
+ err_msg: &'static str,
+) -> ExpandResult, ()> {
+ expr_to_spanned_string(cx, expr, err_msg).map(|res| {
+ res.map_err(|err| match err {
+ Ok((err, _)) => err.emit(),
+ Err(guar) => guar,
+ })
+ .map(|(symbol, style, _)| (symbol, style))
+ })
+}
+
+/// Non-fatally assert that `tts` is empty. Note that this function
+/// returns even when `tts` is non-empty, macros that *need* to stop
+/// compilation should call `cx.diagnostic().abort_if_errors()`
+/// (this should be done as rarely as possible).
+pub(crate) fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) {
+ if !tts.is_empty() {
+ cx.dcx().emit_err(errors::TakesNoArguments { span, name });
+ }
+}
+
+/// Parse an expression. On error, emit it, advancing to `Eof`, and return `Err`.
+pub(crate) fn parse_expr(p: &mut parser::Parser<'_>) -> Result, ErrorGuaranteed> {
+ let guar = match p.parse_expr() {
+ Ok(expr) => return Ok(expr),
+ Err(err) => err.emit(),
+ };
+ while p.token != token::Eof {
+ p.bump();
+ }
+ Err(guar)
+}
+
+/// Interpreting `tts` as a comma-separated sequence of expressions,
+/// expect exactly one string literal, or emit an error and return `Err`.
+pub(crate) fn get_single_str_from_tts(
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ tts: TokenStream,
+ name: &str,
+) -> ExpandResult, ()> {
+ get_single_str_spanned_from_tts(cx, span, tts, name).map(|res| res.map(|(s, _)| s))
+}
+
+pub(crate) fn get_single_str_spanned_from_tts(
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ tts: TokenStream,
+ name: &str,
+) -> ExpandResult, ()> {
+ let mut p = cx.new_parser_from_tts(tts);
+ if p.token == token::Eof {
+ let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
+ return ExpandResult::Ready(Err(guar));
+ }
+ let ret = match parse_expr(&mut p) {
+ Ok(ret) => ret,
+ Err(guar) => return ExpandResult::Ready(Err(guar)),
+ };
+ let _ = p.eat(&token::Comma);
+
+ if p.token != token::Eof {
+ cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
+ }
+ expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| {
+ res.map_err(|err| match err {
+ Ok((err, _)) => err.emit(),
+ Err(guar) => guar,
+ })
+ .map(|(symbol, _style, span)| (symbol, span))
+ })
+}
+
+/// Extracts comma-separated expressions from `tts`.
+/// On error, emit it, and return `Err`.
+pub(crate) fn get_exprs_from_tts(
+ cx: &mut ExtCtxt<'_>,
+ tts: TokenStream,
+) -> ExpandResult>, ErrorGuaranteed>, ()> {
+ let mut p = cx.new_parser_from_tts(tts);
+ let mut es = Vec::new();
+ while p.token != token::Eof {
+ let expr = match parse_expr(&mut p) {
+ Ok(expr) => expr,
+ Err(guar) => return ExpandResult::Ready(Err(guar)),
+ };
+ if !cx.force_mode
+ && let ast::ExprKind::MacCall(m) = &expr.kind
+ && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err()
+ {
+ return ExpandResult::Retry(());
+ }
+
+ // Perform eager expansion on the expression.
+ // We want to be able to handle e.g., `concat!("foo", "bar")`.
+ let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
+
+ es.push(expr);
+ if p.eat(&token::Comma) {
+ continue;
+ }
+ if p.token != token::Eof {
+ let guar = cx.dcx().emit_err(errors::ExpectedCommaInList { span: p.token.span });
+ return ExpandResult::Ready(Err(guar));
+ }
+ }
+ ExpandResult::Ready(Ok(es))
+}
diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl
index fdd1a87cae80..b7aae2af9ef9 100644
--- a/compiler/rustc_expand/messages.ftl
+++ b/compiler/rustc_expand/messages.ftl
@@ -30,9 +30,6 @@ expand_duplicate_matcher_binding = duplicate matcher binding
.label = duplicate binding
.label2 = previous binding
-expand_expected_comma_in_list =
- expected token: `,`
-
expand_expected_paren_or_brace =
expected `(` or `{"{"}`, found `{$token}`
@@ -116,9 +113,6 @@ expand_must_repeat_once =
expand_not_a_meta_item =
not a meta item
-expand_only_one_argument =
- {$name} takes 1 argument
-
expand_only_one_word =
must only be one word
@@ -146,9 +140,6 @@ expand_remove_node_not_supported =
expand_resolve_relative_path =
cannot resolve relative path in non-file source `{$path}`
-expand_takes_no_arguments =
- {$name} takes no arguments
-
expand_trace_macro = trace_macro
expand_unsupported_key_value =
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 3c465709ec7b..6fe74edbd70a 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -5,27 +5,26 @@ use crate::module::DirOwnership;
use rustc_ast::attr::MarkedAttrs;
use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Nonterminal};
+use rustc_ast::token::Nonterminal;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{AssocCtxt, Visitor};
use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
use rustc_attr::{self as attr, Deprecation, Stability};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::{self, Lrc};
-use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, PResult};
+use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
use rustc_feature::Features;
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, RegisteredTools};
use rustc_parse::{parser, MACRO_ARGUMENTS};
use rustc_session::config::CollapseMacroDebuginfo;
-use rustc_session::errors::report_lit_error;
use rustc_session::{parse::ParseSess, Limit, Session};
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::edition::Edition;
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
+use rustc_span::{FileName, Span, DUMMY_SP};
use smallvec::{smallvec, SmallVec};
use std::default::Default;
use std::iter;
@@ -963,7 +962,12 @@ impl SyntaxExtension {
/// Error type that denotes indeterminacy.
pub struct Indeterminate;
-pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option>, bool)>;
+pub struct DeriveResolution {
+ pub path: ast::Path,
+ pub item: Annotatable,
+ pub exts: Option>,
+ pub is_const: bool,
+}
pub trait ResolverExpand {
fn next_node_id(&mut self) -> NodeId;
@@ -1006,11 +1010,11 @@ pub trait ResolverExpand {
&mut self,
expn_id: LocalExpnId,
force: bool,
- derive_paths: &dyn Fn() -> DeriveResolutions,
+ derive_paths: &dyn Fn() -> Vec,
) -> Result<(), Indeterminate>;
/// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId`
/// back from resolver.
- fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option;
+ fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option>;
/// Path resolution logic for `#[cfg_accessible(path)]`.
fn cfg_accessible(
&mut self,
@@ -1264,181 +1268,6 @@ pub fn resolve_path(sess: &Session, path: impl Into, span: Span) -> PRe
}
}
-/// `Ok` represents successfully retrieving the string literal at the correct
-/// position, e.g., `println("abc")`.
-type ExprToSpannedStringResult<'a> = Result<(Symbol, ast::StrStyle, Span), UnexpectedExprKind<'a>>;
-
-/// - `Ok` is returned when the conversion to a string literal is unsuccessful,
-/// but another type of expression is obtained instead.
-/// - `Err` is returned when the conversion process fails.
-type UnexpectedExprKind<'a> = Result<(Diag<'a>, bool /* has_suggestions */), ErrorGuaranteed>;
-
-/// Extracts a string literal from the macro expanded version of `expr`,
-/// returning a diagnostic error of `err_msg` if `expr` is not a string literal.
-/// The returned bool indicates whether an applicable suggestion has already been
-/// added to the diagnostic to avoid emitting multiple suggestions. `Err(Err(ErrorGuaranteed))`
-/// indicates that an ast error was encountered.
-// FIXME(Nilstrieb) Make this function setup translatable
-#[allow(rustc::untranslatable_diagnostic)]
-pub fn expr_to_spanned_string<'a>(
- cx: &'a mut ExtCtxt<'_>,
- expr: P,
- err_msg: &'static str,
-) -> ExpandResult, ()> {
- if !cx.force_mode
- && let ast::ExprKind::MacCall(m) = &expr.kind
- && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err()
- {
- return ExpandResult::Retry(());
- }
-
- // Perform eager expansion on the expression.
- // We want to be able to handle e.g., `concat!("foo", "bar")`.
- let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
-
- ExpandResult::Ready(Err(match expr.kind {
- ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
- Ok(ast::LitKind::Str(s, style)) => {
- return ExpandResult::Ready(Ok((s, style, expr.span)));
- }
- Ok(ast::LitKind::ByteStr(..)) => {
- let mut err = cx.dcx().struct_span_err(expr.span, err_msg);
- let span = expr.span.shrink_to_lo();
- err.span_suggestion(
- span.with_hi(span.lo() + BytePos(1)),
- "consider removing the leading `b`",
- "",
- Applicability::MaybeIncorrect,
- );
- Ok((err, true))
- }
- Ok(ast::LitKind::Err(guar)) => Err(guar),
- Err(err) => Err(report_lit_error(&cx.sess.psess, err, token_lit, expr.span)),
- _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
- },
- ast::ExprKind::Err(guar) => Err(guar),
- ast::ExprKind::Dummy => {
- cx.dcx().span_bug(expr.span, "tried to get a string literal from `ExprKind::Dummy`")
- }
- _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
- }))
-}
-
-/// Extracts a string literal from the macro expanded version of `expr`,
-/// emitting `err_msg` if `expr` is not a string literal. This does not stop
-/// compilation on error, merely emits a non-fatal error and returns `Err`.
-pub fn expr_to_string(
- cx: &mut ExtCtxt<'_>,
- expr: P,
- err_msg: &'static str,
-) -> ExpandResult, ()> {
- expr_to_spanned_string(cx, expr, err_msg).map(|res| {
- res.map_err(|err| match err {
- Ok((err, _)) => err.emit(),
- Err(guar) => guar,
- })
- .map(|(symbol, style, _)| (symbol, style))
- })
-}
-
-/// Non-fatally assert that `tts` is empty. Note that this function
-/// returns even when `tts` is non-empty, macros that *need* to stop
-/// compilation should call `cx.diagnostic().abort_if_errors()`
-/// (this should be done as rarely as possible).
-pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) {
- if !tts.is_empty() {
- cx.dcx().emit_err(errors::TakesNoArguments { span, name });
- }
-}
-
-/// Parse an expression. On error, emit it, advancing to `Eof`, and return `Err`.
-pub fn parse_expr(p: &mut parser::Parser<'_>) -> Result, ErrorGuaranteed> {
- let guar = match p.parse_expr() {
- Ok(expr) => return Ok(expr),
- Err(err) => err.emit(),
- };
- while p.token != token::Eof {
- p.bump();
- }
- Err(guar)
-}
-
-/// Interpreting `tts` as a comma-separated sequence of expressions,
-/// expect exactly one string literal, or emit an error and return `Err`.
-pub fn get_single_str_from_tts(
- cx: &mut ExtCtxt<'_>,
- span: Span,
- tts: TokenStream,
- name: &str,
-) -> ExpandResult, ()> {
- get_single_str_spanned_from_tts(cx, span, tts, name).map(|res| res.map(|(s, _)| s))
-}
-
-pub fn get_single_str_spanned_from_tts(
- cx: &mut ExtCtxt<'_>,
- span: Span,
- tts: TokenStream,
- name: &str,
-) -> ExpandResult, ()> {
- let mut p = cx.new_parser_from_tts(tts);
- if p.token == token::Eof {
- let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
- return ExpandResult::Ready(Err(guar));
- }
- let ret = match parse_expr(&mut p) {
- Ok(ret) => ret,
- Err(guar) => return ExpandResult::Ready(Err(guar)),
- };
- let _ = p.eat(&token::Comma);
-
- if p.token != token::Eof {
- cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
- }
- expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| {
- res.map_err(|err| match err {
- Ok((err, _)) => err.emit(),
- Err(guar) => guar,
- })
- .map(|(symbol, _style, span)| (symbol, span))
- })
-}
-
-/// Extracts comma-separated expressions from `tts`.
-/// On error, emit it, and return `Err`.
-pub fn get_exprs_from_tts(
- cx: &mut ExtCtxt<'_>,
- tts: TokenStream,
-) -> ExpandResult>, ErrorGuaranteed>, ()> {
- let mut p = cx.new_parser_from_tts(tts);
- let mut es = Vec::new();
- while p.token != token::Eof {
- let expr = match parse_expr(&mut p) {
- Ok(expr) => expr,
- Err(guar) => return ExpandResult::Ready(Err(guar)),
- };
- if !cx.force_mode
- && let ast::ExprKind::MacCall(m) = &expr.kind
- && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err()
- {
- return ExpandResult::Retry(());
- }
-
- // Perform eager expansion on the expression.
- // We want to be able to handle e.g., `concat!("foo", "bar")`.
- let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
-
- es.push(expr);
- if p.eat(&token::Comma) {
- continue;
- }
- if p.token != token::Eof {
- let guar = cx.dcx().emit_err(errors::ExpectedCommaInList { span: p.token.span });
- return ExpandResult::Ready(Err(guar));
- }
- }
- ExpandResult::Ready(Ok(es))
-}
-
pub fn parse_macro_name_and_helper_attrs(
dcx: &rustc_errors::DiagCtxt,
attr: &Attribute,
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index 21ce5e1d81e6..db8e4ba07e80 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -152,29 +152,6 @@ pub(crate) struct HelperAttributeNameInvalid {
pub name: Ident,
}
-#[derive(Diagnostic)]
-#[diag(expand_expected_comma_in_list)]
-pub(crate) struct ExpectedCommaInList {
- #[primary_span]
- pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(expand_only_one_argument)]
-pub(crate) struct OnlyOneArgument<'a> {
- #[primary_span]
- pub span: Span,
- pub name: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(expand_takes_no_arguments)]
-pub(crate) struct TakesNoArguments<'a> {
- #[primary_span]
- pub span: Span,
- pub name: &'a str,
-}
-
#[derive(Diagnostic)]
#[diag(expand_feature_removed, code = E0557)]
pub(crate) struct FeatureRemoved<'a> {
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 6029caa965c0..909197d90b66 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -482,7 +482,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
derive_invocations.reserve(derives.len());
derives
.into_iter()
- .map(|(path, item, _exts, is_const)| {
+ .map(|DeriveResolution { path, item, exts: _, is_const }| {
// FIXME: Consider using the derive resolutions (`_exts`)
// instead of enqueuing the derives to be resolved again later.
let expn_id = LocalExpnId::fresh_empty();
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 1b6387acf71e..a33d45990e78 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1304,11 +1304,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
visit::walk_item(self, item);
macro_rules_scope
}
- ItemKind::MacCall(..) => {
- let macro_rules_scope = self.visit_invoc_in_module(item.id);
- visit::walk_item(self, item);
- macro_rules_scope
- }
+ ItemKind::MacCall(..) => self.visit_invoc_in_module(item.id),
_ => {
let orig_macro_rules_scope = self.parent_scope.macro_rules;
self.build_reduced_graph_for_item(item);
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index bef95aca0d1c..c29131a5fb1e 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -136,14 +136,9 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
opt_macro_data = Some(macro_data);
DefKind::Macro(macro_kind)
}
- ItemKind::MacCall(..) => {
- visit::walk_item(self, i);
- return self.visit_macro_invoc(i.id);
- }
ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
- ItemKind::Use(..) => {
- return visit::walk_item(self, i);
- }
+ ItemKind::Use(..) => return visit::walk_item(self, i),
+ ItemKind::MacCall(..) => return self.visit_macro_invoc(i.id),
};
let def_id = self.create_def(i.id, i.ident.name, def_kind, i.span);
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index e07c3247d07a..af0b4792136c 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -38,7 +38,7 @@ use rustc_data_structures::intern::Interned;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{FreezeReadGuard, Lrc};
use rustc_errors::{Applicability, Diag, ErrCode};
-use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
+use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind};
use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::NonMacroAttrKind;
@@ -959,7 +959,7 @@ enum BuiltinMacroState {
}
struct DeriveData {
- resolutions: DeriveResolutions,
+ resolutions: Vec,
helper_attrs: Vec<(usize, Ident)>,
has_derive_copy: bool,
}
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 2a23ed71753f..82e41b6c3143 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -15,7 +15,7 @@ use rustc_attr::StabilityLevel;
use rustc_data_structures::intern::Interned;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, StashKey};
-use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand};
+use rustc_expand::base::{Annotatable, DeriveResolution, Indeterminate, ResolverExpand};
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::compile_declarative_macro;
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
@@ -344,7 +344,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
&mut self,
expn_id: LocalExpnId,
force: bool,
- derive_paths: &dyn Fn() -> DeriveResolutions,
+ derive_paths: &dyn Fn() -> Vec,
) -> Result<(), Indeterminate> {
// Block expansion of the container until we resolve all derives in it.
// This is required for two reasons:
@@ -360,11 +360,11 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
has_derive_copy: false,
});
let parent_scope = self.invocation_parent_scopes[&expn_id];
- for (i, (path, _, opt_ext, _)) in entry.resolutions.iter_mut().enumerate() {
- if opt_ext.is_none() {
- *opt_ext = Some(
+ for (i, resolution) in entry.resolutions.iter_mut().enumerate() {
+ if resolution.exts.is_none() {
+ resolution.exts = Some(
match self.resolve_macro_path(
- path,
+ &resolution.path,
Some(MacroKind::Derive),
&parent_scope,
true,
@@ -372,7 +372,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
) {
Ok((Some(ext), _)) => {
if !ext.helper_attrs.is_empty() {
- let last_seg = path.segments.last().unwrap();
+ let last_seg = resolution.path.segments.last().unwrap();
let span = last_seg.ident.span.normalize_to_macros_2_0();
entry.helper_attrs.extend(
ext.helper_attrs
@@ -416,7 +416,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
Ok(())
}
- fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option {
+ fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option> {
self.derive_data.remove(&expn_id).map(|data| data.resolutions)
}
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 20ebe1c4f8a0..9dd3d7d3fa16 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -532,6 +532,12 @@ impl OsString {
let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
unsafe { Box::from_raw(rw) }
}
+
+ /// Part of a hack to make PathBuf::push/pop more efficient.
+ #[inline]
+ pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec {
+ self.inner.as_mut_vec_for_path_buf()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 1c58671a0cf7..85355435100c 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1158,12 +1158,6 @@ impl FusedIterator for Ancestors<'_> {}
/// Which method works best depends on what kind of situation you're in.
#[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
#[stable(feature = "rust1", since = "1.0.0")]
-// `PathBuf::as_mut_vec` current implementation relies
-// on `PathBuf` being layout-compatible with `Vec`.
-// However, `PathBuf` layout is considered an implementation detail and must not be relied upon. We
-// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
-// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
-#[cfg_attr(not(doc), repr(transparent))]
pub struct PathBuf {
inner: OsString,
}
@@ -1171,7 +1165,7 @@ pub struct PathBuf {
impl PathBuf {
#[inline]
fn as_mut_vec(&mut self) -> &mut Vec {
- unsafe { &mut *(self as *mut PathBuf as *mut Vec) }
+ self.inner.as_mut_vec_for_path_buf()
}
/// Allocates an empty `PathBuf`.
diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs
index 4ca3f1cd1853..3076e18b237d 100644
--- a/library/std/src/sys/os_str/bytes.rs
+++ b/library/std/src/sys/os_str/bytes.rs
@@ -198,6 +198,12 @@ impl Buf {
pub fn into_rc(&self) -> Rc {
self.as_slice().into_rc()
}
+
+ /// Part of a hack to make PathBuf::push/pop more efficient.
+ #[inline]
+ pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec {
+ &mut self.inner
+ }
}
impl Slice {
diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs
index 352bd7359033..b3ceb55802dc 100644
--- a/library/std/src/sys/os_str/wtf8.rs
+++ b/library/std/src/sys/os_str/wtf8.rs
@@ -158,6 +158,12 @@ impl Buf {
pub fn into_rc(&self) -> Rc {
self.as_slice().into_rc()
}
+
+ /// Part of a hack to make PathBuf::push/pop more efficient.
+ #[inline]
+ pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec {
+ self.inner.as_mut_vec_for_path_buf()
+ }
}
impl Slice {
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index 2dbd19d71719..38e15f9f5496 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -468,6 +468,12 @@ impl Wtf8Buf {
let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) };
Wtf8Buf { bytes: bytes.into_vec(), is_known_utf8: false }
}
+
+ /// Part of a hack to make PathBuf::push/pop more efficient.
+ #[inline]
+ pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec {
+ &mut self.bytes
+ }
}
/// Creates a new WTF-8 string from an iterator of code points.
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 9b3c0d0f1a57..1b560ee352c6 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -220,7 +220,6 @@ run-make/pretty-print-to-file/Makefile
run-make/pretty-print-with-dep-file/Makefile
run-make/print-calling-conventions/Makefile
run-make/print-cfg/Makefile
-run-make/print-native-static-libs/Makefile
run-make/print-target-list/Makefile
run-make/profile/Makefile
run-make/prune-link-args/Makefile
diff --git a/tests/crashes/124262.rs b/tests/crashes/124262.rs
new file mode 100644
index 000000000000..b9dac5eca227
--- /dev/null
+++ b/tests/crashes/124262.rs
@@ -0,0 +1,5 @@
+//@ known-bug: #124262
+//@ edition:2021
+
+struct Foo(<&[fn()] as ::core::ops::Deref>::Target);
+const _: *const Foo = 0 as _;
diff --git a/tests/crashes/124340.rs b/tests/crashes/124340.rs
new file mode 100644
index 000000000000..cdf24fa03959
--- /dev/null
+++ b/tests/crashes/124340.rs
@@ -0,0 +1,17 @@
+//@ known-bug: #124340
+#![feature(anonymous_lifetime_in_impl_trait)]
+
+trait Producer {
+ type Output;
+ fn produce(self) -> Self::Output;
+}
+
+trait SomeTrait<'a> {}
+
+fn force_same_lifetime<'a>(_x: &'a i32, _y: impl SomeTrait<'a>) {
+ unimplemented!()
+}
+
+fn foo<'a>(s: &'a i32, producer: impl Producer>) {
+ force_same_lifetime(s, producer.produce());
+}
diff --git a/tests/crashes/124342.rs b/tests/crashes/124342.rs
new file mode 100644
index 000000000000..ae51b3db96f5
--- /dev/null
+++ b/tests/crashes/124342.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #124342
+trait Trait2 : Trait {
+ reuse <() as Trait>::async {
+ (async || {}).await;
+ };
+}
diff --git a/tests/crashes/124347.rs b/tests/crashes/124347.rs
new file mode 100644
index 000000000000..d2bc555fe1c7
--- /dev/null
+++ b/tests/crashes/124347.rs
@@ -0,0 +1,4 @@
+//@ known-bug: #124347
+trait Trait: ToReuse {
+ reuse Trait::lolno { &self.0 };
+}
diff --git a/tests/crashes/124348.rs b/tests/crashes/124348.rs
new file mode 100644
index 000000000000..554f383026cb
--- /dev/null
+++ b/tests/crashes/124348.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #124348
+enum Eek {
+ TheConst,
+ UnusedByTheConst(Sum),
+}
+
+const EEK_ZERO: &[Eek] = &[];
diff --git a/tests/crashes/124350.rs b/tests/crashes/124350.rs
new file mode 100644
index 000000000000..d6038f280cf8
--- /dev/null
+++ b/tests/crashes/124350.rs
@@ -0,0 +1,17 @@
+//@ known-bug: #124350
+
+struct Node {}
+
+impl Node
+where
+ SmallVec<{ D * 2 }>:,
+{
+ fn new() -> Self {
+ let mut node = Node::new();
+ (&a, 0)();
+
+ node
+ }
+}
+
+struct SmallVec {}
diff --git a/tests/crashes/124352.rs b/tests/crashes/124352.rs
new file mode 100644
index 000000000000..e9eb4419e6a4
--- /dev/null
+++ b/tests/crashes/124352.rs
@@ -0,0 +1,4 @@
+//@ known-bug: #124352
+#![rustc_never_type_options(: Unsize = "hi")]
+
+fn main() {}
diff --git a/tests/crashes/124375.rs b/tests/crashes/124375.rs
new file mode 100644
index 000000000000..7165655178d7
--- /dev/null
+++ b/tests/crashes/124375.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #124375
+//@ compile-flags: -Zmir-opt-level=0
+//@ only-x86_64
+#![crate_type = "lib"]
+#![feature(naked_functions)]
+use std::arch::asm;
+
+#[naked]
+pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
+ asm!("lea rax, [rdi + rsi]", "ret", options(noreturn));
+}
diff --git a/tests/crashes/92470.rs b/tests/crashes/92470.rs
new file mode 100644
index 000000000000..a3c518f5ec62
--- /dev/null
+++ b/tests/crashes/92470.rs
@@ -0,0 +1,31 @@
+//@ known-bug: #92470
+fn main() {
+ encode(&mut EncoderImpl);
+}
+
+pub trait Encoder {
+ type W;
+
+ fn writer(&self) -> Self::W;
+}
+
+fn encode(mut encoder: E) {
+ encoder.writer();
+ encode(&mut encoder);
+}
+
+struct EncoderImpl;
+
+impl Encoder for EncoderImpl {
+ type W = ();
+
+ fn writer(&self) {}
+}
+
+impl<'a, T: Encoder> Encoder for &'a mut T {
+ type W = T::W;
+
+ fn writer(&self) -> Self::W {
+ panic!()
+ }
+}
diff --git a/tests/run-make/print-native-static-libs/Makefile b/tests/run-make/print-native-static-libs/Makefile
deleted file mode 100644
index a16c8b0f2a40..000000000000
--- a/tests/run-make/print-native-static-libs/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-include ../tools.mk
-
-# ignore-cross-compile
-# ignore-wasm
-
-all:
- $(RUSTC) --crate-type rlib -lbar_cli bar.rs
- $(RUSTC) foo.rs -lfoo_cli -lfoo_cli --crate-type staticlib --print native-static-libs 2>&1 \
- | grep 'note: native-static-libs: ' \
- | sed 's/note: native-static-libs: \(.*\)/\1/' > $(TMPDIR)/libs.txt
-
- cat $(TMPDIR)/libs.txt | grep -F "glib-2.0" # in bar.rs
- cat $(TMPDIR)/libs.txt | grep -F "systemd" # in foo.rs
- cat $(TMPDIR)/libs.txt | grep -F "bar_cli"
- cat $(TMPDIR)/libs.txt | grep -F "foo_cli"
-
- # make sure that foo_cli and glib-2.0 are not consecutively present
- cat $(TMPDIR)/libs.txt | grep -Fv "foo_cli -lfoo_cli"
- cat $(TMPDIR)/libs.txt | grep -Fv "glib-2.0 -lglib-2.0"
diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs
new file mode 100644
index 000000000000..efc51d276efc
--- /dev/null
+++ b/tests/run-make/print-native-static-libs/rmake.rs
@@ -0,0 +1,63 @@
+//! This checks the output of `--print=native-static-libs`
+//!
+//! Specifically, this test makes sure that one and only one
+//! note is emitted with the text "native-static-libs:" as prefix
+//! that the note contains the link args given in the source code
+//! and cli of the current crate and downstream crates.
+//!
+//! It also checks that there aren't any duplicated consecutive
+//! args, as they are useless and suboptimal for debugability.
+//! See https://github.com/rust-lang/rust/issues/113209.
+
+//@ ignore-cross-compile
+//@ ignore-wasm
+
+extern crate run_make_support;
+
+use std::io::BufRead;
+
+use run_make_support::rustc;
+
+fn main() {
+ // build supporting crate
+ rustc()
+ .input("bar.rs")
+ .crate_type("rlib")
+ .arg("-lbar_cli")
+ .run();
+
+ // build main crate as staticlib
+ let output = rustc()
+ .input("foo.rs")
+ .crate_type("staticlib")
+ .arg("-lfoo_cli")
+ .arg("-lfoo_cli") // 2nd time
+ .print("native-static-libs")
+ .run();
+
+ let mut found_note = false;
+ for l in output.stderr.lines() {
+ let l = l.expect("utf-8 string");
+
+ let Some(args) = l.strip_prefix("note: native-static-libs:") else { continue; };
+ assert!(!found_note);
+ found_note = true;
+
+ let args: Vec<&str> = args.trim().split_ascii_whitespace().collect();
+
+ assert!(args.contains(&"-lglib-2.0")); // in bar.rs
+ assert!(args.contains(&"-lsystemd")); // in foo.rs
+ assert!(args.contains(&"-lbar_cli"));
+ assert!(args.contains(&"-lfoo_cli"));
+
+ // make sure that no args are consecutively present
+ let dedup_args: Vec<&str> = {
+ let mut args = args.clone();
+ args.dedup();
+ args
+ };
+ assert_eq!(args, dedup_args);
+ }
+
+ assert!(found_note);
+}