name = "rustc_data_structures"
version = "0.0.0"
dependencies = [
+ "arrayvec",
"bitflags",
"cfg-if",
"crossbeam-utils 0.7.2",
name = "rustc_infer"
version = "0.0.0"
dependencies = [
+ "arrayvec",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
name = "rustc_middle"
version = "0.0.0"
dependencies = [
+ "arrayvec",
"bitflags",
"byteorder",
"chalk-ir",
+Version 1.47.0 (2020-10-08)
+==========================
+
+Language
+--------
+- [Closures will now warn when not used.][74869]
+
+Compiler
+--------
+- [Stabilized the `-C control-flow-guard` codegen option][73893], which enables
+ [Control Flow Guard][1.47.0-cfg] for Windows platforms, and is ignored on other
+ platforms.
+- [Upgraded to LLVM 11.][73526]
+- [Added tier 3\* support for the `thumbv4t-none-eabi` target.][74419]
+- [Upgrade the FreeBSD toolchain to version 11.4][75204]
+- [`RUST_BACKTRACE`'s output is now more compact.][75048]
+
+\* Refer to Rust's [platform support page][forge-platform-support] for more
+information on Rust's tiered platform support.
+
+Libraries
+---------
+- [`CStr` now implements `Index<RangeFrom<usize>>`.][74021]
+- [Traits in `std`/`core` are now implemented for arrays of any length, not just
+ those of length less than 33.][74060]
+- [`ops::RangeFull` and `ops::Range` now implement Default.][73197]
+- [`panic::Location` now implements `Copy`, `Clone`, `Eq`, `Hash`, `Ord`,
+ `PartialEq`, and `PartialOrd`.][73583]
+
+Stabilized APIs
+---------------
+- [`Ident::new_raw`]
+- [`Range::is_empty`]
+- [`RangeInclusive::is_empty`]
+- [`Result::as_deref`]
+- [`Result::as_deref_mut`]
+- [`Vec::leak`]
+- [`pointer::offset_from`]
+- [`f32::TAU`]
+- [`f64::TAU`]
+
+The following previously stable APIs have now been made const.
+
+- [The `new` method for all `NonZero` integers.][73858]
+- [The `checked_add`,`checked_sub`,`checked_mul`,`checked_neg`, `checked_shl`,
+ `checked_shr`, `saturating_add`, `saturating_sub`, and `saturating_mul`
+ methods for all integers.][73858]
+- [The `checked_abs`, `saturating_abs`, `saturating_neg`, and `signum` for all
+ signed integers.][73858]
+- [The `is_ascii_alphabetic`, `is_ascii_uppercase`, `is_ascii_lowercase`,
+ `is_ascii_alphanumeric`, `is_ascii_digit`, `is_ascii_hexdigit`,
+ `is_ascii_punctuation`, `is_ascii_graphic`, `is_ascii_whitespace`, and
+ `is_ascii_control` methods for `char` and `u8`.][73858]
+
+Cargo
+-----
+- [`build-dependencies` are now built with opt-level 0 by default.][cargo/8500]
+ You can override this by setting the following in your `Cargo.toml`.
+ ```toml
+ [profile.release.build-override]
+ opt-level = 3
+ ```
+- [`cargo-help` will now display man pages for commands rather just the
+ `--help` text.][cargo/8456]
+- [`cargo-metadata` now emits a `test` field indicating if a target has
+ tests enabled.][cargo/8478]
+- [`workspace.default-members` now respects `workspace.exclude`.][cargo/8485]
+- [`cargo-publish` will now use an alternative registry by default if it's the
+ only registry specified in `package.publish`.][cargo/8571]
+
+Misc
+----
+- [Added a help button beside Rustdoc's searchbar that explains rustdoc's
+ type based search.][75366]
+- [Added the Ayu theme to rustdoc.][71237]
+
+Compatibility Notes
+-------------------
+- [Bumped the minimum supported Emscripten version to 1.39.20.][75716]
+- [Fixed a regression parsing `{} && false` in tail expressions.][74650]
+- [Added changes to how proc-macros are expanded in `macro_rules!` that should
+ help to preserve more span information.][73084] These changes may cause
+ compiliation errors if your macro was unhygenic or didn't correctly handle
+ `Delimiter::None`.
+- [Moved support for the CloudABI target to tier 3.][75568]
+- [`linux-gnu` targets now require minimum kernel 2.6.32 and glibc 2.11.][74163]
+
+Internal Only
+--------
+- [Improved default settings for bootstrapping in `x.py`.][73964] You can read details about this change in the ["Changes to `x.py` defaults"](https://blog.rust-lang.org/inside-rust/2020/08/30/changes-to-x-py-defaults.html) post on the Inside Rust blog.
+- [Added the `rustc-docs` component.][75560] This allows you to install
+ and read the documentation for the compiler internal APIs. (Currently only
+ available for `x86_64-unknown-linux-gnu`.)
+
+[1.47.0-cfg]: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard
+[76980]: https://github.com/rust-lang/rust/issues/76980
+[75048]: https://github.com/rust-lang/rust/pull/75048/
+[74163]: https://github.com/rust-lang/rust/pull/74163/
+[71237]: https://github.com/rust-lang/rust/pull/71237/
+[74869]: https://github.com/rust-lang/rust/pull/74869/
+[73858]: https://github.com/rust-lang/rust/pull/73858/
+[75716]: https://github.com/rust-lang/rust/pull/75716/
+[75908]: https://github.com/rust-lang/rust/pull/75908/
+[75516]: https://github.com/rust-lang/rust/pull/75516/
+[75560]: https://github.com/rust-lang/rust/pull/75560/
+[75568]: https://github.com/rust-lang/rust/pull/75568/
+[75366]: https://github.com/rust-lang/rust/pull/75366/
+[75204]: https://github.com/rust-lang/rust/pull/75204/
+[74650]: https://github.com/rust-lang/rust/pull/74650/
+[74419]: https://github.com/rust-lang/rust/pull/74419/
+[73964]: https://github.com/rust-lang/rust/pull/73964/
+[74021]: https://github.com/rust-lang/rust/pull/74021/
+[74060]: https://github.com/rust-lang/rust/pull/74060/
+[73893]: https://github.com/rust-lang/rust/pull/73893/
+[73526]: https://github.com/rust-lang/rust/pull/73526/
+[73583]: https://github.com/rust-lang/rust/pull/73583/
+[73084]: https://github.com/rust-lang/rust/pull/73084/
+[73197]: https://github.com/rust-lang/rust/pull/73197/
+[72488]: https://github.com/rust-lang/rust/pull/72488/
+[cargo/8456]: https://github.com/rust-lang/cargo/pull/8456/
+[cargo/8478]: https://github.com/rust-lang/cargo/pull/8478/
+[cargo/8485]: https://github.com/rust-lang/cargo/pull/8485/
+[cargo/8500]: https://github.com/rust-lang/cargo/pull/8500/
+[cargo/8571]: https://github.com/rust-lang/cargo/pull/8571/
+[`Ident::new_raw`]: https://doc.rust-lang.org/nightly/proc_macro/struct.Ident.html#method.new_raw
+[`Range::is_empty`]: https://doc.rust-lang.org/nightly/std/ops/struct.Range.html#method.is_empty
+[`RangeInclusive::is_empty`]: https://doc.rust-lang.org/nightly/std/ops/struct.RangeInclusive.html#method.is_empty
+[`Result::as_deref_mut`]: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#method.as_deref_mut
+[`Result::as_deref`]: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#method.as_deref
+[`TypeId::of`]: https://doc.rust-lang.org/nightly/std/any/struct.TypeId.html#method.of
+[`Vec::leak`]: https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.leak
+[`f32::TAU`]: https://doc.rust-lang.org/nightly/std/f32/consts/constant.TAU.html
+[`f64::TAU`]: https://doc.rust-lang.org/nightly/std/f64/consts/constant.TAU.html
+[`pointer::offset_from`]: https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from
+
+
Version 1.46.0 (2020-08-27)
==========================
function's caller's location information for panic messages.][72445]
- [Recursively indexing into tuples no longer needs parentheses.][71322] E.g.
`x.0.0` over `(x.0).0`.
-- [`mem::transmute` can now be used in static and constants.][72920] **Note**
+- [`mem::transmute` can now be used in statics and constants.][72920] **Note**
You currently can't use `mem::transmute` in constant functions.
Compiler
-------------------
- [The target configuration option `abi_blacklist` has been renamed
to `unsupported_abis`.][74150] The old name will still continue to work.
-- [Rustc will now warn if you have a C-like enum that implements `Drop`.][72331]
+- [Rustc will now warn if you cast a C-like enum that implements `Drop`.][72331]
This was previously accepted but will become a hard error in a future release.
- [Rustc will fail to compile if you have a struct with
`#[repr(i128)]` or `#[repr(u128)]`.][74109] This representation is currently only
-84b047bf64dfcfa12867781e9c23dfa4f2e6082c
\ No newline at end of file
+18bf6b4f01a6feaf7259ba7cdae58031af1b7b39
\ No newline at end of file
/// assert_eq!(is_string(&"cookie monster".to_string()), true);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_type_id", since = "1.46.0")]
+ #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
pub const fn of<T: ?Sized + 'static>() -> TypeId {
TypeId { t: intrinsics::type_id::<T>() }
}
/// crate it is invoked in.
///
/// The stabilized version of this intrinsic is [`crate::any::TypeId::of`].
- #[rustc_const_stable(feature = "const_type_id", since = "1.46.0")]
+ #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
pub fn type_id<T: ?Sized + 'static>() -> u64;
/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
}
#[inline]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
self.it.count()
}
- unsafe fn get_unchecked(&mut self, idx: usize) -> T
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
where
Self: TrustedRandomAccess,
{
self.it.map(T::clone).fold(init, f)
}
- unsafe fn get_unchecked(&mut self, idx: usize) -> T
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
where
Self: TrustedRandomAccess,
{
self.iter.fold(init, map_fold(self.f, g))
}
- unsafe fn get_unchecked(&mut self, idx: usize) -> B
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
where
Self: TrustedRandomAccess,
{
self.iter.fold(init, enumerate(self.count, fold))
}
- unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
where
Self: TrustedRandomAccess,
{
}
#[inline]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
let i = self.index;
self.index += 1;
// SAFETY: `i` is smaller than `self.len`, thus smaller than `self.a.len()` and `self.b.len()`
- unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
+ unsafe {
+ Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i)))
+ }
} else if A::may_have_side_effect() && self.index < self.a.size() {
// match the base implementation's potential side effects
// SAFETY: we just checked that `self.index` < `self.a.len()`
unsafe {
- self.a.get_unchecked(self.index);
+ self.a.__iterator_get_unchecked(self.index);
}
self.index += 1;
None
// ensures that `end` is smaller than or equal to `self.len`,
// so `i` is also smaller than `self.len`.
unsafe {
- self.a.get_unchecked(i);
+ self.a.__iterator_get_unchecked(i);
}
}
if B::may_have_side_effect() {
// SAFETY: same as above.
unsafe {
- self.b.get_unchecked(i);
+ self.b.__iterator_get_unchecked(i);
}
}
}
let i = self.len;
// SAFETY: `i` is smaller than the previous value of `self.len`,
// which is also smaller than or equal to `self.a.len()` and `self.b.len()`
- unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
+ unsafe {
+ Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i)))
+ }
} else {
None
}
unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item {
// SAFETY: the caller must uphold the contract for
// `Iterator::get_unchecked`.
- unsafe { (self.a.get_unchecked(idx), self.b.get_unchecked(idx)) }
+ unsafe { (self.a.__iterator_get_unchecked(idx), self.b.__iterator_get_unchecked(idx)) }
}
}
unsafe fn try_get_unchecked(&mut self, index: usize) -> Self::Item {
// SAFETY: the caller must uphold the contract for
// `Iterator::get_unchecked`.
- unsafe { self.get_unchecked(index) }
+ unsafe { self.__iterator_get_unchecked(index) }
}
}
#[inline]
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
- unsafe fn get_unchecked(&mut self, _idx: usize) -> Self::Item
+ unsafe fn __iterator_get_unchecked(&mut self, _idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
#![feature(const_slice_ptr_len)]
#![feature(const_size_of_val)]
#![feature(const_align_of_val)]
+#![feature(const_type_id)]
#![feature(const_type_name)]
#![feature(const_likely)]
#![feature(const_unreachable_unchecked)]
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
// SAFETY: the caller must guarantee that `i` is in bounds of
// the underlying slice, so `i` cannot overflow an `isize`, and
// the returned references is guaranteed to refer to an element
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
// SAFETY: since the caller guarantees that `i` is in bounds,
// which means that `i` cannot overflow an `isize`, and the
// slice created by `from_raw_parts` is a subslice of `self.v`
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let start = idx * self.chunk_size;
let end = match start.checked_add(self.chunk_size) {
None => self.v.len(),
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let start = idx * self.chunk_size;
let end = match start.checked_add(self.chunk_size) {
None => self.v.len(),
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let start = idx * self.chunk_size;
// SAFETY: mostly identical to `Chunks::get_unchecked`.
unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let start = idx * self.chunk_size;
// SAFETY: see comments for `ChunksMut::get_unchecked`.
unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
self.iter.last()
}
- unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T; N] {
+ unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a [T; N] {
// SAFETY: The safety guarantees of `get_unchecked` are transferred to
// the caller.
- unsafe { self.iter.get_unchecked(i) }
+ unsafe { self.iter.__iterator_get_unchecked(i) }
}
}
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let end = self.v.len() - idx * self.chunk_size;
let start = match end.checked_sub(self.chunk_size) {
None => 0,
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let end = self.v.len() - idx * self.chunk_size;
let start = match end.checked_sub(self.chunk_size) {
None => 0,
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let end = self.v.len() - idx * self.chunk_size;
let start = end - self.chunk_size;
// SAFETY:
}
#[doc(hidden)]
- unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let end = self.v.len() - idx * self.chunk_size;
let start = end - self.chunk_size;
// SAFETY: see comments for `RChunksMut::get_unchecked`.
}
#[inline]
- unsafe fn get_unchecked(&mut self, idx: usize) -> u8 {
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
// SAFETY: the caller must uphold the safety contract
// for `Iterator::get_unchecked`.
- unsafe { self.0.get_unchecked(idx) }
+ unsafe { self.0.__iterator_get_unchecked(idx) }
}
}
cp_debugger_script("lldb_lookup.py");
cp_debugger_script("lldb_providers.py");
+ cp_debugger_script("lldb_commands")
}
}
}
--set target.x86_64-unknown-linux-gnu.linker=clang \
--set target.x86_64-unknown-linux-gnu.ar=/rustroot/bin/llvm-ar \
--set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \
- --set llvm.thin-lto=true \
+ --set llvm.thin-lto=false \
--set rust.jemalloc
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang
#
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
# either automatically or manually.
-export RUST_RELEASE_CHANNEL=beta
+export RUST_RELEASE_CHANNEL=stable
# Always set the release channel for bootstrap; this is normally not important (i.e., only dist
# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
if isAzurePipelines; then
echo "##vso[task.prependpath]${path}"
elif isGitHubActions; then
- echo "::add-path::${path}"
+ echo "${path}" >> "${GITHUB_PATH}"
else
echo "ciCommandAddPath only works inside CI!"
exit 1
if isAzurePipelines; then
echo "##vso[task.setvariable variable=${name}]${value}"
elif isGitHubActions; then
- echo "::set-env name=${name}::${value}"
+ echo "${name}=${value}" >> "${GITHUB_ENV}"
else
echo "ciCommandSetEnv only works inside CI!"
exit 1
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
```
+## missing-fragment-specifier
+
+The missing_fragment_specifier warning is issued when an unused pattern in a
+`macro_rules!` macro definition has a meta-variable (e.g. `$e`) that is not
+followed by a fragment specifier (e.g. `:expr`).
+
+This warning can always be fixed by removing the unused pattern in the
+`macro_rules!` macro definition.
+
## mutable-transmutes
This lint catches transmuting from `&T` to `&mut T` because it is undefined
-command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_lookup.py\"
type synthetic add -l lldb_lookup.synthetic_lookup -x \".*\" --category Rust
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(alloc::([a-z_]+::)+)String$\" --category Rust
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^&str$\" --category Rust
<If Condition="(base.table.ctrl.pointer[i] & 0x80) == 0">
<!-- Bucket is populated -->
<Exec>n--</Exec>
- <Item Name="{static_cast<tuple<$T1, $T2>*>(base.table.ctrl.pointer)[-(i + 1)].__0}">static_cast<tuple<$T1, $T2>*>(base.table.ctrl.pointer)[-(i + 1)].__1</Item>
+ <Item Name="{((tuple<$T1, $T2>*)base.table.ctrl.pointer)[-(i + 1)].__0}">((tuple<$T1, $T2>*)base.table.ctrl.pointer)[-(i + 1)].__1</Item>
</If>
<Exec>i++</Exec>
</Loop>
<If Condition="(map.base.table.ctrl.pointer[i] & 0x80) == 0">
<!-- Bucket is populated -->
<Exec>n--</Exec>
- <Item>static_cast<$T1*>(map.base.table.ctrl.pointer)[-(i + 1)]</Item>
+ <Item>(($T1*)map.base.table.ctrl.pointer)[-(i + 1)]</Item>
</If>
<Exec>i++</Exec>
</Loop>
fi
fi
+script_import="command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_lookup.py\""
+commands_file="$RUSTC_SYSROOT/lib/rustlib/etc/lldb_commands"
+
# Call LLDB with the commands added to the argument list
-exec "$lldb" --source-before-file ./lldb_commands "$@"
+exec "$lldb" --one-line-before-file "$script_import" --source-before-file "$commands_file" "$@"
if let ExpnKind::Macro(_, macro_name) = orig_span.ctxt().outer_expn_data().kind {
let filename = source_map.span_to_filename(orig_span);
if let FileName::Real(RealFileName::Named(path)) = filename {
- if (path.ends_with("time-macros-impl/src/lib.rs")
- && macro_name == sym::impl_macros)
- || (path.ends_with("js-sys/src/lib.rs") && macro_name == sym::arrays)
+ let matches_prefix = |prefix| {
+ // Check for a path that ends with 'prefix*/src/lib.rs'
+ let mut iter = path.components().rev();
+ iter.next().and_then(|p| p.as_os_str().to_str()) == Some("lib.rs")
+ && iter.next().and_then(|p| p.as_os_str().to_str()) == Some("src")
+ && iter
+ .next()
+ .and_then(|p| p.as_os_str().to_str())
+ .map_or(false, |p| p.starts_with(prefix))
+ };
+
+ if (macro_name == sym::impl_macros && matches_prefix("time-macros-impl"))
+ || (macro_name == sym::arrays && matches_prefix("js-sys"))
{
let snippet = source_map.span_to_snippet(orig_span);
if snippet.as_deref() == Ok("$name") {
LldFlavor::Link => "link",
LldFlavor::Ld64 => "darwin",
});
+ if let LldFlavor::Wasm = flavor {
+ // LLVM expects host-specific formatting for @file
+ // arguments, but we always generate posix formatted files
+ // at this time. Indicate as such.
+ c.arg("--rsp-quoting=posix");
+ }
c
}
};
doctest = false
[dependencies]
+arrayvec = { version = "0.5.1", default-features = false }
ena = "0.14"
indexmap = "1.5.1"
tracing = "0.1"
pub mod stable_set;
#[macro_use]
pub mod stable_hasher;
+mod atomic_ref;
+pub mod fingerprint;
+pub mod profiling;
pub mod sharded;
pub mod stack;
pub mod sync;
pub mod thin_vec;
pub mod tiny_list;
pub mod transitive_relation;
-pub use ena::undo_log;
-pub use ena::unify;
-mod atomic_ref;
-pub mod fingerprint;
-pub mod profiling;
pub mod vec_linked_list;
pub mod work_queue;
pub use atomic_ref::AtomicRef;
pub mod frozen;
+pub mod mini_map;
pub mod tagged_ptr;
pub mod temp_dir;
+pub use ena::undo_log;
+pub use ena::unify;
+
pub struct OnDrop<F: Fn()>(pub F);
impl<F: Fn()> OnDrop<F> {
--- /dev/null
+use crate::fx::FxHashMap;
+use arrayvec::ArrayVec;
+
+use std::hash::Hash;
+
+/// Small-storage-optimized implementation of a map
+/// made specifically for caching results.
+///
+/// Stores elements in a small array up to a certain length
+/// and switches to `HashMap` when that length is exceeded.
+pub enum MiniMap<K, V> {
+ Array(ArrayVec<[(K, V); 8]>),
+ Map(FxHashMap<K, V>),
+}
+
+impl<K: Eq + Hash, V> MiniMap<K, V> {
+ /// Creates an empty `MiniMap`.
+ pub fn new() -> Self {
+ MiniMap::Array(ArrayVec::new())
+ }
+
+ /// Inserts or updates value in the map.
+ pub fn insert(&mut self, key: K, value: V) {
+ match self {
+ MiniMap::Array(array) => {
+ for pair in array.iter_mut() {
+ if pair.0 == key {
+ pair.1 = value;
+ return;
+ }
+ }
+ if let Err(error) = array.try_push((key, value)) {
+ let mut map: FxHashMap<K, V> = array.drain(..).collect();
+ let (key, value) = error.element();
+ map.insert(key, value);
+ *self = MiniMap::Map(map);
+ }
+ }
+ MiniMap::Map(map) => {
+ map.insert(key, value);
+ }
+ }
+ }
+
+ /// Return value by key if any.
+ pub fn get(&self, key: &K) -> Option<&V> {
+ match self {
+ MiniMap::Array(array) => {
+ for pair in array {
+ if pair.0 == *key {
+ return Some(&pair.1);
+ }
+ }
+ return None;
+ }
+ MiniMap::Map(map) => {
+ return map.get(key);
+ }
+ }
+ }
+}
'_',
line_offset + pos,
width_offset + depth,
- code_offset + annotation.start_col - left,
+ (code_offset + annotation.start_col).saturating_sub(left),
style,
);
}
_ if self.teach => {
buffer.set_style_range(
line_offset,
- code_offset + annotation.start_col - left,
- code_offset + annotation.end_col - left,
+ (code_offset + annotation.start_col).saturating_sub(left),
+ (code_offset + annotation.end_col).saturating_sub(left),
style,
annotation.is_primary,
);
/// e.g., `$var`
MetaVar(Span, Ident),
/// e.g., `$var:expr`. This is only used in the left hand side of MBE macros.
- MetaVarDecl(Span, Ident /* name to bind */, NonterminalKind),
+ MetaVarDecl(Span, Ident /* name to bind */, Option<NonterminalKind>),
}
impl TokenTree {
n_rec(sess, next_m, res.by_ref(), ret_val)?;
}
}
+ TokenTree::MetaVarDecl(span, _, None) => {
+ if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
+ return Err((span, "missing fragment specifier".to_string()));
+ }
+ }
TokenTree::MetaVarDecl(sp, bind_name, _) => match ret_val
.entry(MacroRulesNormalizedIdent::new(bind_name))
{
///
/// A `ParseResult`. Note that matches are kept track of through the items generated.
fn inner_parse_loop<'root, 'tt>(
+ sess: &ParseSess,
cur_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
next_items: &mut Vec<MatcherPosHandle<'root, 'tt>>,
eof_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
})));
}
+ // We need to match a metavar (but the identifier is invalid)... this is an error
+ TokenTree::MetaVarDecl(span, _, None) => {
+ if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
+ return Error(span, "missing fragment specifier".to_string());
+ }
+ }
+
// We need to match a metavar with a valid ident... call out to the black-box
// parser by adding an item to `bb_items`.
- TokenTree::MetaVarDecl(_, _, kind) => {
+ TokenTree::MetaVarDecl(_, _, Some(kind)) => {
// Built-in nonterminals never start with these tokens,
// so we can eliminate them from consideration.
if Parser::nonterminal_may_begin_with(kind, token) {
// parsing from the black-box parser done. The result is that `next_items` will contain a
// bunch of possible next matcher positions in `next_items`.
match inner_parse_loop(
+ parser.sess,
&mut cur_items,
&mut next_items,
&mut eof_items,
let nts = bb_items
.iter()
.map(|item| match item.top_elts.get_tt(item.idx) {
- TokenTree::MetaVarDecl(_, bind, kind) => format!("{} ('{}')", kind, bind),
+ TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind),
_ => panic!(),
})
.collect::<Vec<String>>()
assert_eq!(bb_items.len(), 1);
let mut item = bb_items.pop().unwrap();
- if let TokenTree::MetaVarDecl(span, _, kind) = item.top_elts.get_tt(item.idx) {
+ if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) {
let match_cur = item.match_cur;
let nt = match parser.to_mut().parse_nonterminal(kind) {
Err(mut err) => {
let diag = &sess.parse_sess.span_diagnostic;
let lhs_nm = Ident::new(sym::lhs, def.span);
let rhs_nm = Ident::new(sym::rhs, def.span);
- let tt_spec = NonterminalKind::TT;
+ let tt_spec = Some(NonterminalKind::TT);
// Parse the macro_rules! invocation
let (macro_rules, body) = match &def.kind {
TokenTree::Sequence(span, ref seq) => {
if seq.separator.is_none()
&& seq.tts.iter().all(|seq_tt| match *seq_tt {
- TokenTree::MetaVarDecl(_, _, NonterminalKind::Vis) => true,
+ TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true,
TokenTree::Sequence(_, ref sub_seq) => {
sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
|| sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
// Now `last` holds the complete set of NT tokens that could
// end the sequence before SUFFIX. Check that every one works with `suffix`.
for token in &last.tokens {
- if let TokenTree::MetaVarDecl(_, name, kind) = *token {
+ if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token {
for next_token in &suffix_first.tokens {
match is_in_follow(next_token, kind) {
IsInFollow::Yes => {}
}
fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
- if let mbe::TokenTree::MetaVarDecl(_, _, kind) = *tok {
+ if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok {
frag_can_be_followed_by_any(kind)
} else {
// (Non NT's can always be followed by anything in matchers.)
}
_ => IsInFollow::No(TOKENS),
},
- TokenTree::MetaVarDecl(_, _, NonterminalKind::Block) => IsInFollow::Yes,
+ TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes,
_ => IsInFollow::No(TOKENS),
}
}
TokenTree::MetaVarDecl(
_,
_,
- NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path,
+ Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path),
) => IsInFollow::Yes,
_ => IsInFollow::No(TOKENS),
}
match *tt {
mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token),
mbe::TokenTree::MetaVar(_, name) => format!("${}", name),
- mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind),
+ mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind),
+ mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name),
_ => panic!(
"unexpected mbe::TokenTree::{{Sequence or Delimited}} \
in follow set checker"
use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream;
-use rustc_ast::NodeId;
+use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_ast_pretty::pprust;
use rustc_session::parse::ParseSess;
use rustc_span::symbol::{kw, Ident};
.emit();
token::NonterminalKind::Ident
});
- result.push(TokenTree::MetaVarDecl(span, ident, kind));
+ result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
continue;
}
_ => token.span,
}
tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp),
};
- sess.span_diagnostic.struct_span_err(span, "missing fragment specifier").emit();
- continue;
+ if node_id != DUMMY_NODE_ID {
+ // Macros loaded from other crates have dummy node ids.
+ sess.missing_fragment_specifiers.borrow_mut().insert(span, node_id);
+ }
+ result.push(TokenTree::MetaVarDecl(span, ident, None));
}
// Not a metavar or no matchers allowed, so just return the tree
doctest = false
[dependencies]
-arrayvec = "0.5.1"
+arrayvec = { version = "0.5.1", default-features = false }
rustc_serialize = { path = "../librustc_serialize" }
rustc_macros = { path = "../librustc_macros" }
rustc_span = { path = "../librustc_span" }
rustc_target = { path = "../librustc_target" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+arrayvec = { version = "0.5.1", default-features = false }
rustc_ast = { path = "../librustc_ast" }
use crate::traits::{Obligation, PredicateObligations};
use rustc_ast as ast;
+use rustc_data_structures::mini_map::MiniMap;
use rustc_hir::def_id::DefId;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::TypeError;
needs_wf: false,
root_ty: ty,
param_env: self.param_env,
+ cache: MiniMap::new(),
};
let ty = match generalize.relate(ty, ty) {
root_ty: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
+
+ cache: MiniMap<Ty<'tcx>, RelateResult<'tcx, Ty<'tcx>>>,
}
/// Result from a generalization operation. This includes
fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
+ if let Some(result) = self.cache.get(&t) {
+ return result.clone();
+ }
debug!("generalize: t={:?}", t);
// Check to see whether the type we are generalizing references
// any other type variable related to `vid` via
// subtyping. This is basically our "occurs check", preventing
// us from creating infinitely sized types.
- match t.kind {
+ let result = match t.kind {
ty::Infer(ty::TyVar(vid)) => {
let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid);
let sub_vid = self.infcx.inner.borrow_mut().type_variables().sub_root_var(vid);
Ok(t)
}
_ => relate::super_relate_tys(self, t, t),
- }
+ };
+
+ self.cache.insert(t, result.clone());
+ return result;
}
fn regions(
use rustc_data_structures::captures::Captures;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
+use rustc_middle::ty::walk::MiniSet;
use rustc_middle::ty::{self, Ty, TyCtxt};
/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
/// Returns a "verify bound" that encodes what we know about
/// `generic` and the regions it outlives.
pub fn generic_bound(&self, generic: GenericKind<'tcx>) -> VerifyBound<'tcx> {
+ let mut visited = MiniSet::new();
match generic {
GenericKind::Param(param_ty) => self.param_bound(param_ty),
- GenericKind::Projection(projection_ty) => self.projection_bound(projection_ty),
+ GenericKind::Projection(projection_ty) => {
+ self.projection_bound(projection_ty, &mut visited)
+ }
}
}
- fn type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
+ fn type_bound(
+ &self,
+ ty: Ty<'tcx>,
+ visited: &mut MiniSet<GenericArg<'tcx>>,
+ ) -> VerifyBound<'tcx> {
match ty.kind {
ty::Param(p) => self.param_bound(p),
- ty::Projection(data) => self.projection_bound(data),
+ ty::Projection(data) => self.projection_bound(data, visited),
ty::FnDef(_, substs) => {
// HACK(eddyb) ignore lifetimes found shallowly in `substs`.
// This is inconsistent with `ty::Adt` (including all substs),
let mut bounds = substs
.iter()
.filter_map(|child| match child.unpack() {
- GenericArgKind::Type(ty) => Some(self.type_bound(ty)),
+ GenericArgKind::Type(ty) => Some(self.type_bound(ty, visited)),
GenericArgKind::Lifetime(_) => None,
- GenericArgKind::Const(_) => Some(self.recursive_bound(child)),
+ GenericArgKind::Const(_) => Some(self.recursive_bound(child, visited)),
})
.filter(|bound| {
// Remove bounds that must hold, since they are not interesting.
),
}
}
- _ => self.recursive_bound(ty.into()),
+ _ => self.recursive_bound(ty.into(), visited),
}
}
self.declared_projection_bounds_from_trait(projection_ty)
}
- pub fn projection_bound(&self, projection_ty: ty::ProjectionTy<'tcx>) -> VerifyBound<'tcx> {
+ pub fn projection_bound(
+ &self,
+ projection_ty: ty::ProjectionTy<'tcx>,
+ visited: &mut MiniSet<GenericArg<'tcx>>,
+ ) -> VerifyBound<'tcx> {
debug!("projection_bound(projection_ty={:?})", projection_ty);
let projection_ty_as_ty =
// see the extensive comment in projection_must_outlive
let ty = self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs);
- let recursive_bound = self.recursive_bound(ty.into());
+ let recursive_bound = self.recursive_bound(ty.into(), visited);
VerifyBound::AnyBound(env_bounds.chain(trait_bounds).collect()).or(recursive_bound)
}
- fn recursive_bound(&self, parent: GenericArg<'tcx>) -> VerifyBound<'tcx> {
+ fn recursive_bound(
+ &self,
+ parent: GenericArg<'tcx>,
+ visited: &mut MiniSet<GenericArg<'tcx>>,
+ ) -> VerifyBound<'tcx> {
let mut bounds = parent
- .walk_shallow()
+ .walk_shallow(visited)
.filter_map(|child| match child.unpack() {
- GenericArgKind::Type(ty) => Some(self.type_bound(ty)),
+ GenericArgKind::Type(ty) => Some(self.type_bound(ty, visited)),
GenericArgKind::Lifetime(lt) => {
// Ignore late-bound regions.
if !lt.is_late_bound() { Some(VerifyBound::OutlivedBy(lt)) } else { None }
}
- GenericArgKind::Const(_) => Some(self.recursive_bound(child)),
+ GenericArgKind::Const(_) => Some(self.recursive_bound(child, visited)),
})
.filter(|bound| {
// Remove bounds that must hold, since they are not interesting.
use rustc_plugin_impl as plugin;
use rustc_resolve::{Resolver, ResolverArenas};
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode};
+use rustc_session::lint;
use rustc_session::output::{filename_for_input, filename_for_metadata};
use rustc_session::search_paths::PathKind;
use rustc_session::Session;
ecx.check_unused_macros();
});
+ let mut missing_fragment_specifiers: Vec<_> = ecx
+ .sess
+ .parse_sess
+ .missing_fragment_specifiers
+ .borrow()
+ .iter()
+ .map(|(span, node_id)| (*span, *node_id))
+ .collect();
+ missing_fragment_specifiers.sort_unstable_by_key(|(span, _)| *span);
+
+ let recursion_limit_hit = ecx.reduced_recursion_limit.is_some();
+
+ for (span, node_id) in missing_fragment_specifiers {
+ let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
+ let msg = "missing fragment specifier";
+ resolver.lint_buffer().buffer_lint(lint, node_id, span, msg);
+ }
if cfg!(windows) {
env::set_var("PATH", &old_path);
}
- let recursion_limit_hit = ecx.reduced_recursion_limit.is_some();
if recursion_limit_hit {
// If we hit a recursion limit, exit early to avoid later passes getting overwhelmed
// with a large AST
byteorder = { version = "1.3" }
chalk-ir = "0.14.0"
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+arrayvec = { version = "0.5.1", default-features = false }
measureme = "0.7.1"
rustc_session = { path = "../librustc_session" }
// RFC for reference.
use crate::ty::subst::{GenericArg, GenericArgKind};
+use crate::ty::walk::MiniSet;
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use smallvec::SmallVec;
/// Push onto `out` all the things that must outlive `'a` for the condition
/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
pub fn push_outlives_components(self, ty0: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
- compute_components(self, ty0, out);
+ let mut visited = MiniSet::new();
+ compute_components(self, ty0, out, &mut visited);
debug!("components({:?}) = {:?}", ty0, out);
}
}
-fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
+fn compute_components(
+ tcx: TyCtxt<'tcx>,
+ ty: Ty<'tcx>,
+ out: &mut SmallVec<[Component<'tcx>; 4]>,
+ visited: &mut MiniSet<GenericArg<'tcx>>,
+) {
// Descend through the types, looking for the various "base"
// components and collecting them into `out`. This is not written
// with `collect()` because of the need to sometimes skip subtrees
for child in substs {
match child.unpack() {
GenericArgKind::Type(ty) => {
- compute_components(tcx, ty, out);
+ compute_components(tcx, ty, out, visited);
}
GenericArgKind::Lifetime(_) => {}
GenericArgKind::Const(_) => {
- compute_components_recursive(tcx, child, out);
+ compute_components_recursive(tcx, child, out, visited);
}
}
}
ty::Array(element, _) => {
// Don't look into the len const as it doesn't affect regions
- compute_components(tcx, element, out);
+ compute_components(tcx, element, out, visited);
}
ty::Closure(_, ref substs) => {
for upvar_ty in substs.as_closure().upvar_tys() {
- compute_components(tcx, upvar_ty, out);
+ compute_components(tcx, upvar_ty, out, visited);
}
}
ty::Generator(_, ref substs, _) => {
// Same as the closure case
for upvar_ty in substs.as_generator().upvar_tys() {
- compute_components(tcx, upvar_ty, out);
+ compute_components(tcx, upvar_ty, out, visited);
}
// We ignore regions in the generator interior as we don't
// OutlivesProjectionComponents. Continue walking
// through and constrain Pi.
let mut subcomponents = smallvec![];
- compute_components_recursive(tcx, ty.into(), &mut subcomponents);
+ let mut subvisited = MiniSet::new();
+ compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited);
out.push(Component::EscapingProjection(subcomponents.into_iter().collect()));
}
}
// the "bound regions list". In our representation, no such
// list is maintained explicitly, because bound regions
// themselves can be readily identified.
- compute_components_recursive(tcx, ty.into(), out);
+ compute_components_recursive(tcx, ty.into(), out, visited);
}
}
}
tcx: TyCtxt<'tcx>,
parent: GenericArg<'tcx>,
out: &mut SmallVec<[Component<'tcx>; 4]>,
+ visited: &mut MiniSet<GenericArg<'tcx>>,
) {
- for child in parent.walk_shallow() {
+ for child in parent.walk_shallow(visited) {
match child.unpack() {
GenericArgKind::Type(ty) => {
- compute_components(tcx, ty, out);
+ compute_components(tcx, ty, out, visited);
}
GenericArgKind::Lifetime(lt) => {
// Ignore late-bound regions.
}
}
GenericArgKind::Const(_) => {
- compute_components_recursive(tcx, child, out);
+ compute_components_recursive(tcx, child, out, visited);
}
}
}
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::ty::walk::MiniSet;
// `pretty` is a separate module only for organization.
mod pretty;
/// function tries to find a "characteristic `DefId`" for a
/// type. It's just a heuristic so it makes some questionable
/// decisions and we may want to adjust it later.
-pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
+///
+/// Visited set is needed to avoid full iteration over
+/// deeply nested tuples that have no DefId.
+fn characteristic_def_id_of_type_cached<'a>(
+ ty: Ty<'a>,
+ visited: &mut MiniSet<Ty<'a>>,
+) -> Option<DefId> {
match ty.kind {
ty::Adt(adt_def, _) => Some(adt_def.did),
ty::Dynamic(data, ..) => data.principal_def_id(),
- ty::Array(subty, _) | ty::Slice(subty) => characteristic_def_id_of_type(subty),
+ ty::Array(subty, _) | ty::Slice(subty) => {
+ characteristic_def_id_of_type_cached(subty, visited)
+ }
- ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty),
+ ty::RawPtr(mt) => characteristic_def_id_of_type_cached(mt.ty, visited),
- ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
+ ty::Ref(_, ty, _) => characteristic_def_id_of_type_cached(ty, visited),
- ty::Tuple(ref tys) => {
- tys.iter().find_map(|ty| characteristic_def_id_of_type(ty.expect_ty()))
- }
+ ty::Tuple(ref tys) => tys.iter().find_map(|ty| {
+ let ty = ty.expect_ty();
+ if visited.insert(ty) {
+ return characteristic_def_id_of_type_cached(ty, visited);
+ }
+ return None;
+ }),
ty::FnDef(def_id, _)
| ty::Closure(def_id, _)
| ty::Float(_) => None,
}
}
+pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
+ characteristic_def_id_of_type_cached(ty, &mut MiniSet::new())
+}
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::RegionKind {
type Output = P::Region;
used_region_names: FxHashSet<Symbol>,
region_index: usize,
binder_depth: usize,
+ printed_type_count: usize,
pub region_highlight_mode: RegionHighlightMode,
used_region_names: Default::default(),
region_index: 0,
binder_depth: 0,
+ printed_type_count: 0,
region_highlight_mode: RegionHighlightMode::default(),
name_resolver: None,
}))
self.pretty_print_region(region)
}
- fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
- self.pretty_print_type(ty)
+ fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
+ if self.tcx.sess.type_length_limit().value_within_limit(self.printed_type_count) {
+ self.printed_type_count += 1;
+ self.pretty_print_type(ty)
+ } else {
+ write!(self, "...")?;
+ Ok(self)
+ }
}
fn print_dyn_existential(
use crate::ty;
use crate::ty::subst::{GenericArg, GenericArgKind};
+use arrayvec::ArrayVec;
+use rustc_data_structures::fx::FxHashSet;
use smallvec::{self, SmallVec};
+use std::hash::Hash;
+
+/// Small-storage-optimized implementation of a set
+/// made specifically for walking type tree.
+///
+/// Stores elements in a small array up to a certain length
+/// and switches to `HashSet` when that length is exceeded.
+pub enum MiniSet<T> {
+ Array(ArrayVec<[T; 8]>),
+ Set(FxHashSet<T>),
+}
+
+impl<T: Eq + Hash + Copy> MiniSet<T> {
+ /// Creates an empty `MiniSet`.
+ pub fn new() -> Self {
+ MiniSet::Array(ArrayVec::new())
+ }
+
+ /// Adds a value to the set.
+ ///
+ /// If the set did not have this value present, true is returned.
+ ///
+ /// If the set did have this value present, false is returned.
+ pub fn insert(&mut self, elem: T) -> bool {
+ match self {
+ MiniSet::Array(array) => {
+ if array.iter().any(|e| *e == elem) {
+ false
+ } else {
+ if array.try_push(elem).is_err() {
+ let mut set: FxHashSet<T> = array.iter().copied().collect();
+ set.insert(elem);
+ *self = MiniSet::Set(set);
+ }
+ true
+ }
+ }
+ MiniSet::Set(set) => set.insert(elem),
+ }
+ }
+}
// The TypeWalker's stack is hot enough that it's worth going to some effort to
// avoid heap allocations.
pub struct TypeWalker<'tcx> {
stack: TypeWalkerStack<'tcx>,
last_subtree: usize,
+ visited: MiniSet<GenericArg<'tcx>>,
}
+/// An iterator for walking the type tree.
+///
+/// It's very easy to produce a deeply
+/// nested type tree with a lot of
+/// identical subtrees. In order to work efficiently
+/// in this situation walker only visits each type once.
+/// It maintains a set of visited types and
+/// skips any types that are already there.
impl<'tcx> TypeWalker<'tcx> {
- pub fn new(root: GenericArg<'tcx>) -> TypeWalker<'tcx> {
- TypeWalker { stack: smallvec![root], last_subtree: 1 }
+ pub fn new(root: GenericArg<'tcx>) -> Self {
+ Self { stack: smallvec![root], last_subtree: 1, visited: MiniSet::new() }
}
/// Skips the subtree corresponding to the last type
fn next(&mut self) -> Option<GenericArg<'tcx>> {
debug!("next(): stack={:?}", self.stack);
- let next = self.stack.pop()?;
- self.last_subtree = self.stack.len();
- push_inner(&mut self.stack, next);
- debug!("next: stack={:?}", self.stack);
- Some(next)
+ loop {
+ let next = self.stack.pop()?;
+ self.last_subtree = self.stack.len();
+ if self.visited.insert(next) {
+ push_inner(&mut self.stack, next);
+ debug!("next: stack={:?}", self.stack);
+ return Some(next);
+ }
+ }
}
}
/// Iterator that walks the immediate children of `self`. Hence
/// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
/// (but not `i32`, like `walk`).
- pub fn walk_shallow(self) -> impl Iterator<Item = GenericArg<'tcx>> {
+ ///
+ /// Iterator only walks items once.
+ /// It accepts visited set, updates it with all visited types
+ /// and skips any types that are already there.
+ pub fn walk_shallow(
+ self,
+ visited: &mut MiniSet<GenericArg<'tcx>>,
+ ) -> impl Iterator<Item = GenericArg<'tcx>> {
let mut stack = SmallVec::new();
push_inner(&mut stack, self);
+ stack.retain(|a| visited.insert(*a));
stack.into_iter()
}
}
inlining_map.lock_mut().record_accesses(caller, &accesses);
}
+// Shrinks string by keeping prefix and suffix of given sizes.
+fn shrink(s: String, before: usize, after: usize) -> String {
+ // An iterator of all byte positions including the end of the string.
+ let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
+
+ let shrunk = format!(
+ "{before}...{after}",
+ before = &s[..positions().nth(before).unwrap_or(s.len())],
+ after = &s[positions().rev().nth(after).unwrap_or(0)..],
+ );
+
+ // Only use the shrunk version if it's really shorter.
+ // This also avoids the case where before and after slices overlap.
+ if shrunk.len() < s.len() { shrunk } else { s }
+}
+
+// Format instance name that is already known to be too long for rustc.
+// Show only the first and last 32 characters to avoid blasting
+// the user's terminal with thousands of lines of type-name.
+fn shrunk_instance_name(instance: &Instance<'tcx>) -> String {
+ shrink(instance.to_string(), 32, 32)
+}
+
fn check_recursion_limit<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
// more than the recursion limit is assumed to be causing an
// infinite expansion.
if !tcx.sess.recursion_limit().value_within_limit(adjusted_recursion_depth) {
- let error = format!("reached the recursion limit while instantiating `{}`", instance);
+ let error = format!(
+ "reached the recursion limit while instantiating `{}`",
+ shrunk_instance_name(&instance),
+ );
let mut err = tcx.sess.struct_span_fatal(span, &error);
err.span_note(
tcx.def_span(def_id),
//
// Bail out in these cases to avoid that bad user experience.
if !tcx.sess.type_length_limit().value_within_limit(type_length) {
- // The instance name is already known to be too long for rustc.
- // Show only the first and last 32 characters to avoid blasting
- // the user's terminal with thousands of lines of type-name.
- let shrink = |s: String, before: usize, after: usize| {
- // An iterator of all byte positions including the end of the string.
- let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
-
- let shrunk = format!(
- "{before}...{after}",
- before = &s[..positions().nth(before).unwrap_or(s.len())],
- after = &s[positions().rev().nth(after).unwrap_or(0)..],
- );
-
- // Only use the shrunk version if it's really shorter.
- // This also avoids the case where before and after slices overlap.
- if shrunk.len() < s.len() { shrunk } else { s }
- };
let msg = format!(
"reached the type-length limit while instantiating `{}`",
- shrink(instance.to_string(), 32, 32)
+ shrunk_instance_name(&instance),
);
let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
diag.note(&format!(
// All successor basic blocks must be equal or contain statements that are pairwise considered equal.
for ((bb_l_idx,bb_l), (bb_r_idx,bb_r)) in iter_bbs_reachable.tuple_windows() {
let trivial_checks = bb_l.is_cleanup == bb_r.is_cleanup
- && bb_l.terminator().kind == bb_r.terminator().kind;
+ && bb_l.terminator().kind == bb_r.terminator().kind
+ && bb_l.statements.len() == bb_r.statements.len();
let statement_check = || {
bb_l.statements.iter().zip(&bb_r.statements).try_fold(StatementEquality::TrivialEqual, |acc,(l,r)| {
- let stmt_equality = self.statement_equality(*adt_matched_on, &l, bb_l_idx, &r, bb_r_idx);
+ let stmt_equality = self.statement_equality(*adt_matched_on, &l, bb_l_idx, &r, bb_r_idx, self.tcx.sess.opts.debugging_opts.mir_opt_level);
if matches!(stmt_equality, StatementEquality::NotEqual) {
// short circuit
None
x_bb_idx: BasicBlock,
y: &Statement<'tcx>,
y_bb_idx: BasicBlock,
+ mir_opt_level: usize,
) -> StatementEquality {
let helper = |rhs: &Rvalue<'tcx>,
place: &Box<Place<'tcx>>,
match rhs {
Rvalue::Use(operand) if operand.place() == Some(adt_matched_on) => {
- StatementEquality::ConsideredEqual(side_to_choose)
+ // FIXME(76803): This logic is currently broken because it does not take into
+ // account the current discriminant value.
+ if mir_opt_level > 2 {
+ StatementEquality::ConsideredEqual(side_to_choose)
+ } else {
+ StatementEquality::NotEqual
+ }
}
_ => {
trace!(
Ok(t) => {
// Parsed successfully, therefore most probably the code only
// misses a separator.
+ let mut exp_span = self.sess.source_map().next_point(sp);
+ if self.sess.source_map().is_multiline(exp_span) {
+ exp_span = sp;
+ }
expect_err
.span_suggestion_short(
- self.sess.source_map().next_point(sp),
+ exp_span,
&format!("missing `{}`", token_str),
token_str,
Applicability::MaybeIncorrect,
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
..
} => false,
+ hir::GenericParamKind::Lifetime {
+ kind: hir::LifetimeParamKind::Elided,
+ } => false,
_ => true,
}) {
(param.span.shrink_to_lo(), format!("{}, ", lifetime_ref))
};
}
+declare_lint! {
+ pub MISSING_FRAGMENT_SPECIFIER,
+ Deny,
+ "detects missing fragment specifiers in unused `macro_rules!` patterns",
+ @future_incompatible = FutureIncompatibleInfo {
+ reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
+ edition: None,
+ };
+}
+
declare_lint! {
pub LATE_BOUND_LIFETIME_ARGUMENTS,
Warn,
UNALIGNED_REFERENCES,
SAFE_PACKED_BORROWS,
PATTERNS_IN_FNS_WITHOUT_BODY,
+ MISSING_FRAGMENT_SPECIFIER,
LATE_BOUND_LIFETIME_ARGUMENTS,
ORDER_DEPENDENT_TRAIT_OBJECTS,
COHERENCE_LEAK_CHECK,
pub unstable_features: UnstableFeatures,
pub config: CrateConfig,
pub edition: Edition,
+ pub missing_fragment_specifiers: Lock<FxHashMap<Span, NodeId>>,
/// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
pub raw_identifier_spans: Lock<Vec<Span>>,
/// Used to determine and report recursive module inclusions.
unstable_features: UnstableFeatures::from_environment(),
config: FxHashSet::default(),
edition: ExpnId::root().expn_data().edition,
+ missing_fragment_specifiers: Default::default(),
raw_identifier_spans: Lock::new(Vec::new()),
included_mod_stack: Lock::new(vec![]),
source_map,
use crate::infer::{InferCtxt, InferOk};
use crate::traits::error_reporting::InferCtxtExt;
use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
+use rustc_data_structures::mini_map::MiniMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_infer::traits::Normalized;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
param_env: self.param_env,
obligations: vec![],
error: false,
+ cache: MiniMap::new(),
anon_depth: 0,
};
cause: &'cx ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
obligations: Vec<PredicateObligation<'tcx>>,
+ cache: MiniMap<Ty<'tcx>, Ty<'tcx>>,
error: bool,
anon_depth: usize,
}
return ty;
}
+ if let Some(ty) = self.cache.get(&ty) {
+ return ty;
+ }
+
let ty = ty.super_fold_with(self);
- match ty.kind {
+ let res = (|| match ty.kind {
ty::Opaque(def_id, substs) => {
// Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() {
}
_ => ty,
- }
+ })();
+ self.cache.insert(ty, res);
+ res
}
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
// reachable in rustdoc generated documentation
if !did.is_local() {
if let Some(traitref) = associated_trait {
- if !cx.renderinfo.borrow().access_levels.is_public(traitref.def_id) {
+ let did = traitref.def_id;
+ if !cx.renderinfo.borrow().access_levels.is_public(did) {
return;
}
- }
- // Skip foreign unstable traits from lists of trait implementations and
- // such. This helps prevent dependencies of the standard library, for
- // example, from getting documented as "traits `u32` implements" which
- // isn't really too helpful.
- if let Some(trait_did) = associated_trait {
- if let Some(stab) = cx.tcx.lookup_stability(trait_did.def_id) {
- if stab.level.is_unstable() {
+ if let Some(stab) = tcx.lookup_stability(did) {
+ if stab.level.is_unstable() && stab.feature == sym::rustc_private {
return;
}
}
if !cx.renderinfo.borrow().access_levels.is_public(did) {
return;
}
+
+ if let Some(stab) = tcx.lookup_stability(did) {
+ if stab.level.is_unstable() && stab.feature == sym::rustc_private {
+ return;
+ }
+ }
}
}
# source tarball for a stable release you'll likely see `1.x.0` for rustc and
# `0.(x+1).0` for Cargo where they were released on `date`.
-date: 2020-08-24
+date: 2020-08-27
rustc: 1.46.0
cargo: 0.47.0
# looking at a beta source tarball and it's uncommented we'll shortly comment it
# out.
-dev: 1
+#dev: 1
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16
-- switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16
-+ goto -> bb1; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16
+ switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16
}
bb1: {
-- discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:12:17: 12:21
-- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
-- }
--
-- bb2: {
-- unreachable; // scope 0 at $DIR/simplify-arm.rs:10:11: 10:12
-- }
--
-- bb3: {
+ discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:12:17: 12:21
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/simplify-arm.rs:10:11: 10:12
+ }
+
+ bb3: {
_0 = move _1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
-- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
-+ goto -> bb2; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
}
-- bb4: {
-+ bb2: {
+ bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:14:2: 14:2
}
}
--- /dev/null
+// aux-build:realcore.rs
+
+#![crate_name = "real_gimli"]
+#![feature(staged_api, extremely_unstable)]
+#![unstable(feature = "rustc_private", issue = "none")]
+
+extern crate realcore;
+
+#[unstable(feature = "rustc_private", issue = "none")]
+pub struct EndianSlice;
+
+#[unstable(feature = "rustc_private", issue = "none")]
+impl realcore::Deref for EndianSlice {}
--- /dev/null
+#![crate_name = "realcore"]
+#![feature(staged_api)]
+#![unstable(feature = "extremely_unstable", issue = "none")]
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+pub struct Foo {}
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+pub trait Join {}
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+impl Join for Foo {}
+
+#[stable(feature = "faked_deref", since = "1.47.0")]
+pub trait Deref {}
--- /dev/null
+// ignore-tidy-linelength
+// aux-build:realcore.rs
+// aux-build:real_gimli.rs
+
+// Ensure unstably exported traits have their Implementors sections.
+
+#![crate_name = "foo"]
+#![feature(extremely_unstable_foo)]
+
+extern crate realcore;
+extern crate real_gimli;
+
+// issue #74672
+// @!has foo/trait.Deref.html '//*[@id="impl-Deref-for-EndianSlice"]//code' 'impl Deref for EndianSlice'
+pub use realcore::Deref;
+
+// @has foo/trait.Join.html '//*[@id="impl-Join-for-Foo"]//code' 'impl Join for Foo'
+pub use realcore::Join;
--- /dev/null
+// build-pass
+
+// Closures include captured types twice in a type tree.
+//
+// Wrapping one closure with another leads to doubling
+// the amount of types in the type tree.
+//
+// This test ensures that rust can handle
+// deeply nested type trees with a lot
+// of duplicated subtrees.
+
+fn dup(f: impl Fn(i32) -> i32) -> impl Fn(i32) -> i32 {
+ move |a| f(a * 2)
+}
+
+fn main() {
+ let f = |a| a;
+
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+
+ // Compiler dies around here if it tries
+ // to walk the tree exhaustively.
+
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+ let f = dup(f);
+
+ println!("Type size was at least {}", f(1));
+}
// run-pass
+#![feature(const_type_id)]
#![feature(core_intrinsics)]
use std::any::TypeId;
// will be properly rejected. This test will ensure that monomorphic use of these
// would not be wrongly rejected in patterns.
+#![feature(const_type_id)]
#![feature(const_type_name)]
use std::any::{self, TypeId};
// This test case should either run-pass or be rejected at compile time.
// Currently we just disallow this usage and require pattern is monomorphic.
+#![feature(const_type_id)]
#![feature(const_type_name)]
use std::any::{self, TypeId};
error: constant pattern depends on a generic parameter
- --> $DIR/issue-73976-polymorphic.rs:19:37
+ --> $DIR/issue-73976-polymorphic.rs:20:37
|
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^
error: constant pattern depends on a generic parameter
- --> $DIR/issue-73976-polymorphic.rs:31:42
+ --> $DIR/issue-73976-polymorphic.rs:32:42
|
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: constant pattern depends on a generic parameter
- --> $DIR/issue-73976-polymorphic.rs:19:37
+ --> $DIR/issue-73976-polymorphic.rs:20:37
|
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^
error: constant pattern depends on a generic parameter
- --> $DIR/issue-73976-polymorphic.rs:31:42
+ --> $DIR/issue-73976-polymorphic.rs:32:42
|
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: reached the recursion limit while instantiating `function::<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<usize>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `function::<std::option::Option<s...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
--> $DIR/infinite-instantiation.rs:21:9
|
LL | function(counter - 1, t.to_option());
--- /dev/null
+// run-rustfix
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+fn f(
+ x: u8,
+ y: u8,
+) {}
+//~^^ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y`
+
+fn main() {}
--- /dev/null
+// run-rustfix
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+fn f(
+ x: u8
+ y: u8,
+) {}
+//~^^ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y`
+
+fn main() {}
--- /dev/null
+error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y`
+ --> $DIR/issue-76597.rs:7:38
+ |
+LL | ... x: u8
+ | -
+ | |
+ | expected one of 7 possible tokens
+ | help: missing `,`
+LL | ... y: u8,
+ | ^ unexpected token
+
+error: aborting due to previous error
+
impl D {
pub fn matches<F: Fn()>(&self, f: &F) {
- //~^ ERROR reached the type-length limit while instantiating `D::matches::<[closure
let &D(ref a) = self;
a.matches(f)
+ //~^ ERROR reached the recursion limit while instantiating `A::matches::<[closure
}
}
-error: reached the type-length limit while instantiating `D::matches::$CLOSURE`
- --> $DIR/issue-22638.rs:53:5
+error: reached the recursion limit while instantiating `A::matches::$CLOSURE`
+ --> $DIR/issue-22638.rs:55:9
+ |
+LL | a.matches(f)
+ | ^^^^^^^^^^^^
+ |
+note: `A::matches` defined here
+ --> $DIR/issue-22638.rs:14:5
|
LL | pub fn matches<F: Fn()>(&self, f: &F) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: consider adding a `#![type_length_limit="30408681"]` attribute to your crate
error: aborting due to previous error
impl<T> Foo for T {
#[allow(unconditional_recursion)]
- fn recurse(&self) { //~ ERROR reached the type-length limit
- (self, self).recurse();
+ fn recurse(&self) {
+ (self, self).recurse(); //~ ERROR reached the recursion limit
}
}
-error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(...))))))))))))))) as Foo>::recurse`
+error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse`
+ --> $DIR/issue-37311.rs:16:9
+ |
+LL | (self, self).recurse();
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: `<T as Foo>::recurse` defined here
--> $DIR/issue-37311.rs:15:5
|
LL | fn recurse(&self) {
| ^^^^^^^^^^^^^^^^^
- |
- = note: consider adding a `#![type_length_limit="2097149"]` attribute to your crate
error: aborting due to previous error
--- /dev/null
+#![allow(unused)]
+
+macro_rules! m { ($i) => {} }
+//~^ ERROR missing fragment specifier
+//~| WARN previously accepted
+
+fn main() {}
--- /dev/null
+error: missing fragment specifier
+ --> $DIR/issue-39404.rs:3:19
+ |
+LL | macro_rules! m { ($i) => {} }
+ | ^^
+ |
+ = note: `#[deny(missing_fragment_specifier)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
+
+error: aborting due to previous error
+
-error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut Empty>`
+error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>`
--> $DIR/issue-67552.rs:27:9
|
LL | rec(identity(&mut it))
= note: `#[warn(unconditional_recursion)]` on by default
= help: a `loop` may express intention better if this is on purpose
-error: reached the recursion limit while instantiating `generic::<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `generic::<std::option::Option<st...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
--> $DIR/issue-8727.rs:7:5
|
LL | generic::<Option<T>>();
( $($i:ident)* ) => { $($i)+ }; //~ WARN meta-variable repeats with different Kleene operator
}
+#[warn(missing_fragment_specifier)]
+macro_rules! m { ($i) => {} } //~ WARN missing fragment specifier
+ //~| WARN this was previously accepted
+
#[warn(soft_unstable)]
mod benches {
#[bench] //~ WARN use of unstable library feature 'test'
LL | #[warn(meta_variable_misuse)]
| ^^^^^^^^^^^^^^^^^^^^
+warning: missing fragment specifier
+ --> $DIR/expansion-time.rs:9:19
+ |
+LL | macro_rules! m { ($i) => {} }
+ | ^^
+ |
+note: the lint level is defined here
+ --> $DIR/expansion-time.rs:8:8
+ |
+LL | #[warn(missing_fragment_specifier)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
+
warning: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
- --> $DIR/expansion-time.rs:10:7
+ --> $DIR/expansion-time.rs:14:7
|
LL | #[bench]
| ^^^^^
|
note: the lint level is defined here
- --> $DIR/expansion-time.rs:8:8
+ --> $DIR/expansion-time.rs:12:8
|
LL | #[warn(soft_unstable)]
| ^^^^^^^^^^^^^
| ^
|
note: the lint level is defined here
- --> $DIR/expansion-time.rs:15:8
+ --> $DIR/expansion-time.rs:19:8
|
LL | #[warn(incomplete_include)]
| ^^^^^^^^^^^^^^^^^^
-warning: 3 warnings emitted
+warning: 4 warnings emitted
+++ /dev/null
-#![allow(unused)]
-
-macro_rules! m { ($i) => {} }
-//~^ ERROR missing fragment specifier
-
-fn main() {}
+++ /dev/null
-error: missing fragment specifier
- --> $DIR/issue-39404.rs:3:19
- |
-LL | macro_rules! m { ($i) => {} }
- | ^^
-
-error: aborting due to previous error
-
($a, $b) => {
//~^ ERROR missing fragment
//~| ERROR missing fragment
+ //~| WARN this was previously accepted
()
};
}
|
LL | ($a, $b) => {
| ^^
+ |
+ = note: `#[deny(missing_fragment_specifier)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
error: aborting due to 2 previous errors
--- /dev/null
+// run-pass
+
+#[derive(Debug, Eq, PartialEq)]
+pub enum Type {
+ A,
+ B,
+}
+
+
+pub fn encode(v: Type) -> Type {
+ match v {
+ Type::A => Type::B,
+ _ => v,
+ }
+}
+
+fn main() {
+ assert_eq!(Type::B, encode(Type::A));
+}
--- /dev/null
+// Regression test for SimplifyBranchSame miscompilation.
+// run-pass
+
+macro_rules! m {
+ ($a:expr, $b:expr, $c:block) => {
+ match $a {
+ Lto::Fat | Lto::Thin => { $b; (); $c }
+ Lto::No => { $b; () }
+ }
+ }
+}
+
+pub enum Lto { No, Thin, Fat }
+
+fn f(mut cookie: u32, lto: Lto) -> u32 {
+ let mut _a = false;
+ m!(lto, _a = true, {cookie = 0});
+ cookie
+}
+
+fn main() { assert_eq!(f(42, Lto::Thin), 0) }
{ $+ } => { //~ ERROR expected identifier, found `+`
//~^ ERROR missing fragment specifier
$(x)(y) //~ ERROR expected one of: `*`, `+`, or `?`
- //~^ ERROR attempted to repeat an expression containing no syntax variables
}
}
LL | { $+ } => {
| ^
-error: missing fragment specifier
- --> $DIR/issue-33569.rs:2:8
- |
-LL | { $+ } => {
- | ^
-
error: expected one of: `*`, `+`, or `?`
--> $DIR/issue-33569.rs:4:13
|
LL | $(x)(y)
| ^^^
-error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth
- --> $DIR/issue-33569.rs:4:10
+error: missing fragment specifier
+ --> $DIR/issue-33569.rs:2:8
|
-LL | $(x)(y)
- | ^^^
+LL | { $+ } => {
+ | ^
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
// place of a `None`-delimited group. This allows us to maintain
// backwards compatibility for older versions of these crates.
-include!("js-sys/src/lib.rs");
-include!("time-macros-impl/src/lib.rs");
+mod no_version {
+ include!("js-sys/src/lib.rs");
+ include!("time-macros-impl/src/lib.rs");
-macro_rules! other {
- ($name:ident) => {
- #[my_macro] struct Three($name);
+ macro_rules! other {
+ ($name:ident) => {
+ #[my_macro] struct Three($name);
+ }
}
+
+ struct Foo;
+ impl_macros!(Foo);
+ arrays!(Foo);
+ other!(Foo);
}
-fn main() {
+mod with_version {
+ include!("js-sys-0.3.17/src/lib.rs");
+ include!("time-macros-impl-0.1.0/src/lib.rs");
+
+ macro_rules! other {
+ ($name:ident) => {
+ #[my_macro] struct Three($name);
+ }
+ }
+
struct Foo;
impl_macros!(Foo);
arrays!(Foo);
other!(Foo);
}
+
+
+fn main() {}
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl/src/lib.rs:5:21: 5:27 (#5) }, Ident { ident: "One", span: $DIR/time-macros-impl/src/lib.rs:5:28: 5:31 (#5) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:27:18: 27:21 (#0) }], span: $DIR/time-macros-impl/src/lib.rs:5:31: 5:38 (#5) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl/src/lib.rs:5:38: 5:39 (#5) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys/src/lib.rs:5:21: 5:27 (#9) }, Ident { ident: "Two", span: $DIR/js-sys/src/lib.rs:5:28: 5:31 (#9) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:28:13: 28:16 (#0) }], span: $DIR/js-sys/src/lib.rs:5:31: 5:38 (#9) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys/src/lib.rs:5:38: 5:39 (#9) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:21:21: 21:27 (#13) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:21:28: 21:33 (#13) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:12: 29:15 (#0) }], span: $DIR/group-compat-hack.rs:21:34: 21:39 (#13) }], span: $DIR/group-compat-hack.rs:21:33: 21:40 (#13) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:21:40: 21:41 (#13) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:22:25: 22:31 (#13) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:22:32: 22:37 (#13) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:12: 29:15 (#0) }], span: $DIR/group-compat-hack.rs:22:38: 22:43 (#13) }], span: $DIR/group-compat-hack.rs:22:37: 22:44 (#13) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:22:44: 22:45 (#13) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:21: 5:27 (#19) }, Ident { ident: "One", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:28: 5:31 (#19) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:43:18: 43:21 (#0) }], span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:31: 5:38 (#19) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:38: 5:39 (#19) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.17/src/lib.rs:5:21: 5:27 (#23) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.17/src/lib.rs:5:28: 5:31 (#23) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:44:13: 44:16 (#0) }], span: $DIR/js-sys-0.3.17/src/lib.rs:5:31: 5:38 (#23) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.17/src/lib.rs:5:38: 5:39 (#23) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:38:25: 38:31 (#27) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:38:32: 38:37 (#27) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:45:12: 45:15 (#0) }], span: $DIR/group-compat-hack.rs:38:38: 38:43 (#27) }], span: $DIR/group-compat-hack.rs:38:37: 38:44 (#27) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:38:44: 38:45 (#27) }]
--- /dev/null
+// ignore-test this is not a test
+
+macro_rules! arrays {
+ ($name:ident) => {
+ #[my_macro] struct Two($name);
+ }
+}
--- /dev/null
+// ignore-test this is not a test
+
+macro_rules! impl_macros {
+ ($name:ident) => {
+ #[my_macro] struct One($name);
+ }
+}
-error: reached the recursion limit while instantiating `std::intrinsics::drop_in_place::<S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>> - shim(Some(S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>))`
+error: reached the recursion limit while instantiating `std::intrinsics::drop_in_place::...)))))))))))))))))))))))))))))>))`
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | / pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Nil>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
--> $DIR/recursion.rs:17:11
|
LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
+// edition:2018
// Check that lifetime resolver enforces the lifetime name scoping
// rules correctly in various scenarios.
{
}
+struct Bug {}
+impl Bug {
+ async fn buggy(&self) -> &'a str { //~ ERROR use of undeclared lifetime name `'a`
+ todo!()
+ }
+}
+
pub fn main() {}
error[E0261]: use of undeclared lifetime name `'b`
- --> $DIR/regions-name-undeclared.rs:15:24
+ --> $DIR/regions-name-undeclared.rs:16:24
|
LL | fn m4(&self, arg: &'b isize) { }
| ^^ undeclared lifetime
| ^^^^
error[E0261]: use of undeclared lifetime name `'b`
- --> $DIR/regions-name-undeclared.rs:16:12
+ --> $DIR/regions-name-undeclared.rs:17:12
|
LL | fn m5(&'b self) { }
| ^^ undeclared lifetime
| ^^^^
error[E0261]: use of undeclared lifetime name `'b`
- --> $DIR/regions-name-undeclared.rs:17:27
+ --> $DIR/regions-name-undeclared.rs:18:27
|
LL | fn m6(&self, arg: Foo<'b>) { }
| ^^ undeclared lifetime
| ^^^^
error[E0261]: use of undeclared lifetime name `'a`
- --> $DIR/regions-name-undeclared.rs:25:22
+ --> $DIR/regions-name-undeclared.rs:26:22
|
LL | type X = Option<&'a isize>;
| - ^^ undeclared lifetime
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
error[E0261]: use of undeclared lifetime name `'a`
- --> $DIR/regions-name-undeclared.rs:27:13
+ --> $DIR/regions-name-undeclared.rs:28:13
|
LL | enum E {
| - help: consider introducing lifetime `'a` here: `<'a>`
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
error[E0261]: use of undeclared lifetime name `'a`
- --> $DIR/regions-name-undeclared.rs:30:13
+ --> $DIR/regions-name-undeclared.rs:31:13
|
LL | struct S {
| - help: consider introducing lifetime `'a` here: `<'a>`
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
error[E0261]: use of undeclared lifetime name `'a`
- --> $DIR/regions-name-undeclared.rs:32:14
+ --> $DIR/regions-name-undeclared.rs:33:14
|
LL | fn f(a: &'a isize) { }
| - ^^ undeclared lifetime
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
error[E0261]: use of undeclared lifetime name `'a`
- --> $DIR/regions-name-undeclared.rs:40:17
+ --> $DIR/regions-name-undeclared.rs:41:17
|
LL | fn fn_types(a: &'a isize,
| - ^^ undeclared lifetime
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
error[E0261]: use of undeclared lifetime name `'b`
- --> $DIR/regions-name-undeclared.rs:42:36
+ --> $DIR/regions-name-undeclared.rs:43:36
|
LL | ... &'b isize,
| ^^ undeclared lifetime
| ^^^^
error[E0261]: use of undeclared lifetime name `'b`
- --> $DIR/regions-name-undeclared.rs:45:36
+ --> $DIR/regions-name-undeclared.rs:46:36
|
LL | ... &'b isize)>,
| ^^ undeclared lifetime
| ^^^^
error[E0261]: use of undeclared lifetime name `'a`
- --> $DIR/regions-name-undeclared.rs:46:17
+ --> $DIR/regions-name-undeclared.rs:47:17
|
LL | fn fn_types(a: &'a isize,
| - help: consider introducing lifetime `'a` here: `<'a>`
|
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
-error: aborting due to 11 previous errors
+error[E0261]: use of undeclared lifetime name `'a`
+ --> $DIR/regions-name-undeclared.rs:53:31
+ |
+LL | async fn buggy(&self) -> &'a str {
+ | ^^ undeclared lifetime
+ |
+ = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
+help: consider introducing lifetime `'a` here
+ |
+LL | impl<'a> Bug {
+ | ^^^^
+help: consider introducing lifetime `'a` here
+ |
+LL | async fn buggy<'a>(&self) -> &'a str {
+ | ^^^^
+
+error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0261`.
// Test that the type length limit can be changed.
#![allow(dead_code)]
-#![type_length_limit="256"]
+#![type_length_limit="4"]
macro_rules! link {
($id:ident, $t:ty) => {
-error: reached the type-length limit while instantiating `std::mem::drop::<std::option::Op... G), (G, G, G), (G, G, G))))))>>`
+error: reached the type-length limit while instantiating `std::mem::drop::<std::option::Op....., ...), ..., ...), ..., ...)>>`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | pub fn drop<T>(_x: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
- = note: consider adding a `#![type_length_limit="1094"]` attribute to your crate
+ = note: consider adding a `#![type_length_limit="8"]` attribute to your crate
error: aborting due to previous error
Test {
name: "tokei",
repo: "https://github.com/XAMPPRocky/tokei",
- sha: "a950ff128d5a435a8083b1c7577c0431f98360ca",
+ sha: "5e11c4852fe4aa086b0e4fe5885822fbe57ba928",
+ lock: None,
+ packages: &[],
+ },
+ Test {
+ name: "treeify",
+ repo: "https://github.com/dzamlo/treeify",
+ sha: "999001b223152441198f117a68fb81f57bc086dd",
lock: None,
packages: &[],
},
if let Some(entry) = LINKCHECK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) {
entry.1.contains(&link)
} else {
+ // FIXME(#63351): Concat trait in alloc/slice reexported in primitive page
+ //
+ // NOTE: This cannot be added to `LINKCHECK_EXCEPTIONS` because the resolved path
+ // calculated in `check` function is outside `build/<triple>/doc` dir.
+ // So the `strip_prefix` method just returns the old absolute broken path.
+ if file.ends_with("std/primitive.slice.html") {
+ if link.ends_with("primitive.slice.html") {
+ return true;
+ }
+ }
false
}
}
-1.47.0-beta.2 (84b047bf6 2020-08-28)
\ No newline at end of file
+1.47.0 (18bf6b4f0 2020-10-07)
\ No newline at end of file