use crate::Mode;
use crate::Compiler;
use crate::builder::{Step, RunConfig, ShouldRun, Builder};
-use crate::util::{exe, add_lib_path};
+use crate::util::{exe, add_lib_path, CiEnv};
use crate::compile;
use crate::channel::GitInfo;
use crate::channel;
cargo
}
+fn rustbook_features() -> Vec<String> {
+ let mut features = Vec::new();
+
+ // Due to CI budged and risk of spurious failures we want to limit jobs running this check.
+ // At same time local builds should run it regardless of the platform.
+ // `CiEnv::None` means it's local build and `CHECK_LINKS` is defined in x86_64-gnu-tools to
+ // explicitly enable it on single job
+ if CiEnv::current() == CiEnv::None || env::var("CHECK_LINKS").is_ok() {
+ features.push("linkcheck".to_string());
+ }
+
+ features
+}
+
macro_rules! bootstrap_tool {
($(
$name:ident, $path:expr, $tool_name:expr
$(,llvm_tools = $llvm:expr)*
$(,is_external_tool = $external:expr)*
+ $(,features = $features:expr)*
;
)+) => {
#[derive(Copy, PartialEq, Eq, Clone)]
} else {
SourceType::InTree
},
- extra_features: Vec::new(),
+ extra_features: {
+ // FIXME(#60643): avoid this lint by using `_`
+ let mut _tmp = Vec::new();
+ $(_tmp.extend($features);)*
+ _tmp
+ },
}).expect("expected to build -- essential tool")
}
}
}
bootstrap_tool!(
- Rustbook, "src/tools/rustbook", "rustbook";
+ Rustbook, "src/tools/rustbook", "rustbook", features = rustbook_features();
UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen";
Tidy, "src/tools/tidy", "tidy";
Linkchecker, "src/tools/linkchecker", "linkchecker";
COPY x86_64-gnu-tools/checktools.sh /tmp/
COPY x86_64-gnu-tools/repo.sh /tmp/
+# Run rustbook with `linkcheck` feature enabled
+ENV CHECK_LINKS 1
+
ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
--save-toolstates=/tmp/toolstates.json
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: ?Sized> fmt::Debug for Cow<'_, B>
- where B: fmt::Debug + ToOwned,
- <B as ToOwned>::Owned: fmt::Debug
+where
+ B: fmt::Debug + ToOwned<Owned: fmt::Debug>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: ?Sized> fmt::Display for Cow<'_, B>
- where B: fmt::Display + ToOwned,
- <B as ToOwned>::Owned: fmt::Display
+where
+ B: fmt::Display + ToOwned<Owned: fmt::Display>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
#[stable(feature = "default", since = "1.11.0")]
impl<B: ?Sized> Default for Cow<'_, B>
- where B: ToOwned,
- <B as ToOwned>::Owned: Default
+where
+ B: ToOwned<Owned: Default>,
{
/// Creates an owned Cow<'a, B> with the default value for the contained owned value.
fn default() -> Self {
#![feature(alloc_layout_extra)]
#![feature(try_trait)]
#![feature(mem_take)]
+#![feature(associated_type_bounds)]
// Allow testing this library
#[test]
fn test_split_off_large_random_sorted() {
+ #[cfg(not(miri))] // Miri is too slow
let mut data = rand_data(1529);
+ #[cfg(miri)]
+ let mut data = rand_data(529);
// special case with maximum height.
data.sort();
m.insert(1);
m.insert(2);
- assert!(m.clone() == m);
+ assert_eq!(m.clone(), m);
}
#[test]
y.insert(2);
y.insert(1);
- assert!(hash(&x) == hash(&y));
+ assert_eq!(hash(&x), hash(&y));
}
fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
check_intersection(&[11, 1, 3, 77, 103, 5, -5],
&[2, 11, 77, -9, -42, 5, 3],
&[3, 5, 11, 77]);
+
+ if cfg!(miri) { // Miri is too slow
+ return;
+ }
+
let large = (0..1000).collect::<Vec<_>>();
check_intersection(&[], &large, &[]);
check_intersection(&large, &[], &[]);
check_difference(&[-5, 11, 22, 33, 40, 42],
&[-12, -5, 14, 23, 34, 38, 39, 50],
&[11, 22, 33, 40, 42]);
+
+ if cfg!(miri) { // Miri is too slow
+ return;
+ }
+
let large = (0..1000).collect::<Vec<_>>();
check_difference(&[], &large, &[]);
check_difference(&[-1], &large, &[-1]);
assert_eq!(is_subset(&[1, 2], &[1]), false);
assert_eq!(is_subset(&[1, 2], &[1, 2]), true);
assert_eq!(is_subset(&[1, 2], &[2, 3]), false);
+ assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42],
+ &[-12, -5, 14, 23, 11, 34, 22, 38, 33, 42, 39, 40]),
+ true);
+ assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42],
+ &[-12, -5, 14, 23, 34, 38, 22, 11]),
+ false);
+
+ if cfg!(miri) { // Miri is too slow
+ return;
+ }
+
let large = (0..1000).collect::<Vec<_>>();
assert_eq!(is_subset(&[], &large), true);
assert_eq!(is_subset(&large, &[]), false);
#[test]
fn test_split_off_large_random_sorted() {
+ #[cfg(not(miri))] // Miri is too slow
let mut data = rand_data(1529);
+ #[cfg(miri)]
+ let mut data = rand_data(529);
// special case with maximum height.
data.sort();
#![feature(trusted_len)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
+#![feature(associated_type_bounds)]
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
}
}
- fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
- right: Vec<SearchStep>)
- where P::Searcher: ReverseSearcher<'a>
- {
+ fn cmp_search_to_vec<'a>(
+ rev: bool,
+ pat: impl Pattern<'a, Searcher: ReverseSearcher<'a>>,
+ haystack: &'a str,
+ right: Vec<SearchStep>
+ ) {
let mut searcher = pat.into_searcher(haystack);
let mut v = vec![];
loop {
}
}
+/// Derive macro generating an impl of the trait `Clone`.
+#[cfg(not(bootstrap))]
+#[rustc_builtin_macro]
+#[rustc_macro_transparency = "semitransparent"]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
+pub macro Clone($item:item) { /* compiler built-in */ }
+
// FIXME(aburka): these structs are used solely by #[derive] to
// assert that every component of a type implements Clone or Copy.
//
fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
}
+/// Derive macro generating an impl of the trait `PartialEq`.
+#[cfg(not(bootstrap))]
+#[rustc_builtin_macro]
+#[rustc_macro_transparency = "semitransparent"]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics)]
+pub macro PartialEq($item:item) { /* compiler built-in */ }
+
/// Trait for equality comparisons which are [equivalence relations](
/// https://en.wikipedia.org/wiki/Equivalence_relation).
///
fn assert_receiver_is_total_eq(&self) {}
}
+/// Derive macro generating an impl of the trait `Eq`.
+#[cfg(not(bootstrap))]
+#[rustc_builtin_macro]
+#[rustc_macro_transparency = "semitransparent"]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics, derive_eq)]
+pub macro Eq($item:item) { /* compiler built-in */ }
+
// FIXME: this struct is used solely by #[derive] to
// assert that every component of a type implements Eq.
//
}
}
+/// Derive macro generating an impl of the trait `Ord`.
+#[cfg(not(bootstrap))]
+#[rustc_builtin_macro]
+#[rustc_macro_transparency = "semitransparent"]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics)]
+pub macro Ord($item:item) { /* compiler built-in */ }
+
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for Ordering {}
}
}
+/// Derive macro generating an impl of the trait `PartialOrd`.
+#[cfg(not(bootstrap))]
+#[rustc_builtin_macro]
+#[rustc_macro_transparency = "semitransparent"]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics)]
+pub macro PartialOrd($item:item) { /* compiler built-in */ }
+
/// Compares and returns the minimum of two values.
///
/// Returns the first argument if the comparison determines them to be equal.
// FIXME (#45742): replace the above impls for &/&mut with the following more general one:
// // As lifts over Deref
-// impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
+// impl<D: ?Sized + Deref<Target: AsRef<U>>, U: ?Sized> AsRef<U> for D {
// fn as_ref(&self) -> &U {
// self.deref().as_ref()
// }
// FIXME (#45742): replace the above impl for &mut with the following more general one:
// // AsMut lifts over DerefMut
-// impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
+// impl<D: ?Sized + Deref<Target: AsMut<U>>, U: ?Sized> AsMut<U> for D {
// fn as_mut(&mut self) -> &mut U {
// self.deref_mut().as_mut()
// }
fn default() -> Self;
}
+/// Derive macro generating an impl of the trait `Default`.
+#[cfg(not(bootstrap))]
+#[rustc_builtin_macro]
+#[rustc_macro_transparency = "semitransparent"]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics)]
+pub macro Default($item:item) { /* compiler built-in */ }
+
macro_rules! default_impl {
($t:ty, $v:expr, $doc:tt) => {
#[stable(feature = "rust1", since = "1.0.0")]
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
}
+// Separate module to reexport the macro `Debug` from prelude without the trait `Debug`.
+#[cfg(not(bootstrap))]
+pub(crate) mod macros {
+ /// Derive macro generating an impl of the trait `Debug`.
+ #[rustc_builtin_macro]
+ #[rustc_macro_transparency = "semitransparent"]
+ #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+ #[allow_internal_unstable(core_intrinsics)]
+ pub macro Debug($item:item) { /* compiler built-in */ }
+}
+#[cfg(not(bootstrap))]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(inline)]
+pub use macros::Debug;
+
/// Format trait for an empty format, `{}`.
///
/// `Display` is similar to [`Debug`][debug], but `Display` is for user-facing
#[stable(feature = "futures_api", since = "1.36.0")]
impl<P> Future for Pin<P>
where
- P: Unpin + ops::DerefMut,
- P::Target: Future,
+ P: Unpin + ops::DerefMut<Target: Future>,
{
type Output = <<P as ops::Deref>::Target as Future>::Output;
}
}
+// Separate module to reexport the macro `Hash` from prelude without the trait `Hash`.
+#[cfg(not(bootstrap))]
+pub(crate) mod macros {
+ /// Derive macro generating an impl of the trait `Hash`.
+ #[rustc_builtin_macro]
+ #[rustc_macro_transparency = "semitransparent"]
+ #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+ #[allow_internal_unstable(core_intrinsics)]
+ pub macro Hash($item:item) { /* compiler built-in */ }
+}
+#[cfg(not(bootstrap))]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(inline)]
+pub use macros::Hash;
+
/// A trait for hashing an arbitrary stream of bytes.
///
/// Instances of `Hasher` usually represent state that is changed while hashing
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Clone, U: Clone + IntoIterator, F: Clone> Clone for FlatMap<I, U, F>
- where <U as IntoIterator>::IntoIter: Clone
+impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
+where
+ U: Clone + IntoIterator<IntoIter: Clone>,
{
fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } }
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, U: IntoIterator, F> fmt::Debug for FlatMap<I, U, F>
- where U::IntoIter: fmt::Debug
+impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
+where
+ U: IntoIterator<IntoIter: fmt::Debug>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FlatMap").field("inner", &self.inner).finish()
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
- where F: FnMut(I::Item) -> U,
- U: IntoIterator,
- U::IntoIter: DoubleEndedIterator
+where
+ F: FnMut(I::Item) -> U,
+ U: IntoIterator,
+ U::IntoIter: DoubleEndedIterator,
{
#[inline]
fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub struct Flatten<I: Iterator>
-where I::Item: IntoIterator {
+where
+ I::Item: IntoIterator,
+{
inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
}
-impl<I: Iterator> Flatten<I>
-where I::Item: IntoIterator {
+
+impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
pub(in super::super) fn new(iter: I) -> Flatten<I> {
Flatten { inner: FlattenCompat::new(iter) }
}
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> fmt::Debug for Flatten<I>
- where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug,
- I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
+where
+ I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+ U: fmt::Debug + Iterator,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Flatten").field("inner", &self.inner).finish()
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> Clone for Flatten<I>
- where I: Iterator + Clone, U: Iterator + Clone,
- I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
+where
+ I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+ U: Clone + Iterator,
{
fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } }
}
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> Iterator for Flatten<I>
- where I: Iterator, U: Iterator,
- I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+where
+ I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+ U: Iterator,
{
type Item = U::Item;
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> DoubleEndedIterator for Flatten<I>
- where I: DoubleEndedIterator, U: DoubleEndedIterator,
- I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+where
+ I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+ U: DoubleEndedIterator,
{
#[inline]
fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> FusedIterator for Flatten<I>
- where I: FusedIterator, U: Iterator,
- I::Item: IntoIterator<IntoIter = U, Item = U::Item> {}
+where
+ I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+ U: Iterator,
+{}
/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
/// this type.
}
impl<I, U> Iterator for FlattenCompat<I, U>
- where I: Iterator, U: Iterator,
- I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+where
+ I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+ U: Iterator,
{
type Item = U::Item;
}
impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
- where I: DoubleEndedIterator, U: DoubleEndedIterator,
- I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+where
+ I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+ U: DoubleEndedIterator,
{
#[inline]
fn next_back(&mut self) -> Option<U::Item> {
///
/// ```rust
/// fn collect_as_strings<T>(collection: T) -> Vec<String>
-/// where T: IntoIterator,
-/// T::Item: std::fmt::Debug,
+/// where
+/// T: IntoIterator,
+/// T::Item: std::fmt::Debug,
/// {
/// collection
/// .into_iter()
#![feature(maybe_uninit_slice, maybe_uninit_array)]
#![feature(external_doc)]
#![feature(mem_take)]
+#![feature(associated_type_bounds)]
#[prelude_import]
#[allow(unused)]
/// ```
#[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 {
/// [`panic!`]: ../std/macro.panic.html
#[stable(feature = "compile_error_macro", since = "1.20.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro compile_error {
- ($msg:expr) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! compile_error {
+ ($msg:expr) => ({ /* compiler built-in */ });
($msg:expr,) => ({ /* compiler built-in */ })
}
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(fmt_internals)]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro format_args {
- ($fmt:expr) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ #[rustc_macro_transparency = "opaque"]
+ macro_rules! format_args {
+ ($fmt:expr) => ({ /* compiler built-in */ });
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
}
language use and is subject to change")]
#[allow_internal_unstable(fmt_internals)]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro format_args_nl {
- ($fmt:expr) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ #[rustc_macro_transparency = "opaque"]
+ macro_rules! format_args_nl {
+ ($fmt:expr) => ({ /* compiler built-in */ });
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro env {
- ($name:expr) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! env {
+ ($name:expr) => ({ /* compiler built-in */ });
($name:expr,) => ({ /* compiler built-in */ })
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro option_env {
- ($name:expr) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! option_env {
+ ($name:expr) => ({ /* compiler built-in */ });
($name:expr,) => ({ /* compiler built-in */ })
}
#[unstable(feature = "concat_idents", issue = "29599",
reason = "`concat_idents` is not stable enough for use and is subject to change")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro concat_idents {
- ($($e:ident),+) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! concat_idents {
+ ($($e:ident),+) => ({ /* compiler built-in */ });
($($e:ident,)+) => ({ /* compiler built-in */ })
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro concat {
- ($($e:expr),*) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! concat {
+ ($($e:expr),*) => ({ /* compiler built-in */ });
($($e:expr,)*) => ({ /* compiler built-in */ })
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro line() { /* compiler built-in */ }
+ #[macro_export]
+ macro_rules! line { () => { /* compiler built-in */ } }
/// Expands to the column number at which it was invoked.
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro column() { /* compiler built-in */ }
+ #[macro_export]
+ macro_rules! column { () => { /* compiler built-in */ } }
/// Same as `column`, but less likely to be shadowed.
#[unstable(feature = "__rust_unstable_column", issue = "0",
reason = "internal implementation detail of the `panic` macro")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro __rust_unstable_column() { /* compiler built-in */ }
+ #[macro_export]
+ macro_rules! __rust_unstable_column { () => { /* compiler built-in */ } }
/// Expands to the file name in which it was invoked.
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro file() { /* compiler built-in */ }
+ #[macro_export]
+ macro_rules! file { () => { /* compiler built-in */ } }
/// Stringifies its arguments.
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro stringify($($t:tt)*) { /* compiler built-in */ }
+ #[macro_export]
+ macro_rules! stringify { ($($t:tt)*) => { /* compiler built-in */ } }
/// Includes a utf8-encoded file as a string.
///
/// Compiling 'main.rs' and running the resulting binary will print "adiós".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro include_str {
- ($file:expr) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! include_str {
+ ($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ })
}
/// Compiling 'main.rs' and running the resulting binary will print "adiós".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro include_bytes {
- ($file:expr) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! include_bytes {
+ ($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ })
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro module_path() { /* compiler built-in */ }
+ #[macro_export]
+ macro_rules! module_path { () => { /* compiler built-in */ } }
/// Evaluates boolean combinations of configuration flags at compile-time.
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro cfg($($cfg:tt)*) { /* compiler built-in */ }
+ #[macro_export]
+ macro_rules! cfg { ($($cfg:tt)*) => { /* compiler built-in */ } }
/// Parses a file as an expression or an item according to the context.
///
/// "🙈🙊🙉🙈🙊🙉".
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro include {
- ($file:expr) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! include {
+ ($file:expr) => ({ /* compiler built-in */ });
($file:expr,) => ({ /* compiler built-in */ })
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro assert {
- ($cond:expr) => ({ /* compiler built-in */ }),
- ($cond:expr,) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! assert {
+ ($cond:expr) => ({ /* compiler built-in */ });
+ ($cond:expr,) => ({ /* compiler built-in */ });
($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ })
}
#[unstable(feature = "asm", issue = "29722",
reason = "inline assembly is not stable enough for use and is subject to change")]
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro asm("assembly template"
- : $("output"(operand),)*
- : $("input"(operand),)*
- : $("clobbers",)*
- : $("options",)*) { /* compiler built-in */ }
+ #[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]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro global_asm("assembly") { /* compiler built-in */ }
+ #[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]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro log_syntax($($arg:tt)*) { /* compiler built-in */ }
+ #[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]
- #[rustc_macro_transparency = "semitransparent"]
- pub macro trace_macros {
- (true) => ({ /* compiler built-in */ }),
+ #[macro_export]
+ macro_rules! trace_macros {
+ (true) => ({ /* compiler built-in */ });
(false) => ({ /* compiler built-in */ })
}
#[rustc_macro_transparency = "semitransparent"]
pub macro global_allocator($item:item) { /* compiler built-in */ }
- /// Derive macro generating an impl of the trait `Clone`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
- pub macro Clone($item:item) { /* compiler built-in */ }
-
- /// Derive macro generating an impl of the trait `Copy`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
- pub macro Copy($item:item) { /* compiler built-in */ }
-
- /// Derive macro generating an impl of the trait `Debug`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics)]
- pub macro Debug($item:item) { /* compiler built-in */ }
-
- /// Derive macro generating an impl of the trait `Default`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics)]
- pub macro Default($item:item) { /* compiler built-in */ }
-
- /// Derive macro generating an impl of the trait `Eq`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics, derive_eq)]
- pub macro Eq($item:item) { /* compiler built-in */ }
-
- /// Derive macro generating an impl of the trait `Hash`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics)]
- pub macro Hash($item:item) { /* compiler built-in */ }
-
- /// Derive macro generating an impl of the trait `Ord`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics)]
- pub macro Ord($item:item) { /* compiler built-in */ }
-
- /// Derive macro generating an impl of the trait `PartialEq`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics)]
- pub macro PartialEq($item:item) { /* compiler built-in */ }
-
- /// Derive macro generating an impl of the trait `PartialOrd`.
- #[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[allow_internal_unstable(core_intrinsics)]
- pub macro PartialOrd($item:item) { /* compiler built-in */ }
-
/// Unstable implementation detail of the `rustc` compiler, do not use.
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
// Empty.
}
+/// Derive macro generating an impl of the trait `Copy`.
+#[cfg(not(bootstrap))]
+#[rustc_builtin_macro]
+#[rustc_macro_transparency = "semitransparent"]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
+pub macro Copy($item:item) { /* compiler built-in */ }
+
/// Types for which it is safe to share references between threads.
///
/// This trait is automatically implemented when the compiler determines
}
}
-impl<P: Deref> Pin<P>
-where
- P::Target: Unpin,
-{
+impl<P: Deref<Target: Unpin>> Pin<P> {
/// Construct a new `Pin<P>` around a pointer to some data of a type that
/// implements [`Unpin`].
///
}
#[stable(feature = "pin", since = "1.33.0")]
-impl<P: DerefMut> DerefMut for Pin<P>
-where
- P::Target: Unpin
-{
+impl<P: DerefMut<Target: Unpin>> DerefMut for Pin<P> {
fn deref_mut(&mut self) -> &mut P::Target {
Pin::get_mut(Pin::as_mut(self))
}
// Re-exported built-in macros
#[cfg(not(bootstrap))]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
-#[allow(deprecated)]
#[doc(no_inline)]
-pub use crate::macros::builtin::{
- Clone,
- Copy,
- Debug,
- Default,
- Eq,
- Hash,
- Ord,
- PartialEq,
- PartialOrd,
- RustcDecodable,
- RustcEncodable,
+pub use crate::fmt::macros::Debug;
+#[cfg(not(bootstrap))]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(no_inline)]
+pub use crate::hash::macros::Hash;
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(no_inline)]
+pub use crate::{
__rust_unstable_column,
asm,
assert,
- bench,
cfg,
column,
compile_error,
file,
format_args,
format_args_nl,
- global_allocator,
global_asm,
include,
include_bytes,
module_path,
option_env,
stringify,
+ trace_macros,
+};
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow(deprecated)]
+#[doc(no_inline)]
+pub use crate::macros::builtin::{
+ RustcDecodable,
+ RustcEncodable,
+ bench,
+ global_allocator,
test,
test_case,
- trace_macros,
};
/// wrapper types of the form X<'a, P>
macro_rules! derive_pattern_clone {
(clone $t:ident with |$s:ident| $e:expr) => {
- impl<'a, P: Pattern<'a>> Clone for $t<'a, P>
- where P::Searcher: Clone
+ impl<'a, P> Clone for $t<'a, P>
+ where
+ P: Pattern<'a, Searcher: Clone>,
{
fn clone(&self) -> Self {
let $s = self;
pub struct $forward_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>);
$(#[$common_stability_attribute])*
- impl<'a, P: Pattern<'a>> fmt::Debug for $forward_iterator<'a, P>
- where P::Searcher: fmt::Debug
+ impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: fmt::Debug>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple(stringify!($forward_iterator))
}
$(#[$common_stability_attribute])*
- impl<'a, P: Pattern<'a>> Clone for $forward_iterator<'a, P>
- where P::Searcher: Clone
+ impl<'a, P> Clone for $forward_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: Clone>,
{
fn clone(&self) -> Self {
$forward_iterator(self.0.clone())
pub struct $reverse_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>);
$(#[$common_stability_attribute])*
- impl<'a, P: Pattern<'a>> fmt::Debug for $reverse_iterator<'a, P>
- where P::Searcher: fmt::Debug
+ impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: fmt::Debug>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple(stringify!($reverse_iterator))
}
$(#[$common_stability_attribute])*
- impl<'a, P: Pattern<'a>> Iterator for $reverse_iterator<'a, P>
- where P::Searcher: ReverseSearcher<'a>
+ impl<'a, P> Iterator for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
type Item = $iterty;
}
$(#[$common_stability_attribute])*
- impl<'a, P: Pattern<'a>> Clone for $reverse_iterator<'a, P>
- where P::Searcher: Clone
+ impl<'a, P> Clone for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: Clone>,
{
fn clone(&self) -> Self {
$reverse_iterator(self.0.clone())
impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
#[stable(feature = "fused", since = "1.26.0")]
- impl<'a, P: Pattern<'a>> FusedIterator for $reverse_iterator<'a, P>
- where P::Searcher: ReverseSearcher<'a> {}
+ impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+ {}
generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
$forward_iterator,
$reverse_iterator:ident, $iterty:ty
} => {
$(#[$common_stability_attribute])*
- impl<'a, P: Pattern<'a>> DoubleEndedIterator for $forward_iterator<'a, P>
- where P::Searcher: DoubleEndedSearcher<'a>
+ impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
{
#[inline]
fn next_back(&mut self) -> Option<$iterty> {
}
$(#[$common_stability_attribute])*
- impl<'a, P: Pattern<'a>> DoubleEndedIterator for $reverse_iterator<'a, P>
- where P::Searcher: DoubleEndedSearcher<'a>
+ impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
{
#[inline]
fn next_back(&mut self) -> Option<$iterty> {
finished: bool,
}
-impl<'a, P: Pattern<'a>> fmt::Debug for SplitInternal<'a, P> where P::Searcher: fmt::Debug {
+impl<'a, P> fmt::Debug for SplitInternal<'a, P>
+where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SplitInternal")
.field("start", &self.start)
count: usize,
}
-impl<'a, P: Pattern<'a>> fmt::Debug for SplitNInternal<'a, P> where P::Searcher: fmt::Debug {
+impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
+where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SplitNInternal")
.field("iter", &self.iter)
struct MatchIndicesInternal<'a, P: Pattern<'a>>(P::Searcher);
-impl<'a, P: Pattern<'a>> fmt::Debug for MatchIndicesInternal<'a, P> where P::Searcher: fmt::Debug {
+impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
+where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("MatchIndicesInternal")
.field(&self.0)
struct MatchesInternal<'a, P: Pattern<'a>>(P::Searcher);
-impl<'a, P: Pattern<'a>> fmt::Debug for MatchesInternal<'a, P> where P::Searcher: fmt::Debug {
+impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
+where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("MatchesInternal")
.field(&self.0)
/// assert!(!bananas.ends_with("nana"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
- where P::Searcher: ReverseSearcher<'a>
+ pub fn ends_with<'a, P>(&'a self, pat: P) -> bool
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
pat.is_suffix_of(self)
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
- where P::Searcher: ReverseSearcher<'a>
+ pub fn rfind<'a, P>(&'a self, pat: P) -> Option<usize>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
pat.into_searcher(self).next_match_back().map(|(i, _)| i)
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
- where P::Searcher: ReverseSearcher<'a>
+ pub fn rsplit<'a, P>(&'a self, pat: P) -> RSplit<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
RSplit(self.split(pat).0)
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
- where P::Searcher: ReverseSearcher<'a>
+ pub fn rsplit_terminator<'a, P>(&'a self, pat: P) -> RSplitTerminator<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
RSplitTerminator(self.split_terminator(pat).0)
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
- where P::Searcher: ReverseSearcher<'a>
+ pub fn rsplitn<'a, P>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
RSplitN(self.splitn(n, pat).0)
}
/// ```
#[stable(feature = "str_matches", since = "1.2.0")]
#[inline]
- pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
- where P::Searcher: ReverseSearcher<'a>
+ pub fn rmatches<'a, P>(&'a self, pat: P) -> RMatches<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
RMatches(self.matches(pat).0)
}
/// ```
#[stable(feature = "str_match_indices", since = "1.5.0")]
#[inline]
- pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
- where P::Searcher: ReverseSearcher<'a>
+ pub fn rmatch_indices<'a, P>(&'a self, pat: P) -> RMatchIndices<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
RMatchIndices(self.match_indices(pat).0)
}
#[must_use = "this returns the trimmed string as a new slice, \
without modifying the original"]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
- where P::Searcher: DoubleEndedSearcher<'a>
+ pub fn trim_matches<'a, P>(&'a self, pat: P) -> &'a str
+ where
+ P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
{
let mut i = 0;
let mut j = 0;
#[must_use = "this returns the trimmed string as a new slice, \
without modifying the original"]
#[stable(feature = "trim_direction", since = "1.30.0")]
- pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
- where P::Searcher: ReverseSearcher<'a>
+ pub fn trim_end_matches<'a, P>(&'a self, pat: P) -> &'a str
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
let mut j = 0;
let mut matcher = pat.into_searcher(self);
reason = "superseded by `trim_end_matches`",
suggestion = "trim_end_matches",
)]
- pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
- where P::Searcher: ReverseSearcher<'a>
+ pub fn trim_right_matches<'a, P>(&'a self, pat: P) -> &'a str
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
{
self.trim_end_matches(pat)
}
fn zero() {
test_literal!(0.0);
test_literal!(1e-325);
+ #[cfg(not(miri))] // Miri is too slow
test_literal!(1e-326);
#[cfg(not(miri))] // Miri is too slow
test_literal!(1e-500);
assert_almost_eq!(estimate_scaling_factor(1, -1074), -323);
assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309);
- for i in -1074..972 {
+ #[cfg(not(miri))] // Miri is too slow
+ let iter = -1074..972;
+ #[cfg(miri)]
+ let iter = (-1074..972).step_by(37);
+
+ for i in iter {
let expected = super::ldexp_f64(1.0, i).log10().ceil();
assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
}
-#![cfg(not(miri))] // Miri does not implement ldexp, which most tests here need
-
use std::prelude::v1::*;
use std::{str, i16, f32, f64, fmt};
check_shortest!(f(minf32) => b"1", -44);
}
+#[cfg(not(miri))] // Miri is too slow
pub fn f32_exact_sanity_test<F>(mut f: F)
where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
let minf32 = ldexp_f32(1.0, -149);
check_shortest!(f(minf64) => b"5", -323);
}
+#[cfg(not(miri))] // Miri is too slow
pub fn f64_exact_sanity_test<F>(mut f: F)
where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
let minf64 = ldexp_f64(1.0, -1074);
assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", ""));
assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", ""));
+ if cfg!(miri) { // Miri is too slow
+ return;
+ }
+
// very large output
assert_eq!(to_string(f, 1.1, Minus, 80000, false), format!("1.1{:0>79999}", ""));
}
"1.401298464324817070923729583289916131280261941876515771757068283\
8897910826858606014866381883621215820312500000000000000000000000e-45");
+ if cfg!(miri) { // Miri is too slow
+ return;
+ }
+
assert_eq!(to_string(f, f64::MAX, Minus, 1, false), "2e308");
assert_eq!(to_string(f, f64::MAX, Minus, 2, false), "1.8e308");
assert_eq!(to_string(f, f64::MAX, Minus, 4, false), "1.798e308");
assert_eq!(to_string(f, f32::MAX, Minus, 2, false),
"340282346638528859811704183484516925440.00");
+ if cfg!(miri) { // Miri is too slow
+ return;
+ }
+
let minf32 = ldexp_f32(1.0, -149);
assert_eq!(to_string(f, minf32, Minus, 0, false), "0");
assert_eq!(to_string(f, minf32, Minus, 1, false), "0.0");
#[test]
fn shortest_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
- f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
- f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
+ #[cfg(not(miri))] // Miri is too slow
+ const N: usize = 10_000;
+ #[cfg(miri)]
+ const N: usize = 10;
+
+ f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
+ f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
}
#[test] #[ignore] // it is too expensive
#[test]
fn exact_f32_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
+ #[cfg(not(miri))] // Miri is too slow
+ const N: usize = 1_000;
+ #[cfg(miri)]
+ const N: usize = 3;
+
for k in 1..21 {
f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
- |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
+ |d, buf| fallback(d, buf, i16::MIN), k, N);
}
}
#[test]
fn exact_f64_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
+ #[cfg(not(miri))] // Miri is too slow
+ const N: usize = 1_000;
+ #[cfg(miri)]
+ const N: usize = 3;
+
for k in 1..21 {
f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
- |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
+ |d, buf| fallback(d, buf, i16::MIN), k, N);
}
}
}
#[test]
+#[cfg(not(miri))] // Miri is too slow
fn exact_sanity_test() {
// This test ends up running what I can only assume is some corner-ish case
// of the `exp2` library function, defined in whatever C runtime we're
}
#[test]
+#[cfg(not(miri))] // Miri is too slow
fn exact_sanity_test() {
// See comments in dragon.rs's exact_sanity_test for why this test is
// ignored on MSVC
#[test]
fn test_position() {
let b = [1, 2, 3, 5, 5];
- assert!(b.iter().position(|&v| v == 9) == None);
- assert!(b.iter().position(|&v| v == 5) == Some(3));
- assert!(b.iter().position(|&v| v == 3) == Some(2));
- assert!(b.iter().position(|&v| v == 0) == None);
+ assert_eq!(b.iter().position(|&v| v == 9), None);
+ assert_eq!(b.iter().position(|&v| v == 5), Some(3));
+ assert_eq!(b.iter().position(|&v| v == 3), Some(2));
+ assert_eq!(b.iter().position(|&v| v == 0), None);
}
#[test]
fn test_rposition() {
let b = [1, 2, 3, 5, 5];
- assert!(b.iter().rposition(|&v| v == 9) == None);
- assert!(b.iter().rposition(|&v| v == 5) == Some(4));
- assert!(b.iter().rposition(|&v| v == 3) == Some(2));
- assert!(b.iter().rposition(|&v| v == 0) == None);
+ assert_eq!(b.iter().rposition(|&v| v == 9), None);
+ assert_eq!(b.iter().rposition(|&v| v == 5), Some(4));
+ assert_eq!(b.iter().rposition(|&v| v == 3), Some(2));
+ assert_eq!(b.iter().rposition(|&v| v == 0), None);
}
#[test]
}
#[test]
-#[cfg(not(miri))]
+#[cfg(not(miri))] // Miri is too slow
fn brute_force_rotate_test_0() {
// In case of edge cases involving multiple algorithms
let n = 300;
#[test]
fn creation() {
- assert!(Duration::from_secs(1) != Duration::from_secs(0));
+ assert_ne!(Duration::from_secs(1), Duration::from_secs(0));
assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
Duration::from_secs(3));
assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// assert_eq!(dur.as_secs_f64(), 2.7);
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
- pub const fn as_secs_f64(&self) -> f64 {
+ pub fn as_secs_f64(&self) -> f64 {
(self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
}
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// assert_eq!(dur.as_secs_f32(), 2.7);
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
- pub const fn as_secs_f32(&self) -> f32 {
+ pub fn as_secs_f32(&self) -> f32 {
(self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
}
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::from_secs_f64(2.7);
/// assert_eq!(dur, Duration::new(2, 700_000_000));
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn from_secs_f64(secs: f64) -> Duration {
const MAX_NANOS_F64: f64 =
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::from_secs_f32(2.7);
/// assert_eq!(dur, Duration::new(2, 700_000_000));
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn from_secs_f32(secs: f32) -> Duration {
const MAX_NANOS_F32: f32 =
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000));
/// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn mul_f64(self, rhs: f64) -> Duration {
Duration::from_secs_f64(rhs * self.as_secs_f64())
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
/// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn mul_f32(self, rhs: f32) -> Duration {
Duration::from_secs_f32(rhs * self.as_secs_f32())
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// // note that truncation is used, not rounding
/// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn div_f64(self, rhs: f64) -> Duration {
Duration::from_secs_f64(self.as_secs_f64() / rhs)
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// // note that truncation is used, not rounding
/// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn div_f32(self, rhs: f32) -> Duration {
Duration::from_secs_f32(self.as_secs_f32() / rhs)
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
+ /// #![feature(div_duration)]
/// use std::time::Duration;
///
/// let dur1 = Duration::new(2, 700_000_000);
/// let dur2 = Duration::new(5, 400_000_000);
/// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[unstable(feature = "div_duration", issue = "63139")]
#[inline]
pub fn div_duration_f64(self, rhs: Duration) -> f64 {
self.as_secs_f64() / rhs.as_secs_f64()
///
/// # Examples
/// ```
- /// #![feature(duration_float)]
+ /// #![feature(div_duration)]
/// use std::time::Duration;
///
/// let dur1 = Duration::new(2, 700_000_000);
/// let dur2 = Duration::new(5, 400_000_000);
/// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
/// ```
- #[unstable(feature = "duration_float", issue = "54361")]
+ #[unstable(feature = "div_duration", issue = "63139")]
#[inline]
pub fn div_duration_f32(self, rhs: Duration) -> f32 {
self.as_secs_f32() / rhs.as_secs_f32()
micro: 0,
_priv: (),
};
-pub mod general_category {
- pub const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
+pub(crate) mod general_category {
+ const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
r1: &[
0, 1, 0
],
Cc_table.lookup(c)
}
- pub const N_table: &super::BoolTrie = &super::BoolTrie {
+ const N_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x03ff000000000000, 0x0000000000000000, 0x720c000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
}
-pub mod derived_property {
- pub const Alphabetic_table: &super::BoolTrie = &super::BoolTrie {
+pub(crate) mod derived_property {
+ const Alphabetic_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
Alphabetic_table.lookup(c)
}
- pub const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie {
+ const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0400408000000000, 0x0000000140000000, 0x0190a10000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
Case_Ignorable_table.lookup(c)
}
- pub const Cased_table: &super::BoolTrie = &super::BoolTrie {
+ const Cased_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xf7ffffffffffffff, 0xfffffffffffffff0,
Cased_table.lookup(c)
}
- pub const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
+ const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
Grapheme_Extend_table.lookup(c)
}
- pub const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
+ const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x07fffffe00000000, 0x0420040000000000, 0xff7fffff80000000,
0x55aaaaaaaaaaaaaa, 0xd4aaaaaaaaaaab55, 0xe6512d2a4e243129, 0xaa29aaaab5555240,
Lowercase_table.lookup(c)
}
- pub const Uppercase_table: &super::BoolTrie = &super::BoolTrie {
+ const Uppercase_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x0000000007fffffe, 0x0000000000000000, 0x000000007f7fffff,
0xaa55555555555555, 0x2b555555555554aa, 0x11aed2d5b1dbced6, 0x55d255554aaaa490,
Uppercase_table.lookup(c)
}
- pub const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
+ const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
XID_Continue_table.lookup(c)
}
- pub const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
+ const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
r1: [
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
}
-pub mod property {
- pub const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
+pub(crate) mod property {
+ const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
r1: &[
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Pattern_White_Space_table.lookup(c)
}
- pub const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
+ const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
r1: &[
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
}
-pub mod conversions {
+pub(crate) mod conversions {
pub fn to_lower(c: char) -> [char; 3] {
match bsearch_case_table(c, to_lowercase_table) {
None => [c, '\0', '\0'],
return root, child_data
-def generate_bool_trie(name, codepoint_ranges, is_pub=True):
+def generate_bool_trie(name, codepoint_ranges, is_pub=False):
# type: (str, List[Tuple[int, int]], bool) -> Iterator[str]
"""
Generate Rust code for BoolTrie struct.
yield " };\n\n"
-def generate_small_bool_trie(name, codepoint_ranges, is_pub=True):
+def generate_small_bool_trie(name, codepoint_ranges, is_pub=False):
# type: (str, List[Tuple[int, int]], bool) -> Iterator[str]
"""
Generate Rust code for `SmallBoolTrie` struct.
Generate Rust code for module defining properties.
"""
- yield "pub mod %s {\n" % mod
+ yield "pub(crate) mod %s {\n" % mod
for cat in sorted(category_subset):
if cat in ("Cc", "White_Space", "Pattern_White_Space"):
generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat])
Generate Rust code for module defining conversions.
"""
- yield "pub mod conversions {"
+ yield "pub(crate) mod conversions {"
yield """
pub fn to_lower(c: char) -> [char; 3] {
match bsearch_case_table(c, to_lowercase_table) {
self.definitions.def_index_to_hir_id(def_id.to_def_id().index)
}
- fn def_kind(&self, hir_id: HirId) -> Option<DefKind> {
+ pub fn def_kind(&self, hir_id: HirId) -> Option<DefKind> {
let node = if let Some(node) = self.find(hir_id) {
node
} else {
}
}
_ => {
+ // `last_ty` can be `!`, `expected` will have better info when present.
+ let t = self.resolve_vars_if_possible(&match exp_found {
+ Some(ty::error::ExpectedFound { expected, .. }) => expected,
+ _ => last_ty,
+ });
let msg = "`match` arms have incompatible types";
err.span_label(cause.span, msg);
if prior_arms.len() <= 4 {
for sp in prior_arms {
- err.span_label(*sp, format!(
- "this is found to be of type `{}`",
- self.resolve_vars_if_possible(&last_ty),
- ));
+ err.span_label( *sp, format!("this is found to be of type `{}`", t));
}
} else if let Some(sp) = prior_arms.last() {
- err.span_label(*sp, format!(
- "this and all prior arms are found to be of type `{}`", last_ty,
- ));
+ err.span_label(
+ *sp,
+ format!("this and all prior arms are found to be of type `{}`", t),
+ );
}
}
},
}
(_, false, _) => {
if let Some(exp_found) = exp_found {
- let (def_id, ret_ty) = match exp_found.found.sty {
- ty::FnDef(def, _) => {
- (Some(def), Some(self.tcx.fn_sig(def).output()))
- }
- _ => (None, None),
- };
-
- let exp_is_struct = match exp_found.expected.sty {
- ty::Adt(def, _) => def.is_struct(),
- _ => false,
- };
-
- if let (Some(def_id), Some(ret_ty)) = (def_id, ret_ty) {
- if exp_is_struct && &exp_found.expected == ret_ty.skip_binder() {
- let message = format!(
- "did you mean `{}(/* fields */)`?",
- self.tcx.def_path_str(def_id)
- );
- diag.span_label(span, message);
- }
- }
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
}
#![feature(proc_macro_hygiene)]
#![feature(log_syntax)]
#![feature(mem_take)]
+#![feature(associated_type_bounds)]
#![recursion_limit="512"]
// each predicate must be preceded by the obligations required
// to normalize it.
// for example, if we have:
- // impl<U: Iterator, V: Iterator<Item=U>> Foo for V where U::Item: Copy
+ // impl<U: Iterator<Item: Copy>, V: Iterator<Item = U>> Foo for V
// the impl will have the following predicates:
// <V as Iterator>::Item = U,
// U: Iterator, U: Sized,
(chalk_engine::DelayedLiteral::Negative)(a),
(chalk_engine::DelayedLiteral::Positive)(a, b),
} where
- C: chalk_engine::context::Context + Clone,
- C::CanonicalConstrainedSubst: TypeFoldable<'tcx>,
+ C: chalk_engine::context::Context<CanonicalConstrainedSubst: TypeFoldable<'tcx>> + Clone,
}
EnumTypeFoldableImpl! {
(chalk_engine::Literal::Negative)(a),
(chalk_engine::Literal::Positive)(a),
} where
- C: chalk_engine::context::Context + Clone,
- C::GoalInEnvironment: Clone + TypeFoldable<'tcx>,
+ C: chalk_engine::context::Context<GoalInEnvironment: Clone + TypeFoldable<'tcx>> + Clone,
}
CloneTypeFoldableAndLiftImpls! {
unsafety: hir::Unsafety,
abi: abi::Abi)
-> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
- where I: Iterator,
- I::Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>
+ where
+ I: Iterator<Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>,
{
inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
inputs_and_output: self.intern_type_list(xs),
impl<'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
where
- C: LayoutOf<Ty = Ty<'tcx>> + HasTyCtxt<'tcx>,
- C::TyLayout: MaybeResult<TyLayout<'tcx>>,
- C: HasParamEnv<'tcx>,
+ C: LayoutOf<Ty = Ty<'tcx>, TyLayout: MaybeResult<TyLayout<'tcx>>>
+ + HasTyCtxt<'tcx>
+ + HasParamEnv<'tcx>,
{
fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: VariantIdx) -> TyLayout<'tcx> {
let details = match this.variants {
query_result_index: &mut EncodedQueryResultIndex,
) -> Result<(), E::Error>
where
- Q: super::config::QueryDescription<'tcx>,
+ Q: super::config::QueryDescription<'tcx, Value: Encodable>,
E: 'a + TyEncoder,
- Q::Value: Encodable,
{
let desc = &format!("encode_query_results for {}",
::std::any::type_name::<Q>());
}
pub fn args<I>(&mut self, args: I) -> &mut Command
- where I: IntoIterator,
- I::Item: AsRef<OsStr>,
+ where
+ I: IntoIterator<Item: AsRef<OsStr>>,
{
for arg in args {
self._arg(arg.as_ref());
#![feature(nll)]
#![feature(trusted_len)]
#![feature(mem_take)]
+#![feature(associated_type_bounds)]
#![recursion_limit="256"]
#![feature(core_intrinsics)]
#![feature(integer_atomics)]
#![feature(test)]
+#![feature(associated_type_bounds)]
#![cfg_attr(unix, feature(libc))]
}
impl<O, H> OwningHandle<O, H>
- where O: StableAddress, O::Target: ToHandle<Handle = H>, H: Deref,
+where
+ O: StableAddress<Target: ToHandle<Handle = H>>,
+ H: Deref,
{
/// Creates a new `OwningHandle` for a type that implements `ToHandle`. For types
/// that don't implement `ToHandle`, callers may invoke `new_with_fn`, which accepts
}
impl<O, H> OwningHandle<O, H>
- where O: StableAddress, O::Target: ToHandleMut<HandleMut = H>, H: DerefMut,
+where
+ O: StableAddress<Target: ToHandleMut<HandleMut = H>>,
+ H: DerefMut,
{
/// Creates a new mutable `OwningHandle` for a type that implements `ToHandleMut`.
pub fn new_mut(o: O) -> Self {
self.gen_set.insert(e);
self.kill_set.remove(e);
}
- fn gen_all<I>(&mut self, i: I)
- where I: IntoIterator,
- I::Item: Borrow<E>
- {
+
+ fn gen_all(&mut self, i: impl IntoIterator<Item: Borrow<E>>) {
for j in i {
self.gen(*j.borrow());
}
self.kill_set.insert(e);
}
- fn kill_all<I>(&mut self, i: I)
- where I: IntoIterator,
- I::Item: Borrow<E>
- {
+ fn kill_all(&mut self, i: impl IntoIterator<Item: Borrow<E>>) {
for j in i {
self.kill(*j.borrow());
}
#![feature(trusted_len)]
#![feature(try_blocks)]
#![feature(mem_take)]
+#![feature(associated_type_bounds)]
#![recursion_limit="256"]
let vis = match tcx.hir().get(hir_id) {
Node::Item(item) => &item.vis,
Node::ForeignItem(foreign_item) => &foreign_item.vis,
+ Node::MacroDef(macro_def) => {
+ if attr::contains_name(¯o_def.attrs, sym::macro_export) {
+ return (ty::Visibility::Public, macro_def.span, "public");
+ } else {
+ ¯o_def.vis
+ }
+ },
Node::TraitItem(..) | Node::Variant(..) => {
return def_id_visibility(tcx, tcx.hir().get_parent_did(hir_id));
}
struct EmbargoVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
- // Accessibility levels for reachable nodes.
+ /// Accessibility levels for reachable nodes.
access_levels: AccessLevels,
- // Previous accessibility level; `None` means unreachable.
+ /// A set of pairs corresponding to modules, where the first module is
+ /// reachable via a macro that's defined in the second module. This cannot
+ /// be represented as reachable because it can't handle the following case:
+ ///
+ /// pub mod n { // Should be `Public`
+ /// pub(crate) mod p { // Should *not* be accessible
+ /// pub fn f() -> i32 { 12 } // Must be `Reachable`
+ /// }
+ /// }
+ /// pub macro m() {
+ /// n::p::f()
+ /// }
+ macro_reachable: FxHashSet<(hir::HirId, DefId)>,
+ /// Previous accessibility level; `None` means unreachable.
prev_level: Option<AccessLevel>,
- // Has something changed in the level map?
+ /// Has something changed in the level map?
changed: bool,
}
self.access_levels.map.get(&id).cloned()
}
- // Updates node level and returns the updated level.
+ /// Updates node level and returns the updated level.
fn update(&mut self, id: hir::HirId, level: Option<AccessLevel>) -> Option<AccessLevel> {
let old_level = self.get(id);
// Accessibility levels can only grow.
}
}
+ /// Updates the item as being reachable through a macro defined in the given
+ /// module. Returns `true` if the level has changed.
+ fn update_macro_reachable(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) -> bool {
+ if self.macro_reachable.insert((reachable_mod, defining_mod)) {
+ self.update_macro_reachable_mod(reachable_mod, defining_mod);
+ true
+ } else {
+ false
+ }
+ }
+
+ fn update_macro_reachable_mod(
+ &mut self,
+ reachable_mod: hir::HirId,
+ defining_mod: DefId,
+ ) {
+ let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
+ let module = self.tcx.hir().get_module(module_def_id).0;
+ for item_id in &module.item_ids {
+ let hir_id = item_id.id;
+ let item_def_id = self.tcx.hir().local_def_id(hir_id);
+ if let Some(def_kind) = self.tcx.def_kind(item_def_id) {
+ let item = self.tcx.hir().expect_item(hir_id);
+ let vis = ty::Visibility::from_hir(&item.vis, hir_id, self.tcx);
+ self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
+ }
+ }
+
+ if let Some(exports) = self.tcx.module_exports(module_def_id) {
+ for export in exports {
+ if export.vis.is_accessible_from(defining_mod, self.tcx) {
+ if let Res::Def(def_kind, def_id) = export.res {
+ let vis = def_id_visibility(self.tcx, def_id).0;
+ if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
+ self.update_macro_reachable_def(
+ hir_id,
+ def_kind,
+ vis,
+ defining_mod,
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ fn update_macro_reachable_def(
+ &mut self,
+ hir_id: hir::HirId,
+ def_kind: DefKind,
+ vis: ty::Visibility,
+ module: DefId,
+ ) {
+ let level = Some(AccessLevel::Reachable);
+ if let ty::Visibility::Public = vis {
+ self.update(hir_id, level);
+ }
+ match def_kind {
+ // No type privacy, so can be directly marked as reachable.
+ DefKind::Const
+ | DefKind::Macro(_)
+ | DefKind::Static
+ | DefKind::TraitAlias
+ | DefKind::TyAlias => {
+ if vis.is_accessible_from(module, self.tcx) {
+ self.update(hir_id, level);
+ }
+ },
+
+ // We can't use a module name as the final segment of a path, except
+ // in use statements. Since re-export checking doesn't consider
+ // hygiene these don't need to be marked reachable. The contents of
+ // the module, however may be reachable.
+ DefKind::Mod => {
+ if vis.is_accessible_from(module, self.tcx) {
+ self.update_macro_reachable(hir_id, module);
+ }
+ }
+
+ DefKind::Struct | DefKind::Union => {
+ // While structs and unions have type privacy, their fields do
+ // not.
+ if let ty::Visibility::Public = vis {
+ let item = self.tcx.hir().expect_item(hir_id);
+ if let hir::ItemKind::Struct(ref struct_def, _)
+ | hir::ItemKind::Union(ref struct_def, _) = item.node
+ {
+ for field in struct_def.fields() {
+ let field_vis = ty::Visibility::from_hir(
+ &field.vis,
+ field.hir_id,
+ self.tcx,
+ );
+ if field_vis.is_accessible_from(module, self.tcx) {
+ self.reach(field.hir_id, level).ty();
+ }
+ }
+ } else {
+ bug!("item {:?} with DefKind {:?}", item, def_kind);
+ }
+ }
+ }
+
+ // These have type privacy, so are not reachable unless they're
+ // public
+ DefKind::AssocConst
+ | DefKind::AssocTy
+ | DefKind::AssocOpaqueTy
+ | DefKind::ConstParam
+ | DefKind::Ctor(_, _)
+ | DefKind::Enum
+ | DefKind::ForeignTy
+ | DefKind::Fn
+ | DefKind::OpaqueTy
+ | DefKind::Method
+ | DefKind::Trait
+ | DefKind::TyParam
+ | DefKind::Variant => (),
+ }
+ }
/// Given the path segments of a `ItemKind::Use`, then we need
/// to update the visibility of the intermediate use so that it isn't linted
return
}
- let module_did = ty::DefIdTree::parent(
+ let macro_module_def_id = ty::DefIdTree::parent(
self.tcx,
self.tcx.hir().local_def_id(md.hir_id)
).unwrap();
- let mut module_id = self.tcx.hir().as_local_hir_id(module_did).unwrap();
+ let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap();
let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
- let level = self.update(md.hir_id, level);
- if level.is_none() {
+ let new_level = self.update(md.hir_id, level);
+ if new_level.is_none() {
return
}
loop {
- let module = if module_id == hir::CRATE_HIR_ID {
- &self.tcx.hir().krate().module
- } else if let hir::ItemKind::Mod(ref module) =
- self.tcx.hir().expect_item(module_id).node {
- module
- } else {
- unreachable!()
- };
- for id in &module.item_ids {
- self.update(id.id, level);
- }
- let def_id = self.tcx.hir().local_def_id(module_id);
- if let Some(exports) = self.tcx.module_exports(def_id) {
- for export in exports.iter() {
- if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.res.def_id()) {
- self.update(hir_id, level);
- }
- }
- }
-
- if module_id == hir::CRATE_HIR_ID {
- break
+ let changed_reachability = self.update_macro_reachable(module_id, macro_module_def_id);
+ if changed_reachability || module_id == hir::CRATE_HIR_ID {
+ break;
}
module_id = self.tcx.hir().get_parent_node(module_id);
}
fn tcx(&self) -> TyCtxt<'tcx> { self.ev.tcx }
fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) -> bool {
if let Some(hir_id) = self.ev.tcx.hir().as_local_hir_id(def_id) {
- self.ev.update(hir_id, self.access_level);
+ if let ((ty::Visibility::Public, ..), _)
+ | (_, Some(AccessLevel::ReachableFromImplTrait))
+ = (def_id_visibility(self.tcx(), def_id), self.access_level)
+ {
+ self.ev.update(hir_id, self.access_level);
+ }
}
false
}
let mut visitor = EmbargoVisitor {
tcx,
access_levels: Default::default(),
+ macro_reachable: Default::default(),
prev_level: Some(AccessLevel::Public),
changed: false,
};
coerce.coerce(self, &cause, e, e_ty);
} else {
assert!(e_ty.is_unit());
- coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
+ let ty = coerce.expected_ty();
+ coerce.coerce_forced_unit(self, &cause, &mut |err| {
+ let val = match ty.sty {
+ ty::Bool => "true",
+ ty::Char => "'a'",
+ ty::Int(_) | ty::Uint(_) => "42",
+ ty::Float(_) => "3.14159",
+ ty::Error | ty::Never => return,
+ _ => "value",
+ };
+ let msg = "give it a value of the expected type";
+ let label = destination.label
+ .map(|l| format!(" {}", l.ident))
+ .unwrap_or_else(String::new);
+ let sugg = format!("break{} {}", label, val);
+ err.span_suggestion(expr.span, msg, sugg, Applicability::HasPlaceholders);
+ }, false);
}
} else {
// If `ctxt.coerce` is `None`, we can just ignore
self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
}
if let Some(fn_span) = fn_span {
- err.span_label(fn_span, "this function's body doesn't return");
+ err.span_label(
+ fn_span,
+ "implicitly returns `()` as its body has no tail or `return` \
+ expression",
+ );
}
}, false);
}
pointing_at_return_type
}
+ /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
+ /// the ctor would successfully solve the type mismatch and if so, suggest it:
+ /// ```
+ /// fn foo(x: usize) -> usize { x }
+ /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
+ /// ```
+ fn suggest_fn_call(
+ &self,
+ err: &mut DiagnosticBuilder<'tcx>,
+ expr: &hir::Expr,
+ expected: Ty<'tcx>,
+ found: Ty<'tcx>,
+ ) -> bool {
+ match found.sty {
+ ty::FnDef(..) | ty::FnPtr(_) => {}
+ _ => return false,
+ }
+ let hir = self.tcx.hir();
+
+ let sig = found.fn_sig(self.tcx);
+ let sig = self
+ .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
+ .0;
+ let sig = self.normalize_associated_types_in(expr.span, &sig);
+ if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) {
+ let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
+ (String::new(), Applicability::MachineApplicable)
+ } else {
+ ("...".to_string(), Applicability::HasPlaceholders)
+ };
+ let mut msg = "call this function";
+ if let ty::FnDef(def_id, ..) = found.sty {
+ match hir.get_if_local(def_id) {
+ Some(Node::Item(hir::Item {
+ node: ItemKind::Fn(.., body_id),
+ ..
+ })) |
+ Some(Node::ImplItem(hir::ImplItem {
+ node: hir::ImplItemKind::Method(_, body_id),
+ ..
+ })) |
+ Some(Node::TraitItem(hir::TraitItem {
+ node: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
+ ..
+ })) => {
+ let body = hir.body(*body_id);
+ sugg_call = body.arguments.iter()
+ .map(|arg| match &arg.pat.node {
+ hir::PatKind::Binding(_, _, ident, None)
+ if ident.name != kw::SelfLower => ident.to_string(),
+ _ => "_".to_string(),
+ }).collect::<Vec<_>>().join(", ");
+ }
+ Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
+ sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
+ match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
+ Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
+ msg = "instantiate this tuple variant";
+ }
+ Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
+ msg = "instantiate this tuple struct";
+ }
+ _ => {}
+ }
+ }
+ Some(Node::ForeignItem(hir::ForeignItem {
+ node: hir::ForeignItemKind::Fn(_, idents, _),
+ ..
+ })) |
+ Some(Node::TraitItem(hir::TraitItem {
+ node: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
+ ..
+ })) => sugg_call = idents.iter()
+ .map(|ident| if ident.name != kw::SelfLower {
+ ident.to_string()
+ } else {
+ "_".to_string()
+ }).collect::<Vec<_>>()
+ .join(", "),
+ _ => {}
+ }
+ };
+ if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
+ err.span_suggestion(
+ expr.span,
+ &format!("use parentheses to {}", msg),
+ format!("{}({})", code, sugg_call),
+ applicability,
+ );
+ return true;
+ }
+ }
+ false
+ }
+
pub fn suggest_ref_or_into(
&self,
err: &mut DiagnosticBuilder<'tcx>,
suggestion,
Applicability::MachineApplicable,
);
+ } else if let (ty::FnDef(def_id, ..), true) = (
+ &found.sty,
+ self.suggest_fn_call(err, expr, expected, found),
+ ) {
+ if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
+ let sp = self.sess().source_map().def_span(sp);
+ err.span_label(sp, &format!("{} defined here", found));
+ }
} else if !self.check_for_cast(err, expr, found, expected) {
let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
expr.hir_id,
use smallvec::{Array, SmallVec};
-impl<A> Encodable for SmallVec<A>
- where A: Array,
- A::Item: Encodable
-{
+impl<A: Array<Item: Encodable>> Encodable for SmallVec<A> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_seq(self.len(), |s| {
for (i, e) in self.iter().enumerate() {
}
}
-impl<A> Decodable for SmallVec<A>
- where A: Array,
- A::Item: Decodable
-{
+impl<A: Array<Item: Decodable>> Decodable for SmallVec<A> {
fn decode<D: Decoder>(d: &mut D) -> Result<SmallVec<A>, D::Error> {
d.read_seq(|d, len| {
let mut vec = SmallVec::with_capacity(len);
#![feature(specialization)]
#![feature(never_type)]
#![feature(nll)]
+#![feature(associated_type_bounds)]
#![cfg_attr(test, feature(test))]
pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
#![feature(arbitrary_self_types)]
#![feature(array_error_internals)]
#![feature(asm)]
+#![feature(associated_type_bounds)]
#![feature(bind_by_move_pattern_guards)]
#![feature(box_syntax)]
#![feature(c_variadic)]
// Access to Bencher, etc.
#[cfg(test)] extern crate test;
-// Re-export a few macros from core
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use core::{unreachable, unimplemented, write, writeln, r#try, todo};
-
#[allow(unused_imports)] // macros from `alloc` are not used on all platforms
#[macro_use]
extern crate alloc as alloc_crate;
#[cfg(not(test))]
pub use std_detect::detect;
-// Document built-in macros in the crate root for consistency with libcore and existing tradition.
-// FIXME: Attribute and derive macros are not reexported because rustdoc renders them
-// as reexports rather than as macros, and that's not what we want.
-#[cfg(rustdoc)]
+// Re-export macros defined in libcore.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated_in_future)]
+pub use core::{
+ // Stable
+ assert_eq,
+ assert_ne,
+ debug_assert_eq,
+ debug_assert_ne,
+ debug_assert,
+ r#try,
+ unimplemented,
+ unreachable,
+ write,
+ writeln,
+ // Unstable
+ todo,
+};
+
+// Re-export built-in macros defined through libcore.
+#[cfg(not(bootstrap))]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
-pub use crate::prelude::v1::{
- __rust_unstable_column,
- asm,
+pub use core::{
+ // Stable
assert,
cfg,
column,
compile_error,
concat,
- concat_idents,
env,
file,
format_args,
- format_args_nl,
- global_asm,
include,
include_bytes,
include_str,
line,
- log_syntax,
module_path,
option_env,
stringify,
+ // Unstable
+ __rust_unstable_column,
+ asm,
+ concat_idents,
+ format_args_nl,
+ global_asm,
+ log_syntax,
trace_macros,
};
impl<T: CoerceUnsized<U>, U> CoerceUnsized<UserRef<U>> for UserRef<T> {}
#[unstable(feature = "sgx_platform", issue = "56975")]
-impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe {
+impl<T, I> Index<I> for UserRef<[T]>
+where
+ [T]: UserSafe,
+ I: SliceIndex<[T], Output: UserSafe>,
+{
type Output = UserRef<I::Output>;
#[inline]
}
#[unstable(feature = "sgx_platform", issue = "56975")]
-impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe {
+impl<T, I> IndexMut<I> for UserRef<[T]>
+where
+ [T]: UserSafe,
+ I: SliceIndex<[T], Output: UserSafe>,
+{
#[inline]
fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
unsafe {
use crate::ext::base::*;
use crate::ext::proc_macro::collect_derives;
use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind};
+use crate::ext::tt::macro_rules::annotate_err_with_kind;
use crate::ext::placeholders::{placeholder, PlaceholderExpander};
use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
use crate::mut_visit::*;
);
}
- fn parse_ast_fragment(&mut self,
- toks: TokenStream,
- kind: AstFragmentKind,
- path: &Path,
- span: Span)
- -> AstFragment {
+ fn parse_ast_fragment(
+ &mut self,
+ toks: TokenStream,
+ kind: AstFragmentKind,
+ path: &Path,
+ span: Span,
+ ) -> AstFragment {
let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
match parser.parse_ast_fragment(kind, false) {
Ok(fragment) => {
}
Err(mut err) => {
err.set_span(span);
+ annotate_err_with_kind(&mut err, kind, span);
err.emit();
self.cx.trace_macros_diag();
kind.dummy(span)
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
use crate::{ast, attr, attr::TransparencyError};
-use errors::FatalError;
+use errors::{DiagnosticBuilder, FatalError};
use log::debug;
use syntax_pos::Span;
arm_span: Span,
}
+pub fn annotate_err_with_kind(err: &mut DiagnosticBuilder<'_>, kind: AstFragmentKind, span: Span) {
+ match kind {
+ AstFragmentKind::Ty => {
+ err.span_label(span, "this macro call doesn't expand to a type");
+ }
+ AstFragmentKind::Pat => {
+ err.span_label(span, "this macro call doesn't expand to a pattern");
+ }
+ _ => {}
+ };
+}
+
impl<'a> ParserAnyMacro<'a> {
pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
} else if !parser.sess.source_map().span_to_filename(parser.token.span).is_real() {
e.span_label(site_span, "in this macro invocation");
}
+ match kind {
+ AstFragmentKind::Pat if macro_ident.name == sym::vec => {
+ let mut suggestion = None;
+ if let Ok(code) = parser.sess.source_map().span_to_snippet(site_span) {
+ if let Some(bang) = code.find('!') {
+ suggestion = Some(code[bang + 1..].to_string());
+ }
+ }
+ if let Some(suggestion) = suggestion {
+ e.span_suggestion(
+ site_span,
+ "use a slice pattern here instead",
+ suggestion,
+ Applicability::MachineApplicable,
+ );
+ } else {
+ e.span_label(
+ site_span,
+ "use a slice pattern here instead",
+ );
+ }
+ e.help("for more information, see https://doc.rust-lang.org/edition-guide/\
+ rust-2018/slice-patterns.html");
+ }
+ _ => annotate_err_with_kind(&mut e, kind, site_span),
+ };
e
}));
while self.token != token::CloseDelim(token::Paren) {
es.push(match self.parse_expr() {
Ok(es) => es,
- Err(err) => {
+ Err(mut err) => {
// recover from parse error in tuple list
- return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err)));
+ match self.token.kind {
+ token::Ident(name, false)
+ if name == kw::Underscore && self.look_ahead(1, |t| {
+ t == &token::Comma
+ }) => {
+ // Special-case handling of `Foo<(_, _, _)>`
+ err.emit();
+ let sp = self.token.span;
+ self.bump();
+ self.mk_expr(sp, ExprKind::Err, ThinVec::new())
+ }
+ _ => return Ok(
+ self.recover_seq_parse_error(token::Paren, lo, Err(err)),
+ ),
+ }
}
});
recovered = self.expect_one_of(
}
/// Parses `a.b` or `a(13)` or `a[4]` or just `a`.
- fn parse_dot_or_call_expr(&mut self,
- already_parsed_attrs: Option<ThinVec<Attribute>>)
- -> PResult<'a, P<Expr>> {
+ fn parse_dot_or_call_expr(
+ &mut self,
+ already_parsed_attrs: Option<ThinVec<Attribute>>,
+ ) -> PResult<'a, P<Expr>> {
let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
let b = self.parse_bottom_expr();
self.parse_dot_or_call_expr_with(b, span, attrs)
}
- fn parse_dot_or_call_expr_with(&mut self,
- e0: P<Expr>,
- lo: Span,
- mut attrs: ThinVec<Attribute>)
- -> PResult<'a, P<Expr>> {
+ fn parse_dot_or_call_expr_with(
+ &mut self,
+ e0: P<Expr>,
+ lo: Span,
+ mut attrs: ThinVec<Attribute>,
+ ) -> PResult<'a, P<Expr>> {
// Stitch the list of outer attributes onto the return value.
// A little bit ugly, but the best way given the current code
// structure
- self.parse_dot_or_call_expr_with_(e0, lo)
- .map(|expr|
+ self.parse_dot_or_call_expr_with_(e0, lo).map(|expr|
expr.map(|mut expr| {
attrs.extend::<Vec<_>>(expr.attrs.into());
expr.attrs = attrs;
ExprKind::If(..) if !expr.attrs.is_empty() => {
// Just point to the first attribute in there...
let span = expr.attrs[0].span;
-
- self.span_err(span,
- "attributes are not yet allowed on `if` \
- expressions");
+ self.span_err(span, "attributes are not yet allowed on `if` expressions");
}
_ => {}
}
}
fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec<P<Expr>>> {
- self.parse_paren_comma_seq(|p| p.parse_expr()).map(|(r, _)| r)
+ self.parse_paren_comma_seq(|p| {
+ match p.parse_expr() {
+ Ok(expr) => Ok(expr),
+ Err(mut err) => match p.token.kind {
+ token::Ident(name, false)
+ if name == kw::Underscore && p.look_ahead(1, |t| {
+ t == &token::Comma
+ }) => {
+ // Special-case handling of `foo(_, _, _)`
+ err.emit();
+ let sp = p.token.span;
+ p.bump();
+ Ok(p.mk_expr(sp, ExprKind::Err, ThinVec::new()))
+ }
+ _ => Err(err),
+ },
+ }
+ }).map(|(r, _)| r)
}
crate fn process_potential_macro_variable(&mut self) {
/// This parses an expression accounting for associativity and precedence of the operators in
/// the expression.
#[inline]
- fn parse_assoc_expr(&mut self,
- already_parsed_attrs: Option<ThinVec<Attribute>>)
- -> PResult<'a, P<Expr>> {
+ fn parse_assoc_expr(
+ &mut self,
+ already_parsed_attrs: Option<ThinVec<Attribute>>,
+ ) -> PResult<'a, P<Expr>> {
self.parse_assoc_expr_with(0, already_parsed_attrs.into())
}
let mut heads = Vec::with_capacity(self.args.len());
let names_pos: Vec<_> = (0..self.args.len())
- .map(|i| self.ecx.ident_of(&format!("arg{}", i)).gensym())
+ .map(|i| ast::Ident::from_str_and_span(&format!("arg{}", i), self.macsp))
.collect();
// First, build up the static array which will become our precompiled
let arg_unique_types: Vec<_> = (0..args.len()).map(|_| Vec::new()).collect();
let mut macsp = ecx.call_site();
- macsp = macsp.apply_mark(ecx.current_expansion.id);
+ macsp = macsp.with_ctxt(ecx.backtrace());
let msg = "format argument must be a string literal";
let fmt_sp = efmt.span;
-Subproject commit f2b0c67661f19bb2564225d47aca424ad0449791
+Subproject commit 48818e9f5d0f2d5978a9b43ad1a2e8d0b83f6aa0
// check-pass
+#![allow(deprecated)]
+
pub type ParseResult<T> = Result<T, ()>;
pub enum Item<'a> {
LL | fn return_targets_async_block_not_fn() -> u8 {
| --------------------------------- ^^ expected u8, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `u8`
found type `()`
LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
| ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `std::result::Result<u8, MyErr>`
found type `()`
LL | fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
| ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `std::result::Result<u8, MyErr>`
found type `()`
LL | fn f() -> String {
| - ^^^^^^ expected struct `std::string::String`, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
LL | 0u8;
LL | "bla".to_string();
| - help: consider removing this semicolon
LL | fn g() -> String {
| - ^^^^^^ expected struct `std::string::String`, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
LL | "this won't work".to_string();
LL | "removeme".to_string();
| - help: consider removing this semicolon
LL | fn blah() -> i32 {
| ---- ^^^ expected i32, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
...
LL | ;
| - help: consider removing this semicolon
LL | fn foo() -> String {
| --- ^^^^^^ expected struct `std::string::String`, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
...
LL | ;
| - help: consider removing this semicolon
LL | fn bar() -> String {
| --- ^^^^^^ expected struct `std::string::String`, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
LL | "foobar".to_string()
LL | ;
| - help: consider removing this semicolon
LL | fn plus_one(x: i32) -> i32 {
| -------- ^^^ expected i32, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
LL | x + 1;
| - help: consider removing this semicolon
|
LL | fn foo() -> Result<u8, u64> {
| --- ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
LL | Ok(1);
| - help: consider removing this semicolon
|
--- /dev/null
+#![feature(decl_macro)]
+
+mod n {
+ pub struct B(pub(crate) p::C);
+ impl B {
+ pub fn new() -> Self {
+ B(p::C)
+ }
+ }
+ mod p {
+ pub struct C;
+
+ impl C {
+ pub fn foo(&self) -> i32 {
+ 33
+ }
+ }
+ }
+}
+
+pub macro m() {
+ n::B::new().0.foo()
+}
--- /dev/null
+#![feature(decl_macro)]
+
+mod n {
+ pub(crate) mod p {
+ pub fn f() -> i32 { 12 }
+ }
+}
+
+pub macro m() {
+ n::p::f()
+}
--- /dev/null
+#![feature(decl_macro)]
+
+mod n {
+ pub static S: i32 = 57;
+}
+
+use n::S;
+
+pub macro m() {
+ S
+}
--- /dev/null
+// Check that functions accessible through a field visible to a macro are
+// considered reachable
+
+// aux-build:nested-fn-macro.rs
+// run-pass
+
+extern crate nested_fn_macro;
+
+fn main() {
+ assert_eq!(nested_fn_macro::m!(), 12);
+}
--- /dev/null
+// Check that functions visible to macros through paths with >2 segements are
+// considered reachable
+
+// aux-build:field-method-macro.rs
+// run-pass
+
+extern crate field_method_macro;
+
+fn main() {
+ assert_eq!(field_method_macro::m!(), 33);
+}
--- /dev/null
+// Check that we don't require stability annotations for private modules,
+// imports and fields that are accessible to opaque macros.
+
+// check-pass
+
+#![feature(decl_macro, staged_api)]
+#![stable(feature = "test", since = "1.0.0")]
+
+extern crate std as local_std;
+use local_std::marker::Copy as LocalCopy;
+mod private_mod {
+ #[stable(feature = "test", since = "1.0.0")]
+ pub struct A {
+ pub(crate) f: i32,
+ }
+}
+
+#[stable(feature = "test", since = "1.0.0")]
+pub macro m() {}
+
+fn main() {}
--- /dev/null
+// Check that type privacy is taken into account when considering reachability
+
+// check-pass
+
+#![feature(decl_macro, staged_api)]
+#![stable(feature = "test", since = "1.0.0")]
+
+// Type privacy should prevent use of these in other crates, so we shouldn't
+// need a stability annotation.
+fn private_function() {}
+struct PrivateStruct { f: () }
+enum PrivateEnum { V }
+union PrivateUnion { g: () }
+trait PrivateTrait {}
+
+#[stable(feature = "test", since = "1.0.0")]
+pub macro m() {}
+
+fn main() {}
--- /dev/null
+// Check that private use statements can be used by
+
+// run-pass
+// aux-build:private-use-macro.rs
+
+extern crate private_use_macro;
+
+fn main() {
+ assert_eq!(private_use_macro::m!(), 57);
+}
// Test that the resolve failure does not lead to downstream type errors.
// See issue #31997.
+#![allow(deprecated)]
trait TheTrait { }
error[E0425]: cannot find function `bar` in this scope
- --> $DIR/issue-31997.rs:13:21
+ --> $DIR/issue-31997.rs:14:21
|
LL | try!(closure(|| bar(core::ptr::null_mut())));
| ^^^ not found in this scope
+++ /dev/null
-// run-pass
-
-#![allow(non_upper_case_globals)]
-pub const arg0: u8 = 1;
-
-pub fn main() {
- format!("{}", 1);
-}
--- /dev/null
+// check-pass
+
+#![allow(non_upper_case_globals)]
+#![feature(format_args_nl)]
+
+static arg0: () = ();
+
+fn main() {
+ static arg1: () = ();
+ format_args!("{} {:?}", 0, 1);
+ format_args_nl!("{} {:?}", 0, 1);
+}
// Macro from prelude is shadowed by non-existent import recovered as `Res::Err`.
-use std::assert; //~ ERROR unresolved import `std::assert`
+mod m {}
+use m::assert; //~ ERROR unresolved import `m::assert`
fn main() {
assert!(true);
-error[E0432]: unresolved import `std::assert`
- --> $DIR/issue-53512.rs:3:5
+error[E0432]: unresolved import `m::assert`
+ --> $DIR/issue-53512.rs:4:5
|
-LL | use std::assert;
- | ^^^^^^^^^^^ no `assert` in the root
+LL | use m::assert;
+ | ^^^^^^^^^ no `assert` in `m`
error: aborting due to previous error
--> $DIR/issue-27042.rs:6:16
|
LL | loop { break };
- | ^^^^^ expected (), found i32
+ | ^^^^^
+ | |
+ | expected i32, found ()
+ | help: give it a value of the expected type: `break 42`
|
- = note: expected type `()`
- found type `i32`
+ = note: expected type `i32`
+ found type `()`
error[E0308]: mismatched types
--> $DIR/issue-27042.rs:8:9
LL | pub fn f<'a, T: Tr<'a>>() -> <T as Tr<'a>>::Out {}
| - ^^^^^^^^^^^^^^^^^^ expected associated type, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `<T as Tr<'a>>::Out`
found type `()`
//~| ERROR mismatched types
//~| ERROR invalid left-hand side expression
//~| ERROR expected expression, found reserved identifier `_`
+ //~| ERROR expected expression, found reserved identifier `_`
let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
//~^ ERROR no method named `iter` found for type `()` in the current scope
}
LL | let sr: Vec<(u32, _, _) = vec![];
| ^ expected expression
+error: expected expression, found reserved identifier `_`
+ --> $DIR/issue-34334.rs:2:26
+ |
+LL | let sr: Vec<(u32, _, _) = vec![];
+ | ^ expected expression
+
error: expected one of `,` or `>`, found `=`
--> $DIR/issue-34334.rs:2:29
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ left-hand of expression not valid
error[E0599]: no method named `iter` found for type `()` in the current scope
- --> $DIR/issue-34334.rs:8:36
+ --> $DIR/issue-34334.rs:9:36
|
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
| ^^^^
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
Some errors have detailed explanations: E0070, E0308, E0423, E0599.
For more information about an error, try `rustc --explain E0070`.
error[E0308]: mismatched types
--> $DIR/issue-35241.rs:3:20
|
+LL | struct Foo(u32);
+ | ---------------- fn(u32) -> Foo {Foo} defined here
+LL |
LL | fn test() -> Foo { Foo }
| --- ^^^
| | |
| | expected struct `Foo`, found fn item
- | | did you mean `Foo(/* fields */)`?
+ | | help: use parentheses to instantiate this tuple struct: `Foo(_)`
| expected `Foo` because of return type
|
= note: expected type `Foo`
LL | fn foo() -> bool {
| --- ^^^^ expected bool, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
LL |
LL | break true;
| - help: consider removing this semicolon
--- /dev/null
+pub trait Trait<'a> {
+ type Assoc;
+}
+
+pub struct Type;
+
+impl<'a> Trait<'a> for Type {
+ type Assoc = ();
+}
+
+pub fn break_me<T, F>(f: F)
+where T: for<'b> Trait<'b>,
+ F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
+ break_me::<Type, fn(_)>;
+ //~^ ERROR: type mismatch in function arguments
+ //~| ERROR: type mismatch resolving
+}
+
+fn main() {}
--- /dev/null
+error[E0631]: type mismatch in function arguments
+ --> $DIR/issue-43623.rs:14:5
+ |
+LL | break_me::<Type, fn(_)>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
+ | found signature of `fn(_) -> _`
+ |
+note: required by `break_me`
+ --> $DIR/issue-43623.rs:11:1
+ |
+LL | / pub fn break_me<T, F>(f: F)
+LL | | where T: for<'b> Trait<'b>,
+LL | | F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
+LL | | break_me::<Type, fn(_)>;
+LL | |
+LL | |
+LL | | }
+ | |_^
+
+error[E0271]: type mismatch resolving `for<'b> <fn(_) as std::ops::FnOnce<(<Type as Trait<'b>>::Assoc,)>>::Output == ()`
+ --> $DIR/issue-43623.rs:14:5
+ |
+LL | break_me::<Type, fn(_)>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
+ |
+note: required by `break_me`
+ --> $DIR/issue-43623.rs:11:1
+ |
+LL | / pub fn break_me<T, F>(f: F)
+LL | | where T: for<'b> Trait<'b>,
+LL | | F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
+LL | | break_me::<Type, fn(_)>;
+LL | |
+LL | |
+LL | | }
+ | |_^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize {
| ------------------------ ^^^^^ expected isize, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `isize`
found type `()`
--- /dev/null
+use std::ops::Index;
+
+struct Test;
+struct Container(Test);
+
+impl Test {
+ fn test(&mut self) {}
+}
+
+impl<'a> Index<&'a bool> for Container {
+ type Output = Test;
+
+ fn index(&self, _index: &'a bool) -> &Test {
+ &self.0
+ }
+}
+
+fn main() {
+ let container = Container(Test);
+ let mut val = true;
+ container[&mut val].test(); //~ ERROR: cannot borrow data
+}
--- /dev/null
+error[E0596]: cannot borrow data in an index of `Container` as mutable
+ --> $DIR/issue-44405.rs:21:5
+ |
+LL | container[&mut val].test();
+ | ^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
+ |
+ = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `Container`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
LL | fn foo(b: bool) -> Result<bool,String> {
| --- ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
LL | Err("bar".to_string());
| - help: consider removing this semicolon
|
#![deny(unused_qualifications)]
+#[allow(deprecated)]
mod foo {
pub fn bar() {}
error: unnecessary qualification
- --> $DIR/lint-qualification.rs:9:5
+ --> $DIR/lint-qualification.rs:10:5
|
LL | foo::bar();
| ^^^^^^^^
LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; }
| - ^^^^^ expected isize, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `isize`
found type `()`
LL | fn f() -> isize {
| - ^^^^^ expected isize, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `isize`
found type `()`
| --- ^^^ - help: consider removing this semicolon
| | |
| | expected i32, found ()
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
...
LL | test!();
| -------- in this macro invocation
LL | fn no_return() -> i32 {}
| --------- ^^^ expected i32, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `i32`
found type `()`
LL | fn bar(x: u32) -> u32 {
| --- ^^^ expected u32, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
LL | x * 2;
| - help: consider removing this semicolon
|
LL | fn baz(x: u64) -> u32 {
| --- ^^^ expected u32, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `u32`
found type `()`
--> $DIR/loop-break-value.rs:4:31
|
LL | let val: ! = loop { break break; };
- | ^^^^^ expected (), found !
+ | ^^^^^ expected !, found ()
|
- = note: expected type `()`
- found type `!`
+ = note: expected type `!`
+ found type `()`
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:11:19
--> $DIR/loop-break-value.rs:90:9
|
LL | break;
- | ^^^^^ expected (), found integer
+ | ^^^^^
+ | |
+ | expected integer, found ()
+ | help: give it a value of the expected type: `break value`
|
- = note: expected type `()`
- found type `{integer}`
+ = note: expected type `{integer}`
+ found type `()`
error: aborting due to 16 previous errors
--> $DIR/loop-labeled-break-value.rs:3:29
|
LL | let _: i32 = loop { break };
- | ^^^^^ expected (), found i32
+ | ^^^^^
+ | |
+ | expected i32, found ()
+ | help: give it a value of the expected type: `break 42`
|
- = note: expected type `()`
- found type `i32`
+ = note: expected type `i32`
+ found type `()`
error[E0308]: mismatched types
--> $DIR/loop-labeled-break-value.rs:6:37
|
LL | let _: i32 = 'inner: loop { break 'inner };
- | ^^^^^^^^^^^^ expected (), found i32
+ | ^^^^^^^^^^^^
+ | |
+ | expected i32, found ()
+ | help: give it a value of the expected type: `break 'inner 42`
|
- = note: expected type `()`
- found type `i32`
+ = note: expected type `i32`
+ found type `()`
error[E0308]: mismatched types
--> $DIR/loop-labeled-break-value.rs:9:45
|
LL | let _: i32 = 'inner2: loop { loop { break 'inner2 } };
- | ^^^^^^^^^^^^^ expected (), found i32
+ | ^^^^^^^^^^^^^
+ | |
+ | expected i32, found ()
+ | help: give it a value of the expected type: `break 'inner2 42`
|
- = note: expected type `()`
- found type `i32`
+ = note: expected type `i32`
+ found type `()`
error: aborting due to 3 previous errors
--> $DIR/loop-properly-diverging-2.rs:2:23
|
LL | let x: i32 = loop { break };
- | ^^^^^ expected (), found i32
+ | ^^^^^
+ | |
+ | expected i32, found ()
+ | help: give it a value of the expected type: `break 42`
|
- = note: expected type `()`
- found type `i32`
+ = note: expected type `i32`
+ found type `()`
error: aborting due to previous error
--- /dev/null
+// Names of public modules in libstd and libcore don't accidentally get into prelude
+// because macros with the same names are in prelude.
+
+fn main() {
+ env::current_dir; //~ ERROR use of undeclared type or module `env`
+ type A = panic::PanicInfo; //~ ERROR use of undeclared type or module `panic`
+ type B = vec::Vec<u8>; //~ ERROR use of undeclared type or module `vec`
+}
--- /dev/null
+error[E0433]: failed to resolve: use of undeclared type or module `env`
+ --> $DIR/builtin-prelude-no-accidents.rs:5:5
+ |
+LL | env::current_dir;
+ | ^^^ use of undeclared type or module `env`
+
+error[E0433]: failed to resolve: use of undeclared type or module `panic`
+ --> $DIR/builtin-prelude-no-accidents.rs:6:14
+ |
+LL | type A = panic::PanicInfo;
+ | ^^^^^ use of undeclared type or module `panic`
+
+error[E0433]: failed to resolve: use of undeclared type or module `vec`
+ --> $DIR/builtin-prelude-no-accidents.rs:7:14
+ |
+LL | type B = vec::Vec<u8>;
+ | ^^^ use of undeclared type or module `vec`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
--- /dev/null
+#[derive(
+ core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core`
+ core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core`
+)]
+#[core::bench] //~ ERROR could not find `bench` in `core`
+#[core::global_allocator] //~ ERROR could not find `global_allocator` in `core`
+#[core::test_case] //~ ERROR could not find `test_case` in `core`
+#[core::test] //~ ERROR could not find `test` in `core`
+struct Core;
+
+#[derive(
+ std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std`
+ std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std`
+)]
+#[std::bench] //~ ERROR could not find `bench` in `std`
+#[std::global_allocator] //~ ERROR could not find `global_allocator` in `std`
+#[std::test_case] //~ ERROR could not find `test_case` in `std`
+#[std::test] //~ ERROR could not find `test` in `std`
+struct Std;
+
+fn main() {}
--- /dev/null
+error[E0433]: failed to resolve: could not find `bench` in `core`
+ --> $DIR/builtin-std-paths-fail.rs:5:9
+ |
+LL | #[core::bench]
+ | ^^^^^ could not find `bench` in `core`
+
+error[E0433]: failed to resolve: could not find `global_allocator` in `core`
+ --> $DIR/builtin-std-paths-fail.rs:6:9
+ |
+LL | #[core::global_allocator]
+ | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `core`
+
+error[E0433]: failed to resolve: could not find `test_case` in `core`
+ --> $DIR/builtin-std-paths-fail.rs:7:9
+ |
+LL | #[core::test_case]
+ | ^^^^^^^^^ could not find `test_case` in `core`
+
+error[E0433]: failed to resolve: could not find `test` in `core`
+ --> $DIR/builtin-std-paths-fail.rs:8:9
+ |
+LL | #[core::test]
+ | ^^^^ could not find `test` in `core`
+
+error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
+ --> $DIR/builtin-std-paths-fail.rs:2:11
+ |
+LL | core::RustcDecodable,
+ | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
+
+error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
+ --> $DIR/builtin-std-paths-fail.rs:3:11
+ |
+LL | core::RustcDecodable,
+ | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
+
+error[E0433]: failed to resolve: could not find `bench` in `std`
+ --> $DIR/builtin-std-paths-fail.rs:15:8
+ |
+LL | #[std::bench]
+ | ^^^^^ could not find `bench` in `std`
+
+error[E0433]: failed to resolve: could not find `global_allocator` in `std`
+ --> $DIR/builtin-std-paths-fail.rs:16:8
+ |
+LL | #[std::global_allocator]
+ | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `std`
+
+error[E0433]: failed to resolve: could not find `test_case` in `std`
+ --> $DIR/builtin-std-paths-fail.rs:17:8
+ |
+LL | #[std::test_case]
+ | ^^^^^^^^^ could not find `test_case` in `std`
+
+error[E0433]: failed to resolve: could not find `test` in `std`
+ --> $DIR/builtin-std-paths-fail.rs:18:8
+ |
+LL | #[std::test]
+ | ^^^^ could not find `test` in `std`
+
+error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
+ --> $DIR/builtin-std-paths-fail.rs:12:10
+ |
+LL | std::RustcDecodable,
+ | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
+
+error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
+ --> $DIR/builtin-std-paths-fail.rs:13:10
+ |
+LL | std::RustcDecodable,
+ | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
--- /dev/null
+// check-pass
+
+#[derive(
+ core::clone::Clone,
+ core::marker::Copy,
+ core::fmt::Debug,
+ core::default::Default,
+ core::cmp::Eq,
+ core::hash::Hash,
+ core::cmp::Ord,
+ core::cmp::PartialEq,
+ core::cmp::PartialOrd,
+)]
+struct Core;
+
+#[derive(
+ std::clone::Clone,
+ std::marker::Copy,
+ std::fmt::Debug,
+ std::default::Default,
+ std::cmp::Eq,
+ std::hash::Hash,
+ std::cmp::Ord,
+ std::cmp::PartialEq,
+ std::cmp::PartialOrd,
+)]
+struct Std;
+
+fn main() {
+ core::column!();
+ std::column!();
+}
#![cfg_attr(core, no_std)]
+#![allow(deprecated)] // for deprecated `try!()` macro
#![feature(concat_idents)]
#[cfg(std)] use std::fmt;
// run-pass
+#![allow(deprecated)] // for deprecated `try!()` macro
use std::num::{ParseFloatError, ParseIntError};
fn main() {
--- /dev/null
+enum E {
+ A,
+ B,
+ C,
+ D,
+ E,
+ F,
+}
+
+fn main() {
+ match E::F {
+ E::A => 1,
+ E::B => 2,
+ E::C => 3,
+ E::D => 4,
+ E::E => unimplemented!(""),
+ E::F => "", //~ ERROR match arms have incompatible types
+ };
+}
--- /dev/null
+error[E0308]: match arms have incompatible types
+ --> $DIR/match-arm-resolving-to-never.rs:17:17
+ |
+LL | / match E::F {
+LL | | E::A => 1,
+LL | | E::B => 2,
+LL | | E::C => 3,
+LL | | E::D => 4,
+LL | | E::E => unimplemented!(""),
+ | | ------------------ this and all prior arms are found to be of type `{integer}`
+LL | | E::F => "",
+ | | ^^ expected integer, found reference
+LL | | };
+ | |_____- `match` arms have incompatible types
+ |
+ = note: expected type `{integer}`
+ found type `&'static str`
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
LL | fn f() -> isize { }
| - ^^^^^ expected isize, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `isize`
found type `()`
LL | fn f() -> isize { fn f() -> isize {} pub f<
| - ^^^^^ expected isize, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `isize`
found type `()`
LL | fn v() -> isize {
| - ^^^^^ expected isize, found ()
| |
- | this function's body doesn't return
+ | implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected type `isize`
found type `()`
--> $DIR/lifetimes.rs:9:10
|
LL | type A = single_quote_alone!();
- | ^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^ this macro call doesn't expand to a type
error: aborting due to previous error
error[E0308]: mismatched types
--> $DIR/privacy-enum-ctor.rs:27:20
|
+LL | Fn(u8),
+ | ------ fn(u8) -> m::n::Z {m::n::Z::Fn} defined here
+...
LL | let _: Z = Z::Fn;
- | ^^^^^ expected enum `m::n::Z`, found fn item
+ | ^^^^^
+ | |
+ | expected enum `m::n::Z`, found fn item
+ | help: use parentheses to instantiate this tuple variant: `Z::Fn(_)`
|
= note: expected type `m::n::Z`
found type `fn(u8) -> m::n::Z {m::n::Z::Fn}`
error[E0308]: mismatched types
--> $DIR/privacy-enum-ctor.rs:43:16
|
+LL | Fn(u8),
+ | ------ fn(u8) -> m::E {m::E::Fn} defined here
+...
LL | let _: E = m::E::Fn;
- | ^^^^^^^^ expected enum `m::E`, found fn item
+ | ^^^^^^^^
+ | |
+ | expected enum `m::E`, found fn item
+ | help: use parentheses to instantiate this tuple variant: `m::E::Fn(_)`
|
= note: expected type `m::E`
found type `fn(u8) -> m::E {m::E::Fn}`
error[E0308]: mismatched types
--> $DIR/privacy-enum-ctor.rs:51:16
|
+LL | Fn(u8),
+ | ------ fn(u8) -> m::E {m::E::Fn} defined here
+...
LL | let _: E = E::Fn;
- | ^^^^^ expected enum `m::E`, found fn item
+ | ^^^^^
+ | |
+ | expected enum `m::E`, found fn item
+ | help: use parentheses to instantiate this tuple variant: `E::Fn(_)`
|
= note: expected type `m::E`
found type `fn(u8) -> m::E {m::E::Fn}`
#![warn(rust_2018_compatibility)]
#![allow(unused_variables)]
#![allow(dead_code)]
+#![allow(deprecated)]
fn foo() -> Result<usize, ()> {
let x: Result<usize, ()> = Ok(22);
#![warn(rust_2018_compatibility)]
#![allow(unused_variables)]
#![allow(dead_code)]
+#![allow(deprecated)]
fn foo() -> Result<usize, ()> {
let x: Result<usize, ()> = Ok(22);
warning: `try` is a keyword in the 2018 edition
- --> $DIR/try-macro.rs:12:5
+ --> $DIR/try-macro.rs:13:5
|
LL | try!(x);
| ^^^ help: you can use a raw identifier to stay compatible: `r#try`
--- /dev/null
+// check-pass
+#![feature(specialization)]
+
+pub struct Cloned<I>(I);
+
+impl<'a, I, T: 'a> Iterator for Cloned<I>
+where
+ I: Iterator<Item = &'a T>,
+ T: Clone,
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ unimplemented!()
+ }
+}
+
+impl<'a, I, T: 'a> Iterator for Cloned<I>
+where
+ I: Iterator<Item = &'a T>,
+ T: Copy,
+{
+ fn count(self) -> usize {
+ unimplemented!()
+ }
+}
+
+fn main() {
+ let a = [1,2,3,4];
+ Cloned(a.iter()).count();
+}
error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:16:17
|
+LL | fn bar<'a, T>() where T: 'a {}
+ | --------------------------- fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>} defined here
+...
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected (), found fn item
+ | help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>()`
|
= note: expected type `()`
found type `fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>}`
error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:25:17
|
+LL | fn bar<'a, T>() where T: 'a {}
+ | --------------------------- fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>} defined here
+...
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected (), found fn item
+ | help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u32>>::bar::<'static, char>()`
|
= note: expected type `()`
found type `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:33:17
|
+LL | fn baz() {}
+ | -------- fn() {<i8 as Foo<'static, 'static, u8>>::baz} defined here
+...
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected (), found fn item
+ | help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u8>>::baz()`
|
= note: expected type `()`
found type `fn() {<i8 as Foo<'static, 'static, u8>>::baz}`
error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:41:17
|
+LL | fn foo<'z>() where &'z (): Sized {
+ | -------------------------------- fn() {foo::<'static>} defined here
+...
LL | let x: () = foo::<'static>;
- | ^^^^^^^^^^^^^^ expected (), found fn item
+ | ^^^^^^^^^^^^^^
+ | |
+ | expected (), found fn item
+ | help: use parentheses to call this function: `foo::<'static>()`
|
= note: expected type `()`
found type `fn() {foo::<'static>}`
error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:16:17
|
+LL | fn bar<'a, T>() where T: 'a {}
+ | --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>} defined here
+...
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected (), found fn item
+ | help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>()`
|
= note: expected type `()`
found type `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>}`
error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:25:17
|
+LL | fn bar<'a, T>() where T: 'a {}
+ | --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>} defined here
+...
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected (), found fn item
+ | help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u32>>::bar::<'static, char>()`
|
= note: expected type `()`
found type `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:33:17
|
+LL | fn baz() {}
+ | -------- fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz} defined here
+...
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected (), found fn item
+ | help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u8>>::baz()`
|
= note: expected type `()`
found type `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz}`
error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:41:17
|
+LL | fn foo<'z>() where &'z (): Sized {
+ | -------------------------------- fn() {foo::<ReStatic>} defined here
+...
LL | let x: () = foo::<'static>;
- | ^^^^^^^^^^^^^^ expected (), found fn item
+ | ^^^^^^^^^^^^^^
+ | |
+ | expected (), found fn item
+ | help: use parentheses to call this function: `foo::<'static>()`
|
= note: expected type `()`
found type `fn() {foo::<ReStatic>}`
--- /dev/null
+fn foo(a: usize, b: usize) -> usize { a }
+
+struct S(usize, usize);
+
+trait T {
+ fn baz(x: usize, y: usize) -> usize { x }
+}
+
+fn main() {
+ let _: usize = foo(_, _);
+ //~^ ERROR expected expression
+ //~| ERROR expected expression
+ let _: S = S(_, _);
+ //~^ ERROR expected expression
+ //~| ERROR expected expression
+ let _: usize = T::baz(_, _);
+ //~^ ERROR expected expression
+ //~| ERROR expected expression
+}
--- /dev/null
+error: expected expression, found reserved identifier `_`
+ --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24
+ |
+LL | let _: usize = foo(_, _);
+ | ^ expected expression
+
+error: expected expression, found reserved identifier `_`
+ --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:27
+ |
+LL | let _: usize = foo(_, _);
+ | ^ expected expression
+
+error: expected expression, found reserved identifier `_`
+ --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:18
+ |
+LL | let _: S = S(_, _);
+ | ^ expected expression
+
+error: expected expression, found reserved identifier `_`
+ --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:21
+ |
+LL | let _: S = S(_, _);
+ | ^ expected expression
+
+error: expected expression, found reserved identifier `_`
+ --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:27
+ |
+LL | let _: usize = T::baz(_, _);
+ | ^ expected expression
+
+error: expected expression, found reserved identifier `_`
+ --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:30
+ |
+LL | let _: usize = T::baz(_, _);
+ | ^ expected expression
+
+error: aborting due to 6 previous errors
+
--- /dev/null
+fn foo(a: usize, b: usize) -> usize { a }
+
+fn bar() -> usize { 42 }
+
+struct S(usize, usize);
+enum E {
+ A(usize),
+ B { a: usize },
+}
+struct V();
+
+trait T {
+ fn baz(x: usize, y: usize) -> usize { x }
+ fn bat(x: usize) -> usize { 42 }
+ fn bax(x: usize) -> usize { 42 }
+ fn bach(x: usize) -> usize;
+ fn ban(&self) -> usize { 42 }
+ fn bal(&self) -> usize;
+}
+
+struct X;
+
+impl T for X {
+ fn bach(x: usize) -> usize { 42 }
+ fn bal(&self) -> usize { 42 }
+}
+
+fn main() {
+ let _: usize = foo; //~ ERROR mismatched types
+ let _: S = S; //~ ERROR mismatched types
+ let _: usize = bar; //~ ERROR mismatched types
+ let _: V = V; //~ ERROR mismatched types
+ let _: usize = T::baz; //~ ERROR mismatched types
+ let _: usize = T::bat; //~ ERROR mismatched types
+ let _: E = E::A; //~ ERROR mismatched types
+ let _: E = E::B; //~ ERROR expected value, found struct variant `E::B`
+ let _: usize = X::baz; //~ ERROR mismatched types
+ let _: usize = X::bat; //~ ERROR mismatched types
+ let _: usize = X::bax; //~ ERROR mismatched types
+ let _: usize = X::bach; //~ ERROR mismatched types
+ let _: usize = X::ban; //~ ERROR mismatched types
+ let _: usize = X::bal; //~ ERROR mismatched types
+ let _: usize = X.ban; //~ ERROR attempted to take value of method
+ let _: usize = X.bal; //~ ERROR attempted to take value of method
+}
--- /dev/null
+error[E0423]: expected value, found struct variant `E::B`
+ --> $DIR/fn-or-tuple-struct-without-args.rs:36:16
+ |
+LL | let _: E = E::B;
+ | ^^^-
+ | | |
+ | | help: a tuple variant with a similar name exists: `A`
+ | did you mean `E::B { /* fields */ }`?
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:29:20
+ |
+LL | fn foo(a: usize, b: usize) -> usize { a }
+ | ----------------------------------- fn(usize, usize) -> usize {foo} defined here
+...
+LL | let _: usize = foo;
+ | ^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `foo(a, b)`
+ |
+ = note: expected type `usize`
+ found type `fn(usize, usize) -> usize {foo}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:30:16
+ |
+LL | struct S(usize, usize);
+ | ----------------------- fn(usize, usize) -> S {S} defined here
+...
+LL | let _: S = S;
+ | ^
+ | |
+ | expected struct `S`, found fn item
+ | help: use parentheses to instantiate this tuple struct: `S(_, _)`
+ |
+ = note: expected type `S`
+ found type `fn(usize, usize) -> S {S}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:31:20
+ |
+LL | fn bar() -> usize { 42 }
+ | ----------------- fn() -> usize {bar} defined here
+...
+LL | let _: usize = bar;
+ | ^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `bar()`
+ |
+ = note: expected type `usize`
+ found type `fn() -> usize {bar}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:32:16
+ |
+LL | struct V();
+ | ----------- fn() -> V {V} defined here
+...
+LL | let _: V = V;
+ | ^
+ | |
+ | expected struct `V`, found fn item
+ | help: use parentheses to instantiate this tuple struct: `V()`
+ |
+ = note: expected type `V`
+ found type `fn() -> V {V}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:33:20
+ |
+LL | fn baz(x: usize, y: usize) -> usize { x }
+ | ----------------------------------- fn(usize, usize) -> usize {<_ as T>::baz} defined here
+...
+LL | let _: usize = T::baz;
+ | ^^^^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `T::baz(x, y)`
+ |
+ = note: expected type `usize`
+ found type `fn(usize, usize) -> usize {<_ as T>::baz}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:34:20
+ |
+LL | fn bat(x: usize) -> usize { 42 }
+ | ------------------------- fn(usize) -> usize {<_ as T>::bat} defined here
+...
+LL | let _: usize = T::bat;
+ | ^^^^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `T::bat(x)`
+ |
+ = note: expected type `usize`
+ found type `fn(usize) -> usize {<_ as T>::bat}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:35:16
+ |
+LL | A(usize),
+ | -------- fn(usize) -> E {E::A} defined here
+...
+LL | let _: E = E::A;
+ | ^^^^
+ | |
+ | expected enum `E`, found fn item
+ | help: use parentheses to instantiate this tuple variant: `E::A(_)`
+ |
+ = note: expected type `E`
+ found type `fn(usize) -> E {E::A}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:37:20
+ |
+LL | fn baz(x: usize, y: usize) -> usize { x }
+ | ----------------------------------- fn(usize, usize) -> usize {<X as T>::baz} defined here
+...
+LL | let _: usize = X::baz;
+ | ^^^^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `X::baz(x, y)`
+ |
+ = note: expected type `usize`
+ found type `fn(usize, usize) -> usize {<X as T>::baz}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:38:20
+ |
+LL | fn bat(x: usize) -> usize { 42 }
+ | ------------------------- fn(usize) -> usize {<X as T>::bat} defined here
+...
+LL | let _: usize = X::bat;
+ | ^^^^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `X::bat(x)`
+ |
+ = note: expected type `usize`
+ found type `fn(usize) -> usize {<X as T>::bat}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:39:20
+ |
+LL | fn bax(x: usize) -> usize { 42 }
+ | ------------------------- fn(usize) -> usize {<X as T>::bax} defined here
+...
+LL | let _: usize = X::bax;
+ | ^^^^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `X::bax(x)`
+ |
+ = note: expected type `usize`
+ found type `fn(usize) -> usize {<X as T>::bax}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:40:20
+ |
+LL | fn bach(x: usize) -> usize;
+ | --------------------------- fn(usize) -> usize {<X as T>::bach} defined here
+...
+LL | let _: usize = X::bach;
+ | ^^^^^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `X::bach(x)`
+ |
+ = note: expected type `usize`
+ found type `fn(usize) -> usize {<X as T>::bach}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:41:20
+ |
+LL | fn ban(&self) -> usize { 42 }
+ | ---------------------- for<'r> fn(&'r X) -> usize {<X as T>::ban} defined here
+...
+LL | let _: usize = X::ban;
+ | ^^^^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `X::ban(_)`
+ |
+ = note: expected type `usize`
+ found type `for<'r> fn(&'r X) -> usize {<X as T>::ban}`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-or-tuple-struct-without-args.rs:42:20
+ |
+LL | fn bal(&self) -> usize;
+ | ----------------------- for<'r> fn(&'r X) -> usize {<X as T>::bal} defined here
+...
+LL | let _: usize = X::bal;
+ | ^^^^^^
+ | |
+ | expected usize, found fn item
+ | help: use parentheses to call this function: `X::bal(_)`
+ |
+ = note: expected type `usize`
+ found type `for<'r> fn(&'r X) -> usize {<X as T>::bal}`
+
+error[E0615]: attempted to take value of method `ban` on type `X`
+ --> $DIR/fn-or-tuple-struct-without-args.rs:43:22
+ |
+LL | let _: usize = X.ban;
+ | ^^^ help: use parentheses to call the method: `ban()`
+
+error[E0615]: attempted to take value of method `bal` on type `X`
+ --> $DIR/fn-or-tuple-struct-without-args.rs:44:22
+ |
+LL | let _: usize = X.bal;
+ | ^^^ help: use parentheses to call the method: `bal()`
+
+error: aborting due to 16 previous errors
+
+Some errors have detailed explanations: E0308, E0423, E0615.
+For more information about an error, try `rustc --explain E0308`.
--- /dev/null
+// run-rustfix
+fn main() {
+ // everything after `.as_ref` should be suggested
+ match Some(vec![3]).as_ref().map(|v| v.as_slice()) {
+ Some([_x]) => (), //~ ERROR unexpected `(` after qualified path
+ _ => (),
+ }
+}
--- /dev/null
+// run-rustfix
+fn main() {
+ // everything after `.as_ref` should be suggested
+ match Some(vec![3]).as_ref().map(|v| v.as_slice()) {
+ Some(vec![_x]) => (), //~ ERROR unexpected `(` after qualified path
+ _ => (),
+ }
+}
--- /dev/null
+error: unexpected `(` after qualified path
+ --> $DIR/vec-macro-in-pattern.rs:5:14
+ |
+LL | Some(vec![_x]) => (),
+ | ^^^^^^^^
+ | |
+ | unexpected `(` after qualified path
+ | in this macro invocation
+ | help: use a slice pattern here instead: `[_x]`
+ |
+ = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
+ = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
| | |
| | expected type
| | in this macro invocation
+ | | this macro call doesn't expand to a type
| help: maybe write a path separator here: `::`
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
assert_eq!(TypeId::of::<other1::U32Iterator>(), other1::id_u32_iterator());
assert_eq!(other1::id_i32_iterator(), other2::id_i32_iterator());
assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator());
- assert!(other1::id_i32_iterator() != other1::id_u32_iterator());
- assert!(TypeId::of::<other1::I32Iterator>() != TypeId::of::<other1::U32Iterator>());
+ assert_ne!(other1::id_i32_iterator(), other1::id_u32_iterator());
+ assert_ne!(TypeId::of::<other1::I32Iterator>(), TypeId::of::<other1::U32Iterator>());
// Check fn pointer against collisions
- assert!(TypeId::of::<fn(fn(A) -> A) -> A>() !=
- TypeId::of::<fn(fn() -> A, A) -> A>());
+ assert_ne!(
+ TypeId::of::<fn(fn(A) -> A) -> A>(),
+ TypeId::of::<fn(fn() -> A, A) -> A>()
+ );
+ assert_ne!(
+ TypeId::of::<for<'a> fn(&'a i32) -> &'a i32>(),
+ TypeId::of::<for<'a> fn(&'a i32) -> &'static i32>()
+ );
+ assert_ne!(
+ TypeId::of::<for<'a, 'b> fn(&'a i32, &'b i32) -> &'a i32>(),
+ TypeId::of::<for<'a, 'b> fn(&'b i32, &'a i32) -> &'a i32>()
+ );
}
license = "MIT OR Apache-2.0"
edition = "2018"
+[features]
+linkcheck = ["mdbook-linkcheck"]
+
[dependencies]
clap = "2.25.0"
failure = "0.1"
+mdbook-linkcheck = { version = "0.3.0", optional = true }
[dependencies.mdbook]
version = "0.3.0"
default-features = false
features = ["search"]
-
-[target.'cfg(all(target_arch = "x86_64", target_os = "linux"))'.dependencies]
-mdbook-linkcheck = "0.3.0"
use mdbook::MDBook;
use mdbook::errors::{Result as Result3};
-#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
+#[cfg(feature = "linkcheck")]
use mdbook::renderer::RenderContext;
-
-#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
+#[cfg(feature = "linkcheck")]
use mdbook_linkcheck::{self, errors::BrokenLinks};
use failure::Error;
if let Err(err) = linkcheck(sub_matches) {
eprintln!("Error: {}", err);
- #[cfg(all(target_arch = "x86_64", target_os = "linux"))]
+ #[cfg(feature = "linkcheck")]
{
if let Ok(broken_links) = err.downcast::<BrokenLinks>() {
for cause in broken_links.links().iter() {
};
}
-#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
+#[cfg(feature = "linkcheck")]
pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> {
let book_dir = get_book_dir(args);
let book = MDBook::load(&book_dir).unwrap();
mdbook_linkcheck::check_links(&render_ctx)
}
-#[cfg(not(all(target_arch = "x86_64", target_os = "linux")))]
+#[cfg(not(feature = "linkcheck"))]
pub fn linkcheck(_args: &ArgMatches<'_>) -> Result<(), Error> {
- println!("mdbook-linkcheck only works on x86_64 linux targets.");
+ println!("mdbook-linkcheck is disabled.");
Ok(())
}