Skip to content

Commit

Permalink
Rollup merge of #62243 - petrochenkov:macrodoc, r=eddyb
Browse files Browse the repository at this point in the history
Improve documentation for built-in macros

This is the `libcore` part of #62086.
Right now the only effect is improved documentation.

The changes in the last few commits are required to make the `libcore` change compile successfully.
  • Loading branch information
Centril committed Jul 6, 2019
2 parents 296e825 + 3274507 commit 154726c
Show file tree
Hide file tree
Showing 22 changed files with 811 additions and 176 deletions.
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#![feature(const_fn)]
#![feature(const_fn_union)]
#![feature(custom_inner_attributes)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
#![feature(extern_types)]
Expand Down
719 changes: 628 additions & 91 deletions src/libcore/macros.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4010,7 +4010,7 @@ impl<'a> LoweringContext<'a> {
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_doc_only_macro) {
attr::contains_name(&i.attrs, sym::rustc_builtin_macro) {
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
3 changes: 2 additions & 1 deletion src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use rustc_data_structures::fx::FxHashSet;
use syntax::ast::Ident;
use syntax::attr;
use syntax::symbol::{kw, sym};
use syntax_pos::hygiene::Transparency;
use syntax_pos::Span;

use std::{cmp, fmt, mem};
Expand Down Expand Up @@ -743,7 +744,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
}

fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
if md.legacy {
if attr::find_transparency(&md.attrs, md.legacy).0 != Transparency::Opaque {
self.update(md.hir_id, Some(AccessLevel::Public));
return
}
Expand Down
16 changes: 11 additions & 5 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,27 +770,33 @@ impl<'a> Resolver<'a> {
}

pub fn get_macro(&mut self, res: Res) -> Lrc<SyntaxExtension> {
self.opt_get_macro(res).expect("expected `DefKind::Macro` or `Res::NonMacroAttr`")
}

crate fn opt_get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
let def_id = match res {
Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) =>
return Some(self.non_macro_attr(true)), // some dummy extension
Res::Def(DefKind::Macro(..), def_id) => def_id,
Res::NonMacroAttr(attr_kind) =>
return self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool),
_ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
return Some(self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool)),
_ => return None,
};
if let Some(ext) = self.macro_map.get(&def_id) {
return ext.clone();
return Some(ext.clone());
}

let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) {
LoadedMacro::MacroDef(macro_def) => macro_def,
LoadedMacro::ProcMacro(ext) => return ext,
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)));
self.macro_map.insert(def_id, ext.clone());
ext
Some(ext)
}

/// Ensures that the reduced graph rooted at the given external module
Expand Down
21 changes: 16 additions & 5 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,19 @@ impl<'a> Resolver<'a> {
});
}

crate fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
// Reserve some names that are not quite covered by the general check
// performed on `Resolver::builtin_attrs`.
if ident.name == sym::cfg || ident.name == sym::cfg_attr || ident.name == sym::derive {
let macro_kind = self.opt_get_macro(res).map(|ext| ext.macro_kind());
if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) {
self.session.span_err(
ident.span, &format!("name `{}` is reserved in attribute namespace", ident)
);
}
}
}

pub fn define_macro(&mut self,
item: &ast::Item,
expansion: Mark,
Expand All @@ -1117,13 +1130,14 @@ impl<'a> Resolver<'a> {
let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess,
&self.session.features_untracked(),
item, self.session.edition()));
let macro_kind = ext.macro_kind();
let res = Res::Def(DefKind::Macro(macro_kind), def_id);
self.macro_map.insert(def_id, ext);

let def = match item.node { ast::ItemKind::MacroDef(ref def) => def, _ => unreachable!() };
if def.legacy {
let ident = ident.modern();
self.macro_names.insert(ident);
let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export);
let vis = if is_macro_export {
ty::Visibility::Public
Expand All @@ -1142,14 +1156,11 @@ impl<'a> Resolver<'a> {
self.define(module, ident, MacroNS,
(res, vis, item.span, expansion, IsMacroExport));
} else {
if !attr::contains_name(&item.attrs, sym::rustc_doc_only_macro) {
self.check_reserved_macro_name(ident, MacroNS);
}
self.check_reserved_macro_name(ident, res);
self.unused_macros.insert(def_id);
}
} else {
let module = self.current_module;
let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
let vis = self.resolve_visibility(&item.vis);
if vis != ty::Visibility::Public {
self.unused_macros.insert(def_id);
Expand Down
20 changes: 5 additions & 15 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use rustc::{bug, span_bug};
use syntax::ast::{self, Ident, Name, NodeId, CRATE_NODE_ID};
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
use syntax::ext::hygiene::Mark;
use syntax::symbol::{kw, sym};
use syntax::symbol::kw;
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::{struct_span_err, unwrap_or};
use syntax_pos::{MultiSpan, Span};
Expand Down Expand Up @@ -492,35 +492,25 @@ impl<'a> Resolver<'a> {
})
}

crate fn check_reserved_macro_name(&self, ident: Ident, ns: Namespace) {
// Reserve some names that are not quite covered by the general check
// performed on `Resolver::builtin_attrs`.
if ns == MacroNS &&
(ident.name == sym::cfg || ident.name == sym::cfg_attr ||
ident.name == sym::derive) {
self.session.span_err(ident.span,
&format!("name `{}` is reserved in macro namespace", ident));
}
}

// Define the name or return the existing binding if there is a collision.
pub fn try_define(&mut self,
module: Module<'a>,
ident: Ident,
ns: Namespace,
binding: &'a NameBinding<'a>)
-> Result<(), &'a NameBinding<'a>> {
self.check_reserved_macro_name(ident, ns);
let res = binding.res();
self.check_reserved_macro_name(ident, res);
self.set_binding_parent_module(binding, module);
self.update_resolution(module, ident, ns, |this, resolution| {
if let Some(old_binding) = resolution.binding {
if binding.res() == Res::Err {
if res == Res::Err {
// Do not override real bindings with `Res::Err`s from error recovery.
return Ok(());
}
match (old_binding.is_glob_import(), binding.is_glob_import()) {
(true, true) => {
if binding.res() != old_binding.res() {
if res != old_binding.res() {
resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsGlob,
old_binding, binding));
} else if !old_binding.vis.is_at_least(binding.vis, &*this) {
Expand Down
32 changes: 16 additions & 16 deletions src/libstd/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ mod builtin {
///
/// [`panic!`]: ../std/macro.panic.html
#[stable(feature = "compile_error_macro", since = "1.20.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! compile_error {
($msg:expr) => ({ /* compiler built-in */ });
($msg:expr,) => ({ /* compiler built-in */ });
Expand Down Expand Up @@ -462,7 +462,7 @@ mod builtin {
/// assert_eq!(s, format!("hello {}", "world"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! format_args {
($fmt:expr) => ({ /* compiler built-in */ });
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
Expand Down Expand Up @@ -500,7 +500,7 @@ mod builtin {
/// error: what's that?!
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! env {
($name:expr) => ({ /* compiler built-in */ });
($name:expr,) => ({ /* compiler built-in */ });
Expand All @@ -526,7 +526,7 @@ mod builtin {
/// println!("the secret key might be: {:?}", key);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! option_env {
($name:expr) => ({ /* compiler built-in */ });
($name:expr,) => ({ /* compiler built-in */ });
Expand Down Expand Up @@ -557,7 +557,7 @@ mod builtin {
/// # }
/// ```
#[unstable(feature = "concat_idents_macro", issue = "29599")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! concat_idents {
($($e:ident),+) => ({ /* compiler built-in */ });
($($e:ident,)+) => ({ /* compiler built-in */ });
Expand All @@ -579,7 +579,7 @@ mod builtin {
/// assert_eq!(s, "test10btrue");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! concat {
($($e:expr),*) => ({ /* compiler built-in */ });
($($e:expr,)*) => ({ /* compiler built-in */ });
Expand Down Expand Up @@ -607,7 +607,7 @@ mod builtin {
/// println!("defined on line: {}", current_line);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! line { () => ({ /* compiler built-in */ }) }

/// Expands to the column number at which it was invoked.
Expand All @@ -632,7 +632,7 @@ mod builtin {
/// println!("defined on column: {}", current_col);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! column { () => ({ /* compiler built-in */ }) }

/// Expands to the file name in which it was invoked.
Expand All @@ -656,7 +656,7 @@ mod builtin {
/// println!("defined in file: {}", this_file);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! file { () => ({ /* compiler built-in */ }) }

/// Stringifies its arguments.
Expand All @@ -675,7 +675,7 @@ mod builtin {
/// assert_eq!(one_plus_one, "1 + 1");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) }

/// Includes a utf8-encoded file as a string.
Expand Down Expand Up @@ -709,7 +709,7 @@ mod builtin {
///
/// Compiling 'main.rs' and running the resulting binary will print "adiós".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! include_str {
($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ });
Expand Down Expand Up @@ -746,7 +746,7 @@ mod builtin {
///
/// Compiling 'main.rs' and running the resulting binary will print "adiós".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! include_bytes {
($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ });
Expand All @@ -770,7 +770,7 @@ mod builtin {
/// test::foo();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! module_path { () => ({ /* compiler built-in */ }) }

/// Evaluates boolean combinations of configuration flags at compile-time.
Expand All @@ -794,7 +794,7 @@ mod builtin {
/// };
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }

/// Parses a file as an expression or an item according to the context.
Expand Down Expand Up @@ -837,7 +837,7 @@ mod builtin {
/// Compiling 'main.rs' and running the resulting binary will print
/// "🙈🙊🙉🙈🙊🙉".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! include {
($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ });
Expand Down Expand Up @@ -889,7 +889,7 @@ mod builtin {
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_doc_only_macro]
#[rustc_builtin_macro]
macro_rules! assert {
($cond:expr) => ({ /* compiler built-in */ });
($cond:expr,) => ({ /* compiler built-in */ });
Expand Down
33 changes: 33 additions & 0 deletions src/libsyntax/attr/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::feature_gate::{Features, GatedCfg};
use crate::parse::ParseSess;

use errors::{Applicability, Handler};
use syntax_pos::hygiene::Transparency;
use syntax_pos::{symbol::Symbol, symbol::sym, Span};

use super::{mark_used, MetaItemKind};
Expand Down Expand Up @@ -854,3 +855,35 @@ fn int_type_of_word(s: Symbol) -> Option<IntType> {
_ => None
}
}

pub enum TransparencyError {
UnknownTransparency(Symbol, Span),
MultipleTransparencyAttrs(Span, Span),
}

pub fn find_transparency(
attrs: &[Attribute], is_legacy: bool
) -> (Transparency, Option<TransparencyError>) {
let mut transparency = None;
let mut error = None;
for attr in attrs {
if attr.check_name(sym::rustc_macro_transparency) {
if let Some((_, old_span)) = transparency {
error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span));
break;
} else if let Some(value) = attr.value_str() {
transparency = Some((match &*value.as_str() {
"transparent" => Transparency::Transparent,
"semitransparent" => Transparency::SemiTransparent,
"opaque" => Transparency::Opaque,
_ => {
error = Some(TransparencyError::UnknownTransparency(value, attr.span));
continue;
}
}, attr.span));
}
}
}
let fallback = if is_legacy { Transparency::SemiTransparent } else { Transparency::Opaque };
(transparency.map_or(fallback, |t| t.0), error)
}
6 changes: 1 addition & 5 deletions src/libsyntax/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

mod builtin;

pub use builtin::{
cfg_matches, contains_feature_attr, eval_condition, find_crate_name, find_deprecation,
find_repr_attrs, find_stability, find_unwind_attr, Deprecation, InlineAttr, OptimizeAttr,
IntType, ReprAttr, RustcDeprecation, Stability, StabilityLevel, UnwindAttr,
};
pub use builtin::*;
pub use IntType::*;
pub use ReprAttr::*;
pub use StabilityLevel::*;
Expand Down
Loading

0 comments on commit 154726c

Please sign in to comment.