Rollup merge of #62243 - petrochenkov:macrodoc, r=eddyb
Improve documentation for built-in macros This is the `libcore` part of https://github.com/rust-lang/rust/pull/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.
This commit is contained in:
commit
154726cf7d
@ -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)]
|
||||
|
@ -642,183 +642,720 @@ macro_rules! uninitialized_array {
|
||||
/// 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.
|
||||
///
|
||||
/// For more information, see documentation for `std`'s macros.
|
||||
#[cfg(rustdoc)]
|
||||
mod builtin {
|
||||
|
||||
/// Causes compilation to fail with the given error message when encountered.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::compile_error!`].
|
||||
/// 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.
|
||||
///
|
||||
/// [`std::compile_error!`]: ../std/macro.compile_error.html
|
||||
/// # 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_doc_only_macro]
|
||||
macro_rules! compile_error {
|
||||
($msg:expr) => ({ /* compiler built-in */ });
|
||||
($msg:expr,) => ({ /* compiler built-in */ });
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro compile_error {
|
||||
($msg:expr) => ({ /* compiler built-in */ }),
|
||||
($msg:expr,) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Constructs parameters for the other string-formatting macros.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::format_args!`].
|
||||
/// 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.
|
||||
///
|
||||
/// [`std::format_args!`]: ../std/macro.format_args.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! format_args {
|
||||
($fmt:expr) => ({ /* compiler built-in */ });
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
|
||||
#[allow_internal_unstable(fmt_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro format_args {
|
||||
($fmt:expr) => ({ /* compiler built-in */ }),
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Same as `format_args`, but adds a newline in the end.
|
||||
#[unstable(feature = "format_args_nl", issue = "0",
|
||||
reason = "`format_args_nl` is only for internal \
|
||||
language use and is subject to change")]
|
||||
#[allow_internal_unstable(fmt_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro format_args_nl {
|
||||
($fmt:expr) => ({ /* compiler built-in */ }),
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Inspects an environment variable at compile time.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::env!`].
|
||||
/// This macro will expand to the value of the named environment variable at
|
||||
/// compile time, yielding an expression of type `&'static str`.
|
||||
///
|
||||
/// [`std::env!`]: ../std/macro.env.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! env {
|
||||
($name:expr) => ({ /* compiler built-in */ });
|
||||
($name:expr,) => ({ /* compiler built-in */ });
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro env {
|
||||
($name:expr) => ({ /* compiler built-in */ }),
|
||||
($name:expr,) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Optionally inspects an environment variable at compile time.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::option_env!`].
|
||||
/// 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.
|
||||
///
|
||||
/// [`std::option_env!`]: ../std/macro.option_env.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! option_env {
|
||||
($name:expr) => ({ /* compiler built-in */ });
|
||||
($name:expr,) => ({ /* compiler built-in */ });
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro option_env {
|
||||
($name:expr) => ({ /* compiler built-in */ }),
|
||||
($name:expr,) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Concatenates identifiers into one identifier.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::concat_idents!`].
|
||||
/// 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.
|
||||
///
|
||||
/// [`std::concat_idents!`]: ../std/macro.concat_idents.html
|
||||
#[unstable(feature = "concat_idents_macro", issue = "29599")]
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! concat_idents {
|
||||
($($e:ident),+) => ({ /* compiler built-in */ });
|
||||
($($e:ident,)+) => ({ /* compiler built-in */ });
|
||||
/// # 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", issue = "29599",
|
||||
reason = "`concat_idents` is not stable enough for use and is subject to change")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro concat_idents {
|
||||
($($e:ident),+) => ({ /* compiler built-in */ }),
|
||||
($($e:ident,)+) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Concatenates literals into a static string slice.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::concat!`].
|
||||
/// 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.
|
||||
///
|
||||
/// [`std::concat!`]: ../std/macro.concat.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! concat {
|
||||
($($e:expr),*) => ({ /* compiler built-in */ });
|
||||
($($e:expr,)*) => ({ /* compiler built-in */ });
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro concat {
|
||||
($($e:expr),*) => ({ /* compiler built-in */ }),
|
||||
($($e:expr,)*) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Expands to the line number on which it was invoked.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::line!`].
|
||||
/// With [`column!`] and [`file!`], these macros provide debugging information for
|
||||
/// developers about the location within the source.
|
||||
///
|
||||
/// [`std::line!`]: ../std/macro.line.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! line { () => ({ /* compiler built-in */ }) }
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro line() { /* compiler built-in */ }
|
||||
|
||||
/// Expands to the column number on which it was invoked.
|
||||
/// Expands to the column number at which it was invoked.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::column!`].
|
||||
/// With [`line!`] and [`file!`], these macros provide debugging information for
|
||||
/// developers about the location within the source.
|
||||
///
|
||||
/// [`std::column!`]: ../std/macro.column.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! column { () => ({ /* compiler built-in */ }) }
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro column() { /* compiler built-in */ }
|
||||
|
||||
/// Expands to the file name from which it was invoked.
|
||||
/// Same as `column`, but less likely to be shadowed.
|
||||
#[unstable(feature = "__rust_unstable_column", issue = "0",
|
||||
reason = "internal implementation detail of the `column` macro")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro __rust_unstable_column() { /* compiler built-in */ }
|
||||
|
||||
/// Expands to the file name in which it was invoked.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::file!`].
|
||||
/// With [`line!`] and [`column!`], these macros provide debugging information for
|
||||
/// developers about the location within the source.
|
||||
///
|
||||
/// [`std::file!`]: ../std/macro.file.html
|
||||
///
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! file { () => ({ /* compiler built-in */ }) }
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro file() { /* compiler built-in */ }
|
||||
|
||||
/// Stringifies its arguments.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::stringify!`].
|
||||
/// 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.
|
||||
///
|
||||
/// [`std::stringify!`]: ../std/macro.stringify.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) }
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro stringify($($t:tt)*) { /* compiler built-in */ }
|
||||
|
||||
/// Includes a utf8-encoded file as a string.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::include_str!`].
|
||||
/// The file is located relative to the current file. (similarly to how
|
||||
/// modules are found)
|
||||
///
|
||||
/// [`std::include_str!`]: ../std/macro.include_str.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! include_str {
|
||||
($file:expr) => ({ /* compiler built-in */ });
|
||||
($file:expr,) => ({ /* compiler built-in */ });
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro include_str {
|
||||
($file:expr) => ({ /* compiler built-in */ }),
|
||||
($file:expr,) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Includes a file as a reference to a byte array.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::include_bytes!`].
|
||||
/// The file is located relative to the current file. (similarly to how
|
||||
/// modules are found)
|
||||
///
|
||||
/// [`std::include_bytes!`]: ../std/macro.include_bytes.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! include_bytes {
|
||||
($file:expr) => ({ /* compiler built-in */ });
|
||||
($file:expr,) => ({ /* compiler built-in */ });
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro include_bytes {
|
||||
($file:expr) => ({ /* compiler built-in */ }),
|
||||
($file:expr,) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Expands to a string that represents the current module path.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::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.
|
||||
///
|
||||
/// [`std::module_path!`]: ../std/macro.module_path.html
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// mod test {
|
||||
/// pub fn foo() {
|
||||
/// assert!(module_path!().ends_with("test"));
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// test::foo();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! module_path { () => ({ /* compiler built-in */ }) }
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro module_path() { /* compiler built-in */ }
|
||||
|
||||
/// Evaluates boolean combinations of configuration flags, at compile-time.
|
||||
/// Evaluates boolean combinations of configuration flags at compile-time.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::cfg!`].
|
||||
/// 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.
|
||||
///
|
||||
/// [`std::cfg!`]: ../std/macro.cfg.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro cfg($($cfg:tt)*) { /* compiler built-in */ }
|
||||
|
||||
/// Parses a file as an expression or an item according to the context.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::include!`].
|
||||
/// The file is located relative to the current file (similarly to how
|
||||
/// modules are found).
|
||||
///
|
||||
/// [`std::include!`]: ../std/macro.include.html
|
||||
/// 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_doc_only_macro]
|
||||
macro_rules! include {
|
||||
($file:expr) => ({ /* compiler built-in */ });
|
||||
($file:expr,) => ({ /* compiler built-in */ });
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro include {
|
||||
($file:expr) => ({ /* compiler built-in */ }),
|
||||
($file:expr,) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Asserts that a boolean expression is `true` at runtime.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::assert!`].
|
||||
/// This will invoke the [`panic!`] macro if the provided expression cannot be
|
||||
/// evaluated to `true` at runtime.
|
||||
///
|
||||
/// [`std::assert!`]: ../std/macro.assert.html
|
||||
#[rustc_doc_only_macro]
|
||||
/// # 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")]
|
||||
macro_rules! assert {
|
||||
($cond:expr) => ({ /* compiler built-in */ });
|
||||
($cond:expr,) => ({ /* compiler built-in */ });
|
||||
($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ });
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro assert {
|
||||
($cond:expr) => ({ /* compiler built-in */ }),
|
||||
($cond:expr,) => ({ /* compiler built-in */ }),
|
||||
($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Inline assembly.
|
||||
#[unstable(feature = "asm", issue = "29722",
|
||||
reason = "inline assembly is not stable enough for use and is subject to change")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro asm("assembly template"
|
||||
: $("output"(operand),)*
|
||||
: $("input"(operand),)*
|
||||
: $("clobbers",)*
|
||||
: $("options",)*) { /* compiler built-in */ }
|
||||
|
||||
/// Module-level inline assembly.
|
||||
#[unstable(feature = "global_asm", issue = "35119",
|
||||
reason = "`global_asm!` is not stable enough for use and is subject to change")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro global_asm("assembly") { /* compiler built-in */ }
|
||||
|
||||
/// Prints passed tokens into the standard output.
|
||||
#[unstable(feature = "log_syntax", issue = "29598",
|
||||
reason = "`log_syntax!` is not stable enough for use and is subject to change")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro log_syntax($($arg:tt)*) { /* compiler built-in */ }
|
||||
|
||||
/// Enables or disables tracing functionality used for debugging other macros.
|
||||
#[unstable(feature = "trace_macros", issue = "29598",
|
||||
reason = "`trace_macros` is not stable enough for use and is subject to change")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro trace_macros {
|
||||
(true) => ({ /* compiler built-in */ }),
|
||||
(false) => ({ /* compiler built-in */ })
|
||||
}
|
||||
|
||||
/// Attribute macro applied to a function to turn it into a unit test.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro test($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Attribute macro applied to a function to turn it into a benchmark test.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro bench($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// An implementation detail of the `#[test]` and `#[bench]` macros.
|
||||
#[unstable(feature = "custom_test_frameworks", issue = "50297",
|
||||
reason = "custom test frameworks are an unstable feature")]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro test_case($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `Clone`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
|
||||
pub macro Clone($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `Copy`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
|
||||
pub macro Copy($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `Debug`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro Debug($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.0.0",
|
||||
reason = "derive(Decodable) is deprecated in favor of derive(RustcDecodable)",
|
||||
suggestion = "RustcDecodable",
|
||||
)]
|
||||
#[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
|
||||
pub macro Decodable($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `Default`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro Default($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.0.0",
|
||||
reason = "derive(Encodable) is deprecated in favor of derive(RustcEncodable)",
|
||||
suggestion = "RustcEncodable",
|
||||
)]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro Encodable($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `Eq`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics, derive_eq)]
|
||||
pub macro Eq($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `Hash`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro Hash($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `Ord`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro Ord($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `PartialEq`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro PartialEq($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Derive macro generating an impl of the trait `PartialOrd`.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro PartialOrd($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
|
||||
pub macro RustcDecodable($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro RustcEncodable($item:item) { /* compiler built-in */ }
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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};
|
||||
@ -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
|
||||
}
|
||||
|
@ -770,19 +770,25 @@ 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,
|
||||
@ -790,7 +796,7 @@ impl<'a> Resolver<'a> {
|
||||
¯o_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
|
||||
|
@ -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,
|
||||
@ -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
|
||||
@ -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);
|
||||
|
@ -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};
|
||||
@ -492,17 +492,6 @@ 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>,
|
||||
@ -510,17 +499,18 @@ impl<'a> Resolver<'a> {
|
||||
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) {
|
||||
|
@ -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 */ });
|
||||
@ -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 */ });
|
||||
@ -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 */ });
|
||||
@ -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 */ });
|
||||
@ -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 */ });
|
||||
@ -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 */ });
|
||||
@ -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.
|
||||
@ -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.
|
||||
@ -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.
|
||||
@ -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.
|
||||
@ -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 */ });
|
||||
@ -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 */ });
|
||||
@ -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.
|
||||
@ -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.
|
||||
@ -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 */ });
|
||||
@ -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 */ });
|
||||
|
@ -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};
|
||||
@ -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)
|
||||
}
|
||||
|
@ -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::*;
|
||||
|
@ -2,7 +2,6 @@ use crate::edition::Edition;
|
||||
use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander};
|
||||
use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind};
|
||||
use crate::ext::expand::{AstFragment, AstFragmentKind};
|
||||
use crate::ext::hygiene::Transparency;
|
||||
use crate::ext::tt::macro_parser::{parse, parse_failure_msg};
|
||||
use crate::ext::tt::macro_parser::{Error, Failure, Success};
|
||||
use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq};
|
||||
@ -15,7 +14,7 @@ use crate::parse::token::{self, NtTT, Token};
|
||||
use crate::parse::{Directory, ParseSess};
|
||||
use crate::symbol::{kw, sym, Symbol};
|
||||
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
|
||||
use crate::{ast, attr};
|
||||
use crate::{ast, attr, attr::TransparencyError};
|
||||
|
||||
use errors::FatalError;
|
||||
use log::debug;
|
||||
@ -380,13 +379,19 @@ pub fn compile(
|
||||
let expander: Box<_> =
|
||||
Box::new(MacroRulesMacroExpander { name: def.ident, lhses, rhses, valid });
|
||||
|
||||
let default_transparency = if attr::contains_name(&def.attrs, sym::rustc_transparent_macro) {
|
||||
Transparency::Transparent
|
||||
} else if body.legacy {
|
||||
Transparency::SemiTransparent
|
||||
} else {
|
||||
Transparency::Opaque
|
||||
};
|
||||
let (default_transparency, transparency_error) =
|
||||
attr::find_transparency(&def.attrs, body.legacy);
|
||||
match transparency_error {
|
||||
Some(TransparencyError::UnknownTransparency(value, span)) =>
|
||||
sess.span_diagnostic.span_err(
|
||||
span, &format!("unknown macro transparency: `{}`", value)
|
||||
),
|
||||
Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) =>
|
||||
sess.span_diagnostic.span_err(
|
||||
vec![old_span, new_span], "multiple macro transparency attributes"
|
||||
),
|
||||
None => {}
|
||||
}
|
||||
|
||||
let allow_internal_unstable =
|
||||
attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
|
||||
|
@ -245,7 +245,7 @@ declare_features! (
|
||||
(active, allocator_internals, "1.20.0", None, None),
|
||||
|
||||
// Allows using the `format_args_nl` macro.
|
||||
(active, format_args_nl, "1.29.0", None, None),
|
||||
(active, format_args_nl, "1.29.0", Some(0), None),
|
||||
|
||||
// no-tracking-issue-end
|
||||
|
||||
@ -1313,7 +1313,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
"the `#[rustc_test_marker]` attribute \
|
||||
is used internally to track tests",
|
||||
cfg_fn!(rustc_attrs))),
|
||||
(sym::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
|
||||
(sym::rustc_macro_transparency, Whitelisted, template!(NameValueStr:
|
||||
"transparent|semitransparent|opaque"),
|
||||
Gated(Stability::Unstable,
|
||||
sym::rustc_attrs,
|
||||
"used internally for testing macro hygiene",
|
||||
cfg_fn!(rustc_attrs))),
|
||||
@ -1374,7 +1376,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
"internal implementation detail",
|
||||
cfg_fn!(rustc_attrs))),
|
||||
|
||||
(sym::rustc_doc_only_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
|
||||
(sym::rustc_builtin_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
|
||||
sym::rustc_attrs,
|
||||
"internal implementation detail",
|
||||
cfg_fn!(rustc_attrs))),
|
||||
|
@ -537,6 +537,7 @@ symbols! {
|
||||
rustc_allow_const_fn_ptr,
|
||||
rustc_args_required_const,
|
||||
rustc_attrs,
|
||||
rustc_builtin_macro,
|
||||
rustc_clean,
|
||||
rustc_const_unstable,
|
||||
rustc_conversion_suggestion,
|
||||
@ -545,7 +546,6 @@ symbols! {
|
||||
rustc_deprecated,
|
||||
rustc_diagnostic_macros,
|
||||
rustc_dirty,
|
||||
rustc_doc_only_macro,
|
||||
rustc_dummy,
|
||||
rustc_dump_env_program_clauses,
|
||||
rustc_dump_program_clauses,
|
||||
@ -557,6 +557,7 @@ symbols! {
|
||||
rustc_layout,
|
||||
rustc_layout_scalar_valid_range_end,
|
||||
rustc_layout_scalar_valid_range_start,
|
||||
rustc_macro_transparency,
|
||||
rustc_mir,
|
||||
rustc_nonnull_optimization_guaranteed,
|
||||
rustc_object_lifetime_default,
|
||||
@ -579,7 +580,6 @@ symbols! {
|
||||
rustc_synthetic,
|
||||
rustc_test_marker,
|
||||
rustc_then_this_would_need,
|
||||
rustc_transparent_macro,
|
||||
rustc_variance,
|
||||
rustdoc,
|
||||
rust_eh_personality,
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![feature(decl_macro, rustc_attrs)]
|
||||
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
pub macro dollar_crate() {
|
||||
let s = $crate::S;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ macro genmod($FromOutside: ident, $Outer: ident) {
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro genmod_transparent() {
|
||||
type A = FromOutside;
|
||||
struct Outer;
|
||||
|
31
src/test/ui/hygiene/rustc-macro-transparency.rs
Normal file
31
src/test/ui/hygiene/rustc-macro-transparency.rs
Normal file
@ -0,0 +1,31 @@
|
||||
#![feature(decl_macro, rustc_attrs)]
|
||||
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro transparent() {
|
||||
struct Transparent;
|
||||
let transparent = 0;
|
||||
}
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
macro semitransparent() {
|
||||
struct SemiTransparent;
|
||||
let semitransparent = 0;
|
||||
}
|
||||
#[rustc_macro_transparency = "opaque"]
|
||||
macro opaque() {
|
||||
struct Opaque;
|
||||
let opaque = 0;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
transparent!();
|
||||
semitransparent!();
|
||||
opaque!();
|
||||
|
||||
Transparent; // OK
|
||||
SemiTransparent; // OK
|
||||
Opaque; //~ ERROR cannot find value `Opaque` in this scope
|
||||
|
||||
transparent; // OK
|
||||
semitransparent; //~ ERROR cannot find value `semitransparent` in this scope
|
||||
opaque; //~ ERROR cannot find value `opaque` in this scope
|
||||
}
|
21
src/test/ui/hygiene/rustc-macro-transparency.stderr
Normal file
21
src/test/ui/hygiene/rustc-macro-transparency.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0425]: cannot find value `Opaque` in this scope
|
||||
--> $DIR/rustc-macro-transparency.rs:26:5
|
||||
|
|
||||
LL | Opaque;
|
||||
| ^^^^^^ help: a local variable with a similar name exists: `opaque`
|
||||
|
||||
error[E0425]: cannot find value `semitransparent` in this scope
|
||||
--> $DIR/rustc-macro-transparency.rs:29:5
|
||||
|
|
||||
LL | semitransparent;
|
||||
| ^^^^^^^^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find value `opaque` in this scope
|
||||
--> $DIR/rustc-macro-transparency.rs:30:5
|
||||
|
|
||||
LL | opaque;
|
||||
| ^^^^^^ not found in this scope
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
@ -5,12 +5,12 @@
|
||||
|
||||
extern crate transparent_basic;
|
||||
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro binding() {
|
||||
let x = 10;
|
||||
}
|
||||
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro label() {
|
||||
break 'label
|
||||
}
|
||||
|
@ -80,17 +80,17 @@
|
||||
struct Right;
|
||||
// struct Wrong; // not defined
|
||||
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro include() {
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_outer() {
|
||||
macro m() { Wrong }
|
||||
}
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_inner() {
|
||||
macro m() { Right }
|
||||
}
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_invoc() {
|
||||
m!()
|
||||
}
|
||||
@ -100,7 +100,7 @@ macro include() {
|
||||
fn check1() {
|
||||
macro m() {}
|
||||
{
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_gen_inner_invoc() {
|
||||
gen_inner!();
|
||||
m!(); //~ ERROR `m` is ambiguous
|
||||
@ -112,7 +112,7 @@ macro include() {
|
||||
fn check5() {
|
||||
macro m() { Wrong }
|
||||
{
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_inner_invoc() {
|
||||
macro m() { Right }
|
||||
m!(); // OK
|
||||
@ -124,7 +124,7 @@ macro include() {
|
||||
fn check9() {
|
||||
macro m() { Wrong }
|
||||
{
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_inner_gen_invoc() {
|
||||
macro m() { Right }
|
||||
gen_invoc!(); // OK
|
||||
@ -145,7 +145,7 @@ macro include() {
|
||||
macro m() {}
|
||||
{
|
||||
gen_inner!();
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous
|
||||
gen_invoc!();
|
||||
}
|
||||
@ -186,7 +186,7 @@ macro include() {
|
||||
fn check52() {
|
||||
gen_outer!();
|
||||
{
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_gen_inner_invoc() {
|
||||
gen_inner!();
|
||||
m!(); //~ ERROR `m` is ambiguous
|
||||
@ -198,7 +198,7 @@ macro include() {
|
||||
fn check56() {
|
||||
gen_outer!();
|
||||
{
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_inner_invoc() {
|
||||
macro m() { Right }
|
||||
m!(); // OK
|
||||
@ -218,7 +218,7 @@ macro include() {
|
||||
fn check60() {
|
||||
gen_outer!();
|
||||
{
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_inner_gen_invoc() {
|
||||
macro m() { Right }
|
||||
gen_invoc!(); // OK
|
||||
@ -231,7 +231,7 @@ macro include() {
|
||||
gen_outer!();
|
||||
{
|
||||
gen_inner!();
|
||||
#[rustc_transparent_macro]
|
||||
#[rustc_macro_transparency = "transparent"]
|
||||
macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous
|
||||
gen_invoc!();
|
||||
}
|
||||
|
@ -8,18 +8,18 @@ use proc_macro::*;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
//~^ ERROR name `cfg` is reserved in macro namespace
|
||||
//~^ ERROR name `cfg` is reserved in attribute namespace
|
||||
input
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
//~^ ERROR name `cfg_attr` is reserved in macro namespace
|
||||
//~^ ERROR name `cfg_attr` is reserved in attribute namespace
|
||||
input
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
//~^ ERROR name `derive` is reserved in macro namespace
|
||||
//~^ ERROR name `derive` is reserved in attribute namespace
|
||||
input
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
error: name `cfg` is reserved in macro namespace
|
||||
error: name `cfg` is reserved in attribute namespace
|
||||
--> $DIR/reserved-macro-names.rs:10:8
|
||||
|
|
||||
LL | pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
| ^^^
|
||||
|
||||
error: name `cfg_attr` is reserved in macro namespace
|
||||
error: name `cfg_attr` is reserved in attribute namespace
|
||||
--> $DIR/reserved-macro-names.rs:16:8
|
||||
|
|
||||
LL | pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
| ^^^^^^^^
|
||||
|
||||
error: name `derive` is reserved in macro namespace
|
||||
error: name `derive` is reserved in attribute namespace
|
||||
--> $DIR/reserved-macro-names.rs:22:8
|
||||
|
|
||||
LL | pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
|
@ -13,7 +13,8 @@ pub fn check(path: &Path, bad: &mut bool) {
|
||||
&mut |entry, contents| {
|
||||
let subpath = entry.path();
|
||||
if let Some("rs") = subpath.extension().and_then(|e| e.to_str()) {
|
||||
if contents.contains("#[test]") {
|
||||
let contents = contents.trim();
|
||||
if !contents.starts_with("//") && contents.contains("#[test]") {
|
||||
tidy_error!(
|
||||
bad,
|
||||
"{} contains #[test]; libcore tests must be placed inside \
|
||||
|
Loading…
Reference in New Issue
Block a user