提交 8eaf17bc 编写于 作者: V Vadim Petrochenkov

Introduce built-in macros through libcore

上级 4268e7ee
......@@ -657,13 +657,13 @@
);
}
/// Built-in macros to the compiler itself.
/// Definitions of built-in macros.
///
/// These macros do not have any corresponding definition with a `macro_rules!`
/// macro, but are documented here. Their implementations can be found hardcoded
/// into libsyntax itself.
#[cfg(rustdoc)]
mod builtin {
/// Most of the macro properties (stability, visibility, etc.) are taken from the source code here,
/// with exception of expansion functions transforming macro inputs into outputs,
/// those functions are provided by the compiler.
#[cfg(not(bootstrap))]
pub(crate) mod builtin {
/// Causes compilation to fail with the given error message when encountered.
///
......@@ -950,7 +950,7 @@ mod builtin {
/// Same as `column`, but less likely to be shadowed.
#[unstable(feature = "__rust_unstable_column", issue = "0",
reason = "internal implementation detail of the `column` macro")]
reason = "internal implementation detail of the `panic` macro")]
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro __rust_unstable_column() { /* compiler built-in */ }
......
......@@ -44,3 +44,50 @@
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
pub use crate::result::Result::{self, Ok, Err};
// Re-exported built-in macros
#[cfg(not(bootstrap))]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow(deprecated)]
#[doc(no_inline)]
pub use crate::macros::builtin::{
Clone,
Copy,
Debug,
Decodable,
Default,
Encodable,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
RustcDecodable,
RustcEncodable,
__rust_unstable_column,
asm,
assert,
bench,
cfg,
column,
compile_error,
concat,
concat_idents,
env,
file,
format_args,
format_args_nl,
global_allocator,
global_asm,
include,
include_bytes,
include_str,
line,
log_syntax,
module_path,
option_env,
stringify,
test,
test_case,
trace_macros,
};
......@@ -217,7 +217,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// This handle encapsulates a [`RawWaker`] instance, which defines the
/// executor-specific wakeup behavior.
///
/// Implements [`Clone`], [`Send`], and [`Sync`].
/// Implements [`Clone`], [`trait@Send`], and [`trait@Sync`].
///
/// [`RawWaker`]: struct.RawWaker.html
#[repr(transparent)]
......
......@@ -12,10 +12,6 @@ pub struct CrateId {
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CrateNum {
/// Virtual crate for builtin macros
// FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
// `CrateNum`s.
BuiltinMacros,
/// A special CrateNum that we use for the tcx.rcache when decoding from
/// the incr. comp. cache.
ReservedForIncrCompCache,
......@@ -26,7 +22,6 @@ impl ::std::fmt::Debug for CrateNum {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match self {
CrateNum::Index(id) => write!(fmt, "crate{}", id.private),
CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"),
CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"),
}
}
......@@ -86,7 +81,6 @@ impl fmt::Display for CrateNum {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CrateNum::Index(id) => fmt::Display::fmt(&id.private, f),
CrateNum::BuiltinMacros => write!(f, "builtin macros crate"),
CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"),
}
}
......
......@@ -4009,8 +4009,7 @@ pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
let mut vis = self.lower_visibility(&i.vis, None);
let attrs = self.lower_attrs(&i.attrs);
if let ItemKind::MacroDef(ref def) = i.node {
if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) ||
attr::contains_name(&i.attrs, sym::rustc_builtin_macro) {
if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) {
let body = self.lower_token_stream(def.stream());
let hir_id = self.lower_node_id(i.id);
self.exported_macros.push(hir::MacroDef {
......
......@@ -372,7 +372,10 @@ fn configure_and_expand_inner<'a>(
crate_loader,
&resolver_arenas,
);
syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts, sess.edition());
syntax_ext::register_builtin_macros(&mut resolver, sess.edition());
syntax_ext::plugin_macro_defs::inject(
&mut krate, &mut resolver, plugin_info.syntax_exts, sess.edition()
);
// Expand all macros
sess.profiler(|p| p.start_activity("macro expansion"));
......
......@@ -13,7 +13,7 @@
use rustc::bug;
use rustc::hir::def::{self, *};
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
use rustc::ty;
use rustc::middle::cstore::CrateStore;
use rustc_metadata::cstore::LoadedMacro;
......@@ -31,7 +31,6 @@
use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant};
use syntax::ext::base::SyntaxExtension;
use syntax::ext::hygiene::ExpnId;
use syntax::ext::tt::macro_rules;
use syntax::feature_gate::is_builtin_attr;
use syntax::parse::token::{self, Token};
use syntax::span_err;
......@@ -748,7 +747,7 @@ pub fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
};
if let Some(id) = self.definitions.as_local_node_id(def_id) {
self.local_macro_def_scopes[&id]
} else if def_id.krate == CrateNum::BuiltinMacros {
} else if self.is_builtin_macro(Some(def_id)) {
self.injected_crate.unwrap_or(self.graph_root)
} else {
let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
......@@ -756,13 +755,16 @@ pub fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
}
}
pub fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
let def_id = match res {
Res::Def(DefKind::Macro(..), def_id) => def_id,
crate fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
match res {
Res::Def(DefKind::Macro(..), def_id) => self.get_macro_by_def_id(def_id),
Res::NonMacroAttr(attr_kind) =>
return Some(self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool)),
_ => return None,
};
Some(self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool)),
_ => None,
}
}
crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
if let Some(ext) = self.macro_map.get(&def_id) {
return Some(ext.clone());
}
......@@ -772,10 +774,7 @@ pub fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
LoadedMacro::ProcMacro(ext) => return Some(ext),
};
let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess,
&self.session.features_untracked(),
&macro_def,
self.cstore.crate_edition_untracked(def_id.krate)));
let ext = self.compile_macro(&macro_def, self.cstore.crate_edition_untracked(def_id.krate));
self.macro_map.insert(def_id, ext.clone());
Some(ext)
}
......
......@@ -35,17 +35,12 @@ enum AssocSuggestion {
struct TypoSuggestion {
candidate: Symbol,
/// The kind of the binding ("crate", "module", etc.)
kind: &'static str,
/// An appropriate article to refer to the binding ("a", "an", etc.)
article: &'static str,
res: Res,
}
impl TypoSuggestion {
fn from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
TypoSuggestion { candidate, kind: res.descr(), article: res.article() }
TypoSuggestion { candidate, res }
}
}
......@@ -59,7 +54,9 @@ fn add_typo_suggestion(
err: &mut DiagnosticBuilder<'_>, suggestion: Option<TypoSuggestion>, span: Span
) -> bool {
if let Some(suggestion) = suggestion {
let msg = format!("{} {} with a similar name exists", suggestion.article, suggestion.kind);
let msg = format!(
"{} {} with a similar name exists", suggestion.res.article(), suggestion.res.descr()
);
err.span_suggestion(
span, &msg, suggestion.candidate.to_string(), Applicability::MaybeIncorrect
);
......@@ -566,7 +563,7 @@ fn early_lookup_typo_candidate(
filter_fn: &impl Fn(Res) -> bool,
) -> Option<TypoSuggestion> {
let mut suggestions = Vec::new();
self.visit_scopes(scope_set, parent_scope, ident, |this, scope, _| {
self.visit_scopes(scope_set, parent_scope, ident, |this, scope, use_prelude, _| {
match scope {
Scope::DeriveHelpers => {
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
......@@ -611,16 +608,6 @@ fn early_lookup_typo_candidate(
}
}));
}
Scope::BuiltinMacros => {
suggestions.extend(this.builtin_macros.iter().filter_map(|(name, binding)| {
let res = binding.res();
if filter_fn(res) {
Some(TypoSuggestion::from_res(*name, res))
} else {
None
}
}));
}
Scope::BuiltinAttrs => {
let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
if filter_fn(res) {
......@@ -656,7 +643,11 @@ fn early_lookup_typo_candidate(
}
Scope::StdLibPrelude => {
if let Some(prelude) = this.prelude {
add_module_candidates(prelude, &mut suggestions, filter_fn);
let mut tmp_suggestions = Vec::new();
add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
suggestions.extend(tmp_suggestions.into_iter().filter(|s| {
use_prelude || this.is_builtin_macro(s.res.opt_def_id())
}));
}
}
Scope::BuiltinTypes => {
......@@ -733,11 +724,7 @@ fn lookup_typo_candidate(
);
if filter_fn(crate_mod) {
Some(TypoSuggestion {
candidate: ident.name,
article: "a",
kind: "crate",
})
Some(TypoSuggestion::from_res(ident.name, crate_mod))
} else {
None
}
......
......@@ -114,7 +114,6 @@ enum Scope<'a> {
CrateRoot,
Module(Module<'a>),
MacroUsePrelude,
BuiltinMacros,
BuiltinAttrs,
LegacyPluginHelpers,
ExternPrelude,
......@@ -1679,7 +1678,7 @@ pub struct Resolver<'a> {
crate_loader: &'a mut CrateLoader<'a>,
macro_names: FxHashSet<Ident>,
builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
builtin_macros: FxHashMap<Name, SyntaxExtension>,
macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
pub all_macros: FxHashMap<Name, Res>,
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
......@@ -2021,7 +2020,7 @@ pub fn new(session: &'a Session,
crate_loader,
macro_names: FxHashSet::default(),
builtin_macros: FxHashMap::default(),
builtin_macros: Default::default(),
macro_use_prelude: FxHashMap::default(),
all_macros: FxHashMap::default(),
macro_map: FxHashMap::default(),
......@@ -2068,6 +2067,11 @@ fn per_ns<F: FnMut(&mut Self, Namespace)>(&mut self, mut f: F) {
f(self, MacroNS);
}
fn is_builtin_macro(&mut self, def_id: Option<DefId>) -> bool {
def_id.and_then(|def_id| self.get_macro_by_def_id(def_id))
.map_or(false, |ext| ext.is_builtin)
}
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
loop {
match self.macro_defs.get(&ctxt.outer_expn()) {
......@@ -2146,7 +2150,7 @@ fn visit_scopes<T>(
scope_set: ScopeSet,
parent_scope: &ParentScope<'a>,
ident: Ident,
mut visitor: impl FnMut(&mut Self, Scope<'a>, Ident) -> Option<T>,
mut visitor: impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>,
) -> Option<T> {
// General principles:
// 1. Not controlled (user-defined) names should have higher priority than controlled names
......@@ -2185,8 +2189,8 @@ fn visit_scopes<T>(
// 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
// 4a. User-defined prelude from macro-use
// (open, the open part is from macro expansions, not controlled).
// 4b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
// 5. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
// 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).
// 4c. Standard library prelude (de-facto closed, controlled).
// 6. Language prelude: builtin attributes (closed, controlled).
// 4-6. Legacy plugin helpers (open, not controlled). Similar to derive helpers,
// but introduced by legacy plugins using `register_attribute`. Priority is somewhere
......@@ -2214,17 +2218,16 @@ fn visit_scopes<T>(
Scope::CrateRoot => true,
Scope::Module(..) => true,
Scope::MacroUsePrelude => use_prelude || rust_2015,
Scope::BuiltinMacros => true,
Scope::BuiltinAttrs => true,
Scope::LegacyPluginHelpers => use_prelude || rust_2015,
Scope::ExternPrelude => use_prelude || is_absolute_path,
Scope::ToolPrelude => use_prelude,
Scope::StdLibPrelude => use_prelude,
Scope::StdLibPrelude => use_prelude || ns == MacroNS,
Scope::BuiltinTypes => true,
};
if visit {
if let break_result @ Some(..) = visitor(self, scope, ident) {
if let break_result @ Some(..) = visitor(self, scope, use_prelude, ident) {
return break_result;
}
}
......@@ -2263,7 +2266,6 @@ fn visit_scopes<T>(
}
}
Scope::MacroUsePrelude => Scope::StdLibPrelude,
Scope::BuiltinMacros => Scope::BuiltinAttrs,
Scope::BuiltinAttrs => Scope::LegacyPluginHelpers,
Scope::LegacyPluginHelpers => break, // nowhere else to search
Scope::ExternPrelude if is_absolute_path => break,
......@@ -2272,7 +2274,7 @@ fn visit_scopes<T>(
Scope::StdLibPrelude => match ns {
TypeNS => Scope::BuiltinTypes,
ValueNS => break, // nowhere else to search
MacroNS => Scope::BuiltinMacros,
MacroNS => Scope::BuiltinAttrs,
}
Scope::BuiltinTypes => break, // nowhere else to search
};
......
use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy};
use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak};
use crate::{Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding};
use crate::{Module, ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
use crate::{resolve_error, KNOWN_TOOLS};
use crate::ModuleOrUniformRoot;
use crate::Namespace::*;
use crate::build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
use crate::resolve_imports::ImportResolver;
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
use rustc::hir::map::DefCollector;
use rustc::middle::stability;
use rustc::{ty, lint, span_bug};
use syntax::ast::{self, Ident, ItemKind};
use syntax::attr::{self, StabilityLevel};
use syntax::edition::Edition;
use syntax::ext::base::{self, Indeterminate};
use syntax::ext::base::{MacroKind, SyntaxExtension};
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
......@@ -182,21 +183,8 @@ fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &A
invocation.output_legacy_scope.set(Some(visitor.current_legacy_scope));
}
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
let def_id = DefId {
krate: CrateNum::BuiltinMacros,
index: DefIndex::from(self.macro_map.len()),
};
let kind = ext.macro_kind();
self.macro_map.insert(def_id, ext);
let binding = self.arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Res(Res::Def(DefKind::Macro(kind), def_id), false),
ambiguity: None,
span: DUMMY_SP,
vis: ty::Visibility::Public,
expansion: ExpnId::root(),
});
if self.builtin_macros.insert(ident.name, binding).is_some() {
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) {
if self.builtin_macros.insert(ident.name, ext).is_some() {
self.session.span_err(ident.span,
&format!("built-in macro `{}` was already defined", ident));
}
......@@ -449,8 +437,8 @@ struct Flags: u8 {
let mut determinacy = Determinacy::Determined;
// Go through all the scopes and try to resolve the name.
let break_result =
self.visit_scopes(scope_set, parent_scope, orig_ident, |this, scope, ident| {
let break_result = self.visit_scopes(scope_set, parent_scope, orig_ident,
|this, scope, use_prelude, ident| {
let result = match scope {
Scope::DeriveHelpers => {
let mut result = Err(Determinacy::Determined);
......@@ -535,10 +523,6 @@ struct Flags: u8 {
this.graph_root.unresolved_invocations.borrow().is_empty()
))
}
Scope::BuiltinMacros => match this.builtin_macros.get(&ident.name).cloned() {
Some(binding) => Ok((binding, Flags::PRELUDE)),
None => Err(Determinacy::Determined),
}
Scope::BuiltinAttrs => if is_builtin_attr_name(ident.name) {
let binding = (Res::NonMacroAttr(NonMacroAttrKind::Builtin),
ty::Visibility::Public, DUMMY_SP, ExpnId::root())
......@@ -579,7 +563,9 @@ struct Flags: u8 {
false,
path_span,
) {
result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE));
if use_prelude || this.is_builtin_macro(binding.res().opt_def_id()) {
result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE));
}
}
}
result
......@@ -844,18 +830,42 @@ fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>
}
}
/// Compile the macro into a `SyntaxExtension` and possibly replace it with a pre-defined
/// extension partially or entirely for built-in macros and legacy plugin macros.
crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> Lrc<SyntaxExtension> {
let mut result = macro_rules::compile(
&self.session.parse_sess, self.session.features_untracked(), item, edition
);
if result.is_builtin {
// The macro was marked with `#[rustc_builtin_macro]`.
if let Some(ext) = self.builtin_macros.remove(&item.ident.name) {
if ext.is_builtin {
// The macro is a built-in, replace only the expander function.
result.kind = ext.kind;
// Also reset its edition to the global one for compatibility.
result.edition = self.session.edition();
} else {
// The macro is from a plugin, the in-source definition is dummy,
// take all the data from the resolver.
result = ext;
}
} else {
let msg = format!("cannot find a built-in macro with name `{}`", item.ident);
self.session.span_err(item.span, &msg);
}
}
Lrc::new(result)
}
pub fn define_macro(&mut self,
item: &ast::Item,
expansion: ExpnId,
current_legacy_scope: &mut LegacyScope<'a>) {
let (ext, ident, span, is_legacy) = match &item.node {
ItemKind::MacroDef(def) => {
let ext = Lrc::new(macro_rules::compile(
&self.session.parse_sess,
&self.session.features_untracked(),
item,
self.session.edition(),
));
let ext = self.compile_macro(item, self.session.edition());
(ext, item.ident, item.span, def.legacy)
}
ItemKind::Fn(..) => match proc_macro_stub(item) {
......
......@@ -21,8 +21,8 @@
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
UNUSED_IMPORTS,
};
use rustc::hir::def_id::{CrateNum, DefId};
use rustc::hir::def::{self, DefKind, PartialRes, Export};
use rustc::hir::def_id::DefId;
use rustc::hir::def::{self, PartialRes, Export};
use rustc::session::DiagnosticMessageId;
use rustc::util::nodemap::FxHashSet;
use rustc::{bug, span_bug};
......@@ -1214,17 +1214,7 @@ fn finalize_import(
// this may resolve to either a value or a type, but for documentation
// purposes it's good enough to just favor one over the other.
self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
let mut res = binding.res();
if let Res::Def(DefKind::Macro(_), def_id) = res {
// `DefId`s from the "built-in macro crate" should not leak from resolve because
// later stages are not ready to deal with them and produce lots of ICEs. Replace
// them with `Res::Err` until some saner scheme is implemented for built-in macros.
if def_id.krate == CrateNum::BuiltinMacros {
this.session.span_err(directive.span, "cannot import a built-in macro");
res = Res::Err;
}
}
this.import_res_map.entry(directive.id).or_default()[ns] = Some(res);
this.import_res_map.entry(directive.id).or_default()[ns] = Some(binding.res());
});
self.check_for_redundant_imports(
......@@ -1388,7 +1378,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
let res = binding.res();
if res != Res::Err {
if let Some(def_id) = res.opt_def_id() {
if !def_id.is_local() && def_id.krate != CrateNum::BuiltinMacros {
if !def_id.is_local() {
self.cstore.export_macros_untracked(def_id.krate);
}
}
......
......@@ -254,8 +254,8 @@ fn from(err: E) -> Box<dyn Error + 'a> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of dyn [`Error`] +
/// [`Send`] + [`Sync`].
/// Converts a type of [`Error`] + [`trait@Send`] + [`trait@Sync`] into a box of
/// dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
///
/// [`Error`]: ../error/trait.Error.html
///
......@@ -298,7 +298,7 @@ fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for Box<dyn Error + Send + Sync> {
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
/// Converts a [`String`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
///
/// [`Error`]: ../error/trait.Error.html
///
......@@ -362,7 +362,7 @@ fn from(str_err: String) -> Box<dyn Error> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
/// Converts a [`str`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
///
/// [`Error`]: ../error/trait.Error.html
///
......@@ -405,7 +405,7 @@ fn from(err: &str) -> Box<dyn Error> {
#[stable(feature = "cow_box_error", since = "1.22.0")]
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
///
/// [`Cow`]: ../borrow/enum.Cow.html
/// [`Error`]: ../error/trait.Error.html
......
......@@ -221,14 +221,15 @@
#![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))]
#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
feature(global_asm, slice_index_methods,
decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
feature(slice_index_methods, decl_macro, coerce_unsized,
sgx_platform, ptr_wrapping_offset_from))]
#![cfg_attr(all(test, target_vendor = "fortanix", target_env = "sgx"),
feature(fixed_size_array, maybe_uninit_extra))]
// std is implemented with unstable features, many of which are internal
// compiler details that will never be stable
// NB: the following list is sorted to minimize merge conflicts.
#![cfg_attr(not(bootstrap), feature(__rust_unstable_column))]
#![feature(alloc_error_handler)]
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
......@@ -251,6 +252,7 @@
#![feature(const_cstr_unchecked)]
#![feature(const_raw_ptr_deref)]
#![feature(core_intrinsics)]
#![feature(custom_test_frameworks)]
#![feature(doc_alias)]
#![feature(doc_cfg)]
#![feature(doc_keyword)]
......@@ -262,7 +264,9 @@
#![feature(exhaustive_patterns)]
#![feature(external_doc)]
#![feature(fn_traits)]
#![feature(format_args_nl)]
#![feature(generator_trait)]
#![feature(global_asm)]
#![feature(hash_raw_entry)]
#![feature(hashmap_internals)]
#![feature(int_error_internals)]
......@@ -272,6 +276,7 @@
#![feature(libc)]
#![feature(link_args)]
#![feature(linkage)]
#![feature(log_syntax)]
#![feature(maybe_uninit_ref)]
#![feature(maybe_uninit_slice)]
#![feature(mem_take)]
......@@ -303,6 +308,7 @@
#![feature(thread_local)]
#![feature(todo_macro)]
#![feature(toowned_clone_into)]
#![feature(trace_macros)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(untagged_unions)]
......@@ -510,6 +516,36 @@ pub mod task {
#[cfg(not(test))]
pub use std_detect::detect;
// Document built-in macros in the crate root for consistency with libcore and existing tradition.
// FIXME: Attribute and derive macros are not reexported because rustdoc renders them
// as reexports rather than as macros, and that's not what we want.
#[cfg(rustdoc)]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
pub use crate::prelude::v1::{
__rust_unstable_column,
asm,
assert,
cfg,
column,
compile_error,
concat,
concat_idents,
env,
file,
format_args,
format_args_nl,
global_asm,
include,
include_bytes,
include_str,
line,
log_syntax,
module_path,
option_env,
stringify,
trace_macros,
};
// Include a number of private modules that exist solely to provide
// the rustdoc documentation for primitive types. Using `include!`
// because rustdoc only looks for these modules at the crate level.
......
......@@ -365,534 +365,3 @@
"{} is not approximately equal to {}", *a, *b);
})
}
/// Built-in macros to the compiler itself.
///
/// These macros do not have any corresponding definition with a `macro_rules!`
/// macro, but are documented here. Their implementations can be found hardcoded
/// into libsyntax itself.
#[cfg(rustdoc)]
mod builtin {
/// Causes compilation to fail with the given error message when encountered.
///
/// This macro should be used when a crate uses a conditional compilation strategy to provide
/// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
/// which emits an error at *runtime*, rather than during compilation.
///
/// # Examples
///
/// Two such examples are macros and `#[cfg]` environments.
///
/// Emit better compiler error if a macro is passed invalid values. Without the final branch,
/// the compiler would still emit an error, but the error's message would not mention the two
/// valid values.
///
/// ```compile_fail
/// macro_rules! give_me_foo_or_bar {
/// (foo) => {};
/// (bar) => {};
/// ($x:ident) => {
/// compile_error!("This macro only accepts `foo` or `bar`");
/// }
/// }
///
/// give_me_foo_or_bar!(neither);
/// // ^ will fail at compile time with message "This macro only accepts `foo` or `bar`"
/// ```
///
/// Emit compiler error if one of a number of features isn't available.
///
/// ```compile_fail
/// #[cfg(not(any(feature = "foo", feature = "bar")))]
/// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.");
/// ```
///
/// [`panic!`]: ../std/macro.panic.html
#[stable(feature = "compile_error_macro", since = "1.20.0")]
#[rustc_builtin_macro]
macro_rules! compile_error {
($msg:expr) => ({ /* compiler built-in */ });
($msg:expr,) => ({ /* compiler built-in */ });
}
/// Constructs parameters for the other string-formatting macros.
///
/// This macro functions by taking a formatting string literal containing
/// `{}` for each additional argument passed. `format_args!` prepares the
/// additional parameters to ensure the output can be interpreted as a string
/// and canonicalizes the arguments into a single type. Any value that implements
/// the [`Display`] trait can be passed to `format_args!`, as can any
/// [`Debug`] implementation be passed to a `{:?}` within the formatting string.
///
/// This macro produces a value of type [`fmt::Arguments`]. This value can be
/// passed to the macros within [`std::fmt`] for performing useful redirection.
/// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
/// proxied through this one. `format_args!`, unlike its derived macros, avoids
/// heap allocations.
///
/// You can use the [`fmt::Arguments`] value that `format_args!` returns
/// in `Debug` and `Display` contexts as seen below. The example also shows
/// that `Debug` and `Display` format to the same thing: the interpolated
/// format string in `format_args!`.
///
/// ```rust
/// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
/// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
/// assert_eq!("1 foo 2", display);
/// assert_eq!(display, debug);
/// ```
///
/// For more information, see the documentation in [`std::fmt`].
///
/// [`Display`]: ../std/fmt/trait.Display.html
/// [`Debug`]: ../std/fmt/trait.Debug.html
/// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html
/// [`std::fmt`]: ../std/fmt/index.html
/// [`format!`]: ../std/macro.format.html
/// [`write!`]: ../std/macro.write.html
/// [`println!`]: ../std/macro.println.html
///
/// # Examples
///
/// ```
/// use std::fmt;
///
/// let s = fmt::format(format_args!("hello {}", "world"));
/// assert_eq!(s, format!("hello {}", "world"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! format_args {
($fmt:expr) => ({ /* compiler built-in */ });
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
}
/// Inspects an environment variable at compile time.
///
/// This macro will expand to the value of the named environment variable at
/// compile time, yielding an expression of type `&'static str`.
///
/// If the environment variable is not defined, then a compilation error
/// will be emitted. To not emit a compile error, use the [`option_env!`]
/// macro instead.
///
/// [`option_env!`]: ../std/macro.option_env.html
///
/// # Examples
///
/// ```
/// let path: &'static str = env!("PATH");
/// println!("the $PATH variable at the time of compiling was: {}", path);
/// ```
///
/// You can customize the error message by passing a string as the second
/// parameter:
///
/// ```compile_fail
/// let doc: &'static str = env!("documentation", "what's that?!");
/// ```
///
/// If the `documentation` environment variable is not defined, you'll get
/// the following error:
///
/// ```text
/// error: what's that?!
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! env {
($name:expr) => ({ /* compiler built-in */ });
($name:expr,) => ({ /* compiler built-in */ });
}
/// Optionally inspects an environment variable at compile time.
///
/// If the named environment variable is present at compile time, this will
/// expand into an expression of type `Option<&'static str>` whose value is
/// `Some` of the value of the environment variable. If the environment
/// variable is not present, then this will expand to `None`. See
/// [`Option<T>`][option] for more information on this type.
///
/// A compile time error is never emitted when using this macro regardless
/// of whether the environment variable is present or not.
///
/// [option]: ../std/option/enum.Option.html
///
/// # Examples
///
/// ```
/// let key: Option<&'static str> = option_env!("SECRET_KEY");
/// println!("the secret key might be: {:?}", key);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! option_env {
($name:expr) => ({ /* compiler built-in */ });
($name:expr,) => ({ /* compiler built-in */ });
}
/// Concatenates identifiers into one identifier.
///
/// This macro takes any number of comma-separated identifiers, and
/// concatenates them all into one, yielding an expression which is a new
/// identifier. Note that hygiene makes it such that this macro cannot
/// capture local variables. Also, as a general rule, macros are only
/// allowed in item, statement or expression position. That means while
/// you may use this macro for referring to existing variables, functions or
/// modules etc, you cannot define a new one with it.
///
/// # Examples
///
/// ```
/// #![feature(concat_idents)]
///
/// # fn main() {
/// fn foobar() -> u32 { 23 }
///
/// let f = concat_idents!(foo, bar);
/// println!("{}", f());
///
/// // fn concat_idents!(new, fun, name) { } // not usable in this way!
/// # }
/// ```
#[unstable(feature = "concat_idents_macro", issue = "29599")]
#[rustc_builtin_macro]
macro_rules! concat_idents {
($($e:ident),+) => ({ /* compiler built-in */ });
($($e:ident,)+) => ({ /* compiler built-in */ });
}
/// Concatenates literals into a static string slice.
///
/// This macro takes any number of comma-separated literals, yielding an
/// expression of type `&'static str` which represents all of the literals
/// concatenated left-to-right.
///
/// Integer and floating point literals are stringified in order to be
/// concatenated.
///
/// # Examples
///
/// ```
/// let s = concat!("test", 10, 'b', true);
/// assert_eq!(s, "test10btrue");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! concat {
($($e:expr),*) => ({ /* compiler built-in */ });
($($e:expr,)*) => ({ /* compiler built-in */ });
}
/// Expands to the line number on which it was invoked.
///
/// With [`column!`] and [`file!`], these macros provide debugging information for
/// developers about the location within the source.
///
/// The expanded expression has type `u32` and is 1-based, so the first line
/// in each file evaluates to 1, the second to 2, etc. This is consistent
/// with error messages by common compilers or popular editors.
/// The returned line is *not necessarily* the line of the `line!` invocation itself,
/// but rather the first macro invocation leading up to the invocation
/// of the `line!` macro.
///
/// [`column!`]: macro.column.html
/// [`file!`]: macro.file.html
///
/// # Examples
///
/// ```
/// let current_line = line!();
/// println!("defined on line: {}", current_line);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! line { () => ({ /* compiler built-in */ }) }
/// Expands to the column number at which it was invoked.
///
/// With [`line!`] and [`file!`], these macros provide debugging information for
/// developers about the location within the source.
///
/// The expanded expression has type `u32` and is 1-based, so the first column
/// in each line evaluates to 1, the second to 2, etc. This is consistent
/// with error messages by common compilers or popular editors.
/// The returned column is *not necessarily* the line of the `column!` invocation itself,
/// but rather the first macro invocation leading up to the invocation
/// of the `column!` macro.
///
/// [`line!`]: macro.line.html
/// [`file!`]: macro.file.html
///
/// # Examples
///
/// ```
/// let current_col = column!();
/// println!("defined on column: {}", current_col);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! column { () => ({ /* compiler built-in */ }) }
/// Expands to the file name in which it was invoked.
///
/// With [`line!`] and [`column!`], these macros provide debugging information for
/// developers about the location within the source.
///
///
/// The expanded expression has type `&'static str`, and the returned file
/// is not the invocation of the `file!` macro itself, but rather the
/// first macro invocation leading up to the invocation of the `file!`
/// macro.
///
/// [`line!`]: macro.line.html
/// [`column!`]: macro.column.html
///
/// # Examples
///
/// ```
/// let this_file = file!();
/// println!("defined in file: {}", this_file);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! file { () => ({ /* compiler built-in */ }) }
/// Stringifies its arguments.
///
/// This macro will yield an expression of type `&'static str` which is the
/// stringification of all the tokens passed to the macro. No restrictions
/// are placed on the syntax of the macro invocation itself.
///
/// Note that the expanded results of the input tokens may change in the
/// future. You should be careful if you rely on the output.
///
/// # Examples
///
/// ```
/// let one_plus_one = stringify!(1 + 1);
/// assert_eq!(one_plus_one, "1 + 1");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) }
/// Includes a utf8-encoded file as a string.
///
/// The file is located relative to the current file. (similarly to how
/// modules are found)
///
/// This macro will yield an expression of type `&'static str` which is the
/// contents of the file.
///
/// # Examples
///
/// Assume there are two files in the same directory with the following
/// contents:
///
/// File 'spanish.in':
///
/// ```text
/// adiós
/// ```
///
/// File 'main.rs':
///
/// ```ignore (cannot-doctest-external-file-dependency)
/// fn main() {
/// let my_str = include_str!("spanish.in");
/// assert_eq!(my_str, "adiós\n");
/// print!("{}", my_str);
/// }
/// ```
///
/// Compiling 'main.rs' and running the resulting binary will print "adiós".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! include_str {
($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ });
}
/// Includes a file as a reference to a byte array.
///
/// The file is located relative to the current file. (similarly to how
/// modules are found)
///
/// This macro will yield an expression of type `&'static [u8; N]` which is
/// the contents of the file.
///
/// # Examples
///
/// Assume there are two files in the same directory with the following
/// contents:
///
/// File 'spanish.in':
///
/// ```text
/// adiós
/// ```
///
/// File 'main.rs':
///
/// ```ignore (cannot-doctest-external-file-dependency)
/// fn main() {
/// let bytes = include_bytes!("spanish.in");
/// assert_eq!(bytes, b"adi\xc3\xb3s\n");
/// print!("{}", String::from_utf8_lossy(bytes));
/// }
/// ```
///
/// Compiling 'main.rs' and running the resulting binary will print "adiós".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! include_bytes {
($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ });
}
/// Expands to a string that represents the current module path.
///
/// The current module path can be thought of as the hierarchy of modules
/// leading back up to the crate root. The first component of the path
/// returned is the name of the crate currently being compiled.
///
/// # Examples
///
/// ```
/// mod test {
/// pub fn foo() {
/// assert!(module_path!().ends_with("test"));
/// }
/// }
///
/// test::foo();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! module_path { () => ({ /* compiler built-in */ }) }
/// Evaluates boolean combinations of configuration flags at compile-time.
///
/// In addition to the `#[cfg]` attribute, this macro is provided to allow
/// boolean expression evaluation of configuration flags. This frequently
/// leads to less duplicated code.
///
/// The syntax given to this macro is the same syntax as the [`cfg`]
/// attribute.
///
/// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute
///
/// # Examples
///
/// ```
/// let my_directory = if cfg!(windows) {
/// "windows-specific-directory"
/// } else {
/// "unix-directory"
/// };
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
/// Parses a file as an expression or an item according to the context.
///
/// The file is located relative to the current file (similarly to how
/// modules are found).
///
/// Using this macro is often a bad idea, because if the file is
/// parsed as an expression, it is going to be placed in the
/// surrounding code unhygienically. This could result in variables
/// or functions being different from what the file expected if
/// there are variables or functions that have the same name in
/// the current file.
///
/// # Examples
///
/// Assume there are two files in the same directory with the following
/// contents:
///
/// File 'monkeys.in':
///
/// ```ignore (only-for-syntax-highlight)
/// ['🙈', '🙊', '🙉']
/// .iter()
/// .cycle()
/// .take(6)
/// .collect::<String>()
/// ```
///
/// File 'main.rs':
///
/// ```ignore (cannot-doctest-external-file-dependency)
/// fn main() {
/// let my_string = include!("monkeys.in");
/// assert_eq!("🙈🙊🙉🙈🙊🙉", my_string);
/// println!("{}", my_string);
/// }
/// ```
///
/// Compiling 'main.rs' and running the resulting binary will print
/// "🙈🙊🙉🙈🙊🙉".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! include {
($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ });
}
/// Asserts that a boolean expression is `true` at runtime.
///
/// This will invoke the [`panic!`] macro if the provided expression cannot be
/// evaluated to `true` at runtime.
///
/// # Uses
///
/// Assertions are always checked in both debug and release builds, and cannot
/// be disabled. See [`debug_assert!`] for assertions that are not enabled in
/// release builds by default.
///
/// Unsafe code relies on `assert!` to enforce run-time invariants that, if
/// violated could lead to unsafety.
///
/// Other use-cases of `assert!` include testing and enforcing run-time
/// invariants in safe code (whose violation cannot result in unsafety).
///
/// # Custom Messages
///
/// This macro has a second form, where a custom panic message can
/// be provided with or without arguments for formatting. See [`std::fmt`]
/// for syntax for this form.
///
/// [`panic!`]: macro.panic.html
/// [`debug_assert!`]: macro.debug_assert.html
/// [`std::fmt`]: ../std/fmt/index.html
///
/// # Examples
///
/// ```
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// assert!(true);
///
/// fn some_computation() -> bool { true } // a very simple function
///
/// assert!(some_computation());
///
/// // assert with a custom message
/// let x = true;
/// assert!(x, "x wasn't true!");
///
/// let a = 3; let b = 27;
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
macro_rules! assert {
($cond:expr) => ({ /* compiler built-in */ });
($cond:expr,) => ({ /* compiler built-in */ });
($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ });
}
}
......@@ -7,9 +7,13 @@
#![stable(feature = "rust1", since = "1.0.0")]
// Re-exported core operators
#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)]
pub use crate::marker::{Copy, Send, Sized, Sync, Unpin};
pub use crate::marker::Copy;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)]
pub use crate::marker::{Send, Sized, Sync, Unpin};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)]
pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
......@@ -20,15 +24,18 @@
pub use crate::mem::drop;
// Re-exported types and traits
#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)]
pub use crate::clone::Clone;
#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)]
pub use crate::cmp::{PartialEq, PartialOrd, Eq, Ord};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)]
pub use crate::convert::{AsRef, AsMut, Into, From};
#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)]
pub use crate::default::Default;
......@@ -45,6 +52,60 @@
#[doc(no_inline)]
pub use crate::result::Result::{self, Ok, Err};
// Re-exported built-in macros
#[cfg(not(bootstrap))]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[doc(no_inline)]
pub use core::prelude::v1::{
__rust_unstable_column,
asm,
assert,
cfg,
column,
compile_error,
concat,
concat_idents,
env,
file,
format_args,
format_args_nl,
global_asm,
include,
include_bytes,
include_str,
line,
log_syntax,
module_path,
option_env,
stringify,
trace_macros,
};
// FIXME: Attribute and derive macros are not documented because for them rustdoc generates
// dead links which fail link checker testing.
#[cfg(not(bootstrap))]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow(deprecated)]
#[doc(hidden)]
pub use core::prelude::v1::{
Clone,
Copy,
Debug,
Decodable,
Default,
Encodable,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
RustcDecodable,
RustcEncodable,
bench,
global_allocator,
test,
test_case,
};
// The file so far is equivalent to src/libcore/prelude/v1.rs,
// and below to src/liballoc/prelude.rs.
......
......@@ -592,6 +592,9 @@ pub struct SyntaxExtension {
pub helper_attrs: Vec<Symbol>,
/// Edition of the crate in which this macro is defined.
pub edition: Edition,
/// Built-in macros have a couple of special properties (meaning of `$crate`,
/// availability in `#[no_implicit_prelude]` modules), so we have to keep this flag.
pub is_builtin: bool,
}
impl SyntaxExtensionKind {
......@@ -636,6 +639,7 @@ pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
deprecation: None,
helper_attrs: Vec::new(),
edition,
is_builtin: false,
kind,
}
}
......@@ -687,7 +691,7 @@ pub trait Resolver {
fn resolve_dollar_crates(&mut self);
fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
derives: &[ExpnId]);
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
fn resolve_imports(&mut self);
......
......@@ -437,6 +437,7 @@ pub fn compile(
deprecation: attr::find_deprecation(&sess, &def.attrs, def.span),
helper_attrs: Vec::new(),
edition,
is_builtin: attr::contains_name(&def.attrs, sym::rustc_builtin_macro),
}
}
......
//! The compiler code necessary to implement the `#[derive]` extensions.
use rustc_data_structures::sync::Lrc;
use syntax::ast::{self, MetaItem};
use syntax::attr::Deprecation;
use syntax::edition::Edition;
use syntax::ext::base::{Annotatable, ExtCtxt, Resolver, MultiItemModifier};
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
use syntax::ext::base::{Annotatable, ExtCtxt, MultiItemModifier};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use syntax::symbol::{Symbol, sym};
......@@ -43,8 +39,8 @@
pub mod generic;
struct BuiltinDerive(
fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable))
crate struct BuiltinDerive(
crate fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable))
);
impl MultiItemModifier for BuiltinDerive {
......@@ -60,82 +56,6 @@ fn expand(&self,
}
}
macro_rules! derive_traits {
($( [$deprecation:expr] $name:ident => $func:path, )+) => {
pub fn is_builtin_trait(name: ast::Name) -> bool {
match name {
$( sym::$name )|+ => true,
_ => false,
}
}
pub fn register_builtin_derives(resolver: &mut dyn Resolver, edition: Edition) {
let allow_internal_unstable = Some([
sym::core_intrinsics,
sym::rustc_attrs,
Symbol::intern("derive_clone_copy"),
Symbol::intern("derive_eq"),
Symbol::intern("libstd_sys_internals"), // RustcDeserialize and RustcSerialize
][..].into());
$(
resolver.add_builtin(
ast::Ident::with_empty_ctxt(sym::$name),
Lrc::new(SyntaxExtension {
deprecation: $deprecation.map(|msg| Deprecation {
since: Some(Symbol::intern("1.0.0")),
note: Some(Symbol::intern(msg)),
}),
allow_internal_unstable: allow_internal_unstable.clone(),
..SyntaxExtension::default(
SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($func))),
edition,
)
}),
);
)+
}
}
}
derive_traits! {
[None]
Clone => clone::expand_deriving_clone,
[None]
Hash => hash::expand_deriving_hash,
[None]
RustcEncodable => encodable::expand_deriving_rustc_encodable,
[None]
RustcDecodable => decodable::expand_deriving_rustc_decodable,
[None]
PartialEq => partial_eq::expand_deriving_partial_eq,
[None]
Eq => eq::expand_deriving_eq,
[None]
PartialOrd => partial_ord::expand_deriving_partial_ord,
[None]
Ord => ord::expand_deriving_ord,
[None]
Debug => debug::expand_deriving_debug,
[None]
Default => default::expand_deriving_default,
[None]
Copy => bounds::expand_deriving_copy,
// deprecated
[Some("derive(Encodable) is deprecated in favor of derive(RustcEncodable)")]
Encodable => encodable::expand_deriving_encodable,
[Some("derive(Decodable) is deprecated in favor of derive(RustcDecodable)")]
Decodable => decodable::expand_deriving_decodable,
}
/// Construct a name for the inner type parameter that can't collide with any type parameters of
/// the item. This is achieved by starting with a base and then concatenating the names of all
/// other type parameters.
......
......@@ -5,19 +5,25 @@
#![deny(rust_2018_idioms)]
#![deny(unused_lifetimes)]
#![feature(in_band_lifetimes)]
#![feature(crate_visibility_modifier)]
#![feature(decl_macro)]
#![feature(nll)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_span)]
#![feature(decl_macro)]
#![feature(nll)]
#![feature(rustc_diagnostic_macros)]
#![feature(unicode_internals)]
#![recursion_limit="256"]
extern crate proc_macro;
use crate::deriving::*;
use syntax::ast::Ident;
use syntax::edition::Edition;
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, MacroExpanderFn};
use syntax::ext::source_util;
use syntax::symbol::sym;
mod error_codes;
mod asm;
......@@ -38,147 +44,71 @@
mod trace_macros;
pub mod deriving;
pub mod plugin_macro_defs;
pub mod proc_macro_decls;
pub mod proc_macro_impl;
use rustc_data_structures::sync::Lrc;
use syntax::ast;
use syntax::attr::Stability;
use syntax::ext::base::MacroExpanderFn;
use syntax::ext::base::{NamedSyntaxExtension, SyntaxExtension, SyntaxExtensionKind};
use syntax::edition::Edition;
use syntax::symbol::{sym, Symbol};
const EXPLAIN_ASM: &str =
"inline assembly is not stable enough for use and is subject to change";
const EXPLAIN_GLOBAL_ASM: &str =
"`global_asm!` is not stable enough for use and is subject to change";
const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &str =
"custom test frameworks are an unstable feature";
const EXPLAIN_LOG_SYNTAX: &str =
"`log_syntax!` is not stable enough for use and is subject to change";
const EXPLAIN_CONCAT_IDENTS: &str =
"`concat_idents` is not stable enough for use and is subject to change";
const EXPLAIN_FORMAT_ARGS_NL: &str =
"`format_args_nl` is only for internal language use and is subject to change";
const EXPLAIN_TRACE_MACROS: &str =
"`trace_macros` is not stable enough for use and is subject to change";
const EXPLAIN_UNSTABLE_COLUMN: &str =
"internal implementation detail of the `column` macro";
pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
user_exts: Vec<NamedSyntaxExtension>,
edition: Edition) {
deriving::register_builtin_derives(resolver, edition);
let mut register = |name, ext| {
resolver.add_builtin(ast::Ident::with_empty_ctxt(name), Lrc::new(ext));
};
macro_rules! register {
($( $name:ident: $f:expr, )*) => { $(
register(sym::$name, SyntaxExtension::default(
SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition
));
)* }
pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, edition: Edition) {
let mut register = |name, kind| resolver.register_builtin_macro(
Ident::with_empty_ctxt(name), SyntaxExtension {
is_builtin: true, ..SyntaxExtension::default(kind, edition)
},
);
macro register_bang($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)*
}
macro register_attr($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
}
macro_rules! register_unstable {
($( [$feature:expr, $reason:expr, $issue:expr] $name:ident: $f:expr, )*) => { $(
register(sym::$name, SyntaxExtension {
stability: Some(Stability::unstable(
$feature, Some(Symbol::intern($reason)), $issue
)),
..SyntaxExtension::default(
SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition
)
});
)* }
macro register_derive($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
}
use syntax::ext::source_util::*;
register! {
line: expand_line,
column: expand_column,
file: expand_file,
stringify: expand_stringify,
include: expand_include,
include_str: expand_include_str,
include_bytes: expand_include_bytes,
module_path: expand_mod,
register_bang! {
__rust_unstable_column: source_util::expand_column,
asm: asm::expand_asm,
assert: assert::expand_assert,
cfg: cfg::expand_cfg,
column: source_util::expand_column,
compile_error: compile_error::expand_compile_error,
concat_idents: concat_idents::expand_syntax_ext,
concat: concat::expand_syntax_ext,
env: env::expand_env,
option_env: env::expand_option_env,
compile_error: compile_error::expand_compile_error,
assert: assert::expand_assert,
}
register_unstable! {
[sym::__rust_unstable_column, EXPLAIN_UNSTABLE_COLUMN, 0]
__rust_unstable_column: expand_column,
[sym::asm, EXPLAIN_ASM, 29722]
asm: asm::expand_asm,
[sym::global_asm, EXPLAIN_GLOBAL_ASM, 35119]
file: source_util::expand_file,
format_args_nl: format::expand_format_args_nl,
format_args: format::expand_format_args,
global_asm: global_asm::expand_global_asm,
[sym::concat_idents, EXPLAIN_CONCAT_IDENTS, 29599]
concat_idents: concat_idents::expand_syntax_ext,
[sym::log_syntax, EXPLAIN_LOG_SYNTAX, 29598]
include_bytes: source_util::expand_include_bytes,
include_str: source_util::expand_include_str,
include: source_util::expand_include,
line: source_util::expand_line,
log_syntax: log_syntax::expand_syntax_ext,
[sym::trace_macros, EXPLAIN_TRACE_MACROS, 29598]
module_path: source_util::expand_mod,
option_env: env::expand_option_env,
stringify: source_util::expand_stringify,
trace_macros: trace_macros::expand_trace_macros,
}
let allow_internal_unstable = Some([sym::test, sym::rustc_attrs][..].into());
register(sym::test_case, SyntaxExtension {
stability: Some(Stability::unstable(
sym::custom_test_frameworks,
Some(Symbol::intern(EXPLAIN_CUSTOM_TEST_FRAMEWORKS)),
50297,
)),
allow_internal_unstable: allow_internal_unstable.clone(),
..SyntaxExtension::default(
SyntaxExtensionKind::LegacyAttr(Box::new(test_case::expand)), edition
)
});
register(sym::test, SyntaxExtension {
allow_internal_unstable: allow_internal_unstable.clone(),
..SyntaxExtension::default(
SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_test)), edition
)
});
register(sym::bench, SyntaxExtension {
allow_internal_unstable,
..SyntaxExtension::default(
SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_bench)), edition
)
});
register(sym::global_allocator, SyntaxExtension {
allow_internal_unstable: Some([sym::rustc_attrs][..].into()),
..SyntaxExtension::default(
SyntaxExtensionKind::LegacyAttr(Box::new(global_allocator::expand)), edition
)
});
let allow_internal_unstable = Some([sym::fmt_internals][..].into());
register(sym::format_args, SyntaxExtension {
allow_internal_unstable: allow_internal_unstable.clone(),
..SyntaxExtension::default(
SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args)), edition
)
});
register(sym::format_args_nl, SyntaxExtension {
stability: Some(Stability::unstable(
sym::format_args_nl,
Some(Symbol::intern(EXPLAIN_FORMAT_ARGS_NL)),
0,
)),
allow_internal_unstable,
..SyntaxExtension::default(
SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args_nl)), edition
)
});
register_attr! {
bench: test::expand_bench,
global_allocator: global_allocator::expand,
test: test::expand_test,
test_case: test_case::expand,
}
for (name, ext) in user_exts {
register(name, ext);
register_derive! {
Clone: clone::expand_deriving_clone,
Copy: bounds::expand_deriving_copy,
Debug: debug::expand_deriving_debug,
Decodable: decodable::expand_deriving_decodable,
Default: default::expand_deriving_default,
Encodable: encodable::expand_deriving_encodable,
Eq: eq::expand_deriving_eq,
Hash: hash::expand_deriving_hash,
Ord: ord::expand_deriving_ord,
PartialEq: partial_eq::expand_deriving_partial_eq,
PartialOrd: partial_ord::expand_deriving_partial_ord,
RustcDecodable: decodable::expand_deriving_rustc_decodable,
RustcEncodable: encodable::expand_deriving_rustc_encodable,
}
}
//! Each macro must have a definition, so `#[plugin]` attributes
//! inject a dummy `macro_rules` item for each macro they define.
use syntax::ast::*;
use syntax::attr;
use syntax::edition::Edition;
use syntax::ext::base::{Resolver, NamedSyntaxExtension};
use syntax::parse::token;
use syntax::ptr::P;
use syntax::source_map::respan;
use syntax::symbol::sym;
use syntax::tokenstream::*;
use syntax_pos::{Span, DUMMY_SP};
use syntax_pos::hygiene::{ExpnId, ExpnInfo, ExpnKind, MacroKind};
use std::mem;
fn plugin_macro_def(name: Name, span: Span) -> P<Item> {
let rustc_builtin_macro = Attribute {
id: attr::mk_attr_id(),
style: AttrStyle::Outer,
path: Path::from_ident(Ident::new(sym::rustc_builtin_macro, span)),
tokens: TokenStream::empty(),
is_sugared_doc: false,
span,
};
let parens: TreeAndJoint = TokenTree::Delimited(
DelimSpan::from_single(span), token::Paren, TokenStream::empty()
).into();
let trees = vec![parens.clone(), TokenTree::token(token::FatArrow, span).into(), parens];
P(Item {
ident: Ident::new(name, span),
attrs: vec![rustc_builtin_macro],
id: DUMMY_NODE_ID,
node: ItemKind::MacroDef(MacroDef { tokens: TokenStream::new(trees), legacy: true }),
vis: respan(span, VisibilityKind::Inherited),
span: span,
tokens: None,
})
}
pub fn inject(
krate: &mut Crate,
resolver: &mut dyn Resolver,
named_exts: Vec<NamedSyntaxExtension>,
edition: Edition,
) {
if !named_exts.is_empty() {
let mut extra_items = Vec::new();
let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition,
[sym::rustc_attrs][..].into(),
));
for (name, ext) in named_exts {
resolver.register_builtin_macro(Ident::with_empty_ctxt(name), ext);
extra_items.push(plugin_macro_def(name, span));
}
// The `macro_rules` items must be inserted before any other items.
mem::swap(&mut extra_items, &mut krate.module.items);
krate.module.items.append(&mut extra_items);
}
}
use std::mem;
use crate::deriving;
use syntax::ast::{self, Ident};
use syntax::attr;
use syntax::source_map::{ExpnInfo, ExpnKind, respan};
......@@ -136,10 +134,6 @@ fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribut
self.handler.span_err(trait_attr.span,
&format!("`{}` cannot be a name of derive macro", trait_ident));
}
if deriving::is_builtin_trait(trait_ident.name) {
self.handler.span_err(trait_attr.span,
"cannot override a built-in derive macro");
}
let attributes_attr = list.get(1);
let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
......
......@@ -5,7 +5,7 @@
#![feature(no_core, optin_builtin_traits)]
#![no_core]
#![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items)]
#![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items, rustc_attrs)]
#[repr(C)]
......@@ -74,3 +74,7 @@ pub mod marker {
#[lang = "freeze"]
auto trait Freeze {}
#[macro_export]
#[rustc_builtin_macro]
macro_rules! Copy { () => () }
// @has intra_link_builtin_macros/index.html
// @has - '//a/@href' 'https://doc.rust-lang.org/nightly/core/macro.cfg.html'
//! [cfg]
......@@ -3,20 +3,21 @@
#![feature(plugin_registrar)]
#![feature(rustc_private)]
extern crate syntax;
extern crate rustc;
extern crate rustc_plugin;
extern crate rustc_driver;
extern crate rustc_plugin;
extern crate syntax;
use syntax::symbol::Symbol;
use syntax::feature_gate::AttributeType;
use rustc_plugin::Registry;
use syntax::ext::base::SyntaxExtension;
use syntax::feature_gate::AttributeType;
use syntax::symbol::Symbol;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_attribute(Symbol::intern("foo"), AttributeType::Normal);
reg.register_attribute(Symbol::intern("bar"), AttributeType::CrateLevel);
reg.register_attribute(Symbol::intern("baz"), AttributeType::Whitelisted);
reg.register_syntax_extension(
Symbol::intern("mac"), SyntaxExtension::dummy_bang(reg.sess.edition())
);
}
......@@ -2,7 +2,7 @@ warning: use of deprecated item 'Encodable': derive(Encodable) is deprecated in
--> $DIR/deprecated-derive.rs:8:10
|
LL | #[derive(Encodable)]
| ^^^^^^^^^
| ^^^^^^^^^ help: replace the use of the deprecated item: `RustcEncodable`
|
= note: `#[warn(deprecated)]` on by default
// edition:2018
// aux-build:attr-plugin-test.rs
// ignore-stage1
#![feature(plugin)]
#![plugin(attr_plugin_test)]
pub use mac as reexport; //~ ERROR `mac` is private, and cannot be re-exported
fn main() {}
error[E0364]: `mac` is private, and cannot be re-exported
--> $DIR/plugin-reexport.rs:8:9
|
LL | pub use mac as reexport;
| ^^^^^^^^^^^^^^^
|
note: consider marking `mac` as `pub` in the imported module
--> $DIR/plugin-reexport.rs:8:9
|
LL | pub use mac as reexport;
| ^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0364`.
// error-pattern: `main` function not found
// At time of authorship, a crate-level #![bench] with no `--test`
// will cause compilation to error unconditionally with "main function
// not found" (despite having one), similar to #[bench].
//
// (The non-crate level cases are in
// issue-43106-gating-of-builtin-attrs.rs.)
// The non-crate level cases are in issue-43106-gating-of-builtin-attrs.rs.
// See issue-12997-1.rs and issue-12997-2.rs to see how `#[bench]` is
// handled in "weird places" when `--test` is passed.
#![feature(custom_inner_attributes)]
#![bench = "4100"]
//~^ ERROR cannot determine resolution for the attribute macro `bench`
fn main() { }
fn main() {}
warning: attribute must be of the form `#[bench]`
--> $DIR/issue-43106-gating-of-bench.rs:15:1
error: cannot determine resolution for the attribute macro `bench`
--> $DIR/issue-43106-gating-of-bench.rs:7:4
|
LL | #![bench = "4100"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^
|
= note: `#[warn(ill_formed_attribute_input)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
error[E0601]: `main` function not found in crate `issue_43106_gating_of_bench`
|
= note: consider adding a `main` function to `$DIR/issue-43106-gating-of-bench.rs`
= note: import resolution is stuck, try simplifying macro imports
error: aborting due to previous error
For more information about this error, try `rustc --explain E0601`.
// error-pattern: `main` function not found
// At time of authorship, crate-level #[test] attribute with no
// `--test` signals unconditional error complaining of missing main
// function (despite having one), similar to #[bench].
//
// (The non-crate level cases are in
// issue-43106-gating-of-builtin-attrs.rs.)
// The non-crate level cases are in issue-43106-gating-of-builtin-attrs.rs.
#![test = "4200"]
//~^ ERROR cannot determine resolution for the attribute macro `test`
fn main() { }
fn main() {}
warning: attribute must be of the form `#[test]`
--> $DIR/issue-43106-gating-of-test.rs:10:1
error: cannot determine resolution for the attribute macro `test`
--> $DIR/issue-43106-gating-of-test.rs:3:4
|
LL | #![test = "4200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^
|
= note: `#[warn(ill_formed_attribute_input)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
error[E0601]: `main` function not found in crate `issue_43106_gating_of_test`
|
= note: consider adding a `main` function to `$DIR/issue-43106-gating-of-test.rs`
= note: import resolution is stuck, try simplifying macro imports
error: aborting due to previous error
For more information about this error, try `rustc --explain E0601`.
#![feature(intrinsics, lang_items, no_core)]
#![feature(intrinsics, lang_items, no_core, rustc_attrs)]
#![crate_type="rlib"]
#![no_core]
......@@ -88,3 +88,7 @@ fn main() {
cfg!(target_has_atomic = "ptr");
//~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change
}
#[macro_export]
#[rustc_builtin_macro]
macro_rules! cfg { () => () }
......@@ -4,7 +4,7 @@ error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope
LL | let x = env!("PATH");
| ^^^ ambiguous name
|
= note: `env` could refer to a built-in macro
= note: `env` could refer to a macro from prelude
note: `env` could also refer to the macro imported here
--> $DIR/glob-shadowing.rs:9:9
|
......@@ -19,7 +19,7 @@ error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope
LL | let x = env!("PATH");
| ^^^ ambiguous name
|
= note: `env` could refer to a built-in macro
= note: `env` could refer to a macro from prelude
note: `env` could also refer to the macro imported here
--> $DIR/glob-shadowing.rs:17:13
|
......
......@@ -27,7 +27,7 @@ error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded
LL | include!();
| ^^^^^^^ ambiguous name
|
= note: `include` could refer to a built-in macro
= note: `include` could refer to a macro from prelude
note: `include` could also refer to the macro defined here
--> $DIR/local-modularized-tricky-fail-1.rs:17:5
|
......
// compile-flags: --test
#![test] //~ ERROR only functions may be used as tests
#![test] //~ ERROR cannot determine resolution for the attribute macro `test`
error: only functions may be used as tests
--> $DIR/issue-28134.rs:3:1
error: cannot determine resolution for the attribute macro `test`
--> $DIR/issue-28134.rs:3:4
|
LL | #![test]
| ^^^^^^^^
| ^^^^
|
= note: import resolution is stuck, try simplifying macro imports
error: aborting due to previous error
// error-pattern: cannot find a built-in macro with name `line`
#![feature(rustc_attrs)]
#[rustc_builtin_macro]
macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown`
#[rustc_builtin_macro]
macro_rules! line { () => () }
fn main() {
line!();
std::prelude::v1::line!();
}
error: cannot find a built-in macro with name `unknown`
--> $DIR/unknown-builtin.rs:6:1
|
LL | macro_rules! unknown { () => () }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: cannot find a built-in macro with name `line`
--> <::core::macros::builtin::line macros>:1:1
|
LL | () => { }
| ^^^^^^^^^
error: aborting due to 2 previous errors
......@@ -40,8 +40,7 @@ pub fn foo8(input: TokenStream) -> TokenStream { input }
//~^ ERROR: `self` cannot be a name of derive macro
pub fn foo9(input: TokenStream) -> TokenStream { input }
#[proc_macro_derive(PartialEq)]
//~^ ERROR: cannot override a built-in derive macro
#[proc_macro_derive(PartialEq)] // OK
pub fn foo10(input: TokenStream) -> TokenStream { input }
#[proc_macro_derive(d11, a)]
......
......@@ -40,56 +40,50 @@ error: `self` cannot be a name of derive macro
LL | #[proc_macro_derive(self)]
| ^^^^
error: cannot override a built-in derive macro
--> $DIR/attribute.rs:43:21
|
LL | #[proc_macro_derive(PartialEq)]
| ^^^^^^^^^
error: second argument must be `attributes`
--> $DIR/attribute.rs:47:26
--> $DIR/attribute.rs:46:26
|
LL | #[proc_macro_derive(d11, a)]
| ^
error: attribute must be of form: `attributes(foo, bar)`
--> $DIR/attribute.rs:47:26
--> $DIR/attribute.rs:46:26
|
LL | #[proc_macro_derive(d11, a)]
| ^
error: attribute must be of form: `attributes(foo, bar)`
--> $DIR/attribute.rs:52:26
--> $DIR/attribute.rs:51:26
|
LL | #[proc_macro_derive(d12, attributes)]
| ^^^^^^^^^^
error: not a meta item
--> $DIR/attribute.rs:56:37
--> $DIR/attribute.rs:55:37
|
LL | #[proc_macro_derive(d13, attributes("a"))]
| ^^^
error: must only be one word
--> $DIR/attribute.rs:60:37
--> $DIR/attribute.rs:59:37
|
LL | #[proc_macro_derive(d14, attributes(a = ""))]
| ^^^^^^
error: must only be one word
--> $DIR/attribute.rs:64:37
--> $DIR/attribute.rs:63:37
|
LL | #[proc_macro_derive(d15, attributes(m::a))]
| ^^^^
error: must only be one word
--> $DIR/attribute.rs:68:37
--> $DIR/attribute.rs:67:37
|
LL | #[proc_macro_derive(d16, attributes(a(b)))]
| ^^^^
error: `self` cannot be a name of derive helper attribute
--> $DIR/attribute.rs:72:37
--> $DIR/attribute.rs:71:37
|
LL | #[proc_macro_derive(d17, attributes(self))]
| ^^^^
......@@ -106,5 +100,5 @@ error: malformed `proc_macro_derive` attribute input
LL | #[proc_macro_derive = ""]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
error: aborting due to 18 previous errors
error: aborting due to 17 previous errors
......@@ -3,7 +3,7 @@
// Tests that arbitrary crates (other than `core`, `std` and `meta`)
// aren't allowed without `--extern`, even if they're in the sysroot.
use alloc; //~ ERROR unresolved import `alloc`
use test; //~ ERROR cannot import a built-in macro
use test; // OK, imports the built-in attribute macro `#[test]`, but not the `test` crate.
use proc_macro; // OK, imports the built-in `proc_macro` attribute, but not the `proc_macro` crate.
fn main() {}
error: cannot import a built-in macro
--> $DIR/not-whitelisted.rs:6:5
|
LL | use test;
| ^^^^
error[E0432]: unresolved import `alloc`
--> $DIR/not-whitelisted.rs:5:5
|
LL | use alloc;
| ^^^^^ no `alloc` external crate
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
// edition:2018
// Built-in macro
use env as env_imported; //~ ERROR cannot import a built-in macro
// Tool attribute
use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt`
fn main() {
env_imported!("PATH");
}
fn main() {}
error: cannot import a built-in macro
--> $DIR/prelude-fail.rs:4:5
|
LL | use env as env_imported;
| ^^^^^^^^^^^^^^^^^^^
error[E0432]: unresolved import `rustfmt`
--> $DIR/prelude-fail.rs:7:5
--> $DIR/prelude-fail.rs:4:5
|
LL | use rustfmt::skip as imported_rustfmt_skip;
| ^^^^^^^ `rustfmt` is a tool module, not a module
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
......@@ -10,9 +10,13 @@
// Built-in type
use u8 as imported_u8;
// Built-in macro
use env as env_imported;
type A = imported_u8;
fn main() {
imported_vec![0];
ImportedVec::<u8>::new();
env_imported!("PATH");
}
error[E0658]: use of unstable library feature '__rust_unstable_column': internal implementation detail of the `column` macro
error[E0658]: use of unstable library feature '__rust_unstable_column': internal implementation detail of the `panic` macro
--> $DIR/rust-unstable-column-gated.rs:2:20
|
LL | println!("{}", __rust_unstable_column!());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册