Require a list of features to allow in allow_internal_unstable
This commit is contained in:
parent
57d7cfc3cf
commit
d3c212c552
@ -34,7 +34,8 @@
|
||||
#[cfg(not(test))]
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(box_syntax))]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
macro_rules! vec {
|
||||
($elem:expr; $n:expr) => (
|
||||
$crate::vec::from_elem($elem, $n)
|
||||
|
@ -1,6 +1,7 @@
|
||||
/// Entry point of thread panic, for details, see std::macros
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(core_panic, __rust_unstable_column))]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
macro_rules! panic {
|
||||
() => (
|
||||
@ -409,7 +410,8 @@ macro_rules! write {
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(format_args_nl))]
|
||||
macro_rules! writeln {
|
||||
($dst:expr) => (
|
||||
write!($dst, "\n")
|
||||
|
@ -681,13 +681,18 @@ impl<'a> LoweringContext<'a> {
|
||||
Ident::with_empty_ctxt(Symbol::gensym(s))
|
||||
}
|
||||
|
||||
fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span {
|
||||
fn allow_internal_unstable(
|
||||
&self,
|
||||
reason: CompilerDesugaringKind,
|
||||
span: Span,
|
||||
allow_internal_unstable: Vec<Symbol>,
|
||||
) -> Span {
|
||||
let mark = Mark::fresh(Mark::root());
|
||||
mark.set_expn_info(source_map::ExpnInfo {
|
||||
call_site: span,
|
||||
def_site: Some(span),
|
||||
format: source_map::CompilerDesugaring(reason),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable,
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: source_map::hygiene::default_edition(),
|
||||
@ -964,7 +969,13 @@ impl<'a> LoweringContext<'a> {
|
||||
attrs: ThinVec::new(),
|
||||
};
|
||||
|
||||
let unstable_span = self.allow_internal_unstable(CompilerDesugaringKind::Async, span);
|
||||
let unstable_span = self.allow_internal_unstable(
|
||||
CompilerDesugaringKind::Async,
|
||||
span,
|
||||
vec![
|
||||
Symbol::intern("gen_future"),
|
||||
],
|
||||
);
|
||||
let gen_future = self.expr_std_path(
|
||||
unstable_span, &["future", "from_generator"], None, ThinVec::new());
|
||||
hir::ExprKind::Call(P(gen_future), hir_vec![generator])
|
||||
@ -1363,6 +1374,7 @@ impl<'a> LoweringContext<'a> {
|
||||
let exist_ty_span = self.allow_internal_unstable(
|
||||
CompilerDesugaringKind::ExistentialReturnType,
|
||||
span,
|
||||
Vec::new(), // doesn'c actually allow anything unstable
|
||||
);
|
||||
|
||||
let exist_ty_def_index = self
|
||||
@ -3927,8 +3939,13 @@ impl<'a> LoweringContext<'a> {
|
||||
}),
|
||||
ExprKind::TryBlock(ref body) => {
|
||||
self.with_catch_scope(body.id, |this| {
|
||||
let unstable_span =
|
||||
this.allow_internal_unstable(CompilerDesugaringKind::TryBlock, body.span);
|
||||
let unstable_span = this.allow_internal_unstable(
|
||||
CompilerDesugaringKind::TryBlock,
|
||||
body.span,
|
||||
vec![
|
||||
Symbol::intern("try_trait"),
|
||||
],
|
||||
);
|
||||
let mut block = this.lower_block(body, true).into_inner();
|
||||
let tail = block.expr.take().map_or_else(
|
||||
|| {
|
||||
@ -4363,6 +4380,7 @@ impl<'a> LoweringContext<'a> {
|
||||
let desugared_span = self.allow_internal_unstable(
|
||||
CompilerDesugaringKind::ForLoop,
|
||||
head_sp,
|
||||
Vec::new(),
|
||||
);
|
||||
|
||||
let iter = self.str_to_ident("iter");
|
||||
@ -4525,8 +4543,13 @@ impl<'a> LoweringContext<'a> {
|
||||
// return Try::from_error(From::from(err)),
|
||||
// }
|
||||
|
||||
let unstable_span =
|
||||
self.allow_internal_unstable(CompilerDesugaringKind::QuestionMark, e.span);
|
||||
let unstable_span = self.allow_internal_unstable(
|
||||
CompilerDesugaringKind::QuestionMark,
|
||||
e.span,
|
||||
vec![
|
||||
Symbol::intern("try_trait")
|
||||
],
|
||||
);
|
||||
|
||||
// `Try::into_result(<expr>)`
|
||||
let discr = {
|
||||
|
@ -561,11 +561,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
/// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
|
||||
/// `id`.
|
||||
pub fn eval_stability(self, def_id: DefId, id: Option<NodeId>, span: Span) -> EvalResult {
|
||||
if span.allows_unstable() {
|
||||
debug!("stability: skipping span={:?} since it is internal", span);
|
||||
return EvalResult::Allow;
|
||||
}
|
||||
|
||||
let lint_deprecated = |def_id: DefId,
|
||||
id: NodeId,
|
||||
note: Option<Symbol>,
|
||||
@ -694,6 +689,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
match stability {
|
||||
Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
|
||||
if span.allows_unstable(&feature.as_str()) {
|
||||
debug!("stability: skipping span={:?} since it is internal", span);
|
||||
return EvalResult::Allow;
|
||||
}
|
||||
if self.stability().active_features.contains(&feature) {
|
||||
return EvalResult::Allow;
|
||||
}
|
||||
|
@ -91,7 +91,9 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> {
|
||||
call_site: item.span, // use the call site of the static
|
||||
def_site: None,
|
||||
format: MacroAttribute(Symbol::intern(name)),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("rustc_attrs"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: hygiene::default_edition(),
|
||||
|
@ -570,7 +570,7 @@ impl<'a> CrateLoader<'a> {
|
||||
ProcMacro::Bang { name, client } => {
|
||||
(name, SyntaxExtension::ProcMacro {
|
||||
expander: Box::new(BangProcMacro { client }),
|
||||
allow_internal_unstable: false,
|
||||
allow_internal_unstable: Vec::new(),
|
||||
edition: root.edition,
|
||||
})
|
||||
}
|
||||
|
@ -425,7 +425,9 @@ impl cstore::CStore {
|
||||
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
|
||||
let ext = SyntaxExtension::ProcMacro {
|
||||
expander: Box::new(BangProcMacro { client }),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("proc_macro_def_site"),
|
||||
],
|
||||
edition: data.root.edition,
|
||||
};
|
||||
return LoadedMacro::ProcMacro(Lrc::new(ext));
|
||||
|
@ -907,7 +907,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
// Check `#[unstable]` const fns or `#[rustc_const_unstable]`
|
||||
// functions without the feature gate active in this crate in
|
||||
// order to report a better error message than the one below.
|
||||
if self.span.allows_unstable() {
|
||||
if self.span.allows_unstable(&feature.as_str()) {
|
||||
// `allow_internal_unstable` can make such calls stable.
|
||||
is_const_fn = true;
|
||||
} else {
|
||||
|
@ -110,8 +110,8 @@ impl<'a> Registry<'a> {
|
||||
edition,
|
||||
}
|
||||
}
|
||||
IdentTT(ext, _, allow_internal_unstable) => {
|
||||
IdentTT(ext, Some(self.krate_span), allow_internal_unstable)
|
||||
IdentTT { ext, span: _, allow_internal_unstable } => {
|
||||
IdentTT { ext, span: Some(self.krate_span), allow_internal_unstable }
|
||||
}
|
||||
_ => extension,
|
||||
}));
|
||||
@ -126,7 +126,7 @@ impl<'a> Registry<'a> {
|
||||
self.register_syntax_extension(Symbol::intern(name), NormalTT {
|
||||
expander: Box::new(expander),
|
||||
def_info: None,
|
||||
allow_internal_unstable: false,
|
||||
allow_internal_unstable: Vec::new(),
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
unstable_feature: None,
|
||||
|
@ -53,7 +53,8 @@
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(__rust_unstable_column, libstd_sys_internals))]
|
||||
macro_rules! panic {
|
||||
() => ({
|
||||
panic!("explicit panic")
|
||||
@ -111,7 +112,8 @@ macro_rules! panic {
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(print_internals))]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
|
||||
}
|
||||
@ -143,7 +145,8 @@ macro_rules! print {
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(print_internals, format_args_nl))]
|
||||
macro_rules! println {
|
||||
() => (print!("\n"));
|
||||
($($arg:tt)*) => ({
|
||||
@ -174,7 +177,8 @@ macro_rules! println {
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "eprint", since = "1.19.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(print_internals))]
|
||||
macro_rules! eprint {
|
||||
($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)));
|
||||
}
|
||||
@ -202,7 +206,8 @@ macro_rules! eprint {
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "eprint", since = "1.19.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(print_internals, format_args_nl))]
|
||||
macro_rules! eprintln {
|
||||
() => (eprint!("\n"));
|
||||
($($arg:tt)*) => ({
|
||||
@ -325,7 +330,8 @@ macro_rules! dbg {
|
||||
/// A macro to await on an async call.
|
||||
#[macro_export]
|
||||
#[unstable(feature = "await_macro", issue = "50547")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(gen_future, generators))]
|
||||
#[allow_internal_unsafe]
|
||||
macro_rules! await {
|
||||
($e:expr) => { {
|
||||
|
@ -126,7 +126,8 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
|
||||
/// [`std::thread::LocalKey`]: ../std/thread/struct.LocalKey.html
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(thread_local_internals))]
|
||||
macro_rules! thread_local {
|
||||
// empty (base case for the recursion)
|
||||
() => {};
|
||||
@ -148,7 +149,10 @@ macro_rules! thread_local {
|
||||
reason = "should not be necessary",
|
||||
issue = "0")]
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable]
|
||||
#[cfg_attr(stage0, allow_internal_unstable)]
|
||||
#[cfg_attr(not(stage0), allow_internal_unstable(
|
||||
thread_local_internals, cfg_target_thread_local, thread_local,
|
||||
))]
|
||||
#[allow_internal_unsafe]
|
||||
macro_rules! __thread_local_inner {
|
||||
(@key $(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
|
||||
|
@ -621,7 +621,8 @@ pub enum SyntaxExtension {
|
||||
/// A function-like procedural macro. TokenStream -> TokenStream.
|
||||
ProcMacro {
|
||||
expander: Box<dyn ProcMacro + sync::Sync + sync::Send>,
|
||||
allow_internal_unstable: bool,
|
||||
/// Whitelist of unstable features that are treated as stable inside this macro
|
||||
allow_internal_unstable: Vec<Symbol>,
|
||||
edition: Edition,
|
||||
},
|
||||
|
||||
@ -638,8 +639,10 @@ pub enum SyntaxExtension {
|
||||
expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
|
||||
def_info: Option<(ast::NodeId, Span)>,
|
||||
/// Whether the contents of the macro can
|
||||
/// directly use `#[unstable]` things (true == yes).
|
||||
allow_internal_unstable: bool,
|
||||
/// directly use `#[unstable]` things.
|
||||
///
|
||||
/// Only allows things that require a feature gate in the given whitelist
|
||||
allow_internal_unstable: Vec<Symbol>,
|
||||
/// Whether the contents of the macro can use `unsafe`
|
||||
/// without triggering the `unsafe_code` lint.
|
||||
allow_internal_unsafe: bool,
|
||||
@ -654,8 +657,11 @@ pub enum SyntaxExtension {
|
||||
|
||||
/// A function-like syntax extension that has an extra ident before
|
||||
/// the block.
|
||||
///
|
||||
IdentTT(Box<dyn IdentMacroExpander + sync::Sync + sync::Send>, Option<Span>, bool),
|
||||
IdentTT {
|
||||
ext: Box<dyn IdentMacroExpander + sync::Sync + sync::Send>,
|
||||
span: Option<Span>,
|
||||
allow_internal_unstable: Vec<Symbol>,
|
||||
},
|
||||
|
||||
/// An attribute-like procedural macro. TokenStream -> TokenStream.
|
||||
/// The input is the annotated item.
|
||||
@ -682,7 +688,7 @@ impl SyntaxExtension {
|
||||
match *self {
|
||||
SyntaxExtension::DeclMacro { .. } |
|
||||
SyntaxExtension::NormalTT { .. } |
|
||||
SyntaxExtension::IdentTT(..) |
|
||||
SyntaxExtension::IdentTT { .. } |
|
||||
SyntaxExtension::ProcMacro { .. } =>
|
||||
MacroKind::Bang,
|
||||
SyntaxExtension::NonMacroAttr { .. } |
|
||||
@ -716,7 +722,7 @@ impl SyntaxExtension {
|
||||
SyntaxExtension::ProcMacroDerive(.., edition) => edition,
|
||||
// Unstable legacy stuff
|
||||
SyntaxExtension::NonMacroAttr { .. } |
|
||||
SyntaxExtension::IdentTT(..) |
|
||||
SyntaxExtension::IdentTT { .. } |
|
||||
SyntaxExtension::MultiDecorator(..) |
|
||||
SyntaxExtension::MultiModifier(..) |
|
||||
SyntaxExtension::BuiltinDerive(..) => hygiene::default_edition(),
|
||||
|
@ -58,7 +58,10 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
|
||||
call_site: span,
|
||||
def_site: None,
|
||||
format: ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("rustc_attrs"),
|
||||
Symbol::intern("structural_match"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: hygiene::default_edition(),
|
||||
|
@ -558,7 +558,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
call_site: attr.span,
|
||||
def_site: None,
|
||||
format: MacroAttribute(Symbol::intern(&attr.path.to_string())),
|
||||
allow_internal_unstable: false,
|
||||
allow_internal_unstable: Vec::new(),
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: ext.edition(),
|
||||
@ -725,7 +725,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
// don't stability-check macros in the same crate
|
||||
// (the only time this is null is for syntax extensions registered as macros)
|
||||
if def_site_span.map_or(false, |def_span| !crate_span.contains(def_span))
|
||||
&& !span.allows_unstable() && this.cx.ecfg.features.map_or(true, |feats| {
|
||||
&& !span.allows_unstable(&feature.as_str())
|
||||
&& this.cx.ecfg.features.map_or(true, |feats| {
|
||||
// macro features will count as lib features
|
||||
!feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature)
|
||||
}) {
|
||||
@ -757,7 +758,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
let opt_expanded = match *ext {
|
||||
DeclMacro { ref expander, def_info, edition, .. } => {
|
||||
if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s),
|
||||
false, false, false, None,
|
||||
Vec::new(), false, false, None,
|
||||
edition) {
|
||||
dummy_span
|
||||
} else {
|
||||
@ -768,14 +769,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
NormalTT {
|
||||
ref expander,
|
||||
def_info,
|
||||
allow_internal_unstable,
|
||||
ref allow_internal_unstable,
|
||||
allow_internal_unsafe,
|
||||
local_inner_macros,
|
||||
unstable_feature,
|
||||
edition,
|
||||
} => {
|
||||
if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s),
|
||||
allow_internal_unstable,
|
||||
allow_internal_unstable.clone(),
|
||||
allow_internal_unsafe,
|
||||
local_inner_macros,
|
||||
unstable_feature,
|
||||
@ -791,7 +792,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
IdentTT(ref expander, tt_span, allow_internal_unstable) => {
|
||||
IdentTT { ext: ref expander, span: tt_span, ref allow_internal_unstable } => {
|
||||
if ident.name == keywords::Invalid.name() {
|
||||
self.cx.span_err(path.span,
|
||||
&format!("macro {}! expects an ident argument", path));
|
||||
@ -802,7 +803,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
call_site: span,
|
||||
def_site: tt_span,
|
||||
format: macro_bang_format(path),
|
||||
allow_internal_unstable,
|
||||
allow_internal_unstable: allow_internal_unstable.clone(),
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: hygiene::default_edition(),
|
||||
@ -827,7 +828,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
kind.dummy(span)
|
||||
}
|
||||
|
||||
SyntaxExtension::ProcMacro { ref expander, allow_internal_unstable, edition } => {
|
||||
SyntaxExtension::ProcMacro { ref expander, ref allow_internal_unstable, edition } => {
|
||||
if ident.name != keywords::Invalid.name() {
|
||||
let msg =
|
||||
format!("macro {}! expects no ident argument, given '{}'", path, ident);
|
||||
@ -843,7 +844,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
def_site: None,
|
||||
format: macro_bang_format(path),
|
||||
// FIXME probably want to follow macro_rules macros here.
|
||||
allow_internal_unstable,
|
||||
allow_internal_unstable: allow_internal_unstable.clone(),
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition,
|
||||
@ -918,7 +919,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
call_site: span,
|
||||
def_site: None,
|
||||
format: MacroAttribute(pretty_name),
|
||||
allow_internal_unstable: false,
|
||||
allow_internal_unstable: Vec::new(),
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: ext.edition(),
|
||||
@ -937,7 +938,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
Some(invoc.fragment_kind.expect_from_annotatables(items))
|
||||
}
|
||||
BuiltinDerive(func) => {
|
||||
expn_info.allow_internal_unstable = true;
|
||||
expn_info.allow_internal_unstable = vec![
|
||||
Symbol::intern("rustc_attrs"),
|
||||
Symbol::intern("derive_clone_copy"),
|
||||
Symbol::intern("derive_eq"),
|
||||
];
|
||||
invoc.expansion_data.mark.set_expn_info(expn_info);
|
||||
let span = span.with_ctxt(self.cx.backtrace());
|
||||
let mut items = Vec::new();
|
||||
|
@ -44,7 +44,7 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTr
|
||||
/* __rust_unstable_column!(): expands to the current column number */
|
||||
pub fn expand_column_gated(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
if sp.allows_unstable() {
|
||||
if sp.allows_unstable("__rust_unstable_column") {
|
||||
expand_column(cx, sp, tts)
|
||||
} else {
|
||||
cx.span_fatal(sp, "the __rust_unstable_column macro is unstable");
|
||||
|
@ -376,7 +376,18 @@ pub fn compile(
|
||||
});
|
||||
|
||||
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_or(Vec::new(), |attr| attr
|
||||
.meta_item_list()
|
||||
.unwrap_or_else(|| sess.span_diagnostic.span_bug(
|
||||
attr.span, "allow_internal_unstable expects list of feature names",
|
||||
))
|
||||
.iter()
|
||||
.map(|it| it.name().unwrap_or_else(|| sess.span_diagnostic.span_bug(
|
||||
it.span, "allow internal unstable expects feature names",
|
||||
)))
|
||||
.collect()
|
||||
);
|
||||
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") {
|
||||
|
@ -1091,7 +1091,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
|
||||
stable",
|
||||
cfg_fn!(profiler_runtime))),
|
||||
|
||||
("allow_internal_unstable", Normal, template!(Word), Gated(Stability::Unstable,
|
||||
("allow_internal_unstable", Normal, template!(List: "feat1, feat2"), Gated(Stability::Unstable,
|
||||
"allow_internal_unstable",
|
||||
EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
|
||||
cfg_fn!(allow_internal_unstable))),
|
||||
@ -1199,7 +1199,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
|
||||
("proc_macro", Normal, template!(Word), Ungated),
|
||||
|
||||
("rustc_proc_macro_decls", Normal, template!(Word), Gated(Stability::Unstable,
|
||||
"rustc_proc_macro_decls",
|
||||
"rustc_attrs",
|
||||
"used internally by rustc",
|
||||
cfg_fn!(rustc_attrs))),
|
||||
|
||||
@ -1284,7 +1284,7 @@ impl GatedCfg {
|
||||
|
||||
pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) {
|
||||
let (cfg, feature, has_feature) = GATED_CFGS[self.index];
|
||||
if !has_feature(features) && !self.span.allows_unstable() {
|
||||
if !has_feature(features) && !self.span.allows_unstable(feature) {
|
||||
let explain = format!("`cfg({})` is experimental and subject to change", cfg);
|
||||
emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain);
|
||||
}
|
||||
@ -1303,7 +1303,7 @@ macro_rules! gate_feature_fn {
|
||||
name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level);
|
||||
let has_feature: bool = has_feature(&$cx.features);
|
||||
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
|
||||
if !has_feature && !span.allows_unstable() {
|
||||
if !has_feature && !span.allows_unstable($name) {
|
||||
leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level)
|
||||
.emit();
|
||||
}
|
||||
@ -1328,7 +1328,11 @@ impl<'a> Context<'a> {
|
||||
for &(n, ty, _template, ref gateage) in BUILTIN_ATTRIBUTES {
|
||||
if name == n {
|
||||
if let Gated(_, name, desc, ref has_feature) = *gateage {
|
||||
gate_feature_fn!(self, has_feature, attr.span, name, desc, GateStrength::Hard);
|
||||
if !attr.span.allows_unstable(name) {
|
||||
gate_feature_fn!(
|
||||
self, has_feature, attr.span, name, desc, GateStrength::Hard
|
||||
);
|
||||
}
|
||||
} else if name == "doc" {
|
||||
if let Some(content) = attr.meta_item_list() {
|
||||
if content.iter().any(|c| c.check_name("include")) {
|
||||
@ -1493,13 +1497,13 @@ struct PostExpansionVisitor<'a> {
|
||||
macro_rules! gate_feature_post {
|
||||
($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
|
||||
let (cx, span) = ($cx, $span);
|
||||
if !span.allows_unstable() {
|
||||
if !span.allows_unstable(stringify!($feature)) {
|
||||
gate_feature!(cx.context, $feature, span, $explain)
|
||||
}
|
||||
}};
|
||||
($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
|
||||
let (cx, span) = ($cx, $span);
|
||||
if !span.allows_unstable() {
|
||||
if !span.allows_unstable(stringify!($feature)) {
|
||||
gate_feature!(cx.context, $feature, span, $explain, $level)
|
||||
}
|
||||
}}
|
||||
@ -1610,10 +1614,8 @@ impl<'a> PostExpansionVisitor<'a> {
|
||||
|
||||
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
fn visit_attribute(&mut self, attr: &ast::Attribute) {
|
||||
if !attr.span.allows_unstable() {
|
||||
// check for gated attributes
|
||||
self.context.check_attribute(attr, false);
|
||||
}
|
||||
// check for gated attributes
|
||||
self.context.check_attribute(attr, false);
|
||||
|
||||
if attr.check_name("doc") {
|
||||
if let Some(content) = attr.meta_item_list() {
|
||||
|
@ -20,7 +20,9 @@ fn ignored_span(sp: Span) -> Span {
|
||||
call_site: DUMMY_SP,
|
||||
def_site: None,
|
||||
format: MacroAttribute(Symbol::intern("std_inject")),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("prelude_import"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: hygiene::default_edition(),
|
||||
|
@ -285,7 +285,11 @@ fn generate_test_harness(sess: &ParseSess,
|
||||
call_site: DUMMY_SP,
|
||||
def_site: None,
|
||||
format: MacroAttribute(Symbol::intern("test_case")),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("main"),
|
||||
Symbol::intern("test"),
|
||||
Symbol::intern("rustc_attrs"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: hygiene::default_edition(),
|
||||
|
@ -136,11 +136,15 @@ fn call_intrinsic(cx: &ExtCtxt<'_>,
|
||||
intrinsic: &str,
|
||||
args: Vec<P<ast::Expr>>)
|
||||
-> P<ast::Expr> {
|
||||
if cx.current_expansion.mark.expn_info().unwrap().allow_internal_unstable {
|
||||
let intrinsic_allowed_via_allow_internal_unstable = cx
|
||||
.current_expansion.mark.expn_info().unwrap()
|
||||
.allow_internal_unstable.iter()
|
||||
.any(|&s| s == "core_intrinsics");
|
||||
if intrinsic_allowed_via_allow_internal_unstable {
|
||||
span = span.with_ctxt(cx.backtrace());
|
||||
} else { // Avoid instability errors with user defined curstom derives, cc #36316
|
||||
let mut info = cx.current_expansion.mark.expn_info().unwrap();
|
||||
info.allow_internal_unstable = true;
|
||||
info.allow_internal_unstable = vec![Symbol::intern("core_intrinsics")];
|
||||
let mark = Mark::fresh(Mark::root());
|
||||
mark.set_expn_info(info);
|
||||
span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
|
||||
|
@ -711,7 +711,7 @@ pub fn expand_format_args_nl<'cx>(
|
||||
//if !ecx.ecfg.enable_allow_internal_unstable() {
|
||||
|
||||
// For some reason, the only one that actually works for `println` is the first check
|
||||
if !sp.allows_unstable() // the enclosing span is marked as `#[allow_insternal_unsable]`
|
||||
if !sp.allows_unstable("format_args_nl") // the span is marked as `#[allow_insternal_unsable]`
|
||||
&& !ecx.ecfg.enable_allow_internal_unstable() // NOTE: when is this enabled?
|
||||
&& !ecx.ecfg.enable_format_args_nl() // enabled using `#[feature(format_args_nl]`
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
||||
NormalTT {
|
||||
expander: Box::new($f as MacroExpanderFn),
|
||||
def_info: None,
|
||||
allow_internal_unstable: false,
|
||||
allow_internal_unstable: Vec::new(),
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
unstable_feature: None,
|
||||
@ -103,7 +103,9 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
||||
NormalTT {
|
||||
expander: Box::new(format::expand_format_args),
|
||||
def_info: None,
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("fmt_internals"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
unstable_feature: None,
|
||||
@ -113,7 +115,9 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
||||
NormalTT {
|
||||
expander: Box::new(format::expand_format_args_nl),
|
||||
def_info: None,
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("fmt_internals"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
unstable_feature: None,
|
||||
|
@ -333,7 +333,10 @@ fn mk_decls(
|
||||
call_site: DUMMY_SP,
|
||||
def_site: None,
|
||||
format: MacroAttribute(Symbol::intern("proc_macro")),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("rustc_attrs"),
|
||||
Symbol::intern("proc_macro_internals"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: hygiene::default_edition(),
|
||||
|
@ -66,7 +66,10 @@ pub fn expand_test_or_bench(
|
||||
call_site: DUMMY_SP,
|
||||
def_site: None,
|
||||
format: MacroAttribute(Symbol::intern("test")),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("rustc_attrs"),
|
||||
Symbol::intern("test"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: hygiene::default_edition(),
|
||||
|
@ -41,7 +41,10 @@ pub fn expand(
|
||||
call_site: DUMMY_SP,
|
||||
def_site: None,
|
||||
format: MacroAttribute(Symbol::intern("test_case")),
|
||||
allow_internal_unstable: true,
|
||||
allow_internal_unstable: vec![
|
||||
Symbol::intern("test"),
|
||||
Symbol::intern("rustc_attrs"),
|
||||
],
|
||||
allow_internal_unsafe: false,
|
||||
local_inner_macros: false,
|
||||
edition: hygiene::default_edition(),
|
||||
|
@ -550,10 +550,10 @@ pub struct ExpnInfo {
|
||||
pub def_site: Option<Span>,
|
||||
/// The format with which the macro was invoked.
|
||||
pub format: ExpnFormat,
|
||||
/// Whether the macro is allowed to use #[unstable]/feature-gated
|
||||
/// features internally without forcing the whole crate to opt-in
|
||||
/// List of #[unstable]/feature-gated features that the macro is allowed to use
|
||||
/// internally without forcing the whole crate to opt-in
|
||||
/// to them.
|
||||
pub allow_internal_unstable: bool,
|
||||
pub allow_internal_unstable: Vec<Symbol>,
|
||||
/// Whether the macro is allowed to use `unsafe` internally
|
||||
/// even if the user crate has `#![forbid(unsafe_code)]`.
|
||||
pub allow_internal_unsafe: bool,
|
||||
|
@ -385,9 +385,9 @@ impl Span {
|
||||
/// Check if a span is "internal" to a macro in which `#[unstable]`
|
||||
/// items can be used (that is, a macro marked with
|
||||
/// `#[allow_internal_unstable]`).
|
||||
pub fn allows_unstable(&self) -> bool {
|
||||
pub fn allows_unstable(&self, feature: &str) -> bool {
|
||||
match self.ctxt().outer().expn_info() {
|
||||
Some(info) => info.allow_internal_unstable,
|
||||
Some(info) => info.allow_internal_unstable.iter().any(|&f| f == feature),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
macro_rules! bar {
|
||||
() => {
|
||||
// more layers don't help:
|
||||
#[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
|
||||
#[allow_internal_unstable()] //~ ERROR allow_internal_unstable side-steps
|
||||
macro_rules! baz {
|
||||
() => {}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0658]: allow_internal_unstable side-steps feature gating and stability checks
|
||||
--> $DIR/feature-gate-allow-internal-unstable-nested-macro.rs:8:9
|
||||
|
|
||||
LL | #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[allow_internal_unstable()] //~ ERROR allow_internal_unstable side-steps
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | bar!();
|
||||
| ------- in this macro invocation
|
||||
|
@ -1,7 +1,7 @@
|
||||
// checks that this attribute is caught on non-macro items.
|
||||
// this needs a different test since this is done after expansion
|
||||
|
||||
#[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
|
||||
#[allow_internal_unstable()] //~ ERROR allow_internal_unstable side-steps
|
||||
struct S;
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0658]: allow_internal_unstable side-steps feature gating and stability checks
|
||||
--> $DIR/feature-gate-allow-internal-unstable-struct.rs:4:1
|
||||
|
|
||||
LL | #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[allow_internal_unstable()] //~ ERROR allow_internal_unstable side-steps
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(allow_internal_unstable)] to the crate attributes to enable
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![allow(unused_macros)]
|
||||
|
||||
#[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
|
||||
#[allow_internal_unstable()] //~ ERROR allow_internal_unstable side-steps
|
||||
macro_rules! foo {
|
||||
() => {}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0658]: allow_internal_unstable side-steps feature gating and stability checks
|
||||
--> $DIR/feature-gate-allow-internal-unstable.rs:3:1
|
||||
|
|
||||
LL | #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[allow_internal_unstable()] //~ ERROR allow_internal_unstable side-steps
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(allow_internal_unstable)] to the crate attributes to enable
|
||||
|
||||
|
@ -23,14 +23,14 @@ pub struct Bar {
|
||||
}
|
||||
|
||||
#[stable(feature = "stable", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[allow_internal_unstable(function)]
|
||||
#[macro_export]
|
||||
macro_rules! call_unstable_allow {
|
||||
() => { $crate::unstable() }
|
||||
}
|
||||
|
||||
#[stable(feature = "stable", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[allow_internal_unstable(struct_field)]
|
||||
#[macro_export]
|
||||
macro_rules! construct_unstable_allow {
|
||||
($e: expr) => {
|
||||
@ -39,21 +39,21 @@ macro_rules! construct_unstable_allow {
|
||||
}
|
||||
|
||||
#[stable(feature = "stable", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[allow_internal_unstable(method)]
|
||||
#[macro_export]
|
||||
macro_rules! call_method_allow {
|
||||
($e: expr) => { $e.method() }
|
||||
}
|
||||
|
||||
#[stable(feature = "stable", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[allow_internal_unstable(struct_field, struct2_field)]
|
||||
#[macro_export]
|
||||
macro_rules! access_field_allow {
|
||||
($e: expr) => { $e.x }
|
||||
}
|
||||
|
||||
#[stable(feature = "stable", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
#[allow_internal_unstable()]
|
||||
#[macro_export]
|
||||
macro_rules! pass_through_allow {
|
||||
($e: expr) => { $e }
|
||||
|
@ -13,7 +13,7 @@ macro_rules! foo {
|
||||
}}
|
||||
}
|
||||
|
||||
#[allow_internal_unstable]
|
||||
#[allow_internal_unstable(function)]
|
||||
macro_rules! bar {
|
||||
($e: expr) => {{
|
||||
foo!($e,
|
||||
|
Loading…
x
Reference in New Issue
Block a user