Auto merge of #104696 - matthiaskrgr:rollup-gi1pdb0, r=matthiaskrgr
Rollup of 11 pull requests Successful merges: - #103396 (Pin::new_unchecked: discuss pinning closure captures) - #104416 (Fix using `include_bytes` in pattern position) - #104557 (Add a test case for async dyn* traits) - #104559 (Split `MacArgs` in two.) - #104597 (Probe + better error messsage for `need_migrate_deref_output_trait_object`) - #104656 (Move tests) - #104657 (Do not check transmute if has non region infer) - #104663 (rustdoc: factor out common button CSS) - #104666 (Migrate alias search result to CSS variables) - #104674 (Make negative_impl and negative_impl_exists take the right types) - #104692 (Update test's cfg-if dependency to 1.0) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0f7d81754d
68 changed files with 496 additions and 359 deletions
|
@ -498,10 +498,6 @@ name = "cfg-if"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
dependencies = [
|
|
||||||
"compiler_builtins",
|
|
||||||
"rustc-std-workspace-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -4934,7 +4930,7 @@ dependencies = [
|
||||||
name = "test"
|
name = "test"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 1.0.0",
|
||||||
"core",
|
"core",
|
||||||
"getopts",
|
"getopts",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
|
@ -1544,55 +1544,48 @@ pub enum ClosureBinder {
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub struct MacCall {
|
pub struct MacCall {
|
||||||
pub path: Path,
|
pub path: Path,
|
||||||
pub args: P<MacArgs>,
|
pub args: P<DelimArgs>,
|
||||||
pub prior_type_ascription: Option<(Span, bool)>,
|
pub prior_type_ascription: Option<(Span, bool)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacCall {
|
impl MacCall {
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
self.path.span.to(self.args.span().unwrap_or(self.path.span))
|
self.path.span.to(self.args.dspan.entire())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Arguments passed to an attribute or a function-like macro.
|
/// Arguments passed to an attribute macro.
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum MacArgs {
|
pub enum AttrArgs {
|
||||||
/// No arguments - `#[attr]`.
|
/// No arguments: `#[attr]`.
|
||||||
Empty,
|
Empty,
|
||||||
/// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`.
|
/// Delimited arguments: `#[attr()/[]/{}]`.
|
||||||
Delimited(DelimSpan, MacDelimiter, TokenStream),
|
Delimited(DelimArgs),
|
||||||
/// Arguments of a key-value attribute - `#[attr = "value"]`.
|
/// Arguments of a key-value attribute: `#[attr = "value"]`.
|
||||||
Eq(
|
Eq(
|
||||||
/// Span of the `=` token.
|
/// Span of the `=` token.
|
||||||
Span,
|
Span,
|
||||||
/// The "value".
|
/// The "value".
|
||||||
MacArgsEq,
|
AttrArgsEq,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
// The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion
|
// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro
|
||||||
// is completed, all cases end up either as a literal, which is the form used
|
// expansion is completed, all cases end up either as a literal, which is the
|
||||||
// after lowering to HIR, or as an error.
|
// form used after lowering to HIR, or as an error.
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum MacArgsEq {
|
pub enum AttrArgsEq {
|
||||||
Ast(P<Expr>),
|
Ast(P<Expr>),
|
||||||
Hir(Lit),
|
Hir(Lit),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacArgs {
|
impl AttrArgs {
|
||||||
pub fn delim(&self) -> Option<Delimiter> {
|
|
||||||
match self {
|
|
||||||
MacArgs::Delimited(_, delim, _) => Some(delim.to_token()),
|
|
||||||
MacArgs::Empty | MacArgs::Eq(..) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn span(&self) -> Option<Span> {
|
pub fn span(&self) -> Option<Span> {
|
||||||
match self {
|
match self {
|
||||||
MacArgs::Empty => None,
|
AttrArgs::Empty => None,
|
||||||
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
|
AttrArgs::Delimited(args) => Some(args.dspan.entire()),
|
||||||
MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)),
|
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)),
|
||||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||||
unreachable!("in literal form when getting span: {:?}", lit);
|
unreachable!("in literal form when getting span: {:?}", lit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1602,39 +1595,29 @@ impl MacArgs {
|
||||||
/// Proc macros see these tokens, for example.
|
/// Proc macros see these tokens, for example.
|
||||||
pub fn inner_tokens(&self) -> TokenStream {
|
pub fn inner_tokens(&self) -> TokenStream {
|
||||||
match self {
|
match self {
|
||||||
MacArgs::Empty => TokenStream::default(),
|
AttrArgs::Empty => TokenStream::default(),
|
||||||
MacArgs::Delimited(.., tokens) => tokens.clone(),
|
AttrArgs::Delimited(args) => args.tokens.clone(),
|
||||||
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => TokenStream::from_ast(expr),
|
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr),
|
||||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||||
unreachable!("in literal form when getting inner tokens: {:?}", lit)
|
unreachable!("in literal form when getting inner tokens: {:?}", lit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether a macro with these arguments needs a semicolon
|
|
||||||
/// when used as a standalone item or statement.
|
|
||||||
pub fn need_semicolon(&self) -> bool {
|
|
||||||
!matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace, _))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CTX> HashStable<CTX> for MacArgs
|
impl<CTX> HashStable<CTX> for AttrArgs
|
||||||
where
|
where
|
||||||
CTX: crate::HashStableContext,
|
CTX: crate::HashStableContext,
|
||||||
{
|
{
|
||||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||||
mem::discriminant(self).hash_stable(ctx, hasher);
|
mem::discriminant(self).hash_stable(ctx, hasher);
|
||||||
match self {
|
match self {
|
||||||
MacArgs::Empty => {}
|
AttrArgs::Empty => {}
|
||||||
MacArgs::Delimited(dspan, delim, tokens) => {
|
AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher),
|
||||||
dspan.hash_stable(ctx, hasher);
|
AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => {
|
||||||
delim.hash_stable(ctx, hasher);
|
|
||||||
tokens.hash_stable(ctx, hasher);
|
|
||||||
}
|
|
||||||
MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => {
|
|
||||||
unreachable!("hash_stable {:?}", expr);
|
unreachable!("hash_stable {:?}", expr);
|
||||||
}
|
}
|
||||||
MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) => {
|
AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => {
|
||||||
eq_span.hash_stable(ctx, hasher);
|
eq_span.hash_stable(ctx, hasher);
|
||||||
lit.hash_stable(ctx, hasher);
|
lit.hash_stable(ctx, hasher);
|
||||||
}
|
}
|
||||||
|
@ -1642,6 +1625,34 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`.
|
||||||
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
pub struct DelimArgs {
|
||||||
|
pub dspan: DelimSpan,
|
||||||
|
pub delim: MacDelimiter,
|
||||||
|
pub tokens: TokenStream,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DelimArgs {
|
||||||
|
/// Whether a macro with these arguments needs a semicolon
|
||||||
|
/// when used as a standalone item or statement.
|
||||||
|
pub fn need_semicolon(&self) -> bool {
|
||||||
|
!matches!(self, DelimArgs { delim: MacDelimiter::Brace, .. })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<CTX> HashStable<CTX> for DelimArgs
|
||||||
|
where
|
||||||
|
CTX: crate::HashStableContext,
|
||||||
|
{
|
||||||
|
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||||
|
let DelimArgs { dspan, delim, tokens } = self;
|
||||||
|
dspan.hash_stable(ctx, hasher);
|
||||||
|
delim.hash_stable(ctx, hasher);
|
||||||
|
tokens.hash_stable(ctx, hasher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
pub enum MacDelimiter {
|
pub enum MacDelimiter {
|
||||||
Parenthesis,
|
Parenthesis,
|
||||||
|
@ -1671,7 +1682,7 @@ impl MacDelimiter {
|
||||||
/// Represents a macro definition.
|
/// Represents a macro definition.
|
||||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
pub struct MacroDef {
|
pub struct MacroDef {
|
||||||
pub body: P<MacArgs>,
|
pub body: P<DelimArgs>,
|
||||||
/// `true` if macro was defined with `macro_rules`.
|
/// `true` if macro was defined with `macro_rules`.
|
||||||
pub macro_rules: bool,
|
pub macro_rules: bool,
|
||||||
}
|
}
|
||||||
|
@ -2534,7 +2545,7 @@ impl<D: Decoder> Decodable<D> for AttrId {
|
||||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
pub struct AttrItem {
|
pub struct AttrItem {
|
||||||
pub path: Path,
|
pub path: Path,
|
||||||
pub args: MacArgs,
|
pub args: AttrArgs,
|
||||||
pub tokens: Option<LazyAttrTokenStream>,
|
pub tokens: Option<LazyAttrTokenStream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//! Functions dealing with attributes and meta items.
|
//! Functions dealing with attributes and meta items.
|
||||||
|
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
|
use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
|
||||||
use crate::ast::{Lit, LitKind};
|
use crate::ast::{DelimArgs, Lit, LitKind};
|
||||||
use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
|
use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
|
||||||
use crate::ast::{Path, PathSegment};
|
use crate::ast::{Path, PathSegment};
|
||||||
use crate::ptr::P;
|
use crate::ptr::P;
|
||||||
use crate::token::{self, CommentKind, Delimiter, Token};
|
use crate::token::{self, CommentKind, Delimiter, Token};
|
||||||
|
@ -158,7 +158,7 @@ impl Attribute {
|
||||||
|
|
||||||
pub fn is_word(&self) -> bool {
|
pub fn is_word(&self) -> bool {
|
||||||
if let AttrKind::Normal(normal) = &self.kind {
|
if let AttrKind::Normal(normal) = &self.kind {
|
||||||
matches!(normal.item.args, MacArgs::Empty)
|
matches!(normal.item.args, AttrArgs::Empty)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -223,13 +223,13 @@ impl AttrItem {
|
||||||
pub fn meta(&self, span: Span) -> Option<MetaItem> {
|
pub fn meta(&self, span: Span) -> Option<MetaItem> {
|
||||||
Some(MetaItem {
|
Some(MetaItem {
|
||||||
path: self.path.clone(),
|
path: self.path.clone(),
|
||||||
kind: MetaItemKind::from_mac_args(&self.args)?,
|
kind: MetaItemKind::from_attr_args(&self.args)?,
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn meta_kind(&self) -> Option<MetaItemKind> {
|
pub fn meta_kind(&self) -> Option<MetaItemKind> {
|
||||||
MetaItemKind::from_mac_args(&self.args)
|
MetaItemKind::from_attr_args(&self.args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +390,7 @@ pub fn mk_attr(
|
||||||
g: &AttrIdGenerator,
|
g: &AttrIdGenerator,
|
||||||
style: AttrStyle,
|
style: AttrStyle,
|
||||||
path: Path,
|
path: Path,
|
||||||
args: MacArgs,
|
args: AttrArgs,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Attribute {
|
) -> Attribute {
|
||||||
mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span)
|
mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span)
|
||||||
|
@ -413,12 +413,12 @@ pub fn mk_attr_from_item(
|
||||||
|
|
||||||
/// Returns an inner attribute with the given value and span.
|
/// Returns an inner attribute with the given value and span.
|
||||||
pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
|
pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
|
||||||
mk_attr(g, AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.span)
|
mk_attr(g, AttrStyle::Inner, item.path, item.kind.attr_args(item.span), item.span)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an outer attribute with the given value and span.
|
/// Returns an outer attribute with the given value and span.
|
||||||
pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
|
pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
|
||||||
mk_attr(g, AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.span)
|
mk_attr(g, AttrStyle::Outer, item.path, item.kind.attr_args(item.span), item.span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_doc_comment(
|
pub fn mk_doc_comment(
|
||||||
|
@ -524,9 +524,9 @@ impl MetaItemKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mac_args(&self, span: Span) -> MacArgs {
|
pub fn attr_args(&self, span: Span) -> AttrArgs {
|
||||||
match self {
|
match self {
|
||||||
MetaItemKind::Word => MacArgs::Empty,
|
MetaItemKind::Word => AttrArgs::Empty,
|
||||||
MetaItemKind::NameValue(lit) => {
|
MetaItemKind::NameValue(lit) => {
|
||||||
let expr = P(ast::Expr {
|
let expr = P(ast::Expr {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -535,7 +535,7 @@ impl MetaItemKind {
|
||||||
attrs: ast::AttrVec::new(),
|
attrs: ast::AttrVec::new(),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
});
|
});
|
||||||
MacArgs::Eq(span, MacArgsEq::Ast(expr))
|
AttrArgs::Eq(span, AttrArgsEq::Ast(expr))
|
||||||
}
|
}
|
||||||
MetaItemKind::List(list) => {
|
MetaItemKind::List(list) => {
|
||||||
let mut tts = Vec::new();
|
let mut tts = Vec::new();
|
||||||
|
@ -545,11 +545,11 @@ impl MetaItemKind {
|
||||||
}
|
}
|
||||||
tts.extend(item.token_trees())
|
tts.extend(item.token_trees())
|
||||||
}
|
}
|
||||||
MacArgs::Delimited(
|
AttrArgs::Delimited(DelimArgs {
|
||||||
DelimSpan::from_single(span),
|
dspan: DelimSpan::from_single(span),
|
||||||
MacDelimiter::Parenthesis,
|
delim: MacDelimiter::Parenthesis,
|
||||||
TokenStream::new(tts),
|
tokens: TokenStream::new(tts),
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -608,20 +608,22 @@ impl MetaItemKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> {
|
fn from_attr_args(args: &AttrArgs) -> Option<MetaItemKind> {
|
||||||
match args {
|
match args {
|
||||||
MacArgs::Empty => Some(MetaItemKind::Word),
|
AttrArgs::Empty => Some(MetaItemKind::Word),
|
||||||
MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => {
|
AttrArgs::Delimited(DelimArgs {
|
||||||
MetaItemKind::list_from_tokens(tokens.clone())
|
dspan: _,
|
||||||
}
|
delim: MacDelimiter::Parenthesis,
|
||||||
MacArgs::Delimited(..) => None,
|
tokens,
|
||||||
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => match expr.kind {
|
}) => MetaItemKind::list_from_tokens(tokens.clone()),
|
||||||
|
AttrArgs::Delimited(..) => None,
|
||||||
|
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind {
|
||||||
ast::ExprKind::Lit(token_lit) => Some(MetaItemKind::NameValue(
|
ast::ExprKind::Lit(token_lit) => Some(MetaItemKind::NameValue(
|
||||||
Lit::from_token_lit(token_lit, expr.span).expect("token_lit in from_mac_args"),
|
Lit::from_token_lit(token_lit, expr.span).expect("token_lit in from_attr_args"),
|
||||||
)),
|
)),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())),
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -367,23 +367,27 @@ pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis
|
||||||
}
|
}
|
||||||
|
|
||||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||||
pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) {
|
pub fn visit_attr_args<T: MutVisitor>(args: &mut AttrArgs, vis: &mut T) {
|
||||||
match args {
|
match args {
|
||||||
MacArgs::Empty => {}
|
AttrArgs::Empty => {}
|
||||||
MacArgs::Delimited(dspan, _delim, tokens) => {
|
AttrArgs::Delimited(args) => visit_delim_args(args, vis),
|
||||||
visit_delim_span(dspan, vis);
|
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
|
||||||
visit_tts(tokens, vis);
|
|
||||||
}
|
|
||||||
MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => {
|
|
||||||
vis.visit_span(eq_span);
|
vis.visit_span(eq_span);
|
||||||
vis.visit_expr(expr);
|
vis.visit_expr(expr);
|
||||||
}
|
}
|
||||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||||
unreachable!("in literal form when visiting mac args eq: {:?}", lit)
|
unreachable!("in literal form when visiting mac args eq: {:?}", lit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||||
|
pub fn visit_delim_args<T: MutVisitor>(args: &mut DelimArgs, vis: &mut T) {
|
||||||
|
let DelimArgs { dspan, delim: _, tokens } = args;
|
||||||
|
visit_delim_span(dspan, vis);
|
||||||
|
visit_tts(tokens, vis);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) {
|
pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) {
|
||||||
vis.visit_span(&mut dspan.open);
|
vis.visit_span(&mut dspan.open);
|
||||||
vis.visit_span(&mut dspan.close);
|
vis.visit_span(&mut dspan.close);
|
||||||
|
@ -601,7 +605,7 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
|
||||||
let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } =
|
let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } =
|
||||||
&mut **normal;
|
&mut **normal;
|
||||||
vis.visit_path(path);
|
vis.visit_path(path);
|
||||||
visit_mac_args(args, vis);
|
visit_attr_args(args, vis);
|
||||||
visit_lazy_tts(tokens, vis);
|
visit_lazy_tts(tokens, vis);
|
||||||
visit_lazy_tts(attr_tokens, vis);
|
visit_lazy_tts(attr_tokens, vis);
|
||||||
}
|
}
|
||||||
|
@ -613,12 +617,12 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
|
||||||
pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) {
|
pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) {
|
||||||
let MacCall { path, args, prior_type_ascription: _ } = mac;
|
let MacCall { path, args, prior_type_ascription: _ } = mac;
|
||||||
vis.visit_path(path);
|
vis.visit_path(path);
|
||||||
visit_mac_args(args, vis);
|
visit_delim_args(args, vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) {
|
pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) {
|
||||||
let MacroDef { body, macro_rules: _ } = macro_def;
|
let MacroDef { body, macro_rules: _ } = macro_def;
|
||||||
visit_mac_args(body, vis);
|
visit_delim_args(body, vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) {
|
pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) {
|
||||||
|
@ -792,7 +796,7 @@ pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T
|
||||||
token::NtMeta(item) => {
|
token::NtMeta(item) => {
|
||||||
let AttrItem { path, args, tokens } = item.deref_mut();
|
let AttrItem { path, args, tokens } = item.deref_mut();
|
||||||
vis.visit_path(path);
|
vis.visit_path(path);
|
||||||
visit_mac_args(args, vis);
|
visit_attr_args(args, vis);
|
||||||
visit_lazy_tts(tokens, vis);
|
visit_lazy_tts(tokens, vis);
|
||||||
}
|
}
|
||||||
token::NtPath(path) => vis.visit_path(path),
|
token::NtPath(path) => vis.visit_path(path),
|
||||||
|
|
|
@ -926,17 +926,17 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) {
|
||||||
|
|
||||||
pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) {
|
pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) {
|
||||||
match &attr.kind {
|
match &attr.kind {
|
||||||
AttrKind::Normal(normal) => walk_mac_args(visitor, &normal.item.args),
|
AttrKind::Normal(normal) => walk_attr_args(visitor, &normal.item.args),
|
||||||
AttrKind::DocComment(..) => {}
|
AttrKind::DocComment(..) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) {
|
pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) {
|
||||||
match args {
|
match args {
|
||||||
MacArgs::Empty => {}
|
AttrArgs::Empty => {}
|
||||||
MacArgs::Delimited(_dspan, _delim, _tokens) => {}
|
AttrArgs::Delimited(_) => {}
|
||||||
MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => visitor.visit_expr(expr),
|
AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => visitor.visit_expr(expr),
|
||||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||||
unreachable!("in literal form when walking mac args eq: {:?}", lit)
|
unreachable!("in literal form when walking mac args eq: {:?}", lit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -671,7 +671,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
kind: AttrKind::Normal(ptr::P(NormalAttr {
|
kind: AttrKind::Normal(ptr::P(NormalAttr {
|
||||||
item: AttrItem {
|
item: AttrItem {
|
||||||
path: Path::from_ident(Ident::new(sym::track_caller, span)),
|
path: Path::from_ident(Ident::new(sym::track_caller, span)),
|
||||||
args: MacArgs::Empty,
|
args: AttrArgs::Empty,
|
||||||
tokens: None,
|
tokens: None,
|
||||||
},
|
},
|
||||||
tokens: None,
|
tokens: None,
|
||||||
|
|
|
@ -470,7 +470,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::ItemKind::TraitAlias(generics, bounds)
|
hir::ItemKind::TraitAlias(generics, bounds)
|
||||||
}
|
}
|
||||||
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
|
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
|
||||||
let body = P(self.lower_mac_args(body));
|
let body = P(self.lower_delim_args(body));
|
||||||
let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id));
|
let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id));
|
||||||
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind)
|
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind)
|
||||||
}
|
}
|
||||||
|
|
|
@ -911,7 +911,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr {
|
AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr {
|
||||||
item: AttrItem {
|
item: AttrItem {
|
||||||
path: normal.item.path.clone(),
|
path: normal.item.path.clone(),
|
||||||
args: self.lower_mac_args(&normal.item.args),
|
args: self.lower_attr_args(&normal.item.args),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
},
|
},
|
||||||
tokens: None,
|
tokens: None,
|
||||||
|
@ -931,32 +931,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
|
fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs {
|
||||||
match *args {
|
match *args {
|
||||||
MacArgs::Empty => MacArgs::Empty,
|
AttrArgs::Empty => AttrArgs::Empty,
|
||||||
MacArgs::Delimited(dspan, delim, ref tokens) => {
|
AttrArgs::Delimited(ref args) => AttrArgs::Delimited(self.lower_delim_args(args)),
|
||||||
// This is either a non-key-value attribute, or a `macro_rules!` body.
|
|
||||||
// We either not have any nonterminals present (in the case of an attribute),
|
|
||||||
// or have tokens available for all nonterminals in the case of a nested
|
|
||||||
// `macro_rules`: e.g:
|
|
||||||
//
|
|
||||||
// ```rust
|
|
||||||
// macro_rules! outer {
|
|
||||||
// ($e:expr) => {
|
|
||||||
// macro_rules! inner {
|
|
||||||
// () => { $e }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ```
|
|
||||||
//
|
|
||||||
// In both cases, we don't want to synthesize any tokens
|
|
||||||
MacArgs::Delimited(dspan, delim, tokens.flattened())
|
|
||||||
}
|
|
||||||
// This is an inert key-value attribute - it will never be visible to macros
|
// This is an inert key-value attribute - it will never be visible to macros
|
||||||
// after it gets lowered to HIR. Therefore, we can extract literals to handle
|
// after it gets lowered to HIR. Therefore, we can extract literals to handle
|
||||||
// nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
|
// nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
|
||||||
MacArgs::Eq(eq_span, MacArgsEq::Ast(ref expr)) => {
|
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(ref expr)) => {
|
||||||
// In valid code the value always ends up as a single literal. Otherwise, a dummy
|
// In valid code the value always ends up as a single literal. Otherwise, a dummy
|
||||||
// literal suffices because the error is handled elsewhere.
|
// literal suffices because the error is handled elsewhere.
|
||||||
let lit = if let ExprKind::Lit(token_lit) = expr.kind {
|
let lit = if let ExprKind::Lit(token_lit) = expr.kind {
|
||||||
|
@ -975,14 +957,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MacArgs::Eq(eq_span, MacArgsEq::Hir(lit))
|
AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit))
|
||||||
}
|
}
|
||||||
MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => {
|
AttrArgs::Eq(_, AttrArgsEq::Hir(ref lit)) => {
|
||||||
unreachable!("in literal form when lowering mac args eq: {:?}", lit)
|
unreachable!("in literal form when lowering mac args eq: {:?}", lit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
|
||||||
|
DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
|
||||||
|
}
|
||||||
|
|
||||||
/// Given an associated type constraint like one of these:
|
/// Given an associated type constraint like one of these:
|
||||||
///
|
///
|
||||||
/// ```ignore (illustrative)
|
/// ```ignore (illustrative)
|
||||||
|
|
|
@ -11,10 +11,9 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
||||||
use rustc_ast::util::classify;
|
use rustc_ast::util::classify;
|
||||||
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
|
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
|
||||||
use rustc_ast::util::parser;
|
use rustc_ast::util::parser;
|
||||||
use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax};
|
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, Mutability, PatKind};
|
||||||
use rustc_ast::{attr, BindingAnnotation, ByRef, Term};
|
use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
|
||||||
use rustc_ast::{GenericArg, MacArgs, MacArgsEq};
|
use rustc_ast::{GenericArg, GenericBound, SelfKind, TraitBoundModifier};
|
||||||
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
|
|
||||||
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
|
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
|
||||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
|
@ -466,26 +465,26 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||||
fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
|
fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
|
||||||
self.ibox(0);
|
self.ibox(0);
|
||||||
match &item.args {
|
match &item.args {
|
||||||
MacArgs::Delimited(_, delim, tokens) => self.print_mac_common(
|
AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common(
|
||||||
Some(MacHeader::Path(&item.path)),
|
Some(MacHeader::Path(&item.path)),
|
||||||
false,
|
false,
|
||||||
None,
|
None,
|
||||||
Some(delim.to_token()),
|
delim.to_token(),
|
||||||
tokens,
|
tokens,
|
||||||
true,
|
true,
|
||||||
span,
|
span,
|
||||||
),
|
),
|
||||||
MacArgs::Empty => {
|
AttrArgs::Empty => {
|
||||||
self.print_path(&item.path, false, 0);
|
self.print_path(&item.path, false, 0);
|
||||||
}
|
}
|
||||||
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => {
|
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
|
||||||
self.print_path(&item.path, false, 0);
|
self.print_path(&item.path, false, 0);
|
||||||
self.space();
|
self.space();
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
let token_str = self.expr_to_string(expr);
|
let token_str = self.expr_to_string(expr);
|
||||||
self.word(token_str);
|
self.word(token_str);
|
||||||
}
|
}
|
||||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||||
self.print_path(&item.path, false, 0);
|
self.print_path(&item.path, false, 0);
|
||||||
self.space();
|
self.space();
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
|
@ -544,7 +543,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
None,
|
None,
|
||||||
Some(*delim),
|
*delim,
|
||||||
tts,
|
tts,
|
||||||
convert_dollar_crate,
|
convert_dollar_crate,
|
||||||
dspan.entire(),
|
dspan.entire(),
|
||||||
|
@ -570,12 +569,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||||
header: Option<MacHeader<'_>>,
|
header: Option<MacHeader<'_>>,
|
||||||
has_bang: bool,
|
has_bang: bool,
|
||||||
ident: Option<Ident>,
|
ident: Option<Ident>,
|
||||||
delim: Option<Delimiter>,
|
delim: Delimiter,
|
||||||
tts: &TokenStream,
|
tts: &TokenStream,
|
||||||
convert_dollar_crate: bool,
|
convert_dollar_crate: bool,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
if delim == Some(Delimiter::Brace) {
|
if delim == Delimiter::Brace {
|
||||||
self.cbox(INDENT_UNIT);
|
self.cbox(INDENT_UNIT);
|
||||||
}
|
}
|
||||||
match header {
|
match header {
|
||||||
|
@ -591,7 +590,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||||
self.print_ident(ident);
|
self.print_ident(ident);
|
||||||
}
|
}
|
||||||
match delim {
|
match delim {
|
||||||
Some(Delimiter::Brace) => {
|
Delimiter::Brace => {
|
||||||
if header.is_some() || has_bang || ident.is_some() {
|
if header.is_some() || has_bang || ident.is_some() {
|
||||||
self.nbsp();
|
self.nbsp();
|
||||||
}
|
}
|
||||||
|
@ -605,7 +604,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||||
let empty = tts.is_empty();
|
let empty = tts.is_empty();
|
||||||
self.bclose(span, empty);
|
self.bclose(span, empty);
|
||||||
}
|
}
|
||||||
Some(delim) => {
|
delim => {
|
||||||
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
|
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
|
||||||
self.word(token_str);
|
self.word(token_str);
|
||||||
self.ibox(0);
|
self.ibox(0);
|
||||||
|
@ -614,11 +613,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||||
let token_str = self.token_kind_to_string(&token::CloseDelim(delim));
|
let token_str = self.token_kind_to_string(&token::CloseDelim(delim));
|
||||||
self.word(token_str);
|
self.word(token_str);
|
||||||
}
|
}
|
||||||
None => {
|
|
||||||
self.ibox(0);
|
|
||||||
self.print_tts(tts, convert_dollar_crate);
|
|
||||||
self.end();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,8 +633,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||||
Some(MacHeader::Keyword(kw)),
|
Some(MacHeader::Keyword(kw)),
|
||||||
has_bang,
|
has_bang,
|
||||||
Some(*ident),
|
Some(*ident),
|
||||||
macro_def.body.delim(),
|
macro_def.body.delim.to_token(),
|
||||||
¯o_def.body.inner_tokens(),
|
¯o_def.body.tokens.clone(),
|
||||||
true,
|
true,
|
||||||
sp,
|
sp,
|
||||||
);
|
);
|
||||||
|
@ -1230,8 +1224,8 @@ impl<'a> State<'a> {
|
||||||
Some(MacHeader::Path(&m.path)),
|
Some(MacHeader::Path(&m.path)),
|
||||||
true,
|
true,
|
||||||
None,
|
None,
|
||||||
m.args.delim(),
|
m.args.delim.to_token(),
|
||||||
&m.args.inner_tokens(),
|
&m.args.tokens.clone(),
|
||||||
true,
|
true,
|
||||||
m.span(),
|
m.span(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::edition_panic::use_panic_2021;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
||||||
use rustc_ast::{Expr, ExprKind, MacArgs, MacCall, MacDelimiter, Path, PathSegment, UnOp};
|
use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, MacDelimiter, Path, PathSegment, UnOp};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{Applicability, PResult};
|
use rustc_errors::{Applicability, PResult};
|
||||||
use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
|
use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
|
||||||
|
@ -54,11 +54,11 @@ pub fn expand_assert<'cx>(
|
||||||
call_site_span,
|
call_site_span,
|
||||||
ExprKind::MacCall(P(MacCall {
|
ExprKind::MacCall(P(MacCall {
|
||||||
path: panic_path(),
|
path: panic_path(),
|
||||||
args: P(MacArgs::Delimited(
|
args: P(DelimArgs {
|
||||||
DelimSpan::from_single(call_site_span),
|
dspan: DelimSpan::from_single(call_site_span),
|
||||||
MacDelimiter::Parenthesis,
|
delim: MacDelimiter::Parenthesis,
|
||||||
tokens,
|
tokens,
|
||||||
)),
|
}),
|
||||||
prior_type_ascription: None,
|
prior_type_ascription: None,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rustc_ast::{
|
||||||
ptr::P,
|
ptr::P,
|
||||||
token,
|
token,
|
||||||
tokenstream::{DelimSpan, TokenStream, TokenTree},
|
tokenstream::{DelimSpan, TokenStream, TokenTree},
|
||||||
BinOpKind, BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, MethodCall,
|
BinOpKind, BorrowKind, DelimArgs, Expr, ExprKind, ItemKind, MacCall, MacDelimiter, MethodCall,
|
||||||
Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID,
|
Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID,
|
||||||
};
|
};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
|
@ -181,11 +181,11 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
||||||
self.span,
|
self.span,
|
||||||
ExprKind::MacCall(P(MacCall {
|
ExprKind::MacCall(P(MacCall {
|
||||||
path: panic_path,
|
path: panic_path,
|
||||||
args: P(MacArgs::Delimited(
|
args: P(DelimArgs {
|
||||||
DelimSpan::from_single(self.span),
|
dspan: DelimSpan::from_single(self.span),
|
||||||
MacDelimiter::Parenthesis,
|
delim: MacDelimiter::Parenthesis,
|
||||||
initial.into_iter().chain(captures).collect::<TokenStream>(),
|
tokens: initial.into_iter().chain(captures).collect::<TokenStream>(),
|
||||||
)),
|
}),
|
||||||
prior_type_ascription: None,
|
prior_type_ascription: None,
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
|
@ -58,11 +58,11 @@ fn expand<'cx>(
|
||||||
.collect(),
|
.collect(),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
},
|
},
|
||||||
args: P(MacArgs::Delimited(
|
args: P(DelimArgs {
|
||||||
DelimSpan::from_single(sp),
|
dspan: DelimSpan::from_single(sp),
|
||||||
MacDelimiter::Parenthesis,
|
delim: MacDelimiter::Parenthesis,
|
||||||
tts,
|
tokens: tts,
|
||||||
)),
|
}),
|
||||||
prior_type_ascription: None,
|
prior_type_ascription: None,
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
|
|
|
@ -507,7 +507,7 @@ impl MacResult for MacEager {
|
||||||
return Some(p);
|
return Some(p);
|
||||||
}
|
}
|
||||||
if let Some(e) = self.expr {
|
if let Some(e) = self.expr {
|
||||||
if let ast::ExprKind::Lit(_) = e.kind {
|
if matches!(e.kind, ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_)) {
|
||||||
return Some(P(ast::Pat {
|
return Some(P(ast::Pat {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: e.span,
|
span: e.span,
|
||||||
|
|
|
@ -11,9 +11,9 @@ use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, Delimiter};
|
use rustc_ast::token::{self, Delimiter};
|
||||||
use rustc_ast::tokenstream::TokenStream;
|
use rustc_ast::tokenstream::TokenStream;
|
||||||
use rustc_ast::visit::{self, AssocCtxt, Visitor};
|
use rustc_ast::visit::{self, AssocCtxt, Visitor};
|
||||||
use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, AttrVec, ExprKind, ForeignItemKind};
|
use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind};
|
||||||
use rustc_ast::{HasAttrs, HasNodeId};
|
use rustc_ast::{ForeignItemKind, HasAttrs, HasNodeId};
|
||||||
use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind};
|
use rustc_ast::{Inline, ItemKind, MacStmtStyle, MetaItemKind, ModKind};
|
||||||
use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind};
|
use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::map_in_place::MapInPlace;
|
use rustc_data_structures::map_in_place::MapInPlace;
|
||||||
|
@ -654,7 +654,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
ExpandResult::Ready(match invoc.kind {
|
ExpandResult::Ready(match invoc.kind {
|
||||||
InvocationKind::Bang { mac, .. } => match ext {
|
InvocationKind::Bang { mac, .. } => match ext {
|
||||||
SyntaxExtensionKind::Bang(expander) => {
|
SyntaxExtensionKind::Bang(expander) => {
|
||||||
let Ok(tok_result) = expander.expand(self.cx, span, mac.args.inner_tokens()) else {
|
let Ok(tok_result) = expander.expand(self.cx, span, mac.args.tokens.clone()) else {
|
||||||
return ExpandResult::Ready(fragment_kind.dummy(span));
|
return ExpandResult::Ready(fragment_kind.dummy(span));
|
||||||
};
|
};
|
||||||
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
|
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
|
||||||
|
@ -662,7 +662,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
SyntaxExtensionKind::LegacyBang(expander) => {
|
SyntaxExtensionKind::LegacyBang(expander) => {
|
||||||
let prev = self.cx.current_expansion.prior_type_ascription;
|
let prev = self.cx.current_expansion.prior_type_ascription;
|
||||||
self.cx.current_expansion.prior_type_ascription = mac.prior_type_ascription;
|
self.cx.current_expansion.prior_type_ascription = mac.prior_type_ascription;
|
||||||
let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens());
|
let tok_result = expander.expand(self.cx, span, mac.args.tokens.clone());
|
||||||
let result = if let Some(result) = fragment_kind.make_from(tok_result) {
|
let result = if let Some(result) = fragment_kind.make_from(tok_result) {
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
|
@ -706,7 +706,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
_ => item.to_tokens(),
|
_ => item.to_tokens(),
|
||||||
};
|
};
|
||||||
let attr_item = attr.unwrap_normal_item();
|
let attr_item = attr.unwrap_normal_item();
|
||||||
if let MacArgs::Eq(..) = attr_item.args {
|
if let AttrArgs::Eq(..) = attr_item.args {
|
||||||
self.cx.span_err(span, "key-value macro attributes are not supported");
|
self.cx.span_err(span, "key-value macro attributes are not supported");
|
||||||
}
|
}
|
||||||
let inner_tokens = attr_item.args.inner_tokens();
|
let inner_tokens = attr_item.args.inner_tokens();
|
||||||
|
|
|
@ -577,7 +577,7 @@ pub fn compile_declarative_macro(
|
||||||
|
|
||||||
// Parse the macro_rules! invocation
|
// Parse the macro_rules! invocation
|
||||||
let (macro_rules, body) = match &def.kind {
|
let (macro_rules, body) = match &def.kind {
|
||||||
ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.inner_tokens()),
|
ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.tokens.clone()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -291,7 +291,7 @@ fn ttdelim_span() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let tts: Vec<_> = match expr.kind {
|
let tts: Vec<_> = match expr.kind {
|
||||||
ast::ExprKind::MacCall(ref mac) => mac.args.inner_tokens().into_trees().collect(),
|
ast::ExprKind::MacCall(ref mac) => mac.args.tokens.clone().into_trees().collect(),
|
||||||
_ => panic!("not a macro"),
|
_ => panic!("not a macro"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,11 @@ pub fn placeholder(
|
||||||
fn mac_placeholder() -> P<ast::MacCall> {
|
fn mac_placeholder() -> P<ast::MacCall> {
|
||||||
P(ast::MacCall {
|
P(ast::MacCall {
|
||||||
path: ast::Path { span: DUMMY_SP, segments: ThinVec::new(), tokens: None },
|
path: ast::Path { span: DUMMY_SP, segments: ThinVec::new(), tokens: None },
|
||||||
args: P(ast::MacArgs::Empty),
|
args: P(ast::DelimArgs {
|
||||||
|
dspan: ast::tokenstream::DelimSpan::dummy(),
|
||||||
|
delim: ast::MacDelimiter::Parenthesis,
|
||||||
|
tokens: ast::tokenstream::TokenStream::new(Vec::new()),
|
||||||
|
}),
|
||||||
prior_type_ascription: None,
|
prior_type_ascription: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rustc_errors::struct_span_err;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
|
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
|
||||||
use rustc_target::abi::{Pointer, VariantIdx};
|
use rustc_target::abi::{Pointer, VariantIdx};
|
||||||
|
|
||||||
use super::FnCtxt;
|
use super::FnCtxt;
|
||||||
|
@ -46,7 +46,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let from = normalize(from);
|
let from = normalize(from);
|
||||||
let to = normalize(to);
|
let to = normalize(to);
|
||||||
trace!(?from, ?to);
|
trace!(?from, ?to);
|
||||||
|
if from.has_non_region_infer() || to.has_non_region_infer() {
|
||||||
|
tcx.sess.delay_span_bug(span, "argument to transmute has inference variables");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Transmutes that are only changing lifetimes are always ok.
|
// Transmutes that are only changing lifetimes are always ok.
|
||||||
if from == to {
|
if from == to {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -2030,10 +2030,10 @@ impl KeywordIdents {
|
||||||
|
|
||||||
impl EarlyLintPass for KeywordIdents {
|
impl EarlyLintPass for KeywordIdents {
|
||||||
fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) {
|
fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) {
|
||||||
self.check_tokens(cx, mac_def.body.inner_tokens());
|
self.check_tokens(cx, mac_def.body.tokens.clone());
|
||||||
}
|
}
|
||||||
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) {
|
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) {
|
||||||
self.check_tokens(cx, mac.args.inner_tokens());
|
self.check_tokens(cx, mac.args.tokens.clone());
|
||||||
}
|
}
|
||||||
fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
|
fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
|
||||||
self.check_ident_token(cx, UnderMacro(false), ident);
|
self.check_ident_token(cx, UnderMacro(false), ident);
|
||||||
|
|
|
@ -400,7 +400,7 @@ define_tables! {
|
||||||
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
|
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
|
||||||
// Slot is full when macro is macro_rules.
|
// Slot is full when macro is macro_rules.
|
||||||
macro_rules: Table<DefIndex, ()>,
|
macro_rules: Table<DefIndex, ()>,
|
||||||
macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>,
|
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
|
||||||
proc_macro: Table<DefIndex, MacroKind>,
|
proc_macro: Table<DefIndex, MacroKind>,
|
||||||
module_reexports: Table<DefIndex, LazyArray<ModChild>>,
|
module_reexports: Table<DefIndex, LazyArray<ModChild>>,
|
||||||
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
|
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
|
||||||
|
|
|
@ -70,7 +70,7 @@ trivially_parameterized_over_tcx! {
|
||||||
ty::adjustment::CoerceUnsizedInfo,
|
ty::adjustment::CoerceUnsizedInfo,
|
||||||
ty::fast_reject::SimplifiedTypeGen<DefId>,
|
ty::fast_reject::SimplifiedTypeGen<DefId>,
|
||||||
rustc_ast::Attribute,
|
rustc_ast::Attribute,
|
||||||
rustc_ast::MacArgs,
|
rustc_ast::DelimArgs,
|
||||||
rustc_attr::ConstStability,
|
rustc_attr::ConstStability,
|
||||||
rustc_attr::DefaultBodyStability,
|
rustc_attr::DefaultBodyStability,
|
||||||
rustc_attr::Deprecation,
|
rustc_attr::Deprecation,
|
||||||
|
|
|
@ -15,8 +15,7 @@ extern crate tracing;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_ast::tokenstream::TokenStream;
|
use rustc_ast::tokenstream::TokenStream;
|
||||||
use rustc_ast::Attribute;
|
use rustc_ast::{AttrItem, Attribute, MetaItem};
|
||||||
use rustc_ast::{AttrItem, MetaItem};
|
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult};
|
use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult};
|
||||||
|
@ -257,10 +256,12 @@ pub fn parse_cfg_attr(
|
||||||
parse_sess: &ParseSess,
|
parse_sess: &ParseSess,
|
||||||
) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> {
|
) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> {
|
||||||
match attr.get_normal_item().args {
|
match attr.get_normal_item().args {
|
||||||
ast::MacArgs::Delimited(dspan, delim, ref tts) if !tts.is_empty() => {
|
ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
|
||||||
|
if !tokens.is_empty() =>
|
||||||
|
{
|
||||||
let msg = "wrong `cfg_attr` delimiters";
|
let msg = "wrong `cfg_attr` delimiters";
|
||||||
crate::validate_attr::check_meta_bad_delim(parse_sess, dspan, delim, msg);
|
crate::validate_attr::check_meta_bad_delim(parse_sess, dspan, delim, msg);
|
||||||
match parse_in(parse_sess, tts.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) {
|
match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) {
|
||||||
Ok(r) => return Some(r),
|
Ok(r) => return Some(r),
|
||||||
Err(mut e) => {
|
Err(mut e) => {
|
||||||
e.help(&format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP))
|
e.help(&format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP))
|
||||||
|
|
|
@ -1501,7 +1501,7 @@ impl<'a> Parser<'a> {
|
||||||
let lo = path.span;
|
let lo = path.span;
|
||||||
let mac = P(MacCall {
|
let mac = P(MacCall {
|
||||||
path,
|
path,
|
||||||
args: self.parse_mac_args()?,
|
args: self.parse_delim_args()?,
|
||||||
prior_type_ascription: self.last_type_ascription,
|
prior_type_ascription: self.last_type_ascription,
|
||||||
});
|
});
|
||||||
(lo.to(self.prev_token.span), ExprKind::MacCall(mac))
|
(lo.to(self.prev_token.span), ExprKind::MacCall(mac))
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree,
|
||||||
use rustc_ast::{BindingAnnotation, Block, FnDecl, FnSig, Param, SelfKind};
|
use rustc_ast::{BindingAnnotation, Block, FnDecl, FnSig, Param, SelfKind};
|
||||||
use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData};
|
use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData};
|
||||||
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
||||||
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
|
use rustc_ast::{MacCall, MacDelimiter};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{struct_span_err, Applicability, IntoDiagnostic, PResult, StashKey};
|
use rustc_errors::{struct_span_err, Applicability, IntoDiagnostic, PResult, StashKey};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
|
@ -471,7 +471,7 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
|
fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
|
||||||
let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
|
let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
|
||||||
self.expect(&token::Not)?; // `!`
|
self.expect(&token::Not)?; // `!`
|
||||||
match self.parse_mac_args() {
|
match self.parse_delim_args() {
|
||||||
// `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
|
// `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
|
||||||
Ok(args) => {
|
Ok(args) => {
|
||||||
self.eat_semi_for_macro_if_needed(&args);
|
self.eat_semi_for_macro_if_needed(&args);
|
||||||
|
@ -1867,7 +1867,7 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> {
|
fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> {
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let body = if self.check(&token::OpenDelim(Delimiter::Brace)) {
|
let body = if self.check(&token::OpenDelim(Delimiter::Brace)) {
|
||||||
self.parse_mac_args()? // `MacBody`
|
self.parse_delim_args()? // `MacBody`
|
||||||
} else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
|
} else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
|
||||||
let params = self.parse_token_tree(); // `MacParams`
|
let params = self.parse_token_tree(); // `MacParams`
|
||||||
let pspan = params.span();
|
let pspan = params.span();
|
||||||
|
@ -1880,7 +1880,7 @@ impl<'a> Parser<'a> {
|
||||||
let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>`
|
let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>`
|
||||||
let tokens = TokenStream::new(vec![params, arrow, body]);
|
let tokens = TokenStream::new(vec![params, arrow, body]);
|
||||||
let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
|
let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
|
||||||
P(MacArgs::Delimited(dspan, MacDelimiter::Brace, tokens))
|
P(DelimArgs { dspan, delim: MacDelimiter::Brace, tokens })
|
||||||
} else {
|
} else {
|
||||||
return self.unexpected();
|
return self.unexpected();
|
||||||
};
|
};
|
||||||
|
@ -1935,7 +1935,7 @@ impl<'a> Parser<'a> {
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = self.parse_mac_args()?;
|
let body = self.parse_delim_args()?;
|
||||||
self.eat_semi_for_macro_if_needed(&body);
|
self.eat_semi_for_macro_if_needed(&body);
|
||||||
self.complain_if_pub_macro(vis, true);
|
self.complain_if_pub_macro(vis, true);
|
||||||
|
|
||||||
|
@ -1974,14 +1974,14 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eat_semi_for_macro_if_needed(&mut self, args: &MacArgs) {
|
fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) {
|
||||||
if args.need_semicolon() && !self.eat(&token::Semi) {
|
if args.need_semicolon() && !self.eat(&token::Semi) {
|
||||||
self.report_invalid_macro_expansion_item(args);
|
self.report_invalid_macro_expansion_item(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_invalid_macro_expansion_item(&self, args: &MacArgs) {
|
fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) {
|
||||||
let span = args.span().expect("undelimited macro call");
|
let span = args.dspan.entire();
|
||||||
let mut err = self.struct_span_err(
|
let mut err = self.struct_span_err(
|
||||||
span,
|
span,
|
||||||
"macros that expand to items must be delimited with braces or followed by a semicolon",
|
"macros that expand to items must be delimited with braces or followed by a semicolon",
|
||||||
|
@ -1990,10 +1990,7 @@ impl<'a> Parser<'a> {
|
||||||
// macros within the same crate (that we can fix), which is sad.
|
// macros within the same crate (that we can fix), which is sad.
|
||||||
if !span.from_expansion() {
|
if !span.from_expansion() {
|
||||||
if self.unclosed_delims.is_empty() {
|
if self.unclosed_delims.is_empty() {
|
||||||
let DelimSpan { open, close } = match args {
|
let DelimSpan { open, close } = args.dspan;
|
||||||
MacArgs::Empty | MacArgs::Eq(..) => unreachable!(),
|
|
||||||
MacArgs::Delimited(dspan, ..) => *dspan,
|
|
||||||
};
|
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
"change the delimiters to curly braces",
|
"change the delimiters to curly braces",
|
||||||
vec![(open, "{".to_string()), (close, '}'.to_string())],
|
vec![(open, "{".to_string()), (close, '}'.to_string())],
|
||||||
|
|
|
@ -25,8 +25,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
||||||
use rustc_ast::util::case::Case;
|
use rustc_ast::util::case::Case;
|
||||||
use rustc_ast::AttrId;
|
use rustc_ast::AttrId;
|
||||||
use rustc_ast::DUMMY_NODE_ID;
|
use rustc_ast::DUMMY_NODE_ID;
|
||||||
use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, Extern};
|
use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, DelimArgs, Extern};
|
||||||
use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacArgsEq, MacDelimiter, Mutability, StrLit};
|
use rustc_ast::{Async, AttrArgs, AttrArgsEq, Expr, ExprKind, MacDelimiter, Mutability, StrLit};
|
||||||
use rustc_ast::{HasAttrs, HasTokens, Unsafe, Visibility, VisibilityKind};
|
use rustc_ast::{HasAttrs, HasTokens, Unsafe, Visibility, VisibilityKind};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
@ -1249,39 +1249,40 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_mac_args(&mut self) -> PResult<'a, P<MacArgs>> {
|
fn parse_delim_args(&mut self) -> PResult<'a, P<DelimArgs>> {
|
||||||
self.parse_mac_args_common(true).map(P)
|
if let Some(args) = self.parse_delim_args_inner() { Ok(P(args)) } else { self.unexpected() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_attr_args(&mut self) -> PResult<'a, MacArgs> {
|
fn parse_attr_args(&mut self) -> PResult<'a, AttrArgs> {
|
||||||
self.parse_mac_args_common(false)
|
Ok(if let Some(args) = self.parse_delim_args_inner() {
|
||||||
}
|
AttrArgs::Delimited(args)
|
||||||
|
} else {
|
||||||
fn parse_mac_args_common(&mut self, delimited_only: bool) -> PResult<'a, MacArgs> {
|
if self.eat(&token::Eq) {
|
||||||
Ok(
|
let eq_span = self.prev_token.span;
|
||||||
if self.check(&token::OpenDelim(Delimiter::Parenthesis))
|
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(self.parse_expr_force_collect()?))
|
||||||
|| self.check(&token::OpenDelim(Delimiter::Bracket))
|
|
||||||
|| self.check(&token::OpenDelim(Delimiter::Brace))
|
|
||||||
{
|
|
||||||
match self.parse_token_tree() {
|
|
||||||
TokenTree::Delimited(dspan, delim, tokens) =>
|
|
||||||
// We've confirmed above that there is a delimiter so unwrapping is OK.
|
|
||||||
{
|
|
||||||
MacArgs::Delimited(dspan, MacDelimiter::from_token(delim).unwrap(), tokens)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
} else if !delimited_only {
|
|
||||||
if self.eat(&token::Eq) {
|
|
||||||
let eq_span = self.prev_token.span;
|
|
||||||
MacArgs::Eq(eq_span, MacArgsEq::Ast(self.parse_expr_force_collect()?))
|
|
||||||
} else {
|
|
||||||
MacArgs::Empty
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return self.unexpected();
|
AttrArgs::Empty
|
||||||
},
|
}
|
||||||
)
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_delim_args_inner(&mut self) -> Option<DelimArgs> {
|
||||||
|
if self.check(&token::OpenDelim(Delimiter::Parenthesis))
|
||||||
|
|| self.check(&token::OpenDelim(Delimiter::Bracket))
|
||||||
|
|| self.check(&token::OpenDelim(Delimiter::Brace))
|
||||||
|
{
|
||||||
|
match self.parse_token_tree() {
|
||||||
|
// We've confirmed above that there is a delimiter so unwrapping is OK.
|
||||||
|
TokenTree::Delimited(dspan, delim, tokens) => Some(DelimArgs {
|
||||||
|
dspan,
|
||||||
|
delim: MacDelimiter::from_token(delim).unwrap(),
|
||||||
|
tokens,
|
||||||
|
}),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_or_use_outer_attributes(
|
fn parse_or_use_outer_attributes(
|
||||||
|
|
|
@ -693,7 +693,7 @@ impl<'a> Parser<'a> {
|
||||||
/// Parse macro invocation
|
/// Parse macro invocation
|
||||||
fn parse_pat_mac_invoc(&mut self, path: Path) -> PResult<'a, PatKind> {
|
fn parse_pat_mac_invoc(&mut self, path: Path) -> PResult<'a, PatKind> {
|
||||||
self.bump();
|
self.bump();
|
||||||
let args = self.parse_mac_args()?;
|
let args = self.parse_delim_args()?;
|
||||||
let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription });
|
let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription });
|
||||||
Ok(PatKind::MacCall(mac))
|
Ok(PatKind::MacCall(mac))
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,14 +167,13 @@ impl<'a> Parser<'a> {
|
||||||
/// Parses a statement macro `mac!(args)` provided a `path` representing `mac`.
|
/// Parses a statement macro `mac!(args)` provided a `path` representing `mac`.
|
||||||
/// At this point, the `!` token after the path has already been eaten.
|
/// At this point, the `!` token after the path has already been eaten.
|
||||||
fn parse_stmt_mac(&mut self, lo: Span, attrs: AttrVec, path: ast::Path) -> PResult<'a, Stmt> {
|
fn parse_stmt_mac(&mut self, lo: Span, attrs: AttrVec, path: ast::Path) -> PResult<'a, Stmt> {
|
||||||
let args = self.parse_mac_args()?;
|
let args = self.parse_delim_args()?;
|
||||||
let delim = args.delim();
|
let delim = args.delim.to_token();
|
||||||
let hi = self.prev_token.span;
|
let hi = self.prev_token.span;
|
||||||
|
|
||||||
let style = match delim {
|
let style = match delim {
|
||||||
Some(Delimiter::Brace) => MacStmtStyle::Braces,
|
Delimiter::Brace => MacStmtStyle::Braces,
|
||||||
Some(_) => MacStmtStyle::NoBraces,
|
_ => MacStmtStyle::NoBraces,
|
||||||
None => unreachable!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription });
|
let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription });
|
||||||
|
|
|
@ -665,7 +665,7 @@ impl<'a> Parser<'a> {
|
||||||
// Macro invocation in type position
|
// Macro invocation in type position
|
||||||
Ok(TyKind::MacCall(P(MacCall {
|
Ok(TyKind::MacCall(P(MacCall {
|
||||||
path,
|
path,
|
||||||
args: self.parse_mac_args()?,
|
args: self.parse_delim_args()?,
|
||||||
prior_type_ascription: self.last_type_ascription,
|
prior_type_ascription: self.last_type_ascription,
|
||||||
})))
|
})))
|
||||||
} else if allow_plus == AllowPlus::Yes && self.check_plus() {
|
} else if allow_plus == AllowPlus::Yes && self.check_plus() {
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
use crate::parse_in;
|
use crate::parse_in;
|
||||||
|
|
||||||
use rustc_ast::tokenstream::DelimSpan;
|
use rustc_ast::tokenstream::DelimSpan;
|
||||||
use rustc_ast::{self as ast, Attribute, MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind};
|
use rustc_ast::MetaItemKind;
|
||||||
|
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MacDelimiter, MetaItem};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{Applicability, FatalError, PResult};
|
use rustc_errors::{Applicability, FatalError, PResult};
|
||||||
use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
||||||
|
@ -24,7 +25,7 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
|
||||||
Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => {
|
Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => {
|
||||||
check_builtin_attribute(sess, attr, *name, *template)
|
check_builtin_attribute(sess, attr, *name, *template)
|
||||||
}
|
}
|
||||||
_ if let MacArgs::Eq(..) = attr.get_normal_item().args => {
|
_ if let AttrArgs::Eq(..) = attr.get_normal_item().args => {
|
||||||
// All key-value attributes are restricted to meta-item syntax.
|
// All key-value attributes are restricted to meta-item syntax.
|
||||||
parse_meta(sess, attr)
|
parse_meta(sess, attr)
|
||||||
.map_err(|mut err| {
|
.map_err(|mut err| {
|
||||||
|
@ -42,13 +43,13 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
|
||||||
span: attr.span,
|
span: attr.span,
|
||||||
path: item.path.clone(),
|
path: item.path.clone(),
|
||||||
kind: match &item.args {
|
kind: match &item.args {
|
||||||
MacArgs::Empty => MetaItemKind::Word,
|
AttrArgs::Empty => MetaItemKind::Word,
|
||||||
MacArgs::Delimited(dspan, delim, t) => {
|
AttrArgs::Delimited(DelimArgs { dspan, delim, tokens }) => {
|
||||||
check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters");
|
check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters");
|
||||||
let nmis = parse_in(sess, t.clone(), "meta list", |p| p.parse_meta_seq_top())?;
|
let nmis = parse_in(sess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?;
|
||||||
MetaItemKind::List(nmis)
|
MetaItemKind::List(nmis)
|
||||||
}
|
}
|
||||||
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => {
|
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
|
||||||
if let ast::ExprKind::Lit(token_lit) = expr.kind
|
if let ast::ExprKind::Lit(token_lit) = expr.kind
|
||||||
&& let Ok(lit) = ast::Lit::from_token_lit(token_lit, expr.span)
|
&& let Ok(lit) = ast::Lit::from_token_lit(token_lit, expr.span)
|
||||||
{
|
{
|
||||||
|
@ -78,7 +79,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()),
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,8 +162,8 @@ fn overlap_within_probe<'cx, 'tcx>(
|
||||||
let infcx = selcx.infcx();
|
let infcx = selcx.infcx();
|
||||||
|
|
||||||
if overlap_mode.use_negative_impl() {
|
if overlap_mode.use_negative_impl() {
|
||||||
if negative_impl(selcx, impl1_def_id, impl2_def_id)
|
if negative_impl(infcx.tcx, impl1_def_id, impl2_def_id)
|
||||||
|| negative_impl(selcx, impl2_def_id, impl1_def_id)
|
|| negative_impl(infcx.tcx, impl2_def_id, impl1_def_id)
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -279,13 +279,8 @@ fn implicit_negative<'cx, 'tcx>(
|
||||||
|
|
||||||
/// Given impl1 and impl2 check if both impls are never satisfied by a common type (including
|
/// Given impl1 and impl2 check if both impls are never satisfied by a common type (including
|
||||||
/// where-clauses) If so, return true, they are disjoint and false otherwise.
|
/// where-clauses) If so, return true, they are disjoint and false otherwise.
|
||||||
fn negative_impl<'cx, 'tcx>(
|
fn negative_impl<'tcx>(tcx: TyCtxt<'tcx>, impl1_def_id: DefId, impl2_def_id: DefId) -> bool {
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
|
||||||
impl1_def_id: DefId,
|
|
||||||
impl2_def_id: DefId,
|
|
||||||
) -> bool {
|
|
||||||
debug!("negative_impl(impl1_def_id={:?}, impl2_def_id={:?})", impl1_def_id, impl2_def_id);
|
debug!("negative_impl(impl1_def_id={:?}, impl2_def_id={:?})", impl1_def_id, impl2_def_id);
|
||||||
let tcx = selcx.infcx().tcx;
|
|
||||||
|
|
||||||
// Create an infcx, taking the predicates of impl1 as assumptions:
|
// Create an infcx, taking the predicates of impl1 as assumptions:
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
|
@ -332,11 +327,10 @@ fn equate<'tcx>(
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
let selcx = &mut SelectionContext::new(&infcx);
|
|
||||||
let opt_failing_obligation = obligations
|
let opt_failing_obligation = obligations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(more_obligations)
|
.chain(more_obligations)
|
||||||
.find(|o| negative_impl_exists(selcx, o, body_def_id));
|
.find(|o| negative_impl_exists(infcx, o, body_def_id));
|
||||||
|
|
||||||
if let Some(failing_obligation) = opt_failing_obligation {
|
if let Some(failing_obligation) = opt_failing_obligation {
|
||||||
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
|
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
|
||||||
|
@ -347,19 +341,19 @@ fn equate<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to prove that a negative impl exist for the given obligation and its super predicates.
|
/// Try to prove that a negative impl exist for the given obligation and its super predicates.
|
||||||
#[instrument(level = "debug", skip(selcx))]
|
#[instrument(level = "debug", skip(infcx))]
|
||||||
fn negative_impl_exists<'cx, 'tcx>(
|
fn negative_impl_exists<'tcx>(
|
||||||
selcx: &SelectionContext<'cx, 'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
o: &PredicateObligation<'tcx>,
|
o: &PredicateObligation<'tcx>,
|
||||||
body_def_id: DefId,
|
body_def_id: DefId,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if resolve_negative_obligation(selcx.infcx().fork(), o, body_def_id) {
|
if resolve_negative_obligation(infcx.fork(), o, body_def_id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to prove a negative obligation exists for super predicates
|
// Try to prove a negative obligation exists for super predicates
|
||||||
for o in util::elaborate_predicates(selcx.tcx(), iter::once(o.predicate)) {
|
for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) {
|
||||||
if resolve_negative_obligation(selcx.infcx().fork(), &o, body_def_id) {
|
if resolve_negative_obligation(infcx.fork(), &o, body_def_id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
use hir::LangItem;
|
use hir::LangItem;
|
||||||
use rustc_errors::DelayDm;
|
use rustc_errors::DelayDm;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
|
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
|
||||||
use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
|
use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
|
||||||
|
@ -707,7 +706,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
cause: &ObligationCause<'tcx>,
|
cause: &ObligationCause<'tcx>,
|
||||||
) -> Option<(Ty<'tcx>, DefId)> {
|
) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
if tcx.features().trait_upcasting {
|
if tcx.features().trait_upcasting {
|
||||||
return None;
|
return None;
|
||||||
|
@ -726,27 +725,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = traits::normalize_projection_type(
|
self.infcx.probe(|_| {
|
||||||
self,
|
let ty = traits::normalize_projection_type(
|
||||||
param_env,
|
self,
|
||||||
ty::ProjectionTy {
|
param_env,
|
||||||
item_def_id: tcx.lang_items().deref_target()?,
|
ty::ProjectionTy {
|
||||||
substs: trait_ref.substs,
|
item_def_id: tcx.lang_items().deref_target()?,
|
||||||
},
|
substs: trait_ref.substs,
|
||||||
cause.clone(),
|
},
|
||||||
0,
|
cause.clone(),
|
||||||
// We're *intentionally* throwing these away,
|
0,
|
||||||
// since we don't actually use them.
|
// We're *intentionally* throwing these away,
|
||||||
&mut vec![],
|
// since we don't actually use them.
|
||||||
)
|
&mut vec![],
|
||||||
.ty()
|
)
|
||||||
.unwrap();
|
.ty()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if let ty::Dynamic(data, ..) = ty.kind() {
|
if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None }
|
||||||
Some((ty, data.principal_def_id()?))
|
})
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Searches for unsizing that might apply to `obligation`.
|
/// Searches for unsizing that might apply to `obligation`.
|
||||||
|
@ -808,21 +805,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
let principal_a = data_a.principal().unwrap();
|
let principal_a = data_a.principal().unwrap();
|
||||||
let target_trait_did = principal_def_id_b.unwrap();
|
let target_trait_did = principal_def_id_b.unwrap();
|
||||||
let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
|
let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
|
||||||
if let Some((deref_output_ty, deref_output_trait_did)) = self
|
if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object(
|
||||||
.need_migrate_deref_output_trait_object(
|
source,
|
||||||
source,
|
obligation.param_env,
|
||||||
obligation.param_env,
|
&obligation.cause,
|
||||||
&obligation.cause,
|
) {
|
||||||
)
|
if deref_trait_ref.def_id() == target_trait_did {
|
||||||
{
|
|
||||||
if deref_output_trait_did == target_trait_did {
|
|
||||||
self.tcx().struct_span_lint_hir(
|
self.tcx().struct_span_lint_hir(
|
||||||
DEREF_INTO_DYN_SUPERTRAIT,
|
DEREF_INTO_DYN_SUPERTRAIT,
|
||||||
obligation.cause.body_id,
|
obligation.cause.body_id,
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
DelayDm(|| format!(
|
DelayDm(|| format!(
|
||||||
"`{}` implements `Deref` with supertrait `{}` as output",
|
"`{}` implements `Deref` with supertrait `{}` as output",
|
||||||
source, deref_output_ty
|
source, deref_trait_ref
|
||||||
)),
|
)),
|
||||||
|lint| lint,
|
|lint| lint,
|
||||||
);
|
);
|
||||||
|
|
|
@ -543,7 +543,7 @@ impl<P: Deref> Pin<P> {
|
||||||
/// let p: Pin<&mut T> = Pin::new_unchecked(&mut a);
|
/// let p: Pin<&mut T> = Pin::new_unchecked(&mut a);
|
||||||
/// // This should mean the pointee `a` can never move again.
|
/// // This should mean the pointee `a` can never move again.
|
||||||
/// }
|
/// }
|
||||||
/// mem::swap(&mut a, &mut b);
|
/// mem::swap(&mut a, &mut b); // Potential UB down the road ⚠️
|
||||||
/// // The address of `a` changed to `b`'s stack slot, so `a` got moved even
|
/// // The address of `a` changed to `b`'s stack slot, so `a` got moved even
|
||||||
/// // though we have previously pinned it! We have violated the pinning API contract.
|
/// // though we have previously pinned it! We have violated the pinning API contract.
|
||||||
/// }
|
/// }
|
||||||
|
@ -563,13 +563,66 @@ impl<P: Deref> Pin<P> {
|
||||||
/// // This should mean the pointee can never move again.
|
/// // This should mean the pointee can never move again.
|
||||||
/// }
|
/// }
|
||||||
/// drop(pinned);
|
/// drop(pinned);
|
||||||
/// let content = Rc::get_mut(&mut x).unwrap();
|
/// let content = Rc::get_mut(&mut x).unwrap(); // Potential UB down the road ⚠️
|
||||||
/// // Now, if `x` was the only reference, we have a mutable reference to
|
/// // Now, if `x` was the only reference, we have a mutable reference to
|
||||||
/// // data that we pinned above, which we could use to move it as we have
|
/// // data that we pinned above, which we could use to move it as we have
|
||||||
/// // seen in the previous example. We have violated the pinning API contract.
|
/// // seen in the previous example. We have violated the pinning API contract.
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ## Pinning of closure captures
|
||||||
|
///
|
||||||
|
/// Particular care is required when using `Pin::new_unchecked` in a closure:
|
||||||
|
/// `Pin::new_unchecked(&mut var)` where `var` is a by-value (moved) closure capture
|
||||||
|
/// implicitly makes the promise that the closure itself is pinned, and that *all* uses
|
||||||
|
/// of this closure capture respect that pinning.
|
||||||
|
/// ```
|
||||||
|
/// use std::pin::Pin;
|
||||||
|
/// use std::task::Context;
|
||||||
|
/// use std::future::Future;
|
||||||
|
///
|
||||||
|
/// fn move_pinned_closure(mut x: impl Future, cx: &mut Context<'_>) {
|
||||||
|
/// // Create a closure that moves `x`, and then internally uses it in a pinned way.
|
||||||
|
/// let mut closure = move || unsafe {
|
||||||
|
/// let _ignore = Pin::new_unchecked(&mut x).poll(cx);
|
||||||
|
/// };
|
||||||
|
/// // Call the closure, so the future can assume it has been pinned.
|
||||||
|
/// closure();
|
||||||
|
/// // Move the closure somewhere else. This also moves `x`!
|
||||||
|
/// let mut moved = closure;
|
||||||
|
/// // Calling it again means we polled the future from two different locations,
|
||||||
|
/// // violating the pinning API contract.
|
||||||
|
/// moved(); // Potential UB ⚠️
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// When passing a closure to another API, it might be moving the closure any time, so
|
||||||
|
/// `Pin::new_unchecked` on closure captures may only be used if the API explicitly documents
|
||||||
|
/// that the closure is pinned.
|
||||||
|
///
|
||||||
|
/// The better alternative is to avoid all that trouble and do the pinning in the outer function
|
||||||
|
/// instead (here using the unstable `pin` macro):
|
||||||
|
/// ```
|
||||||
|
/// #![feature(pin_macro)]
|
||||||
|
/// use std::pin::pin;
|
||||||
|
/// use std::task::Context;
|
||||||
|
/// use std::future::Future;
|
||||||
|
///
|
||||||
|
/// fn move_pinned_closure(mut x: impl Future, cx: &mut Context<'_>) {
|
||||||
|
/// let mut x = pin!(x);
|
||||||
|
/// // Create a closure that captures `x: Pin<&mut _>`, which is safe to move.
|
||||||
|
/// let mut closure = move || {
|
||||||
|
/// let _ignore = x.as_mut().poll(cx);
|
||||||
|
/// };
|
||||||
|
/// // Call the closure, so the future can assume it has been pinned.
|
||||||
|
/// closure();
|
||||||
|
/// // Move the closure somewhere else.
|
||||||
|
/// let mut moved = closure;
|
||||||
|
/// // Calling it again here is fine (except that we might be polling a future that already
|
||||||
|
/// // returned `Poll::Ready`, but that is a separate problem).
|
||||||
|
/// moved();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// [`mem::swap`]: crate::mem::swap
|
/// [`mem::swap`]: crate::mem::swap
|
||||||
#[lang = "new_unchecked"]
|
#[lang = "new_unchecked"]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||||
crate-type = ["dylib", "rlib"]
|
crate-type = ["dylib", "rlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
|
cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
|
||||||
getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
|
getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
|
||||||
std = { path = "../std" }
|
std = { path = "../std" }
|
||||||
core = { path = "../core" }
|
core = { path = "../core" }
|
||||||
|
|
|
@ -580,7 +580,7 @@ pub(super) fn display_macro_source(
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
vis: ty::Visibility<DefId>,
|
vis: ty::Visibility<DefId>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
|
let tts: Vec<_> = def.body.tokens.clone().into_trees().collect();
|
||||||
// Extract the spans of all matchers. They represent the "interface" of the macro.
|
// Extract the spans of all matchers. They represent the "interface" of the macro.
|
||||||
let matchers = tts.chunks(4).map(|arm| &arm[0]);
|
let matchers = tts.chunks(4).map(|arm| &arm[0]);
|
||||||
|
|
||||||
|
|
|
@ -290,20 +290,21 @@ p:last-child {
|
||||||
button {
|
button {
|
||||||
/* Buttons on Safari have different default padding than other platforms. Make them the same. */
|
/* Buttons on Safari have different default padding than other platforms. Make them the same. */
|
||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
|
/* Opinionated tweak: use pointer cursor as clickability signifier. */
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* end tweaks for normalize.css 8 */
|
||||||
|
|
||||||
button#toggle-all-docs {
|
button#toggle-all-docs {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
|
||||||
/* iOS button gradient: https://stackoverflow.com/q/5438567 */
|
/* iOS button gradient: https://stackoverflow.com/q/5438567 */
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end tweaks for normalize.css 8 */
|
|
||||||
|
|
||||||
.rustdoc {
|
.rustdoc {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -906,6 +907,13 @@ so that we can apply CSS-filters to change the arrow color in themes */
|
||||||
background-color: var(--search-result-link-focus-background-color);
|
background-color: var(--search-result-link-focus-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-results .result-name span.alias {
|
||||||
|
color: var(--search-results-alias-color);
|
||||||
|
}
|
||||||
|
.search-results .result-name span.grey {
|
||||||
|
color: var(--search-results-grey-color);
|
||||||
|
}
|
||||||
|
|
||||||
.popover {
|
.popover {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@ -1305,7 +1313,6 @@ a.test-arrow:hover {
|
||||||
#titles > button {
|
#titles > button {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.125rem;
|
font-size: 1.125rem;
|
||||||
cursor: pointer;
|
|
||||||
border: 0;
|
border: 0;
|
||||||
border-top: 2px solid;
|
border-top: 2px solid;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -1345,7 +1352,6 @@ a.test-arrow:hover {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
background: none;
|
background: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
cursor: pointer;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
@ -1367,7 +1373,6 @@ a.test-arrow:hover {
|
||||||
|
|
||||||
#settings-menu > a, #help-button > a, #copy-path {
|
#settings-menu > a, #help-button > a, #copy-path {
|
||||||
width: 33px;
|
width: 33px;
|
||||||
cursor: pointer;
|
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1796,7 +1801,6 @@ in storage.js
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
border-top-right-radius: 3px;
|
border-top-right-radius: 3px;
|
||||||
border-bottom-right-radius: 3px;
|
border-bottom-right-radius: 3px;
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
}
|
}
|
||||||
|
@ -1967,7 +1971,6 @@ in storage.js
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.25em;
|
top: 0.25em;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
cursor: pointer;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
@ -41,9 +41,11 @@ Original by Dempfi (https://github.com/dempfi/ayu)
|
||||||
--sidebar-current-link-background-color: transparent;
|
--sidebar-current-link-background-color: transparent;
|
||||||
--search-result-link-focus-background-color: #3c3c3c;
|
--search-result-link-focus-background-color: #3c3c3c;
|
||||||
--search-result-border-color: #aaa3;
|
--search-result-border-color: #aaa3;
|
||||||
|
--search-color: #fff;
|
||||||
|
--search-results-alias-color: #c5c5c5;
|
||||||
|
--search-results-grey-color: #999;
|
||||||
--stab-background-color: #314559;
|
--stab-background-color: #314559;
|
||||||
--stab-code-color: #e6e1cf;
|
--stab-code-color: #e6e1cf;
|
||||||
--search-color: #fff;
|
|
||||||
--code-highlight-kw-color: #ff7733;
|
--code-highlight-kw-color: #ff7733;
|
||||||
--code-highlight-kw-2-color: #ff7733;
|
--code-highlight-kw-2-color: #ff7733;
|
||||||
--code-highlight-lifetime-color: #ff7733;
|
--code-highlight-lifetime-color: #ff7733;
|
||||||
|
@ -202,13 +204,6 @@ pre.rust .kw-2, pre.rust .prelude-ty {}
|
||||||
filter: invert(100);
|
filter: invert(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-results .result-name span.alias {
|
|
||||||
color: #c5c5c5;
|
|
||||||
}
|
|
||||||
.search-results .result-name span.grey {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
#source-sidebar > .title {
|
#source-sidebar > .title {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,11 @@
|
||||||
--sidebar-current-link-background-color: #444;
|
--sidebar-current-link-background-color: #444;
|
||||||
--search-result-link-focus-background-color: #616161;
|
--search-result-link-focus-background-color: #616161;
|
||||||
--search-result-border-color: #aaa3;
|
--search-result-border-color: #aaa3;
|
||||||
|
--search-color: #111;
|
||||||
|
--search-results-alias-color: #fff;
|
||||||
|
--search-results-grey-color: #ccc;
|
||||||
--stab-background-color: #314559;
|
--stab-background-color: #314559;
|
||||||
--stab-code-color: #e6e1cf;
|
--stab-code-color: #e6e1cf;
|
||||||
--search-color: #111;
|
|
||||||
--code-highlight-kw-color: #ab8ac1;
|
--code-highlight-kw-color: #ab8ac1;
|
||||||
--code-highlight-kw-2-color: #769acb;
|
--code-highlight-kw-2-color: #769acb;
|
||||||
--code-highlight-lifetime-color: #d97f26;
|
--code-highlight-lifetime-color: #d97f26;
|
||||||
|
@ -103,13 +105,6 @@ details.rustdoc-toggle > summary::before {
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-results .result-name span.alias {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.search-results .result-name span.grey {
|
|
||||||
color: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
|
#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
|
||||||
#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
|
#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
|
|
|
@ -36,9 +36,11 @@
|
||||||
--sidebar-current-link-background-color: #fff;
|
--sidebar-current-link-background-color: #fff;
|
||||||
--search-result-link-focus-background-color: #ccc;
|
--search-result-link-focus-background-color: #ccc;
|
||||||
--search-result-border-color: #aaa3;
|
--search-result-border-color: #aaa3;
|
||||||
|
--search-color: #000;
|
||||||
|
--search-results-alias-color: #000;
|
||||||
|
--search-results-grey-color: #999;
|
||||||
--stab-background-color: #fff5d6;
|
--stab-background-color: #fff5d6;
|
||||||
--stab-code-color: #000;
|
--stab-code-color: #000;
|
||||||
--search-color: #000;
|
|
||||||
--code-highlight-kw-color: #8959a8;
|
--code-highlight-kw-color: #8959a8;
|
||||||
--code-highlight-kw-2-color: #4271ae;
|
--code-highlight-kw-2-color: #4271ae;
|
||||||
--code-highlight-lifetime-color: #b76514;
|
--code-highlight-lifetime-color: #b76514;
|
||||||
|
@ -96,13 +98,6 @@ body.source .example-wrap pre.rust a {
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-results .result-name span.alias {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
.search-results .result-name span.grey {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
|
#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
|
||||||
#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
|
#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
|
||||||
background-color: #E0E0E0;
|
background-color: #E0E0E0;
|
||||||
|
|
24
src/test/rustdoc-gui/cursor.goml
Normal file
24
src/test/rustdoc-gui/cursor.goml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// This test ensures that several clickable items actually have the pointer cursor.
|
||||||
|
goto: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html"
|
||||||
|
|
||||||
|
// the `[+]/[-]` button
|
||||||
|
assert-css: ("#toggle-all-docs", {"cursor": "pointer"})
|
||||||
|
|
||||||
|
// the button next to the path header
|
||||||
|
assert-css: ("#copy-path", {"cursor": "pointer"})
|
||||||
|
|
||||||
|
// the search tabs
|
||||||
|
write: (".search-input", "Foo")
|
||||||
|
// To be SURE that the search will be run.
|
||||||
|
press-key: 'Enter'
|
||||||
|
// Waiting for the search results to appear...
|
||||||
|
wait-for: "#titles"
|
||||||
|
assert-css: ("#titles > button", {"cursor": "pointer"})
|
||||||
|
|
||||||
|
// mobile sidebar toggle button
|
||||||
|
size: (500, 700)
|
||||||
|
assert-css: (".sidebar-menu-toggle", {"cursor": "pointer"})
|
||||||
|
|
||||||
|
// the sidebar toggle button on the source code pages
|
||||||
|
goto: "file://" + |DOC_PATH| + "/src/lib2/lib.rs.html"
|
||||||
|
assert-css: ("#sidebar-toggle > button", {"cursor": "pointer"})
|
|
@ -366,23 +366,42 @@ assert-css: (
|
||||||
{"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
|
{"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check the alias more specifically in the dark theme.
|
// Check the alias.
|
||||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||||
// We set the theme so we're sure that the correct values will be used, whatever the computer
|
|
||||||
// this test is running on.
|
|
||||||
local-storage: {
|
|
||||||
"rustdoc-theme": "dark",
|
|
||||||
"rustdoc-use-system-theme": "false",
|
|
||||||
}
|
|
||||||
// If the text isn't displayed, the browser doesn't compute color style correctly...
|
// If the text isn't displayed, the browser doesn't compute color style correctly...
|
||||||
show-text: true
|
show-text: true
|
||||||
// We reload the page so the local storage settings are being used.
|
|
||||||
reload:
|
define-function: (
|
||||||
write: (".search-input", "thisisanalias")
|
"check-alias",
|
||||||
// To be SURE that the search will be run.
|
(theme, alias, grey),
|
||||||
press-key: 'Enter'
|
[
|
||||||
// Waiting for the search results to appear...
|
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||||
wait-for: "#titles"
|
("reload"),
|
||||||
// Checking that the colors for the alias element are the ones expected.
|
("write", (".search-input", "thisisanalias")),
|
||||||
assert-css: (".result-name > .alias", {"color": "rgb(255, 255, 255)"})
|
// To be SURE that the search will be run.
|
||||||
assert-css: (".result-name > .alias > .grey", {"color": "rgb(204, 204, 204)"})
|
("press-key", 'Enter'),
|
||||||
|
// Waiting for the search results to appear...
|
||||||
|
("wait-for", "#titles"),
|
||||||
|
// Checking that the colors for the alias element are the ones expected.
|
||||||
|
("assert-css", (".result-name > .alias", {"color": |alias|})),
|
||||||
|
("assert-css", (".result-name > .alias > .grey", {"color": |grey|})),
|
||||||
|
// Leave the search results to prevent reloading with an already filled search input.
|
||||||
|
("press-key", "Escape"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
call-function: ("check-alias", {
|
||||||
|
"theme": "ayu",
|
||||||
|
"alias": "rgb(197, 197, 197)",
|
||||||
|
"grey": "rgb(153, 153, 153)",
|
||||||
|
})
|
||||||
|
call-function: ("check-alias", {
|
||||||
|
"theme": "dark",
|
||||||
|
"alias": "rgb(255, 255, 255)",
|
||||||
|
"grey": "rgb(204, 204, 204)",
|
||||||
|
})
|
||||||
|
call-function: ("check-alias", {
|
||||||
|
"theme": "light",
|
||||||
|
"alias": "rgb(0, 0, 0)",
|
||||||
|
"grey": "rgb(153, 153, 153)",
|
||||||
|
})
|
||||||
|
|
10
src/test/ui/consts/issue-104609.rs
Normal file
10
src/test/ui/consts/issue-104609.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
fn foo() {
|
||||||
|
oops;
|
||||||
|
//~^ ERROR: cannot find value `oops` in this scope
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn bar() {
|
||||||
|
std::mem::transmute::<_, *mut _>(1_u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
9
src/test/ui/consts/issue-104609.stderr
Normal file
9
src/test/ui/consts/issue-104609.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0425]: cannot find value `oops` in this scope
|
||||||
|
--> $DIR/issue-104609.rs:2:5
|
||||||
|
|
|
||||||
|
LL | oops;
|
||||||
|
| ^^^^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0425`.
|
36
src/test/ui/dyn-star/dyn-async-trait.rs
Normal file
36
src/test/ui/dyn-star/dyn-async-trait.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// check-pass
|
||||||
|
// edition: 2021
|
||||||
|
|
||||||
|
// This test case is meant to demonstrate how close we can get to async
|
||||||
|
// functions in dyn traits with the current level of dyn* support.
|
||||||
|
|
||||||
|
#![feature(dyn_star)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
|
trait DynAsyncCounter {
|
||||||
|
fn increment<'a>(&'a mut self) -> dyn* Future<Output = usize> + 'a;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MyCounter {
|
||||||
|
count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DynAsyncCounter for MyCounter {
|
||||||
|
fn increment<'a>(&'a mut self) -> dyn* Future<Output = usize> + 'a {
|
||||||
|
Box::pin(async {
|
||||||
|
self.count += 1;
|
||||||
|
self.count
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn do_counter(counter: &mut dyn DynAsyncCounter) -> usize {
|
||||||
|
counter.increment().await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut counter = MyCounter { count: 0 };
|
||||||
|
let _ = do_counter(&mut counter);
|
||||||
|
}
|
|
@ -123,4 +123,10 @@ expand_expr_fail!(echo_pm!(arbitrary_expression() + "etc"));
|
||||||
|
|
||||||
const _: u32 = recursive_expand!(); //~ ERROR: recursion limit reached while expanding `recursive_expand!`
|
const _: u32 = recursive_expand!(); //~ ERROR: recursion limit reached while expanding `recursive_expand!`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {
|
||||||
|
// https://github.com/rust-lang/rust/issues/104414
|
||||||
|
match b"Included file contents\n" {
|
||||||
|
include_bytes!("auxiliary/included-file.txt") => (),
|
||||||
|
_ => panic!("include_bytes! in pattern"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ fn take_a(_: &dyn A) {}
|
||||||
|
|
||||||
fn whoops(b: &dyn B) {
|
fn whoops(b: &dyn B) {
|
||||||
take_a(b)
|
take_a(b)
|
||||||
//~^ ERROR `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output
|
//~^ ERROR `dyn B` implements `Deref` with supertrait `A` as output
|
||||||
//~^^ WARN this was previously accepted by the compiler but is being phased out;
|
//~^^ WARN this was previously accepted by the compiler but is being phased out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output
|
error: `dyn B` implements `Deref` with supertrait `A` as output
|
||||||
--> $DIR/migrate-lint-deny.rs:20:12
|
--> $DIR/migrate-lint-deny.rs:20:12
|
||||||
|
|
|
|
||||||
LL | take_a(b)
|
LL | take_a(b)
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl EarlyLintPass for CrateInMacroDef {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if item.attrs.iter().any(is_macro_export);
|
if item.attrs.iter().any(is_macro_export);
|
||||||
if let ItemKind::MacroDef(macro_def) = &item.kind;
|
if let ItemKind::MacroDef(macro_def) = &item.kind;
|
||||||
let tts = macro_def.body.inner_tokens();
|
let tts = macro_def.body.tokens.clone();
|
||||||
if let Some(span) = contains_unhygienic_crate_reference(&tts);
|
if let Some(span) = contains_unhygienic_crate_reference(&tts);
|
||||||
then {
|
then {
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
|
|
@ -388,7 +388,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
||||||
&& over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
|
&& over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
|
||||||
},
|
},
|
||||||
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
|
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
|
||||||
(MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_mac_args(&l.body, &r.body),
|
(MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_delim_args(&l.body, &r.body),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -709,7 +709,7 @@ pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eq_mac_call(l: &MacCall, r: &MacCall) -> bool {
|
pub fn eq_mac_call(l: &MacCall, r: &MacCall) -> bool {
|
||||||
eq_path(&l.path, &r.path) && eq_mac_args(&l.args, &r.args)
|
eq_path(&l.path, &r.path) && eq_delim_args(&l.args, &r.args)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
|
pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
|
||||||
|
@ -717,18 +717,22 @@ pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
|
||||||
l.style == r.style
|
l.style == r.style
|
||||||
&& match (&l.kind, &r.kind) {
|
&& match (&l.kind, &r.kind) {
|
||||||
(DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2,
|
(DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2,
|
||||||
(Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_mac_args(&l.item.args, &r.item.args),
|
(Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_attr_args(&l.item.args, &r.item.args),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eq_mac_args(l: &MacArgs, r: &MacArgs) -> bool {
|
pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool {
|
||||||
use MacArgs::*;
|
use AttrArgs::*;
|
||||||
match (l, r) {
|
match (l, r) {
|
||||||
(Empty, Empty) => true,
|
(Empty, Empty) => true,
|
||||||
(Delimited(_, ld, lts), Delimited(_, rd, rts)) => ld == rd && lts.eq_unspanned(rts),
|
(Delimited(la), Delimited(ra)) => eq_delim_args(la, ra),
|
||||||
(Eq(_, MacArgsEq::Ast(le)), Eq(_, MacArgsEq::Ast(re))) => eq_expr(le, re),
|
(Eq(_, AttrArgsEq::Ast(le)), Eq(_, AttrArgsEq::Ast(re))) => eq_expr(le, re),
|
||||||
(Eq(_, MacArgsEq::Hir(ll)), Eq(_, MacArgsEq::Hir(rl))) => ll.kind == rl.kind,
|
(Eq(_, AttrArgsEq::Hir(ll)), Eq(_, AttrArgsEq::Hir(rl))) => ll.kind == rl.kind,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn eq_delim_args(l: &DelimArgs, r: &DelimArgs) -> bool {
|
||||||
|
l.delim == r.delim && l.tokens.eq_unspanned(&r.tokens)
|
||||||
|
}
|
||||||
|
|
|
@ -1341,7 +1341,7 @@ pub(crate) fn can_be_overflowed_expr(
|
||||||
}
|
}
|
||||||
ast::ExprKind::MacCall(ref mac) => {
|
ast::ExprKind::MacCall(ref mac) => {
|
||||||
match (
|
match (
|
||||||
rustc_ast::ast::MacDelimiter::from_token(mac.args.delim().unwrap()),
|
rustc_ast::ast::MacDelimiter::from_token(mac.args.delim.to_token()),
|
||||||
context.config.overflow_delimited_expr(),
|
context.config.overflow_delimited_expr(),
|
||||||
) {
|
) {
|
||||||
(Some(ast::MacDelimiter::Bracket), true)
|
(Some(ast::MacDelimiter::Bracket), true)
|
||||||
|
|
|
@ -208,7 +208,7 @@ fn rewrite_macro_inner(
|
||||||
original_style
|
original_style
|
||||||
};
|
};
|
||||||
|
|
||||||
let ts = mac.args.inner_tokens();
|
let ts = mac.args.tokens.clone();
|
||||||
let has_comment = contains_comment(context.snippet(mac.span()));
|
let has_comment = contains_comment(context.snippet(mac.span()));
|
||||||
if ts.is_empty() && !has_comment {
|
if ts.is_empty() && !has_comment {
|
||||||
return match style {
|
return match style {
|
||||||
|
@ -392,7 +392,7 @@ pub(crate) fn rewrite_macro_def(
|
||||||
return snippet;
|
return snippet;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ts = def.body.inner_tokens();
|
let ts = def.body.tokens.clone();
|
||||||
let mut parser = MacroParser::new(ts.into_trees());
|
let mut parser = MacroParser::new(ts.into_trees());
|
||||||
let parsed_def = match parser.parse() {
|
let parsed_def = match parser.parse() {
|
||||||
Some(def) => def,
|
Some(def) => def,
|
||||||
|
@ -1087,7 +1087,7 @@ pub(crate) fn convert_try_mac(
|
||||||
) -> Option<ast::Expr> {
|
) -> Option<ast::Expr> {
|
||||||
let path = &pprust::path_to_string(&mac.path);
|
let path = &pprust::path_to_string(&mac.path);
|
||||||
if path == "try" || path == "r#try" {
|
if path == "try" || path == "r#try" {
|
||||||
let ts = mac.args.inner_tokens();
|
let ts = mac.args.tokens.clone();
|
||||||
|
|
||||||
Some(ast::Expr {
|
Some(ast::Expr {
|
||||||
id: ast::NodeId::root(), // dummy value
|
id: ast::NodeId::root(), // dummy value
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::rewrite::RewriteContext;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> {
|
pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> {
|
||||||
let ts = mac.args.inner_tokens();
|
let ts = mac.args.tokens.clone();
|
||||||
let mut parser = super::build_parser(context, ts);
|
let mut parser = super::build_parser(context, ts);
|
||||||
parse_asm_args(&mut parser, context.parse_sess.inner(), mac.span(), false).ok()
|
parse_asm_args(&mut parser, context.parse_sess.inner(), mac.span(), false).ok()
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn parse_cfg_if_inner<'a>(
|
||||||
sess: &'a ParseSess,
|
sess: &'a ParseSess,
|
||||||
mac: &'a ast::MacCall,
|
mac: &'a ast::MacCall,
|
||||||
) -> Result<Vec<ast::Item>, &'static str> {
|
) -> Result<Vec<ast::Item>, &'static str> {
|
||||||
let ts = mac.args.inner_tokens();
|
let ts = mac.args.tokens.clone();
|
||||||
let mut parser = build_stream_parser(sess.inner(), ts);
|
let mut parser = build_stream_parser(sess.inner(), ts);
|
||||||
|
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::path::Path;
|
||||||
const ENTRY_LIMIT: usize = 1000;
|
const ENTRY_LIMIT: usize = 1000;
|
||||||
// FIXME: The following limits should be reduced eventually.
|
// FIXME: The following limits should be reduced eventually.
|
||||||
const ROOT_ENTRY_LIMIT: usize = 939;
|
const ROOT_ENTRY_LIMIT: usize = 939;
|
||||||
const ISSUES_ENTRY_LIMIT: usize = 2085;
|
const ISSUES_ENTRY_LIMIT: usize = 2070;
|
||||||
|
|
||||||
fn check_entries(path: &Path, bad: &mut bool) {
|
fn check_entries(path: &Path, bad: &mut bool) {
|
||||||
for dir in Walk::new(&path.join("test/ui")) {
|
for dir in Walk::new(&path.join("test/ui")) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue