Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define built-in macros through libcore #62086

Merged
merged 1 commit into from
Jul 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/libcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,13 +657,13 @@ macro_rules! uninit_array {
);
}

/// 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.
///
Expand Down Expand Up @@ -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 */ }
Expand Down
47 changes: 47 additions & 0 deletions src/libcore/prelude/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,50 @@ pub use crate::option::Option::{self, Some, None};
#[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,
};
2 changes: 1 addition & 1 deletion src/libcore/task/wake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ impl fmt::Debug for Context<'_> {
/// 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)]
Expand Down
6 changes: 0 additions & 6 deletions src/librustc/hir/def_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ newtype_index! {

#[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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Zoxc @michaelwoerister I really wish we could remove this, btw.

Expand All @@ -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"),
}
}
Expand Down Expand Up @@ -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"),
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4009,8 +4009,7 @@ impl<'a> LoweringContext<'a> {
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 {
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down
25 changes: 12 additions & 13 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{resolve_error, resolve_struct_error, ResolutionError, Determinacy};

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;
Expand All @@ -31,7 +31,6 @@ use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, Nod
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;
Expand Down Expand Up @@ -748,21 +747,24 @@ impl<'a> Resolver<'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();
self.get_module(module_def_id)
}
}

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());
}
Expand All @@ -772,10 +774,7 @@ impl<'a> Resolver<'a> {
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)
}
Expand Down
37 changes: 12 additions & 25 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
}

Expand All @@ -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
);
Expand Down Expand Up @@ -566,7 +563,7 @@ impl<'a> Resolver<'a> {
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);
Expand Down Expand Up @@ -611,16 +608,6 @@ impl<'a> Resolver<'a> {
}
}));
}
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) {
Expand Down Expand Up @@ -656,7 +643,11 @@ impl<'a> Resolver<'a> {
}
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 => {
Expand Down Expand Up @@ -733,11 +724,7 @@ impl<'a> Resolver<'a> {
);

if filter_fn(crate_mod) {
Some(TypoSuggestion {
candidate: ident.name,
article: "a",
kind: "crate",
})
Some(TypoSuggestion::from_res(ident.name, crate_mod))
} else {
None
}
Expand Down
24 changes: 13 additions & 11 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ enum Scope<'a> {
CrateRoot,
Module(Module<'a>),
MacroUsePrelude,
BuiltinMacros,
BuiltinAttrs,
LegacyPluginHelpers,
ExternPrelude,
Expand Down Expand Up @@ -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>>,
Expand Down Expand Up @@ -2021,7 +2020,7 @@ impl<'a> Resolver<'a> {

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(),
Expand Down Expand Up @@ -2068,6 +2067,11 @@ impl<'a> Resolver<'a> {
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()) {
Expand Down Expand Up @@ -2146,7 +2150,7 @@ impl<'a> Resolver<'a> {
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
Expand Down Expand Up @@ -2185,8 +2189,8 @@ impl<'a> Resolver<'a> {
// 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
Expand Down Expand Up @@ -2214,17 +2218,16 @@ impl<'a> Resolver<'a> {
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;
}
}
Expand Down Expand Up @@ -2263,7 +2266,6 @@ impl<'a> Resolver<'a> {
}
}
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,
Expand All @@ -2272,7 +2274,7 @@ impl<'a> Resolver<'a> {
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
};
Expand Down
Loading