use crate::{ast, attr};
use crate::edition::Edition;
-use crate::errors::FatalError;
use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
use crate::ext::base::{NormalTT, TTMacroExpander};
use crate::ext::expand::{AstFragment, AstFragmentKind};
use crate::symbol::Symbol;
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
+use errors::FatalError;
use syntax_pos::{Span, DUMMY_SP, symbol::Ident};
use log::debug;
use std::collections::hash_map::Entry;
use rustc_data_structures::sync::Lrc;
-use crate::errors::Applicability;
+use errors::Applicability;
const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, \
});
if body.legacy {
- let allow_internal_unstable = attr::contains_name(&def.attrs, "allow_internal_unstable");
+ let allow_internal_unstable = attr::find_by_name(&def.attrs, "allow_internal_unstable")
+ .map(|attr| attr
+ .meta_item_list()
+ .map(|list| list.iter()
+ .map(|it| it.name().unwrap_or_else(|| sess.span_diagnostic.span_bug(
+ it.span, "allow internal unstable expects feature names",
+ )))
+ .collect::<Vec<Symbol>>().into()
+ )
+ .unwrap_or_else(|| {
+ sess.span_diagnostic.span_warn(
+ attr.span, "allow_internal_unstable expects list of feature names. In the \
+ future this will become a hard error. Please use `allow_internal_unstable(\
+ foo, bar)` to only allow the `foo` and `bar` features",
+ );
+ vec![Symbol::intern("allow_internal_unstable_backcompat_hack")].into()
+ })
+ );
let allow_internal_unsafe = attr::contains_name(&def.attrs, "allow_internal_unsafe");
let mut local_inner_macros = false;
if let Some(macro_export) = attr::find_by_name(&def.attrs, "macro_export") {
// after parsing/expansion. we can report every error in every macro this way.
}
-/// Check that the lhs contains no repetition which could match an empty token
+/// Checks that the lhs contains no repetition which could match an empty token
/// tree, because then the matcher would hang indefinitely.
fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool {
use quoted::TokenTree;
}
}
-/// True if a fragment of type `frag` can be followed by any sort of
-/// token. We use this (among other things) as a useful approximation
+/// Returns `true` if a fragment of type `frag` can be followed by any sort of
+/// token. We use this (among other things) as a useful approximation
/// for when `frag` can be followed by a repetition like `$(...)*` or
/// `$(...)+`. In general, these can be a bit tricky to reason about,
/// so we adopt a conservative position that says that any fragment
Invalid(String, &'static str),
}
-/// True if `frag` can legally be followed by the token `tok`. For
+/// Returns `true` if `frag` can legally be followed by the token `tok`. For
/// fragments that can consume an unbounded number of tokens, `tok`
/// must be within a well-defined follow set. This is intended to
/// guarantee future compatibility: for example, without this rule, if