]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #66471 - Alexendoo:test-issue-63116, r=Centril
authorYuki Okushi <huyuumi.dev@gmail.com>
Sun, 17 Nov 2019 04:36:24 +0000 (13:36 +0900)
committerGitHub <noreply@github.com>
Sun, 17 Nov 2019 04:36:24 +0000 (13:36 +0900)
Add test for issue 63116

Closes #63116

70 files changed:
Cargo.lock
src/doc/rustc-guide
src/liballoc/vec.rs
src/libcore/macros.rs [deleted file]
src/libcore/macros/mod.rs [new file with mode: 0644]
src/libcore/macros/panic.md [new file with mode: 0644]
src/libpanic_unwind/lib.rs
src/libpanic_unwind/miri.rs
src/librustc/hir/def.rs
src/librustc/hir/lowering.rs
src/librustc/hir/lowering/item.rs
src/librustc/session/mod.rs
src/librustc_driver/Cargo.toml
src/librustc_driver/lib.rs
src/librustc_error_codes/error_codes.rs
src/librustc_error_codes/lib.rs
src/librustc_interface/Cargo.toml
src/librustc_interface/interface.rs
src/librustc_interface/passes.rs
src/librustc_interface/util.rs
src/librustc_lint/unused.rs
src/librustc_mir/transform/const_prop.rs
src/librustc_parse/parser/expr.rs
src/librustc_parse/parser/item.rs
src/librustc_parse/parser/mod.rs
src/librustc_parse/parser/ty.rs
src/librustc_passes/dead.rs
src/librustc_plugin/registry.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_save_analysis/sig.rs
src/librustdoc/core.rs
src/librustdoc/lib.rs
src/librustdoc/test.rs
src/libstd/keyword_docs.rs
src/libstd/macros.rs
src/libsyntax/ast.rs
src/libsyntax/attr/builtin.rs
src/libsyntax/feature_gate/check.rs
src/libsyntax/mut_visit.rs
src/libsyntax/print/pprust.rs
src/libsyntax_expand/expand.rs
src/libsyntax_expand/proc_macro.rs
src/libsyntax_ext/asm.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_pos/symbol.rs
src/test/run-make-fulldeps/issue-19371/foo.rs
src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs
src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
src/test/ui-fulldeps/issue-40001.rs
src/test/ui-fulldeps/plugin-attr-register-deny.rs [deleted file]
src/test/ui-fulldeps/plugin-attr-register-deny.stderr [deleted file]
src/test/ui/asm/asm-literal-escaping.rs [new file with mode: 0644]
src/test/ui/asm/asm-parse-errors.stderr
src/test/ui/consts/issue-66342.rs [new file with mode: 0644]
src/test/ui/consts/issue-66397.rs [new file with mode: 0644]
src/test/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs [new file with mode: 0644]
src/test/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr [new file with mode: 0644]
src/test/ui/lint/dead-code/lint-dead-code-4.rs
src/test/ui/lint/dead-code/lint-dead-code-4.stderr
src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs [new file with mode: 0644]
src/test/ui/proc-macro/derive-helper-shadowing.rs
src/test/ui/proc-macro/derive-helper-shadowing.stderr
src/test/ui/proc-macro/span-preservation.rs
src/test/ui/proc-macro/span-preservation.stderr
src/test/ui/union/union-fields-1.rs
src/test/ui/union/union-fields-1.stderr
src/test/ui/union/union-lint-dead-code.rs
src/test/ui/union/union-lint-dead-code.stderr

index f135a94ef7d7781368fb9b15bf0a8f161ba3a14c..2ecb38851e7bd111ae7d76d2378ed7397670c82c 100644 (file)
@@ -3522,6 +3522,7 @@ dependencies = [
  "rustc",
  "rustc_codegen_utils",
  "rustc_data_structures",
+ "rustc_error_codes",
  "rustc_errors",
  "rustc_interface",
  "rustc_lint",
@@ -3595,7 +3596,6 @@ dependencies = [
  "rustc_codegen_ssa",
  "rustc_codegen_utils",
  "rustc_data_structures",
- "rustc_error_codes",
  "rustc_errors",
  "rustc_incremental",
  "rustc_lint",
index 75a5f9236c689a547fe207a10854f0775bce7937..934380b7cfceaaa4e1b9bb0de4a372f32725520b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 75a5f9236c689a547fe207a10854f0775bce7937
+Subproject commit 934380b7cfceaaa4e1b9bb0de4a372f32725520b
index 4363314dc4580a65006000a6d457b3dfcb73f2af..07e4358d644c61fd4cb11a51d2180bef2f06aa91 100644 (file)
@@ -1333,10 +1333,9 @@ pub fn is_empty(&self) -> bool {
 
     /// Splits the collection into two at the given index.
     ///
-    /// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
-    /// and the returned `Self` contains elements `[at, len)`.
-    ///
-    /// Note that the capacity of `self` does not change.
+    /// Returns a newly allocated vector containing the elements in the range
+    /// `[at, len)`. After the call, the original vector will be left containing
+    /// the elements `[0, at)` with its previous capacity unchanged.
     ///
     /// # Panics
     ///
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
deleted file mode 100644 (file)
index d6b6e26..0000000
+++ /dev/null
@@ -1,1328 +0,0 @@
-/// Panics the current thread.
-///
-/// For details, see `std::macros`.
-#[macro_export]
-#[allow_internal_unstable(core_panic,
-    // FIXME(anp, eddyb) `core_intrinsics` is used here to allow calling
-    // the `caller_location` intrinsic, but once  `#[track_caller]` is implemented,
-    // `panicking::{panic, panic_fmt}` can use that instead of a `Location` argument.
-    core_intrinsics,
-)]
-#[stable(feature = "core", since = "1.6.0")]
-macro_rules! panic {
-    () => (
-        $crate::panic!("explicit panic")
-    );
-    ($msg:expr) => (
-        $crate::panicking::panic($msg, $crate::intrinsics::caller_location())
-    );
-    ($msg:expr,) => (
-        $crate::panic!($msg)
-    );
-    ($fmt:expr, $($arg:tt)+) => (
-        $crate::panicking::panic_fmt(
-            $crate::format_args!($fmt, $($arg)+),
-            $crate::intrinsics::caller_location(),
-        )
-    );
-}
-
-/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
-///
-/// On panic, this macro will print the values of the expressions with their
-/// debug representations.
-///
-/// Like [`assert!`], this macro has a second form, where a custom
-/// panic message can be provided.
-///
-/// [`PartialEq`]: cmp/trait.PartialEq.html
-/// [`assert!`]: macro.assert.html
-///
-/// # Examples
-///
-/// ```
-/// let a = 3;
-/// let b = 1 + 2;
-/// assert_eq!(a, b);
-///
-/// assert_eq!(a, b, "we are testing addition with {} and {}", a, b);
-/// ```
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-macro_rules! assert_eq {
-    ($left:expr, $right:expr) => ({
-        match (&$left, &$right) {
-            (left_val, right_val) => {
-                if !(*left_val == *right_val) {
-                    // The reborrows below are intentional. Without them, the stack slot for the
-                    // borrow is initialized even before the values are compared, leading to a
-                    // noticeable slow down.
-                    panic!(r#"assertion failed: `(left == right)`
-  left: `{:?}`,
- right: `{:?}`"#, &*left_val, &*right_val)
-                }
-            }
-        }
-    });
-    ($left:expr, $right:expr,) => ({
-        $crate::assert_eq!($left, $right)
-    });
-    ($left:expr, $right:expr, $($arg:tt)+) => ({
-        match (&($left), &($right)) {
-            (left_val, right_val) => {
-                if !(*left_val == *right_val) {
-                    // The reborrows below are intentional. Without them, the stack slot for the
-                    // borrow is initialized even before the values are compared, leading to a
-                    // noticeable slow down.
-                    panic!(r#"assertion failed: `(left == right)`
-  left: `{:?}`,
- right: `{:?}`: {}"#, &*left_val, &*right_val,
-                           $crate::format_args!($($arg)+))
-                }
-            }
-        }
-    });
-}
-
-/// Asserts that two expressions are not equal to each other (using [`PartialEq`]).
-///
-/// On panic, this macro will print the values of the expressions with their
-/// debug representations.
-///
-/// Like [`assert!`], this macro has a second form, where a custom
-/// panic message can be provided.
-///
-/// [`PartialEq`]: cmp/trait.PartialEq.html
-/// [`assert!`]: macro.assert.html
-///
-/// # Examples
-///
-/// ```
-/// let a = 3;
-/// let b = 2;
-/// assert_ne!(a, b);
-///
-/// assert_ne!(a, b, "we are testing that the values are not equal");
-/// ```
-#[macro_export]
-#[stable(feature = "assert_ne", since = "1.13.0")]
-macro_rules! assert_ne {
-    ($left:expr, $right:expr) => ({
-        match (&$left, &$right) {
-            (left_val, right_val) => {
-                if *left_val == *right_val {
-                    // The reborrows below are intentional. Without them, the stack slot for the
-                    // borrow is initialized even before the values are compared, leading to a
-                    // noticeable slow down.
-                    panic!(r#"assertion failed: `(left != right)`
-  left: `{:?}`,
- right: `{:?}`"#, &*left_val, &*right_val)
-                }
-            }
-        }
-    });
-    ($left:expr, $right:expr,) => {
-        $crate::assert_ne!($left, $right)
-    };
-    ($left:expr, $right:expr, $($arg:tt)+) => ({
-        match (&($left), &($right)) {
-            (left_val, right_val) => {
-                if *left_val == *right_val {
-                    // The reborrows below are intentional. Without them, the stack slot for the
-                    // borrow is initialized even before the values are compared, leading to a
-                    // noticeable slow down.
-                    panic!(r#"assertion failed: `(left != right)`
-  left: `{:?}`,
- right: `{:?}`: {}"#, &*left_val, &*right_val,
-                           $crate::format_args!($($arg)+))
-                }
-            }
-        }
-    });
-}
-
-/// Asserts that a boolean expression is `true` at runtime.
-///
-/// This will invoke the [`panic!`] macro if the provided expression cannot be
-/// evaluated to `true` at runtime.
-///
-/// Like [`assert!`], this macro also has a second version, where a custom panic
-/// message can be provided.
-///
-/// # Uses
-///
-/// Unlike [`assert!`], `debug_assert!` statements are only enabled in non
-/// optimized builds by default. An optimized build will not execute
-/// `debug_assert!` statements unless `-C debug-assertions` is passed to the
-/// compiler. This makes `debug_assert!` useful for checks that are too
-/// expensive to be present in a release build but may be helpful during
-/// development. The result of expanding `debug_assert!` is always type checked.
-///
-/// An unchecked assertion allows a program in an inconsistent state to keep
-/// running, which might have unexpected consequences but does not introduce
-/// unsafety as long as this only happens in safe code. The performance cost
-/// of assertions, is however, not measurable in general. Replacing [`assert!`]
-/// with `debug_assert!` is thus only encouraged after thorough profiling, and
-/// more importantly, only in safe code!
-///
-/// [`panic!`]: macro.panic.html
-/// [`assert!`]: macro.assert.html
-///
-/// # Examples
-///
-/// ```
-/// // the panic message for these assertions is the stringified value of the
-/// // expression given.
-/// debug_assert!(true);
-///
-/// fn some_expensive_computation() -> bool { true } // a very simple function
-/// debug_assert!(some_expensive_computation());
-///
-/// // assert with a custom message
-/// let x = true;
-/// debug_assert!(x, "x wasn't true!");
-///
-/// let a = 3; let b = 27;
-/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
-/// ```
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-macro_rules! debug_assert {
-    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert!($($arg)*); })
-}
-
-/// Asserts that two expressions are equal to each other.
-///
-/// On panic, this macro will print the values of the expressions with their
-/// debug representations.
-///
-/// Unlike [`assert_eq!`], `debug_assert_eq!` statements are only enabled in non
-/// optimized builds by default. An optimized build will not execute
-/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
-/// compiler. This makes `debug_assert_eq!` useful for checks that are too
-/// expensive to be present in a release build but may be helpful during
-/// development. The result of expanding `debug_assert_eq!` is always type checked.
-///
-/// [`assert_eq!`]: ../std/macro.assert_eq.html
-///
-/// # Examples
-///
-/// ```
-/// let a = 3;
-/// let b = 1 + 2;
-/// debug_assert_eq!(a, b);
-/// ```
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-macro_rules! debug_assert_eq {
-    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_eq!($($arg)*); })
-}
-
-/// Asserts that two expressions are not equal to each other.
-///
-/// On panic, this macro will print the values of the expressions with their
-/// debug representations.
-///
-/// Unlike [`assert_ne!`], `debug_assert_ne!` statements are only enabled in non
-/// optimized builds by default. An optimized build will not execute
-/// `debug_assert_ne!` statements unless `-C debug-assertions` is passed to the
-/// compiler. This makes `debug_assert_ne!` useful for checks that are too
-/// expensive to be present in a release build but may be helpful during
-/// development. The result of expanding `debug_assert_ne!` is always type checked.
-///
-/// [`assert_ne!`]: ../std/macro.assert_ne.html
-///
-/// # Examples
-///
-/// ```
-/// let a = 3;
-/// let b = 2;
-/// debug_assert_ne!(a, b);
-/// ```
-#[macro_export]
-#[stable(feature = "assert_ne", since = "1.13.0")]
-macro_rules! debug_assert_ne {
-    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
-}
-
-/// Returns whether the given expression matches any of the given patterns.
-///
-/// Like in a `match` expression, the pattern can be optionally followed by `if`
-/// and a guard expression that has access to names bound by the pattern.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(matches_macro)]
-///
-/// let foo = 'f';
-/// assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
-///
-/// let bar = Some(4);
-/// assert!(matches!(bar, Some(x) if x > 2));
-/// ```
-#[macro_export]
-#[unstable(feature = "matches_macro", issue = "65721")]
-macro_rules! matches {
-    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => {
-        match $expression {
-            $( $pattern )|+ $( if $guard )? => true,
-            _ => false
-        }
-    }
-}
-
-/// Unwraps a result or propagates its error.
-///
-/// The `?` operator was added to replace `try!` and should be used instead.
-/// Furthermore, `try` is a reserved word in Rust 2018, so if you must use
-/// it, you will need to use the [raw-identifier syntax][ris]: `r#try`.
-///
-/// [ris]: https://doc.rust-lang.org/nightly/rust-by-example/compatibility/raw_identifiers.html
-///
-/// `try!` matches the given [`Result`]. In case of the `Ok` variant, the
-/// expression has the value of the wrapped value.
-///
-/// In case of the `Err` variant, it retrieves the inner error. `try!` then
-/// performs conversion using `From`. This provides automatic conversion
-/// between specialized errors and more general ones. The resulting
-/// error is then immediately returned.
-///
-/// Because of the early return, `try!` can only be used in functions that
-/// return [`Result`].
-///
-/// [`Result`]: ../std/result/enum.Result.html
-///
-/// # Examples
-///
-/// ```
-/// use std::io;
-/// use std::fs::File;
-/// use std::io::prelude::*;
-///
-/// enum MyError {
-///     FileWriteError
-/// }
-///
-/// impl From<io::Error> for MyError {
-///     fn from(e: io::Error) -> MyError {
-///         MyError::FileWriteError
-///     }
-/// }
-///
-/// // The preferred method of quick returning Errors
-/// fn write_to_file_question() -> Result<(), MyError> {
-///     let mut file = File::create("my_best_friends.txt")?;
-///     file.write_all(b"This is a list of my best friends.")?;
-///     Ok(())
-/// }
-///
-/// // The previous method of quick returning Errors
-/// fn write_to_file_using_try() -> Result<(), MyError> {
-///     let mut file = r#try!(File::create("my_best_friends.txt"));
-///     r#try!(file.write_all(b"This is a list of my best friends."));
-///     Ok(())
-/// }
-///
-/// // This is equivalent to:
-/// fn write_to_file_using_match() -> Result<(), MyError> {
-///     let mut file = r#try!(File::create("my_best_friends.txt"));
-///     match file.write_all(b"This is a list of my best friends.") {
-///         Ok(v) => v,
-///         Err(e) => return Err(From::from(e)),
-///     }
-///     Ok(())
-/// }
-/// ```
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_deprecated(since = "1.39.0", reason = "use the `?` operator instead")]
-#[doc(alias = "?")]
-macro_rules! r#try {
-    ($expr:expr) => (match $expr {
-        $crate::result::Result::Ok(val) => val,
-        $crate::result::Result::Err(err) => {
-            return $crate::result::Result::Err($crate::convert::From::from(err))
-        }
-    });
-    ($expr:expr,) => ($crate::r#try!($expr));
-}
-
-/// Writes formatted data into a buffer.
-///
-/// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be
-/// formatted according to the specified format string and the result will be passed to the writer.
-/// The writer may be any value with a `write_fmt` method; generally this comes from an
-/// implementation of either the [`std::fmt::Write`] or the [`std::io::Write`] trait. The macro
-/// returns whatever the `write_fmt` method returns; commonly a [`std::fmt::Result`], or an
-/// [`io::Result`].
-///
-/// See [`std::fmt`] for more information on the format string syntax.
-///
-/// [`std::fmt`]: ../std/fmt/index.html
-/// [`std::fmt::Write`]: ../std/fmt/trait.Write.html
-/// [`std::io::Write`]: ../std/io/trait.Write.html
-/// [`std::fmt::Result`]: ../std/fmt/type.Result.html
-/// [`io::Result`]: ../std/io/type.Result.html
-///
-/// # Examples
-///
-/// ```
-/// use std::io::Write;
-///
-/// fn main() -> std::io::Result<()> {
-///     let mut w = Vec::new();
-///     write!(&mut w, "test")?;
-///     write!(&mut w, "formatted {}", "arguments")?;
-///
-///     assert_eq!(w, b"testformatted arguments");
-///     Ok(())
-/// }
-/// ```
-///
-/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
-/// implementing either, as objects do not typically implement both. However, the module must
-/// import the traits qualified so their names do not conflict:
-///
-/// ```
-/// use std::fmt::Write as FmtWrite;
-/// use std::io::Write as IoWrite;
-///
-/// fn main() -> Result<(), Box<dyn std::error::Error>> {
-///     let mut s = String::new();
-///     let mut v = Vec::new();
-///
-///     write!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt
-///     write!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt
-///     assert_eq!(v, b"s = \"abc 123\"");
-///     Ok(())
-/// }
-/// ```
-///
-/// Note: This macro can be used in `no_std` setups as well.
-/// In a `no_std` setup you are responsible for the implementation details of the components.
-///
-/// ```no_run
-/// # extern crate core;
-/// use core::fmt::Write;
-///
-/// struct Example;
-///
-/// impl Write for Example {
-///     fn write_str(&mut self, _s: &str) -> core::fmt::Result {
-///          unimplemented!();
-///     }
-/// }
-///
-/// let mut m = Example{};
-/// write!(&mut m, "Hello World").expect("Not written");
-/// ```
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-macro_rules! write {
-    ($dst:expr, $($arg:tt)*) => ($dst.write_fmt($crate::format_args!($($arg)*)))
-}
-
-/// Write formatted data into a buffer, with a newline appended.
-///
-/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
-/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
-///
-/// For more information, see [`write!`]. For information on the format string syntax, see
-/// [`std::fmt`].
-///
-/// [`write!`]: macro.write.html
-/// [`std::fmt`]: ../std/fmt/index.html
-///
-///
-/// # Examples
-///
-/// ```
-/// use std::io::{Write, Result};
-///
-/// fn main() -> Result<()> {
-///     let mut w = Vec::new();
-///     writeln!(&mut w)?;
-///     writeln!(&mut w, "test")?;
-///     writeln!(&mut w, "formatted {}", "arguments")?;
-///
-///     assert_eq!(&w[..], "\ntest\nformatted arguments\n".as_bytes());
-///     Ok(())
-/// }
-/// ```
-///
-/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
-/// implementing either, as objects do not typically implement both. However, the module must
-/// import the traits qualified so their names do not conflict:
-///
-/// ```
-/// use std::fmt::Write as FmtWrite;
-/// use std::io::Write as IoWrite;
-///
-/// fn main() -> Result<(), Box<dyn std::error::Error>> {
-///     let mut s = String::new();
-///     let mut v = Vec::new();
-///
-///     writeln!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt
-///     writeln!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt
-///     assert_eq!(v, b"s = \"abc 123\\n\"\n");
-///     Ok(())
-/// }
-/// ```
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow_internal_unstable(format_args_nl)]
-macro_rules! writeln {
-    ($dst:expr) => (
-        $crate::write!($dst, "\n")
-    );
-    ($dst:expr,) => (
-        $crate::writeln!($dst)
-    );
-    ($dst:expr, $($arg:tt)*) => (
-        $dst.write_fmt($crate::format_args_nl!($($arg)*))
-    );
-}
-
-/// Indicates unreachable code.
-///
-/// This is useful any time that the compiler can't determine that some code is unreachable. For
-/// example:
-///
-/// * Match arms with guard conditions.
-/// * Loops that dynamically terminate.
-/// * Iterators that dynamically terminate.
-///
-/// If the determination that the code is unreachable proves incorrect, the
-/// program immediately terminates with a [`panic!`].
-///
-/// The unsafe counterpart of this macro is the [`unreachable_unchecked`] function, which
-/// will cause undefined behavior if the code is reached.
-///
-/// [`panic!`]: ../std/macro.panic.html
-/// [`unreachable_unchecked`]: ../std/hint/fn.unreachable_unchecked.html
-/// [`std::hint`]: ../std/hint/index.html
-///
-/// # Panics
-///
-/// This will always [`panic!`]
-///
-/// [`panic!`]: ../std/macro.panic.html
-///
-/// # Examples
-///
-/// Match arms:
-///
-/// ```
-/// # #[allow(dead_code)]
-/// fn foo(x: Option<i32>) {
-///     match x {
-///         Some(n) if n >= 0 => println!("Some(Non-negative)"),
-///         Some(n) if n <  0 => println!("Some(Negative)"),
-///         Some(_)           => unreachable!(), // compile error if commented out
-///         None              => println!("None")
-///     }
-/// }
-/// ```
-///
-/// Iterators:
-///
-/// ```
-/// # #[allow(dead_code)]
-/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
-///     for i in 0.. {
-///         if 3*i < i { panic!("u32 overflow"); }
-///         if x < 3*i { return i-1; }
-///     }
-///     unreachable!();
-/// }
-/// ```
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-macro_rules! unreachable {
-    () => ({
-        panic!("internal error: entered unreachable code")
-    });
-    ($msg:expr) => ({
-        $crate::unreachable!("{}", $msg)
-    });
-    ($msg:expr,) => ({
-        $crate::unreachable!($msg)
-    });
-    ($fmt:expr, $($arg:tt)*) => ({
-        panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
-    });
-}
-
-/// Indicates unfinished code by panicking with a message of "not yet implemented".
-///
-/// This allows the your code to type-check, which is useful if you are prototyping or
-/// implementing a trait that requires multiple methods which you don't plan of using all of.
-///
-/// There is no difference between `unimplemented!` and `todo!` apart from the
-/// name.
-///
-/// # Panics
-///
-/// This will always [panic!](macro.panic.html) because `unimplemented!` is just a
-/// shorthand for `panic!` with a fixed, specific message.
-///
-/// Like `panic!`, this macro has a second form for displaying custom values.
-///
-/// # Examples
-///
-/// Here's an example of some in-progress code. We have a trait `Foo`:
-///
-/// ```
-/// trait Foo {
-///     fn bar(&self) -> u8;
-///     fn baz(&self);
-///     fn qux(&self) -> Result<u64, ()>;
-/// }
-/// ```
-///
-/// We want to implement `Foo` for 'MyStruct', but so far we only know how to
-/// implement the `bar()` function. `baz()` and `qux()` will still need to be defined
-/// in our implementation of `Foo`, but we can use `unimplemented!` in their definitions
-/// to allow our code to compile.
-///
-/// In the meantime, we want to have our program stop running once these
-/// unimplemented functions are reached.
-///
-/// ```
-/// # trait Foo {
-/// #     fn bar(&self) -> u8;
-/// #     fn baz(&self);
-/// #     fn qux(&self) -> Result<u64, ()>;
-/// # }
-/// struct MyStruct;
-///
-/// impl Foo for MyStruct {
-///     fn bar(&self) -> u8 {
-///         1 + 1
-///     }
-///
-///     fn baz(&self) {
-///         // We aren't sure how to even start writing baz yet,
-///         // so we have no logic here at all.
-///         // This will display "thread 'main' panicked at 'not yet implemented'".
-///         unimplemented!();
-///     }
-///
-///     fn qux(&self) -> Result<u64, ()> {
-///         let n = self.bar();
-///         // We have some logic here,
-///         // so we can use unimplemented! to display what we have so far.
-///         // This will display:
-///         // "thread 'main' panicked at 'not yet implemented: we need to divide by 2'".
-///         unimplemented!("we need to divide by {}", n);
-///     }
-/// }
-///
-/// fn main() {
-///     let s = MyStruct;
-///     s.bar();
-/// }
-/// ```
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-macro_rules! unimplemented {
-    () => (panic!("not yet implemented"));
-    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
-}
-
-/// Indicates unfinished code.
-///
-/// This can be useful if you are prototyping and are just looking to have your
-/// code typecheck.
-///
-/// There is no difference between `unimplemented!` and `todo!` apart from the
-/// name.
-///
-/// # Panics
-///
-/// This will always [panic!](macro.panic.html)
-///
-/// # Examples
-///
-/// Here's an example of some in-progress code. We have a trait `Foo`:
-///
-/// ```
-/// trait Foo {
-///     fn bar(&self);
-///     fn baz(&self);
-/// }
-/// ```
-///
-/// We want to implement `Foo` on one of our types, but we also want to work on
-/// just `bar()` first. In order for our code to compile, we need to implement
-/// `baz()`, so we can use `todo!`:
-///
-/// ```
-/// # trait Foo {
-/// #     fn bar(&self);
-/// #     fn baz(&self);
-/// # }
-/// struct MyStruct;
-///
-/// impl Foo for MyStruct {
-///     fn bar(&self) {
-///         // implementation goes here
-///     }
-///
-///     fn baz(&self) {
-///         // let's not worry about implementing baz() for now
-///         todo!();
-///     }
-/// }
-///
-/// fn main() {
-///     let s = MyStruct;
-///     s.bar();
-///
-///     // we aren't even using baz() yet, so this is fine.
-/// }
-/// ```
-#[macro_export]
-#[stable(feature = "todo_macro", since = "1.39.0")]
-macro_rules! todo {
-    () => (panic!("not yet implemented"));
-    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
-}
-
-/// Definitions of built-in macros.
-///
-/// 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.
-pub(crate) mod builtin {
-
-    /// Causes compilation to fail with the given error message when encountered.
-    ///
-    /// This macro should be used when a crate uses a conditional compilation strategy to provide
-    /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
-    /// but emits an error during *compilation* rather than at *runtime*.
-    ///
-    /// # Examples
-    ///
-    /// Two such examples are macros and `#[cfg]` environments.
-    ///
-    /// Emit better compiler error if a macro is passed invalid values. Without the final branch,
-    /// the compiler would still emit an error, but the error's message would not mention the two
-    /// valid values.
-    ///
-    /// ```compile_fail
-    /// macro_rules! give_me_foo_or_bar {
-    ///     (foo) => {};
-    ///     (bar) => {};
-    ///     ($x:ident) => {
-    ///         compile_error!("This macro only accepts `foo` or `bar`");
-    ///     }
-    /// }
-    ///
-    /// give_me_foo_or_bar!(neither);
-    /// // ^ will fail at compile time with message "This macro only accepts `foo` or `bar`"
-    /// ```
-    ///
-    /// Emit compiler error if one of a number of features isn't available.
-    ///
-    /// ```compile_fail
-    /// #[cfg(not(any(feature = "foo", feature = "bar")))]
-    /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.");
-    /// ```
-    ///
-    /// [`panic!`]: ../std/macro.panic.html
-    #[stable(feature = "compile_error_macro", since = "1.20.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! compile_error {
-        ($msg:expr) => ({ /* compiler built-in */ });
-        ($msg:expr,) => ({ /* compiler built-in */ })
-    }
-
-    /// Constructs parameters for the other string-formatting macros.
-    ///
-    /// This macro functions by taking a formatting string literal containing
-    /// `{}` for each additional argument passed. `format_args!` prepares the
-    /// additional parameters to ensure the output can be interpreted as a string
-    /// and canonicalizes the arguments into a single type. Any value that implements
-    /// the [`Display`] trait can be passed to `format_args!`, as can any
-    /// [`Debug`] implementation be passed to a `{:?}` within the formatting string.
-    ///
-    /// This macro produces a value of type [`fmt::Arguments`]. This value can be
-    /// passed to the macros within [`std::fmt`] for performing useful redirection.
-    /// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
-    /// proxied through this one. `format_args!`, unlike its derived macros, avoids
-    /// heap allocations.
-    ///
-    /// You can use the [`fmt::Arguments`] value that `format_args!` returns
-    /// in `Debug` and `Display` contexts as seen below. The example also shows
-    /// that `Debug` and `Display` format to the same thing: the interpolated
-    /// format string in `format_args!`.
-    ///
-    /// ```rust
-    /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
-    /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
-    /// assert_eq!("1 foo 2", display);
-    /// assert_eq!(display, debug);
-    /// ```
-    ///
-    /// For more information, see the documentation in [`std::fmt`].
-    ///
-    /// [`Display`]: ../std/fmt/trait.Display.html
-    /// [`Debug`]: ../std/fmt/trait.Debug.html
-    /// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html
-    /// [`std::fmt`]: ../std/fmt/index.html
-    /// [`format!`]: ../std/macro.format.html
-    /// [`write!`]: ../std/macro.write.html
-    /// [`println!`]: ../std/macro.println.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::fmt;
-    ///
-    /// let s = fmt::format(format_args!("hello {}", "world"));
-    /// assert_eq!(s, format!("hello {}", "world"));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[allow_internal_unstable(fmt_internals)]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! 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]
-    #[macro_export]
-    macro_rules! format_args_nl {
-        ($fmt:expr) => ({ /* compiler built-in */ });
-        ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
-    }
-
-    /// Inspects an environment variable at compile time.
-    ///
-    /// This macro will expand to the value of the named environment variable at
-    /// compile time, yielding an expression of type `&'static str`.
-    ///
-    /// If the environment variable is not defined, then a compilation error
-    /// will be emitted. To not emit a compile error, use the [`option_env!`]
-    /// macro instead.
-    ///
-    /// [`option_env!`]: ../std/macro.option_env.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let path: &'static str = env!("PATH");
-    /// println!("the $PATH variable at the time of compiling was: {}", path);
-    /// ```
-    ///
-    /// You can customize the error message by passing a string as the second
-    /// parameter:
-    ///
-    /// ```compile_fail
-    /// let doc: &'static str = env!("documentation", "what's that?!");
-    /// ```
-    ///
-    /// If the `documentation` environment variable is not defined, you'll get
-    /// the following error:
-    ///
-    /// ```text
-    /// error: what's that?!
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! env {
-        ($name:expr) => ({ /* compiler built-in */ });
-        ($name:expr,) => ({ /* compiler built-in */ })
-    }
-
-    /// Optionally inspects an environment variable at compile time.
-    ///
-    /// If the named environment variable is present at compile time, this will
-    /// expand into an expression of type `Option<&'static str>` whose value is
-    /// `Some` of the value of the environment variable. If the environment
-    /// variable is not present, then this will expand to `None`. See
-    /// [`Option<T>`][option] for more information on this type.
-    ///
-    /// A compile time error is never emitted when using this macro regardless
-    /// of whether the environment variable is present or not.
-    ///
-    /// [option]: ../std/option/enum.Option.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
-    /// println!("the secret key might be: {:?}", key);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! option_env {
-        ($name:expr) => ({ /* compiler built-in */ });
-        ($name:expr,) => ({ /* compiler built-in */ })
-    }
-
-    /// Concatenates identifiers into one identifier.
-    ///
-    /// This macro takes any number of comma-separated identifiers, and
-    /// concatenates them all into one, yielding an expression which is a new
-    /// identifier. Note that hygiene makes it such that this macro cannot
-    /// capture local variables. Also, as a general rule, macros are only
-    /// allowed in item, statement or expression position. That means while
-    /// you may use this macro for referring to existing variables, functions or
-    /// modules etc, you cannot define a new one with it.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(concat_idents)]
-    ///
-    /// # fn main() {
-    /// fn foobar() -> u32 { 23 }
-    ///
-    /// let f = concat_idents!(foo, bar);
-    /// println!("{}", f());
-    ///
-    /// // fn concat_idents!(new, fun, name) { } // not usable in this way!
-    /// # }
-    /// ```
-    #[unstable(feature = "concat_idents", issue = "29599",
-               reason = "`concat_idents` is not stable enough for use and is subject to change")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! concat_idents {
-        ($($e:ident),+) => ({ /* compiler built-in */ });
-        ($($e:ident,)+) => ({ /* compiler built-in */ })
-    }
-
-    /// Concatenates literals into a static string slice.
-    ///
-    /// This macro takes any number of comma-separated literals, yielding an
-    /// expression of type `&'static str` which represents all of the literals
-    /// concatenated left-to-right.
-    ///
-    /// Integer and floating point literals are stringified in order to be
-    /// concatenated.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let s = concat!("test", 10, 'b', true);
-    /// assert_eq!(s, "test10btrue");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! concat {
-        ($($e:expr),*) => ({ /* compiler built-in */ });
-        ($($e:expr,)*) => ({ /* compiler built-in */ })
-    }
-
-    /// Expands to the line number on which it was invoked.
-    ///
-    /// With [`column!`] and [`file!`], these macros provide debugging information for
-    /// developers about the location within the source.
-    ///
-    /// The expanded expression has type `u32` and is 1-based, so the first line
-    /// in each file evaluates to 1, the second to 2, etc. This is consistent
-    /// with error messages by common compilers or popular editors.
-    /// The returned line is *not necessarily* the line of the `line!` invocation itself,
-    /// but rather the first macro invocation leading up to the invocation
-    /// of the `line!` macro.
-    ///
-    /// [`column!`]: macro.column.html
-    /// [`file!`]: macro.file.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let current_line = line!();
-    /// println!("defined on line: {}", current_line);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! line { () => { /* compiler built-in */ } }
-
-    /// Expands to the column number at which it was invoked.
-    ///
-    /// With [`line!`] and [`file!`], these macros provide debugging information for
-    /// developers about the location within the source.
-    ///
-    /// The expanded expression has type `u32` and is 1-based, so the first column
-    /// in each line evaluates to 1, the second to 2, etc. This is consistent
-    /// with error messages by common compilers or popular editors.
-    /// The returned column is *not necessarily* the line of the `column!` invocation itself,
-    /// but rather the first macro invocation leading up to the invocation
-    /// of the `column!` macro.
-    ///
-    /// [`line!`]: macro.line.html
-    /// [`file!`]: macro.file.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let current_col = column!();
-    /// println!("defined on column: {}", current_col);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! column { () => { /* compiler built-in */ } }
-
-    /// Expands to the file name in which it was invoked.
-    ///
-    /// With [`line!`] and [`column!`], these macros provide debugging information for
-    /// developers about the location within the source.
-    ///
-    ///
-    /// The expanded expression has type `&'static str`, and the returned file
-    /// is not the invocation of the `file!` macro itself, but rather the
-    /// first macro invocation leading up to the invocation of the `file!`
-    /// macro.
-    ///
-    /// [`line!`]: macro.line.html
-    /// [`column!`]: macro.column.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let this_file = file!();
-    /// println!("defined in file: {}", this_file);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! file { () => { /* compiler built-in */ } }
-
-    /// Stringifies its arguments.
-    ///
-    /// This macro will yield an expression of type `&'static str` which is the
-    /// stringification of all the tokens passed to the macro. No restrictions
-    /// are placed on the syntax of the macro invocation itself.
-    ///
-    /// Note that the expanded results of the input tokens may change in the
-    /// future. You should be careful if you rely on the output.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let one_plus_one = stringify!(1 + 1);
-    /// assert_eq!(one_plus_one, "1 + 1");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! stringify { ($($t:tt)*) => { /* compiler built-in */ } }
-
-    /// Includes a utf8-encoded file as a string.
-    ///
-    /// The file is located relative to the current file. (similarly to how
-    /// modules are found)
-    ///
-    /// This macro will yield an expression of type `&'static str` which is the
-    /// contents of the file.
-    ///
-    /// # Examples
-    ///
-    /// Assume there are two files in the same directory with the following
-    /// contents:
-    ///
-    /// File 'spanish.in':
-    ///
-    /// ```text
-    /// adiós
-    /// ```
-    ///
-    /// File 'main.rs':
-    ///
-    /// ```ignore (cannot-doctest-external-file-dependency)
-    /// fn main() {
-    ///     let my_str = include_str!("spanish.in");
-    ///     assert_eq!(my_str, "adiós\n");
-    ///     print!("{}", my_str);
-    /// }
-    /// ```
-    ///
-    /// Compiling 'main.rs' and running the resulting binary will print "adiós".
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! include_str {
-        ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ })
-    }
-
-    /// Includes a file as a reference to a byte array.
-    ///
-    /// The file is located relative to the current file. (similarly to how
-    /// modules are found)
-    ///
-    /// This macro will yield an expression of type `&'static [u8; N]` which is
-    /// the contents of the file.
-    ///
-    /// # Examples
-    ///
-    /// Assume there are two files in the same directory with the following
-    /// contents:
-    ///
-    /// File 'spanish.in':
-    ///
-    /// ```text
-    /// adiós
-    /// ```
-    ///
-    /// File 'main.rs':
-    ///
-    /// ```ignore (cannot-doctest-external-file-dependency)
-    /// fn main() {
-    ///     let bytes = include_bytes!("spanish.in");
-    ///     assert_eq!(bytes, b"adi\xc3\xb3s\n");
-    ///     print!("{}", String::from_utf8_lossy(bytes));
-    /// }
-    /// ```
-    ///
-    /// Compiling 'main.rs' and running the resulting binary will print "adiós".
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! include_bytes {
-        ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ })
-    }
-
-    /// Expands to a string that represents the current module path.
-    ///
-    /// The current module path can be thought of as the hierarchy of modules
-    /// leading back up to the crate root. The first component of the path
-    /// returned is the name of the crate currently being compiled.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// mod test {
-    ///     pub fn foo() {
-    ///         assert!(module_path!().ends_with("test"));
-    ///     }
-    /// }
-    ///
-    /// test::foo();
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! module_path { () => { /* compiler built-in */ } }
-
-    /// Evaluates boolean combinations of configuration flags at compile-time.
-    ///
-    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
-    /// boolean expression evaluation of configuration flags. This frequently
-    /// leads to less duplicated code.
-    ///
-    /// The syntax given to this macro is the same syntax as the [`cfg`]
-    /// attribute.
-    ///
-    /// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let my_directory = if cfg!(windows) {
-    ///     "windows-specific-directory"
-    /// } else {
-    ///     "unix-directory"
-    /// };
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! cfg { ($($cfg:tt)*) => { /* compiler built-in */ } }
-
-    /// Parses a file as an expression or an item according to the context.
-    ///
-    /// The file is located relative to the current file (similarly to how
-    /// modules are found).
-    ///
-    /// Using this macro is often a bad idea, because if the file is
-    /// parsed as an expression, it is going to be placed in the
-    /// surrounding code unhygienically. This could result in variables
-    /// or functions being different from what the file expected if
-    /// there are variables or functions that have the same name in
-    /// the current file.
-    ///
-    /// # Examples
-    ///
-    /// Assume there are two files in the same directory with the following
-    /// contents:
-    ///
-    /// File 'monkeys.in':
-    ///
-    /// ```ignore (only-for-syntax-highlight)
-    /// ['🙈', '🙊', '🙉']
-    ///     .iter()
-    ///     .cycle()
-    ///     .take(6)
-    ///     .collect::<String>()
-    /// ```
-    ///
-    /// File 'main.rs':
-    ///
-    /// ```ignore (cannot-doctest-external-file-dependency)
-    /// fn main() {
-    ///     let my_string = include!("monkeys.in");
-    ///     assert_eq!("🙈🙊🙉🙈🙊🙉", my_string);
-    ///     println!("{}", my_string);
-    /// }
-    /// ```
-    ///
-    /// Compiling 'main.rs' and running the resulting binary will print
-    /// "🙈🙊🙉🙈🙊🙉".
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! include {
-        ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ })
-    }
-
-    /// Asserts that a boolean expression is `true` at runtime.
-    ///
-    /// This will invoke the [`panic!`] macro if the provided expression cannot be
-    /// evaluated to `true` at runtime.
-    ///
-    /// # Uses
-    ///
-    /// Assertions are always checked in both debug and release builds, and cannot
-    /// be disabled. See [`debug_assert!`] for assertions that are not enabled in
-    /// release builds by default.
-    ///
-    /// Unsafe code relies on `assert!` to enforce run-time invariants that, if
-    /// violated could lead to unsafety.
-    ///
-    /// Other use-cases of `assert!` include testing and enforcing run-time
-    /// invariants in safe code (whose violation cannot result in unsafety).
-    ///
-    /// # Custom Messages
-    ///
-    /// This macro has a second form, where a custom panic message can
-    /// be provided with or without arguments for formatting. See [`std::fmt`]
-    /// for syntax for this form.
-    ///
-    /// [`panic!`]: macro.panic.html
-    /// [`debug_assert!`]: macro.debug_assert.html
-    /// [`std::fmt`]: ../std/fmt/index.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// // the panic message for these assertions is the stringified value of the
-    /// // expression given.
-    /// assert!(true);
-    ///
-    /// fn some_computation() -> bool { true } // a very simple function
-    ///
-    /// assert!(some_computation());
-    ///
-    /// // assert with a custom message
-    /// let x = true;
-    /// assert!(x, "x wasn't true!");
-    ///
-    /// let a = 3; let b = 27;
-    /// assert!(a + b == 30, "a = {}, b = {}", a, b);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! assert {
-        ($cond:expr) => ({ /* compiler built-in */ });
-        ($cond:expr,) => ({ /* compiler built-in */ });
-        ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ })
-    }
-
-    /// Inline assembly.
-    ///
-    /// Read the [unstable book] for the usage.
-    ///
-    /// [unstable book]: ../unstable-book/library-features/asm.html
-    #[unstable(feature = "asm", issue = "29722",
-               reason = "inline assembly is not stable enough for use and is subject to change")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! 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]
-    #[macro_export]
-    macro_rules! 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]
-    #[macro_export]
-    macro_rules! 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]
-    #[macro_export]
-    macro_rules! 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")]
-    #[allow_internal_unstable(test, rustc_attrs)]
-    #[rustc_builtin_macro]
-    pub macro test($item:item) { /* compiler built-in */ }
-
-    /// Attribute macro applied to a function to turn it into a benchmark test.
-    #[unstable(soft, feature = "test", issue = "50297",
-               reason = "`bench` is a part of custom test frameworks which are unstable")]
-    #[allow_internal_unstable(test, rustc_attrs)]
-    #[rustc_builtin_macro]
-    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")]
-    #[allow_internal_unstable(test, rustc_attrs)]
-    #[rustc_builtin_macro]
-    pub macro test_case($item:item) { /* compiler built-in */ }
-
-    /// Attribute macro applied to a static to register it as a global allocator.
-    #[stable(feature = "global_allocator", since = "1.28.0")]
-    #[allow_internal_unstable(rustc_attrs)]
-    #[rustc_builtin_macro]
-    pub macro global_allocator($item:item) { /* compiler built-in */ }
-
-    /// Unstable implementation detail of the `rustc` compiler, do not use.
-    #[rustc_builtin_macro]
-    #[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]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[allow_internal_unstable(core_intrinsics)]
-    pub macro RustcEncodable($item:item) { /* compiler built-in */ }
-}
diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs
new file mode 100644 (file)
index 0000000..7f27e62
--- /dev/null
@@ -0,0 +1,1326 @@
+#[doc(include = "panic.md")]
+#[macro_export]
+#[allow_internal_unstable(core_panic,
+    // FIXME(anp, eddyb) `core_intrinsics` is used here to allow calling
+    // the `caller_location` intrinsic, but once  `#[track_caller]` is implemented,
+    // `panicking::{panic, panic_fmt}` can use that instead of a `Location` argument.
+    core_intrinsics,
+)]
+#[stable(feature = "core", since = "1.6.0")]
+macro_rules! panic {
+    () => (
+        $crate::panic!("explicit panic")
+    );
+    ($msg:expr) => (
+        $crate::panicking::panic($msg, $crate::intrinsics::caller_location())
+    );
+    ($msg:expr,) => (
+        $crate::panic!($msg)
+    );
+    ($fmt:expr, $($arg:tt)+) => (
+        $crate::panicking::panic_fmt(
+            $crate::format_args!($fmt, $($arg)+),
+            $crate::intrinsics::caller_location(),
+        )
+    );
+}
+
+/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
+///
+/// On panic, this macro will print the values of the expressions with their
+/// debug representations.
+///
+/// Like [`assert!`], this macro has a second form, where a custom
+/// panic message can be provided.
+///
+/// [`PartialEq`]: cmp/trait.PartialEq.html
+/// [`assert!`]: macro.assert.html
+///
+/// # Examples
+///
+/// ```
+/// let a = 3;
+/// let b = 1 + 2;
+/// assert_eq!(a, b);
+///
+/// assert_eq!(a, b, "we are testing addition with {} and {}", a, b);
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+macro_rules! assert_eq {
+    ($left:expr, $right:expr) => ({
+        match (&$left, &$right) {
+            (left_val, right_val) => {
+                if !(*left_val == *right_val) {
+                    // The reborrows below are intentional. Without them, the stack slot for the
+                    // borrow is initialized even before the values are compared, leading to a
+                    // noticeable slow down.
+                    panic!(r#"assertion failed: `(left == right)`
+  left: `{:?}`,
+ right: `{:?}`"#, &*left_val, &*right_val)
+                }
+            }
+        }
+    });
+    ($left:expr, $right:expr,) => ({
+        $crate::assert_eq!($left, $right)
+    });
+    ($left:expr, $right:expr, $($arg:tt)+) => ({
+        match (&($left), &($right)) {
+            (left_val, right_val) => {
+                if !(*left_val == *right_val) {
+                    // The reborrows below are intentional. Without them, the stack slot for the
+                    // borrow is initialized even before the values are compared, leading to a
+                    // noticeable slow down.
+                    panic!(r#"assertion failed: `(left == right)`
+  left: `{:?}`,
+ right: `{:?}`: {}"#, &*left_val, &*right_val,
+                           $crate::format_args!($($arg)+))
+                }
+            }
+        }
+    });
+}
+
+/// Asserts that two expressions are not equal to each other (using [`PartialEq`]).
+///
+/// On panic, this macro will print the values of the expressions with their
+/// debug representations.
+///
+/// Like [`assert!`], this macro has a second form, where a custom
+/// panic message can be provided.
+///
+/// [`PartialEq`]: cmp/trait.PartialEq.html
+/// [`assert!`]: macro.assert.html
+///
+/// # Examples
+///
+/// ```
+/// let a = 3;
+/// let b = 2;
+/// assert_ne!(a, b);
+///
+/// assert_ne!(a, b, "we are testing that the values are not equal");
+/// ```
+#[macro_export]
+#[stable(feature = "assert_ne", since = "1.13.0")]
+macro_rules! assert_ne {
+    ($left:expr, $right:expr) => ({
+        match (&$left, &$right) {
+            (left_val, right_val) => {
+                if *left_val == *right_val {
+                    // The reborrows below are intentional. Without them, the stack slot for the
+                    // borrow is initialized even before the values are compared, leading to a
+                    // noticeable slow down.
+                    panic!(r#"assertion failed: `(left != right)`
+  left: `{:?}`,
+ right: `{:?}`"#, &*left_val, &*right_val)
+                }
+            }
+        }
+    });
+    ($left:expr, $right:expr,) => {
+        $crate::assert_ne!($left, $right)
+    };
+    ($left:expr, $right:expr, $($arg:tt)+) => ({
+        match (&($left), &($right)) {
+            (left_val, right_val) => {
+                if *left_val == *right_val {
+                    // The reborrows below are intentional. Without them, the stack slot for the
+                    // borrow is initialized even before the values are compared, leading to a
+                    // noticeable slow down.
+                    panic!(r#"assertion failed: `(left != right)`
+  left: `{:?}`,
+ right: `{:?}`: {}"#, &*left_val, &*right_val,
+                           $crate::format_args!($($arg)+))
+                }
+            }
+        }
+    });
+}
+
+/// Asserts that a boolean expression is `true` at runtime.
+///
+/// This will invoke the [`panic!`] macro if the provided expression cannot be
+/// evaluated to `true` at runtime.
+///
+/// Like [`assert!`], this macro also has a second version, where a custom panic
+/// message can be provided.
+///
+/// # Uses
+///
+/// Unlike [`assert!`], `debug_assert!` statements are only enabled in non
+/// optimized builds by default. An optimized build will not execute
+/// `debug_assert!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development. The result of expanding `debug_assert!` is always type checked.
+///
+/// An unchecked assertion allows a program in an inconsistent state to keep
+/// running, which might have unexpected consequences but does not introduce
+/// unsafety as long as this only happens in safe code. The performance cost
+/// of assertions, is however, not measurable in general. Replacing [`assert!`]
+/// with `debug_assert!` is thus only encouraged after thorough profiling, and
+/// more importantly, only in safe code!
+///
+/// [`panic!`]: macro.panic.html
+/// [`assert!`]: macro.assert.html
+///
+/// # Examples
+///
+/// ```
+/// // the panic message for these assertions is the stringified value of the
+/// // expression given.
+/// debug_assert!(true);
+///
+/// fn some_expensive_computation() -> bool { true } // a very simple function
+/// debug_assert!(some_expensive_computation());
+///
+/// // assert with a custom message
+/// let x = true;
+/// debug_assert!(x, "x wasn't true!");
+///
+/// let a = 3; let b = 27;
+/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+macro_rules! debug_assert {
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert!($($arg)*); })
+}
+
+/// Asserts that two expressions are equal to each other.
+///
+/// On panic, this macro will print the values of the expressions with their
+/// debug representations.
+///
+/// Unlike [`assert_eq!`], `debug_assert_eq!` statements are only enabled in non
+/// optimized builds by default. An optimized build will not execute
+/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert_eq!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development. The result of expanding `debug_assert_eq!` is always type checked.
+///
+/// [`assert_eq!`]: ../std/macro.assert_eq.html
+///
+/// # Examples
+///
+/// ```
+/// let a = 3;
+/// let b = 1 + 2;
+/// debug_assert_eq!(a, b);
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+macro_rules! debug_assert_eq {
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_eq!($($arg)*); })
+}
+
+/// Asserts that two expressions are not equal to each other.
+///
+/// On panic, this macro will print the values of the expressions with their
+/// debug representations.
+///
+/// Unlike [`assert_ne!`], `debug_assert_ne!` statements are only enabled in non
+/// optimized builds by default. An optimized build will not execute
+/// `debug_assert_ne!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert_ne!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development. The result of expanding `debug_assert_ne!` is always type checked.
+///
+/// [`assert_ne!`]: ../std/macro.assert_ne.html
+///
+/// # Examples
+///
+/// ```
+/// let a = 3;
+/// let b = 2;
+/// debug_assert_ne!(a, b);
+/// ```
+#[macro_export]
+#[stable(feature = "assert_ne", since = "1.13.0")]
+macro_rules! debug_assert_ne {
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
+}
+
+/// Returns whether the given expression matches any of the given patterns.
+///
+/// Like in a `match` expression, the pattern can be optionally followed by `if`
+/// and a guard expression that has access to names bound by the pattern.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(matches_macro)]
+///
+/// let foo = 'f';
+/// assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
+///
+/// let bar = Some(4);
+/// assert!(matches!(bar, Some(x) if x > 2));
+/// ```
+#[macro_export]
+#[unstable(feature = "matches_macro", issue = "65721")]
+macro_rules! matches {
+    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => {
+        match $expression {
+            $( $pattern )|+ $( if $guard )? => true,
+            _ => false
+        }
+    }
+}
+
+/// Unwraps a result or propagates its error.
+///
+/// The `?` operator was added to replace `try!` and should be used instead.
+/// Furthermore, `try` is a reserved word in Rust 2018, so if you must use
+/// it, you will need to use the [raw-identifier syntax][ris]: `r#try`.
+///
+/// [ris]: https://doc.rust-lang.org/nightly/rust-by-example/compatibility/raw_identifiers.html
+///
+/// `try!` matches the given [`Result`]. In case of the `Ok` variant, the
+/// expression has the value of the wrapped value.
+///
+/// In case of the `Err` variant, it retrieves the inner error. `try!` then
+/// performs conversion using `From`. This provides automatic conversion
+/// between specialized errors and more general ones. The resulting
+/// error is then immediately returned.
+///
+/// Because of the early return, `try!` can only be used in functions that
+/// return [`Result`].
+///
+/// [`Result`]: ../std/result/enum.Result.html
+///
+/// # Examples
+///
+/// ```
+/// use std::io;
+/// use std::fs::File;
+/// use std::io::prelude::*;
+///
+/// enum MyError {
+///     FileWriteError
+/// }
+///
+/// impl From<io::Error> for MyError {
+///     fn from(e: io::Error) -> MyError {
+///         MyError::FileWriteError
+///     }
+/// }
+///
+/// // The preferred method of quick returning Errors
+/// fn write_to_file_question() -> Result<(), MyError> {
+///     let mut file = File::create("my_best_friends.txt")?;
+///     file.write_all(b"This is a list of my best friends.")?;
+///     Ok(())
+/// }
+///
+/// // The previous method of quick returning Errors
+/// fn write_to_file_using_try() -> Result<(), MyError> {
+///     let mut file = r#try!(File::create("my_best_friends.txt"));
+///     r#try!(file.write_all(b"This is a list of my best friends."));
+///     Ok(())
+/// }
+///
+/// // This is equivalent to:
+/// fn write_to_file_using_match() -> Result<(), MyError> {
+///     let mut file = r#try!(File::create("my_best_friends.txt"));
+///     match file.write_all(b"This is a list of my best friends.") {
+///         Ok(v) => v,
+///         Err(e) => return Err(From::from(e)),
+///     }
+///     Ok(())
+/// }
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_deprecated(since = "1.39.0", reason = "use the `?` operator instead")]
+#[doc(alias = "?")]
+macro_rules! r#try {
+    ($expr:expr) => (match $expr {
+        $crate::result::Result::Ok(val) => val,
+        $crate::result::Result::Err(err) => {
+            return $crate::result::Result::Err($crate::convert::From::from(err))
+        }
+    });
+    ($expr:expr,) => ($crate::r#try!($expr));
+}
+
+/// Writes formatted data into a buffer.
+///
+/// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be
+/// formatted according to the specified format string and the result will be passed to the writer.
+/// The writer may be any value with a `write_fmt` method; generally this comes from an
+/// implementation of either the [`std::fmt::Write`] or the [`std::io::Write`] trait. The macro
+/// returns whatever the `write_fmt` method returns; commonly a [`std::fmt::Result`], or an
+/// [`io::Result`].
+///
+/// See [`std::fmt`] for more information on the format string syntax.
+///
+/// [`std::fmt`]: ../std/fmt/index.html
+/// [`std::fmt::Write`]: ../std/fmt/trait.Write.html
+/// [`std::io::Write`]: ../std/io/trait.Write.html
+/// [`std::fmt::Result`]: ../std/fmt/type.Result.html
+/// [`io::Result`]: ../std/io/type.Result.html
+///
+/// # Examples
+///
+/// ```
+/// use std::io::Write;
+///
+/// fn main() -> std::io::Result<()> {
+///     let mut w = Vec::new();
+///     write!(&mut w, "test")?;
+///     write!(&mut w, "formatted {}", "arguments")?;
+///
+///     assert_eq!(w, b"testformatted arguments");
+///     Ok(())
+/// }
+/// ```
+///
+/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
+/// implementing either, as objects do not typically implement both. However, the module must
+/// import the traits qualified so their names do not conflict:
+///
+/// ```
+/// use std::fmt::Write as FmtWrite;
+/// use std::io::Write as IoWrite;
+///
+/// fn main() -> Result<(), Box<dyn std::error::Error>> {
+///     let mut s = String::new();
+///     let mut v = Vec::new();
+///
+///     write!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt
+///     write!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt
+///     assert_eq!(v, b"s = \"abc 123\"");
+///     Ok(())
+/// }
+/// ```
+///
+/// Note: This macro can be used in `no_std` setups as well.
+/// In a `no_std` setup you are responsible for the implementation details of the components.
+///
+/// ```no_run
+/// # extern crate core;
+/// use core::fmt::Write;
+///
+/// struct Example;
+///
+/// impl Write for Example {
+///     fn write_str(&mut self, _s: &str) -> core::fmt::Result {
+///          unimplemented!();
+///     }
+/// }
+///
+/// let mut m = Example{};
+/// write!(&mut m, "Hello World").expect("Not written");
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+macro_rules! write {
+    ($dst:expr, $($arg:tt)*) => ($dst.write_fmt($crate::format_args!($($arg)*)))
+}
+
+/// Write formatted data into a buffer, with a newline appended.
+///
+/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
+/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
+///
+/// For more information, see [`write!`]. For information on the format string syntax, see
+/// [`std::fmt`].
+///
+/// [`write!`]: macro.write.html
+/// [`std::fmt`]: ../std/fmt/index.html
+///
+///
+/// # Examples
+///
+/// ```
+/// use std::io::{Write, Result};
+///
+/// fn main() -> Result<()> {
+///     let mut w = Vec::new();
+///     writeln!(&mut w)?;
+///     writeln!(&mut w, "test")?;
+///     writeln!(&mut w, "formatted {}", "arguments")?;
+///
+///     assert_eq!(&w[..], "\ntest\nformatted arguments\n".as_bytes());
+///     Ok(())
+/// }
+/// ```
+///
+/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
+/// implementing either, as objects do not typically implement both. However, the module must
+/// import the traits qualified so their names do not conflict:
+///
+/// ```
+/// use std::fmt::Write as FmtWrite;
+/// use std::io::Write as IoWrite;
+///
+/// fn main() -> Result<(), Box<dyn std::error::Error>> {
+///     let mut s = String::new();
+///     let mut v = Vec::new();
+///
+///     writeln!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt
+///     writeln!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt
+///     assert_eq!(v, b"s = \"abc 123\\n\"\n");
+///     Ok(())
+/// }
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow_internal_unstable(format_args_nl)]
+macro_rules! writeln {
+    ($dst:expr) => (
+        $crate::write!($dst, "\n")
+    );
+    ($dst:expr,) => (
+        $crate::writeln!($dst)
+    );
+    ($dst:expr, $($arg:tt)*) => (
+        $dst.write_fmt($crate::format_args_nl!($($arg)*))
+    );
+}
+
+/// Indicates unreachable code.
+///
+/// This is useful any time that the compiler can't determine that some code is unreachable. For
+/// example:
+///
+/// * Match arms with guard conditions.
+/// * Loops that dynamically terminate.
+/// * Iterators that dynamically terminate.
+///
+/// If the determination that the code is unreachable proves incorrect, the
+/// program immediately terminates with a [`panic!`].
+///
+/// The unsafe counterpart of this macro is the [`unreachable_unchecked`] function, which
+/// will cause undefined behavior if the code is reached.
+///
+/// [`panic!`]: ../std/macro.panic.html
+/// [`unreachable_unchecked`]: ../std/hint/fn.unreachable_unchecked.html
+/// [`std::hint`]: ../std/hint/index.html
+///
+/// # Panics
+///
+/// This will always [`panic!`]
+///
+/// [`panic!`]: ../std/macro.panic.html
+///
+/// # Examples
+///
+/// Match arms:
+///
+/// ```
+/// # #[allow(dead_code)]
+/// fn foo(x: Option<i32>) {
+///     match x {
+///         Some(n) if n >= 0 => println!("Some(Non-negative)"),
+///         Some(n) if n <  0 => println!("Some(Negative)"),
+///         Some(_)           => unreachable!(), // compile error if commented out
+///         None              => println!("None")
+///     }
+/// }
+/// ```
+///
+/// Iterators:
+///
+/// ```
+/// # #[allow(dead_code)]
+/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
+///     for i in 0.. {
+///         if 3*i < i { panic!("u32 overflow"); }
+///         if x < 3*i { return i-1; }
+///     }
+///     unreachable!();
+/// }
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+macro_rules! unreachable {
+    () => ({
+        panic!("internal error: entered unreachable code")
+    });
+    ($msg:expr) => ({
+        $crate::unreachable!("{}", $msg)
+    });
+    ($msg:expr,) => ({
+        $crate::unreachable!($msg)
+    });
+    ($fmt:expr, $($arg:tt)*) => ({
+        panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
+    });
+}
+
+/// Indicates unfinished code by panicking with a message of "not yet implemented".
+///
+/// This allows the your code to type-check, which is useful if you are prototyping or
+/// implementing a trait that requires multiple methods which you don't plan of using all of.
+///
+/// There is no difference between `unimplemented!` and `todo!` apart from the
+/// name.
+///
+/// # Panics
+///
+/// This will always [panic!](macro.panic.html) because `unimplemented!` is just a
+/// shorthand for `panic!` with a fixed, specific message.
+///
+/// Like `panic!`, this macro has a second form for displaying custom values.
+///
+/// # Examples
+///
+/// Here's an example of some in-progress code. We have a trait `Foo`:
+///
+/// ```
+/// trait Foo {
+///     fn bar(&self) -> u8;
+///     fn baz(&self);
+///     fn qux(&self) -> Result<u64, ()>;
+/// }
+/// ```
+///
+/// We want to implement `Foo` for 'MyStruct', but so far we only know how to
+/// implement the `bar()` function. `baz()` and `qux()` will still need to be defined
+/// in our implementation of `Foo`, but we can use `unimplemented!` in their definitions
+/// to allow our code to compile.
+///
+/// In the meantime, we want to have our program stop running once these
+/// unimplemented functions are reached.
+///
+/// ```
+/// # trait Foo {
+/// #     fn bar(&self) -> u8;
+/// #     fn baz(&self);
+/// #     fn qux(&self) -> Result<u64, ()>;
+/// # }
+/// struct MyStruct;
+///
+/// impl Foo for MyStruct {
+///     fn bar(&self) -> u8 {
+///         1 + 1
+///     }
+///
+///     fn baz(&self) {
+///         // We aren't sure how to even start writing baz yet,
+///         // so we have no logic here at all.
+///         // This will display "thread 'main' panicked at 'not yet implemented'".
+///         unimplemented!();
+///     }
+///
+///     fn qux(&self) -> Result<u64, ()> {
+///         let n = self.bar();
+///         // We have some logic here,
+///         // so we can use unimplemented! to display what we have so far.
+///         // This will display:
+///         // "thread 'main' panicked at 'not yet implemented: we need to divide by 2'".
+///         unimplemented!("we need to divide by {}", n);
+///     }
+/// }
+///
+/// fn main() {
+///     let s = MyStruct;
+///     s.bar();
+/// }
+/// ```
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+macro_rules! unimplemented {
+    () => (panic!("not yet implemented"));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
+}
+
+/// Indicates unfinished code.
+///
+/// This can be useful if you are prototyping and are just looking to have your
+/// code typecheck.
+///
+/// There is no difference between `unimplemented!` and `todo!` apart from the
+/// name.
+///
+/// # Panics
+///
+/// This will always [panic!](macro.panic.html)
+///
+/// # Examples
+///
+/// Here's an example of some in-progress code. We have a trait `Foo`:
+///
+/// ```
+/// trait Foo {
+///     fn bar(&self);
+///     fn baz(&self);
+/// }
+/// ```
+///
+/// We want to implement `Foo` on one of our types, but we also want to work on
+/// just `bar()` first. In order for our code to compile, we need to implement
+/// `baz()`, so we can use `todo!`:
+///
+/// ```
+/// # trait Foo {
+/// #     fn bar(&self);
+/// #     fn baz(&self);
+/// # }
+/// struct MyStruct;
+///
+/// impl Foo for MyStruct {
+///     fn bar(&self) {
+///         // implementation goes here
+///     }
+///
+///     fn baz(&self) {
+///         // let's not worry about implementing baz() for now
+///         todo!();
+///     }
+/// }
+///
+/// fn main() {
+///     let s = MyStruct;
+///     s.bar();
+///
+///     // we aren't even using baz() yet, so this is fine.
+/// }
+/// ```
+#[macro_export]
+#[stable(feature = "todo_macro", since = "1.39.0")]
+macro_rules! todo {
+    () => (panic!("not yet implemented"));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
+}
+
+/// Definitions of built-in macros.
+///
+/// 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.
+pub(crate) mod builtin {
+
+    /// Causes compilation to fail with the given error message when encountered.
+    ///
+    /// This macro should be used when a crate uses a conditional compilation strategy to provide
+    /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
+    /// but emits an error during *compilation* rather than at *runtime*.
+    ///
+    /// # Examples
+    ///
+    /// Two such examples are macros and `#[cfg]` environments.
+    ///
+    /// Emit better compiler error if a macro is passed invalid values. Without the final branch,
+    /// the compiler would still emit an error, but the error's message would not mention the two
+    /// valid values.
+    ///
+    /// ```compile_fail
+    /// macro_rules! give_me_foo_or_bar {
+    ///     (foo) => {};
+    ///     (bar) => {};
+    ///     ($x:ident) => {
+    ///         compile_error!("This macro only accepts `foo` or `bar`");
+    ///     }
+    /// }
+    ///
+    /// give_me_foo_or_bar!(neither);
+    /// // ^ will fail at compile time with message "This macro only accepts `foo` or `bar`"
+    /// ```
+    ///
+    /// Emit compiler error if one of a number of features isn't available.
+    ///
+    /// ```compile_fail
+    /// #[cfg(not(any(feature = "foo", feature = "bar")))]
+    /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.");
+    /// ```
+    ///
+    /// [`panic!`]: ../std/macro.panic.html
+    #[stable(feature = "compile_error_macro", since = "1.20.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! compile_error {
+        ($msg:expr) => ({ /* compiler built-in */ });
+        ($msg:expr,) => ({ /* compiler built-in */ })
+    }
+
+    /// Constructs parameters for the other string-formatting macros.
+    ///
+    /// This macro functions by taking a formatting string literal containing
+    /// `{}` for each additional argument passed. `format_args!` prepares the
+    /// additional parameters to ensure the output can be interpreted as a string
+    /// and canonicalizes the arguments into a single type. Any value that implements
+    /// the [`Display`] trait can be passed to `format_args!`, as can any
+    /// [`Debug`] implementation be passed to a `{:?}` within the formatting string.
+    ///
+    /// This macro produces a value of type [`fmt::Arguments`]. This value can be
+    /// passed to the macros within [`std::fmt`] for performing useful redirection.
+    /// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
+    /// proxied through this one. `format_args!`, unlike its derived macros, avoids
+    /// heap allocations.
+    ///
+    /// You can use the [`fmt::Arguments`] value that `format_args!` returns
+    /// in `Debug` and `Display` contexts as seen below. The example also shows
+    /// that `Debug` and `Display` format to the same thing: the interpolated
+    /// format string in `format_args!`.
+    ///
+    /// ```rust
+    /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
+    /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
+    /// assert_eq!("1 foo 2", display);
+    /// assert_eq!(display, debug);
+    /// ```
+    ///
+    /// For more information, see the documentation in [`std::fmt`].
+    ///
+    /// [`Display`]: ../std/fmt/trait.Display.html
+    /// [`Debug`]: ../std/fmt/trait.Debug.html
+    /// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html
+    /// [`std::fmt`]: ../std/fmt/index.html
+    /// [`format!`]: ../std/macro.format.html
+    /// [`write!`]: ../std/macro.write.html
+    /// [`println!`]: ../std/macro.println.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fmt;
+    ///
+    /// let s = fmt::format(format_args!("hello {}", "world"));
+    /// assert_eq!(s, format!("hello {}", "world"));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow_internal_unstable(fmt_internals)]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! 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]
+    #[macro_export]
+    macro_rules! format_args_nl {
+        ($fmt:expr) => ({ /* compiler built-in */ });
+        ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
+    }
+
+    /// Inspects an environment variable at compile time.
+    ///
+    /// This macro will expand to the value of the named environment variable at
+    /// compile time, yielding an expression of type `&'static str`.
+    ///
+    /// If the environment variable is not defined, then a compilation error
+    /// will be emitted. To not emit a compile error, use the [`option_env!`]
+    /// macro instead.
+    ///
+    /// [`option_env!`]: ../std/macro.option_env.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let path: &'static str = env!("PATH");
+    /// println!("the $PATH variable at the time of compiling was: {}", path);
+    /// ```
+    ///
+    /// You can customize the error message by passing a string as the second
+    /// parameter:
+    ///
+    /// ```compile_fail
+    /// let doc: &'static str = env!("documentation", "what's that?!");
+    /// ```
+    ///
+    /// If the `documentation` environment variable is not defined, you'll get
+    /// the following error:
+    ///
+    /// ```text
+    /// error: what's that?!
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! env {
+        ($name:expr) => ({ /* compiler built-in */ });
+        ($name:expr,) => ({ /* compiler built-in */ })
+    }
+
+    /// Optionally inspects an environment variable at compile time.
+    ///
+    /// If the named environment variable is present at compile time, this will
+    /// expand into an expression of type `Option<&'static str>` whose value is
+    /// `Some` of the value of the environment variable. If the environment
+    /// variable is not present, then this will expand to `None`. See
+    /// [`Option<T>`][option] for more information on this type.
+    ///
+    /// A compile time error is never emitted when using this macro regardless
+    /// of whether the environment variable is present or not.
+    ///
+    /// [option]: ../std/option/enum.Option.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
+    /// println!("the secret key might be: {:?}", key);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! option_env {
+        ($name:expr) => ({ /* compiler built-in */ });
+        ($name:expr,) => ({ /* compiler built-in */ })
+    }
+
+    /// Concatenates identifiers into one identifier.
+    ///
+    /// This macro takes any number of comma-separated identifiers, and
+    /// concatenates them all into one, yielding an expression which is a new
+    /// identifier. Note that hygiene makes it such that this macro cannot
+    /// capture local variables. Also, as a general rule, macros are only
+    /// allowed in item, statement or expression position. That means while
+    /// you may use this macro for referring to existing variables, functions or
+    /// modules etc, you cannot define a new one with it.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(concat_idents)]
+    ///
+    /// # fn main() {
+    /// fn foobar() -> u32 { 23 }
+    ///
+    /// let f = concat_idents!(foo, bar);
+    /// println!("{}", f());
+    ///
+    /// // fn concat_idents!(new, fun, name) { } // not usable in this way!
+    /// # }
+    /// ```
+    #[unstable(feature = "concat_idents", issue = "29599",
+               reason = "`concat_idents` is not stable enough for use and is subject to change")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! concat_idents {
+        ($($e:ident),+) => ({ /* compiler built-in */ });
+        ($($e:ident,)+) => ({ /* compiler built-in */ })
+    }
+
+    /// Concatenates literals into a static string slice.
+    ///
+    /// This macro takes any number of comma-separated literals, yielding an
+    /// expression of type `&'static str` which represents all of the literals
+    /// concatenated left-to-right.
+    ///
+    /// Integer and floating point literals are stringified in order to be
+    /// concatenated.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = concat!("test", 10, 'b', true);
+    /// assert_eq!(s, "test10btrue");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! concat {
+        ($($e:expr),*) => ({ /* compiler built-in */ });
+        ($($e:expr,)*) => ({ /* compiler built-in */ })
+    }
+
+    /// Expands to the line number on which it was invoked.
+    ///
+    /// With [`column!`] and [`file!`], these macros provide debugging information for
+    /// developers about the location within the source.
+    ///
+    /// The expanded expression has type `u32` and is 1-based, so the first line
+    /// in each file evaluates to 1, the second to 2, etc. This is consistent
+    /// with error messages by common compilers or popular editors.
+    /// The returned line is *not necessarily* the line of the `line!` invocation itself,
+    /// but rather the first macro invocation leading up to the invocation
+    /// of the `line!` macro.
+    ///
+    /// [`column!`]: macro.column.html
+    /// [`file!`]: macro.file.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let current_line = line!();
+    /// println!("defined on line: {}", current_line);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! line { () => { /* compiler built-in */ } }
+
+    /// Expands to the column number at which it was invoked.
+    ///
+    /// With [`line!`] and [`file!`], these macros provide debugging information for
+    /// developers about the location within the source.
+    ///
+    /// The expanded expression has type `u32` and is 1-based, so the first column
+    /// in each line evaluates to 1, the second to 2, etc. This is consistent
+    /// with error messages by common compilers or popular editors.
+    /// The returned column is *not necessarily* the line of the `column!` invocation itself,
+    /// but rather the first macro invocation leading up to the invocation
+    /// of the `column!` macro.
+    ///
+    /// [`line!`]: macro.line.html
+    /// [`file!`]: macro.file.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let current_col = column!();
+    /// println!("defined on column: {}", current_col);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! column { () => { /* compiler built-in */ } }
+
+    /// Expands to the file name in which it was invoked.
+    ///
+    /// With [`line!`] and [`column!`], these macros provide debugging information for
+    /// developers about the location within the source.
+    ///
+    ///
+    /// The expanded expression has type `&'static str`, and the returned file
+    /// is not the invocation of the `file!` macro itself, but rather the
+    /// first macro invocation leading up to the invocation of the `file!`
+    /// macro.
+    ///
+    /// [`line!`]: macro.line.html
+    /// [`column!`]: macro.column.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let this_file = file!();
+    /// println!("defined in file: {}", this_file);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! file { () => { /* compiler built-in */ } }
+
+    /// Stringifies its arguments.
+    ///
+    /// This macro will yield an expression of type `&'static str` which is the
+    /// stringification of all the tokens passed to the macro. No restrictions
+    /// are placed on the syntax of the macro invocation itself.
+    ///
+    /// Note that the expanded results of the input tokens may change in the
+    /// future. You should be careful if you rely on the output.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let one_plus_one = stringify!(1 + 1);
+    /// assert_eq!(one_plus_one, "1 + 1");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! stringify { ($($t:tt)*) => { /* compiler built-in */ } }
+
+    /// Includes a utf8-encoded file as a string.
+    ///
+    /// The file is located relative to the current file. (similarly to how
+    /// modules are found)
+    ///
+    /// This macro will yield an expression of type `&'static str` which is the
+    /// contents of the file.
+    ///
+    /// # Examples
+    ///
+    /// Assume there are two files in the same directory with the following
+    /// contents:
+    ///
+    /// File 'spanish.in':
+    ///
+    /// ```text
+    /// adiós
+    /// ```
+    ///
+    /// File 'main.rs':
+    ///
+    /// ```ignore (cannot-doctest-external-file-dependency)
+    /// fn main() {
+    ///     let my_str = include_str!("spanish.in");
+    ///     assert_eq!(my_str, "adiós\n");
+    ///     print!("{}", my_str);
+    /// }
+    /// ```
+    ///
+    /// Compiling 'main.rs' and running the resulting binary will print "adiós".
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! include_str {
+        ($file:expr) => ({ /* compiler built-in */ });
+        ($file:expr,) => ({ /* compiler built-in */ })
+    }
+
+    /// Includes a file as a reference to a byte array.
+    ///
+    /// The file is located relative to the current file. (similarly to how
+    /// modules are found)
+    ///
+    /// This macro will yield an expression of type `&'static [u8; N]` which is
+    /// the contents of the file.
+    ///
+    /// # Examples
+    ///
+    /// Assume there are two files in the same directory with the following
+    /// contents:
+    ///
+    /// File 'spanish.in':
+    ///
+    /// ```text
+    /// adiós
+    /// ```
+    ///
+    /// File 'main.rs':
+    ///
+    /// ```ignore (cannot-doctest-external-file-dependency)
+    /// fn main() {
+    ///     let bytes = include_bytes!("spanish.in");
+    ///     assert_eq!(bytes, b"adi\xc3\xb3s\n");
+    ///     print!("{}", String::from_utf8_lossy(bytes));
+    /// }
+    /// ```
+    ///
+    /// Compiling 'main.rs' and running the resulting binary will print "adiós".
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! include_bytes {
+        ($file:expr) => ({ /* compiler built-in */ });
+        ($file:expr,) => ({ /* compiler built-in */ })
+    }
+
+    /// Expands to a string that represents the current module path.
+    ///
+    /// The current module path can be thought of as the hierarchy of modules
+    /// leading back up to the crate root. The first component of the path
+    /// returned is the name of the crate currently being compiled.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// mod test {
+    ///     pub fn foo() {
+    ///         assert!(module_path!().ends_with("test"));
+    ///     }
+    /// }
+    ///
+    /// test::foo();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! module_path { () => { /* compiler built-in */ } }
+
+    /// Evaluates boolean combinations of configuration flags at compile-time.
+    ///
+    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
+    /// boolean expression evaluation of configuration flags. This frequently
+    /// leads to less duplicated code.
+    ///
+    /// The syntax given to this macro is the same syntax as the [`cfg`]
+    /// attribute.
+    ///
+    /// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let my_directory = if cfg!(windows) {
+    ///     "windows-specific-directory"
+    /// } else {
+    ///     "unix-directory"
+    /// };
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! cfg { ($($cfg:tt)*) => { /* compiler built-in */ } }
+
+    /// Parses a file as an expression or an item according to the context.
+    ///
+    /// The file is located relative to the current file (similarly to how
+    /// modules are found).
+    ///
+    /// Using this macro is often a bad idea, because if the file is
+    /// parsed as an expression, it is going to be placed in the
+    /// surrounding code unhygienically. This could result in variables
+    /// or functions being different from what the file expected if
+    /// there are variables or functions that have the same name in
+    /// the current file.
+    ///
+    /// # Examples
+    ///
+    /// Assume there are two files in the same directory with the following
+    /// contents:
+    ///
+    /// File 'monkeys.in':
+    ///
+    /// ```ignore (only-for-syntax-highlight)
+    /// ['🙈', '🙊', '🙉']
+    ///     .iter()
+    ///     .cycle()
+    ///     .take(6)
+    ///     .collect::<String>()
+    /// ```
+    ///
+    /// File 'main.rs':
+    ///
+    /// ```ignore (cannot-doctest-external-file-dependency)
+    /// fn main() {
+    ///     let my_string = include!("monkeys.in");
+    ///     assert_eq!("🙈🙊🙉🙈🙊🙉", my_string);
+    ///     println!("{}", my_string);
+    /// }
+    /// ```
+    ///
+    /// Compiling 'main.rs' and running the resulting binary will print
+    /// "🙈🙊🙉🙈🙊🙉".
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! include {
+        ($file:expr) => ({ /* compiler built-in */ });
+        ($file:expr,) => ({ /* compiler built-in */ })
+    }
+
+    /// Asserts that a boolean expression is `true` at runtime.
+    ///
+    /// This will invoke the [`panic!`] macro if the provided expression cannot be
+    /// evaluated to `true` at runtime.
+    ///
+    /// # Uses
+    ///
+    /// Assertions are always checked in both debug and release builds, and cannot
+    /// be disabled. See [`debug_assert!`] for assertions that are not enabled in
+    /// release builds by default.
+    ///
+    /// Unsafe code relies on `assert!` to enforce run-time invariants that, if
+    /// violated could lead to unsafety.
+    ///
+    /// Other use-cases of `assert!` include testing and enforcing run-time
+    /// invariants in safe code (whose violation cannot result in unsafety).
+    ///
+    /// # Custom Messages
+    ///
+    /// This macro has a second form, where a custom panic message can
+    /// be provided with or without arguments for formatting. See [`std::fmt`]
+    /// for syntax for this form.
+    ///
+    /// [`panic!`]: macro.panic.html
+    /// [`debug_assert!`]: macro.debug_assert.html
+    /// [`std::fmt`]: ../std/fmt/index.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// // the panic message for these assertions is the stringified value of the
+    /// // expression given.
+    /// assert!(true);
+    ///
+    /// fn some_computation() -> bool { true } // a very simple function
+    ///
+    /// assert!(some_computation());
+    ///
+    /// // assert with a custom message
+    /// let x = true;
+    /// assert!(x, "x wasn't true!");
+    ///
+    /// let a = 3; let b = 27;
+    /// assert!(a + b == 30, "a = {}, b = {}", a, b);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! assert {
+        ($cond:expr) => ({ /* compiler built-in */ });
+        ($cond:expr,) => ({ /* compiler built-in */ });
+        ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ })
+    }
+
+    /// Inline assembly.
+    ///
+    /// Read the [unstable book] for the usage.
+    ///
+    /// [unstable book]: ../unstable-book/library-features/asm.html
+    #[unstable(feature = "asm", issue = "29722",
+               reason = "inline assembly is not stable enough for use and is subject to change")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! 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]
+    #[macro_export]
+    macro_rules! 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]
+    #[macro_export]
+    macro_rules! 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]
+    #[macro_export]
+    macro_rules! 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")]
+    #[allow_internal_unstable(test, rustc_attrs)]
+    #[rustc_builtin_macro]
+    pub macro test($item:item) { /* compiler built-in */ }
+
+    /// Attribute macro applied to a function to turn it into a benchmark test.
+    #[unstable(soft, feature = "test", issue = "50297",
+               reason = "`bench` is a part of custom test frameworks which are unstable")]
+    #[allow_internal_unstable(test, rustc_attrs)]
+    #[rustc_builtin_macro]
+    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")]
+    #[allow_internal_unstable(test, rustc_attrs)]
+    #[rustc_builtin_macro]
+    pub macro test_case($item:item) { /* compiler built-in */ }
+
+    /// Attribute macro applied to a static to register it as a global allocator.
+    #[stable(feature = "global_allocator", since = "1.28.0")]
+    #[allow_internal_unstable(rustc_attrs)]
+    #[rustc_builtin_macro]
+    pub macro global_allocator($item:item) { /* compiler built-in */ }
+
+    /// Unstable implementation detail of the `rustc` compiler, do not use.
+    #[rustc_builtin_macro]
+    #[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]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow_internal_unstable(core_intrinsics)]
+    pub macro RustcEncodable($item:item) { /* compiler built-in */ }
+}
diff --git a/src/libcore/macros/panic.md b/src/libcore/macros/panic.md
new file mode 100644 (file)
index 0000000..3ecfc43
--- /dev/null
@@ -0,0 +1,47 @@
+Panics the current thread.
+
+This allows a program to terminate immediately and provide feedback
+to the caller of the program. `panic!` should be used when a program reaches
+an unrecoverable state.
+
+This macro is the perfect way to assert conditions in example code and in
+tests. `panic!` is closely tied with the `unwrap` method of both [`Option`]
+and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set
+to None or Err variants.
+
+This macro is used to inject panic into a Rust thread, causing the thread to
+panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
+and the single-argument form of the `panic!` macro will be the value which
+is transmitted.
+
+[`Result`] enum is often a better solution for recovering from errors than
+using the `panic!` macro. This macro should be used to avoid proceeding using
+incorrect values, such as from external sources. Detailed information about
+error handling is found in the [book].
+
+The multi-argument form of this macro panics with a string and has the
+[`format!`] syntax for building a string.
+
+See also the macro [`compile_error!`], for raising errors during compilation.
+
+[runwrap]: ../std/result/enum.Result.html#method.unwrap
+[`Option`]: ../std/option/enum.Option.html#method.unwrap
+[`Result`]: ../std/result/enum.Result.html
+[`format!`]: ../std/macro.format.html
+[`compile_error!`]: ../std/macro.compile_error.html
+[book]: ../book/ch09-00-error-handling.html
+
+# Current implementation
+
+If the main thread panics it will terminate all your threads and end your
+program with code `101`.
+
+# Examples
+
+```should_panic
+# #![allow(unreachable_code)]
+panic!();
+panic!("this is a terrible mistake!");
+panic!(4); // panic with the value of 4 to be collected elsewhere
+panic!("this is a {} {message}", "fancy", message = "message");
+```
index 5f345c2133f6b5c2313f3c7c99fcc65907a443f5..d97a7a8a87d8d20ae244cc0585d9614e6bd6218f 100644 (file)
     if #[cfg(miri)] {
         #[path = "miri.rs"]
         mod imp;
-        // On MSVC we need the SEH lang items as well...
-        // This should match the conditions of the `seh.rs` import below.
-        #[cfg(all(target_env = "msvc", not(target_arch = "aarch64")))]
-        #[allow(unused)]
-        mod seh;
     } else if #[cfg(target_os = "emscripten")] {
         #[path = "emcc.rs"]
         mod imp;
index 254a9383b42236ee616f24e75e040ebaa045969f..f26c42fd4bcbaac9c707b22ff7b50fd961b64e98 100644 (file)
@@ -1,3 +1,5 @@
+#![allow(nonstandard_style)]
+
 use core::any::Any;
 use alloc::boxed::Box;
 
@@ -13,7 +15,6 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
     Box::from_raw(ptr)
 }
 
-
 // This is required by the compiler to exist (e.g., it's a lang item),
 // but is never used by Miri. Therefore, we just use a stub here
 #[lang = "eh_personality"]
@@ -21,3 +22,21 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
 fn rust_eh_personality() {
     unsafe { core::intrinsics::abort() }
 }
+
+// The rest is required on *some* targets to exist (specifically, MSVC targets that use SEH).
+// We just add it on all targets. Copied from `seh.rs`.
+#[repr(C)]
+pub struct _TypeDescriptor {
+    pub pVFTable: *const u8,
+    pub spare: *mut u8,
+    pub name: [u8; 11],
+}
+
+const TYPE_NAME: [u8; 11] = *b"rust_panic\0";
+
+#[cfg_attr(not(test), lang = "eh_catch_typeinfo")]
+static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
+    pVFTable: core::ptr::null(),
+    spare: core::ptr::null_mut(),
+    name: TYPE_NAME,
+};
index 025494e3fd7be01be3cc9734a1f1322654097b40..a1ad11580dbb7f4c73e1c9f13a272518fc69dbd0 100644 (file)
@@ -42,8 +42,6 @@ pub enum NonMacroAttrKind {
     DeriveHelper,
     /// Single-segment custom attribute registered with `#[register_attr]`.
     Registered,
-    /// Single-segment custom attribute registered by a legacy plugin (`register_attribute`).
-    LegacyPluginHelper,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
@@ -330,7 +328,6 @@ pub fn descr(self) -> &'static str {
             NonMacroAttrKind::Tool => "tool attribute",
             NonMacroAttrKind::DeriveHelper => "derive helper attribute",
             NonMacroAttrKind::Registered => "explicitly registered attribute",
-            NonMacroAttrKind::LegacyPluginHelper => "legacy plugin helper attribute",
         }
     }
 
@@ -345,8 +342,7 @@ pub fn article(self) -> &'static str {
     pub fn is_used(self) -> bool {
         match self {
             NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper => true,
-            NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered |
-            NonMacroAttrKind::LegacyPluginHelper => false,
+            NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered  => false,
         }
     }
 }
index ef6a6ae23dc2f8efcd209a6443abfe2e592b1e0d..12f6f66e96b50cc038d380c4ee5791bf6cf8267d 100644 (file)
@@ -1219,7 +1219,7 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
                                     ImplTraitContext::disallowed(),
                                 ),
                                 unsafety: f.unsafety,
-                                abi: this.lower_abi(f.abi),
+                                abi: this.lower_extern(f.ext),
                                 decl: this.lower_fn_decl(&f.decl, None, false, None),
                                 param_names: this.lower_fn_params_to_names(&f.decl),
                             }))
index 4cd42927868d731550f298bbbce6ce4352b821c6..f689e7f96222f18242fdaa6f57baf1732da8ed56 100644 (file)
@@ -735,7 +735,7 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
 
     fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
         hir::ForeignMod {
-            abi: self.lower_abi(fm.abi),
+            abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
             items: fm.items
                 .iter()
                 .map(|x| self.lower_foreign_item(x))
@@ -1283,18 +1283,26 @@ fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
             unsafety: h.unsafety,
             asyncness: self.lower_asyncness(h.asyncness.node),
             constness: h.constness.node,
-            abi: self.lower_abi(h.abi),
+            abi: self.lower_extern(h.ext),
         }
     }
 
-    pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
-        abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
+    pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
+        abi::lookup(&abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
             self.error_on_invalid_abi(abi);
             abi::Abi::Rust
         })
     }
 
-    fn error_on_invalid_abi(&self, abi: Abi) {
+    pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
+        match ext {
+            Extern::None => abi::Abi::Rust,
+            Extern::Implicit => abi::Abi::C,
+            Extern::Explicit(abi) => self.lower_abi(abi),
+        }
+    }
+
+    fn error_on_invalid_abi(&self, abi: StrLit) {
         struct_span_err!(
             self.sess,
             abi.span,
index 4fbc8da9cbf026433f99e33b0172f8f9dab3e8bb..1af20188ab5db64a338e8d88c64c30157ff78873 100644 (file)
 use errors::emitter::HumanReadableErrorType;
 use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter};
 use syntax::edition::Edition;
-use syntax::feature_gate::{self, AttributeType};
+use syntax::feature_gate;
 use errors::json::JsonEmitter;
 use syntax::source_map;
 use syntax::sess::{ParseSess, ProcessCfgMod};
-use syntax::symbol::Symbol;
 use syntax_pos::{MultiSpan, Span};
 
 use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
@@ -79,7 +78,6 @@ pub struct Session {
     /// in order to avoid redundantly verbose output (Issue #24690, #44953).
     pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
     pub plugin_llvm_passes: OneThread<RefCell<Vec<String>>>,
-    pub plugin_attributes: Lock<Vec<(Symbol, AttributeType)>>,
     pub crate_types: Once<Vec<config::CrateType>>,
     /// The `crate_disambiguator` is constructed out of all the `-C metadata`
     /// arguments passed to the compiler. Its value together with the crate-name
@@ -1039,12 +1037,11 @@ pub fn build_session_with_source_map(
 
     let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace;
 
-    let emitter = match diagnostics_output {
-        DiagnosticOutput::Default => default_emitter(&sopts, registry, &source_map, None),
-        DiagnosticOutput::Raw(write) => {
-            default_emitter(&sopts, registry, &source_map, Some(write))
-        }
+    let write_dest = match diagnostics_output {
+        DiagnosticOutput::Default => None,
+        DiagnosticOutput::Raw(write) => Some(write),
     };
+    let emitter = default_emitter(&sopts, registry, &source_map, write_dest);
 
     let diagnostic_handler = errors::Handler::with_emitter_and_flags(
         emitter,
@@ -1166,7 +1163,6 @@ fn build_session_(
         working_dir,
         one_time_diagnostics: Default::default(),
         plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),
-        plugin_attributes: Lock::new(Vec::new()),
         crate_types: Once::new(),
         crate_disambiguator: Once::new(),
         features: Once::new(),
index f1565a2bd0a5f16d514e74bd8e4648d23af58bb2..ff673e52b60c2e786a32306dbb0e50bd4d8dd1af 100644 (file)
@@ -26,6 +26,7 @@ rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the s
 rustc_plugin_impl = { path = "../librustc_plugin" }
 rustc_save_analysis = { path = "../librustc_save_analysis" }
 rustc_codegen_utils = { path = "../librustc_codegen_utils" }
+rustc_error_codes = { path = "../librustc_error_codes" }
 rustc_interface = { path = "../librustc_interface" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc_resolve = { path = "../librustc_resolve" }
index d4f796ee3a7023672667165b72139e9d73a0ddc8..ef638464adce9b8074292899ab2308bdf2462983 100644 (file)
@@ -40,7 +40,7 @@
 use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
 use rustc_metadata::locator;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
-use errors::PResult;
+use errors::{PResult, registry::Registry};
 use rustc_interface::interface;
 use rustc_interface::util::get_codegen_sysroot;
 use rustc_data_structures::sync::SeqCst;
@@ -140,6 +140,10 @@ fn config(&mut self, config: &mut interface::Config) {
     }
 }
 
+pub fn diagnostics_registry() -> Registry {
+    Registry::new(&rustc_error_codes::DIAGNOSTICS)
+}
+
 // Parse args and run the compiler. This is the primary entry point for rustc.
 // See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
@@ -182,13 +186,14 @@ pub fn run_compiler(
             lint_caps: Default::default(),
             register_lints: None,
             override_queries: None,
+            registry: diagnostics_registry(),
         };
         callbacks.config(&mut config);
         config
     };
 
     if let Some(ref code) = matches.opt_str("explain") {
-        handle_explain(code, sopts.error_format);
+        handle_explain(diagnostics_registry(), code, sopts.error_format);
         return Ok(());
     }
 
@@ -261,6 +266,7 @@ pub fn run_compiler(
         lint_caps: Default::default(),
         register_lints: None,
         override_queries: None,
+        registry: diagnostics_registry(),
     };
 
     callbacks.config(&mut config);
@@ -510,15 +516,13 @@ fn stdout_isatty() -> bool {
     }
 }
 
-fn handle_explain(code: &str,
-                  output: ErrorOutputType) {
-    let descriptions = rustc_interface::util::diagnostics_registry();
+fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
     let normalised = if code.starts_with("E") {
         code.to_string()
     } else {
         format!("E{0:0>4}", code)
     };
-    match descriptions.find_description(&normalised) {
+    match registry.find_description(&normalised) {
         Some(ref description) => {
             let mut is_in_code_block = false;
             let mut text = String::new();
index ffefe51f854f5e7fa2bd42828a5abb040ec9dc32..428cecf13a3b01beedea67c5eb77f0f4a70d41dc 100644 (file)
@@ -7,8 +7,7 @@
 // Error messages' format must follow the RFC 1567 available here:
 // https://github.com/rust-lang/rfcs/pull/1567
 
-crate::register_diagnostics! {
-
+register_diagnostics! {
 E0001: include_str!("./error_codes/E0001.md"),
 E0002: include_str!("./error_codes/E0002.md"),
 E0004: include_str!("./error_codes/E0004.md"),
index 36b1518c869b97c330a8e8439b5fb1f273e62e3f..14210fd69ad51b81a7432cdd64118723fb4f9665 100644 (file)
@@ -1,19 +1,14 @@
-//! This library is used to gather all error codes into one place. The goal
-//! being to make their maintenance easier.
+//! This library is used to gather all error codes into one place,
+//! the goal being to make their maintenance easier.
 
-#[macro_export]
 macro_rules! register_diagnostics {
-    ($($ecode:ident: $message:expr,)*) => (
-        $crate::register_diagnostics!{$($ecode:$message,)* ;}
-    );
-
     ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
         pub static DIAGNOSTICS: &[(&str, &str)] = &[
             $( (stringify!($ecode), $message), )*
         ];
 
         $(
-            pub const $ecode: &str = $message;
+            pub const $ecode: () = ();
         )*
         $(
             pub const $code: () = ();
index b16cfe9efa7473869f3e95159b3672420730f806..de59882bbdf957f851818b73de4ea98d2c97962c 100644 (file)
@@ -34,7 +34,6 @@ rustc_errors = { path = "../librustc_errors" }
 rustc_plugin = { path = "../librustc_plugin", package = "rustc_plugin_impl" }
 rustc_privacy = { path = "../librustc_privacy" }
 rustc_resolve = { path = "../librustc_resolve" }
-rustc_error_codes = { path = "../librustc_error_codes" }
 tempfile = "3.0.5"
 once_cell = "1"
 
index fae4eb48c4a1b127aa810d5de5b8aada02057efc..c153de7103ac2cba88a02ba60d1e81c7903ac76d 100644 (file)
@@ -11,6 +11,7 @@
 use rustc_data_structures::OnDrop;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
+use rustc_errors::registry::Registry;
 use rustc_parse::new_parser_from_source_str;
 use rustc::ty;
 use std::path::PathBuf;
@@ -141,12 +142,16 @@ pub struct Config {
     /// The second parameter is local providers and the third parameter is external providers.
     pub override_queries:
         Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)>,
+
+    /// Registry of diagnostics codes.
+    pub registry: Registry,
 }
 
-pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
-where
-    F: FnOnce(&Compiler) -> R,
-{
+pub fn run_compiler_in_existing_thread_pool<R>(
+    config: Config,
+    f: impl FnOnce(&Compiler) -> R,
+) -> R {
+    let registry = &config.registry;
     let (sess, codegen_backend, source_map) = util::create_session(
         config.opts,
         config.crate_cfg,
@@ -154,6 +159,7 @@ pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
         config.file_loader,
         config.input_path.clone(),
         config.lint_caps,
+        registry.clone(),
     );
 
     let compiler = Compiler {
@@ -171,17 +177,13 @@ pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
     };
 
     let _sess_abort_error = OnDrop(|| {
-        compiler.sess.diagnostic().print_error_count(&util::diagnostics_registry());
+        compiler.sess.diagnostic().print_error_count(registry);
     });
 
     f(&compiler)
 }
 
-pub fn run_compiler<F, R>(mut config: Config, f: F) -> R
-where
-    F: FnOnce(&Compiler) -> R + Send,
-    R: Send,
-{
+pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
     let stderr = config.stderr.take();
     util::spawn_thread_pool(
         config.opts.edition,
@@ -191,11 +193,7 @@ pub fn run_compiler<F, R>(mut config: Config, f: F) -> R
     )
 }
 
-pub fn default_thread_pool<F, R>(edition: edition::Edition, f: F) -> R
-where
-    F: FnOnce() -> R + Send,
-    R: Send,
-{
+pub fn default_thread_pool<R: Send>(edition: edition::Edition, f: impl FnOnce() -> R + Send) -> R {
     // the 1 here is duplicating code in config.opts.debugging_opts.threads
     // which also defaults to 1; it ultimately doesn't matter as the default
     // isn't threaded, and just ignores this parameter
index 83b936dd7aa2c6a09115a79d13244e746b830e89..86d58bfe8bdac2c7ddadb40bc83187911bb97e00 100644 (file)
@@ -240,15 +240,8 @@ pub fn register_plugins<'a>(
         }
     });
 
-    let Registry {
-        syntax_exts,
-        llvm_passes,
-        attributes,
-        ..
-    } = registry;
-
+    let Registry { syntax_exts, llvm_passes, .. } = registry;
     *sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
-    *sess.plugin_attributes.borrow_mut() = attributes;
 
     Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store)))
 }
index a5653a21b31bf3e85d01e87d7b917b7ae283391c..2b4320c04e6e5d3cab8405c76385257bd88319d4 100644 (file)
@@ -15,7 +15,6 @@
 use rustc_errors::registry::Registry;
 use rustc_metadata::dynamic_lib::DynamicLibrary;
 use rustc_resolve::{self, Resolver};
-use rustc_error_codes;
 use std::env;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
 use std::io::{self, Write};
 #[cfg(not(parallel_compiler))]
 use std::{thread, panic};
 
-pub fn diagnostics_registry() -> Registry {
-    let mut all_errors = Vec::new();
-    all_errors.extend_from_slice(&rustc_error_codes::DIAGNOSTICS);
-    // FIXME: need to figure out a way to get these back in here
-    // all_errors.extend_from_slice(get_codegen_backend(sess).diagnostics());
-
-    Registry::new(&all_errors)
-}
-
 /// Adds `target_feature = "..."` cfgs for a variety of platform
 /// specific features (SSE, NEON etc.).
 ///
@@ -77,9 +67,8 @@ pub fn create_session(
     file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
     input_path: Option<PathBuf>,
     lint_caps: FxHashMap<lint::LintId, lint::Level>,
+    descriptions: Registry,
 ) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
-    let descriptions = diagnostics_registry();
-
     let loader = file_loader.unwrap_or(box RealFileLoader);
     let source_map = Lrc::new(SourceMap::with_file_loader(
         loader,
index 642b8e3279d6655b9707475d7e50cd58a510d82d..9f293bdaa105e592c69d3e4be57ce8a721534de8 100644 (file)
@@ -309,29 +309,11 @@ fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
             }
         }
 
-        let plugin_attributes = cx.sess().plugin_attributes.borrow();
-        for &(name, ty) in plugin_attributes.iter() {
-            if ty == AttributeType::Whitelisted && attr.check_name(name) {
-                debug!("{:?} (plugin attr) is whitelisted with ty {:?}", name, ty);
-                break;
-            }
-        }
-
-        let name = attr.name_or_empty();
         if !attr::is_used(attr) {
             debug!("emitting warning for: {:?}", attr);
             cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
             // Is it a builtin attribute that must be used at the crate level?
-            let known_crate = attr_info.map(|&&(_, ty, ..)| {
-                    ty == AttributeType::CrateLevel
-            }).unwrap_or(false);
-
-            // Has a plugin registered this attribute as one that must be used at
-            // the crate level?
-            let plugin_crate = plugin_attributes.iter()
-                .find(|&&(x, t)| name == x && AttributeType::CrateLevel == t)
-                .is_some();
-            if known_crate || plugin_crate {
+            if attr_info.map_or(false, |(_, ty, ..)| ty == &AttributeType::CrateLevel) {
                 let msg = match attr.style {
                     ast::AttrStyle::Outer => {
                         "crate-level attribute should be an inner attribute: add an exclamation \
index 2ede43e2111ed164a5f39422f3eda3f9e7bc3f72..51d0ab7943c75ec3d3a7bc10a6a45c04640b5e51 100644 (file)
@@ -22,7 +22,7 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::vec::IndexVec;
 use rustc::ty::layout::{
-    LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout,
+    LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size,
 };
 
 use crate::rustc::ty::subst::Subst;
@@ -35,6 +35,9 @@
 use crate::const_eval::error_to_const_error;
 use crate::transform::{MirPass, MirSource};
 
+/// The maximum number of bytes that we'll allocate space for a return value.
+const MAX_ALLOC_LIMIT: u64 = 1024;
+
 pub struct ConstProp;
 
 impl<'tcx> MirPass<'tcx> for ConstProp {
@@ -313,8 +316,10 @@ fn new(
             ecx
                 .layout_of(body.return_ty().subst(tcx, substs))
                 .ok()
-                // Don't bother allocating memory for ZST types which have no values.
-                .filter(|ret_layout| !ret_layout.is_zst())
+                // Don't bother allocating memory for ZST types which have no values
+                // or for large values.
+                .filter(|ret_layout| !ret_layout.is_zst() &&
+                                     ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT))
                 .map(|ret_layout| ecx.allocate(ret_layout, MemoryKind::Stack));
 
         ecx.push_stack_frame(
@@ -453,6 +458,11 @@ fn const_prop(
     ) -> Option<()> {
         let span = source_info.span;
 
+        // #66397: Don't try to eval into large places as that can cause an OOM
+        if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) {
+            return None;
+        }
+
         let overflow_check = self.tcx.sess.overflow_checks();
 
         // Perform any special handling for specific Rvalue types.
index dadb91f8b3c16b52db036800022ef9205067cefe..a56a7bf1802c77b8b70f5b1d30324b9b7f335e06 100644 (file)
@@ -778,13 +778,12 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
 
         macro_rules! parse_lit {
             () => {
-                match self.parse_lit() {
-                    Ok(literal) => {
+                match self.parse_opt_lit() {
+                    Some(literal) => {
                         hi = self.prev_span;
                         ex = ExprKind::Lit(literal);
                     }
-                    Err(mut err) => {
-                        err.cancel();
+                    None => {
                         return Err(self.expected_expression_found());
                     }
                 }
@@ -1074,11 +1073,39 @@ macro_rules! parse_lit {
         self.maybe_recover_from_bad_qpath(expr, true)
     }
 
-    /// Matches `lit = true | false | token_lit`.
+    /// Returns a string literal if the next token is a string literal.
+    /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
+    /// and returns `None` if the next token is not literal at all.
+    pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<Lit>> {
+        match self.parse_opt_lit() {
+            Some(lit) => match lit.kind {
+                ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit {
+                    style,
+                    symbol: lit.token.symbol,
+                    suffix: lit.token.suffix,
+                    span: lit.span,
+                    symbol_unescaped,
+                }),
+                _ => Err(Some(lit)),
+            }
+            None => Err(None),
+        }
+    }
+
     pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
+        self.parse_opt_lit().ok_or_else(|| {
+            let msg = format!("unexpected token: {}", self.this_token_descr());
+            self.span_fatal(self.token.span, &msg)
+        })
+    }
+
+    /// Matches `lit = true | false | token_lit`.
+    /// Returns `None` if the next token is not a literal.
+    pub(super) fn parse_opt_lit(&mut self) -> Option<Lit> {
         let mut recovered = None;
         if self.token == token::Dot {
-            // Attempt to recover `.4` as `0.4`.
+            // Attempt to recover `.4` as `0.4`. We don't currently have any syntax where
+            // dot would follow an optional literal, so we do this unconditionally.
             recovered = self.look_ahead(1, |next_token| {
                 if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
                         = next_token.kind {
@@ -1107,11 +1134,10 @@ pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
         match Lit::from_token(token) {
             Ok(lit) => {
                 self.bump();
-                Ok(lit)
+                Some(lit)
             }
             Err(LitError::NotLiteral) => {
-                let msg = format!("unexpected token: {}", self.this_token_descr());
-                Err(self.span_fatal(token.span, &msg))
+                None
             }
             Err(err) => {
                 let span = token.span;
@@ -1120,18 +1146,18 @@ pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
                     _ => unreachable!(),
                 };
                 self.bump();
-                self.error_literal_from_token(err, lit, span);
+                self.report_lit_error(err, lit, span);
                 // Pack possible quotes and prefixes from the original literal into
                 // the error literal's symbol so they can be pretty-printed faithfully.
                 let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
                 let symbol = Symbol::intern(&suffixless_lit.to_string());
                 let lit = token::Lit::new(token::Err, symbol, lit.suffix);
-                Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
+                Some(Lit::from_lit_token(lit, span).unwrap_or_else(|_| unreachable!()))
             }
         }
     }
 
-    fn error_literal_from_token(&self, err: LitError, lit: token::Lit, span: Span) {
+    fn report_lit_error(&self, err: LitError, lit: token::Lit, span: Span) {
         // Checks if `s` looks like i32 or u1234 etc.
         fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
             s.len() > 1
index 730991698798958af3478f31cd7400a14e3b8643..20b96d5cd62f6a6060fd7303526afe1d8ff1c31b 100644 (file)
@@ -3,9 +3,9 @@
 
 use crate::maybe_whole;
 
-use syntax::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
+use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
 use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
-use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
+use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
 use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
 use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField};
 use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
@@ -105,7 +105,7 @@ fn parse_item_implementation(
                 return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?));
             }
 
-            let abi = self.parse_opt_abi()?;
+            let abi = self.parse_abi();
 
             if self.eat_keyword(kw::Fn) {
                 // EXTERN FUNCTION ITEM
@@ -114,7 +114,7 @@ fn parse_item_implementation(
                     unsafety: Unsafety::Normal,
                     asyncness: respan(fn_span, IsAsync::NotAsync),
                     constness: respan(fn_span, Constness::NotConst),
-                    abi,
+                    ext: Extern::from_abi(abi),
                 };
                 return self.parse_item_fn(lo, vis, attrs, header);
             } else if self.check(&token::OpenDelim(token::Brace)) {
@@ -143,14 +143,14 @@ fn parse_item_implementation(
                 if self.check_keyword(kw::Extern) {
                     self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span));
                 }
-                let abi = self.parse_extern_abi()?;
+                let ext = self.parse_extern()?;
                 self.bump(); // `fn`
 
                 let header = FnHeader {
                     unsafety,
                     asyncness: respan(const_span, IsAsync::NotAsync),
                     constness: respan(const_span, Constness::Const),
-                    abi,
+                    ext,
                 };
                 return self.parse_item_fn(lo, vis, attrs, header);
             }
@@ -193,7 +193,7 @@ fn parse_item_implementation(
                     unsafety,
                     asyncness,
                     constness: respan(fn_span, Constness::NotConst),
-                    abi: Abi::new(sym::Rust, fn_span),
+                    ext: Extern::None,
                 };
                 return self.parse_item_fn(lo, vis, attrs, header);
             }
@@ -230,7 +230,7 @@ fn parse_item_implementation(
                 unsafety: Unsafety::Normal,
                 asyncness: respan(fn_span, IsAsync::NotAsync),
                 constness: respan(fn_span, Constness::NotConst),
-                abi: Abi::new(sym::Rust, fn_span),
+                ext: Extern::None,
             };
             return self.parse_item_fn(lo, vis, attrs, header);
         }
@@ -242,14 +242,14 @@ fn parse_item_implementation(
             self.bump(); // `unsafe`
             // `{` is also expected after `unsafe`; in case of error, include it in the diagnostic.
             self.check(&token::OpenDelim(token::Brace));
-            let abi = self.parse_extern_abi()?;
+            let ext = self.parse_extern()?;
             self.expect_keyword(kw::Fn)?;
             let fn_span = self.prev_span;
             let header = FnHeader {
                 unsafety: Unsafety::Unsafe,
                 asyncness: respan(fn_span, IsAsync::NotAsync),
                 constness: respan(fn_span, Constness::NotConst),
-                abi,
+                ext,
             };
             return self.parse_item_fn(lo, vis, attrs, header);
         }
@@ -1100,7 +1100,7 @@ fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
     fn parse_item_foreign_mod(
         &mut self,
         lo: Span,
-        abi: Abi,
+        abi: Option<StrLit>,
         visibility: Visibility,
         mut attrs: Vec<Attribute>,
         extern_sp: Span,
@@ -1775,9 +1775,16 @@ fn parse_item_fn(
         attrs: Vec<Attribute>,
         header: FnHeader,
     ) -> PResult<'a, Option<P<Item>>> {
+        let is_c_abi = match header.ext {
+            ast::Extern::None => false,
+            ast::Extern::Implicit => true,
+            ast::Extern::Explicit(abi) => abi.symbol_unescaped == sym::C,
+        };
         let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
             is_self_allowed: false,
-            allow_c_variadic: header.abi.symbol == sym::C && header.unsafety == Unsafety::Unsafe,
+            // FIXME: Parsing should not depend on ABI or unsafety and
+            // the variadic parameter should always be parsed.
+            allow_c_variadic: is_c_abi && header.unsafety == Unsafety::Unsafe,
             is_name_required: |_| true,
         })?;
         let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
@@ -1905,11 +1912,11 @@ fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
         }
         let asyncness = respan(self.prev_span, asyncness);
         let unsafety = self.parse_unsafety();
-        let (constness, unsafety, abi) = if is_const_fn {
-            (respan(const_span, Constness::Const), unsafety, Abi::default())
+        let (constness, unsafety, ext) = if is_const_fn {
+            (respan(const_span, Constness::Const), unsafety, Extern::None)
         } else {
-            let abi = self.parse_extern_abi()?;
-            (respan(self.prev_span, Constness::NotConst), unsafety, abi)
+            let ext = self.parse_extern()?;
+            (respan(self.prev_span, Constness::NotConst), unsafety, ext)
         };
         if !self.eat_keyword(kw::Fn) {
             // It is possible for `expect_one_of` to recover given the contents of
@@ -1917,7 +1924,7 @@ fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
             // account for this.
             if !self.expect_one_of(&[], &[])? { unreachable!() }
         }
-        Ok(FnHeader { constness, unsafety, asyncness, abi })
+        Ok(FnHeader { constness, unsafety, asyncness, ext })
     }
 
     /// Parse the "signature", including the identifier, parameters, and generics of a function.
index f62f0c9a2682ed1cc8ca6726532bf138512729fa..d5ec46114980659ad45b76ce1ae95ec76b08b710 100644 (file)
@@ -15,8 +15,8 @@
 use crate::lexer::UnmatchedBrace;
 
 use syntax::ast::{
-    self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
-    IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
+    self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, StrLit,
+    IsAsync, MacDelimiter, Mutability, Visibility, VisibilityKind, Unsafety,
 };
 
 use syntax::print::pprust;
@@ -1212,40 +1212,34 @@ fn recover_incorrect_vis_restriction(&mut self) -> PResult<'a, ()> {
     }
 
     /// Parses `extern string_literal?`.
-    /// If `extern` is not found, the Rust ABI is used.
-    /// If `extern` is found and a `string_literal` does not follow, the C ABI is used.
-    fn parse_extern_abi(&mut self) -> PResult<'a, Abi> {
+    fn parse_extern(&mut self) -> PResult<'a, Extern> {
         Ok(if self.eat_keyword(kw::Extern) {
-            self.parse_opt_abi()?
+            Extern::from_abi(self.parse_abi())
         } else {
-            Abi::default()
+            Extern::None
         })
     }
 
     /// Parses a string literal as an ABI spec.
-    /// If one is not found, the "C" ABI is used.
-    fn parse_opt_abi(&mut self) -> PResult<'a, Abi> {
-        let span = if self.token.can_begin_literal_or_bool() {
-            let ast::Lit { span, kind, .. } = self.parse_lit()?;
-            match kind {
-                ast::LitKind::Str(symbol, _) => return Ok(Abi::new(symbol, span)),
-                ast::LitKind::Err(_) => {}
+    fn parse_abi(&mut self) -> Option<StrLit> {
+        match self.parse_str_lit() {
+            Ok(str_lit) => Some(str_lit),
+            Err(Some(lit)) => match lit.kind {
+                ast::LitKind::Err(_) => None,
                 _ => {
-                    self.struct_span_err(span, "non-string ABI literal")
+                    self.struct_span_err(lit.span, "non-string ABI literal")
                         .span_suggestion(
-                            span,
+                            lit.span,
                             "specify the ABI with a string literal",
                             "\"C\"".to_string(),
                             Applicability::MaybeIncorrect,
                         )
                         .emit();
+                    None
                 }
             }
-            span
-        } else {
-            self.prev_span
-        };
-        Ok(Abi::new(sym::C, span))
+            Err(None) => None,
+        }
     }
 
     /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
@@ -1337,34 +1331,6 @@ fn is_import_coupler(&mut self) -> bool {
             self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) ||
                                    *t == token::BinOp(token::Star))
     }
-
-    fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
-        let ret = match self.token.kind {
-            token::Literal(token::Lit { kind: token::Str, symbol, suffix }) =>
-                (symbol, ast::StrStyle::Cooked, suffix),
-            token::Literal(token::Lit { kind: token::StrRaw(n), symbol, suffix }) =>
-                (symbol, ast::StrStyle::Raw(n), suffix),
-            _ => return None
-        };
-        self.bump();
-        Some(ret)
-    }
-
-    pub fn parse_str(&mut self) -> PResult<'a, (Symbol, StrStyle)> {
-        match self.parse_optional_str() {
-            Some((s, style, suf)) => {
-                let sp = self.prev_span;
-                self.expect_no_suffix(sp, "a string literal", suf);
-                Ok((s, style))
-            }
-            _ => {
-                let msg = "expected string literal";
-                let mut err = self.fatal(msg);
-                err.span_label(self.token.span, msg);
-                Err(err)
-            }
-        }
-    }
 }
 
 crate fn make_unclosed_delims_error(
index 4c7d10061835980071be1886e8b4b8a61b543677..8e6bc29be521803e02472068d1eb97148690df80 100644 (file)
@@ -287,7 +287,7 @@ fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a,
         */
 
         let unsafety = self.parse_unsafety();
-        let abi = self.parse_extern_abi()?;
+        let ext = self.parse_extern()?;
         self.expect_keyword(kw::Fn)?;
         let cfg = ParamCfg {
             is_self_allowed: false,
@@ -296,7 +296,7 @@ fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a,
         };
         let decl = self.parse_fn_decl(cfg, false)?;
         Ok(TyKind::BareFn(P(BareFnTy {
-            abi,
+            ext,
             unsafety,
             generic_params,
             decl,
index 2aeec029cc334dee7f57da7b60409eb3bf46af95..db661e7f4d2a5f768e2b4009d94f0293a4fa6f65 100644 (file)
@@ -631,7 +631,7 @@ fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) {
 
     fn visit_struct_field(&mut self, field: &'tcx hir::StructField) {
         if self.should_warn_about_field(&field) {
-            self.warn_dead_code(field.hir_id, field.span, field.ident.name, "field", "used");
+            self.warn_dead_code(field.hir_id, field.span, field.ident.name, "field", "read");
         }
         intravisit::walk_struct_field(self, field);
     }
index 3f4b87a97c7736fc59452cec0578c3821e2808fa..aa5ea80f0b0e4caf0e69da050283ccc9bae53ecb 100644 (file)
@@ -7,7 +7,6 @@
 use syntax_expand::base::MacroExpanderFn;
 use syntax::symbol::Symbol;
 use syntax::ast;
-use syntax::feature_gate::AttributeType;
 use syntax_pos::Span;
 
 use std::borrow::ToOwned;
@@ -39,9 +38,6 @@ pub struct Registry<'a> {
 
     #[doc(hidden)]
     pub llvm_passes: Vec<String>,
-
-    #[doc(hidden)]
-    pub attributes: Vec<(Symbol, AttributeType)>,
 }
 
 impl<'a> Registry<'a> {
@@ -54,7 +50,6 @@ pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -
             krate_span,
             syntax_exts: vec![],
             llvm_passes: vec![],
-            attributes: vec![],
         }
     }
 
@@ -98,12 +93,4 @@ pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
     pub fn register_llvm_pass(&mut self, name: &str) {
         self.llvm_passes.push(name.to_owned());
     }
-
-    /// Register an attribute with an attribute type.
-    ///
-    /// `Whitelisted` attributes will additionally not trigger the `unused_attribute`
-    /// lint. `CrateLevel` attributes will not be allowed on anything other than a crate.
-    pub fn register_attribute(&mut self, name: Symbol, ty: AttributeType) {
-        self.attributes.push((name, ty));
-    }
 }
index 1ebe9b5e120f457016ebdbe7f6a6eb5d5d6c430b..e134b8b92ac2e34aefec7af73cccf79a845f3eda 100644 (file)
@@ -368,7 +368,16 @@ fn early_lookup_typo_candidate(
         let mut suggestions = Vec::new();
         self.visit_scopes(scope_set, parent_scope, ident, |this, scope, use_prelude, _| {
             match scope {
-                Scope::DeriveHelpers => {
+                Scope::DeriveHelpers(expn_id) => {
+                    let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
+                    if filter_fn(res) {
+                        suggestions.extend(this.helper_attrs.get(&expn_id)
+                                               .into_iter().flatten().map(|ident| {
+                            TypoSuggestion::from_res(ident.name, res)
+                        }));
+                    }
+                }
+                Scope::DeriveHelpersCompat => {
                     let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
                     if filter_fn(res) {
                         for derive in parent_scope.derives {
@@ -428,15 +437,6 @@ fn early_lookup_typo_candidate(
                         }));
                     }
                 }
-                Scope::LegacyPluginHelpers => {
-                    let res = Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
-                    if filter_fn(res) {
-                        let plugin_attributes = this.session.plugin_attributes.borrow();
-                        suggestions.extend(plugin_attributes.iter().map(|(name, _)| {
-                            TypoSuggestion::from_res(*name, res)
-                        }));
-                    }
-                }
                 Scope::ExternPrelude => {
                     suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
                         let res = Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX));
index 47e8cf80a05bf9dd646332fea5a501daa765122e..8f6bb91f028c3d1d70b8c13bf10eb42e576a8f8a 100644 (file)
@@ -45,7 +45,7 @@
 use syntax::source_map::Spanned;
 use syntax::visit::{self, Visitor};
 use syntax_expand::base::SyntaxExtension;
-use syntax_pos::hygiene::{MacroKind, ExpnId, Transparency, SyntaxContext};
+use syntax_pos::hygiene::{MacroKind, ExpnId, ExpnKind, Transparency, SyntaxContext};
 use syntax_pos::{Span, DUMMY_SP};
 use errors::{Applicability, DiagnosticBuilder};
 
@@ -97,14 +97,14 @@ fn determined(determined: bool) -> Determinacy {
 /// but not for late resolution yet.
 #[derive(Clone, Copy)]
 enum Scope<'a> {
-    DeriveHelpers,
+    DeriveHelpers(ExpnId),
+    DeriveHelpersCompat,
     MacroRules(LegacyScope<'a>),
     CrateRoot,
     Module(Module<'a>),
     RegisteredAttrs,
     MacroUsePrelude,
     BuiltinAttrs,
-    LegacyPluginHelpers,
     ExternPrelude,
     ToolPrelude,
     StdLibPrelude,
@@ -942,6 +942,8 @@ pub struct Resolver<'a> {
     /// Legacy scopes *produced* by expanding the macro invocations,
     /// include all the `macro_rules` items and other invocations generated by them.
     output_legacy_scopes: FxHashMap<ExpnId, LegacyScope<'a>>,
+    /// Helper attributes that are in scope for the given expansion.
+    helper_attrs: FxHashMap<ExpnId, Vec<Ident>>,
 
     /// Avoid duplicated errors for "name already defined".
     name_already_seen: FxHashMap<Name, Span>,
@@ -1219,6 +1221,7 @@ pub fn new(session: &'a Session,
             non_macro_attrs: [non_macro_attr(false), non_macro_attr(true)],
             invocation_parent_scopes,
             output_legacy_scopes: Default::default(),
+            helper_attrs: Default::default(),
             macro_defs,
             local_macro_def_scopes: FxHashMap::default(),
             name_already_seen: FxHashMap::default(),
@@ -1462,36 +1465,35 @@ fn visit_scopes<T>(
         // 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
-        //    in prelude, not sure where exactly (creates ambiguities with any other prelude names).
 
         let rust_2015 = ident.span.rust_2015();
-        let (ns, is_absolute_path) = match scope_set {
-            ScopeSet::All(ns, _) => (ns, false),
-            ScopeSet::AbsolutePath(ns) => (ns, true),
-            ScopeSet::Macro(_) => (MacroNS, false),
+        let (ns, macro_kind, is_absolute_path) = match scope_set {
+            ScopeSet::All(ns, _) => (ns, None, false),
+            ScopeSet::AbsolutePath(ns) => (ns, None, true),
+            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
         };
         // Jump out of trait or enum modules, they do not act as scopes.
         let module = parent_scope.module.nearest_item_scope();
         let mut scope = match ns {
             _ if is_absolute_path => Scope::CrateRoot,
             TypeNS | ValueNS => Scope::Module(module),
-            MacroNS => Scope::DeriveHelpers,
+            MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
         };
         let mut ident = ident.modern();
         let mut use_prelude = !module.no_implicit_prelude;
 
         loop {
             let visit = match scope {
-                Scope::DeriveHelpers => true,
+                // Derive helpers are not in scope when resolving derives in the same container.
+                Scope::DeriveHelpers(expn_id) =>
+                    !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive)),
+                Scope::DeriveHelpersCompat => true,
                 Scope::MacroRules(..) => true,
                 Scope::CrateRoot => true,
                 Scope::Module(..) => true,
                 Scope::RegisteredAttrs => use_prelude,
                 Scope::MacroUsePrelude => use_prelude || rust_2015,
                 Scope::BuiltinAttrs => true,
-                Scope::LegacyPluginHelpers => use_prelude || rust_2015,
                 Scope::ExternPrelude => use_prelude || is_absolute_path,
                 Scope::ToolPrelude => use_prelude,
                 Scope::StdLibPrelude => use_prelude || ns == MacroNS,
@@ -1505,7 +1507,18 @@ fn visit_scopes<T>(
             }
 
             scope = match scope {
-                Scope::DeriveHelpers =>
+                Scope::DeriveHelpers(expn_id) if expn_id != ExpnId::root() => {
+                    // Derive helpers are not visible to code generated by bang or derive macros.
+                    let expn_data = expn_id.expn_data();
+                    match expn_data.kind {
+                        ExpnKind::Root |
+                        ExpnKind::Macro(MacroKind::Bang, _) |
+                        ExpnKind::Macro(MacroKind::Derive, _) => Scope::DeriveHelpersCompat,
+                        _ => Scope::DeriveHelpers(expn_data.parent),
+                    }
+                }
+                Scope::DeriveHelpers(..) => Scope::DeriveHelpersCompat,
+                Scope::DeriveHelpersCompat =>
                     Scope::MacroRules(parent_scope.legacy),
                 Scope::MacroRules(legacy_scope) => match legacy_scope {
                     LegacyScope::Binding(binding) => Scope::MacroRules(
@@ -1540,8 +1553,7 @@ fn visit_scopes<T>(
                 }
                 Scope::RegisteredAttrs => Scope::MacroUsePrelude,
                 Scope::MacroUsePrelude => Scope::StdLibPrelude,
-                Scope::BuiltinAttrs => Scope::LegacyPluginHelpers,
-                Scope::LegacyPluginHelpers => break, // nowhere else to search
+                Scope::BuiltinAttrs => break, // nowhere else to search
                 Scope::ExternPrelude if is_absolute_path => break,
                 Scope::ExternPrelude => Scope::ToolPrelude,
                 Scope::ToolPrelude => Scope::StdLibPrelude,
index 2d125a459c86b701947294d7445859809e1c6e19..4f687b5ba92006a9ab379b2cf61ef65824c00dac 100644 (file)
@@ -237,15 +237,26 @@ fn resolve_macro_invocation(
                 // - Derives in the container need to know whether one of them is a built-in `Copy`.
                 // FIXME: Try to avoid repeated resolutions for derives here and in expansion.
                 let mut exts = Vec::new();
+                let mut helper_attrs = Vec::new();
                 for path in derives {
                     exts.push(match self.resolve_macro_path(
                         path, Some(MacroKind::Derive), &parent_scope, true, force
                     ) {
-                        Ok((Some(ext), _)) => ext,
+                        Ok((Some(ext), _)) => {
+                            let span = path.segments.last().unwrap().ident.span.modern();
+                            helper_attrs.extend(
+                                ext.helper_attrs.iter().map(|name| Ident::new(*name, span))
+                            );
+                            if ext.is_derive_copy {
+                                self.add_derive_copy(invoc_id);
+                            }
+                            ext
+                        }
                         Ok(_) | Err(Determinacy::Determined) => self.dummy_ext(MacroKind::Derive),
                         Err(Determinacy::Undetermined) => return Err(Indeterminate),
                     })
                 }
+                self.helper_attrs.insert(invoc_id, helper_attrs);
                 return Ok(InvocationRes::DeriveContainer(exts));
             }
         };
@@ -498,7 +509,19 @@ struct Flags: u8 {
                 Flags::empty(),
             ));
             let result = match scope {
-                Scope::DeriveHelpers => {
+                Scope::DeriveHelpers(expn_id) => {
+                    if let Some(attr) = this.helper_attrs.get(&expn_id).and_then(|attrs| {
+                        attrs.iter().rfind(|i| ident == **i)
+                    }) {
+                        let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
+                                       ty::Visibility::Public, attr.span, expn_id)
+                                       .to_name_binding(this.arenas);
+                        Ok((binding, Flags::empty()))
+                    } else {
+                        Err(Determinacy::Determined)
+                    }
+                }
+                Scope::DeriveHelpersCompat => {
                     let mut result = Err(Determinacy::Determined);
                     for derive in parent_scope.derives {
                         let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
@@ -590,13 +613,6 @@ struct Flags: u8 {
                 } else {
                     Err(Determinacy::Determined)
                 }
-                Scope::LegacyPluginHelpers => if this.session.plugin_attributes.borrow().iter()
-                                                     .any(|(name, _)| ident.name == *name) {
-                    let res = Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
-                    ok(res, DUMMY_SP, this.arenas)
-                } else {
-                    Err(Determinacy::Determined)
-                }
                 Scope::ExternPrelude => match this.extern_prelude_get(ident, !record_used) {
                     Some(binding) => Ok((binding, Flags::empty())),
                     None => Err(Determinacy::determined(
index 50dfac62024b1306e63edafb53eff911a192f251..255938a193c9763fafc7a7b5d3997c0dba507d14 100644 (file)
@@ -30,9 +30,8 @@
 use rls_data::{SigElement, Signature};
 
 use rustc::hir::def::{Res, DefKind};
-use syntax::ast::{self, NodeId};
+use syntax::ast::{self, Extern, NodeId};
 use syntax::print::pprust;
-use syntax_pos::sym;
 
 pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
     if !scx.config.signatures {
@@ -157,9 +156,11 @@ fn text_sig(text: String) -> Signature {
     }
 }
 
-fn push_abi(text: &mut String, abi: ast::Abi) {
-    if abi.symbol != sym::Rust {
-        text.push_str(&format!("extern \"{}\" ", abi.symbol));
+fn push_extern(text: &mut String, ext: Extern) {
+    match ext {
+        Extern::None => {}
+        Extern::Implicit => text.push_str("extern "),
+        Extern::Explicit(abi) => text.push_str(&format!("extern \"{}\" ", abi.symbol)),
     }
 }
 
@@ -237,7 +238,7 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_,
                 if f.unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
                 }
-                push_abi(&mut text, f.abi);
+                push_extern(&mut text, f.ext);
                 text.push_str("fn(");
 
                 let mut defs = vec![];
@@ -387,7 +388,7 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_,
                 if header.unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
                 }
-                push_abi(&mut text, header.abi);
+                push_extern(&mut text, header.ext);
                 text.push_str("fn ");
 
                 let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
@@ -936,7 +937,7 @@ fn make_method_signature(
     if m.header.unsafety == ast::Unsafety::Unsafe {
         text.push_str("unsafe ");
     }
-    push_abi(&mut text, m.header.abi);
+    push_extern(&mut text, m.header.ext);
     text.push_str("fn ");
 
     let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;
index 507732a9107fb166476651f796975f16a0e0d7d5..2b4ac7676fade845c6a97202c1ceddb6b173b006 100644 (file)
@@ -21,7 +21,6 @@
 use errors::json::JsonEmitter;
 use syntax::symbol::sym;
 use syntax_pos::DUMMY_SP;
-use errors;
 use errors::emitter::{Emitter, EmitterWriter};
 
 use std::cell::RefCell;
@@ -341,6 +340,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
         lint_caps,
         register_lints: None,
         override_queries: None,
+        registry: rustc_driver::diagnostics_registry(),
     };
 
     interface::run_compiler_in_existing_thread_pool(config, |compiler| {
index 4f102dbf128f49d4d0ef910514ce6a4df5e1e7fe..8bfaf98f0867e053dc6b28e8cc479977933e4f6a 100644 (file)
@@ -23,8 +23,9 @@
 extern crate env_logger;
 extern crate rustc;
 extern crate rustc_data_structures;
-extern crate rustc_index;
 extern crate rustc_driver;
+extern crate rustc_error_codes;
+extern crate rustc_index;
 extern crate rustc_resolve;
 extern crate rustc_lint;
 extern crate rustc_interface;
index c483f6fb4770f941d7e1722d85f38b07545a8df1..98e18d666f1500c3906c408af38b6f453353c4b6 100644 (file)
@@ -80,6 +80,7 @@ pub fn run(options: Options) -> i32 {
         lint_caps: Default::default(),
         register_lints: None,
         override_queries: None,
+        registry: rustc_driver::diagnostics_registry(),
     };
 
     let mut test_args = options.test_args.clone();
index d025a7d16f2562c17f656f6c2442e5233731e5b9..b0baf36308e44c26facb31c879300453cdecfe72 100644 (file)
@@ -126,7 +126,7 @@ mod break_keyword { }
 /// look like this:
 ///
 /// ```rust
-/// const WORDS: &str = "hello rust!";
+/// const WORDS: &'static str = "hello rust!";
 /// ```
 ///
 /// Thanks to static lifetime elision, you usually don't have to explicitly use 'static:
index cbeaf20b13adc923fc5a913e378fdb76a56a316b..2df79ee97fbacec9c271972fb6eaf15ac76c291a 100644 (file)
@@ -4,53 +4,7 @@
 //! library. Each macro is available for use when linking against the standard
 //! library.
 
-/// Panics the current thread.
-///
-/// This allows a program to terminate immediately and provide feedback
-/// to the caller of the program. `panic!` should be used when a program reaches
-/// an unrecoverable state.
-///
-/// This macro is the perfect way to assert conditions in example code and in
-/// tests. `panic!` is closely tied with the `unwrap` method of both [`Option`]
-/// and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set
-/// to None or Err variants.
-///
-/// This macro is used to inject panic into a Rust thread, causing the thread to
-/// panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
-/// and the single-argument form of the `panic!` macro will be the value which
-/// is transmitted.
-///
-/// [`Result`] enum is often a better solution for recovering from errors than
-/// using the `panic!` macro. This macro should be used to avoid proceeding using
-/// incorrect values, such as from external sources. Detailed information about
-/// error handling is found in the [book].
-///
-/// The multi-argument form of this macro panics with a string and has the
-/// [`format!`] syntax for building a string.
-///
-/// See also the macro [`compile_error!`], for raising errors during compilation.
-///
-/// [runwrap]: ../std/result/enum.Result.html#method.unwrap
-/// [`Option`]: ../std/option/enum.Option.html#method.unwrap
-/// [`Result`]: ../std/result/enum.Result.html
-/// [`format!`]: ../std/macro.format.html
-/// [`compile_error!`]: ../std/macro.compile_error.html
-/// [book]: ../book/ch09-00-error-handling.html
-///
-/// # Current implementation
-///
-/// If the main thread panics it will terminate all your threads and end your
-/// program with code `101`.
-///
-/// # Examples
-///
-/// ```should_panic
-/// # #![allow(unreachable_code)]
-/// panic!();
-/// panic!("this is a terrible mistake!");
-/// panic!(4); // panic with the value of 4 to be collected elsewhere
-/// panic!("this is a {} {message}", "fancy", message = "message");
-/// ```
+#[doc(include = "../libcore/macros/panic.md")]
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(libstd_sys_internals)]
index d358efbe54364d49ee323ee9b6022bb53916e7ba..bbf00825acb3376874e809690c022a4edb79e796 100644 (file)
@@ -1422,6 +1422,33 @@ pub struct Lit {
     pub span: Span,
 }
 
+/// Same as `Lit`, but restricted to string literals.
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+pub struct StrLit {
+    /// The original literal token as written in source code.
+    pub style: StrStyle,
+    pub symbol: Symbol,
+    pub suffix: Option<Symbol>,
+    pub span: Span,
+    /// The unescaped "semantic" representation of the literal lowered from the original token.
+    /// FIXME: Remove this and only create the semantic representation during lowering to HIR.
+    pub symbol_unescaped: Symbol,
+}
+
+impl StrLit {
+    crate fn as_lit(&self) -> Lit {
+        let token_kind = match self.style {
+            StrStyle::Cooked => token::Str,
+            StrStyle::Raw(n) => token::StrRaw(n),
+        };
+        Lit {
+            token: token::Lit::new(token_kind, self.symbol, self.suffix),
+            span: self.span,
+            kind: LitKind::Str(self.symbol_unescaped, self.style),
+        }
+    }
+}
+
 // Clippy uses Hash and PartialEq
 /// Type of the integer literal based on provided suffix.
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
@@ -1745,7 +1772,7 @@ pub struct Ty {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct BareFnTy {
     pub unsafety: Unsafety,
-    pub abi: Abi,
+    pub ext: Extern,
     pub generic_params: Vec<GenericParam>,
     pub decl: P<FnDecl>,
 }
@@ -2128,7 +2155,7 @@ pub struct Mod {
 /// E.g., `extern { .. }` or `extern C { .. }`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct ForeignMod {
-    pub abi: Abi,
+    pub abi: Option<StrLit>,
     pub items: Vec<ForeignItem>,
 }
 
@@ -2411,24 +2438,17 @@ pub fn span_with_attributes(&self) -> Span {
     }
 }
 
-/// A reference to an ABI.
-///
-/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)]
-pub struct Abi {
-    pub symbol: Symbol,
-    pub span: Span,
-}
-
-impl Abi {
-    pub fn new(symbol: Symbol, span: Span) -> Self {
-        Self { symbol, span }
-    }
+/// `extern` qualifier on a function item or function type.
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+pub enum Extern {
+    None,
+    Implicit,
+    Explicit(StrLit),
 }
 
-impl Default for Abi {
-    fn default() -> Self {
-        Self::new(sym::Rust, DUMMY_SP)
+impl Extern {
+    pub fn from_abi(abi: Option<StrLit>) -> Extern {
+        abi.map_or(Extern::Implicit, Extern::Explicit)
     }
 }
 
@@ -2441,7 +2461,7 @@ pub struct FnHeader {
     pub unsafety: Unsafety,
     pub asyncness: Spanned<IsAsync>,
     pub constness: Spanned<Constness>,
-    pub abi: Abi,
+    pub ext: Extern,
 }
 
 impl Default for FnHeader {
@@ -2450,7 +2470,7 @@ fn default() -> FnHeader {
             unsafety: Unsafety::Normal,
             asyncness: dummy_spanned(IsAsync::NotAsync),
             constness: dummy_spanned(Constness::NotConst),
-            abi: Abi::default(),
+            ext: Extern::None,
         }
     }
 }
index acf0dd1cabb7d6f85b4c85a31a867ec4328cf5a6..767fcabc017eddb5c3a6beb2225c8e3d7f075c1d 100644 (file)
@@ -667,7 +667,10 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
             break
         }
 
-        let meta = attr.meta().unwrap();
+        let meta = match attr.meta() {
+            Some(meta) => meta,
+            None => continue,
+        };
         depr = match &meta.kind {
             MetaItemKind::Word => Some(Deprecation { since: None, note: None }),
             MetaItemKind::NameValue(..) => {
index bd836eee42af821765e15defcf96122e6ec4c45b..abf9adefd3c44328d1c0bc2e957fde7478089a90 100644 (file)
@@ -191,10 +191,10 @@ macro_rules! gate_feature_post {
 }
 
 impl<'a> PostExpansionVisitor<'a> {
-    fn check_abi(&self, abi: ast::Abi) {
-        let ast::Abi { symbol, span } = abi;
+    fn check_abi(&self, abi: ast::StrLit) {
+        let ast::StrLit { symbol_unescaped, span, .. } = abi;
 
-        match &*symbol.as_str() {
+        match &*symbol_unescaped.as_str() {
             // Stable
             "Rust" |
             "C" |
@@ -258,6 +258,12 @@ fn check_abi(&self, abi: ast::Abi) {
         }
     }
 
+    fn check_extern(&self, ext: ast::Extern) {
+        if let ast::Extern::Explicit(abi) = ext {
+            self.check_abi(abi);
+        }
+    }
+
     fn maybe_report_invalid_custom_discriminants(&self, variants: &[ast::Variant]) {
         let has_fields = variants.iter().any(|variant| match variant.data {
             VariantData::Tuple(..) | VariantData::Struct(..) => true,
@@ -388,7 +394,9 @@ fn visit_name(&mut self, sp: Span, name: ast::Name) {
     fn visit_item(&mut self, i: &'a ast::Item) {
         match i.kind {
             ast::ItemKind::ForeignMod(ref foreign_module) => {
-                self.check_abi(foreign_module.abi);
+                if let Some(abi) = foreign_module.abi {
+                    self.check_abi(abi);
+                }
             }
 
             ast::ItemKind::Fn(..) => {
@@ -511,7 +519,7 @@ fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
     fn visit_ty(&mut self, ty: &'a ast::Ty) {
         match ty.kind {
             ast::TyKind::BareFn(ref bare_fn_ty) => {
-                self.check_abi(bare_fn_ty.abi);
+                self.check_extern(bare_fn_ty.ext);
             }
             ast::TyKind::Never => {
                 gate_feature_post!(&self, never_type, ty.span,
@@ -605,7 +613,7 @@ fn visit_fn(&mut self,
             // Stability of const fn methods are covered in
             // `visit_trait_item` and `visit_impl_item` below; this is
             // because default methods don't pass through this point.
-            self.check_abi(header.abi);
+            self.check_extern(header.ext);
         }
 
         if fn_decl.c_variadic() {
@@ -639,7 +647,7 @@ fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
         match ti.kind {
             ast::TraitItemKind::Method(ref sig, ref block) => {
                 if block.is_none() {
-                    self.check_abi(sig.header.abi);
+                    self.check_extern(sig.header.ext);
                 }
                 if sig.decl.c_variadic() {
                     gate_feature_post!(&self, c_variadic, ti.span,
index f4ef993edb95ae06757af8af846fcd7c1dfd92d0..da3c885b8609dc9e389ca0c24b8014276bb5793a 100644 (file)
@@ -441,7 +441,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
             vis.visit_mt(mt);
         }
         TyKind::BareFn(bft) => {
-            let BareFnTy { unsafety: _, abi: _, generic_params, decl } = bft.deref_mut();
+            let BareFnTy { unsafety: _, ext: _, generic_params, decl } = bft.deref_mut();
             generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
             vis.visit_fn_decl(decl);
         }
@@ -974,7 +974,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
 }
 
 pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
-    let FnHeader { unsafety: _, asyncness, constness: _, abi: _ } = header;
+    let FnHeader { unsafety: _, asyncness, constness: _, ext: _ } = header;
     vis.visit_asyncness(&mut asyncness.node);
 }
 
index ef65a744e83b012dfcfc5470daa5b6de2d5c69ba..17a7cbddff9cc3e420eb87c68b577e745f0766ab 100644 (file)
@@ -1013,7 +1013,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) {
                 self.pclose();
             }
             ast::TyKind::BareFn(ref f) => {
-                self.print_ty_fn(f.abi,
+                self.print_ty_fn(f.ext,
                                  f.unsafety,
                                  &f.decl,
                                  None,
@@ -1232,7 +1232,10 @@ fn print_associated_type(&mut self,
             }
             ast::ItemKind::ForeignMod(ref nmod) => {
                 self.head("extern");
-                self.print_abi(nmod.abi);
+                if let Some(abi) = nmod.abi {
+                    self.print_literal(&abi.as_lit());
+                    self.nbsp();
+                }
                 self.bopen();
                 self.print_foreign_mod(nmod, &item.attrs);
                 self.bclose(item.span);
@@ -2805,7 +2808,7 @@ pub fn print_mutability(&mut self, mutbl: ast::Mutability) {
     }
 
     crate fn print_ty_fn(&mut self,
-                       abi: ast::Abi,
+                       ext: ast::Extern,
                        unsafety: ast::Unsafety,
                        decl: &ast::FnDecl,
                        name: Option<ast::Ident>,
@@ -2825,7 +2828,7 @@ pub fn print_mutability(&mut self, mutbl: ast::Mutability) {
             span: syntax_pos::DUMMY_SP,
         };
         self.print_fn(decl,
-                      ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
+                      ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() },
                       name,
                       &generics,
                       &source_map::dummy_spanned(ast::VisibilityKind::Inherited));
@@ -2866,18 +2869,21 @@ pub fn print_mutability(&mut self, mutbl: ast::Mutability) {
         self.print_asyncness(header.asyncness.node);
         self.print_unsafety(header.unsafety);
 
-        if header.abi.symbol != sym::Rust {
-            self.word_nbsp("extern");
-            self.print_abi(header.abi);
+        match header.ext {
+            ast::Extern::None => {}
+            ast::Extern::Implicit => {
+                self.word_nbsp("extern");
+            }
+            ast::Extern::Explicit(abi) => {
+                self.word_nbsp("extern");
+                self.print_literal(&abi.as_lit());
+                self.nbsp();
+            }
         }
 
         self.s.word("fn")
     }
 
-    fn print_abi(&mut self, abi: ast::Abi) {
-        self.word_nbsp(format!("\"{}\"", abi.symbol));
-    }
-
     crate fn print_unsafety(&mut self, s: ast::Unsafety) {
         match s {
             ast::Unsafety::Normal => {},
index b7f6364c2b55ca2928292869419c7074ea5b4b68..06aa5deb6e0184dd74231c0dd08aac951cd9a005 100644 (file)
@@ -1,5 +1,5 @@
 use crate::base::*;
-use crate::proc_macro::{collect_derives, MarkAttrs};
+use crate::proc_macro::collect_derives;
 use crate::hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind};
 use crate::mbe::macro_rules::annotate_err_with_kind;
 use crate::placeholders::{placeholder, PlaceholderExpander};
@@ -394,7 +394,9 @@ pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragm
                     let fragment = self.expand_invoc(invoc, &ext.kind);
                     self.collect_invocations(fragment, &[])
                 }
-                InvocationRes::DeriveContainer(exts) => {
+                InvocationRes::DeriveContainer(_exts) => {
+                    // FIXME: Consider using the derive resolutions (`_exts`) immediately,
+                    // instead of enqueuing the derives to be resolved again later.
                     let (derives, item) = match invoc.kind {
                         InvocationKind::DeriveContainer { derives, item } => (derives, item),
                         _ => unreachable!(),
@@ -421,20 +423,6 @@ pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragm
 
                     let mut item = self.fully_configure(item);
                     item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
-                    let mut helper_attrs = Vec::new();
-                    let mut has_copy = false;
-                    for ext in exts {
-                        helper_attrs.extend(&ext.helper_attrs);
-                        has_copy |= ext.is_derive_copy;
-                    }
-                    // Mark derive helpers inside this item as known and used.
-                    // FIXME: This is a hack, derive helpers should be integrated with regular name
-                    // resolution instead. For example, helpers introduced by a derive container
-                    // can be in scope for all code produced by that container's expansion.
-                    item.visit_with(&mut MarkAttrs(&helper_attrs));
-                    if has_copy {
-                        self.cx.resolver.add_derive_copy(invoc.expansion_data.id);
-                    }
 
                     let mut derive_placeholders = Vec::with_capacity(derives.len());
                     invocations.reserve(derives.len());
index db981fae5c2246247479f50ce8b56803498af326..099cf0a4be9049bcb41d04f479eb5c8dd3bdba68 100644 (file)
@@ -1,13 +1,11 @@
 use crate::base::{self, *};
 use crate::proc_macro_server;
 
-use syntax::ast::{self, ItemKind, Attribute, Mac};
-use syntax::attr::{mark_used, mark_known};
+use syntax::ast::{self, ItemKind};
 use syntax::errors::{Applicability, FatalError};
 use syntax::symbol::sym;
 use syntax::token;
 use syntax::tokenstream::{self, TokenStream};
-use syntax::visit::Visitor;
 
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::{Span, DUMMY_SP};
@@ -167,21 +165,6 @@ fn expand(&self,
     }
 }
 
-crate struct MarkAttrs<'a>(crate &'a [ast::Name]);
-
-impl<'a> Visitor<'a> for MarkAttrs<'a> {
-    fn visit_attribute(&mut self, attr: &Attribute) {
-        if let Some(ident) = attr.ident() {
-            if self.0.contains(&ident.name) {
-                mark_used(attr);
-                mark_known(attr);
-            }
-        }
-    }
-
-    fn visit_mac(&mut self, _mac: &Mac) {}
-}
-
 crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
     let mut result = Vec::new();
     attrs.retain(|attr| {
index 5fab101957a0afbb1cd305045ca11e008959d3df..bd345a9a7dada11c83573e30517fcf0d5e3a412e 100644 (file)
@@ -2,19 +2,17 @@
 //
 use State::*;
 
+use errors::{DiagnosticBuilder, PResult};
 use rustc_data_structures::thin_vec::ThinVec;
-
-use errors::DiagnosticBuilder;
-
-use syntax::ast;
-use syntax_expand::base::{self, *};
-use syntax::token::{self, Token};
+use rustc_parse::parser::Parser;
+use syntax_expand::base::*;
+use syntax_pos::Span;
+use syntax::{span_err, struct_span_err};
+use syntax::ast::{self, AsmDialect};
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
-use syntax::ast::AsmDialect;
-use syntax_pos::Span;
+use syntax::token::{self, Token};
 use syntax::tokenstream::{self, TokenStream};
-use syntax::{span_err, struct_span_err};
 
 use rustc_error_codes::*;
 
@@ -45,7 +43,7 @@ fn next(&self) -> State {
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                        sp: Span,
                        tts: TokenStream)
-                       -> Box<dyn base::MacResult + 'cx> {
+                       -> Box<dyn MacResult + 'cx> {
     let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
         Ok(Some(inline_asm)) => inline_asm,
         Ok(None) => return DummyResult::any(sp),
@@ -69,6 +67,18 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
     }))
 }
 
+fn parse_asm_str<'a>(p: &mut Parser<'a>) -> PResult<'a, Symbol> {
+    match p.parse_str_lit() {
+        Ok(str_lit) => Ok(str_lit.symbol_unescaped),
+        Err(opt_lit) => {
+            let span = opt_lit.map_or(p.token.span, |lit| lit.span);
+            let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal");
+            err.span_label(span, "not a string literal");
+            Err(err)
+        }
+    }
+}
+
 fn parse_inline_asm<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
@@ -144,7 +154,7 @@ fn parse_inline_asm<'a>(
                         p.eat(&token::Comma);
                     }
 
-                    let (constraint, _) = p.parse_str()?;
+                    let constraint = parse_asm_str(&mut p)?;
 
                     let span = p.prev_span;
 
@@ -189,7 +199,7 @@ fn parse_inline_asm<'a>(
                         p.eat(&token::Comma);
                     }
 
-                    let (constraint, _) = p.parse_str()?;
+                    let constraint = parse_asm_str(&mut p)?;
 
                     if constraint.as_str().starts_with("=") {
                         span_err!(cx, p.prev_span, E0662,
@@ -212,7 +222,7 @@ fn parse_inline_asm<'a>(
                         p.eat(&token::Comma);
                     }
 
-                    let (s, _) = p.parse_str()?;
+                    let s = parse_asm_str(&mut p)?;
 
                     if OPTIONS.iter().any(|&opt| s == opt) {
                         cx.span_warn(p.prev_span, "expected a clobber, found an option");
@@ -225,7 +235,7 @@ fn parse_inline_asm<'a>(
                 }
             }
             Options => {
-                let (option, _) = p.parse_str()?;
+                let option = parse_asm_str(&mut p)?;
 
                 if option == sym::volatile {
                     // Indicates that the inline assembly has side effects
index b24306def7482941591fbdbd6692aeb15dc35c11..b6bf2f881616f1163d508c932d729eb44f23e49d 100644 (file)
 use std::vec;
 
 use rustc_data_structures::thin_vec::ThinVec;
-use syntax::ast::{self, Abi, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
+use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
 use syntax::ast::{VariantData, GenericParamKind, GenericArg};
 use syntax::attr;
 use syntax::source_map::respan;
@@ -737,7 +737,6 @@ fn expand_struct_def(&self,
                                          self,
                                          type_ident,
                                          generics,
-                                         sym::Rust,
                                          explicit_self,
                                          tys,
                                          body)
@@ -792,7 +791,6 @@ fn expand_enum_def(&self,
                                          self,
                                          type_ident,
                                          generics,
-                                         sym::Rust,
                                          explicit_self,
                                          tys,
                                          body)
@@ -918,7 +916,6 @@ fn create_method(&self,
                      trait_: &TraitDef<'_>,
                      type_ident: Ident,
                      generics: &Generics,
-                     abi: Symbol,
                      explicit_self: Option<ast::ExplicitSelf>,
                      arg_types: Vec<(Ident, P<ast::Ty>)>,
                      body: P<Expr>)
@@ -953,7 +950,7 @@ fn create_method(&self,
         let sig = ast::FnSig {
             header: ast::FnHeader {
                 unsafety,
-                abi: Abi::new(abi, trait_lo_sp),
+                ext: ast::Extern::None,
                 ..ast::FnHeader::default()
             },
             decl: fn_decl,
index b3e9576f43f59f9de2ef7e46677302b76571e921..86eaeeab5a426ec4b27199860928c336a5268f54 100644 (file)
         rust_2018_preview,
         rust_begin_unwind,
         rustc,
-        Rust,
         RustcDecodable,
         RustcEncodable,
         rustc_allocator,
index 9f1850dfb4c90e291a6b612a40e9d777e9f49eb1..f9ecff2abaa839c2349fcdb27d6f7ca2512b503f 100644 (file)
@@ -2,7 +2,7 @@
 
 extern crate rustc;
 extern crate rustc_interface;
-extern crate rustc_driver as _;
+extern crate rustc_driver;
 extern crate syntax;
 
 use rustc::session::DiagnosticOutput;
@@ -61,6 +61,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
         lint_caps: Default::default(),
         register_lints: None,
         override_queries: None,
+        registry: rustc_driver::diagnostics_registry(),
     };
 
     interface::run_compiler(config, |compiler| {
index 3d08c1c9eeefa2e0f52c6d45883614510e8598ae..b17c6a939655c45620dca7fcf073191e307e6696 100644 (file)
@@ -14,9 +14,6 @@
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_attribute(Symbol::intern("foo"), AttributeType::Normal);
-    reg.register_attribute(Symbol::intern("bar"), AttributeType::CrateLevel);
-    reg.register_attribute(Symbol::intern("baz"), AttributeType::Whitelisted);
     reg.register_syntax_extension(
         Symbol::intern("mac"), SyntaxExtension::dummy_bang(reg.sess.edition())
     );
index 6b914f501ca79a735456b635a5beabad7a3267a4..68ea10fe735ad6537e88327daafde5d87ed74b12 100644 (file)
@@ -5,25 +5,17 @@
 extern crate rustc;
 extern crate rustc_driver;
 extern crate syntax;
-extern crate syntax_expand;
 
 use rustc_driver::plugin::Registry;
-use syntax::attr;
-use syntax_expand::base::*;
-use syntax::feature_gate::AttributeType::Whitelisted;
-use syntax::symbol::Symbol;
-
-use rustc::hir;
-use rustc::hir::intravisit;
-use hir::Node;
+use rustc::hir::{self, intravisit, Node};
 use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext};
+use syntax::print::pprust;
 use syntax::source_map;
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
     reg.lint_store.register_lints(&[&MISSING_WHITELISTED_ATTR]);
     reg.lint_store.register_late_pass(|| box MissingWhitelistedAttrPass);
-    reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted);
 }
 
 declare_lint! {
@@ -48,7 +40,8 @@ fn check_fn(&mut self,
             _ => cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_item(id)),
         };
 
-        if !attr::contains_name(&item.attrs, Symbol::intern("whitelisted_attr")) {
+        let whitelisted = |attr| pprust::attribute_to_string(attr).contains("whitelisted_attr");
+        if !item.attrs.iter().any(whitelisted) {
             cx.span_lint(MISSING_WHITELISTED_ATTR, span,
                          "Missing 'whitelisted_attr' attribute");
         }
index e0dc3d6a45b532d948ceea09b6e6cb6feb631119..c3f98197250d1246c2b9e69033b9a82ead5442b9 100644 (file)
@@ -2,8 +2,9 @@
 // aux-build:issue-40001-plugin.rs
 // ignore-stage1
 
-#![feature(plugin)]
+#![feature(plugin, register_tool)]
 #![plugin(issue_40001_plugin)] //~ WARNING compiler plugins are deprecated
+#![register_tool(plugin)]
 
-#[whitelisted_attr]
+#[plugin::whitelisted_attr]
 fn main() {}
diff --git a/src/test/ui-fulldeps/plugin-attr-register-deny.rs b/src/test/ui-fulldeps/plugin-attr-register-deny.rs
deleted file mode 100644 (file)
index dd7c009..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// aux-build:attr-plugin-test.rs
-// ignore-stage1
-
-#![feature(plugin)]
-#![plugin(attr_plugin_test)]
-//~^ WARN use of deprecated attribute `plugin`
-#![deny(unused_attributes)]
-
-#[baz]
-fn baz() { } // no error
-
-#[foo]
-pub fn main() {
-     //~^^ ERROR unused
-    #[bar]
-    fn inner() {}
-    //~^^ ERROR crate
-    //~^^^ ERROR unused
-    baz();
-    inner();
-}
diff --git a/src/test/ui-fulldeps/plugin-attr-register-deny.stderr b/src/test/ui-fulldeps/plugin-attr-register-deny.stderr
deleted file mode 100644 (file)
index 8d95d6f..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/plugin-attr-register-deny.rs:5:1
-   |
-LL | #![plugin(attr_plugin_test)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
-error: unused attribute
-  --> $DIR/plugin-attr-register-deny.rs:15:5
-   |
-LL |     #[bar]
-   |     ^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/plugin-attr-register-deny.rs:7:9
-   |
-LL | #![deny(unused_attributes)]
-   |         ^^^^^^^^^^^^^^^^^
-
-error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/plugin-attr-register-deny.rs:15:5
-   |
-LL |     #[bar]
-   |     ^^^^^^
-
-error: unused attribute
-  --> $DIR/plugin-attr-register-deny.rs:12:1
-   |
-LL | #[foo]
-   | ^^^^^^
-
-error: aborting due to 3 previous errors
-
diff --git a/src/test/ui/asm/asm-literal-escaping.rs b/src/test/ui/asm/asm-literal-escaping.rs
new file mode 100644 (file)
index 0000000..8d464e7
--- /dev/null
@@ -0,0 +1,12 @@
+// build-pass
+// only-x86_64
+
+#![feature(asm)]
+
+fn main() {
+    unsafe {
+        // "nop" :: "r"(x) : "eax" : "volatile"
+        let x = 10;
+        asm!("\x6Eop" :: "\x72"(x) : "\x65ax" : "\x76olatile");
+    }
+}
index 9fe59d12e12cd3ca61c1687bcb77b560b42867fe..2b29332fef5e524adcec3bc4ecf2c0b19faa5ba6 100644 (file)
@@ -8,13 +8,13 @@ error: expected string literal
   --> $DIR/asm-parse-errors.rs:5:18
    |
 LL |     asm!("nop" : struct);
-   |                  ^^^^^^ expected string literal
+   |                  ^^^^^^ not a string literal
 
 error: expected string literal
   --> $DIR/asm-parse-errors.rs:6:30
    |
 LL |     asm!("mov %eax, $$0x2" : struct);
-   |                              ^^^^^^ expected string literal
+   |                              ^^^^^^ not a string literal
 
 error: expected `(`, found keyword `struct`
   --> $DIR/asm-parse-errors.rs:7:39
@@ -32,7 +32,7 @@ error: expected string literal
   --> $DIR/asm-parse-errors.rs:9:44
    |
 LL |     asm!("in %dx, %al" : "={al}"(result) : struct);
-   |                                            ^^^^^^ expected string literal
+   |                                            ^^^^^^ not a string literal
 
 error: expected `(`, found keyword `struct`
   --> $DIR/asm-parse-errors.rs:10:51
@@ -50,13 +50,13 @@ error: expected string literal
   --> $DIR/asm-parse-errors.rs:12:36
    |
 LL |     asm!("mov $$0x200, %eax" : : : struct);
-   |                                    ^^^^^^ expected string literal
+   |                                    ^^^^^^ not a string literal
 
 error: expected string literal
   --> $DIR/asm-parse-errors.rs:13:45
    |
 LL |     asm!("mov eax, 2" : "={eax}"(foo) : : : struct);
-   |                                             ^^^^^^ expected string literal
+   |                                             ^^^^^^ not a string literal
 
 error: inline assembly must be a string literal
   --> $DIR/asm-parse-errors.rs:14:10
diff --git a/src/test/ui/consts/issue-66342.rs b/src/test/ui/consts/issue-66342.rs
new file mode 100644 (file)
index 0000000..417f690
--- /dev/null
@@ -0,0 +1,12 @@
+// check-pass
+// only-x86_64
+
+// Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash.
+
+fn foo() -> [u8; 4 * 1024 * 1024 * 1024 * 1024] {
+    unimplemented!()
+}
+
+fn main() {
+    foo();
+}
diff --git a/src/test/ui/consts/issue-66397.rs b/src/test/ui/consts/issue-66397.rs
new file mode 100644 (file)
index 0000000..1b4aff4
--- /dev/null
@@ -0,0 +1,8 @@
+// check-pass
+// only-x86_64
+
+// Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash.
+
+fn main() {
+    [0; 4 * 1024 * 1024 * 1024 * 1024];
+}
diff --git a/src/test/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs b/src/test/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs
new file mode 100644 (file)
index 0000000..c0cde75
--- /dev/null
@@ -0,0 +1,11 @@
+// The original problem in #66340 was that `find_deprecation_generic`
+// called `attr.meta().unwrap()` under the assumption that the attribute
+// was a well-formed `MetaItem`.
+
+fn main() {
+    foo()
+}
+
+#[deprecated(note = test)]
+//~^ ERROR expected unsuffixed literal or identifier, found `test`
+fn foo() {}
diff --git a/src/test/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr b/src/test/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr
new file mode 100644 (file)
index 0000000..24178fa
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected unsuffixed literal or identifier, found `test`
+  --> $DIR/issue-66340-deprecated-attr-non-meta-grammar.rs:9:21
+   |
+LL | #[deprecated(note = test)]
+   |                     ^^^^
+
+error: aborting due to previous error
+
index 3f4a9e210401ef0ded220748f5a156aba8b069b8..8bcb1e5ba8c0da19466f2d4dc50a7165dcd0a65f 100644 (file)
@@ -4,7 +4,7 @@
 
 struct Foo {
     x: usize,
-    b: bool, //~ ERROR: field is never used
+    b: bool, //~ ERROR: field is never read
 }
 
 fn field_read(f: Foo) -> usize {
@@ -36,8 +36,8 @@ enum IJK {
     I, //~ ERROR variant is never constructed
     J {
         a: String,
-        b: i32, //~ ERROR field is never used
-        c: i32, //~ ERROR field is never used
+        b: i32, //~ ERROR field is never read
+        c: i32, //~ ERROR field is never read
     },
     K //~ ERROR variant is never constructed
 
@@ -58,9 +58,9 @@ fn field_match_in_patterns(b: XYZ) -> String {
 }
 
 struct Bar {
-    x: usize, //~ ERROR: field is never used
+    x: usize, //~ ERROR: field is never read
     b: bool,
-    c: bool, //~ ERROR: field is never used
+    c: bool, //~ ERROR: field is never read
     _guard: ()
 }
 
index 8eaf789f8f7934dd3dd89f8cca1a5ec1dde1c674..cc00fa4e42afd8f6a00b867273260565296f7534 100644 (file)
@@ -1,4 +1,4 @@
-error: field is never used: `b`
+error: field is never read: `b`
   --> $DIR/lint-dead-code-4.rs:7:5
    |
 LL |     b: bool,
@@ -38,13 +38,13 @@ error: variant is never constructed: `I`
 LL |     I,
    |     ^
 
-error: field is never used: `b`
+error: field is never read: `b`
   --> $DIR/lint-dead-code-4.rs:39:9
    |
 LL |         b: i32,
    |         ^^^^^^
 
-error: field is never used: `c`
+error: field is never read: `c`
   --> $DIR/lint-dead-code-4.rs:40:9
    |
 LL |         c: i32,
@@ -56,13 +56,13 @@ error: variant is never constructed: `K`
 LL |     K
    |     ^
 
-error: field is never used: `x`
+error: field is never read: `x`
   --> $DIR/lint-dead-code-4.rs:61:5
    |
 LL |     x: usize,
    |     ^^^^^^^^
 
-error: field is never used: `c`
+error: field is never read: `c`
   --> $DIR/lint-dead-code-4.rs:63:5
    |
 LL |     c: bool,
diff --git a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs
new file mode 100644 (file)
index 0000000..41d3a18
--- /dev/null
@@ -0,0 +1,15 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro_derive(GenHelperUse)]
+pub fn derive_a(_: TokenStream) -> TokenStream {
+    "
+    #[empty_helper]
+    struct Uwu;
+    ".parse().unwrap()
+}
index 21af4093a037de46f187556cfdd07ff63ad53d33..f0ca34db414d441b539f851363813f9f4ff1b83c 100644 (file)
@@ -1,33 +1,54 @@
+// edition:2018
 // aux-build:test-macros.rs
+// aux-build:derive-helper-shadowing.rs
 
 #[macro_use]
 extern crate test_macros;
+#[macro_use]
+extern crate derive_helper_shadowing;
 
 use test_macros::empty_attr as empty_helper;
 
+macro_rules! gen_helper_use {
+    () => {
+        #[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope
+        struct W;
+    }
+}
+
 #[empty_helper] //~ ERROR `empty_helper` is ambiguous
 #[derive(Empty)]
 struct S {
-    // FIXME No ambiguity, attributes in non-macro positions are not resolved properly
-    #[empty_helper]
+    #[empty_helper] //~ ERROR `empty_helper` is ambiguous
     field: [u8; {
-        // FIXME No ambiguity, derive helpers are not put into scope for non-attributes
-        use empty_helper;
+        use empty_helper; //~ ERROR `empty_helper` is ambiguous
 
-        // FIXME No ambiguity, derive helpers are not put into scope for inner items
-        #[empty_helper]
+        #[empty_helper] //~ ERROR `empty_helper` is ambiguous
         struct U;
 
         mod inner {
-            // FIXME No ambiguity, attributes in non-macro positions are not resolved properly
+            // OK, no ambiguity, the non-helper attribute is not in scope here, only the helper.
             #[empty_helper]
             struct V;
+
+            gen_helper_use!();
+
+            #[derive(GenHelperUse)] //~ ERROR cannot find attribute `empty_helper` in this scope
+            struct Owo;
+
+            use empty_helper as renamed;
+            #[renamed] //~ ERROR cannot use a derive helper attribute through an import
+            struct Wow;
         }
 
         0
     }]
 }
 
+// OK, no ambiguity, only the non-helper attribute is in scope.
+#[empty_helper]
+struct Z;
+
 fn main() {
     let s = S { field: [] };
 }
index 2ba517ce29ee743520506c0507dcbb58bfa6dd12..9048830bee24d5f14d932025c1bfe2fffed5d4c6 100644 (file)
+error: cannot use a derive helper attribute through an import
+  --> $DIR/derive-helper-shadowing.rs:40:15
+   |
+LL |             #[renamed]
+   |               ^^^^^^^
+   |
+note: the derive helper attribute imported here
+  --> $DIR/derive-helper-shadowing.rs:39:17
+   |
+LL |             use empty_helper as renamed;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot find attribute `empty_helper` in this scope
+  --> $DIR/derive-helper-shadowing.rs:36:22
+   |
+LL |             #[derive(GenHelperUse)]
+   |                      ^^^^^^^^^^^^
+
+error: cannot find attribute `empty_helper` in this scope
+  --> $DIR/derive-helper-shadowing.rs:14:11
+   |
+LL |         #[empty_helper]
+   |           ^^^^^^^^^^^^
+...
+LL |             gen_helper_use!();
+   |             ------------------ in this macro invocation
+
+error[E0659]: `empty_helper` is ambiguous (name vs any other name during import resolution)
+  --> $DIR/derive-helper-shadowing.rs:24:13
+   |
+LL |         use empty_helper;
+   |             ^^^^^^^^^^^^ ambiguous name
+   |
+note: `empty_helper` could refer to the derive helper attribute defined here
+  --> $DIR/derive-helper-shadowing.rs:20:10
+   |
+LL | #[derive(Empty)]
+   |          ^^^^^
+note: `empty_helper` could also refer to the attribute macro imported here
+  --> $DIR/derive-helper-shadowing.rs:10:5
+   |
+LL | use test_macros::empty_attr as empty_helper;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
+
 error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
-  --> $DIR/derive-helper-shadowing.rs:8:3
+  --> $DIR/derive-helper-shadowing.rs:19:3
    |
 LL | #[empty_helper]
    |   ^^^^^^^^^^^^ ambiguous name
    |
 note: `empty_helper` could refer to the derive helper attribute defined here
-  --> $DIR/derive-helper-shadowing.rs:9:10
+  --> $DIR/derive-helper-shadowing.rs:20:10
+   |
+LL | #[derive(Empty)]
+   |          ^^^^^
+note: `empty_helper` could also refer to the attribute macro imported here
+  --> $DIR/derive-helper-shadowing.rs:10:5
+   |
+LL | use test_macros::empty_attr as empty_helper;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
+
+error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
+  --> $DIR/derive-helper-shadowing.rs:22:7
+   |
+LL |     #[empty_helper]
+   |       ^^^^^^^^^^^^ ambiguous name
+   |
+note: `empty_helper` could refer to the derive helper attribute defined here
+  --> $DIR/derive-helper-shadowing.rs:20:10
+   |
+LL | #[derive(Empty)]
+   |          ^^^^^
+note: `empty_helper` could also refer to the attribute macro imported here
+  --> $DIR/derive-helper-shadowing.rs:10:5
+   |
+LL | use test_macros::empty_attr as empty_helper;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
+
+error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
+  --> $DIR/derive-helper-shadowing.rs:26:11
+   |
+LL |         #[empty_helper]
+   |           ^^^^^^^^^^^^ ambiguous name
+   |
+note: `empty_helper` could refer to the derive helper attribute defined here
+  --> $DIR/derive-helper-shadowing.rs:20:10
    |
 LL | #[derive(Empty)]
    |          ^^^^^
 note: `empty_helper` could also refer to the attribute macro imported here
-  --> $DIR/derive-helper-shadowing.rs:6:5
+  --> $DIR/derive-helper-shadowing.rs:10:5
    |
 LL | use test_macros::empty_attr as empty_helper;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
 
-error: aborting due to previous error
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0659`.
index 55835cb88f4e307c60789ca3506ed89ddb649d92..b22e50c4c1715d785de19052c1593d884219b40b 100644 (file)
@@ -1,9 +1,8 @@
-//~ ERROR mismatched types
-// aux-build:test-macros.rs
-
 // For each of these, we should get the appropriate type mismatch error message,
 // and the function should be echoed.
 
+// aux-build:test-macros.rs
+
 #[macro_use]
 extern crate test_macros;
 
@@ -35,12 +34,9 @@ struct Bar {
     let y = Foo { a: 10, b: 10isize }; //~ ERROR has no field named `b`
 }
 
-// FIXME: This doesn't work at the moment. See the one below. The pretty-printer
-// injects a "C" between `extern` and `fn` which causes a "probably_eq"
-// `TokenStream` mismatch. The lack of `"C"` should be preserved in the AST.
 #[recollect_attr]
 extern fn bar() {
-    0
+    0 //~ ERROR mismatched types
 }
 
 #[recollect_attr]
@@ -48,4 +44,14 @@ extern "C" fn baz() {
     0 //~ ERROR mismatched types
 }
 
+#[recollect_attr]
+extern "Rust" fn rust_abi() {
+    0 //~ ERROR mismatched types
+}
+
+#[recollect_attr]
+extern "\x43" fn c_abi_escaped() {
+    0 //~ ERROR mismatched types
+}
+
 fn main() {}
index 0290f4b2cc98259377d9c6e0228906291933ed12..545c2fa5f40e4ab193ef031e1dde6a49f40655b9 100644 (file)
@@ -1,10 +1,5 @@
 error[E0308]: mismatched types
-   |
-   = note: expected type `()`
-              found type `{integer}`
-
-error[E0308]: mismatched types
-  --> $DIR/span-preservation.rs:12:20
+  --> $DIR/span-preservation.rs:11:20
    |
 LL |     let x: usize = "hello";
    |                    ^^^^^^^ expected usize, found reference
@@ -13,7 +8,7 @@ LL |     let x: usize = "hello";
               found type `&'static str`
 
 error[E0308]: mismatched types
-  --> $DIR/span-preservation.rs:18:29
+  --> $DIR/span-preservation.rs:17:29
    |
 LL | fn b(x: Option<isize>) -> usize {
    |                           ----- expected `usize` because of return type
@@ -22,13 +17,13 @@ LL |         Some(x) => { return x },
    |                             ^ expected usize, found isize
 
 error[E0308]: mismatched types
-  --> $DIR/span-preservation.rs:34:22
+  --> $DIR/span-preservation.rs:33:22
    |
 LL |     let x = Foo { a: 10isize };
    |                      ^^^^^^^ expected usize, found isize
 
 error[E0560]: struct `c::Foo` has no field named `b`
-  --> $DIR/span-preservation.rs:35:26
+  --> $DIR/span-preservation.rs:34:26
    |
 LL |     let y = Foo { a: 10, b: 10isize };
    |                          ^ `c::Foo` does not have this field
@@ -36,7 +31,18 @@ LL |     let y = Foo { a: 10, b: 10isize };
    = note: available fields are: `a`
 
 error[E0308]: mismatched types
-  --> $DIR/span-preservation.rs:48:5
+  --> $DIR/span-preservation.rs:39:5
+   |
+LL | extern fn bar() {
+   |                 - possibly return type missing here?
+LL |     0
+   |     ^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/span-preservation.rs:44:5
    |
 LL | extern "C" fn baz() {
    |                     - possibly return type missing here?
@@ -46,7 +52,29 @@ LL |     0
    = note: expected type `()`
               found type `{integer}`
 
-error: aborting due to 6 previous errors
+error[E0308]: mismatched types
+  --> $DIR/span-preservation.rs:49:5
+   |
+LL | extern "Rust" fn rust_abi() {
+   |                             - possibly return type missing here?
+LL |     0
+   |     ^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/span-preservation.rs:54:5
+   |
+LL | extern "\x43" fn c_abi_escaped() {
+   |                                  - possibly return type missing here?
+LL |     0
+   |     ^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0308, E0560.
 For more information about an error, try `rustc --explain E0308`.
index 6d76e18cc7e0699daff2cbafb10ab28393ece2e5..edef41de159bae806cd36b26a0a9f07e90d3a18e 100644 (file)
@@ -3,19 +3,19 @@
 union U1 {
     a: u8, // should not be reported
     b: u8, // should not be reported
-    c: u8, //~ ERROR field is never used
+    c: u8, //~ ERROR field is never read
 }
 union U2 {
-    a: u8, //~ ERROR field is never used
+    a: u8, //~ ERROR field is never read
     b: u8, // should not be reported
     c: u8, // should not be reported
 }
-union NoDropLike { a: u8 } //~ ERROR field is never used
+union NoDropLike { a: u8 } //~ ERROR field is never read
 
 union U {
     a: u8, // should not be reported
     b: u8, // should not be reported
-    c: u8, //~ ERROR field is never used
+    c: u8, //~ ERROR field is never read
 }
 type A = U;
 
index f848db726f9efc23e28b97ca6d1e307af7fda72d..be145c9496c6cd793dead823d6816a2b0f323610 100644 (file)
@@ -1,4 +1,4 @@
-error: field is never used: `c`
+error: field is never read: `c`
   --> $DIR/union-fields-1.rs:6:5
    |
 LL |     c: u8,
@@ -10,19 +10,19 @@ note: lint level defined here
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
 
-error: field is never used: `a`
+error: field is never read: `a`
   --> $DIR/union-fields-1.rs:9:5
    |
 LL |     a: u8,
    |     ^^^^^
 
-error: field is never used: `a`
+error: field is never read: `a`
   --> $DIR/union-fields-1.rs:13:20
    |
 LL | union NoDropLike { a: u8 }
    |                    ^^^^^
 
-error: field is never used: `c`
+error: field is never read: `c`
   --> $DIR/union-fields-1.rs:18:5
    |
 LL |     c: u8,
index cb6415c18a83bf626e0f75779afafc26b01bea03..ae5337c618a754d470c8af176689390c56be7c60 100644 (file)
@@ -2,7 +2,7 @@
 
 union Foo {
     x: usize,
-    b: bool, //~ ERROR: field is never used
+    b: bool, //~ ERROR: field is never read
     _unused: u16,
 }
 
index 79c38a46814456ff0d986700dc527c3d33c5391c..5fe26dc25384402bbf5b4fe4497ec31c3525d7db 100644 (file)
@@ -1,4 +1,4 @@
-error: field is never used: `b`
+error: field is never read: `b`
   --> $DIR/union-lint-dead-code.rs:5:5
    |
 LL |     b: bool,