Rollup merge of #140852 - est31:edition_guide_let_chains, r=ehuss
Update the edition guide for let chains
Pull https://github.com/rust-lang/edition-guide/pull/337 into the rustc tree.
diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml
index 9455360..ca088ba 100644
--- a/.github/workflows/post-merge.yml
+++ b/.github/workflows/post-merge.yml
@@ -25,12 +25,19 @@
env:
GH_TOKEN: ${{ github.token }}
run: |
+ # Give GitHub some time to propagate the information that the PR was merged
+ sleep 60
+
# Get closest bors merge commit
PARENT_COMMIT=`git rev-list --author='bors <[email protected]>' -n1 --first-parent HEAD^1`
echo "Parent: ${PARENT_COMMIT}"
# Find PR for the current commit
HEAD_PR=`gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number'`
+ if [ -z "${HEAD_PR}" ]; then
+ echo "PR for commit SHA ${{ github.sha }} not found, exiting"
+ exit 1
+ fi
echo "HEAD: ${{ github.sha }} (#${HEAD_PR})"
cd src/ci/citool
diff --git a/Cargo.lock b/Cargo.lock
index 98b90a4..fa0fa33e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -558,7 +558,7 @@
"if_chain",
"itertools",
"parking_lot",
- "pulldown-cmark 0.11.3",
+ "pulldown-cmark",
"quote",
"regex",
"rustc_tools_util 0.4.2",
@@ -2567,7 +2567,6 @@
"humansize",
"humantime",
"log",
- "serde",
"serde_json",
"sysinfo",
"tabled",
@@ -2851,17 +2850,6 @@
[[package]]
name = "pulldown-cmark"
-version = "0.9.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
-dependencies = [
- "bitflags",
- "memchr",
- "unicase",
-]
-
-[[package]]
-name = "pulldown-cmark"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
@@ -4337,7 +4325,7 @@
dependencies = [
"bitflags",
"itertools",
- "pulldown-cmark 0.11.3",
+ "pulldown-cmark",
"rustc_arena",
"rustc_ast",
"rustc_ast_pretty",
@@ -4516,7 +4504,6 @@
"rustc_session",
"rustc_span",
"rustc_transmute",
- "rustc_type_ir",
"smallvec",
"thin-vec",
"tracing",
@@ -4622,7 +4609,6 @@
"indexmap",
"itertools",
"minifier",
- "pulldown-cmark 0.9.6",
"pulldown-cmark-escape",
"regex",
"rustdoc-json-types",
diff --git a/RELEASES.md b/RELEASES.md
index 0948eb8..1a77c33 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,169 @@
+Version 1.87.0 (2025-05-15)
+==========================
+
+<a id="1.87.0-Language"></a>
+
+Language
+--------
+- [Stabilize `asm_goto` feature](https://github.com/rust-lang/rust/pull/133870)
+- [Allow parsing open beginning ranges (`..EXPR`) after unary operators `!`, `~`, `-`, and `*`}](https://github.com/rust-lang/rust/pull/134900).
+- [Don't require method impls for methods with `Self: Sized` bounds in `impl`s for unsized types](https://github.com/rust-lang/rust/pull/135480)
+- [Stabilize `feature(precise_capturing_in_traits)` allowing `use<...>` bounds on return position `impl Trait` in `trait`s](https://github.com/rust-lang/rust/pull/138128)
+
+<a id="1.87.0-Compiler"></a>
+
+Compiler
+--------
+- [x86: make SSE2 required for i686 targets and use it to pass SIMD types](https://github.com/rust-lang/rust/pull/135408)
+
+<a id="1.87.0-Platform-Support"></a>
+
+Platform Support
+----------------
+- [Remove `i586-pc-windows-msvc` target](https://github.com/rust-lang/rust/pull/137957)
+
+Refer to Rust's [platform support page][platform-support-doc]
+for more information on Rust's tiered platform support.
+
+[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html
+
+<a id="1.87.0-Libraries"></a>
+
+Libraries
+---------
+- [Stabilize the anonymous pipe API](https://github.com/rust-lang/rust/issues/127154)
+- [Add support for unbounded left/right shift operations](https://github.com/rust-lang/rust/issues/129375)
+- [Print pointer metadata in `Debug` impl of raw pointers](https://github.com/rust-lang/rust/pull/135080)
+- [`Vec::with_capacity` guarantees it allocates with the amount requested, even if `Vec::capacity` returns a different number.](https://github.com/rust-lang/rust/pull/135933)
+- Most `std::arch` intrinsics which don't take pointer arguments can now be called from safe code if the caller has the appropriate target features already enabled (https://github.com/rust-lang/stdarch/pull/1714, https://github.com/rust-lang/stdarch/pull/1716, https://github.com/rust-lang/stdarch/pull/1717)
+- [Undeprecate `env::home_dir`](https://github.com/rust-lang/rust/pull/137327)
+- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449)
+- [Macros such as `assert_eq!` and `vec!` now support `const {...}` expressions](https://github.com/rust-lang/rust/pull/138162)
+
+<a id="1.87.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [`Vec::extract_if`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.extract_if)
+- [`vec::ExtractIf`](https://doc.rust-lang.org/nightly/std/vec/struct.ExtractIf.html)
+- [`LinkedList::extract_if`](https://doc.rust-lang.org/nightly/std/collections/struct.LinkedList.html#method.extract_if)
+- [`linked_list::ExtractIf`](https://doc.rust-lang.org/nightly/std/collections/linked_list/struct.ExtractIf.html)
+- [`<[T]>::split_off`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off)
+- [`<[T]>::split_off_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_mut)
+- [`<[T]>::split_off_first`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first)
+- [`<[T]>::split_off_first_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first_mut)
+- [`<[T]>::split_off_last`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last)
+- [`<[T]>::split_off_last_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last_mut)
+- [`String::extend_from_within`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within)
+- [`os_str::Display`](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.Display.html)
+- [`OsString::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsString.html#method.display)
+- [`OsStr::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsStr.html#method.display)
+- [`io::pipe`](https://doc.rust-lang.org/nightly/std/io/fn.pipe.html)
+- [`io::PipeReader`](https://doc.rust-lang.org/nightly/std/io/struct.PipeReader.html)
+- [`io::PipeWriter`](https://doc.rust-lang.org/nightly/std/io/struct.PipeWriter.html)
+- [`impl From<PipeReader> for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle)
+- [`impl From<PipeWriter> for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle)
+- [`impl From<PipeReader> for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html)
+- [`impl From<PipeWriter> for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio)
+- [`impl From<PipeReader> for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
+- [`impl From<PipeWriter> for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
+- [`Box<MaybeUninit<T>>::write`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.write)
+- [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
+
+These APIs are now stable in const contexts:
+
+- [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned)
+- [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned)
+- [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned-1)
+- [`<*mut T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned-1)
+- [`NonNull::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.offset_from_unsigned)
+- [`NonNull::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned)
+- [`<uN>::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.cast_signed)
+- [`NonZero::<uN>::cast_signed`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_signed-5).
+- [`<iN>::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.cast_signed).
+- [`NonZero::<iN>::cast_unsigned`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_unsigned-5).
+- [`<uN>::is_multiple_of`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.is_multiple_of)
+- [`<uN>::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shl)
+- [`<uN>::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shr)
+- [`<iN>::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shl)
+- [`<iN>::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shr)
+- [`<str>::from_utf8`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8)
+- [`<str>::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_mut)
+- [`<str>::from_utf8_unchecked`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked)
+- [`<str>::from_utf8_unchecked_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked_mut)
+- [`core::str::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/str/fn.from_utf8_mut.html)
+- [`<[T]>::copy_from_slice`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.copy_from_slice)
+- [`SocketAddr::set_ip`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_ip)
+- [`SocketAddr::set_port`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_port),
+- [`SocketAddrV4::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_ip)
+- [`SocketAddrV4::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_port),
+- [`SocketAddrV6::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_ip)
+- [`SocketAddrV6::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_port)
+- [`SocketAddrV6::set_flowinfo`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_flowinfo)
+- [`SocketAddrV6::set_scope_id`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_scope_id)
+- [`char::is_digit`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_digit)
+- [`char::is_whitespace`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_whitespace)
+- [`<iN>::midpoint`](https://doc.rust-lang.org/std/primitive.isize.html#method.midpoint)
+- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened)
+- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened_mut)
+- [`String::into_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.into_bytes)
+- [`String::as_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_str)
+- [`String::capacity`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.capacity)
+- [`String::as_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_bytes)
+- [`String::len`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.len)
+- [`String::is_empty`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.is_empty)
+- [`String::as_mut_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_str)
+- [`String::as_mut_vec`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_vec)
+- [`Vec::as_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_ptr)
+- [`Vec::as_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_slice)
+- [`Vec::capacity`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.capacity)
+- [`Vec::len`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.len)
+- [`Vec::is_empty`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.is_empty)
+- [`Vec::as_mut_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_slice)
+- [`Vec::as_mut_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_ptr)
+
+<a id="1.87.0-Cargo"></a>
+
+Cargo
+-----
+- [Add terminal integration via ANSI OSC 9;4 sequences](https://github.com/rust-lang/cargo/pull/14615/)
+- [chore: bump openssl to v3](https://github.com/rust-lang/cargo/pull/15232/)
+- [feat(package): add --exclude-lockfile flag](https://github.com/rust-lang/cargo/pull/15234/)
+
+<a id="1.87.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+- [Rust now raises an error for macro invocations inside the `#![crate_name]` attribute](https://github.com/rust-lang/rust/pull/127581)
+- [Unstable fields are now always considered to be inhabited](https://github.com/rust-lang/rust/pull/133889)
+- [Macro arguments of unary operators followed by open beginning ranges may now be matched differently](https://github.com/rust-lang/rust/pull/134900)
+- [Make `Debug` impl of raw pointers print metadata if present](https://github.com/rust-lang/rust/pull/135080)
+- [Warn against function pointers using unsupported ABI strings in dependencies](https://github.com/rust-lang/rust/pull/135767)
+- [Associated types on `dyn` types are no longer deduplicated](https://github.com/rust-lang/rust/pull/136458)
+- [Forbid attributes on `..` inside of struct patterns (`let Struct { #[attribute] .. }) =`](https://github.com/rust-lang/rust/pull/136490)
+- [Make `ptr_cast_add_auto_to_object` lint into hard error](https://github.com/rust-lang/rust/pull/136764)
+- Many `std::arch` intrinsics are now safe to call in some contexts, there may now be new `unused_unsafe` warnings in existing codebases.
+- [Limit `width` and `precision` formatting options to 16 bits on all targets](https://github.com/rust-lang/rust/pull/136932)
+- [Turn order dependent trait objects future incompat warning into a hard error](https://github.com/rust-lang/rust/pull/136968)
+- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449)
+- [Windows: The standard library no longer links `advapi32`, except on win7.](https://github.com/rust-lang/rust/pull/138233) Code such as C libraries that were relying on this assumption may need to explicitly link advapi32.
+- [Proc macros can no longer observe expanded `cfg(true)` attributes.](https://github.com/rust-lang/rust/pull/138844)
+- [Start changing the internal representation of pasted tokens](https://github.com/rust-lang/rust/pull/124141). Certain invalid declarative macros that were previously accepted in obscure circumstances are now correctly rejected by the compiler. Use of a `tt` fragment specifier can often fix these macros.
+- [Don't allow flattened format_args in const.](https://github.com/rust-lang/rust/pull/139624)
+
+<a id="1.87.0-Internal-Changes"></a>
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Update to LLVM 20](https://github.com/rust-lang/rust/pull/135763)
+
+
Version 1.86.0 (2025-04-03)
==========================
diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
index d37ede8..c1d95d0 100644
--- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
@@ -53,7 +53,7 @@ fn parse_unstable<'a>(
for param in list.mixed() {
let param_span = param.span();
- if let Some(ident) = param.meta_item().and_then(|i| i.word_without_args()) {
+ if let Some(ident) = param.meta_item().and_then(|i| i.path_without_args().word()) {
res.push(ident.name);
} else {
cx.emit_err(session_diagnostics::ExpectsFeatures {
diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
index 7d14174..fb3d5f5 100644
--- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
@@ -1,5 +1,4 @@
use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation};
-use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol, sym};
use super::SingleAttributeParser;
@@ -13,16 +12,13 @@
fn get(
cx: &AcceptContext<'_>,
- ident: Ident,
+ name: Symbol,
param_span: Span,
arg: &ArgParser<'_>,
item: &Option<Symbol>,
) -> Option<Symbol> {
if item.is_some() {
- cx.emit_err(session_diagnostics::MultipleItem {
- span: param_span,
- item: ident.to_string(),
- });
+ cx.emit_err(session_diagnostics::MultipleItem { span: param_span, item: name.to_string() });
return None;
}
if let Some(v) = arg.name_value() {
@@ -83,16 +79,16 @@ fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind
return None;
};
- let (ident, arg) = param.word_or_empty();
+ let ident_name = param.path_without_args().word_sym();
- match ident.name {
- sym::since => {
- since = Some(get(cx, ident, param_span, arg, &since)?);
+ match ident_name {
+ Some(name @ sym::since) => {
+ since = Some(get(cx, name, param_span, param.args(), &since)?);
}
- sym::note => {
- note = Some(get(cx, ident, param_span, arg, ¬e)?);
+ Some(name @ sym::note) => {
+ note = Some(get(cx, name, param_span, param.args(), ¬e)?);
}
- sym::suggestion => {
+ Some(name @ sym::suggestion) => {
if !features.deprecated_suggestion() {
cx.emit_err(session_diagnostics::DeprecatedItemSuggestion {
span: param_span,
@@ -101,12 +97,12 @@ fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind
});
}
- suggestion = Some(get(cx, ident, param_span, arg, &suggestion)?);
+ suggestion = Some(get(cx, name, param_span, param.args(), &suggestion)?);
}
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param_span,
- item: ident.to_string(),
+ item: param.path_without_args().to_string(),
expected: if features.deprecated_suggestion() {
&["since", "note", "suggestion"]
} else {
diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs
index 26ca637..43dfb85 100644
--- a/compiler/rustc_attr_parsing/src/attributes/repr.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs
@@ -96,58 +96,75 @@ fn parse_repr(cx: &AcceptContext<'_>, param: &MetaItemParser<'_>) -> Option<Repr
// FIXME(jdonszelmann): invert the parsing here to match on the word first and then the
// structure.
- let (ident, args) = param.word_or_empty();
+ let (name, ident_span) = if let Some(ident) = param.path_without_args().word() {
+ (Some(ident.name), ident.span)
+ } else {
+ (None, rustc_span::DUMMY_SP)
+ };
- match (ident.name, args) {
- (sym::align, ArgParser::NoArgs) => {
- cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident.span });
+ let args = param.args();
+
+ match (name, args) {
+ (Some(sym::align), ArgParser::NoArgs) => {
+ cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident_span });
None
}
- (sym::align, ArgParser::List(l)) => parse_repr_align(cx, l, param.span(), AlignKind::Align),
+ (Some(sym::align), ArgParser::List(l)) => {
+ parse_repr_align(cx, l, param.span(), AlignKind::Align)
+ }
- (sym::packed, ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
- (sym::packed, ArgParser::List(l)) => {
+ (Some(sym::packed), ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
+ (Some(sym::packed), ArgParser::List(l)) => {
parse_repr_align(cx, l, param.span(), AlignKind::Packed)
}
- (sym::align | sym::packed, ArgParser::NameValue(l)) => {
+ (Some(name @ sym::align | name @ sym::packed), ArgParser::NameValue(l)) => {
cx.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
span: param.span(),
// FIXME(jdonszelmann) can just be a string in the diag type
- repr_arg: &ident.to_string(),
+ repr_arg: name,
cause: IncorrectReprFormatGenericCause::from_lit_kind(
param.span(),
&l.value_as_lit().kind,
- ident.name.as_str(),
+ name,
),
});
None
}
- (sym::Rust, ArgParser::NoArgs) => Some(ReprRust),
- (sym::C, ArgParser::NoArgs) => Some(ReprC),
- (sym::simd, ArgParser::NoArgs) => Some(ReprSimd),
- (sym::transparent, ArgParser::NoArgs) => Some(ReprTransparent),
- (i @ int_pat!(), ArgParser::NoArgs) => {
+ (Some(sym::Rust), ArgParser::NoArgs) => Some(ReprRust),
+ (Some(sym::C), ArgParser::NoArgs) => Some(ReprC),
+ (Some(sym::simd), ArgParser::NoArgs) => Some(ReprSimd),
+ (Some(sym::transparent), ArgParser::NoArgs) => Some(ReprTransparent),
+ (Some(name @ int_pat!()), ArgParser::NoArgs) => {
// int_pat!() should make sure it always parses
- Some(ReprInt(int_type_of_word(i).unwrap()))
+ Some(ReprInt(int_type_of_word(name).unwrap()))
}
(
- sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(),
+ Some(
+ name @ sym::Rust
+ | name @ sym::C
+ | name @ sym::simd
+ | name @ sym::transparent
+ | name @ int_pat!(),
+ ),
ArgParser::NameValue(_),
) => {
- cx.emit_err(session_diagnostics::InvalidReprHintNoValue {
- span: param.span(),
- name: ident.to_string(),
- });
+ cx.emit_err(session_diagnostics::InvalidReprHintNoValue { span: param.span(), name });
None
}
- (sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(), ArgParser::List(_)) => {
- cx.emit_err(session_diagnostics::InvalidReprHintNoParen {
- span: param.span(),
- name: ident.to_string(),
- });
+ (
+ Some(
+ name @ sym::Rust
+ | name @ sym::C
+ | name @ sym::simd
+ | name @ sym::transparent
+ | name @ int_pat!(),
+ ),
+ ArgParser::List(_),
+ ) => {
+ cx.emit_err(session_diagnostics::InvalidReprHintNoParen { span: param.span(), name });
None
}
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index bdad6b5..cd1f21d 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -242,9 +242,9 @@ pub(crate) fn parse_stability(
return None;
};
- match param.word_or_empty_without_args().name {
- sym::feature => insert_value_into_option_or_error(cx, ¶m, &mut feature)?,
- sym::since => insert_value_into_option_or_error(cx, ¶m, &mut since)?,
+ match param.path_without_args().word_sym() {
+ Some(sym::feature) => insert_value_into_option_or_error(cx, ¶m, &mut feature)?,
+ Some(sym::since) => insert_value_into_option_or_error(cx, ¶m, &mut since)?,
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param_span,
@@ -310,11 +310,10 @@ pub(crate) fn parse_unstability(
return None;
};
- let (word, args) = param.word_or_empty();
- match word.name {
- sym::feature => insert_value_into_option_or_error(cx, ¶m, &mut feature)?,
- sym::reason => insert_value_into_option_or_error(cx, ¶m, &mut reason)?,
- sym::issue => {
+ match param.path_without_args().word_sym() {
+ Some(sym::feature) => insert_value_into_option_or_error(cx, ¶m, &mut feature)?,
+ Some(sym::reason) => insert_value_into_option_or_error(cx, ¶m, &mut reason)?,
+ Some(sym::issue) => {
insert_value_into_option_or_error(cx, ¶m, &mut issue)?;
// These unwraps are safe because `insert_value_into_option_or_error` ensures the meta item
@@ -328,7 +327,7 @@ pub(crate) fn parse_unstability(
session_diagnostics::InvalidIssueString {
span: param.span(),
cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind(
- args.name_value().unwrap().value_span,
+ param.args().name_value().unwrap().value_span,
err.kind(),
),
},
@@ -338,13 +337,15 @@ pub(crate) fn parse_unstability(
},
};
}
- sym::soft => {
- if !args.no_args() {
+ Some(sym::soft) => {
+ if !param.args().no_args() {
cx.emit_err(session_diagnostics::SoftNoArgs { span: param.span() });
}
is_soft = true;
}
- sym::implied_by => insert_value_into_option_or_error(cx, ¶m, &mut implied_by)?,
+ Some(sym::implied_by) => {
+ insert_value_into_option_or_error(cx, ¶m, &mut implied_by)?
+ }
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param.span(),
diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs
index 40aa397..077d953 100644
--- a/compiler/rustc_attr_parsing/src/parser.rs
+++ b/compiler/rustc_attr_parsing/src/parser.rs
@@ -78,8 +78,8 @@ pub fn word(&self) -> Option<Ident> {
(self.len() == 1).then(|| **self.segments().next().as_ref().unwrap())
}
- pub fn word_or_empty(&self) -> Ident {
- self.word().unwrap_or_else(Ident::empty)
+ pub fn word_sym(&self) -> Option<Symbol> {
+ self.word().map(|ident| ident.name)
}
/// Asserts that this MetaItem is some specific word.
@@ -284,11 +284,6 @@ pub fn word_without_args(&self) -> Option<Ident> {
Some(self.word()?.0)
}
- /// Like [`word`](Self::word), but returns an empty symbol instead of None
- pub fn word_or_empty_without_args(&self) -> Ident {
- self.word_or_empty().0
- }
-
/// Asserts that this MetaItem starts with a word, or single segment path.
///
/// Some examples:
@@ -300,12 +295,6 @@ pub fn word(&self) -> Option<(Ident, &ArgParser<'a>)> {
Some((path.word()?, args))
}
- /// Like [`word`](Self::word), but returns an empty symbol instead of None
- pub fn word_or_empty(&self) -> (Ident, &ArgParser<'a>) {
- let (path, args) = self.deconstruct();
- (path.word().unwrap_or(Ident::empty()), args)
- }
-
/// Asserts that this MetaItem starts with some specific word.
///
/// See [`word`](Self::word) for examples of what a word is.
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
index 9d34b80..2c43417 100644
--- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs
+++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -204,7 +204,7 @@ pub(crate) struct InvalidReprHintNoParen {
#[primary_span]
pub span: Span,
- pub name: String,
+ pub name: Symbol,
}
#[derive(Diagnostic)]
@@ -213,7 +213,7 @@ pub(crate) struct InvalidReprHintNoValue {
#[primary_span]
pub span: Span,
- pub name: String,
+ pub name: Symbol,
}
/// Error code: E0565
@@ -295,21 +295,21 @@ pub(crate) struct IncorrectReprFormatExpectInteger {
#[derive(Diagnostic)]
#[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)]
-pub(crate) struct IncorrectReprFormatGeneric<'a> {
+pub(crate) struct IncorrectReprFormatGeneric {
#[primary_span]
pub span: Span,
- pub repr_arg: &'a str,
+ pub repr_arg: Symbol,
#[subdiagnostic]
- pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
+ pub cause: Option<IncorrectReprFormatGenericCause>,
}
#[derive(Subdiagnostic)]
-pub(crate) enum IncorrectReprFormatGenericCause<'a> {
+pub(crate) enum IncorrectReprFormatGenericCause {
#[suggestion(
attr_parsing_suggestion,
- code = "{name}({int})",
+ code = "{name}({value})",
applicability = "machine-applicable"
)]
Int {
@@ -317,15 +317,15 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
span: Span,
#[skip_arg]
- name: &'a str,
+ name: Symbol,
#[skip_arg]
- int: u128,
+ value: u128,
},
#[suggestion(
attr_parsing_suggestion,
- code = "{name}({symbol})",
+ code = "{name}({value})",
applicability = "machine-applicable"
)]
Symbol {
@@ -333,20 +333,20 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
span: Span,
#[skip_arg]
- name: &'a str,
+ name: Symbol,
#[skip_arg]
- symbol: Symbol,
+ value: Symbol,
},
}
-impl<'a> IncorrectReprFormatGenericCause<'a> {
- pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
- match kind {
- ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
- Some(Self::Int { span, name, int: int.get() })
+impl IncorrectReprFormatGenericCause {
+ pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: Symbol) -> Option<Self> {
+ match *kind {
+ ast::LitKind::Int(value, ast::LitIntType::Unsuffixed) => {
+ Some(Self::Int { span, name, value: value.get() })
}
- ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
+ ast::LitKind::Str(value, _) => Some(Self::Symbol { span, name, value }),
_ => None,
}
}
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 44af1b7..3e075d4 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -47,7 +47,7 @@
use rustc_mir_dataflow::move_paths::{
InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex,
};
-use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
+use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor, visit_results};
use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
use rustc_span::{ErrorGuaranteed, Span, Symbol};
use smallvec::SmallVec;
@@ -127,6 +127,14 @@ fn mir_borrowck(
Ok(tcx.arena.alloc(opaque_types))
} else {
let mut root_cx = BorrowCheckRootCtxt::new(tcx, def);
+ // We need to manually borrowck all nested bodies from the HIR as
+ // we do not generate MIR for dead code. Not doing so causes us to
+ // never check closures in dead code.
+ let nested_bodies = tcx.nested_bodies_within(def);
+ for def_id in nested_bodies {
+ root_cx.get_or_insert_nested(def_id);
+ }
+
let PropagatedBorrowCheckResults { closure_requirements, used_mut_upvars } =
do_mir_borrowck(&mut root_cx, def, None).0;
debug_assert!(closure_requirements.is_none());
@@ -461,11 +469,13 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
// Compute and report region errors, if any.
mbcx.report_region_errors(nll_errors);
- let mut flow_results = get_flow_results(tcx, body, &move_data, &borrow_set, ®ioncx);
+ let (mut flow_analysis, flow_entry_states) =
+ get_flow_results(tcx, body, &move_data, &borrow_set, ®ioncx);
visit_results(
body,
traversal::reverse_postorder(body).map(|(bb, _)| bb),
- &mut flow_results,
+ &mut flow_analysis,
+ &flow_entry_states,
&mut mbcx,
);
@@ -525,7 +535,7 @@ fn get_flow_results<'a, 'tcx>(
move_data: &'a MoveData<'tcx>,
borrow_set: &'a BorrowSet<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
-) -> Results<'tcx, Borrowck<'a, 'tcx>> {
+) -> (Borrowck<'a, 'tcx>, Results<BorrowckDomain>) {
// We compute these three analyses individually, but them combine them into
// a single results so that `mbcx` can visit them all together.
let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
@@ -550,14 +560,14 @@ fn get_flow_results<'a, 'tcx>(
ever_inits: ever_inits.analysis,
};
- assert_eq!(borrows.entry_states.len(), uninits.entry_states.len());
- assert_eq!(borrows.entry_states.len(), ever_inits.entry_states.len());
- let entry_states: EntryStates<'_, Borrowck<'_, '_>> =
- itertools::izip!(borrows.entry_states, uninits.entry_states, ever_inits.entry_states)
+ assert_eq!(borrows.results.len(), uninits.results.len());
+ assert_eq!(borrows.results.len(), ever_inits.results.len());
+ let results: Results<_> =
+ itertools::izip!(borrows.results, uninits.results, ever_inits.results)
.map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits })
.collect();
- Results { analysis, entry_states }
+ (analysis, results)
}
pub(crate) struct BorrowckInferCtxt<'tcx> {
@@ -705,7 +715,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, '_, 'tcx> {
fn visit_after_early_statement_effect(
&mut self,
- _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
+ _analysis: &mut Borrowck<'a, 'tcx>,
state: &BorrowckDomain,
stmt: &Statement<'tcx>,
location: Location,
@@ -781,7 +791,7 @@ fn visit_after_early_statement_effect(
fn visit_after_early_terminator_effect(
&mut self,
- _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
+ _analysis: &mut Borrowck<'a, 'tcx>,
state: &BorrowckDomain,
term: &Terminator<'tcx>,
loc: Location,
@@ -901,7 +911,7 @@ fn visit_after_early_terminator_effect(
fn visit_after_primary_terminator_effect(
&mut self,
- _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
+ _analysis: &mut Borrowck<'a, 'tcx>,
state: &BorrowckDomain,
term: &Terminator<'tcx>,
loc: Location,
diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs
index 13daa5c..66b526f 100644
--- a/compiler/rustc_borrowck/src/root_cx.rs
+++ b/compiler/rustc_borrowck/src/root_cx.rs
@@ -62,7 +62,10 @@ pub(super) fn set_tainted_by_errors(&mut self, guar: ErrorGuaranteed) {
self.tainted_by_errors = Some(guar);
}
- fn get_or_insert_nested(&mut self, def_id: LocalDefId) -> &PropagatedBorrowCheckResults<'tcx> {
+ pub(super) fn get_or_insert_nested(
+ &mut self,
+ def_id: LocalDefId,
+ ) -> &PropagatedBorrowCheckResults<'tcx> {
debug_assert_eq!(
self.tcx.typeck_root_def_id(def_id.to_def_id()),
self.root_def_id.to_def_id()
diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
index d41cbf7..341c50c 100644
--- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
@@ -266,10 +266,6 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'t
where
OP: FnMut(ty::Region<'tcx>),
{
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
- t.super_visit_with(self);
- }
-
fn visit_region(&mut self, r: ty::Region<'tcx>) {
match r.kind() {
// ignore bound regions, keep visiting
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 1265400..39f9d5f 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -1,3 +1,5 @@
+use std::ops::Range;
+
use parse::Position::ArgumentNamed;
use rustc_ast::ptr::P;
use rustc_ast::tokenstream::TokenStream;
@@ -335,7 +337,7 @@ fn make_format_args(
return ExpandResult::Ready(Err(guar));
}
- let to_span = |inner_span: parse::InnerSpan| {
+ let to_span = |inner_span: Range<usize>| {
is_source_literal.then(|| {
fmt_span.from_inner(InnerSpan { start: inner_span.start, end: inner_span.end })
})
@@ -407,7 +409,7 @@ enum ArgRef<'a> {
let mut placeholder_index = 0;
for piece in &pieces {
- match *piece {
+ match piece.clone() {
parse::Piece::Lit(s) => {
unfinished_literal.push_str(s);
}
@@ -417,7 +419,8 @@ enum ArgRef<'a> {
unfinished_literal.clear();
}
- let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s));
+ let span =
+ parser.arg_places.get(placeholder_index).and_then(|s| to_span(s.clone()));
placeholder_index += 1;
let position_span = to_span(position_span);
@@ -609,7 +612,7 @@ enum ArgRef<'a> {
fn invalid_placeholder_type_error(
ecx: &ExtCtxt<'_>,
ty: &str,
- ty_span: Option<parse::InnerSpan>,
+ ty_span: Option<Range<usize>>,
fmt_span: Span,
) {
let sp = ty_span.map(|sp| fmt_span.from_inner(InnerSpan::new(sp.start, sp.end)));
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index bf81eb6..cbac55c 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -364,7 +364,12 @@ fn get_static_inner(&self, def_id: DefId, llty: &'ll Type) -> &'ll Value {
if !def_id.is_local() {
let needs_dll_storage_attr = self.use_dll_storage_attrs
- && !self.tcx.is_foreign_item(def_id)
+ // If the symbol is a foreign item, then don't automatically apply DLLImport, as
+ // we'll rely on the #[link] attribute instead. BUT, if this is an internal symbol
+ // then it may be generated by the compiler in some crate, so we do need to apply
+ // DLLImport when linking with the MSVC linker.
+ && (!self.tcx.is_foreign_item(def_id)
+ || (self.sess().target.is_like_msvc && fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)))
// Local definitions can never be imported, so we must not apply
// the DLLImport annotation.
&& !dso_local
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 2645102..8f57f09 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -19,6 +19,7 @@
use rustc_span::Symbol;
use rustc_target::spec::{MergeFunctions, PanicStrategy, SmallDataThresholdSupport};
use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATURES};
+use smallvec::{SmallVec, smallvec};
use crate::back::write::create_informational_target_machine;
use crate::errors::{
@@ -180,27 +181,27 @@ fn as_str(&self) -> &'a str {
pub(crate) struct LLVMFeature<'a> {
llvm_feature_name: &'a str,
- dependency: Option<TargetFeatureFoldStrength<'a>>,
+ dependencies: SmallVec<[TargetFeatureFoldStrength<'a>; 1]>,
}
impl<'a> LLVMFeature<'a> {
fn new(llvm_feature_name: &'a str) -> Self {
- Self { llvm_feature_name, dependency: None }
+ Self { llvm_feature_name, dependencies: SmallVec::new() }
}
- fn with_dependency(
+ fn with_dependencies(
llvm_feature_name: &'a str,
- dependency: TargetFeatureFoldStrength<'a>,
+ dependencies: SmallVec<[TargetFeatureFoldStrength<'a>; 1]>,
) -> Self {
- Self { llvm_feature_name, dependency: Some(dependency) }
+ Self { llvm_feature_name, dependencies }
}
- fn contains(&self, feat: &str) -> bool {
+ fn contains(&'a self, feat: &str) -> bool {
self.iter().any(|dep| dep == feat)
}
fn iter(&'a self) -> impl Iterator<Item = &'a str> {
- let dependencies = self.dependency.iter().map(|feat| feat.as_str());
+ let dependencies = self.dependencies.iter().map(|feat| feat.as_str());
std::iter::once(self.llvm_feature_name).chain(dependencies)
}
}
@@ -210,7 +211,7 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
type IntoIter = impl Iterator<Item = &'a str>;
fn into_iter(self) -> Self::IntoIter {
- let dependencies = self.dependency.into_iter().map(|feat| feat.as_str());
+ let dependencies = self.dependencies.into_iter().map(|feat| feat.as_str());
std::iter::once(self.llvm_feature_name).chain(dependencies)
}
}
@@ -240,9 +241,9 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
&*sess.target.arch
};
match (arch, s) {
- ("x86", "sse4.2") => Some(LLVMFeature::with_dependency(
+ ("x86", "sse4.2") => Some(LLVMFeature::with_dependencies(
"sse4.2",
- TargetFeatureFoldStrength::EnableOnly("crc32"),
+ smallvec![TargetFeatureFoldStrength::EnableOnly("crc32")],
)),
("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")),
("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")),
@@ -262,9 +263,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
("aarch64", "sme-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")),
("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")),
// Rust ties fp and neon together.
- ("aarch64", "neon") => {
- Some(LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8")))
- }
+ ("aarch64", "neon") => Some(LLVMFeature::with_dependencies(
+ "neon",
+ smallvec![TargetFeatureFoldStrength::Both("fp-armv8")],
+ )),
// In LLVM neon implicitly enables fp, but we manually enable
// neon when a feature only implicitly enables fp
("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")),
@@ -281,9 +283,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
// Filter out features that are not supported by the current LLVM version
("riscv32" | "riscv64", "zacas") if get_version().0 < 20 => None,
// Enable the evex512 target feature if an avx512 target feature is enabled.
- ("x86", s) if s.starts_with("avx512") => {
- Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")))
- }
+ ("x86", s) if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies(
+ s,
+ smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")],
+ )),
// Support for `wide-arithmetic` will first land in LLVM 20 as part of
// llvm/llvm-project#111598
("wasm32" | "wasm64", "wide-arithmetic") if get_version() < (20, 0, 0) => None,
@@ -304,6 +307,18 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
("x86", "avx10.1") => Some(LLVMFeature::new("avx10.1-512")),
("x86", "avx10.2") if get_version().0 < 20 => None,
("x86", "avx10.2") if get_version().0 >= 20 => Some(LLVMFeature::new("avx10.2-512")),
+ ("x86", "apxf") => Some(LLVMFeature::with_dependencies(
+ "egpr",
+ smallvec![
+ TargetFeatureFoldStrength::Both("push2pop2"),
+ TargetFeatureFoldStrength::Both("ppx"),
+ TargetFeatureFoldStrength::Both("ndd"),
+ TargetFeatureFoldStrength::Both("ccmp"),
+ TargetFeatureFoldStrength::Both("cf"),
+ TargetFeatureFoldStrength::Both("nf"),
+ TargetFeatureFoldStrength::Both("zu"),
+ ],
+ )),
(_, s) => Some(LLVMFeature::new(s)),
}
}
@@ -853,7 +868,7 @@ pub(crate) fn global_llvm_features(
"{}{}",
enable_disable, llvm_feature.llvm_feature_name
))
- .chain(llvm_feature.dependency.into_iter().filter_map(
+ .chain(llvm_feature.dependencies.into_iter().filter_map(
move |feat| match (enable, feat) {
(_, TargetFeatureFoldStrength::Both(f))
| (true, TargetFeatureFoldStrength::EnableOnly(f)) => {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 8fc8390..80ee8ea 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -337,7 +337,12 @@ fn add_object(&mut self, path: &Path) {
fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]);
fn no_crt_objects(&mut self);
fn no_default_libraries(&mut self);
- fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
+ fn export_symbols(
+ &mut self,
+ tmpdir: &Path,
+ crate_type: CrateType,
+ symbols: &[(String, SymbolExportKind)],
+ );
fn subsystem(&mut self, subsystem: &str);
fn linker_plugin_lto(&mut self);
fn add_eh_frame_header(&mut self) {}
@@ -770,7 +775,12 @@ fn no_default_libraries(&mut self) {
}
}
- fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
+ fn export_symbols(
+ &mut self,
+ tmpdir: &Path,
+ crate_type: CrateType,
+ symbols: &[(String, SymbolExportKind)],
+ ) {
// Symbol visibility in object files typically takes care of this.
if crate_type == CrateType::Executable {
let should_export_executable_symbols =
@@ -799,7 +809,7 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[St
// Write a plain, newline-separated list of symbols
let res: io::Result<()> = try {
let mut f = File::create_buffered(&path)?;
- for sym in symbols {
+ for (sym, _) in symbols {
debug!(" _{sym}");
writeln!(f, "_{sym}")?;
}
@@ -814,11 +824,12 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[St
// .def file similar to MSVC one but without LIBRARY section
// because LD doesn't like when it's empty
writeln!(f, "EXPORTS")?;
- for symbol in symbols {
+ for (symbol, kind) in symbols {
+ let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" };
debug!(" _{symbol}");
// Quote the name in case it's reserved by linker in some way
// (this accounts for names with dots in particular).
- writeln!(f, " \"{symbol}\"")?;
+ writeln!(f, " \"{symbol}\"{kind_marker}")?;
}
};
if let Err(error) = res {
@@ -831,7 +842,7 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[St
writeln!(f, "{{")?;
if !symbols.is_empty() {
writeln!(f, " global:")?;
- for sym in symbols {
+ for (sym, _) in symbols {
debug!(" {sym};");
writeln!(f, " {sym};")?;
}
@@ -1098,7 +1109,12 @@ fn debuginfo(&mut self, _strip: Strip, natvis_debugger_visualizers: &[PathBuf])
// crates. Upstream rlibs may be linked statically to this dynamic library,
// in which case they may continue to transitively be used and hence need
// their symbols exported.
- fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
+ fn export_symbols(
+ &mut self,
+ tmpdir: &Path,
+ crate_type: CrateType,
+ symbols: &[(String, SymbolExportKind)],
+ ) {
// Symbol visibility takes care of this typically
if crate_type == CrateType::Executable {
let should_export_executable_symbols =
@@ -1116,9 +1132,10 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[St
// straight to exports.
writeln!(f, "LIBRARY")?;
writeln!(f, "EXPORTS")?;
- for symbol in symbols {
+ for (symbol, kind) in symbols {
+ let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" };
debug!(" _{symbol}");
- writeln!(f, " {symbol}")?;
+ writeln!(f, " {symbol}{kind_marker}")?;
}
};
if let Err(error) = res {
@@ -1259,14 +1276,19 @@ fn no_default_libraries(&mut self) {
self.cc_arg("-nodefaultlibs");
}
- fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
+ fn export_symbols(
+ &mut self,
+ _tmpdir: &Path,
+ _crate_type: CrateType,
+ symbols: &[(String, SymbolExportKind)],
+ ) {
debug!("EXPORTED SYMBOLS:");
self.cc_arg("-s");
let mut arg = OsString::from("EXPORTED_FUNCTIONS=");
let encoded = serde_json::to_string(
- &symbols.iter().map(|sym| "_".to_owned() + sym).collect::<Vec<_>>(),
+ &symbols.iter().map(|(sym, _)| "_".to_owned() + sym).collect::<Vec<_>>(),
)
.unwrap();
debug!("{encoded}");
@@ -1428,8 +1450,13 @@ fn no_crt_objects(&mut self) {}
fn no_default_libraries(&mut self) {}
- fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
- for sym in symbols {
+ fn export_symbols(
+ &mut self,
+ _tmpdir: &Path,
+ _crate_type: CrateType,
+ symbols: &[(String, SymbolExportKind)],
+ ) {
+ for (sym, _) in symbols {
self.link_args(&["--export", sym]);
}
@@ -1563,7 +1590,7 @@ fn no_default_libraries(&mut self) {
self.cc_arg("-nostdlib");
}
- fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
+ fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[(String, SymbolExportKind)]) {
// ToDo, not implemented, copy from GCC
self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented);
}
@@ -1720,12 +1747,17 @@ fn no_crt_objects(&mut self) {}
fn no_default_libraries(&mut self) {}
- fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
+ fn export_symbols(
+ &mut self,
+ tmpdir: &Path,
+ _crate_type: CrateType,
+ symbols: &[(String, SymbolExportKind)],
+ ) {
let path = tmpdir.join("list.exp");
let res: io::Result<()> = try {
let mut f = File::create_buffered(&path)?;
// FIXME: use llvm-nm to generate export list.
- for symbol in symbols {
+ for (symbol, _) in symbols {
debug!(" _{symbol}");
writeln!(f, " {symbol}")?;
}
@@ -1769,9 +1801,12 @@ fn for_each_exported_symbols_include_dep<'tcx>(
}
}
-pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
+pub(crate) fn exported_symbols(
+ tcx: TyCtxt<'_>,
+ crate_type: CrateType,
+) -> Vec<(String, SymbolExportKind)> {
if let Some(ref exports) = tcx.sess.target.override_export_symbols {
- return exports.iter().map(ToString::to_string).collect();
+ return exports.iter().map(|name| (name.to_string(), SymbolExportKind::Text)).collect();
}
if let CrateType::ProcMacro = crate_type {
@@ -1781,7 +1816,10 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
}
}
-fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
+fn exported_symbols_for_non_proc_macro(
+ tcx: TyCtxt<'_>,
+ crate_type: CrateType,
+) -> Vec<(String, SymbolExportKind)> {
let mut symbols = Vec::new();
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
@@ -1789,17 +1827,18 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
// from any cdylib. The latter doesn't work anyway as we use hidden visibility for
// compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
if info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) {
- symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate(
- tcx, symbol, cnum,
+ symbols.push((
+ symbol_export::exporting_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
+ info.kind,
));
- symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, cnum);
+ symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, info, cnum);
}
});
symbols
}
-fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
+fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<(String, SymbolExportKind)> {
// `exported_symbols` will be empty when !should_codegen.
if !tcx.sess.opts.output_types.should_codegen() {
return Vec::new();
@@ -1809,7 +1848,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
- vec![proc_macro_decls_name, metadata_symbol_name]
+ vec![
+ (proc_macro_decls_name, SymbolExportKind::Text),
+ (metadata_symbol_name, SymbolExportKind::Text),
+ ]
}
pub(crate) fn linked_symbols(
@@ -1831,7 +1873,9 @@ pub(crate) fn linked_symbols(
|| info.used
{
symbols.push((
- symbol_export::linking_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
+ symbol_export::linking_symbol_name_for_instance_in_crate(
+ tcx, symbol, info.kind, cnum,
+ ),
info.kind,
));
}
@@ -1906,7 +1950,13 @@ fn control_flow_guard(&mut self) {}
fn ehcont_guard(&mut self) {}
- fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {}
+ fn export_symbols(
+ &mut self,
+ _tmpdir: &Path,
+ _crate_type: CrateType,
+ _symbols: &[(String, SymbolExportKind)],
+ ) {
+ }
fn subsystem(&mut self, _subsystem: &str) {}
@@ -1975,10 +2025,15 @@ fn control_flow_guard(&mut self) {}
fn ehcont_guard(&mut self) {}
- fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
+ fn export_symbols(
+ &mut self,
+ _tmpdir: &Path,
+ _crate_type: CrateType,
+ symbols: &[(String, SymbolExportKind)],
+ ) {
match _crate_type {
CrateType::Cdylib => {
- for sym in symbols {
+ for (sym, _) in symbols {
self.link_args(&["--export-symbol", sym]);
}
}
@@ -2052,11 +2107,16 @@ fn control_flow_guard(&mut self) {}
fn ehcont_guard(&mut self) {}
- fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
+ fn export_symbols(
+ &mut self,
+ tmpdir: &Path,
+ _crate_type: CrateType,
+ symbols: &[(String, SymbolExportKind)],
+ ) {
let path = tmpdir.join("symbols");
let res: io::Result<()> = try {
let mut f = File::create_buffered(&path)?;
- for sym in symbols {
+ for (sym, _) in symbols {
writeln!(f, "{sym}")?;
}
};
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 5f0a0cf..06ba5b4 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -692,6 +692,7 @@ fn calling_convention_for_symbol<'tcx>(
pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
tcx: TyCtxt<'tcx>,
symbol: ExportedSymbol<'tcx>,
+ export_kind: SymbolExportKind,
instantiating_crate: CrateNum,
) -> String {
let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
@@ -712,8 +713,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
let prefix = match &target.arch[..] {
"x86" => Some('_'),
"x86_64" => None,
- "arm64ec" => Some('#'),
- // Only x86/64 use symbol decorations.
+ // Only functions are decorated for arm64ec.
+ "arm64ec" if export_kind == SymbolExportKind::Text => Some('#'),
+ // Only x86/64 and arm64ec use symbol decorations.
_ => return undecorated,
};
@@ -753,9 +755,10 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
/// Add it to the symbols list for all kernel functions, so that it is exported in the linked
/// object.
pub(crate) fn extend_exported_symbols<'tcx>(
- symbols: &mut Vec<String>,
+ symbols: &mut Vec<(String, SymbolExportKind)>,
tcx: TyCtxt<'tcx>,
symbol: ExportedSymbol<'tcx>,
+ info: SymbolExportInfo,
instantiating_crate: CrateNum,
) {
let (conv, _) = calling_convention_for_symbol(tcx, symbol);
@@ -767,7 +770,7 @@ pub(crate) fn extend_exported_symbols<'tcx>(
let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
// Add the symbol for the kernel descriptor (with .kd suffix)
- symbols.push(format!("{undecorated}.kd"));
+ symbols.push((format!("{undecorated}.kd"), info.kind));
}
fn maybe_emutls_symbol_name<'tcx>(
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 775ab90..93cbd4c 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -12,9 +12,9 @@
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
use rustc_data_structures::unord::UnordMap;
-use rustc_hir::ItemId;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
+use rustc_hir::{ItemId, Target};
use rustc_metadata::EncodedMetadata;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
@@ -1038,21 +1038,35 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
// by the compiler, but that's ok because all this stuff is unstable anyway.
let target = &tcx.sess.target;
if !are_upstream_rust_objects_already_included(tcx.sess) {
- let missing_weak_lang_items: FxIndexSet<Symbol> = info
+ let add_prefix = match (target.is_like_windows, target.arch.as_ref()) {
+ (true, "x86") => |name: String, _: SymbolExportKind| format!("_{name}"),
+ (true, "arm64ec") => {
+ // Only functions are decorated for arm64ec.
+ |name: String, export_kind: SymbolExportKind| match export_kind {
+ SymbolExportKind::Text => format!("#{name}"),
+ _ => name,
+ }
+ }
+ _ => |name: String, _: SymbolExportKind| name,
+ };
+ let missing_weak_lang_items: FxIndexSet<(Symbol, SymbolExportKind)> = info
.used_crates
.iter()
.flat_map(|&cnum| tcx.missing_lang_items(cnum))
.filter(|l| l.is_weak())
.filter_map(|&l| {
let name = l.link_name()?;
- lang_items::required(tcx, l).then_some(name)
+ let export_kind = match l.target() {
+ Target::Fn => SymbolExportKind::Text,
+ Target::Static => SymbolExportKind::Data,
+ _ => bug!(
+ "Don't know what the export kind is for lang item of kind {:?}",
+ l.target()
+ ),
+ };
+ lang_items::required(tcx, l).then_some((name, export_kind))
})
.collect();
- let prefix = match (target.is_like_windows, target.arch.as_ref()) {
- (true, "x86") => "_",
- (true, "arm64ec") => "#",
- _ => "",
- };
// This loop only adds new items to values of the hash map, so the order in which we
// iterate over the values is not important.
@@ -1065,10 +1079,13 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
.for_each(|(_, linked_symbols)| {
let mut symbols = missing_weak_lang_items
.iter()
- .map(|item| {
+ .map(|(item, export_kind)| {
(
- format!("{prefix}{}", mangle_internal_symbol(tcx, item.as_str())),
- SymbolExportKind::Text,
+ add_prefix(
+ mangle_internal_symbol(tcx, item.as_str()),
+ *export_kind,
+ ),
+ *export_kind,
)
})
.collect::<Vec<_>>();
@@ -1083,12 +1100,12 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
// errors.
linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| {
(
- format!(
- "{prefix}{}",
+ add_prefix(
mangle_internal_symbol(
tcx,
- global_fn_name(method.name).as_str()
- )
+ global_fn_name(method.name).as_str(),
+ ),
+ SymbolExportKind::Text,
),
SymbolExportKind::Text,
)
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index bfec208..4f9757f 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -219,7 +219,7 @@ pub struct CrateInfo {
pub target_cpu: String,
pub target_features: Vec<String>,
pub crate_types: Vec<CrateType>,
- pub exported_symbols: UnordMap<CrateType, Vec<String>>,
+ pub exported_symbols: UnordMap<CrateType, Vec<(String, SymbolExportKind)>>,
pub linked_symbols: FxIndexMap<CrateType, Vec<(String, SymbolExportKind)>>,
pub local_crate_name: Symbol,
pub compiler_builtins: Option<CrateNum>,
diff --git a/compiler/rustc_data_structures/src/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs
similarity index 88%
rename from compiler/rustc_data_structures/src/graph/implementation/mod.rs
rename to compiler/rustc_data_structures/src/graph/linked_graph/mod.rs
index a803659..ecb0095 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs
@@ -1,4 +1,4 @@
-//! A graph module for use in dataflow, region resolution, and elsewhere.
+//! See [`LinkedGraph`].
//!
//! # Interface details
//!
@@ -28,7 +28,23 @@
#[cfg(test)]
mod tests;
-pub struct Graph<N, E> {
+/// A concrete graph implementation that supports:
+/// - Nodes and/or edges labelled with custom data types (`N` and `E` respectively).
+/// - Incremental addition of new nodes/edges (but not removal).
+/// - Flat storage of node/edge data in a pair of vectors.
+/// - Iteration over any node's out-edges or in-edges, via linked lists
+/// threaded through the node/edge data.
+///
+/// # Caution
+/// This is an older graph implementation that is still used by some pieces
+/// of diagnostic/debugging code. New code that needs a graph data structure
+/// should consider using `VecGraph` instead, or implementing its own
+/// special-purpose graph with the specific features needed.
+///
+/// This graph implementation predates the later [graph traits](crate::graph),
+/// and does not implement those traits, so it has its own implementations of a
+/// few basic graph algorithms.
+pub struct LinkedGraph<N, E> {
nodes: Vec<Node<N>>,
edges: Vec<Edge<E>>,
}
@@ -71,13 +87,13 @@ pub fn node_id(self) -> usize {
}
}
-impl<N: Debug, E: Debug> Graph<N, E> {
- pub fn new() -> Graph<N, E> {
- Graph { nodes: Vec::new(), edges: Vec::new() }
+impl<N: Debug, E: Debug> LinkedGraph<N, E> {
+ pub fn new() -> Self {
+ Self { nodes: Vec::new(), edges: Vec::new() }
}
- pub fn with_capacity(nodes: usize, edges: usize) -> Graph<N, E> {
- Graph { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
+ pub fn with_capacity(nodes: usize, edges: usize) -> Self {
+ Self { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
}
// # Simple accessors
@@ -249,7 +265,7 @@ pub fn nodes_in_postorder(
// # Iterators
pub struct AdjacentEdges<'g, N, E> {
- graph: &'g Graph<N, E>,
+ graph: &'g LinkedGraph<N, E>,
direction: Direction,
next: EdgeIndex,
}
@@ -285,7 +301,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
}
pub struct DepthFirstTraversal<'g, N, E> {
- graph: &'g Graph<N, E>,
+ graph: &'g LinkedGraph<N, E>,
stack: Vec<NodeIndex>,
visited: DenseBitSet<usize>,
direction: Direction,
@@ -293,7 +309,7 @@ pub struct DepthFirstTraversal<'g, N, E> {
impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
pub fn with_start_node(
- graph: &'g Graph<N, E>,
+ graph: &'g LinkedGraph<N, E>,
start_node: NodeIndex,
direction: Direction,
) -> Self {
diff --git a/compiler/rustc_data_structures/src/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/linked_graph/tests.rs
similarity index 94%
rename from compiler/rustc_data_structures/src/graph/implementation/tests.rs
rename to compiler/rustc_data_structures/src/graph/linked_graph/tests.rs
index 32a6d9e..357aa81 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/linked_graph/tests.rs
@@ -1,11 +1,11 @@
use tracing::debug;
-use crate::graph::implementation::*;
+use super::{Debug, LinkedGraph, NodeIndex};
-type TestGraph = Graph<&'static str, &'static str>;
+type TestGraph = LinkedGraph<&'static str, &'static str>;
fn create_graph() -> TestGraph {
- let mut graph = Graph::new();
+ let mut graph = LinkedGraph::new();
// Create a simple graph
//
@@ -56,7 +56,7 @@ fn each_edge() {
}
fn test_adjacent_edges<N: PartialEq + Debug, E: PartialEq + Debug>(
- graph: &Graph<N, E>,
+ graph: &LinkedGraph<N, E>,
start_index: NodeIndex,
start_data: N,
expected_incoming: &[(E, N)],
diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs
index 4a1e5db..20416b4 100644
--- a/compiler/rustc_data_structures/src/graph/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/mod.rs
@@ -1,8 +1,8 @@
use rustc_index::Idx;
pub mod dominators;
-pub mod implementation;
pub mod iterate;
+pub mod linked_graph;
mod reference;
pub mod reversed;
pub mod scc;
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 80d49ef..b28c333 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -43,7 +43,7 @@
pub use self::lock::{Lock, LockGuard, Mode};
pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
pub use self::parallel::{
- join, par_for_each_in, par_map, parallel_guard, scope, spawn, try_par_for_each_in,
+ broadcast, join, par_for_each_in, par_map, parallel_guard, scope, spawn, try_par_for_each_in,
};
pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec};
pub use self::worker_local::{Registry, WorkerLocal};
diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs
index 64db39c..ab65c7f3 100644
--- a/compiler/rustc_data_structures/src/sync/parallel.rs
+++ b/compiler/rustc_data_structures/src/sync/parallel.rs
@@ -237,3 +237,13 @@ pub fn par_map<I: DynSend, T: IntoIterator<Item = I>, R: DynSend, C: FromIterato
}
})
}
+
+pub fn broadcast<R: DynSend>(op: impl Fn(usize) -> R + DynSync) -> Vec<R> {
+ if mode::is_dyn_thread_safe() {
+ let op = FromDyn::from(op);
+ let results = rayon_core::broadcast(|context| op.derive(op(context.index())));
+ results.into_iter().map(|r| r.into_inner()).collect()
+ } else {
+ vec![op(0)]
+ }
+}
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index fdf8053..95cfe22 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -463,6 +463,7 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col
// Allow "E0123" or "0123" form.
let upper_cased_code = code.to_ascii_uppercase();
if let Ok(code) = upper_cased_code.strip_prefix('E').unwrap_or(&upper_cased_code).parse::<u32>()
+ && code <= ErrCode::MAX_AS_U32
&& let Ok(description) = registry.try_find_description(ErrCode::from_u32(code))
{
let mut is_in_code_block = false;
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index f341215..a5f89b7 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -316,6 +316,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
// Unstable `#[target_feature]` directives.
(unstable, aarch64_unstable_target_feature, "1.82.0", Some(44839)),
(unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)),
+ (unstable, apx_target_feature, "CURRENT_RUSTC_VERSION", Some(139284)),
(unstable, arm_target_feature, "1.27.0", Some(44839)),
(unstable, avx512_target_feature, "1.27.0", Some(44839)),
(unstable, bpf_target_feature, "1.54.0", Some(44839)),
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 98b4118..f93b9e5 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -309,6 +309,8 @@ pub enum DefPathData {
/// An existential `impl Trait` type node.
/// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name.
OpaqueTy,
+ /// Used for remapped captured lifetimes in an existential `impl Trait` type node.
+ OpaqueLifetime(Symbol),
/// An anonymous associated type from an RPITIT. The symbol refers to the name of the method
/// that defined the type.
AnonAssocTy(Symbol),
@@ -445,7 +447,8 @@ impl DefPathData {
pub fn get_opt_name(&self) -> Option<Symbol> {
use self::DefPathData::*;
match *self {
- TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
+ TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
+ | OpaqueLifetime(name) => Some(name),
Impl
| ForeignMod
@@ -465,9 +468,8 @@ pub fn get_opt_name(&self) -> Option<Symbol> {
fn hashed_symbol(&self) -> Option<Symbol> {
use self::DefPathData::*;
match *self {
- TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name) => {
- Some(name)
- }
+ TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name)
+ | OpaqueLifetime(name) => Some(name),
Impl
| ForeignMod
@@ -486,9 +488,8 @@ fn hashed_symbol(&self) -> Option<Symbol> {
pub fn name(&self) -> DefPathDataName {
use self::DefPathData::*;
match *self {
- TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => {
- DefPathDataName::Named(name)
- }
+ TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
+ | OpaqueLifetime(name) => DefPathDataName::Named(name),
// Note that this does not show up in user print-outs.
CrateRoot => DefPathDataName::Anon { namespace: kw::Crate },
Impl => DefPathDataName::Anon { namespace: kw::Impl },
diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs
index 18f8c52..8684ade 100644
--- a/compiler/rustc_hir/src/hir/tests.rs
+++ b/compiler/rustc_hir/src/hir/tests.rs
@@ -50,21 +50,14 @@ fn trait_object_roundtrips() {
}
fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) {
- let unambig = TyKind::TraitObject::<'_, ()>(
- &[],
- TaggedRef::new(
- &const {
- Lifetime {
- hir_id: HirId::INVALID,
- ident: Ident::new(sym::name, DUMMY_SP),
- kind: LifetimeKind::Static,
- source: LifetimeSource::Other,
- syntax: LifetimeSyntax::Hidden,
- }
- },
- syntax,
- ),
- );
+ let lt = Lifetime {
+ hir_id: HirId::INVALID,
+ ident: Ident::new(sym::name, DUMMY_SP),
+ kind: LifetimeKind::Static,
+ source: LifetimeSource::Other,
+ syntax: LifetimeSyntax::Hidden,
+ };
+ let unambig = TyKind::TraitObject::<'_, ()>(&[], TaggedRef::new(<, syntax));
let unambig_to_ambig = unsafe { std::mem::transmute::<_, TyKind<'_, AmbigArg>>(unambig) };
match unambig_to_ambig {
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index bbf36fe..fb67f2f 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -5,7 +5,7 @@
use hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
-use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
+use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit};
@@ -14,10 +14,10 @@
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{
self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
- TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast,
+ TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
};
use rustc_middle::{bug, span_bug};
-use rustc_span::Span;
+use rustc_span::{DUMMY_SP, Span};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -1137,65 +1137,319 @@ fn check_region_bounds_on_impl_item<'tcx>(
// but found 0" it's confusing, because it looks like there
// are zero. Since I don't quite know how to phrase things at
// the moment, give a kind of vague error message.
- if trait_params != impl_params {
- let span = tcx
- .hir_get_generics(impl_m.def_id.expect_local())
- .expect("expected impl item to have generics or else we can't compare them")
- .span;
+ if trait_params == impl_params {
+ return Ok(());
+ }
- let mut generics_span = None;
- let mut bounds_span = vec![];
- let mut where_span = None;
- if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
- && let Some(trait_generics) = trait_node.generics()
- {
- generics_span = Some(trait_generics.span);
- // FIXME: we could potentially look at the impl's bounds to not point at bounds that
- // *are* present in the impl.
- for p in trait_generics.predicates {
- if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
- for b in pred.bounds {
+ if !delay && let Some(guar) = check_region_late_boundedness(tcx, impl_m, trait_m) {
+ return Err(guar);
+ }
+
+ let span = tcx
+ .hir_get_generics(impl_m.def_id.expect_local())
+ .expect("expected impl item to have generics or else we can't compare them")
+ .span;
+
+ let mut generics_span = None;
+ let mut bounds_span = vec![];
+ let mut where_span = None;
+
+ if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
+ && let Some(trait_generics) = trait_node.generics()
+ {
+ generics_span = Some(trait_generics.span);
+ // FIXME: we could potentially look at the impl's bounds to not point at bounds that
+ // *are* present in the impl.
+ for p in trait_generics.predicates {
+ match p.kind {
+ hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
+ bounds,
+ ..
+ })
+ | hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
+ bounds,
+ ..
+ }) => {
+ for b in *bounds {
if let hir::GenericBound::Outlives(lt) = b {
bounds_span.push(lt.ident.span);
}
}
}
+ _ => {}
}
- if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
- && let Some(impl_generics) = impl_node.generics()
- {
- let mut impl_bounds = 0;
- for p in impl_generics.predicates {
- if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
- for b in pred.bounds {
+ }
+ if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
+ && let Some(impl_generics) = impl_node.generics()
+ {
+ let mut impl_bounds = 0;
+ for p in impl_generics.predicates {
+ match p.kind {
+ hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
+ bounds,
+ ..
+ })
+ | hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
+ bounds,
+ ..
+ }) => {
+ for b in *bounds {
if let hir::GenericBound::Outlives(_) = b {
impl_bounds += 1;
}
}
}
- }
- if impl_bounds == bounds_span.len() {
- bounds_span = vec![];
- } else if impl_generics.has_where_clause_predicates {
- where_span = Some(impl_generics.where_clause_span);
+ _ => {}
}
}
+ if impl_bounds == bounds_span.len() {
+ bounds_span = vec![];
+ } else if impl_generics.has_where_clause_predicates {
+ where_span = Some(impl_generics.where_clause_span);
+ }
}
- let reported = tcx
- .dcx()
- .create_err(LifetimesOrBoundsMismatchOnTrait {
- span,
- item_kind: impl_m.descr(),
- ident: impl_m.ident(tcx),
- generics_span,
- bounds_span,
- where_span,
- })
- .emit_unless(delay);
- return Err(reported);
}
- Ok(())
+ let reported = tcx
+ .dcx()
+ .create_err(LifetimesOrBoundsMismatchOnTrait {
+ span,
+ item_kind: impl_m.descr(),
+ ident: impl_m.ident(tcx),
+ generics_span,
+ bounds_span,
+ where_span,
+ })
+ .emit_unless(delay);
+
+ Err(reported)
+}
+
+#[allow(unused)]
+enum LateEarlyMismatch<'tcx> {
+ EarlyInImpl(DefId, DefId, ty::Region<'tcx>),
+ LateInImpl(DefId, DefId, ty::Region<'tcx>),
+}
+
+fn check_region_late_boundedness<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ impl_m: ty::AssocItem,
+ trait_m: ty::AssocItem,
+) -> Option<ErrorGuaranteed> {
+ if !impl_m.is_fn() {
+ return None;
+ }
+
+ let (infcx, param_env) = tcx
+ .infer_ctxt()
+ .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, impl_m.def_id));
+
+ let impl_m_args = infcx.fresh_args_for_item(DUMMY_SP, impl_m.def_id);
+ let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args);
+ let impl_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, impl_m_sig);
+
+ let trait_m_args = infcx.fresh_args_for_item(DUMMY_SP, trait_m.def_id);
+ let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args);
+ let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig);
+
+ let ocx = ObligationCtxt::new(&infcx);
+
+ // Equate the signatures so that we can infer whether a late-bound param was present where
+ // an early-bound param was expected, since we replace the late-bound lifetimes with
+ // `ReLateParam`, and early-bound lifetimes with infer vars, so the early-bound args will
+ // resolve to `ReLateParam` if there is a mismatch.
+ let Ok(()) = ocx.eq(
+ &ObligationCause::dummy(),
+ param_env,
+ ty::Binder::dummy(trait_m_sig),
+ ty::Binder::dummy(impl_m_sig),
+ ) else {
+ return None;
+ };
+
+ let errors = ocx.select_where_possible();
+ if !errors.is_empty() {
+ return None;
+ }
+
+ let mut mismatched = vec![];
+
+ let impl_generics = tcx.generics_of(impl_m.def_id);
+ for (id_arg, arg) in
+ std::iter::zip(ty::GenericArgs::identity_for_item(tcx, impl_m.def_id), impl_m_args)
+ {
+ if let ty::GenericArgKind::Lifetime(r) = arg.unpack()
+ && let ty::ReVar(vid) = r.kind()
+ && let r = infcx
+ .inner
+ .borrow_mut()
+ .unwrap_region_constraints()
+ .opportunistic_resolve_var(tcx, vid)
+ && let ty::ReLateParam(ty::LateParamRegion {
+ kind: ty::LateParamRegionKind::Named(trait_param_def_id, _),
+ ..
+ }) = r.kind()
+ && let ty::ReEarlyParam(ebr) = id_arg.expect_region().kind()
+ {
+ mismatched.push(LateEarlyMismatch::EarlyInImpl(
+ impl_generics.region_param(ebr, tcx).def_id,
+ trait_param_def_id,
+ id_arg.expect_region(),
+ ));
+ }
+ }
+
+ let trait_generics = tcx.generics_of(trait_m.def_id);
+ for (id_arg, arg) in
+ std::iter::zip(ty::GenericArgs::identity_for_item(tcx, trait_m.def_id), trait_m_args)
+ {
+ if let ty::GenericArgKind::Lifetime(r) = arg.unpack()
+ && let ty::ReVar(vid) = r.kind()
+ && let r = infcx
+ .inner
+ .borrow_mut()
+ .unwrap_region_constraints()
+ .opportunistic_resolve_var(tcx, vid)
+ && let ty::ReLateParam(ty::LateParamRegion {
+ kind: ty::LateParamRegionKind::Named(impl_param_def_id, _),
+ ..
+ }) = r.kind()
+ && let ty::ReEarlyParam(ebr) = id_arg.expect_region().kind()
+ {
+ mismatched.push(LateEarlyMismatch::LateInImpl(
+ impl_param_def_id,
+ trait_generics.region_param(ebr, tcx).def_id,
+ id_arg.expect_region(),
+ ));
+ }
+ }
+
+ if mismatched.is_empty() {
+ return None;
+ }
+
+ let spans: Vec<_> = mismatched
+ .iter()
+ .map(|param| {
+ let (LateEarlyMismatch::EarlyInImpl(impl_param_def_id, ..)
+ | LateEarlyMismatch::LateInImpl(impl_param_def_id, ..)) = param;
+ tcx.def_span(impl_param_def_id)
+ })
+ .collect();
+
+ let mut diag = tcx
+ .dcx()
+ .struct_span_err(spans, "lifetime parameters do not match the trait definition")
+ .with_note("lifetime parameters differ in whether they are early- or late-bound")
+ .with_code(E0195);
+ for mismatch in mismatched {
+ match mismatch {
+ LateEarlyMismatch::EarlyInImpl(
+ impl_param_def_id,
+ trait_param_def_id,
+ early_bound_region,
+ ) => {
+ let mut multispan = MultiSpan::from_spans(vec![
+ tcx.def_span(impl_param_def_id),
+ tcx.def_span(trait_param_def_id),
+ ]);
+ multispan
+ .push_span_label(tcx.def_span(tcx.parent(impl_m.def_id)), "in this impl...");
+ multispan
+ .push_span_label(tcx.def_span(tcx.parent(trait_m.def_id)), "in this trait...");
+ multispan.push_span_label(
+ tcx.def_span(impl_param_def_id),
+ format!("`{}` is early-bound", tcx.item_name(impl_param_def_id)),
+ );
+ multispan.push_span_label(
+ tcx.def_span(trait_param_def_id),
+ format!("`{}` is late-bound", tcx.item_name(trait_param_def_id)),
+ );
+ if let Some(span) =
+ find_region_in_predicates(tcx, impl_m.def_id, early_bound_region)
+ {
+ multispan.push_span_label(
+ span,
+ format!(
+ "this lifetime bound makes `{}` early-bound",
+ tcx.item_name(impl_param_def_id)
+ ),
+ );
+ }
+ diag.span_note(
+ multispan,
+ format!(
+ "`{}` differs between the trait and impl",
+ tcx.item_name(impl_param_def_id)
+ ),
+ );
+ }
+ LateEarlyMismatch::LateInImpl(
+ impl_param_def_id,
+ trait_param_def_id,
+ early_bound_region,
+ ) => {
+ let mut multispan = MultiSpan::from_spans(vec![
+ tcx.def_span(impl_param_def_id),
+ tcx.def_span(trait_param_def_id),
+ ]);
+ multispan
+ .push_span_label(tcx.def_span(tcx.parent(impl_m.def_id)), "in this impl...");
+ multispan
+ .push_span_label(tcx.def_span(tcx.parent(trait_m.def_id)), "in this trait...");
+ multispan.push_span_label(
+ tcx.def_span(impl_param_def_id),
+ format!("`{}` is late-bound", tcx.item_name(impl_param_def_id)),
+ );
+ multispan.push_span_label(
+ tcx.def_span(trait_param_def_id),
+ format!("`{}` is early-bound", tcx.item_name(trait_param_def_id)),
+ );
+ if let Some(span) =
+ find_region_in_predicates(tcx, trait_m.def_id, early_bound_region)
+ {
+ multispan.push_span_label(
+ span,
+ format!(
+ "this lifetime bound makes `{}` early-bound",
+ tcx.item_name(trait_param_def_id)
+ ),
+ );
+ }
+ diag.span_note(
+ multispan,
+ format!(
+ "`{}` differs between the trait and impl",
+ tcx.item_name(impl_param_def_id)
+ ),
+ );
+ }
+ }
+ }
+
+ Some(diag.emit())
+}
+
+fn find_region_in_predicates<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ def_id: DefId,
+ early_bound_region: ty::Region<'tcx>,
+) -> Option<Span> {
+ for (pred, span) in tcx.explicit_predicates_of(def_id).instantiate_identity(tcx) {
+ if pred.visit_with(&mut FindRegion(early_bound_region)).is_break() {
+ return Some(span);
+ }
+ }
+
+ struct FindRegion<'tcx>(ty::Region<'tcx>);
+ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindRegion<'tcx> {
+ type Result = ControlFlow<()>;
+ fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
+ if r == self.0 { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
+ }
+ }
+
+ None
}
#[instrument(level = "debug", skip(infcx))]
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index a891607..709446d 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -14,7 +14,7 @@
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::definitions::DisambiguatorState;
+use rustc_hir::definitions::{DefPathData, DisambiguatorState};
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
use rustc_hir::{
self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node,
@@ -1470,14 +1470,14 @@ fn remap_opaque_captures(
let mut captures = captures.borrow_mut();
let remapped = *captures.entry(lifetime).or_insert_with(|| {
// `opaque_def_id` is unique to the `BoundVarContext` pass which is executed once
- // per `resolve_bound_vars` query. This is the only location that creates nested
- // lifetime inside a opaque type. `<opaque_def_id>::LifetimeNs(..)` is thus unique
+ // per `resolve_bound_vars` query. This is the only location that creates
+ // `OpaqueLifetime` paths. `<opaque_def_id>::OpaqueLifetime(..)` is thus unique
// to this query and duplicates within the query are handled by `self.disambiguator`.
let feed = self.tcx.create_def(
opaque_def_id,
- Some(ident.name),
- DefKind::LifetimeParam,
None,
+ DefKind::LifetimeParam,
+ Some(DefPathData::OpaqueLifetime(ident.name)),
&mut self.disambiguator,
);
feed.def_span(ident.span);
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index bf91eb1..4419d5d 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -9,8 +9,8 @@
use rustc_hir::{AmbigArg, HirId};
use rustc_middle::bug;
use rustc_middle::ty::{
- self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
- TypeVisitor, Upcast,
+ self as ty, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
+ TypeVisitableExt, TypeVisitor, Upcast,
};
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
use rustc_trait_selection::traits;
@@ -996,7 +996,7 @@ struct GenericParamAndBoundVarCollector<'a, 'tcx> {
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 'tcx> {
type Result = ControlFlow<ErrorGuaranteed>;
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
+ fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
&mut self,
binder: &ty::Binder<'tcx, T>,
) -> Self::Result {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 88f7458..f6e5149 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -172,7 +172,14 @@ pub(super) fn lower_trait_object_ty(
let principal_trait = regular_traits.into_iter().next();
- let mut needed_associated_types = vec![];
+ // A stable ordering of associated types from the principal trait and all its
+ // supertraits. We use this to ensure that different substitutions of a trait
+ // don't result in `dyn Trait` types with different projections lists, which
+ // can be unsound: <https://github.com/rust-lang/rust/pull/136458>.
+ // We achieve a stable ordering by walking over the unsubstituted principal
+ // trait ref.
+ let mut ordered_associated_types = vec![];
+
if let Some((principal_trait, ref spans)) = principal_trait {
let principal_trait = principal_trait.map_bound(|trait_pred| {
assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
@@ -197,16 +204,13 @@ pub(super) fn lower_trait_object_ty(
// FIXME(negative_bounds): Handle this correctly...
let trait_ref =
tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
- needed_associated_types.extend(
+ ordered_associated_types.extend(
tcx.associated_items(pred.trait_ref.def_id)
.in_definition_order()
// We only care about associated types.
.filter(|item| item.is_type())
// No RPITITs -- they're not dyn-compatible for now.
.filter(|item| !item.is_impl_trait_in_trait())
- // If the associated type has a `where Self: Sized` bound,
- // we do not need to constrain the associated type.
- .filter(|item| !tcx.generics_require_sized_self(item.def_id))
.map(|item| (item.def_id, trait_ref)),
);
}
@@ -278,14 +282,26 @@ pub(super) fn lower_trait_object_ty(
}
}
+ // We compute the list of projection bounds taking the ordered associated types,
+ // and check if there was an entry in the collected `projection_bounds`. Those
+ // are computed by first taking the user-written associated types, then elaborating
+ // the principal trait ref, and only using those if there was no user-written.
+ // See note below about how we handle missing associated types with `Self: Sized`,
+ // which are not required to be provided, but are still used if they are provided.
let mut missing_assoc_types = FxIndexSet::default();
- let projection_bounds: Vec<_> = needed_associated_types
+ let projection_bounds: Vec<_> = ordered_associated_types
.into_iter()
.filter_map(|key| {
if let Some(assoc) = projection_bounds.get(&key) {
Some(*assoc)
} else {
- missing_assoc_types.insert(key);
+ // If the associated type has a `where Self: Sized` bound, then
+ // we do not need to provide the associated type. This results in
+ // a `dyn Trait` type that has a different number of projection
+ // bounds, which may lead to type mismatches.
+ if !tcx.generics_require_sized_self(key.0) {
+ missing_assoc_types.insert(key);
+ }
None
}
})
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 2e7831f..61dd8c5 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -603,7 +603,8 @@ pub(crate) fn return_position_impl_trait_from_match_expectation(
// FIXME(-Znext-solver): Remove this branch once `replace_opaque_types_with_infer` is gone.
ty::Infer(ty::TyVar(_)) => self
.inner
- .borrow()
+ .borrow_mut()
+ .opaque_types()
.iter_opaque_types()
.find(|(_, v)| v.ty == expected_ty)
.map(|(k, _)| (k.def_id, k.args))?,
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index caf36ba..5bfc3e8 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -1051,20 +1051,19 @@ fn check_ptr_addr_cast(
fn check_ref_cast(
&self,
fcx: &FnCtxt<'a, 'tcx>,
- m_expr: ty::TypeAndMut<'tcx>,
- m_cast: ty::TypeAndMut<'tcx>,
+ mut m_expr: ty::TypeAndMut<'tcx>,
+ mut m_cast: ty::TypeAndMut<'tcx>,
) -> Result<CastKind, CastError<'tcx>> {
// array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
+ m_expr.ty = fcx.try_structurally_resolve_type(self.expr_span, m_expr.ty);
+ m_cast.ty = fcx.try_structurally_resolve_type(self.cast_span, m_cast.ty);
+
if m_expr.mutbl >= m_cast.mutbl
&& let ty::Array(ety, _) = m_expr.ty.kind()
&& fcx.can_eq(fcx.param_env, *ety, m_cast.ty)
{
- // Due to the limitations of LLVM global constants,
- // region pointers end up pointing at copies of
- // vector elements instead of the original values.
- // To allow raw pointers to work correctly, we
- // need to special-case obtaining a raw pointer
- // from a region pointer to a vector.
+ // Due to historical reasons we allow directly casting references of
+ // arrays into raw pointers of their element type.
// Coerce to a raw pointer so that we generate RawPtr in MIR.
let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl);
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 78233a3..60187ab 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -32,6 +32,7 @@
mod intrinsicck;
mod method;
mod op;
+mod opaque_types;
mod pat;
mod place_op;
mod rvalue_scopes;
@@ -245,9 +246,7 @@ fn typeck_with_inspect<'tcx>(
let typeck_results = fcx.resolve_type_vars_in_body(body);
- // We clone the defined opaque types during writeback in the new solver
- // because we have to use them during normalization.
- let _ = fcx.infcx.take_opaque_types();
+ fcx.detect_opaque_types_added_during_writeback();
// Consistency check our TypeckResults instance can hold all ItemLocalIds
// it will need to hold.
diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs
new file mode 100644
index 0000000..e0224f8
--- /dev/null
+++ b/compiler/rustc_hir_typeck/src/opaque_types.rs
@@ -0,0 +1,26 @@
+use super::FnCtxt;
+impl<'tcx> FnCtxt<'_, 'tcx> {
+ /// We may in theory add further uses of an opaque after cloning the opaque
+ /// types storage during writeback when computing the defining uses.
+ ///
+ /// Silently ignoring them is dangerous and could result in ICE or even in
+ /// unsoundness, so we make sure we catch such cases here. There's currently
+ /// no known code where this actually happens, even with the new solver which
+ /// does normalize types in writeback after cloning the opaque type storage.
+ ///
+ /// FIXME(@lcnr): I believe this should be possible in theory and would like
+ /// an actual test here. After playing around with this for an hour, I wasn't
+ /// able to do anything which didn't already try to normalize the opaque before
+ /// then, either allowing compilation to succeed or causing an ambiguity error.
+ pub(super) fn detect_opaque_types_added_during_writeback(&self) {
+ let num_entries = self.checked_opaque_types_storage_entries.take().unwrap();
+ for (key, hidden_type) in
+ self.inner.borrow_mut().opaque_types().opaque_types_added_since(num_entries)
+ {
+ let opaque_type_string = self.tcx.def_path_str(key.def_id);
+ let msg = format!("unexpected cyclic definition of `{opaque_type_string}`");
+ self.dcx().span_delayed_bug(hidden_type.span, msg);
+ }
+ let _ = self.take_opaque_types();
+ }
+}
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index f950215..17d4818 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -650,14 +650,13 @@ fn calc_adjust_mode(
match &pat.kind {
// Type checking these product-like types successfully always require
// that the expected type be of those types and not reference types.
- PatKind::Tuple(..)
- | PatKind::Range(..)
- | PatKind::Slice(..) => AdjustMode::peel_all(),
+ PatKind::Tuple(..) | PatKind::Range(..) | PatKind::Slice(..) => AdjustMode::peel_all(),
// When checking an explicit deref pattern, only peel reference types.
// FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box
// patterns may want `PeelKind::Implicit`, stopping on encountering a box.
- | PatKind::Box(_)
- | PatKind::Deref(_) => AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat },
+ PatKind::Box(_) | PatKind::Deref(_) => {
+ AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat }
+ }
// A never pattern behaves somewhat like a literal or unit variant.
PatKind::Never => AdjustMode::peel_all(),
// For patterns with paths, how we peel the scrutinee depends on the path's resolution.
@@ -679,7 +678,11 @@ fn calc_adjust_mode(
&& self.tcx.features().deref_patterns()
&& !matches!(lt.kind, PatExprKind::Lit { .. })
{
- span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind);
+ span_bug!(
+ lt.span,
+ "FIXME(deref_patterns): adjust mode unimplemented for {:?}",
+ lt.kind
+ );
}
// Call `resolve_vars_if_possible` here for inline const blocks.
let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt));
@@ -687,17 +690,21 @@ fn calc_adjust_mode(
if self.tcx.features().deref_patterns() {
let mut peeled_ty = lit_ty;
let mut pat_ref_layers = 0;
- while let ty::Ref(_, inner_ty, mutbl) = *peeled_ty.kind() {
+ while let ty::Ref(_, inner_ty, mutbl) =
+ *self.try_structurally_resolve_type(pat.span, peeled_ty).kind()
+ {
// We rely on references at the head of constants being immutable.
debug_assert!(mutbl.is_not());
pat_ref_layers += 1;
peeled_ty = inner_ty;
}
- AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: None, pat_ref_layers } }
+ AdjustMode::Peel {
+ kind: PeelKind::Implicit { until_adt: None, pat_ref_layers },
+ }
} else {
if lit_ty.is_ref() { AdjustMode::Pass } else { AdjustMode::peel_all() }
}
- },
+ }
// Ref patterns are complicated, we handle them in `check_pat_ref`.
PatKind::Ref(..)
@@ -928,6 +935,7 @@ fn check_pat_range(
// be peeled to `str` while ty here is still `&str`, if we don't
// err early here, a rather confusing unification error will be
// emitted instead).
+ let ty = self.try_structurally_resolve_type(expr.span, ty);
let fail =
!(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error());
Some((fail, ty, expr.span))
diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
index 56859ee..26be5fc 100644
--- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
+++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
@@ -1,10 +1,10 @@
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
use std::ops::Deref;
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{self as hir, HirId, HirIdMap, LangItem};
-use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
+use rustc_infer::infer::{InferCtxt, InferOk, OpaqueTypeStorageEntries, TyCtxtInferExt};
use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode};
use rustc_span::Span;
@@ -37,6 +37,11 @@ pub(crate) struct TypeckRootCtxt<'tcx> {
pub(super) fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx, FulfillmentError<'tcx>>>>,
+ // Used to detect opaque types uses added after we've already checked them.
+ //
+ // See [FnCtxt::detect_opaque_types_added_during_writeback] for more details.
+ pub(super) checked_opaque_types_storage_entries: Cell<Option<OpaqueTypeStorageEntries>>,
+
/// Some additional `Sized` obligations badly affect type inference.
/// These obligations are added in a later stage of typeck.
/// Removing these may also cause additional complications, see #101066.
@@ -85,12 +90,14 @@ pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
let infcx =
tcx.infer_ctxt().ignoring_regions().build(TypingMode::typeck_for_body(tcx, def_id));
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
+ let fulfillment_cx = RefCell::new(<dyn TraitEngine<'_, _>>::new(&infcx));
TypeckRootCtxt {
- typeck_results,
- fulfillment_cx: RefCell::new(<dyn TraitEngine<'_, _>>::new(&infcx)),
infcx,
+ typeck_results,
locals: RefCell::new(Default::default()),
+ fulfillment_cx,
+ checked_opaque_types_storage_entries: Cell::new(None),
deferred_sized_obligations: RefCell::new(Vec::new()),
deferred_call_resolutions: RefCell::new(Default::default()),
deferred_cast_checks: RefCell::new(Vec::new()),
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 8e7ce83..9be041f 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -535,13 +535,10 @@ fn visit_opaque_types(&mut self) {
let tcx = self.tcx();
// We clone the opaques instead of stealing them here as they are still used for
// normalization in the next generation trait solver.
- //
- // FIXME(-Znext-solver): Opaque types defined after this would simply get dropped
- // at the end of typeck. While this seems unlikely to happen in practice this
- // should still get fixed. Either by preventing writeback from defining new opaque
- // types or by using this function at the end of writeback and running it as a
- // fixpoint.
let opaque_types = self.fcx.infcx.clone_opaque_types();
+ let num_entries = self.fcx.inner.borrow_mut().opaque_types().num_entries();
+ let prev = self.fcx.checked_opaque_types_storage_entries.replace(Some(num_entries));
+ debug_assert_eq!(prev, None);
for (opaque_type_key, hidden_type) in opaque_types {
let hidden_type = self.resolve(hidden_type, &hidden_type.span);
let opaque_type_key = self.resolve(opaque_type_key, &hidden_type.span);
diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs
index 1b2056f..0e04a2a 100644
--- a/compiler/rustc_incremental/src/assert_dep_graph.rs
+++ b/compiler/rustc_incremental/src/assert_dep_graph.rs
@@ -38,7 +38,7 @@
use std::io::Write;
use rustc_data_structures::fx::FxIndexSet;
-use rustc_data_structures::graph::implementation::{Direction, INCOMING, NodeIndex, OUTGOING};
+use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, NodeIndex, OUTGOING};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::dep_graph::{
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 94ce6d9..58fea32 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -44,10 +44,6 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) {
sess.time("assert_dep_graph", || assert_dep_graph(tcx));
sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx));
- if sess.opts.unstable_opts.incremental_info {
- tcx.dep_graph.print_incremental_info()
- }
-
join(
move || {
sess.time("incr_comp_persist_dep_graph", || {
@@ -172,12 +168,5 @@ pub(crate) fn build_dep_graph(
// First encode the commandline arguments hash
sess.opts.dep_tracking_hash(false).encode(&mut encoder);
- Some(DepGraph::new(
- sess,
- prev_graph,
- prev_work_products,
- encoder,
- sess.opts.unstable_opts.query_dep_graph,
- sess.opts.unstable_opts.incremental_info,
- ))
+ Some(DepGraph::new(sess, prev_graph, prev_work_products, encoder))
}
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 5220071..1ae864c 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -132,7 +132,13 @@ fn make_query_response<T>(
let certainty = if errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous };
- let opaque_types = self.take_opaque_types_for_query_response();
+ let opaque_types = self
+ .inner
+ .borrow_mut()
+ .opaque_type_storage
+ .take_opaque_types()
+ .map(|(k, v)| (k, v.ty))
+ .collect();
Ok(QueryResponse {
var_values: inference_vars,
@@ -143,24 +149,6 @@ fn make_query_response<T>(
})
}
- /// Used by the new solver as that one takes the opaque types at the end of a probe
- /// to deal with multiple candidates without having to recompute them.
- pub fn clone_opaque_types_for_query_response(
- &self,
- ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
- self.inner
- .borrow()
- .opaque_type_storage
- .opaque_types
- .iter()
- .map(|(k, v)| (*k, v.ty))
- .collect()
- }
-
- fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
- self.take_opaque_types().into_iter().map(|(k, v)| (k, v.ty)).collect()
- }
-
/// Given the (canonicalized) result to a canonical query,
/// instantiates the result so it can be used, plugging in the
/// values from the canonical query. (Note that the result may
diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs
index 22d7ce7..359b9da 100644
--- a/compiler/rustc_infer/src/infer/context.rs
+++ b/compiler/rustc_infer/src/infer/context.rs
@@ -6,7 +6,10 @@
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
-use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin};
+use super::{
+ BoundRegionConversionTime, InferCtxt, OpaqueTypeStorageEntries, RegionVariableOrigin,
+ SubregionOrigin,
+};
impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
type Interner = TyCtxt<'tcx>;
@@ -213,4 +216,58 @@ fn equate_regions(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>, span: Span) {
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span));
}
+
+ type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;
+ fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries {
+ self.inner.borrow_mut().opaque_types().num_entries()
+ }
+ fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
+ self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect()
+ }
+ fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
+ self.inner
+ .borrow_mut()
+ .opaque_types()
+ .iter_duplicate_entries()
+ .map(|(k, h)| (k, h.ty))
+ .collect()
+ }
+ fn clone_opaque_types_added_since(
+ &self,
+ prev_entries: OpaqueTypeStorageEntries,
+ ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
+ self.inner
+ .borrow_mut()
+ .opaque_types()
+ .opaque_types_added_since(prev_entries)
+ .map(|(k, h)| (k, h.ty))
+ .collect()
+ }
+
+ fn register_hidden_type_in_storage(
+ &self,
+ opaque_type_key: ty::OpaqueTypeKey<'tcx>,
+ hidden_ty: Ty<'tcx>,
+ span: Span,
+ ) -> Option<Ty<'tcx>> {
+ self.register_hidden_type_in_storage(
+ opaque_type_key,
+ ty::OpaqueHiddenType { span, ty: hidden_ty },
+ )
+ }
+ fn add_duplicate_opaque_type(
+ &self,
+ opaque_type_key: ty::OpaqueTypeKey<'tcx>,
+ hidden_ty: Ty<'tcx>,
+ span: Span,
+ ) {
+ self.inner
+ .borrow_mut()
+ .opaque_types()
+ .add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty })
+ }
+
+ fn reset_opaque_types(&self) {
+ let _ = self.take_opaque_types();
+ }
}
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index e352213..2185886 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -3,8 +3,8 @@
use std::fmt;
use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::graph::implementation::{
- Direction, Graph, INCOMING, NodeIndex, OUTGOING,
+use rustc_data_structures::graph::linked_graph::{
+ Direction, INCOMING, LinkedGraph, NodeIndex, OUTGOING,
};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::unord::UnordSet;
@@ -118,7 +118,7 @@ struct RegionAndOrigin<'tcx> {
origin: SubregionOrigin<'tcx>,
}
-type RegionGraph<'tcx> = Graph<(), Constraint<'tcx>>;
+type RegionGraph<'tcx> = LinkedGraph<(), Constraint<'tcx>>;
struct LexicalResolver<'cx, 'tcx> {
region_rels: &'cx RegionRelations<'cx, 'tcx>,
@@ -668,7 +668,7 @@ fn collect_var_errors(
fn construct_graph(&self) -> RegionGraph<'tcx> {
let num_vars = self.num_vars();
- let mut graph = Graph::new();
+ let mut graph = LinkedGraph::new();
for _ in 0..num_vars {
graph.add_node(());
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index d25542d..b408d76 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -9,7 +9,7 @@
pub use freshen::TypeFreshener;
use lexical_region_resolve::LexicalRegionResolutions;
pub use lexical_region_resolve::RegionResolutionError;
-use opaque_types::OpaqueTypeStorage;
+pub use opaque_types::{OpaqueTypeStorage, OpaqueTypeStorageEntries, OpaqueTypeTable};
use region_constraints::{
GenericKind, RegionConstraintCollector, RegionConstraintStorage, VarInfos, VerifyBound,
};
@@ -31,9 +31,9 @@
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{
self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs,
- GenericArgsRef, GenericParamDefKind, InferConst, IntVid, PseudoCanonicalInput, Term, TermKind,
- Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
- TypeVisitableExt, TypingEnv, TypingMode, fold_regions,
+ GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueHiddenType, OpaqueTypeKey,
+ PseudoCanonicalInput, Term, TermKind, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder,
+ TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions,
};
use rustc_span::{Span, Symbol};
use snapshot::undo_log::InferCtxtUndoLogs;
@@ -198,7 +198,7 @@ fn type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'tcx> {
}
#[inline]
- fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> {
+ pub fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> {
self.opaque_type_storage.with_log(&mut self.undo_log)
}
@@ -224,15 +224,6 @@ pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tc
.expect("region constraints already solved")
.with_log(&mut self.undo_log)
}
-
- // Iterates through the opaque type definitions without taking them; this holds the
- // `InferCtxtInner` lock, so make sure to not do anything with `InferCtxt` side-effects
- // while looping through this.
- pub fn iter_opaque_types(
- &self,
- ) -> impl Iterator<Item = (ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>)> {
- self.opaque_type_storage.opaque_types.iter().map(|(&k, &v)| (k, v))
- }
}
pub struct InferCtxt<'tcx> {
@@ -954,13 +945,13 @@ pub fn get_region_var_infos(&self) -> VarInfos {
}
#[instrument(level = "debug", skip(self), ret)]
- pub fn take_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> {
- std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types)
+ pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+ self.inner.borrow_mut().opaque_type_storage.take_opaque_types().collect()
}
#[instrument(level = "debug", skip(self), ret)]
- pub fn clone_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> {
- self.inner.borrow().opaque_type_storage.opaque_types.clone()
+ pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+ self.inner.borrow_mut().opaque_type_storage.iter_opaque_types().collect()
}
#[inline(always)]
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index ce5d2e6..220d5e9 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -1,5 +1,4 @@
use hir::def_id::{DefId, LocalDefId};
-use rustc_data_structures::fx::FxIndexMap;
use rustc_hir as hir;
use rustc_middle::bug;
use rustc_middle::traits::ObligationCause;
@@ -19,8 +18,7 @@
mod table;
-pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>;
-pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable};
+pub use table::{OpaqueTypeStorage, OpaqueTypeStorageEntries, OpaqueTypeTable};
impl<'tcx> InferCtxt<'tcx> {
/// This is a backwards compatibility hack to prevent breaking changes from
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index ba6cc0d..4675284 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -1,18 +1,27 @@
+use std::ops::Deref;
+
+use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::undo_log::UndoLogs;
use rustc_middle::bug;
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
use tracing::instrument;
-use super::OpaqueTypeMap;
use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
#[derive(Default, Debug, Clone)]
-pub(crate) struct OpaqueTypeStorage<'tcx> {
- /// Opaque types found in explicit return types and their
- /// associated fresh inference variable. Writeback resolves these
- /// variables to get the concrete type, which can be used to
- /// 'de-opaque' OpaqueHiddenType, after typeck is done with all functions.
- pub opaque_types: OpaqueTypeMap<'tcx>,
+pub struct OpaqueTypeStorage<'tcx> {
+ opaque_types: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
+ duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>,
+}
+
+/// The number of entries in the opaque type storage at a given point.
+///
+/// Used to check that we haven't added any new opaque types after checking
+/// the opaque types currently in the storage.
+#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
+pub struct OpaqueTypeStorageEntries {
+ opaque_types: usize,
+ duplicate_entries: usize,
}
impl<'tcx> OpaqueTypeStorage<'tcx> {
@@ -33,6 +42,70 @@ pub(crate) fn remove(
}
}
+ pub(crate) fn pop_duplicate_entry(&mut self) {
+ let entry = self.duplicate_entries.pop();
+ assert!(entry.is_some());
+ }
+
+ pub(crate) fn is_empty(&self) -> bool {
+ let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
+ opaque_types.is_empty() && duplicate_entries.is_empty()
+ }
+
+ pub(crate) fn take_opaque_types(
+ &mut self,
+ ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+ let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
+ std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries))
+ }
+
+ pub fn num_entries(&self) -> OpaqueTypeStorageEntries {
+ OpaqueTypeStorageEntries {
+ opaque_types: self.opaque_types.len(),
+ duplicate_entries: self.duplicate_entries.len(),
+ }
+ }
+
+ pub fn opaque_types_added_since(
+ &self,
+ prev_entries: OpaqueTypeStorageEntries,
+ ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+ self.opaque_types
+ .iter()
+ .skip(prev_entries.opaque_types)
+ .map(|(k, v)| (*k, *v))
+ .chain(self.duplicate_entries.iter().skip(prev_entries.duplicate_entries).copied())
+ }
+
+ /// Only returns the opaque types from the lookup table. These are used
+ /// when normalizing opaque types and have a unique key.
+ ///
+ /// Outside of canonicalization one should generally use `iter_opaque_types`
+ /// to also consider duplicate entries.
+ pub fn iter_lookup_table(
+ &self,
+ ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+ self.opaque_types.iter().map(|(k, v)| (*k, *v))
+ }
+
+ /// Only returns the opaque types which are stored in `duplicate_entries`.
+ ///
+ /// These have to considered when checking all opaque type uses but are e.g.
+ /// irrelevant for canonical inputs as nested queries never meaningfully
+ /// accesses them.
+ pub fn iter_duplicate_entries(
+ &self,
+ ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+ self.duplicate_entries.iter().copied()
+ }
+
+ pub fn iter_opaque_types(
+ &self,
+ ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+ let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
+ opaque_types.iter().map(|(k, v)| (*k, *v)).chain(duplicate_entries.iter().copied())
+ }
+
#[inline]
pub(crate) fn with_log<'a>(
&'a mut self,
@@ -44,21 +117,27 @@ pub(crate) fn with_log<'a>(
impl<'tcx> Drop for OpaqueTypeStorage<'tcx> {
fn drop(&mut self) {
- if !self.opaque_types.is_empty() {
+ if !self.is_empty() {
ty::tls::with(|tcx| tcx.dcx().delayed_bug(format!("{:?}", self.opaque_types)));
}
}
}
-pub(crate) struct OpaqueTypeTable<'a, 'tcx> {
+pub struct OpaqueTypeTable<'a, 'tcx> {
storage: &'a mut OpaqueTypeStorage<'tcx>,
undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
}
+impl<'tcx> Deref for OpaqueTypeTable<'_, 'tcx> {
+ type Target = OpaqueTypeStorage<'tcx>;
+ fn deref(&self) -> &Self::Target {
+ self.storage
+ }
+}
impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
- pub(crate) fn register(
+ pub fn register(
&mut self,
key: OpaqueTypeKey<'tcx>,
hidden_type: OpaqueHiddenType<'tcx>,
@@ -72,4 +151,9 @@ pub(crate) fn register(
self.undo_log.push(UndoLog::OpaqueTypes(key, None));
None
}
+
+ pub fn add_duplicate(&mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>) {
+ self.storage.duplicate_entries.push((key, hidden_type));
+ self.undo_log.push(UndoLog::DuplicateOpaqueType);
+ }
}
diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
index c44d9723..2a4b977 100644
--- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
+++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
@@ -24,10 +24,6 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for FreeRegionsVisitor<'tcx, OP>
where
OP: FnMut(ty::Region<'tcx>),
{
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
- t.super_visit_with(self);
- }
-
fn visit_region(&mut self, r: ty::Region<'tcx>) {
match r.kind() {
// ignore bound regions, keep visiting
diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
index ba7d8f5..b7412d3 100644
--- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
@@ -17,6 +17,7 @@ pub struct Snapshot<'tcx> {
/// Records the "undo" data for a single operation that affects some form of inference variable.
#[derive(Clone)]
pub(crate) enum UndoLog<'tcx> {
+ DuplicateOpaqueType,
OpaqueTypes(OpaqueTypeKey<'tcx>, Option<OpaqueHiddenType<'tcx>>),
TypeVariables(sv::UndoLog<ut::Delegate<type_variable::TyVidEqKey<'tcx>>>),
ConstUnificationTable(sv::UndoLog<ut::Delegate<ConstVidKey<'tcx>>>),
@@ -58,6 +59,7 @@ fn from(x: $ty) -> Self {
impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
fn reverse(&mut self, undo: UndoLog<'tcx>) {
match undo {
+ UndoLog::DuplicateOpaqueType => self.opaque_type_storage.pop_duplicate_entry(),
UndoLog::OpaqueTypes(key, idx) => self.opaque_type_storage.remove(key, idx),
UndoLog::TypeVariables(undo) => self.type_variable_storage.reverse(undo),
UndoLog::ConstUnificationTable(undo) => self.const_unification_storage.reverse(undo),
diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs
index ddab131..91d58d9 100644
--- a/compiler/rustc_lint/src/autorefs.rs
+++ b/compiler/rustc_lint/src/autorefs.rs
@@ -15,9 +15,9 @@
///
/// ```rust
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
- /// &raw mut (*ptr)[..16]
- /// // ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`,
- /// // implicitly creating a reference
+ /// unsafe { &raw mut (*ptr)[..16] }
+ /// // ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`,
+ /// // implicitly creating a reference
/// }
/// ```
///
@@ -34,17 +34,17 @@
///
/// ```rust
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
- /// &raw mut (&mut *ptr)[..16]
+ /// unsafe { &raw mut (&mut *ptr)[..16] }
/// }
/// ```
///
/// Otherwise try to find an alternative way to achive your goals using only raw pointers:
///
/// ```rust
- /// use std::slice;
+ /// use std::ptr;
///
- /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
- /// slice::from_raw_parts_mut(ptr.cast(), 16)
+ /// fn fun(ptr: *mut [u8]) -> *mut [u8] {
+ /// ptr::slice_from_raw_parts_mut(ptr.cast(), 16)
/// }
/// ```
pub DANGEROUS_IMPLICIT_AUTOREFS,
diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
index 757fc1f..a56b753 100644
--- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs
+++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
@@ -49,6 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some((pat, arg)) = extract_for_loop(expr) else { return };
+ let arg_span = arg.span.source_callsite();
+
let ty = cx.typeck_results().expr_ty(arg);
let (adt, args, ref_mutability) = match ty.kind() {
@@ -78,27 +80,27 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
&& let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
{
ForLoopsOverFalliblesLoopSub::RemoveNext {
- suggestion: recv.span.between(arg.span.shrink_to_hi()),
+ suggestion: recv.span.between(arg_span.shrink_to_hi()),
recv_snip,
}
} else {
ForLoopsOverFalliblesLoopSub::UseWhileLet {
start_span: expr.span.with_hi(pat.span.lo()),
- end_span: pat.span.between(arg.span),
+ end_span: pat.span.between(arg_span),
var,
}
};
let question_mark = suggest_question_mark(cx, adt, args, expr.span)
- .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
+ .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg_span.shrink_to_hi() });
let suggestion = ForLoopsOverFalliblesSuggestion {
var,
start_span: expr.span.with_hi(pat.span.lo()),
- end_span: pat.span.between(arg.span),
+ end_span: pat.span.between(arg_span),
};
cx.emit_span_lint(
FOR_LOOPS_OVER_FALLIBLES,
- arg.span,
+ arg_span,
ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
);
}
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index 7f4789a..a8f45d0 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -15,7 +15,8 @@
Relate, RelateResult, TypeRelation, structurally_relate_consts, structurally_relate_tys,
};
use rustc_middle::ty::{
- self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
+ self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+ TypeVisitor,
};
use rustc_middle::{bug, span_bug};
use rustc_session::lint::FutureIncompatibilityReason;
@@ -209,7 +210,7 @@ impl<'tcx, VarFn, OutlivesFn> TypeVisitor<TyCtxt<'tcx>>
VarFn: FnOnce() -> FxHashMap<DefId, ty::Variance>,
OutlivesFn: FnOnce() -> OutlivesEnvironment<'tcx>,
{
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
+ fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
// When we get into a binder, we need to add its own bound vars to the scope.
let mut added = vec![];
for arg in t.bound_vars() {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 03b8112..3cea246 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2352,37 +2352,11 @@
}
declare_lint! {
- /// The `soft_unstable` lint detects unstable features that were
- /// unintentionally allowed on stable.
- ///
- /// ### Example
- ///
- /// ```rust,compile_fail
- /// #[cfg(test)]
- /// extern crate test;
- ///
- /// #[bench]
- /// fn name(b: &mut test::Bencher) {
- /// b.iter(|| 123)
- /// }
- /// ```
- ///
- /// {{produces}}
- ///
- /// ### Explanation
- ///
- /// The [`bench` attribute] was accidentally allowed to be specified on
- /// the [stable release channel]. Turning this to a hard error would have
- /// broken some projects. This lint allows those projects to continue to
- /// build correctly when [`--cap-lints`] is used, but otherwise signal an
- /// error that `#[bench]` should not be used on the stable channel. This
- /// is a [future-incompatible] lint to transition this to a hard error in
- /// the future. See [issue #64266] for more details.
+ /// The `soft_unstable` lint detects unstable features that were unintentionally allowed on
+ /// stable. This is a [future-incompatible] lint to transition this to a hard error in the
+ /// future. See [issue #64266] for more details.
///
/// [issue #64266]: https://github.com/rust-lang/rust/issues/64266
- /// [`bench` attribute]: https://doc.rust-lang.org/nightly/unstable-book/library-features/test.html
- /// [stable release channel]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
- /// [`--cap-lints`]: https://doc.rust-lang.org/rustc/lints/levels.html#capping-lints
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub SOFT_UNSTABLE,
Deny,
diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs
index 1d67d0f..64a1f2a 100644
--- a/compiler/rustc_middle/src/middle/exported_symbols.rs
+++ b/compiler/rustc_middle/src/middle/exported_symbols.rs
@@ -22,7 +22,7 @@ pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
}
/// Kind of exported symbols.
-#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable, Hash)]
pub enum SymbolExportKind {
Text,
Data,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index eb04c35..b2133fe 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -387,7 +387,7 @@
}
}
- query stalled_generators_within(
+ query nested_bodies_within(
key: LocalDefId
) -> &'tcx ty::List<LocalDefId> {
desc {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index f9ff5c3..0759fa3 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -691,15 +691,17 @@ fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefI
self.opaque_types_defined_by(defining_anchor)
}
- fn opaque_types_and_generators_defined_by(
+ fn opaque_types_and_coroutines_defined_by(
self,
defining_anchor: Self::LocalDefId,
) -> Self::LocalDefIds {
if self.next_trait_solver_globally() {
+ let coroutines_defined_by = self
+ .nested_bodies_within(defining_anchor)
+ .iter()
+ .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
self.mk_local_def_ids_from_iter(
- self.opaque_types_defined_by(defining_anchor)
- .iter()
- .chain(self.stalled_generators_within(defining_anchor)),
+ self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
)
} else {
self.opaque_types_defined_by(defining_anchor)
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index c4ddaca..2d69a1c 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -309,7 +309,10 @@ pub fn to_string(self, def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
} else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
"pub(self)".to_string()
} else {
- format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
+ format!(
+ "pub(in crate{})",
+ tcx.def_path(restricted_id.to_def_id()).to_string_no_crate_verbose()
+ )
}
}
ty::Visibility::Public => "pub".to_string(),
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index bc1423a..0250c77 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2934,7 +2934,7 @@ pub fn pretty_wrap_binder<T, C: FnOnce(&T, &mut Self) -> Result<(), fmt::Error>>
fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
where
- T: TypeVisitable<TyCtxt<'tcx>>,
+ T: TypeFoldable<TyCtxt<'tcx>>,
{
struct RegionNameCollector<'tcx> {
used_region_names: FxHashSet<Symbol>,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 2165cf1..c31ce1b 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -723,7 +723,10 @@ pub fn new_dynamic(
repr: DynKind,
) -> Ty<'tcx> {
if cfg!(debug_assertions) {
- let projection_count = obj.projection_bounds().count();
+ let projection_count = obj
+ .projection_bounds()
+ .filter(|item| !tcx.generics_require_sized_self(item.item_def_id()))
+ .count();
let expected_count: usize = obj
.principal_def_id()
.into_iter()
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 3853a80..f8042174 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -66,7 +66,7 @@ impl<'tcx, F> TypeVisitor<TyCtxt<'tcx>> for RegionVisitor<F>
{
type Result = ControlFlow<()>;
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
+ fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
&mut self,
t: &Binder<'tcx, T>,
) -> Self::Result {
@@ -168,7 +168,7 @@ fn new(just_constrained: bool) -> Self {
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) {
+ fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) {
self.current_index.shift_in(1);
t.super_visit_with(self);
self.current_index.shift_out(1);
diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
index d500576..3f6e7a0 100644
--- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
@@ -1,5 +1,6 @@
//! Random access inspection of the results of a dataflow analysis.
+use std::borrow::Cow;
use std::cmp::Ordering;
use std::ops::{Deref, DerefMut};
@@ -9,38 +10,30 @@
use super::{Analysis, Direction, Effect, EffectIndex, Results};
-/// Some `ResultsCursor`s want to own a `Results`, and some want to borrow a `Results`, either
-/// mutable or immutably. This type allows all of the above. It's similar to `Cow`.
-pub enum ResultsHandle<'a, 'tcx, A>
-where
- A: Analysis<'tcx>,
-{
- BorrowedMut(&'a mut Results<'tcx, A>),
- Owned(Results<'tcx, A>),
+/// Some `ResultsCursor`s want to own an `Analysis`, and some want to borrow an `Analysis`, either
+/// mutable or immutably. This type allows all of the above. It's similar to `Cow`, but `Cow`
+/// doesn't allow mutable borrowing.
+enum CowMut<'a, T> {
+ BorrowedMut(&'a mut T),
+ Owned(T),
}
-impl<'tcx, A> Deref for ResultsHandle<'_, 'tcx, A>
-where
- A: Analysis<'tcx>,
-{
- type Target = Results<'tcx, A>;
+impl<T> Deref for CowMut<'_, T> {
+ type Target = T;
- fn deref(&self) -> &Results<'tcx, A> {
+ fn deref(&self) -> &T {
match self {
- ResultsHandle::BorrowedMut(borrowed) => borrowed,
- ResultsHandle::Owned(owned) => owned,
+ CowMut::BorrowedMut(borrowed) => borrowed,
+ CowMut::Owned(owned) => owned,
}
}
}
-impl<'tcx, A> DerefMut for ResultsHandle<'_, 'tcx, A>
-where
- A: Analysis<'tcx>,
-{
- fn deref_mut(&mut self) -> &mut Results<'tcx, A> {
+impl<T> DerefMut for CowMut<'_, T> {
+ fn deref_mut(&mut self) -> &mut T {
match self {
- ResultsHandle::BorrowedMut(borrowed) => borrowed,
- ResultsHandle::Owned(owned) => owned,
+ CowMut::BorrowedMut(borrowed) => borrowed,
+ CowMut::Owned(owned) => owned,
}
}
}
@@ -60,7 +53,8 @@ pub struct ResultsCursor<'mir, 'tcx, A>
A: Analysis<'tcx>,
{
body: &'mir mir::Body<'tcx>,
- results: ResultsHandle<'mir, 'tcx, A>,
+ analysis: CowMut<'mir, A>,
+ results: Cow<'mir, Results<A::Domain>>,
state: A::Domain,
pos: CursorPosition,
@@ -88,11 +82,15 @@ pub fn body(&self) -> &'mir mir::Body<'tcx> {
self.body
}
- /// Returns a new cursor that can inspect `results`.
- pub fn new(body: &'mir mir::Body<'tcx>, results: ResultsHandle<'mir, 'tcx, A>) -> Self {
- let bottom_value = results.analysis.bottom_value(body);
+ fn new(
+ body: &'mir mir::Body<'tcx>,
+ analysis: CowMut<'mir, A>,
+ results: Cow<'mir, Results<A::Domain>>,
+ ) -> Self {
+ let bottom_value = analysis.bottom_value(body);
ResultsCursor {
body,
+ analysis,
results,
// Initialize to the `bottom_value` and set `state_needs_reset` to tell the cursor that
@@ -107,6 +105,24 @@ pub fn new(body: &'mir mir::Body<'tcx>, results: ResultsHandle<'mir, 'tcx, A>) -
}
}
+ /// Returns a new cursor that takes ownership of and inspects analysis results.
+ pub fn new_owning(
+ body: &'mir mir::Body<'tcx>,
+ analysis: A,
+ results: Results<A::Domain>,
+ ) -> Self {
+ Self::new(body, CowMut::Owned(analysis), Cow::Owned(results))
+ }
+
+ /// Returns a new cursor that borrows and inspects analysis results.
+ pub fn new_borrowing(
+ body: &'mir mir::Body<'tcx>,
+ analysis: &'mir mut A,
+ results: &'mir Results<A::Domain>,
+ ) -> Self {
+ Self::new(body, CowMut::BorrowedMut(analysis), Cow::Borrowed(results))
+ }
+
/// Allows inspection of unreachable basic blocks even with `debug_assertions` enabled.
#[cfg(test)]
pub(crate) fn allow_unreachable(&mut self) {
@@ -116,7 +132,7 @@ pub(crate) fn allow_unreachable(&mut self) {
/// Returns the `Analysis` used to generate the underlying `Results`.
pub fn analysis(&self) -> &A {
- &self.results.analysis
+ &self.analysis
}
/// Resets the cursor to hold the entry set for the given basic block.
@@ -128,7 +144,7 @@ pub(super) fn seek_to_block_entry(&mut self, block: BasicBlock) {
#[cfg(debug_assertions)]
assert!(self.reachable_blocks.contains(block));
- self.state.clone_from(self.results.entry_set_for_block(block));
+ self.state.clone_from(&self.results[block]);
self.pos = CursorPosition::block_entry(block);
self.state_needs_reset = false;
}
@@ -220,7 +236,7 @@ fn seek_after(&mut self, target: Location, effect: Effect) {
let target_effect_index = effect.at_index(target.statement_index);
A::Direction::apply_effects_in_range(
- &mut self.results.analysis,
+ &mut *self.analysis,
&mut self.state,
target.block,
block_data,
@@ -236,7 +252,7 @@ fn seek_after(&mut self, target: Location, effect: Effect) {
/// This can be used, e.g., to apply the call return effect directly to the cursor without
/// creating an extra copy of the dataflow state.
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) {
- f(&mut self.results.analysis, &mut self.state);
+ f(&mut self.analysis, &mut self.state);
self.state_needs_reset = true;
}
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index b8c26da..e955e38 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -5,7 +5,7 @@
};
use super::visitor::ResultsVisitor;
-use super::{Analysis, Effect, EffectIndex, Results};
+use super::{Analysis, Effect, EffectIndex};
pub trait Direction {
const IS_FORWARD: bool;
@@ -36,13 +36,13 @@ fn apply_effects_in_range<'tcx, A>(
A: Analysis<'tcx>;
/// Called by `ResultsVisitor` to recompute the analysis domain values for
- /// all locations in a basic block (starting from the entry value stored
- /// in `Results`) and to visit them with `vis`.
+ /// all locations in a basic block (starting from `entry_state` and to
+ /// visit them with `vis`.
fn visit_results_in_block<'mir, 'tcx, A>(
state: &mut A::Domain,
block: BasicBlock,
block_data: &'mir mir::BasicBlockData<'tcx>,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
vis: &mut impl ResultsVisitor<'tcx, A>,
) where
A: Analysis<'tcx>;
@@ -211,28 +211,26 @@ fn visit_results_in_block<'mir, 'tcx, A>(
state: &mut A::Domain,
block: BasicBlock,
block_data: &'mir mir::BasicBlockData<'tcx>,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
vis: &mut impl ResultsVisitor<'tcx, A>,
) where
A: Analysis<'tcx>,
{
- state.clone_from(results.entry_set_for_block(block));
-
vis.visit_block_end(state);
let loc = Location { block, statement_index: block_data.statements.len() };
let term = block_data.terminator();
- results.analysis.apply_early_terminator_effect(state, term, loc);
- vis.visit_after_early_terminator_effect(results, state, term, loc);
- results.analysis.apply_primary_terminator_effect(state, term, loc);
- vis.visit_after_primary_terminator_effect(results, state, term, loc);
+ analysis.apply_early_terminator_effect(state, term, loc);
+ vis.visit_after_early_terminator_effect(analysis, state, term, loc);
+ analysis.apply_primary_terminator_effect(state, term, loc);
+ vis.visit_after_primary_terminator_effect(analysis, state, term, loc);
for (statement_index, stmt) in block_data.statements.iter().enumerate().rev() {
let loc = Location { block, statement_index };
- results.analysis.apply_early_statement_effect(state, stmt, loc);
- vis.visit_after_early_statement_effect(results, state, stmt, loc);
- results.analysis.apply_primary_statement_effect(state, stmt, loc);
- vis.visit_after_primary_statement_effect(results, state, stmt, loc);
+ analysis.apply_early_statement_effect(state, stmt, loc);
+ vis.visit_after_early_statement_effect(analysis, state, stmt, loc);
+ analysis.apply_primary_statement_effect(state, stmt, loc);
+ vis.visit_after_primary_statement_effect(analysis, state, stmt, loc);
}
vis.visit_block_start(state);
@@ -393,29 +391,27 @@ fn visit_results_in_block<'mir, 'tcx, A>(
state: &mut A::Domain,
block: BasicBlock,
block_data: &'mir mir::BasicBlockData<'tcx>,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
vis: &mut impl ResultsVisitor<'tcx, A>,
) where
A: Analysis<'tcx>,
{
- state.clone_from(results.entry_set_for_block(block));
-
vis.visit_block_start(state);
for (statement_index, stmt) in block_data.statements.iter().enumerate() {
let loc = Location { block, statement_index };
- results.analysis.apply_early_statement_effect(state, stmt, loc);
- vis.visit_after_early_statement_effect(results, state, stmt, loc);
- results.analysis.apply_primary_statement_effect(state, stmt, loc);
- vis.visit_after_primary_statement_effect(results, state, stmt, loc);
+ analysis.apply_early_statement_effect(state, stmt, loc);
+ vis.visit_after_early_statement_effect(analysis, state, stmt, loc);
+ analysis.apply_primary_statement_effect(state, stmt, loc);
+ vis.visit_after_primary_statement_effect(analysis, state, stmt, loc);
}
let loc = Location { block, statement_index: block_data.statements.len() };
let term = block_data.terminator();
- results.analysis.apply_early_terminator_effect(state, term, loc);
- vis.visit_after_early_terminator_effect(results, state, term, loc);
- results.analysis.apply_primary_terminator_effect(state, term, loc);
- vis.visit_after_primary_terminator_effect(results, state, term, loc);
+ analysis.apply_early_terminator_effect(state, term, loc);
+ vis.visit_after_early_terminator_effect(analysis, state, term, loc);
+ analysis.apply_primary_terminator_effect(state, term, loc);
+ vis.visit_after_primary_terminator_effect(analysis, state, term, loc);
vis.visit_block_end(state);
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index b5e9a0b..a7d5422 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -21,7 +21,9 @@
use {rustc_ast as ast, rustc_graphviz as dot};
use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext};
-use super::{Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor};
+use super::{
+ Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor, visit_results,
+};
use crate::errors::{
DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter,
};
@@ -32,7 +34,8 @@
pub(super) fn write_graphviz_results<'tcx, A>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
+ results: &Results<A::Domain>,
pass_name: Option<&'static str>,
) -> std::io::Result<()>
where
@@ -77,7 +80,7 @@ pub(super) fn write_graphviz_results<'tcx, A>(
let mut buf = Vec::new();
- let graphviz = Formatter::new(body, results, style);
+ let graphviz = Formatter::new(body, analysis, results, style);
let mut render_opts =
vec![dot::RenderOption::Fontname(tcx.sess.opts.unstable_opts.graphviz_font.clone())];
if tcx.sess.opts.unstable_opts.graphviz_dark_mode {
@@ -203,10 +206,11 @@ struct Formatter<'mir, 'tcx, A>
{
body: &'mir Body<'tcx>,
// The `RefCell` is used because `<Formatter as Labeller>::node_label`
- // takes `&self`, but it needs to modify the results. This is also the
+ // takes `&self`, but it needs to modify the analysis. This is also the
// reason for the `Formatter`/`BlockFormatter` split; `BlockFormatter` has
// the operations that involve the mutation, i.e. within the `borrow_mut`.
- results: RefCell<&'mir mut Results<'tcx, A>>,
+ analysis: RefCell<&'mir mut A>,
+ results: &'mir Results<A::Domain>,
style: OutputStyle,
reachable: DenseBitSet<BasicBlock>,
}
@@ -217,11 +221,12 @@ impl<'mir, 'tcx, A> Formatter<'mir, 'tcx, A>
{
fn new(
body: &'mir Body<'tcx>,
- results: &'mir mut Results<'tcx, A>,
+ analysis: &'mir mut A,
+ results: &'mir Results<A::Domain>,
style: OutputStyle,
) -> Self {
let reachable = traversal::reachable_as_bitset(body);
- Formatter { body, results: results.into(), style, reachable }
+ Formatter { body, analysis: analysis.into(), results, style, reachable }
}
}
@@ -259,12 +264,12 @@ fn node_id(&self, n: &Self::Node) -> dot::Id<'_> {
}
fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> {
- let mut results = self.results.borrow_mut();
+ let analysis = &mut **self.analysis.borrow_mut();
- let diffs = StateDiffCollector::run(self.body, *block, *results, self.style);
+ let diffs = StateDiffCollector::run(self.body, *block, analysis, self.results, self.style);
let mut fmt = BlockFormatter {
- cursor: results.as_results_cursor(self.body),
+ cursor: ResultsCursor::new_borrowing(self.body, analysis, self.results),
style: self.style,
bg: Background::Light,
};
@@ -692,7 +697,8 @@ impl<D> StateDiffCollector<D> {
fn run<'tcx, A>(
body: &Body<'tcx>,
block: BasicBlock,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
+ results: &Results<A::Domain>,
style: OutputStyle,
) -> Self
where
@@ -700,12 +706,12 @@ fn run<'tcx, A>(
D: DebugWithContext<A>,
{
let mut collector = StateDiffCollector {
- prev_state: results.analysis.bottom_value(body),
+ prev_state: analysis.bottom_value(body),
after: vec![],
before: (style == OutputStyle::BeforeAndAfter).then_some(vec![]),
};
- results.visit_with(body, std::iter::once(block), &mut collector);
+ visit_results(body, std::iter::once(block), analysis, results, &mut collector);
collector
}
}
@@ -729,49 +735,49 @@ fn visit_block_end(&mut self, state: &A::Domain) {
fn visit_after_early_statement_effect(
&mut self,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
state: &A::Domain,
_statement: &mir::Statement<'tcx>,
_location: Location,
) {
if let Some(before) = self.before.as_mut() {
- before.push(diff_pretty(state, &self.prev_state, &results.analysis));
+ before.push(diff_pretty(state, &self.prev_state, analysis));
self.prev_state.clone_from(state)
}
}
fn visit_after_primary_statement_effect(
&mut self,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
state: &A::Domain,
_statement: &mir::Statement<'tcx>,
_location: Location,
) {
- self.after.push(diff_pretty(state, &self.prev_state, &results.analysis));
+ self.after.push(diff_pretty(state, &self.prev_state, analysis));
self.prev_state.clone_from(state)
}
fn visit_after_early_terminator_effect(
&mut self,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
state: &A::Domain,
_terminator: &mir::Terminator<'tcx>,
_location: Location,
) {
if let Some(before) = self.before.as_mut() {
- before.push(diff_pretty(state, &self.prev_state, &results.analysis));
+ before.push(diff_pretty(state, &self.prev_state, analysis));
self.prev_state.clone_from(state)
}
}
fn visit_after_primary_terminator_effect(
&mut self,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
state: &A::Domain,
_terminator: &mir::Terminator<'tcx>,
_location: Location,
) {
- self.after.push(diff_pretty(state, &self.prev_state, &results.analysis));
+ self.after.push(diff_pretty(state, &self.prev_state, analysis));
self.prev_state.clone_from(state)
}
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs
index 09f6cdb..9cadec1 100644
--- a/compiler/rustc_mir_dataflow/src/framework/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs
@@ -58,8 +58,9 @@
pub use self::cursor::ResultsCursor;
pub use self::direction::{Backward, Direction, Forward};
pub use self::lattice::{JoinSemiLattice, MaybeReachable};
-pub use self::results::{EntryStates, Results};
-pub use self::visitor::{ResultsVisitor, visit_results};
+pub(crate) use self::results::AnalysisAndResults;
+pub use self::results::Results;
+pub use self::visitor::{ResultsVisitor, visit_reachable_results, visit_results};
/// Analysis domains are all bitsets of various kinds. This trait holds
/// operations needed by all of them.
@@ -247,17 +248,15 @@ fn iterate_to_fixpoint<'mir>(
tcx: TyCtxt<'tcx>,
body: &'mir mir::Body<'tcx>,
pass_name: Option<&'static str>,
- ) -> Results<'tcx, Self>
+ ) -> AnalysisAndResults<'tcx, Self>
where
Self: Sized,
Self::Domain: DebugWithContext<Self>,
{
- let mut entry_states =
- IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len());
- self.initialize_start_block(body, &mut entry_states[mir::START_BLOCK]);
+ let mut results = IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len());
+ self.initialize_start_block(body, &mut results[mir::START_BLOCK]);
- if Self::Direction::IS_BACKWARD && entry_states[mir::START_BLOCK] != self.bottom_value(body)
- {
+ if Self::Direction::IS_BACKWARD && results[mir::START_BLOCK] != self.bottom_value(body) {
bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
}
@@ -280,10 +279,9 @@ fn iterate_to_fixpoint<'mir>(
// every iteration.
let mut state = self.bottom_value(body);
while let Some(bb) = dirty_queue.pop() {
- // Set the state to the entry state of the block.
- // This is equivalent to `state = entry_states[bb].clone()`,
- // but it saves an allocation, thus improving compile times.
- state.clone_from(&entry_states[bb]);
+ // Set the state to the entry state of the block. This is equivalent to `state =
+ // results[bb].clone()`, but it saves an allocation, thus improving compile times.
+ state.clone_from(&results[bb]);
Self::Direction::apply_effects_in_block(
&mut self,
@@ -292,7 +290,7 @@ fn iterate_to_fixpoint<'mir>(
bb,
&body[bb],
|target: BasicBlock, state: &Self::Domain| {
- let set_changed = entry_states[target].join(state);
+ let set_changed = results[target].join(state);
if set_changed {
dirty_queue.insert(target);
}
@@ -300,16 +298,14 @@ fn iterate_to_fixpoint<'mir>(
);
}
- let mut results = Results { analysis: self, entry_states };
-
if tcx.sess.opts.unstable_opts.dump_mir_dataflow {
- let res = write_graphviz_results(tcx, body, &mut results, pass_name);
+ let res = write_graphviz_results(tcx, body, &mut self, &results, pass_name);
if let Err(e) = res {
error!("Failed to write graphviz dataflow results: {}", e);
}
}
- results
+ AnalysisAndResults { analysis: self, results }
}
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs
index 93dfc06..7b7e981 100644
--- a/compiler/rustc_mir_dataflow/src/framework/results.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/results.rs
@@ -1,63 +1,30 @@
//! Dataflow analysis results.
use rustc_index::IndexVec;
-use rustc_middle::mir::{BasicBlock, Body, traversal};
+use rustc_middle::mir::{BasicBlock, Body};
-use super::{Analysis, ResultsCursor, ResultsVisitor, visit_results};
-use crate::framework::cursor::ResultsHandle;
+use super::{Analysis, ResultsCursor};
-pub type EntryStates<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
+/// The results of a dataflow analysis that has converged to fixpoint. It only holds the domain
+/// values at the entry of each basic block. Domain values in other parts of the block are
+/// recomputed on the fly by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
+pub type Results<D> = IndexVec<BasicBlock, D>;
-/// A dataflow analysis that has converged to fixpoint. It only holds the domain values at the
-/// entry of each basic block. Domain values in other parts of the block are recomputed on the fly
-/// by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
-#[derive(Clone)]
-pub struct Results<'tcx, A>
+/// Utility type used in a few places where it's convenient to bundle an analysis with its results.
+pub struct AnalysisAndResults<'tcx, A>
where
A: Analysis<'tcx>,
{
pub analysis: A,
- pub entry_states: EntryStates<'tcx, A>,
+ pub results: Results<A::Domain>,
}
-impl<'tcx, A> Results<'tcx, A>
+impl<'tcx, A> AnalysisAndResults<'tcx, A>
where
A: Analysis<'tcx>,
{
- /// Creates a `ResultsCursor` that mutably borrows the `Results`, which is appropriate when the
- /// `Results` is also used outside the cursor.
- pub fn as_results_cursor<'mir>(
- &'mir mut self,
- body: &'mir Body<'tcx>,
- ) -> ResultsCursor<'mir, 'tcx, A> {
- ResultsCursor::new(body, ResultsHandle::BorrowedMut(self))
- }
-
- /// Creates a `ResultsCursor` that takes ownership of the `Results`.
+ /// Creates a `ResultsCursor` that takes ownership of `self`.
pub fn into_results_cursor<'mir>(self, body: &'mir Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> {
- ResultsCursor::new(body, ResultsHandle::Owned(self))
- }
-
- /// Gets the dataflow state for the given block.
- pub fn entry_set_for_block(&self, block: BasicBlock) -> &A::Domain {
- &self.entry_states[block]
- }
-
- pub fn visit_with<'mir>(
- &mut self,
- body: &'mir Body<'tcx>,
- blocks: impl IntoIterator<Item = BasicBlock>,
- vis: &mut impl ResultsVisitor<'tcx, A>,
- ) {
- visit_results(body, blocks, self, vis)
- }
-
- pub fn visit_reachable_with<'mir>(
- &mut self,
- body: &'mir Body<'tcx>,
- vis: &mut impl ResultsVisitor<'tcx, A>,
- ) {
- let blocks = traversal::reachable(body);
- visit_results(body, blocks.map(|(bb, _)| bb), self, vis)
+ ResultsCursor::new_owning(body, self.analysis, self.results)
}
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index ae0f117..8602bb5 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -79,7 +79,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
///
/// The `102` in the block's entry set is derived from the basic block index and ensures that the
/// expected state is unique across all basic blocks. Remember, it is generated by
-/// `mock_entry_states`, not from actually running `MockAnalysis` to fixpoint.
+/// `mock_results`, not from actually running `MockAnalysis` to fixpoint.
struct MockAnalysis<'tcx, D> {
body: &'tcx mir::Body<'tcx>,
dir: PhantomData<D>,
@@ -96,7 +96,7 @@ fn mock_entry_set(&self, bb: BasicBlock) -> DenseBitSet<usize> {
ret
}
- fn mock_entry_states(&self) -> IndexVec<BasicBlock, DenseBitSet<usize>> {
+ fn mock_results(&self) -> IndexVec<BasicBlock, DenseBitSet<usize>> {
let empty = self.bottom_value(self.body);
let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks);
@@ -255,7 +255,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
let body = analysis.body;
let mut cursor =
- Results { entry_states: analysis.mock_entry_states(), analysis }.into_results_cursor(body);
+ AnalysisAndResults { results: analysis.mock_results(), analysis }.into_results_cursor(body);
cursor.allow_unreachable();
diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
index c9fdf46..fbb9e41 100644
--- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
@@ -1,4 +1,4 @@
-use rustc_middle::mir::{self, BasicBlock, Location};
+use rustc_middle::mir::{self, BasicBlock, Location, traversal};
use super::{Analysis, Direction, Results};
@@ -7,12 +7,13 @@
pub fn visit_results<'mir, 'tcx, A>(
body: &'mir mir::Body<'tcx>,
blocks: impl IntoIterator<Item = BasicBlock>,
- results: &mut Results<'tcx, A>,
+ analysis: &mut A,
+ results: &Results<A::Domain>,
vis: &mut impl ResultsVisitor<'tcx, A>,
) where
A: Analysis<'tcx>,
{
- let mut state = results.analysis.bottom_value(body);
+ let mut state = analysis.bottom_value(body);
#[cfg(debug_assertions)]
let reachable_blocks = mir::traversal::reachable_as_bitset(body);
@@ -22,10 +23,24 @@ pub fn visit_results<'mir, 'tcx, A>(
assert!(reachable_blocks.contains(block));
let block_data = &body[block];
- A::Direction::visit_results_in_block(&mut state, block, block_data, results, vis);
+ state.clone_from(&results[block]);
+ A::Direction::visit_results_in_block(&mut state, block, block_data, analysis, vis);
}
}
+/// Like `visit_results`, but only for reachable blocks.
+pub fn visit_reachable_results<'mir, 'tcx, A>(
+ body: &'mir mir::Body<'tcx>,
+ analysis: &mut A,
+ results: &Results<A::Domain>,
+ vis: &mut impl ResultsVisitor<'tcx, A>,
+) where
+ A: Analysis<'tcx>,
+{
+ let blocks = traversal::reachable(body).map(|(bb, _)| bb);
+ visit_results(body, blocks, analysis, results, vis)
+}
+
/// A visitor over the results of an `Analysis`. Use this when you want to inspect domain values in
/// many or all locations; use `ResultsCursor` if you want to inspect domain values only in certain
/// locations.
@@ -38,7 +53,7 @@ fn visit_block_start(&mut self, _state: &A::Domain) {}
/// Called after the "early" effect of the given statement is applied to `state`.
fn visit_after_early_statement_effect(
&mut self,
- _results: &mut Results<'tcx, A>,
+ _analysis: &mut A,
_state: &A::Domain,
_statement: &mir::Statement<'tcx>,
_location: Location,
@@ -48,7 +63,7 @@ fn visit_after_early_statement_effect(
/// Called after the "primary" effect of the given statement is applied to `state`.
fn visit_after_primary_statement_effect(
&mut self,
- _results: &mut Results<'tcx, A>,
+ _analysis: &mut A,
_state: &A::Domain,
_statement: &mir::Statement<'tcx>,
_location: Location,
@@ -58,7 +73,7 @@ fn visit_after_primary_statement_effect(
/// Called after the "early" effect of the given terminator is applied to `state`.
fn visit_after_early_terminator_effect(
&mut self,
- _results: &mut Results<'tcx, A>,
+ _analysis: &mut A,
_state: &A::Domain,
_terminator: &mir::Terminator<'tcx>,
_location: Location,
@@ -70,7 +85,7 @@ fn visit_after_early_terminator_effect(
/// The `call_return_effect` (if one exists) will *not* be applied to `state`.
fn visit_after_primary_terminator_effect(
&mut self,
- _results: &mut Results<'tcx, A>,
+ _analysis: &mut A,
_state: &A::Domain,
_terminator: &mir::Terminator<'tcx>,
_location: Location,
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index 38f82b1..658fbf5 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -18,8 +18,8 @@
move_path_children_matching, on_all_children_bits, on_lookup_result_bits,
};
pub use self::framework::{
- Analysis, Backward, Direction, EntryStates, Forward, GenKill, JoinSemiLattice, MaybeReachable,
- Results, ResultsCursor, ResultsVisitor, fmt, graphviz, lattice, visit_results,
+ Analysis, Backward, Direction, Forward, GenKill, JoinSemiLattice, MaybeReachable, Results,
+ ResultsCursor, ResultsVisitor, fmt, graphviz, lattice, visit_reachable_results, visit_results,
};
use self::move_paths::MoveData;
diff --git a/compiler/rustc_mir_dataflow/src/points.rs b/compiler/rustc_mir_dataflow/src/points.rs
index 21590ff..70d1a34 100644
--- a/compiler/rustc_mir_dataflow/src/points.rs
+++ b/compiler/rustc_mir_dataflow/src/points.rs
@@ -98,7 +98,8 @@ pub struct PointIndex {}
pub fn save_as_intervals<'tcx, N, A>(
elements: &DenseLocationMap,
body: &mir::Body<'tcx>,
- mut results: Results<'tcx, A>,
+ mut analysis: A,
+ results: Results<A::Domain>,
) -> SparseIntervalMatrix<N, PointIndex>
where
N: Idx,
@@ -109,7 +110,8 @@ pub fn save_as_intervals<'tcx, N, A>(
visit_results(
body,
body.basic_blocks.reverse_postorder().iter().copied(),
- &mut results,
+ &mut analysis,
+ &results,
&mut visitor,
);
visitor.values
@@ -127,7 +129,7 @@ impl<'tcx, A, N> ResultsVisitor<'tcx, A> for Visitor<'_, N>
{
fn visit_after_primary_statement_effect<'mir>(
&mut self,
- _results: &mut Results<'tcx, A>,
+ _analysis: &mut A,
state: &A::Domain,
_statement: &'mir mir::Statement<'tcx>,
location: Location,
@@ -141,7 +143,7 @@ fn visit_after_primary_statement_effect<'mir>(
fn visit_after_primary_terminator_effect<'mir>(
&mut self,
- _results: &mut Results<'tcx, A>,
+ _analysis: &mut A,
state: &A::Domain,
_terminator: &'mir mir::Terminator<'tcx>,
location: Location,
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index 399141a..303fc76 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -39,23 +39,23 @@ pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let move_data = MoveData::gather_moves(body, tcx, |_| true);
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
- let flow_inits =
- MaybeInitializedPlaces::new(tcx, body, &move_data).iterate_to_fixpoint(tcx, body, None);
-
- sanity_check_via_rustc_peek(tcx, flow_inits.into_results_cursor(body));
+ let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
+ .iterate_to_fixpoint(tcx, body, None)
+ .into_results_cursor(body);
+ sanity_check_via_rustc_peek(tcx, flow_inits);
}
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() {
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data)
- .iterate_to_fixpoint(tcx, body, None);
-
- sanity_check_via_rustc_peek(tcx, flow_uninits.into_results_cursor(body));
+ .iterate_to_fixpoint(tcx, body, None)
+ .into_results_cursor(body);
+ sanity_check_via_rustc_peek(tcx, flow_uninits);
}
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() {
- let flow_liveness = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None);
-
- sanity_check_via_rustc_peek(tcx, flow_liveness.into_results_cursor(body));
+ let flow_liveness =
+ MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body);
+ sanity_check_via_rustc_peek(tcx, flow_liveness);
}
if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() {
diff --git a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
index 4aff127..8da17a0 100644
--- a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
+++ b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
@@ -55,18 +55,45 @@ fn is_unnecessary_transmute(
},
// char → u32
(Char, Uint(UintTy::U32)) => err(format!("u32::from({arg})")),
+ // char (→ u32) → i32
+ (Char, Int(IntTy::I32)) => err(format!("u32::from({arg}).cast_signed()")),
// u32 → char
(Uint(UintTy::U32), Char) => Error {
sugg: format!("char::from_u32_unchecked({arg})"),
help: Some("consider `char::from_u32(…).unwrap()`"),
span,
},
+ // i32 → char
+ (Int(IntTy::I32), Char) => Error {
+ sugg: format!("char::from_u32_unchecked(i32::cast_unsigned({arg}))"),
+ help: Some("consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`"),
+ span,
+ },
// uNN → iNN
(Uint(ty), Int(_)) => err(format!("{}::cast_signed({arg})", ty.name_str())),
// iNN → uNN
(Int(ty), Uint(_)) => err(format!("{}::cast_unsigned({arg})", ty.name_str())),
+ // fNN → xsize
+ (Float(ty), Uint(UintTy::Usize)) => {
+ err(format!("{}::to_bits({arg}) as usize", ty.name_str()))
+ }
+ (Float(ty), Int(IntTy::Isize)) => {
+ err(format!("{}::to_bits({arg}) as isize", ty.name_str()))
+ }
+ // fNN (→ uNN) → iNN
+ (Float(ty), Int(..)) => err(format!("{}::to_bits({arg}).cast_signed()", ty.name_str())),
// fNN → uNN
(Float(ty), Uint(..)) => err(format!("{}::to_bits({arg})", ty.name_str())),
+ // xsize → fNN
+ (Uint(UintTy::Usize) | Int(IntTy::Isize), Float(ty)) => {
+ err(format!("{}::from_bits({arg} as _)", ty.name_str(),))
+ }
+ // iNN (→ uNN) → fNN
+ (Int(int_ty), Float(ty)) => err(format!(
+ "{}::from_bits({}::cast_unsigned({arg}))",
+ ty.name_str(),
+ int_ty.name_str()
+ )),
// uNN → fNN
(Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())),
// bool → { x8 }
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 66f106b..cddb2f8 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -79,7 +79,9 @@
MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
always_storage_live_locals,
};
-use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor};
+use rustc_mir_dataflow::{
+ Analysis, Results, ResultsCursor, ResultsVisitor, visit_reachable_results,
+};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::source_map::dummy_spanned;
use rustc_span::symbol::sym;
@@ -680,18 +682,29 @@ fn locals_live_across_suspend_points<'tcx>(
.iterate_to_fixpoint(tcx, body, None)
.into_results_cursor(body);
- // Calculate the MIR locals which have been previously
- // borrowed (even if they are still active).
- let borrowed_locals_results =
- MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("coroutine"));
-
- let mut borrowed_locals_cursor = borrowed_locals_results.clone().into_results_cursor(body);
+ // Calculate the MIR locals that have been previously borrowed (even if they are still active).
+ let borrowed_locals = MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("coroutine"));
+ let mut borrowed_locals_analysis1 = borrowed_locals.analysis;
+ let mut borrowed_locals_analysis2 = borrowed_locals_analysis1.clone(); // trivial
+ let borrowed_locals_cursor1 = ResultsCursor::new_borrowing(
+ body,
+ &mut borrowed_locals_analysis1,
+ &borrowed_locals.results,
+ );
+ let mut borrowed_locals_cursor2 = ResultsCursor::new_borrowing(
+ body,
+ &mut borrowed_locals_analysis2,
+ &borrowed_locals.results,
+ );
// Calculate the MIR locals that we need to keep storage around for.
- let mut requires_storage_results =
- MaybeRequiresStorage::new(borrowed_locals_results.into_results_cursor(body))
- .iterate_to_fixpoint(tcx, body, None);
- let mut requires_storage_cursor = requires_storage_results.as_results_cursor(body);
+ let mut requires_storage =
+ MaybeRequiresStorage::new(borrowed_locals_cursor1).iterate_to_fixpoint(tcx, body, None);
+ let mut requires_storage_cursor = ResultsCursor::new_borrowing(
+ body,
+ &mut requires_storage.analysis,
+ &requires_storage.results,
+ );
// Calculate the liveness of MIR locals ignoring borrows.
let mut liveness =
@@ -720,8 +733,8 @@ fn locals_live_across_suspend_points<'tcx>(
// If a borrow is converted to a raw reference, we must also assume that it lives
// forever. Note that the final liveness is still bounded by the storage liveness
// of the local, which happens using the `intersect` operation below.
- borrowed_locals_cursor.seek_before_primary_effect(loc);
- live_locals.union(borrowed_locals_cursor.get());
+ borrowed_locals_cursor2.seek_before_primary_effect(loc);
+ live_locals.union(borrowed_locals_cursor2.get());
}
// Store the storage liveness for later use so we can restore the state
@@ -763,7 +776,8 @@ fn locals_live_across_suspend_points<'tcx>(
body,
&saved_locals,
always_live_locals.clone(),
- requires_storage_results,
+ &mut requires_storage.analysis,
+ &requires_storage.results,
);
LivenessInfo {
@@ -828,7 +842,8 @@ fn compute_storage_conflicts<'mir, 'tcx>(
body: &'mir Body<'tcx>,
saved_locals: &'mir CoroutineSavedLocals,
always_live_locals: DenseBitSet<Local>,
- mut requires_storage: Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>,
+ analysis: &mut MaybeRequiresStorage<'mir, 'tcx>,
+ results: &Results<DenseBitSet<Local>>,
) -> BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal> {
assert_eq!(body.local_decls.len(), saved_locals.domain_size());
@@ -848,7 +863,7 @@ fn compute_storage_conflicts<'mir, 'tcx>(
eligible_storage_live: DenseBitSet::new_empty(body.local_decls.len()),
};
- requires_storage.visit_reachable_with(body, &mut visitor);
+ visit_reachable_results(body, analysis, results, &mut visitor);
let local_conflicts = visitor.local_conflicts;
@@ -891,7 +906,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, MaybeRequiresStorage<'a, 'tcx>>
{
fn visit_after_early_statement_effect(
&mut self,
- _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>,
+ _analysis: &mut MaybeRequiresStorage<'a, 'tcx>,
state: &DenseBitSet<Local>,
_statement: &Statement<'tcx>,
loc: Location,
@@ -901,7 +916,7 @@ fn visit_after_early_statement_effect(
fn visit_after_early_terminator_effect(
&mut self,
- _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>,
+ _analysis: &mut MaybeRequiresStorage<'a, 'tcx>,
state: &DenseBitSet<Local>,
_terminator: &Terminator<'tcx>,
loc: Location,
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
index 73bd2d0..b4b4d04 100644
--- a/compiler/rustc_mir_transform/src/coverage/mappings.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -91,7 +91,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
// When debugging flag `-Zcoverage-options=no-mir-spans` is set, we need
// to give the same treatment to _all_ functions, because `llvm-cov`
// seems to ignore functions that don't have any ordinary code spans.
- if let Some(span) = hir_info.fn_sig_span_extended {
+ if let Some(span) = hir_info.fn_sig_span {
code_mappings.push(CodeMapping { span, bcb: START_BCB });
}
} else {
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index f2e8f9e..702c62e 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -268,9 +268,9 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
struct ExtractedHirInfo {
function_source_hash: u64,
is_async_fn: bool,
- /// The span of the function's signature, extended to the start of `body_span`.
+ /// The span of the function's signature, if available.
/// Must have the same context and filename as the body span.
- fn_sig_span_extended: Option<Span>,
+ fn_sig_span: Option<Span>,
body_span: Span,
/// "Holes" are regions within the function body (or its expansions) that
/// should not be included in coverage spans for this function
@@ -308,30 +308,20 @@ fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHir
// The actual signature span is only used if it has the same context and
// filename as the body, and precedes the body.
- let fn_sig_span_extended = maybe_fn_sig
- .map(|fn_sig| fn_sig.span)
- .filter(|&fn_sig_span| {
- let source_map = tcx.sess.source_map();
- let file_idx = |span: Span| source_map.lookup_source_file_idx(span.lo());
+ let fn_sig_span = maybe_fn_sig.map(|fn_sig| fn_sig.span).filter(|&fn_sig_span| {
+ let source_map = tcx.sess.source_map();
+ let file_idx = |span: Span| source_map.lookup_source_file_idx(span.lo());
- fn_sig_span.eq_ctxt(body_span)
- && fn_sig_span.hi() <= body_span.lo()
- && file_idx(fn_sig_span) == file_idx(body_span)
- })
- // If so, extend it to the start of the body span.
- .map(|fn_sig_span| fn_sig_span.with_hi(body_span.lo()));
+ fn_sig_span.eq_ctxt(body_span)
+ && fn_sig_span.hi() <= body_span.lo()
+ && file_idx(fn_sig_span) == file_idx(body_span)
+ });
let function_source_hash = hash_mir_source(tcx, hir_body);
let hole_spans = extract_hole_spans_from_hir(tcx, hir_body);
- ExtractedHirInfo {
- function_source_hash,
- is_async_fn,
- fn_sig_span_extended,
- body_span,
- hole_spans,
- }
+ ExtractedHirInfo { function_source_hash, is_async_fn, fn_sig_span, body_span, hole_spans }
}
fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx hir::Body<'tcx>) -> u64 {
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index f57a158..ec76076 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,11 +1,8 @@
-use std::collections::VecDeque;
-use std::iter;
-
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::mir;
use rustc_middle::ty::TyCtxt;
use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
-use tracing::{debug, debug_span, instrument};
+use tracing::instrument;
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
use crate::coverage::spans::from_mir::{Hole, RawSpanFromMir, SpanFromMir};
@@ -42,12 +39,12 @@ pub(super) fn extract_refined_covspans<'tcx>(
return;
}
- // Also add the adjusted function signature span, if available.
+ // Also add the function signature span, if available.
// Otherwise, add a fake span at the start of the body, to avoid an ugly
// gap between the start of the body and the first real span.
// FIXME: Find a more principled way to solve this problem.
covspans.push(SpanFromMir::for_fn_sig(
- hir_info.fn_sig_span_extended.unwrap_or_else(|| body_span.shrink_to_lo()),
+ hir_info.fn_sig_span.unwrap_or_else(|| body_span.shrink_to_lo()),
));
// First, perform the passes that need macro information.
@@ -83,24 +80,17 @@ pub(super) fn extract_refined_covspans<'tcx>(
holes.sort_by(|a, b| compare_spans(a.span, b.span));
holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b));
- // Split the covspans into separate buckets that don't overlap any holes.
- let buckets = divide_spans_into_buckets(covspans, &holes);
+ // Discard any span that overlaps with a hole.
+ discard_spans_overlapping_holes(&mut covspans, &holes);
- for covspans in buckets {
- let _span = debug_span!("processing bucket", ?covspans).entered();
+ // Perform more refinement steps after holes have been dealt with.
+ let mut covspans = remove_unwanted_overlapping_spans(covspans);
+ covspans.dedup_by(|b, a| a.merge_if_eligible(b));
- let mut covspans = remove_unwanted_overlapping_spans(covspans);
- debug!(?covspans, "after removing overlaps");
-
- // Do one last merge pass, to simplify the output.
- covspans.dedup_by(|b, a| a.merge_if_eligible(b));
- debug!(?covspans, "after merge");
-
- code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| {
- // Each span produced by the refiner represents an ordinary code region.
- mappings::CodeMapping { span, bcb }
- }));
- }
+ code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| {
+ // Each span produced by the refiner represents an ordinary code region.
+ mappings::CodeMapping { span, bcb }
+ }));
}
/// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate
@@ -142,52 +132,36 @@ fn shrink_visible_macro_spans(tcx: TyCtxt<'_>, covspans: &mut Vec<SpanFromMir>)
}
}
-/// Uses the holes to divide the given covspans into buckets, such that:
-/// - No span in any hole overlaps a bucket (discarding spans if necessary).
-/// - The spans in each bucket are strictly after all spans in previous buckets,
-/// and strictly before all spans in subsequent buckets.
+/// Discard all covspans that overlap a hole.
///
-/// The lists of covspans and holes must be sorted.
-/// The resulting buckets are sorted relative to each other, and each bucket's
-/// contents are sorted.
-#[instrument(level = "debug")]
-fn divide_spans_into_buckets(input_covspans: Vec<Covspan>, holes: &[Hole]) -> Vec<Vec<Covspan>> {
- debug_assert!(input_covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
+/// The lists of covspans and holes must be sorted, and any holes that overlap
+/// with each other must have already been merged.
+fn discard_spans_overlapping_holes(covspans: &mut Vec<Covspan>, holes: &[Hole]) {
+ debug_assert!(covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
debug_assert!(holes.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
+ debug_assert!(holes.array_windows().all(|[a, b]| !a.span.overlaps_or_adjacent(b.span)));
- // Now we're ready to start grouping spans into buckets separated by holes.
+ let mut curr_hole = 0usize;
+ let mut overlaps_hole = |covspan: &Covspan| -> bool {
+ while let Some(hole) = holes.get(curr_hole) {
+ // Both lists are sorted, so we can permanently skip any holes that
+ // end before the start of the current span.
+ if hole.span.hi() <= covspan.span.lo() {
+ curr_hole += 1;
+ continue;
+ }
- let mut input_covspans = VecDeque::from(input_covspans);
+ return hole.span.overlaps(covspan.span);
+ }
- // For each hole:
- // - Identify the spans that are entirely or partly before the hole.
- // - Discard any that overlap with the hole.
- // - Add the remaining identified spans to the corresponding bucket.
- let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>();
- for (hole, bucket) in holes.iter().zip(&mut buckets) {
- bucket.extend(
- drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi())
- .filter(|c| !c.span.overlaps(hole.span)),
- );
- }
+ // No holes left, so this covspan doesn't overlap with any holes.
+ false
+ };
- // Any remaining spans form their own final bucket, after the final hole.
- // (If there were no holes, this will just be all of the initial spans.)
- buckets.push(Vec::from(input_covspans));
-
- buckets
+ covspans.retain(|covspan| !overlaps_hole(covspan));
}
-/// Similar to `.drain(..)`, but stops just before it would remove an item not
-/// satisfying the predicate.
-fn drain_front_while<'a, T>(
- queue: &'a mut VecDeque<T>,
- mut pred_fn: impl FnMut(&T) -> bool,
-) -> impl Iterator<Item = T> {
- iter::from_fn(move || queue.pop_front_if(|x| pred_fn(x)))
-}
-
-/// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines"
+/// Takes a list of sorted spans extracted from MIR, and "refines"
/// those spans by removing spans that overlap in unwanted ways.
#[instrument(level = "debug")]
fn remove_unwanted_overlapping_spans(sorted_spans: Vec<Covspan>) -> Vec<Covspan> {
@@ -227,19 +201,21 @@ struct Covspan {
}
impl Covspan {
- /// If `self` and `other` can be merged (i.e. they have the same BCB),
- /// mutates `self.span` to also include `other.span` and returns true.
+ /// If `self` and `other` can be merged, mutates `self.span` to also
+ /// include `other.span` and returns true.
///
- /// Note that compatible covspans can be merged even if their underlying
- /// spans are not overlapping/adjacent; any space between them will also be
- /// part of the merged covspan.
+ /// Two covspans can be merged if they have the same BCB, and they are
+ /// overlapping or adjacent.
fn merge_if_eligible(&mut self, other: &Self) -> bool {
- if self.bcb != other.bcb {
- return false;
- }
+ let eligible_for_merge =
+ |a: &Self, b: &Self| (a.bcb == b.bcb) && a.span.overlaps_or_adjacent(b.span);
- self.span = self.span.to(other.span);
- true
+ if eligible_for_merge(self, other) {
+ self.span = self.span.to(other.span);
+ true
+ } else {
+ false
+ }
}
}
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index a2103a0..99b95e7 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -23,7 +23,7 @@
use rustc_mir_dataflow::value_analysis::{
Map, PlaceIndex, State, TrackElem, ValueOrPlace, debug_with_context,
};
-use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor};
+use rustc_mir_dataflow::{Analysis, ResultsVisitor, visit_reachable_results};
use rustc_span::DUMMY_SP;
use tracing::{debug, debug_span, instrument};
@@ -61,13 +61,14 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let map = Map::new(tcx, body, place_limit);
// Perform the actual dataflow analysis.
- let analysis = ConstAnalysis::new(tcx, body, map);
- let mut results =
- debug_span!("analyze").in_scope(|| analysis.iterate_to_fixpoint(tcx, body, None));
+ let mut const_ = debug_span!("analyze")
+ .in_scope(|| ConstAnalysis::new(tcx, body, map).iterate_to_fixpoint(tcx, body, None));
// Collect results and patch the body afterwards.
let mut visitor = Collector::new(tcx, &body.local_decls);
- debug_span!("collect").in_scope(|| results.visit_reachable_with(body, &mut visitor));
+ debug_span!("collect").in_scope(|| {
+ visit_reachable_results(body, &mut const_.analysis, &const_.results, &mut visitor)
+ });
let mut patch = visitor.patch;
debug_span!("patch").in_scope(|| patch.visit_body_preserves_cfg(body));
}
@@ -959,10 +960,10 @@ fn try_write_constant<'tcx>(
}
impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> {
- #[instrument(level = "trace", skip(self, results, statement))]
+ #[instrument(level = "trace", skip(self, analysis, statement))]
fn visit_after_early_statement_effect(
&mut self,
- results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
+ analysis: &mut ConstAnalysis<'_, 'tcx>,
state: &State<FlatSet<Scalar>>,
statement: &Statement<'tcx>,
location: Location,
@@ -972,8 +973,8 @@ fn visit_after_early_statement_effect(
OperandCollector {
state,
visitor: self,
- ecx: &mut results.analysis.ecx,
- map: &results.analysis.map,
+ ecx: &mut analysis.ecx,
+ map: &analysis.map,
}
.visit_rvalue(rvalue, location);
}
@@ -981,10 +982,10 @@ fn visit_after_early_statement_effect(
}
}
- #[instrument(level = "trace", skip(self, results, statement))]
+ #[instrument(level = "trace", skip(self, analysis, statement))]
fn visit_after_primary_statement_effect(
&mut self,
- results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
+ analysis: &mut ConstAnalysis<'_, 'tcx>,
state: &State<FlatSet<Scalar>>,
statement: &Statement<'tcx>,
location: Location,
@@ -994,12 +995,9 @@ fn visit_after_primary_statement_effect(
// Don't overwrite the assignment if it already uses a constant (to keep the span).
}
StatementKind::Assign(box (place, _)) => {
- if let Some(value) = self.try_make_constant(
- &mut results.analysis.ecx,
- place,
- state,
- &results.analysis.map,
- ) {
+ if let Some(value) =
+ self.try_make_constant(&mut analysis.ecx, place, state, &analysis.map)
+ {
self.patch.assignments.insert(location, value);
}
}
@@ -1009,18 +1007,13 @@ fn visit_after_primary_statement_effect(
fn visit_after_early_terminator_effect(
&mut self,
- results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
+ analysis: &mut ConstAnalysis<'_, 'tcx>,
state: &State<FlatSet<Scalar>>,
terminator: &Terminator<'tcx>,
location: Location,
) {
- OperandCollector {
- state,
- visitor: self,
- ecx: &mut results.analysis.ecx,
- map: &results.analysis.map,
- }
- .visit_terminator(terminator, location);
+ OperandCollector { state, visitor: self, ecx: &mut analysis.ecx, map: &analysis.map }
+ .visit_terminator(terminator, location);
}
}
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 7395ad4..4c94a6c 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -171,7 +171,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let live = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, Some("MaybeLiveLocals-DestProp"));
let points = DenseLocationMap::new(body);
- let mut live = save_as_intervals(&points, body, live);
+ let mut live = save_as_intervals(&points, body, live.analysis, live.results);
// In order to avoid having to collect data for every single pair of locals in the body, we
// do not allow doing more than one merge for places that are derived from the same local at
diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
index b8cb101..75f351f 100644
--- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
+++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
@@ -235,8 +235,9 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
// When we encounter a DROP of some place P we only care
// about the drop if `P` may be initialized.
let move_data = MoveData::gather_moves(body, tcx, |_| true);
- let maybe_init = MaybeInitializedPlaces::new(tcx, body, &move_data);
- let mut maybe_init = maybe_init.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body);
+ let mut maybe_init = MaybeInitializedPlaces::new(tcx, body, &move_data)
+ .iterate_to_fixpoint(tcx, body, None)
+ .into_results_cursor(body);
let mut block_drop_value_info =
IndexVec::from_elem_n(MovePathIndexAtBlock::Unknown, body.basic_blocks.len());
for (&block, candidates) in &bid_per_block {
diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs
index 2549397..90a7c2e 100644
--- a/compiler/rustc_next_trait_solver/src/delegate.rs
+++ b/compiler/rustc_next_trait_solver/src/delegate.rs
@@ -39,10 +39,6 @@ fn well_formed_goals(
term: <Self::Interner as Interner>::Term,
) -> Option<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>>;
- fn clone_opaque_types_for_query_response(
- &self,
- ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
-
fn make_deduplicated_outlives_constraints(
&self,
) -> Vec<ty::OutlivesPredicate<Self::Interner, <Self::Interner as Interner>::GenericArg>>;
@@ -61,14 +57,6 @@ fn instantiate_canonical_var_with_infer(
span: <Self::Interner as Interner>::Span,
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
) -> <Self::Interner as Interner>::GenericArg;
-
- fn register_hidden_type_in_storage(
- &self,
- opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
- hidden_ty: <Self::Interner as Interner>::Ty,
- span: <Self::Interner as Interner>::Span,
- ) -> Option<<Self::Interner as Interner>::Ty>;
-
fn add_item_bounds_for_hidden_type(
&self,
def_id: <Self::Interner as Interner>::DefId,
@@ -77,7 +65,6 @@ fn add_item_bounds_for_hidden_type(
hidden_ty: <Self::Interner as Interner>::Ty,
goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
);
- fn reset_opaque_types(&self);
fn fetch_eligible_assoc_item(
&self,
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index 101129a..345a272 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -2,21 +2,24 @@
pub(super) mod structural_traits;
+use std::ops::ControlFlow;
+
use derive_where::derive_where;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::{
- self as ty, Interner, TypeFoldable, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
+ self as ty, Interner, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _,
+ TypeVisitor, TypingMode, Upcast as _, elaborate,
};
use tracing::{debug, instrument};
-use super::has_only_region_constraints;
use super::trait_goals::TraitGoalProvenVia;
+use super::{has_only_region_constraints, inspect};
use crate::delegate::SolverDelegate;
use crate::solve::inspect::ProbeKind;
use crate::solve::{
BuiltinImplSource, CandidateSource, CanonicalResponse, Certainty, EvalCtxt, Goal, GoalSource,
- MaybeCause, NoSolution, QueryResult,
+ MaybeCause, NoSolution, ParamEnvSource, QueryResult,
};
enum AliasBoundKind {
@@ -49,18 +52,6 @@ pub(super) trait GoalKind<D, I = <D as SolverDelegate>::Interner>:
fn trait_def_id(self, cx: I) -> I::DefId;
- /// Try equating an assumption predicate against a goal's predicate. If it
- /// holds, then execute the `then` callback, which should do any additional
- /// work, then produce a response (typically by executing
- /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
- fn probe_and_match_goal_against_assumption(
- ecx: &mut EvalCtxt<'_, D>,
- source: CandidateSource<I>,
- goal: Goal<I, Self>,
- assumption: I::Clause,
- then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
- ) -> Result<Candidate<I>, NoSolution>;
-
/// Consider a clause, which consists of a "assumption" and some "requirements",
/// to satisfy a goal. If the requirements hold, then attempt to satisfy our
/// goal by equating it with the assumption.
@@ -119,6 +110,67 @@ fn consider_additional_alias_assumptions(
alias_ty: ty::AliasTy<I>,
) -> Vec<Candidate<I>>;
+ fn probe_and_consider_param_env_candidate(
+ ecx: &mut EvalCtxt<'_, D>,
+ goal: Goal<I, Self>,
+ assumption: I::Clause,
+ ) -> Result<Candidate<I>, NoSolution> {
+ Self::fast_reject_assumption(ecx, goal, assumption)?;
+
+ ecx.probe(|candidate: &Result<Candidate<I>, NoSolution>| match candidate {
+ Ok(candidate) => inspect::ProbeKind::TraitCandidate {
+ source: candidate.source,
+ result: Ok(candidate.result),
+ },
+ Err(NoSolution) => inspect::ProbeKind::TraitCandidate {
+ source: CandidateSource::ParamEnv(ParamEnvSource::Global),
+ result: Err(NoSolution),
+ },
+ })
+ .enter(|ecx| {
+ Self::match_assumption(ecx, goal, assumption)?;
+ let source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?;
+ Ok(Candidate {
+ source,
+ result: ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)?,
+ })
+ })
+ }
+
+ /// Try equating an assumption predicate against a goal's predicate. If it
+ /// holds, then execute the `then` callback, which should do any additional
+ /// work, then produce a response (typically by executing
+ /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
+ fn probe_and_match_goal_against_assumption(
+ ecx: &mut EvalCtxt<'_, D>,
+ source: CandidateSource<I>,
+ goal: Goal<I, Self>,
+ assumption: I::Clause,
+ then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
+ ) -> Result<Candidate<I>, NoSolution> {
+ Self::fast_reject_assumption(ecx, goal, assumption)?;
+
+ ecx.probe_trait_candidate(source).enter(|ecx| {
+ Self::match_assumption(ecx, goal, assumption)?;
+ then(ecx)
+ })
+ }
+
+ /// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`]
+ /// and `DefId`.
+ fn fast_reject_assumption(
+ ecx: &mut EvalCtxt<'_, D>,
+ goal: Goal<I, Self>,
+ assumption: I::Clause,
+ ) -> Result<(), NoSolution>;
+
+ /// Relate the goal and assumption.
+ fn match_assumption(
+ ecx: &mut EvalCtxt<'_, D>,
+ goal: Goal<I, Self>,
+ assumption: I::Clause,
+ ) -> Result<(), NoSolution>;
+
fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
@@ -500,14 +552,8 @@ fn assemble_param_env_candidates<G: GoalKind<D>>(
goal: Goal<I, G>,
candidates: &mut Vec<Candidate<I>>,
) {
- for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
- candidates.extend(G::probe_and_consider_implied_clause(
- self,
- CandidateSource::ParamEnv(i),
- goal,
- assumption,
- [],
- ));
+ for assumption in goal.param_env.caller_bounds().iter() {
+ candidates.extend(G::probe_and_consider_param_env_candidate(self, goal, assumption));
}
}
@@ -943,4 +989,88 @@ pub(super) fn assemble_and_merge_candidates<G: GoalKind<D>>(
}
}
}
+
+ /// Compute whether a param-env assumption is global or non-global after normalizing it.
+ ///
+ /// This is necessary because, for example, given:
+ ///
+ /// ```ignore,rust
+ /// where
+ /// T: Trait<Assoc = u32>,
+ /// i32: From<T::Assoc>,
+ /// ```
+ ///
+ /// The `i32: From<T::Assoc>` bound is non-global before normalization, but is global after.
+ /// Since the old trait solver normalized param-envs eagerly, we want to emulate this
+ /// behavior lazily.
+ fn characterize_param_env_assumption(
+ &mut self,
+ param_env: I::ParamEnv,
+ assumption: I::Clause,
+ ) -> Result<CandidateSource<I>, NoSolution> {
+ // FIXME: This should be fixed, but it also requires changing the behavior
+ // in the old solver which is currently relied on.
+ if assumption.has_bound_vars() {
+ return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal));
+ }
+
+ match assumption.visit_with(&mut FindParamInClause { ecx: self, param_env }) {
+ ControlFlow::Break(Err(NoSolution)) => Err(NoSolution),
+ ControlFlow::Break(Ok(())) => Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)),
+ ControlFlow::Continue(()) => Ok(CandidateSource::ParamEnv(ParamEnvSource::Global)),
+ }
+ }
+}
+
+struct FindParamInClause<'a, 'b, D: SolverDelegate<Interner = I>, I: Interner> {
+ ecx: &'a mut EvalCtxt<'b, D>,
+ param_env: I::ParamEnv,
+}
+
+impl<D, I> TypeVisitor<I> for FindParamInClause<'_, '_, D, I>
+where
+ D: SolverDelegate<Interner = I>,
+ I: Interner,
+{
+ type Result = ControlFlow<Result<(), NoSolution>>;
+
+ fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+ self.ecx.enter_forall(t.clone(), |ecx, v| {
+ v.visit_with(&mut FindParamInClause { ecx, param_env: self.param_env })
+ })
+ }
+
+ fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
+ let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else {
+ return ControlFlow::Break(Err(NoSolution));
+ };
+
+ if let ty::Placeholder(_) = ty.kind() {
+ ControlFlow::Break(Ok(()))
+ } else {
+ ty.super_visit_with(self)
+ }
+ }
+
+ fn visit_const(&mut self, ct: I::Const) -> Self::Result {
+ let Ok(ct) = self.ecx.structurally_normalize_const(self.param_env, ct) else {
+ return ControlFlow::Break(Err(NoSolution));
+ };
+
+ if let ty::ConstKind::Placeholder(_) = ct.kind() {
+ ControlFlow::Break(Ok(()))
+ } else {
+ ct.super_visit_with(self)
+ }
+ }
+
+ fn visit_region(&mut self, r: I::Region) -> Self::Result {
+ match self.ecx.eager_resolve_region(r).kind() {
+ ty::ReStatic | ty::ReError(_) => ControlFlow::Continue(()),
+ ty::ReVar(_) | ty::RePlaceholder(_) => ControlFlow::Break(Ok(())),
+ ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReBound(..) => {
+ unreachable!()
+ }
+ }
+ }
}
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 5edc777..84a83d7 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -36,39 +36,38 @@ fn trait_def_id(self, _: I) -> I::DefId {
self.def_id()
}
- fn probe_and_match_goal_against_assumption(
+ fn fast_reject_assumption(
ecx: &mut EvalCtxt<'_, D>,
- source: rustc_type_ir::solve::CandidateSource<I>,
goal: Goal<I, Self>,
- assumption: <I as Interner>::Clause,
- then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
- ) -> Result<Candidate<I>, NoSolution> {
+ assumption: I::Clause,
+ ) -> Result<(), NoSolution> {
if let Some(host_clause) = assumption.as_host_effect_clause() {
if host_clause.def_id() == goal.predicate.def_id()
&& host_clause.constness().satisfies(goal.predicate.constness)
{
- if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+ if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args,
host_clause.skip_binder().trait_ref.args,
) {
- return Err(NoSolution);
+ return Ok(());
}
-
- ecx.probe_trait_candidate(source).enter(|ecx| {
- let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
- ecx.eq(
- goal.param_env,
- goal.predicate.trait_ref,
- assumption_trait_pred.trait_ref,
- )?;
- then(ecx)
- })
- } else {
- Err(NoSolution)
}
- } else {
- Err(NoSolution)
}
+
+ Err(NoSolution)
+ }
+
+ fn match_assumption(
+ ecx: &mut EvalCtxt<'_, D>,
+ goal: Goal<I, Self>,
+ assumption: I::Clause,
+ ) -> Result<(), NoSolution> {
+ let host_clause = assumption.as_host_effect_clause().unwrap();
+
+ let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
+ ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
+
+ Ok(())
}
/// Register additional assumptions for aliases corresponding to `~const` item bounds.
@@ -124,7 +123,7 @@ fn consider_additional_alias_assumptions(
fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
- impl_def_id: <I as Interner>::DefId,
+ impl_def_id: I::DefId,
) -> Result<Candidate<I>, NoSolution> {
let cx = ecx.cx();
@@ -178,7 +177,7 @@ fn consider_impl_candidate(
fn consider_error_guaranteed_candidate(
ecx: &mut EvalCtxt<'_, D>,
- _guar: <I as Interner>::ErrorGuaranteed,
+ _guar: I::ErrorGuaranteed,
) -> Result<Candidate<I>, NoSolution> {
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index dded84f..36f6880 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -56,7 +56,10 @@ pub(super) fn canonicalize_goal<T: TypeFoldable<I>>(
&self,
goal: Goal<I, T>,
) -> (Vec<I::GenericArg>, CanonicalInput<I, T>) {
- let opaque_types = self.delegate.clone_opaque_types_for_query_response();
+ // We only care about one entry per `OpaqueTypeKey` here,
+ // so we only canonicalize the lookup table and ignore
+ // duplicate entries.
+ let opaque_types = self.delegate.clone_opaque_types_lookup_table();
let (goal, opaque_types) =
(goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate));
@@ -129,12 +132,14 @@ pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
(Certainty::Yes, NestedNormalizationGoals(goals))
}
_ => {
- let certainty = shallow_certainty.unify_with(goals_certainty);
+ let certainty = shallow_certainty.and(goals_certainty);
(certainty, NestedNormalizationGoals::empty())
}
};
- if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty {
+ if let Certainty::Maybe(cause @ MaybeCause::Overflow { keep_constraints: false, .. }) =
+ certainty
+ {
// If we have overflow, it's probable that we're substituting a type
// into itself infinitely and any partial substitutions in the query
// response are probably not useful anyways, so just return an empty
@@ -190,6 +195,7 @@ pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
debug!(?num_non_region_vars, "too many inference variables -> overflow");
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
suggest_increasing_limit: true,
+ keep_constraints: false,
}));
}
}
@@ -241,19 +247,15 @@ fn compute_external_query_constraints(
Default::default()
};
- ExternalConstraintsData {
- region_constraints,
- opaque_types: self
- .delegate
- .clone_opaque_types_for_query_response()
- .into_iter()
- // Only return *newly defined* opaque types.
- .filter(|(a, _)| {
- self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
- })
- .collect(),
- normalization_nested_goals,
- }
+ // We only return *newly defined* opaque types from canonical queries.
+ //
+ // Constraints for any existing opaque types are already tracked by changes
+ // to the `var_values`.
+ let opaque_types = self
+ .delegate
+ .clone_opaque_types_added_since(self.initial_opaque_types_storage_num_entries);
+
+ ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals }
}
/// After calling a canonical query, we apply the constraints returned
@@ -432,7 +434,16 @@ fn register_region_constraints(
fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) {
for &(key, ty) in opaque_types {
let prev = self.delegate.register_hidden_type_in_storage(key, ty, self.origin_span);
- assert_eq!(prev, None);
+ // We eagerly resolve inference variables when computing the query response.
+ // This can cause previously distinct opaque type keys to now be structurally equal.
+ //
+ // To handle this, we store any duplicate entries in a separate list to check them
+ // at the end of typeck/borrowck. We could alternatively eagerly equate the hidden
+ // types here. However, doing so is difficult as it may result in nested goals and
+ // any errors may make it harder to track the control flow for diagnostics.
+ if let Some(prev) = prev {
+ self.delegate.add_duplicate_opaque_type(key, prev, self.origin_span);
+ }
}
}
}
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 6dd5542..fc5dad9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -14,7 +14,7 @@
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
TypingMode,
};
-use tracing::{instrument, trace};
+use tracing::{debug, instrument, trace};
use super::has_only_region_constraints;
use crate::coherence;
@@ -23,8 +23,7 @@
use crate::solve::search_graph::SearchGraph;
use crate::solve::{
CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind, GoalSource,
- HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryInput,
- QueryResult,
+ HasChanged, NestedNormalizationGoals, NoSolution, QueryInput, QueryResult,
};
pub(super) mod canonical;
@@ -99,8 +98,6 @@ pub struct EvalCtxt<'a, D, I = <D as SolverDelegate>::Interner>
current_goal_kind: CurrentGoalKind,
pub(super) var_values: CanonicalVarValues<I>,
- predefined_opaques_in_body: I::PredefinedOpaques,
-
/// The highest universe index nameable by the caller.
///
/// When we enter a new binder inside of the query we create new universes
@@ -111,6 +108,10 @@ pub struct EvalCtxt<'a, D, I = <D as SolverDelegate>::Interner>
/// if we have a coinductive cycle and because that's the only way we can return
/// new placeholders to the caller.
pub(super) max_input_universe: ty::UniverseIndex,
+ /// The opaque types from the canonical input. We only need to return opaque types
+ /// which have been added to the storage while evaluating this goal.
+ pub(super) initial_opaque_types_storage_num_entries:
+ <D::Infcx as InferCtxtLike>::OpaqueTypeStorageEntries,
pub(super) search_graph: &'a mut SearchGraph<D>,
@@ -305,10 +306,8 @@ pub(super) fn enter_root<R>(
// Only relevant when canonicalizing the response,
// which we don't do within this evaluation context.
- predefined_opaques_in_body: delegate
- .cx()
- .mk_predefined_opaques_in_body(PredefinedOpaquesData::default()),
max_input_universe: ty::UniverseIndex::ROOT,
+ initial_opaque_types_storage_num_entries: Default::default(),
variables: Default::default(),
var_values: CanonicalVarValues::dummy(),
current_goal_kind: CurrentGoalKind::Misc,
@@ -342,16 +341,34 @@ fn enter_canonical<R>(
canonical_goal_evaluation: &mut ProofTreeBuilder<D>,
f: impl FnOnce(&mut EvalCtxt<'_, D>, Goal<I, I::Predicate>) -> R,
) -> R {
- let (ref delegate, input, var_values) =
- SolverDelegate::build_with_canonical(cx, &canonical_input);
+ let (ref delegate, input, var_values) = D::build_with_canonical(cx, &canonical_input);
+ for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
+ let prev = delegate.register_hidden_type_in_storage(key, ty, I::Span::dummy());
+ // It may be possible that two entries in the opaque type storage end up
+ // with the same key after resolving contained inference variables.
+ //
+ // We could put them in the duplicate list but don't have to. The opaques we
+ // encounter here are already tracked in the caller, so there's no need to
+ // also store them here. We'd take them out when computing the query response
+ // and then discard them, as they're already present in the input.
+ //
+ // Ideally we'd drop duplicate opaque type definitions when computing
+ // the canonical input. This is more annoying to implement and may cause a
+ // perf regression, so we do it inside of the query for now.
+ if let Some(prev) = prev {
+ debug!(?key, ?ty, ?prev, "ignore duplicate in `opaque_types_storage`");
+ }
+ }
+
+ let initial_opaque_types_storage_num_entries = delegate.opaque_types_storage_num_entries();
let mut ecx = EvalCtxt {
delegate,
variables: canonical_input.canonical.variables,
var_values,
current_goal_kind: CurrentGoalKind::from_query_input(cx, input),
- predefined_opaques_in_body: input.predefined_opaques_in_body,
max_input_universe: canonical_input.canonical.max_universe,
+ initial_opaque_types_storage_num_entries,
search_graph,
nested_goals: Default::default(),
origin_span: I::Span::dummy(),
@@ -359,15 +376,6 @@ fn enter_canonical<R>(
inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values),
};
- for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
- let prev = ecx.delegate.register_hidden_type_in_storage(key, ty, ecx.origin_span);
- assert_eq!(prev, None);
- }
-
- if !ecx.nested_goals.is_empty() {
- panic!("prepopulating opaque types shouldn't add goals: {:?}", ecx.nested_goals);
- }
-
let result = f(&mut ecx, input.goal);
ecx.inspect.probe_final_state(ecx.delegate, ecx.max_input_universe);
canonical_goal_evaluation.goal_evaluation_step(ecx.inspect);
@@ -653,7 +661,7 @@ fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution>
Certainty::Yes => {}
Certainty::Maybe(_) => {
self.nested_goals.push((source, with_resolved_vars));
- unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
+ unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
}
}
} else {
@@ -667,7 +675,7 @@ fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution>
Certainty::Yes => {}
Certainty::Maybe(_) => {
self.nested_goals.push((source, goal));
- unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
+ unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
}
}
}
@@ -987,6 +995,14 @@ pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
self.delegate.resolve_vars_if_possible(value)
}
+ pub(super) fn eager_resolve_region(&self, r: I::Region) -> I::Region {
+ if let ty::ReVar(vid) = r.kind() {
+ self.delegate.opportunistic_resolve_lt_var(vid)
+ } else {
+ r
+ }
+ }
+
pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs {
let args = self.delegate.fresh_args_for_item(def_id);
for arg in args.iter() {
@@ -1065,14 +1081,17 @@ pub(super) fn probe_existing_opaque_ty(
&mut self,
key: ty::OpaqueTypeKey<I>,
) -> Option<(ty::OpaqueTypeKey<I>, I::Ty)> {
- let mut matching =
- self.delegate.clone_opaque_types_for_query_response().into_iter().filter(
- |(candidate_key, _)| {
- candidate_key.def_id == key.def_id
- && DeepRejectCtxt::relate_rigid_rigid(self.cx())
- .args_may_unify(candidate_key.args, key.args)
- },
- );
+ // We shouldn't have any duplicate entries when using
+ // this function during `TypingMode::Analysis`.
+ let duplicate_entries = self.delegate.clone_duplicate_opaque_types();
+ assert!(duplicate_entries.is_empty(), "unexpected duplicates: {duplicate_entries:?}");
+ let mut matching = self.delegate.clone_opaque_types_lookup_table().into_iter().filter(
+ |(candidate_key, _)| {
+ candidate_key.def_id == key.def_id
+ && DeepRejectCtxt::relate_rigid_rigid(self.cx())
+ .args_may_unify(candidate_key.args, key.args)
+ },
+ );
let first = matching.next();
let second = matching.next();
assert_eq!(second, None);
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
index 0a9e7fa..ed0cedc 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
@@ -26,32 +26,33 @@ impl<D, I, F, T> ProbeCtxt<'_, '_, D, I, F, T>
I: Interner,
{
pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, D>) -> T) -> T {
- let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self;
+ let ProbeCtxt { ecx: outer, probe_kind, _result } = self;
- let delegate = outer_ecx.delegate;
- let max_input_universe = outer_ecx.max_input_universe;
- let mut nested_ecx = EvalCtxt {
+ let delegate = outer.delegate;
+ let max_input_universe = outer.max_input_universe;
+ let mut nested = EvalCtxt {
delegate,
- variables: outer_ecx.variables,
- var_values: outer_ecx.var_values,
- current_goal_kind: outer_ecx.current_goal_kind,
- predefined_opaques_in_body: outer_ecx.predefined_opaques_in_body,
+ variables: outer.variables,
+ var_values: outer.var_values,
+ current_goal_kind: outer.current_goal_kind,
max_input_universe,
- search_graph: outer_ecx.search_graph,
- nested_goals: outer_ecx.nested_goals.clone(),
- origin_span: outer_ecx.origin_span,
- tainted: outer_ecx.tainted,
- inspect: outer_ecx.inspect.take_and_enter_probe(),
+ initial_opaque_types_storage_num_entries: outer
+ .initial_opaque_types_storage_num_entries,
+ search_graph: outer.search_graph,
+ nested_goals: outer.nested_goals.clone(),
+ origin_span: outer.origin_span,
+ tainted: outer.tainted,
+ inspect: outer.inspect.take_and_enter_probe(),
};
- let r = nested_ecx.delegate.probe(|| {
- let r = f(&mut nested_ecx);
- nested_ecx.inspect.probe_final_state(delegate, max_input_universe);
+ let r = nested.delegate.probe(|| {
+ let r = f(&mut nested);
+ nested.inspect.probe_final_state(delegate, max_input_universe);
r
});
- if !nested_ecx.inspect.is_noop() {
+ if !nested.inspect.is_noop() {
let probe_kind = probe_kind(&r);
- nested_ecx.inspect.probe_kind(probe_kind);
- outer_ecx.inspect = nested_ecx.inspect.finish_probe();
+ nested.inspect.probe_kind(probe_kind);
+ outer.inspect = nested.inspect.finish_probe();
}
r
}
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index c9f4fc6..8173146 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -253,16 +253,18 @@ fn try_merge_responses(
}
fn bail_with_ambiguity(&mut self, responses: &[CanonicalResponse<I>]) -> CanonicalResponse<I> {
- debug_assert!(!responses.is_empty());
- if let Certainty::Maybe(maybe_cause) =
- responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| {
- certainty.unify_with(response.value.certainty)
- })
- {
- self.make_ambiguous_response_no_constraints(maybe_cause)
- } else {
- panic!("expected flounder response to be ambiguous")
- }
+ debug_assert!(responses.len() > 1);
+ let maybe_cause = responses.iter().fold(MaybeCause::Ambiguity, |maybe_cause, response| {
+ // Pull down the certainty of `Certainty::Yes` to ambiguity when combining
+ // these responses, b/c we're combining more than one response and this we
+ // don't know which one applies.
+ let candidate = match response.value.certainty {
+ Certainty::Yes => MaybeCause::Ambiguity,
+ Certainty::Maybe(candidate) => candidate,
+ };
+ maybe_cause.or(candidate)
+ });
+ self.make_ambiguous_response_no_constraints(maybe_cause)
}
/// If we fail to merge responses we flounder and return overflow or ambiguity.
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 400b4ce..b90e34e 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -106,50 +106,48 @@ fn trait_def_id(self, cx: I) -> I::DefId {
self.trait_def_id(cx)
}
- fn probe_and_match_goal_against_assumption(
+ fn fast_reject_assumption(
ecx: &mut EvalCtxt<'_, D>,
- source: CandidateSource<I>,
goal: Goal<I, Self>,
assumption: I::Clause,
- then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
- ) -> Result<Candidate<I>, NoSolution> {
+ ) -> Result<(), NoSolution> {
if let Some(projection_pred) = assumption.as_projection_clause() {
if projection_pred.item_def_id() == goal.predicate.def_id() {
- let cx = ecx.cx();
- if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+ if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.alias.args,
projection_pred.skip_binder().projection_term.args,
) {
- return Err(NoSolution);
+ return Ok(());
}
- ecx.probe_trait_candidate(source).enter(|ecx| {
- let assumption_projection_pred =
- ecx.instantiate_binder_with_infer(projection_pred);
- ecx.eq(
- goal.param_env,
- goal.predicate.alias,
- assumption_projection_pred.projection_term,
- )?;
-
- ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
-
- // Add GAT where clauses from the trait's definition
- // FIXME: We don't need these, since these are the type's own WF obligations.
- ecx.add_goals(
- GoalSource::AliasWellFormed,
- cx.own_predicates_of(goal.predicate.def_id())
- .iter_instantiated(cx, goal.predicate.alias.args)
- .map(|pred| goal.with(cx, pred)),
- );
-
- then(ecx)
- })
- } else {
- Err(NoSolution)
}
- } else {
- Err(NoSolution)
}
+
+ Err(NoSolution)
+ }
+
+ fn match_assumption(
+ ecx: &mut EvalCtxt<'_, D>,
+ goal: Goal<I, Self>,
+ assumption: I::Clause,
+ ) -> Result<(), NoSolution> {
+ let projection_pred = assumption.as_projection_clause().unwrap();
+
+ let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred);
+ ecx.eq(goal.param_env, goal.predicate.alias, assumption_projection_pred.projection_term)?;
+
+ ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
+
+ // Add GAT where clauses from the trait's definition
+ // FIXME: We don't need these, since these are the type's own WF obligations.
+ let cx = ecx.cx();
+ ecx.add_goals(
+ GoalSource::AliasWellFormed,
+ cx.own_predicates_of(goal.predicate.def_id())
+ .iter_instantiated(cx, goal.predicate.alias.args)
+ .map(|pred| goal.with(cx, pred)),
+ );
+
+ Ok(())
}
fn consider_additional_alias_assumptions(
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index d19249d..e3addf8 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -17,7 +17,7 @@
use crate::solve::inspect::ProbeKind;
use crate::solve::{
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
- NoSolution, QueryResult,
+ NoSolution, ParamEnvSource,
};
impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
@@ -125,39 +125,38 @@ fn consider_error_guaranteed_candidate(
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
}
- fn probe_and_match_goal_against_assumption(
+ fn fast_reject_assumption(
ecx: &mut EvalCtxt<'_, D>,
- source: CandidateSource<I>,
goal: Goal<I, Self>,
assumption: I::Clause,
- then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
- ) -> Result<Candidate<I>, NoSolution> {
+ ) -> Result<(), NoSolution> {
if let Some(trait_clause) = assumption.as_trait_clause() {
if trait_clause.def_id() == goal.predicate.def_id()
&& trait_clause.polarity() == goal.predicate.polarity
{
- if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+ if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args,
trait_clause.skip_binder().trait_ref.args,
) {
- return Err(NoSolution);
+ return Ok(());
}
-
- ecx.probe_trait_candidate(source).enter(|ecx| {
- let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
- ecx.eq(
- goal.param_env,
- goal.predicate.trait_ref,
- assumption_trait_pred.trait_ref,
- )?;
- then(ecx)
- })
- } else {
- Err(NoSolution)
}
- } else {
- Err(NoSolution)
}
+
+ Err(NoSolution)
+ }
+
+ fn match_assumption(
+ ecx: &mut EvalCtxt<'_, D>,
+ goal: Goal<I, Self>,
+ assumption: I::Clause,
+ ) -> Result<(), NoSolution> {
+ let trait_clause = assumption.as_trait_clause().unwrap();
+
+ let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
+ ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
+
+ Ok(())
}
fn consider_auto_trait_candidate(
@@ -1253,10 +1252,9 @@ impl<D, I> EvalCtxt<'_, D>
D: SolverDelegate<Interner = I>,
I: Interner,
{
- #[instrument(level = "debug", skip(self, goal), ret)]
+ #[instrument(level = "debug", skip(self), ret)]
pub(super) fn merge_trait_candidates(
&mut self,
- goal: Goal<I, TraitPredicate<I>>,
mut candidates: Vec<Candidate<I>>,
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
if let TypingMode::Coherence = self.typing_mode() {
@@ -1284,21 +1282,9 @@ pub(super) fn merge_trait_candidates(
// If there are non-global where-bounds, prefer where-bounds
// (including global ones) over everything else.
- let has_non_global_where_bounds = candidates.iter().any(|c| match c.source {
- CandidateSource::ParamEnv(idx) => {
- let where_bound = goal.param_env.caller_bounds().get(idx).unwrap();
- let ty::ClauseKind::Trait(trait_pred) = where_bound.kind().skip_binder() else {
- unreachable!("expected trait-bound: {where_bound:?}");
- };
-
- if trait_pred.has_bound_vars() || !trait_pred.is_global() {
- return true;
- }
-
- false
- }
- _ => false,
- });
+ let has_non_global_where_bounds = candidates
+ .iter()
+ .any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)));
if has_non_global_where_bounds {
let where_bounds: Vec<_> = candidates
.iter()
@@ -1331,13 +1317,16 @@ pub(super) fn merge_trait_candidates(
// is still reported as being proven-via the param-env so that rigid projections
// operate correctly. Otherwise, drop all global where-bounds before merging the
// remaining candidates.
- let proven_via =
- if candidates.iter().all(|c| matches!(c.source, CandidateSource::ParamEnv(_))) {
- TraitGoalProvenVia::ParamEnv
- } else {
- candidates.retain(|c| !matches!(c.source, CandidateSource::ParamEnv(_)));
- TraitGoalProvenVia::Misc
- };
+ let proven_via = if candidates
+ .iter()
+ .all(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)))
+ {
+ TraitGoalProvenVia::ParamEnv
+ } else {
+ candidates
+ .retain(|c| !matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)));
+ TraitGoalProvenVia::Misc
+ };
let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect();
if let Some(response) = self.try_merge_responses(&all_candidates) {
@@ -1353,7 +1342,7 @@ pub(super) fn compute_trait_goal(
goal: Goal<I, TraitPredicate<I>>,
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
let candidates = self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All);
- self.merge_trait_candidates(goal, candidates)
+ self.merge_trait_candidates(candidates)
}
fn try_stall_coroutine_witness(
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 3e953e6..f88c157 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -690,8 +690,8 @@
parse_or_in_let_chain = `||` operators are not supported in let chain conditions
-parse_or_pattern_not_allowed_in_fn_parameters = top-level or-patterns are not allowed in function parameters
-parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allowed in `let` bindings
+parse_or_pattern_not_allowed_in_fn_parameters = function parameters require top-level or-patterns in parentheses
+parse_or_pattern_not_allowed_in_let_binding = `let` bindings require top-level or-patterns in parentheses
parse_out_of_range_hex_escape = out of range hex escape
.label = must be a character in the range [\x00-\x7f]
@@ -715,6 +715,16 @@
parse_path_double_colon = path separator must be a double colon
.suggestion = use a double colon instead
+
+parse_path_found_attribute_in_params = `Trait(...)` syntax does not support attributes in parameters
+ .suggestion = remove the attributes
+
+parse_path_found_c_variadic_params = `Trait(...)` syntax does not support c_variadic parameters
+ .suggestion = remove the `...`
+
+parse_path_found_named_params = `Trait(...)` syntax does not support named parameters
+ .suggestion = remove the parameter name
+
parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies
.suggestion = give this argument a name or use an underscore to ignore it
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 9e5c81d..766baf6 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1647,6 +1647,30 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword {
}
#[derive(Diagnostic)]
+#[diag(parse_path_found_named_params)]
+pub(crate) struct FnPathFoundNamedParams {
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = "")]
+ pub named_param_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_path_found_c_variadic_params)]
+pub(crate) struct PathFoundCVariadicParams {
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = "")]
+ pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_path_found_attribute_in_params)]
+pub(crate) struct PathFoundAttributeInParams {
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = "")]
+ pub span: Span,
+}
+
+#[derive(Diagnostic)]
#[diag(parse_path_double_colon)]
pub(crate) struct PathSingleColon {
#[primary_span]
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index f3b5397..2a7910a 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -3828,7 +3828,7 @@ fn recover_ident_into_label(&mut self, ident: Ident) -> Label {
// Convert `label` -> `'label`,
// so that nameres doesn't complain about non-existing label
let label = format!("'{}", ident.name);
- let ident = Ident { name: Symbol::intern(&label), span: ident.span };
+ let ident = Ident::new(Symbol::intern(&label), ident.span);
self.dcx().emit_err(errors::ExpectedLabelFoundIdent {
span: ident.span,
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 4be8a90..babc55c 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2894,7 +2894,7 @@ pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinV
let (mut params, _) = self.parse_paren_comma_seq(|p| {
p.recover_vcs_conflict_marker();
let snapshot = p.create_snapshot_for_diagnostic();
- let param = p.parse_param_general(req_name, first_param).or_else(|e| {
+ let param = p.parse_param_general(req_name, first_param, true).or_else(|e| {
let guar = e.emit();
// When parsing a param failed, we should check to make the span of the param
// not contain '(' before it.
@@ -2922,7 +2922,13 @@ pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinV
/// Parses a single function parameter.
///
/// - `self` is syntactically allowed when `first_param` holds.
- fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResult<'a, Param> {
+ /// - `recover_arg_parse` is used to recover from a failed argument parse.
+ pub(super) fn parse_param_general(
+ &mut self,
+ req_name: ReqName,
+ first_param: bool,
+ recover_arg_parse: bool,
+ ) -> PResult<'a, Param> {
let lo = self.token.span;
let attrs = self.parse_outer_attributes()?;
self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
@@ -2990,12 +2996,13 @@ fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResu
// If this is a C-variadic argument and we hit an error, return the error.
Err(err) if this.token == token::DotDotDot => return Err(err),
Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
- // Recover from attempting to parse the argument as a type without pattern.
- Err(err) => {
+ Err(err) if recover_arg_parse => {
+ // Recover from attempting to parse the argument as a type without pattern.
err.cancel();
this.restore_snapshot(parser_snapshot_before_ty);
this.recover_arg_parse()?
}
+ Err(err) => return Err(err),
}
};
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 1093e4f..9bce2fa 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -15,7 +15,11 @@
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{Parser, Restrictions, TokenType};
-use crate::errors::{self, PathSingleColon, PathTripleColon};
+use crate::ast::{PatKind, TyKind};
+use crate::errors::{
+ self, FnPathFoundNamedParams, PathFoundAttributeInParams, PathFoundCVariadicParams,
+ PathSingleColon, PathTripleColon,
+};
use crate::exp;
use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
@@ -396,7 +400,28 @@ pub(super) fn parse_path_segment(
snapshot = Some(self.create_snapshot_for_diagnostic());
}
- let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) {
+ let dcx = self.dcx();
+ let parse_params_result = self.parse_paren_comma_seq(|p| {
+ let param = p.parse_param_general(|_| false, false, false);
+ param.map(move |param| {
+ if !matches!(param.pat.kind, PatKind::Missing) {
+ dcx.emit_err(FnPathFoundNamedParams {
+ named_param_span: param.pat.span,
+ });
+ }
+ if matches!(param.ty.kind, TyKind::CVarArgs) {
+ dcx.emit_err(PathFoundCVariadicParams { span: param.pat.span });
+ }
+ if !param.attrs.is_empty() {
+ dcx.emit_err(PathFoundAttributeInParams {
+ span: param.attrs[0].span,
+ });
+ }
+ param.ty
+ })
+ });
+
+ let (inputs, _) = match parse_params_result {
Ok(output) => output,
Err(mut error) if prev_token_before_parsing == token::PathSep => {
error.span_label(
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 999e715..9dd064a 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -15,50 +15,13 @@
)]
// tidy-alphabetical-end
+use std::ops::Range;
+
pub use Alignment::*;
pub use Count::*;
pub use Position::*;
use rustc_literal_escaper::{Mode, unescape_unicode};
-// Note: copied from rustc_span
-/// Range inside of a `Span` used for diagnostics when we only have access to relative positions.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub struct InnerSpan {
- pub start: usize,
- pub end: usize,
-}
-
-impl InnerSpan {
- pub fn new(start: usize, end: usize) -> InnerSpan {
- InnerSpan { start, end }
- }
-}
-
-/// The location and before/after width of a character whose width has changed from its source code
-/// representation
-#[derive(Copy, Clone, PartialEq, Eq)]
-pub struct InnerWidthMapping {
- /// Index of the character in the source
- pub position: usize,
- /// The inner width in characters
- pub before: usize,
- /// The transformed width in characters
- pub after: usize,
-}
-
-impl InnerWidthMapping {
- pub fn new(position: usize, before: usize, after: usize) -> InnerWidthMapping {
- InnerWidthMapping { position, before, after }
- }
-}
-
-/// Whether the input string is a literal. If yes, it contains the inner width mappings.
-#[derive(Clone, PartialEq, Eq)]
-enum InputStringKind {
- NotALiteral,
- Literal { width_mappings: Vec<InnerWidthMapping> },
-}
-
/// The type of format string that we are parsing.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ParseMode {
@@ -68,15 +31,6 @@ pub enum ParseMode {
InlineAsm,
}
-#[derive(Copy, Clone)]
-struct InnerOffset(usize);
-
-impl InnerOffset {
- fn to(self, end: InnerOffset) -> InnerSpan {
- InnerSpan::new(self.0, end.0)
- }
-}
-
/// A piece is a portion of the format string which represents the next part
/// to emit. These are emitted as a stream by the `Parser` class.
#[derive(Clone, Debug, PartialEq)]
@@ -89,13 +43,13 @@ pub enum Piece<'a> {
}
/// Representation of an argument specification.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
pub struct Argument<'a> {
/// Where to find this argument
pub position: Position<'a>,
/// The span of the position indicator. Includes any whitespace in implicit
/// positions (`{ }`).
- pub position_span: InnerSpan,
+ pub position_span: Range<usize>,
/// How to format the argument
pub format: FormatSpec<'a>,
}
@@ -125,12 +79,12 @@ pub fn is_identifier(&self) -> bool {
}
/// Specification for the formatting of an argument in the format string.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
pub struct FormatSpec<'a> {
/// Optionally specified character to fill alignment with.
pub fill: Option<char>,
/// Span of the optionally specified fill character.
- pub fill_span: Option<InnerSpan>,
+ pub fill_span: Option<Range<usize>>,
/// Optionally specified alignment.
pub align: Alignment,
/// The `+` or `-` flag.
@@ -144,21 +98,21 @@ pub struct FormatSpec<'a> {
/// The integer precision to use.
pub precision: Count<'a>,
/// The span of the precision formatting flag (for diagnostics).
- pub precision_span: Option<InnerSpan>,
+ pub precision_span: Option<Range<usize>>,
/// The string width requested for the resulting format.
pub width: Count<'a>,
/// The span of the width formatting flag (for diagnostics).
- pub width_span: Option<InnerSpan>,
+ pub width_span: Option<Range<usize>>,
/// The descriptor string representing the name of the format desired for
/// this argument, this can be empty or any number of characters, although
/// it is required to be one word.
pub ty: &'a str,
/// The span of the descriptor string (for diagnostics).
- pub ty_span: Option<InnerSpan>,
+ pub ty_span: Option<Range<usize>>,
}
/// Enum describing where an argument for a format can be located.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
pub enum Position<'a> {
/// The argument is implied to be located at an index
ArgumentImplicitlyIs(usize),
@@ -210,12 +164,12 @@ pub enum DebugHex {
/// A count is used for the precision and width parameters of an integer, and
/// can reference either an argument or a literal integer.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
pub enum Count<'a> {
/// The count is specified explicitly.
CountIs(u16),
/// The count is specified by the argument with the given name.
- CountIsName(&'a str, InnerSpan),
+ CountIsName(&'a str, Range<usize>),
/// The count is specified by the argument at the given index.
CountIsParam(usize),
/// The count is specified by a star (like in `{:.*}`) that refers to the argument at the given index.
@@ -228,8 +182,8 @@ pub struct ParseError {
pub description: String,
pub note: Option<String>,
pub label: String,
- pub span: InnerSpan,
- pub secondary_label: Option<(String, InnerSpan)>,
+ pub span: Range<usize>,
+ pub secondary_label: Option<(String, Range<usize>)>,
pub suggestion: Suggestion,
}
@@ -240,12 +194,12 @@ pub enum Suggestion {
UsePositional,
/// Remove `r#` from identifier:
/// `format!("{r#foo}")` -> `format!("{foo}")`
- RemoveRawIdent(InnerSpan),
+ RemoveRawIdent(Range<usize>),
/// Reorder format parameter:
/// `format!("{foo:?#}")` -> `format!("{foo:#?}")`
/// `format!("{foo:?x}")` -> `format!("{foo:x?}")`
/// `format!("{foo:?X}")` -> `format!("{foo:X?}")`
- ReorderFormatParameter(InnerSpan, String),
+ ReorderFormatParameter(Range<usize>, String),
}
/// The parser structure for interpreting the input format string. This is
@@ -256,92 +210,94 @@ pub enum Suggestion {
/// necessary there's probably lots of room for improvement performance-wise.
pub struct Parser<'a> {
mode: ParseMode,
+ /// Input to be parsed
input: &'a str,
- cur: std::iter::Peekable<std::str::CharIndices<'a>>,
+ /// Tuples of the span in the code snippet (input as written before being unescaped), the pos in input, and the char in input
+ input_vec: Vec<(Range<usize>, usize, char)>,
+ /// Index into input_vec
+ input_vec_index: usize,
/// Error messages accumulated during parsing
pub errors: Vec<ParseError>,
/// Current position of implicit positional argument pointer
pub curarg: usize,
- /// `Some(raw count)` when the string is "raw", used to position spans correctly
- style: Option<usize>,
/// Start and end byte offset of every successfully parsed argument
- pub arg_places: Vec<InnerSpan>,
- /// Characters whose length has been changed from their in-code representation
- width_map: Vec<InnerWidthMapping>,
+ pub arg_places: Vec<Range<usize>>,
/// Span of the last opening brace seen, used for error reporting
- last_opening_brace: Option<InnerSpan>,
- /// Whether the source string is comes from `println!` as opposed to `format!` or `print!`
- append_newline: bool,
+ last_open_brace: Option<Range<usize>>,
/// Whether this formatting string was written directly in the source. This controls whether we
/// can use spans to refer into it and give better error messages.
/// N.B: This does _not_ control whether implicit argument captures can be used.
pub is_source_literal: bool,
+ /// Index to the end of the literal snippet
+ end_of_snippet: usize,
/// Start position of the current line.
cur_line_start: usize,
/// Start and end byte offset of every line of the format string. Excludes
/// newline characters and leading whitespace.
- pub line_spans: Vec<InnerSpan>,
+ pub line_spans: Vec<Range<usize>>,
}
impl<'a> Iterator for Parser<'a> {
type Item = Piece<'a>;
fn next(&mut self) -> Option<Piece<'a>> {
- if let Some(&(pos, c)) = self.cur.peek() {
- match c {
+ if let Some(&(Range { start, end }, idx, ch)) = self.input_vec.get(self.input_vec_index) {
+ match ch {
'{' => {
- let curr_last_brace = self.last_opening_brace;
- let byte_pos = self.to_span_index(pos);
- let lbrace_end = InnerOffset(byte_pos.0 + self.to_span_width(pos));
- self.last_opening_brace = Some(byte_pos.to(lbrace_end));
- self.cur.next();
- if self.consume('{') {
- self.last_opening_brace = curr_last_brace;
-
- Some(Piece::Lit(self.string(pos + 1)))
+ self.input_vec_index += 1;
+ if let Some(&(_, i, '{')) = self.input_vec.get(self.input_vec_index) {
+ self.input_vec_index += 1;
+ // double open brace escape: "{{"
+ // next state after this is either end-of-input or seen-a-brace
+ Some(Piece::Lit(self.string(i)))
} else {
- let arg = self.argument(lbrace_end);
- if let Some(rbrace_pos) = self.consume_closing_brace(&arg) {
+ // single open brace
+ self.last_open_brace = Some(start..end);
+ let arg = self.argument();
+ if let Some(close_brace_range) = self.consume_closing_brace(&arg) {
if self.is_source_literal {
- let lbrace_byte_pos = self.to_span_index(pos);
- let rbrace_byte_pos = self.to_span_index(rbrace_pos);
-
- let width = self.to_span_width(rbrace_pos);
-
- self.arg_places.push(
- lbrace_byte_pos.to(InnerOffset(rbrace_byte_pos.0 + width)),
- );
+ self.arg_places.push(start..close_brace_range.end);
}
- } else if let Some(&(_, maybe)) = self.cur.peek() {
- match maybe {
+ } else if let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) {
+ match c {
'?' => self.suggest_format_debug(),
- '<' | '^' | '>' => self.suggest_format_align(maybe),
- _ => self.suggest_positional_arg_instead_of_captured_arg(arg),
+ '<' | '^' | '>' => self.suggest_format_align(c),
+ _ => {
+ self.suggest_positional_arg_instead_of_captured_arg(arg.clone())
+ }
}
}
Some(Piece::NextArgument(Box::new(arg)))
}
}
'}' => {
- self.cur.next();
- if self.consume('}') {
- Some(Piece::Lit(self.string(pos + 1)))
+ self.input_vec_index += 1;
+ if let Some(&(_, i, '}')) = self.input_vec.get(self.input_vec_index) {
+ self.input_vec_index += 1;
+ // double close brace escape: "}}"
+ // next state after this is either end-of-input or start
+ Some(Piece::Lit(self.string(i)))
} else {
- let err_pos = self.to_span_index(pos);
- self.err_with_note(
- "unmatched `}` found",
- "unmatched `}`",
- "if you intended to print `}`, you can escape it using `}}`",
- err_pos.to(err_pos),
- );
+ // error: single close brace without corresponding open brace
+ self.errors.push(ParseError {
+ description: "unmatched `}` found".into(),
+ note: Some(
+ "if you intended to print `}`, you can escape it using `}}`".into(),
+ ),
+ label: "unmatched `}`".into(),
+ span: start..end,
+ secondary_label: None,
+ suggestion: Suggestion::None,
+ });
None
}
}
- _ => Some(Piece::Lit(self.string(pos))),
+ _ => Some(Piece::Lit(self.string(idx))),
}
} else {
+ // end of input
if self.is_source_literal {
- let span = self.span(self.cur_line_start, self.input.len());
+ let span = self.cur_line_start..self.end_of_snippet;
if self.line_spans.last() != Some(&span) {
self.line_spans.push(span);
}
@@ -352,71 +308,104 @@ fn next(&mut self) -> Option<Piece<'a>> {
}
impl<'a> Parser<'a> {
- /// Creates a new parser for the given format string
+ /// Creates a new parser for the given unescaped input string and
+ /// optional code snippet (the input as written before being unescaped),
+ /// where `style` is `Some(nr_hashes)` when the snippet is a raw string with that many hashes.
+ /// If the input comes via `println` or `panic`, then it has a newline already appended,
+ /// which is reflected in the `appended_newline` parameter.
pub fn new(
- s: &'a str,
+ input: &'a str,
style: Option<usize>,
snippet: Option<String>,
- append_newline: bool,
+ appended_newline: bool,
mode: ParseMode,
- ) -> Parser<'a> {
- let input_string_kind = find_width_map_from_snippet(s, snippet, style);
- let (width_map, is_source_literal) = match input_string_kind {
- InputStringKind::Literal { width_mappings } => (width_mappings, true),
- InputStringKind::NotALiteral => (Vec::new(), false),
+ ) -> Self {
+ let quote_offset = style.map_or(1, |nr_hashes| nr_hashes + 2);
+
+ let (is_source_literal, end_of_snippet, pre_input_vec) = if let Some(snippet) = snippet {
+ if let Some(nr_hashes) = style {
+ // snippet is a raw string, which starts with 'r', a number of hashes, and a quote
+ // and ends with a quote and the same number of hashes
+ (true, snippet.len() - nr_hashes - 1, vec![])
+ } else {
+ // snippet is not a raw string
+ if snippet.starts_with('"') {
+ // snippet looks like an ordinary string literal
+ // check whether it is the escaped version of input
+ let without_quotes = &snippet[1..snippet.len() - 1];
+ let (mut ok, mut vec) = (true, vec![]);
+ let mut chars = input.chars();
+ unescape_unicode(without_quotes, Mode::Str, &mut |range, res| match res {
+ Ok(ch) if ok && chars.next().is_some_and(|c| ch == c) => {
+ vec.push((range, ch));
+ }
+ _ => {
+ ok = false;
+ vec = vec![];
+ }
+ });
+ let end = vec.last().map(|(r, _)| r.end).unwrap_or(0);
+ if ok {
+ if appended_newline {
+ if chars.as_str() == "\n" {
+ vec.push((end..end + 1, '\n'));
+ (true, 1 + end, vec)
+ } else {
+ (false, snippet.len(), vec![])
+ }
+ } else if chars.as_str() == "" {
+ (true, 1 + end, vec)
+ } else {
+ (false, snippet.len(), vec![])
+ }
+ } else {
+ (false, snippet.len(), vec![])
+ }
+ } else {
+ // snippet is not a raw string and does not start with '"'
+ (false, snippet.len(), vec![])
+ }
+ }
+ } else {
+ // snippet is None
+ (false, input.len() - if appended_newline { 1 } else { 0 }, vec![])
+ };
+
+ let input_vec: Vec<(Range<usize>, usize, char)> = if pre_input_vec.is_empty() {
+ // Snippet is *not* input before unescaping, so spans pointing at it will be incorrect.
+ // This can happen with proc macros that respan generated literals.
+ input
+ .char_indices()
+ .map(|(idx, c)| {
+ let i = idx + quote_offset;
+ (i..i + c.len_utf8(), idx, c)
+ })
+ .collect()
+ } else {
+ // Snippet is input before unescaping
+ input
+ .char_indices()
+ .zip(pre_input_vec)
+ .map(|((i, c), (r, _))| (r.start + quote_offset..r.end + quote_offset, i, c))
+ .collect()
};
Parser {
mode,
- input: s,
- cur: s.char_indices().peekable(),
+ input,
+ input_vec,
+ input_vec_index: 0,
errors: vec![],
curarg: 0,
- style,
arg_places: vec![],
- width_map,
- last_opening_brace: None,
- append_newline,
+ last_open_brace: None,
is_source_literal,
- cur_line_start: 0,
+ end_of_snippet,
+ cur_line_start: quote_offset,
line_spans: vec![],
}
}
- /// Notifies of an error. The message doesn't actually need to be of type
- /// String, but I think it does when this eventually uses conditions so it
- /// might as well start using it now.
- fn err(&mut self, description: impl Into<String>, label: impl Into<String>, span: InnerSpan) {
- self.errors.push(ParseError {
- description: description.into(),
- note: None,
- label: label.into(),
- span,
- secondary_label: None,
- suggestion: Suggestion::None,
- });
- }
-
- /// Notifies of an error. The message doesn't actually need to be of type
- /// String, but I think it does when this eventually uses conditions so it
- /// might as well start using it now.
- fn err_with_note(
- &mut self,
- description: impl Into<String>,
- label: impl Into<String>,
- note: impl Into<String>,
- span: InnerSpan,
- ) {
- self.errors.push(ParseError {
- description: description.into(),
- note: Some(note.into()),
- label: label.into(),
- span,
- secondary_label: None,
- suggestion: Suggestion::None,
- });
- }
-
/// Optionally consumes the specified character. If the character is not at
/// the current position, then the current iterator isn't moved and `false` is
/// returned, otherwise the character is consumed and `true` is returned.
@@ -428,94 +417,56 @@ fn consume(&mut self, c: char) -> bool {
/// the current position, then the current iterator isn't moved and `None` is
/// returned, otherwise the character is consumed and the current position is
/// returned.
- fn consume_pos(&mut self, c: char) -> Option<usize> {
- if let Some(&(pos, maybe)) = self.cur.peek() {
- if c == maybe {
- self.cur.next();
- return Some(pos);
+ fn consume_pos(&mut self, ch: char) -> Option<(Range<usize>, usize)> {
+ if let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) {
+ if ch == *c {
+ self.input_vec_index += 1;
+ return Some((r.clone(), *i));
}
}
None
}
- fn remap_pos(&self, mut pos: usize) -> InnerOffset {
- for width in &self.width_map {
- if pos > width.position {
- pos += width.before - width.after;
- } else if pos == width.position && width.after == 0 {
- pos += width.before;
- } else {
- break;
- }
- }
-
- InnerOffset(pos)
- }
-
- fn to_span_index(&self, pos: usize) -> InnerOffset {
- // This handles the raw string case, the raw argument is the number of #
- // in r###"..."### (we need to add one because of the `r`).
- let raw = self.style.map_or(0, |raw| raw + 1);
- let pos = self.remap_pos(pos);
- InnerOffset(raw + pos.0 + 1)
- }
-
- fn to_span_width(&self, pos: usize) -> usize {
- let pos = self.remap_pos(pos);
- match self.width_map.iter().find(|w| w.position == pos.0) {
- Some(w) => w.before,
- None => 1,
- }
- }
-
- fn span(&self, start_pos: usize, end_pos: usize) -> InnerSpan {
- let start = self.to_span_index(start_pos);
- let end = self.to_span_index(end_pos);
- start.to(end)
- }
-
/// Forces consumption of the specified character. If the character is not
/// found, an error is emitted.
- fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option<usize> {
+ fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option<Range<usize>> {
self.ws();
- let pos;
- let description;
-
- if let Some(&(peek_pos, maybe)) = self.cur.peek() {
- if maybe == '}' {
- self.cur.next();
- return Some(peek_pos);
+ let (range, description) = if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index)
+ {
+ if *c == '}' {
+ self.input_vec_index += 1;
+ return Some(r.clone());
}
-
- pos = peek_pos;
- description = format!("expected `}}`, found `{}`", maybe.escape_debug());
+ // or r.clone()?
+ (r.start..r.start, format!("expected `}}`, found `{}`", c.escape_debug()))
} else {
- description = "expected `}` but string was terminated".to_owned();
- // point at closing `"`
- pos = self.input.len() - if self.append_newline { 1 } else { 0 };
- }
+ (
+ // point at closing `"`
+ self.end_of_snippet..self.end_of_snippet,
+ "expected `}` but string was terminated".to_owned(),
+ )
+ };
- let pos = self.to_span_index(pos);
-
- let label = "expected `}`".to_owned();
let (note, secondary_label) = if arg.format.fill == Some('}') {
(
Some("the character `}` is interpreted as a fill character because of the `:` that precedes it".to_owned()),
- arg.format.fill_span.map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)),
+ arg.format.fill_span.clone().map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)),
)
} else {
(
Some("if you intended to print `{`, you can escape it using `{{`".to_owned()),
- self.last_opening_brace.map(|sp| ("because of this opening brace".to_owned(), sp)),
+ self.last_open_brace
+ .clone()
+ .map(|sp| ("because of this opening brace".to_owned(), sp)),
)
};
self.errors.push(ParseError {
description,
note,
- label,
- span: pos.to(pos),
+ label: "expected `}`".to_owned(),
+ span: range.start..range.start,
secondary_label,
suggestion: Suggestion::None,
});
@@ -525,28 +476,30 @@ fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option<usize> {
/// Consumes all whitespace characters until the first non-whitespace character
fn ws(&mut self) {
- while let Some(_) = self.cur.next_if(|&(_, c)| c.is_whitespace()) {}
+ let rest = &self.input_vec[self.input_vec_index..];
+ let step = rest.iter().position(|&(_, _, c)| !c.is_whitespace()).unwrap_or(rest.len());
+ self.input_vec_index += step;
}
/// Parses all of a string which is to be considered a "raw literal" in a
/// format string. This is everything outside of the braces.
fn string(&mut self, start: usize) -> &'a str {
- // we may not consume the character, peek the iterator
- while let Some(&(pos, c)) = self.cur.peek() {
+ while let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) {
match c {
'{' | '}' => {
- return &self.input[start..pos];
+ return &self.input[start..*i];
}
'\n' if self.is_source_literal => {
- self.line_spans.push(self.span(self.cur_line_start, pos));
- self.cur_line_start = pos + 1;
- self.cur.next();
+ self.input_vec_index += 1;
+ self.line_spans.push(self.cur_line_start..r.start);
+ self.cur_line_start = r.end;
}
_ => {
- if self.is_source_literal && pos == self.cur_line_start && c.is_whitespace() {
- self.cur_line_start = pos + c.len_utf8();
+ self.input_vec_index += 1;
+ if self.is_source_literal && r.start == self.cur_line_start && c.is_whitespace()
+ {
+ self.cur_line_start = r.end;
}
- self.cur.next();
}
}
}
@@ -554,15 +507,13 @@ fn string(&mut self, start: usize) -> &'a str {
}
/// Parses an `Argument` structure, or what's contained within braces inside the format string.
- fn argument(&mut self, start: InnerOffset) -> Argument<'a> {
- let pos = self.position();
+ fn argument(&mut self) -> Argument<'a> {
+ let start_idx = self.input_vec_index;
- let end = self
- .cur
- .clone()
- .find(|(_, ch)| !ch.is_whitespace())
- .map_or(start, |(end, _)| self.to_span_index(end));
- let position_span = start.to(end);
+ let position = self.position();
+ self.ws();
+
+ let end_idx = self.input_vec_index;
let format = match self.mode {
ParseMode::Format => self.format(),
@@ -570,16 +521,15 @@ fn argument(&mut self, start: InnerOffset) -> Argument<'a> {
};
// Resolve position after parsing format spec.
- let pos = match pos {
- Some(position) => position,
- None => {
- let i = self.curarg;
- self.curarg += 1;
- ArgumentImplicitlyIs(i)
- }
- };
+ let position = position.unwrap_or_else(|| {
+ let i = self.curarg;
+ self.curarg += 1;
+ ArgumentImplicitlyIs(i)
+ });
- Argument { position: pos, position_span, format }
+ let position_span =
+ self.input_vec_index2range(start_idx).start..self.input_vec_index2range(end_idx).start;
+ Argument { position, position_span, format }
}
/// Parses a positional argument for a format. This could either be an
@@ -590,23 +540,26 @@ fn position(&mut self) -> Option<Position<'a>> {
if let Some(i) = self.integer() {
Some(ArgumentIs(i.into()))
} else {
- match self.cur.peek() {
- Some(&(lo, c)) if rustc_lexer::is_id_start(c) => {
+ match self.input_vec.get(self.input_vec_index) {
+ Some((range, _, c)) if rustc_lexer::is_id_start(*c) => {
+ let start = range.start;
let word = self.word();
// Recover from `r#ident` in format strings.
// FIXME: use a let chain
if word == "r" {
- if let Some((pos, '#')) = self.cur.peek() {
- if self.input[pos + 1..]
- .chars()
- .next()
- .is_some_and(rustc_lexer::is_id_start)
+ if let Some((r, _, '#')) = self.input_vec.get(self.input_vec_index) {
+ if self
+ .input_vec
+ .get(self.input_vec_index + 1)
+ .is_some_and(|(_, _, c)| rustc_lexer::is_id_start(*c))
{
- self.cur.next();
+ self.input_vec_index += 1;
+ let prefix_end = r.end;
let word = self.word();
- let prefix_span = self.span(lo, lo + 2);
- let full_span = self.span(lo, lo + 2 + word.len());
+ let prefix_span = start..prefix_end;
+ let full_span =
+ start..self.input_vec_index2range(self.input_vec_index).start;
self.errors.insert(0, ParseError {
description: "raw identifiers are not supported".to_owned(),
note: Some("identifiers in format strings can be keywords and don't need to be prefixed with `r#`".to_string()),
@@ -622,7 +575,6 @@ fn position(&mut self) -> Option<Position<'a>> {
Some(ArgumentNamed(word))
}
-
// This is an `ArgumentNext`.
// Record the fact and do the resolution after parsing the
// format spec, to make things like `{:.*}` work.
@@ -631,8 +583,16 @@ fn position(&mut self) -> Option<Position<'a>> {
}
}
- fn current_pos(&mut self) -> usize {
- if let Some(&(pos, _)) = self.cur.peek() { pos } else { self.input.len() }
+ fn input_vec_index2pos(&self, index: usize) -> usize {
+ if let Some(&(_, pos, _)) = self.input_vec.get(index) { pos } else { self.input.len() }
+ }
+
+ fn input_vec_index2range(&self, index: usize) -> Range<usize> {
+ if let Some((r, _, _)) = self.input_vec.get(index) {
+ r.clone()
+ } else {
+ self.end_of_snippet..self.end_of_snippet
+ }
}
/// Parses a format specifier at the current position, returning all of the
@@ -658,11 +618,11 @@ fn format(&mut self) -> FormatSpec<'a> {
}
// fill character
- if let Some(&(idx, c)) = self.cur.peek() {
- if let Some((_, '>' | '<' | '^')) = self.cur.clone().nth(1) {
+ if let Some(&(ref r, _, c)) = self.input_vec.get(self.input_vec_index) {
+ if let Some((_, _, '>' | '<' | '^')) = self.input_vec.get(self.input_vec_index + 1) {
+ self.input_vec_index += 1;
spec.fill = Some(c);
- spec.fill_span = Some(self.span(idx, idx + 1));
- self.cur.next();
+ spec.fill_span = Some(r.clone());
}
}
// Alignment
@@ -686,14 +646,14 @@ fn format(&mut self) -> FormatSpec<'a> {
// Width and precision
let mut havewidth = false;
- if self.consume('0') {
+ if let Some((range, _)) = self.consume_pos('0') {
// small ambiguity with '0$' as a format string. In theory this is a
// '0' flag and then an ill-formatted format string with just a '$'
// and no count, but this is better if we instead interpret this as
// no '0' flag and '0$' as the width instead.
- if let Some(end) = self.consume_pos('$') {
+ if let Some((r, _)) = self.consume_pos('$') {
spec.width = CountIsParam(0);
- spec.width_span = Some(self.span(end - 1, end + 1));
+ spec.width_span = Some(range.start..r.end);
havewidth = true;
} else {
spec.zero_pad = true;
@@ -701,15 +661,15 @@ fn format(&mut self) -> FormatSpec<'a> {
}
if !havewidth {
- let start = self.current_pos();
- spec.width = self.count(start);
+ let start_idx = self.input_vec_index;
+ spec.width = self.count();
if spec.width != CountImplied {
- let end = self.current_pos();
- spec.width_span = Some(self.span(start, end));
+ let end = self.input_vec_index2range(self.input_vec_index).start;
+ spec.width_span = Some(self.input_vec_index2range(start_idx).start..end);
}
}
- if let Some(start) = self.consume_pos('.') {
+ if let Some((range, _)) = self.consume_pos('.') {
if self.consume('*') {
// Resolve `CountIsNextParam`.
// We can do this immediately as `position` is resolved later.
@@ -717,13 +677,13 @@ fn format(&mut self) -> FormatSpec<'a> {
self.curarg += 1;
spec.precision = CountIsStar(i);
} else {
- spec.precision = self.count(start + 1);
+ spec.precision = self.count();
}
- let end = self.current_pos();
- spec.precision_span = Some(self.span(start, end));
+ spec.precision_span =
+ Some(range.start..self.input_vec_index2range(self.input_vec_index).start);
}
- let ty_span_start = self.current_pos();
+ let start_idx = self.input_vec_index;
// Optional radix followed by the actual format specifier
if self.consume('x') {
if self.consume('?') {
@@ -739,19 +699,33 @@ fn format(&mut self) -> FormatSpec<'a> {
} else {
spec.ty = "X";
}
- } else if self.consume('?') {
+ } else if let Some((range, _)) = self.consume_pos('?') {
spec.ty = "?";
- if let Some(&(_, maybe)) = self.cur.peek() {
- match maybe {
- '#' | 'x' | 'X' => self.suggest_format_parameter(maybe),
+ if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index) {
+ match c {
+ '#' | 'x' | 'X' => self.errors.insert(
+ 0,
+ ParseError {
+ description: format!("expected `}}`, found `{c}`"),
+ note: None,
+ label: "expected `'}'`".into(),
+ span: r.clone(),
+ secondary_label: None,
+ suggestion: Suggestion::ReorderFormatParameter(
+ range.start..r.end,
+ format!("{c}?"),
+ ),
+ },
+ ),
_ => (),
}
}
} else {
spec.ty = self.word();
if !spec.ty.is_empty() {
- let ty_span_end = self.current_pos();
- spec.ty_span = Some(self.span(ty_span_start, ty_span_end));
+ let start = self.input_vec_index2range(start_idx).start;
+ let end = self.input_vec_index2range(self.input_vec_index).start;
+ spec.ty_span = Some(start..end);
}
}
spec
@@ -779,11 +753,12 @@ fn inline_asm(&mut self) -> FormatSpec<'a> {
return spec;
}
- let ty_span_start = self.current_pos();
+ let start_idx = self.input_vec_index;
spec.ty = self.word();
if !spec.ty.is_empty() {
- let ty_span_end = self.current_pos();
- spec.ty_span = Some(self.span(ty_span_start, ty_span_end));
+ let start = self.input_vec_index2range(start_idx).start;
+ let end = self.input_vec_index2range(self.input_vec_index).start;
+ spec.ty_span = Some(start..end);
}
spec
@@ -792,55 +767,58 @@ fn inline_asm(&mut self) -> FormatSpec<'a> {
/// Parses a `Count` parameter at the current position. This does not check
/// for 'CountIsNextParam' because that is only used in precision, not
/// width.
- fn count(&mut self, start: usize) -> Count<'a> {
+ fn count(&mut self) -> Count<'a> {
if let Some(i) = self.integer() {
if self.consume('$') { CountIsParam(i.into()) } else { CountIs(i) }
} else {
- let tmp = self.cur.clone();
+ let start_idx = self.input_vec_index;
let word = self.word();
if word.is_empty() {
- self.cur = tmp;
CountImplied
- } else if let Some(end) = self.consume_pos('$') {
- let name_span = self.span(start, end);
- CountIsName(word, name_span)
+ } else if let Some((r, _)) = self.consume_pos('$') {
+ CountIsName(word, self.input_vec_index2range(start_idx).start..r.start)
} else {
- self.cur = tmp;
+ self.input_vec_index = start_idx;
CountImplied
}
}
}
- /// Parses a word starting at the current position. A word is the same as
+ /// Parses a word starting at the current position. A word is the same as a
/// Rust identifier, except that it can't start with `_` character.
fn word(&mut self) -> &'a str {
- let start = match self.cur.peek() {
- Some(&(pos, c)) if rustc_lexer::is_id_start(c) => {
- self.cur.next();
- pos
+ let index = self.input_vec_index;
+ match self.input_vec.get(self.input_vec_index) {
+ Some(&(ref r, i, c)) if rustc_lexer::is_id_start(c) => {
+ self.input_vec_index += 1;
+ (r.start, i)
}
_ => {
return "";
}
};
- let mut end = None;
- while let Some(&(pos, c)) = self.cur.peek() {
- if rustc_lexer::is_id_continue(c) {
- self.cur.next();
+ let (err_end, end): (usize, usize) = loop {
+ if let Some(&(ref r, i, c)) = self.input_vec.get(self.input_vec_index) {
+ if rustc_lexer::is_id_continue(c) {
+ self.input_vec_index += 1;
+ } else {
+ break (r.start, i);
+ }
} else {
- end = Some(pos);
- break;
+ break (self.end_of_snippet, self.input.len());
}
- }
- let end = end.unwrap_or(self.input.len());
- let word = &self.input[start..end];
+ };
+
+ let word = &self.input[self.input_vec_index2pos(index)..end];
if word == "_" {
- self.err_with_note(
- "invalid argument name `_`",
- "invalid argument name",
- "argument name cannot be a single underscore",
- self.span(start, end),
- );
+ self.errors.push(ParseError {
+ description: "invalid argument name `_`".into(),
+ note: Some("argument name cannot be a single underscore".into()),
+ label: "invalid argument name".into(),
+ span: self.input_vec_index2range(index).start..err_end,
+ secondary_label: None,
+ suggestion: Suggestion::None,
+ });
}
word
}
@@ -849,9 +827,10 @@ fn integer(&mut self) -> Option<u16> {
let mut cur: u16 = 0;
let mut found = false;
let mut overflow = false;
- let start = self.current_pos();
- while let Some(&(_, c)) = self.cur.peek() {
+ let start_index = self.input_vec_index;
+ while let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) {
if let Some(i) = c.to_digit(10) {
+ self.input_vec_index += 1;
let (tmp, mul_overflow) = cur.overflowing_mul(10);
let (tmp, add_overflow) = tmp.overflowing_add(i as u16);
if mul_overflow || add_overflow {
@@ -859,40 +838,42 @@ fn integer(&mut self) -> Option<u16> {
}
cur = tmp;
found = true;
- self.cur.next();
} else {
break;
}
}
if overflow {
- let end = self.current_pos();
- let overflowed_int = &self.input[start..end];
- self.err(
- format!(
+ let overflowed_int = &self.input[self.input_vec_index2pos(start_index)
+ ..self.input_vec_index2pos(self.input_vec_index)];
+ self.errors.push(ParseError {
+ description: format!(
"integer `{}` does not fit into the type `u16` whose range is `0..={}`",
overflowed_int,
u16::MAX
),
- "integer out of range for `u16`",
- self.span(start, end),
- );
+ note: None,
+ label: "integer out of range for `u16`".into(),
+ span: self.input_vec_index2range(start_index).start
+ ..self.input_vec_index2range(self.input_vec_index).end,
+ secondary_label: None,
+ suggestion: Suggestion::None,
+ });
}
found.then_some(cur)
}
fn suggest_format_debug(&mut self) {
- if let (Some(pos), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
+ if let (Some((range, _)), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
let word = self.word();
- let pos = self.to_span_index(pos);
self.errors.insert(
0,
ParseError {
description: "expected format parameter to occur after `:`".to_owned(),
note: Some(format!("`?` comes after `:`, try `{}:{}` instead", word, "?")),
label: "expected `?` to occur after `:`".to_owned(),
- span: pos.to(pos),
+ span: range,
secondary_label: None,
suggestion: Suggestion::None,
},
@@ -901,15 +882,14 @@ fn suggest_format_debug(&mut self) {
}
fn suggest_format_align(&mut self, alignment: char) {
- if let Some(pos) = self.consume_pos(alignment) {
- let pos = self.to_span_index(pos);
+ if let Some((range, _)) = self.consume_pos(alignment) {
self.errors.insert(
0,
ParseError {
description: "expected format parameter to occur after `:`".to_owned(),
note: None,
label: format!("expected `{}` to occur after `:`", alignment),
- span: pos.to(pos),
+ span: range,
secondary_label: None,
suggestion: Suggestion::None,
},
@@ -923,10 +903,8 @@ fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>)
return;
}
- if let Some(end) = self.consume_pos('.') {
- let byte_pos = self.to_span_index(end);
- let start = InnerOffset(byte_pos.0 + 1);
- let field = self.argument(start);
+ if let Some((_range, _pos)) = self.consume_pos('.') {
+ let field = self.argument();
// We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any
// deeper nesting, or another type of expression, like method calls, are not supported
if !self.consume('}') {
@@ -941,10 +919,7 @@ fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>)
description: "field access isn't supported".to_string(),
note: None,
label: "not supported".to_string(),
- span: InnerSpan::new(
- arg.position_span.start,
- field.position_span.end,
- ),
+ span: arg.position_span.start..field.position_span.end,
secondary_label: None,
suggestion: Suggestion::UsePositional,
},
@@ -957,10 +932,7 @@ fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>)
description: "tuple index access isn't supported".to_string(),
note: None,
label: "not supported".to_string(),
- span: InnerSpan::new(
- arg.position_span.start,
- field.position_span.end,
- ),
+ span: arg.position_span.start..field.position_span.end,
secondary_label: None,
suggestion: Suggestion::UsePositional,
},
@@ -971,164 +943,6 @@ fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>)
}
}
}
-
- fn suggest_format_parameter(&mut self, c: char) {
- let replacement = match c {
- '#' => "#?",
- 'x' => "x?",
- 'X' => "X?",
- _ => return,
- };
- let Some(pos) = self.consume_pos(c) else {
- return;
- };
-
- let span = self.span(pos - 1, pos + 1);
- let pos = self.to_span_index(pos);
-
- self.errors.insert(
- 0,
- ParseError {
- description: format!("expected `}}`, found `{c}`"),
- note: None,
- label: "expected `'}'`".into(),
- span: pos.to(pos),
- secondary_label: None,
- suggestion: Suggestion::ReorderFormatParameter(span, format!("{replacement}")),
- },
- )
- }
-}
-
-/// Finds the indices of all characters that have been processed and differ between the actual
-/// written code (code snippet) and the `InternedString` that gets processed in the `Parser`
-/// in order to properly synthesise the intra-string `Span`s for error diagnostics.
-fn find_width_map_from_snippet(
- input: &str,
- snippet: Option<String>,
- str_style: Option<usize>,
-) -> InputStringKind {
- let snippet = match snippet {
- Some(ref s) if s.starts_with('"') || s.starts_with("r\"") || s.starts_with("r#") => s,
- _ => return InputStringKind::NotALiteral,
- };
-
- if str_style.is_some() {
- return InputStringKind::Literal { width_mappings: Vec::new() };
- }
-
- // Strip quotes.
- let snippet = &snippet[1..snippet.len() - 1];
-
- // Macros like `println` add a newline at the end. That technically doesn't make them "literals" anymore, but it's fine
- // since we will never need to point our spans there, so we lie about it here by ignoring it.
- // Since there might actually be newlines in the source code, we need to normalize away all trailing newlines.
- // If we only trimmed it off the input, `format!("\n")` would cause a mismatch as here we they actually match up.
- // Alternatively, we could just count the trailing newlines and only trim one from the input if they don't match up.
- let input_no_nl = input.trim_end_matches('\n');
- let Some(unescaped) = unescape_string(snippet) else {
- return InputStringKind::NotALiteral;
- };
-
- let unescaped_no_nl = unescaped.trim_end_matches('\n');
-
- if unescaped_no_nl != input_no_nl {
- // The source string that we're pointing at isn't our input, so spans pointing at it will be incorrect.
- // This can for example happen with proc macros that respan generated literals.
- return InputStringKind::NotALiteral;
- }
-
- let mut s = snippet.char_indices();
- let mut width_mappings = vec![];
- while let Some((pos, c)) = s.next() {
- match (c, s.clone().next()) {
- // skip whitespace and empty lines ending in '\\'
- ('\\', Some((_, '\n'))) => {
- let _ = s.next();
- let mut width = 2;
-
- while let Some((_, c)) = s.clone().next() {
- if matches!(c, ' ' | '\n' | '\t') {
- width += 1;
- let _ = s.next();
- } else {
- break;
- }
- }
-
- width_mappings.push(InnerWidthMapping::new(pos, width, 0));
- }
- ('\\', Some((_, 'n' | 't' | 'r' | '0' | '\\' | '\'' | '\"'))) => {
- width_mappings.push(InnerWidthMapping::new(pos, 2, 1));
- let _ = s.next();
- }
- ('\\', Some((_, 'x'))) => {
- // consume `\xAB` literal
- s.nth(2);
- width_mappings.push(InnerWidthMapping::new(pos, 4, 1));
- }
- ('\\', Some((_, 'u'))) => {
- let mut width = 2;
- let _ = s.next();
-
- if let Some((_, next_c)) = s.next() {
- if next_c == '{' {
- // consume up to 6 hexanumeric chars
- let digits_len =
- s.clone().take(6).take_while(|(_, c)| c.is_ascii_hexdigit()).count();
-
- let len_utf8 = s
- .as_str()
- .get(..digits_len)
- .and_then(|digits| u32::from_str_radix(digits, 16).ok())
- .and_then(char::from_u32)
- .map_or(1, char::len_utf8);
-
- // Skip the digits, for chars that encode to more than 1 utf-8 byte
- // exclude as many digits as it is greater than 1 byte
- //
- // So for a 3 byte character, exclude 2 digits
- let required_skips = digits_len.saturating_sub(len_utf8.saturating_sub(1));
-
- // skip '{' and '}' also
- width += required_skips + 2;
-
- s.nth(digits_len);
- } else if next_c.is_ascii_hexdigit() {
- width += 1;
-
- // We suggest adding `{` and `}` when appropriate, accept it here as if
- // it were correct
- let mut i = 0; // consume up to 6 hexanumeric chars
- while let (Some((_, c)), _) = (s.next(), i < 6) {
- if c.is_ascii_hexdigit() {
- width += 1;
- } else {
- break;
- }
- i += 1;
- }
- }
- }
-
- width_mappings.push(InnerWidthMapping::new(pos, width, 1));
- }
- _ => {}
- }
- }
-
- InputStringKind::Literal { width_mappings }
-}
-
-fn unescape_string(string: &str) -> Option<String> {
- let mut buf = String::new();
- let mut ok = true;
- unescape_unicode(string, Mode::Str, &mut |_, unescaped_char| match unescaped_char {
- Ok(c) => buf.push(c),
- Err(_) => ok = false,
- });
-
- ok.then_some(buf)
}
// Assert a reasonable size for `Piece`
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index cc8a006..e6a7f24 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -41,7 +41,6 @@ fn simple() {
same("}}", &[Lit("}")]);
same("\\}}", &[Lit("\\"), Lit("}")]);
}
-
#[test]
fn invalid01() {
musterr("{")
@@ -79,23 +78,48 @@ fn invalid_precision() {
}
#[test]
-fn format_nothing() {
+fn format_empty() {
same(
"{}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: fmtdflt(),
}))],
);
}
#[test]
+fn format_tab_empty() {
+ let fmt_pre = r###""\t{}""###;
+ let fmt = "\t{}";
+ let parser = Parser::new(fmt, None, Some(fmt_pre.into()), false, ParseMode::Format);
+ assert_eq!(
+ parser.collect::<Vec<Piece<'static>>>(),
+ &[
+ Lit("\t"),
+ NextArgument(Box::new(Argument {
+ position: ArgumentImplicitlyIs(0),
+ position_span: 4..4,
+ format: fmtdflt(),
+ }))
+ ],
+ );
+}
+#[test]
+fn format_open_brace_tab() {
+ let fmt_pre = r###""{\t""###;
+ let fmt = "{\t";
+ let mut parser = Parser::new(fmt, None, Some(fmt_pre.into()), false, ParseMode::Format);
+ let _ = parser.by_ref().collect::<Vec<Piece<'static>>>();
+ assert_eq!(parser.errors[0].span, 4..4);
+}
+#[test]
fn format_position() {
same(
"{3}",
&[NextArgument(Box::new(Argument {
position: ArgumentIs(3),
- position_span: InnerSpan { start: 2, end: 3 },
+ position_span: 2..3,
format: fmtdflt(),
}))],
);
@@ -106,7 +130,7 @@ fn format_position_nothing_else() {
"{3:}",
&[NextArgument(Box::new(Argument {
position: ArgumentIs(3),
- position_span: InnerSpan { start: 2, end: 3 },
+ position_span: 2..3,
format: fmtdflt(),
}))],
);
@@ -117,18 +141,54 @@ fn format_named() {
"{name}",
&[NextArgument(Box::new(Argument {
position: ArgumentNamed("name"),
- position_span: InnerSpan { start: 2, end: 6 },
+ position_span: 2..6,
format: fmtdflt(),
}))],
)
}
#[test]
+fn format_named_space_nothing() {
+ same(
+ "{name} {}",
+ &[
+ NextArgument(Box::new(Argument {
+ position: ArgumentNamed("name"),
+ position_span: 2..6,
+ format: fmtdflt(),
+ })),
+ Lit(" "),
+ NextArgument(Box::new(Argument {
+ position: ArgumentImplicitlyIs(0),
+ position_span: 9..9,
+ format: fmtdflt(),
+ })),
+ ],
+ )
+}
+#[test]
+fn format_raw() {
+ let snippet = r###"r#"assertion `left {op} right` failed"#"###.into();
+ let source = r#"assertion `left {op} right` failed"#;
+
+ let parser = Parser::new(source, Some(1), Some(snippet), true, ParseMode::Format);
+ let expected = &[
+ Lit("assertion `left "),
+ NextArgument(Box::new(Argument {
+ position: ArgumentNamed("op"),
+ position_span: 20..22,
+ format: fmtdflt(),
+ })),
+ Lit(" right` failed"),
+ ];
+ assert_eq!(parser.collect::<Vec<Piece<'static>>>(), expected);
+}
+#[test]
fn format_type() {
same(
"{3:x}",
&[NextArgument(Box::new(Argument {
position: ArgumentIs(3),
- position_span: InnerSpan { start: 2, end: 3 },
+ position_span: 2..3,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -153,7 +213,7 @@ fn format_align_fill() {
"{3:>}",
&[NextArgument(Box::new(Argument {
position: ArgumentIs(3),
- position_span: InnerSpan { start: 2, end: 3 },
+ position_span: 2..3,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -175,10 +235,10 @@ fn format_align_fill() {
"{3:0<}",
&[NextArgument(Box::new(Argument {
position: ArgumentIs(3),
- position_span: InnerSpan { start: 2, end: 3 },
+ position_span: 2..3,
format: FormatSpec {
fill: Some('0'),
- fill_span: Some(InnerSpan::new(4, 5)),
+ fill_span: Some(4..5),
align: AlignLeft,
sign: None,
alternate: false,
@@ -197,10 +257,10 @@ fn format_align_fill() {
"{3:*<abcd}",
&[NextArgument(Box::new(Argument {
position: ArgumentIs(3),
- position_span: InnerSpan { start: 2, end: 3 },
+ position_span: 2..3,
format: FormatSpec {
fill: Some('*'),
- fill_span: Some(InnerSpan::new(4, 5)),
+ fill_span: Some(4..5),
align: AlignLeft,
sign: None,
alternate: false,
@@ -211,7 +271,7 @@ fn format_align_fill() {
precision_span: None,
width_span: None,
ty: "abcd",
- ty_span: Some(InnerSpan::new(6, 10)),
+ ty_span: Some(6..10),
},
}))],
);
@@ -222,7 +282,7 @@ fn format_counts() {
"{:10x}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -234,7 +294,7 @@ fn format_counts() {
precision: CountImplied,
precision_span: None,
width: CountIs(10),
- width_span: Some(InnerSpan { start: 3, end: 5 }),
+ width_span: Some(3..5),
ty: "x",
ty_span: None,
},
@@ -244,7 +304,7 @@ fn format_counts() {
"{:10$.10x}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -254,9 +314,9 @@ fn format_counts() {
zero_pad: false,
debug_hex: None,
precision: CountIs(10),
- precision_span: Some(InnerSpan { start: 6, end: 9 }),
+ precision_span: Some(6..9),
width: CountIsParam(10),
- width_span: Some(InnerSpan { start: 3, end: 6 }),
+ width_span: Some(3..6),
ty: "x",
ty_span: None,
},
@@ -266,7 +326,7 @@ fn format_counts() {
"{1:0$.10x}",
&[NextArgument(Box::new(Argument {
position: ArgumentIs(1),
- position_span: InnerSpan { start: 2, end: 3 },
+ position_span: 2..3,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -276,9 +336,9 @@ fn format_counts() {
zero_pad: false,
debug_hex: None,
precision: CountIs(10),
- precision_span: Some(InnerSpan { start: 6, end: 9 }),
+ precision_span: Some(6..9),
width: CountIsParam(0),
- width_span: Some(InnerSpan { start: 4, end: 6 }),
+ width_span: Some(4..6),
ty: "x",
ty_span: None,
},
@@ -288,7 +348,7 @@ fn format_counts() {
"{:.*x}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(1),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -298,7 +358,7 @@ fn format_counts() {
zero_pad: false,
debug_hex: None,
precision: CountIsStar(0),
- precision_span: Some(InnerSpan { start: 3, end: 5 }),
+ precision_span: Some(3..5),
width: CountImplied,
width_span: None,
ty: "x",
@@ -310,7 +370,7 @@ fn format_counts() {
"{:.10$x}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -321,7 +381,7 @@ fn format_counts() {
debug_hex: None,
precision: CountIsParam(10),
width: CountImplied,
- precision_span: Some(InnerSpan::new(3, 7)),
+ precision_span: Some(3..7),
width_span: None,
ty: "x",
ty_span: None,
@@ -332,7 +392,7 @@ fn format_counts() {
"{:a$.b$?}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -341,10 +401,10 @@ fn format_counts() {
alternate: false,
zero_pad: false,
debug_hex: None,
- precision: CountIsName("b", InnerSpan { start: 6, end: 7 }),
- precision_span: Some(InnerSpan { start: 5, end: 8 }),
- width: CountIsName("a", InnerSpan { start: 3, end: 4 }),
- width_span: Some(InnerSpan { start: 3, end: 5 }),
+ precision: CountIsName("b", 6..7),
+ precision_span: Some(5..8),
+ width: CountIsName("a", 3..4),
+ width_span: Some(3..5),
ty: "?",
ty_span: None,
},
@@ -354,7 +414,7 @@ fn format_counts() {
"{:.4}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -364,7 +424,7 @@ fn format_counts() {
zero_pad: false,
debug_hex: None,
precision: CountIs(4),
- precision_span: Some(InnerSpan { start: 3, end: 5 }),
+ precision_span: Some(3..5),
width: CountImplied,
width_span: None,
ty: "",
@@ -379,7 +439,7 @@ fn format_flags() {
"{:-}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -401,7 +461,7 @@ fn format_flags() {
"{:+#}",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 2 },
+ position_span: 2..2,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -428,7 +488,7 @@ fn format_mixture() {
Lit("abcd "),
NextArgument(Box::new(Argument {
position: ArgumentIs(3),
- position_span: InnerSpan { start: 7, end: 8 },
+ position_span: 7..8,
format: FormatSpec {
fill: None,
fill_span: None,
@@ -455,7 +515,7 @@ fn format_whitespace() {
"{ }",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 3 },
+ position_span: 2..3,
format: fmtdflt(),
}))],
);
@@ -463,8 +523,33 @@ fn format_whitespace() {
"{ }",
&[NextArgument(Box::new(Argument {
position: ArgumentImplicitlyIs(0),
- position_span: InnerSpan { start: 2, end: 4 },
+ position_span: 2..4,
format: fmtdflt(),
}))],
);
}
+#[test]
+fn asm_linespans() {
+ let asm_pre = r###"r"
+ .intel_syntax noprefix
+ nop""###;
+ let asm = r"
+ .intel_syntax noprefix
+ nop";
+ let mut parser = Parser::new(asm, Some(0), Some(asm_pre.into()), false, ParseMode::InlineAsm);
+ assert!(parser.is_source_literal);
+ assert_eq!(
+ parser.by_ref().collect::<Vec<Piece<'static>>>(),
+ &[Lit("\n .intel_syntax noprefix\n nop")]
+ );
+ assert_eq!(parser.line_spans, &[2..2, 11..33, 42..45]);
+}
+#[test]
+fn asm_concat() {
+ let asm_pre = r###"concat!("invalid", "_", "instruction")"###;
+ let asm = "invalid_instruction";
+ let mut parser = Parser::new(asm, None, Some(asm_pre.into()), false, ParseMode::InlineAsm);
+ assert!(!parser.is_source_literal);
+ assert_eq!(parser.by_ref().collect::<Vec<Piece<'static>>>(), &[Lit(asm)]);
+ assert_eq!(parser.line_spans, &[]);
+}
diff --git a/compiler/rustc_pattern_analysis/messages.ftl b/compiler/rustc_pattern_analysis/messages.ftl
index 41a1d95..d3a3107 100644
--- a/compiler/rustc_pattern_analysis/messages.ftl
+++ b/compiler/rustc_pattern_analysis/messages.ftl
@@ -6,6 +6,10 @@
.label = this range doesn't match `{$max}` because `..` is an exclusive range
.suggestion = use an inclusive range instead
+pattern_analysis_mixed_deref_pattern_constructors = mix of deref patterns and normal constructors
+ .deref_pattern_label = matches on the result of dereferencing `{$smart_pointer_ty}`
+ .normal_constructor_label = matches directly on `{$smart_pointer_ty}`
+
pattern_analysis_non_exhaustive_omitted_pattern = some variants are not matched explicitly
.help = ensure that all variants are matched explicitly by adding the suggested match arms
.note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 4ce868f..f7a4931 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -696,6 +696,10 @@ pub enum Constructor<Cx: PatCx> {
F128Range(IeeeFloat<QuadS>, IeeeFloat<QuadS>, RangeEnd),
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
Str(Cx::StrLit),
+ /// Deref patterns (enabled by the `deref_patterns` feature) provide a way of matching on a
+ /// smart pointer ADT through its pointee. They don't directly correspond to ADT constructors,
+ /// and currently are not supported alongside them. Carries the type of the pointee.
+ DerefPattern(Cx::Ty),
/// Constants that must not be matched structurally. They are treated as black boxes for the
/// purposes of exhaustiveness: we must not inspect them, and they don't count towards making a
/// match exhaustive.
@@ -740,6 +744,7 @@ fn clone(&self) -> Self {
Constructor::F64Range(lo, hi, end) => Constructor::F64Range(*lo, *hi, *end),
Constructor::F128Range(lo, hi, end) => Constructor::F128Range(*lo, *hi, *end),
Constructor::Str(value) => Constructor::Str(value.clone()),
+ Constructor::DerefPattern(ty) => Constructor::DerefPattern(ty.clone()),
Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
Constructor::Or => Constructor::Or,
Constructor::Never => Constructor::Never,
@@ -856,6 +861,10 @@ pub(crate) fn is_covered_by(&self, cx: &Cx, other: &Self) -> Result<bool, Cx::Er
}
(Slice(self_slice), Slice(other_slice)) => self_slice.is_covered_by(*other_slice),
+ // Deref patterns only interact with other deref patterns. Prior to usefulness analysis,
+ // we ensure they don't appear alongside any other non-wild non-opaque constructors.
+ (DerefPattern(_), DerefPattern(_)) => true,
+
// Opaque constructors don't interact with anything unless they come from the
// syntactically identical pattern.
(Opaque(self_id), Opaque(other_id)) => self_id == other_id,
@@ -932,6 +941,7 @@ pub(crate) fn fmt_fields(
F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
F128Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
Str(value) => write!(f, "{value:?}")?,
+ DerefPattern(_) => write!(f, "deref!({:?})", fields.next().unwrap())?,
Opaque(..) => write!(f, "<constant pattern>")?,
Or => {
for pat in fields {
@@ -1039,8 +1049,17 @@ pub fn split<'a>(
let mut missing = Vec::new();
// Constructors in `ctors`, except wildcards and opaques.
let mut seen = Vec::new();
+ // If we see a deref pattern, it must be the only non-wildcard non-opaque constructor; we
+ // ensure this prior to analysis.
+ let mut deref_pat_present = false;
for ctor in ctors.cloned() {
match ctor {
+ DerefPattern(..) => {
+ if !deref_pat_present {
+ deref_pat_present = true;
+ present.push(ctor);
+ }
+ }
Opaque(..) => present.push(ctor),
Wildcard => {} // discard wildcards
_ => seen.push(ctor),
@@ -1048,6 +1067,9 @@ pub fn split<'a>(
}
match self {
+ _ if deref_pat_present => {
+ // Deref patterns are the only constructor; nothing is missing.
+ }
ConstructorSet::Struct { empty } => {
if !seen.is_empty() {
present.push(Struct);
diff --git a/compiler/rustc_pattern_analysis/src/errors.rs b/compiler/rustc_pattern_analysis/src/errors.rs
index e60930d..156ba97 100644
--- a/compiler/rustc_pattern_analysis/src/errors.rs
+++ b/compiler/rustc_pattern_analysis/src/errors.rs
@@ -1,5 +1,5 @@
use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic};
-use rustc_macros::{LintDiagnostic, Subdiagnostic};
+use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::Ty;
use rustc_span::Span;
@@ -133,3 +133,15 @@ pub(crate) struct NonExhaustiveOmittedPatternLintOnArm {
pub lint_level: &'static str,
pub lint_name: &'static str,
}
+
+#[derive(Diagnostic)]
+#[diag(pattern_analysis_mixed_deref_pattern_constructors)]
+pub(crate) struct MixedDerefPatternConstructors<'tcx> {
+ #[primary_span]
+ pub spans: Vec<Span>,
+ pub smart_pointer_ty: Ty<'tcx>,
+ #[label(pattern_analysis_deref_pattern_label)]
+ pub deref_pattern_label: Span,
+ #[label(pattern_analysis_normal_constructor_label)]
+ pub normal_constructor_label: Span,
+}
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index 7c12f69..a89d01d 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -269,6 +269,7 @@ fn reveal_and_alloc<'a, 'tcx>(
}
_ => bug!("bad slice pattern {:?} {:?}", ctor, ty),
},
+ DerefPattern(pointee_ty) => reveal_and_alloc(cx, once(pointee_ty.inner())),
Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
| F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing
| PrivateUninhabited | Wildcard => &[],
@@ -296,7 +297,7 @@ pub(crate) fn ctor_arity(&self, ctor: &Constructor<'p, 'tcx>, ty: RevealedTy<'tc
}
_ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"),
},
- Ref => 1,
+ Ref | DerefPattern(_) => 1,
Slice(slice) => slice.arity(),
Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
| F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing
@@ -493,11 +494,15 @@ pub fn lower_pat(&self, pat: &'p Pat<'tcx>) -> DeconstructedPat<'p, 'tcx> {
),
};
}
- PatKind::DerefPattern { .. } => {
- // FIXME(deref_patterns): At least detect that `box _` is irrefutable.
- fields = vec![];
- arity = 0;
- ctor = Opaque(OpaqueId::new());
+ PatKind::DerefPattern { subpattern, .. } => {
+ // NB(deref_patterns): This assumes the deref pattern is matching on a trusted
+ // `DerefPure` type. If the `Deref` impl isn't trusted, exhaustiveness must take
+ // into account that multiple calls to deref may return different results. Hence
+ // multiple deref! patterns cannot be exhaustive together unless each is exhaustive
+ // by itself.
+ fields = vec![self.lower_pat(subpattern).at_index(0)];
+ arity = 1;
+ ctor = DerefPattern(cx.reveal_opaque_ty(subpattern.ty));
}
PatKind::Leaf { subpatterns } | PatKind::Variant { subpatterns, .. } => {
match ty.kind() {
@@ -874,6 +879,7 @@ pub fn print_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> String {
print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap();
s
}
+ DerefPattern(_) => format!("deref!({})", print(&pat.fields[0])),
Slice(slice) => {
let (prefix_len, has_dot_dot) = match slice.kind {
SliceKind::FixedLen(len) => (len, false),
@@ -1100,6 +1106,14 @@ pub fn analyze_match<'p, 'tcx>(
scrut_ty: Ty<'tcx>,
) -> Result<UsefulnessReport<'p, 'tcx>, ErrorGuaranteed> {
let scrut_ty = tycx.reveal_opaque_ty(scrut_ty);
+
+ // The analysis doesn't support deref patterns mixed with normal constructors; error if present.
+ // FIXME(deref_patterns): This only needs to run when a deref pattern was found during lowering.
+ if tycx.tcx.features().deref_patterns() {
+ let pat_column = PatternColumn::new(arms);
+ detect_mixed_deref_pat_ctors(tycx, &pat_column)?;
+ }
+
let scrut_validity = PlaceValidity::from_bool(tycx.known_valid_scrutinee);
let report = compute_match_usefulness(
tycx,
@@ -1119,6 +1133,51 @@ pub fn analyze_match<'p, 'tcx>(
Ok(report)
}
+// FIXME(deref_patterns): Currently it's the responsibility of the frontend (rustc or rust-analyzer)
+// to ensure that deref patterns don't appear in the same column as normal constructors. Deref
+// patterns aren't currently implemented in rust-analyzer, but should they be, the columnwise check
+// here could be made generic and shared between frontends.
+fn detect_mixed_deref_pat_ctors<'p, 'tcx>(
+ cx: &RustcPatCtxt<'p, 'tcx>,
+ column: &PatternColumn<'p, RustcPatCtxt<'p, 'tcx>>,
+) -> Result<(), ErrorGuaranteed> {
+ let Some(&ty) = column.head_ty() else {
+ return Ok(());
+ };
+
+ // Check for a mix of deref patterns and normal constructors.
+ let mut normal_ctor_span = None;
+ let mut deref_pat_span = None;
+ for pat in column.iter() {
+ match pat.ctor() {
+ // The analysis can handle mixing deref patterns with wildcards and opaque patterns.
+ Wildcard | Opaque(_) => {}
+ DerefPattern(_) => deref_pat_span = Some(pat.data().span),
+ // Nothing else can be compared to deref patterns in `Constructor::is_covered_by`.
+ _ => normal_ctor_span = Some(pat.data().span),
+ }
+ }
+ if let Some(normal_constructor_label) = normal_ctor_span
+ && let Some(deref_pattern_label) = deref_pat_span
+ {
+ return Err(cx.tcx.dcx().emit_err(errors::MixedDerefPatternConstructors {
+ spans: vec![deref_pattern_label, normal_constructor_label],
+ smart_pointer_ty: ty.inner(),
+ deref_pattern_label,
+ normal_constructor_label,
+ }));
+ }
+
+ // Specialize and recurse into the patterns' fields.
+ let set = column.analyze_ctors(cx, &ty)?;
+ for ctor in set.present {
+ for specialized_column in column.specialize(cx, &ty, &ctor).iter() {
+ detect_mixed_deref_pat_ctors(cx, specialized_column)?;
+ }
+ }
+ Ok(())
+}
+
struct RecursiveOpaque {
def_id: DefId,
}
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index 11ebbea..53638f2 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -702,6 +702,7 @@
//! - `ui/consts/const_in_pattern`
//! - `ui/rfc-2008-non-exhaustive`
//! - `ui/half-open-range-patterns`
+//! - `ui/pattern/deref-patterns`
//! - probably many others
//!
//! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific
@@ -866,7 +867,8 @@ fn is_known_valid(self) -> bool {
/// inside `&` and union fields where validity is reset to `MaybeInvalid`.
fn specialize<Cx: PatCx>(self, ctor: &Constructor<Cx>) -> Self {
// We preserve validity except when we go inside a reference or a union field.
- if matches!(ctor, Constructor::Ref | Constructor::UnionField) {
+ if matches!(ctor, Constructor::Ref | Constructor::DerefPattern(_) | Constructor::UnionField)
+ {
// Validity of `x: &T` does not imply validity of `*x: T`.
MaybeInvalid
} else {
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 0d56db1..3ae56ce 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -11,7 +11,7 @@
use rustc_data_structures::profiling::QueryInvocationId;
use rustc_data_structures::sharded::{self, ShardedHashMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::{AtomicU64, Lock};
+use rustc_data_structures::sync::{AtomicU64, Lock, is_dyn_thread_safe};
use rustc_data_structures::unord::UnordMap;
use rustc_errors::DiagInner;
use rustc_index::IndexVec;
@@ -124,19 +124,11 @@ pub fn new(
prev_graph: Arc<SerializedDepGraph>,
prev_work_products: WorkProductMap,
encoder: FileEncoder,
- record_graph: bool,
- record_stats: bool,
) -> DepGraph<D> {
let prev_graph_node_count = prev_graph.node_count();
- let current = CurrentDepGraph::new(
- session,
- prev_graph_node_count,
- encoder,
- record_graph,
- record_stats,
- Arc::clone(&prev_graph),
- );
+ let current =
+ CurrentDepGraph::new(session, prev_graph_node_count, encoder, Arc::clone(&prev_graph));
let colors = DepNodeColorMap::new(prev_graph_node_count);
@@ -1052,17 +1044,8 @@ pub fn exec_cache_promotions<Tcx: DepContext>(&self, tcx: Tcx) {
}
}
- pub fn print_incremental_info(&self) {
- if let Some(data) = &self.data {
- data.current.encoder.print_incremental_info(
- data.current.total_read_count.load(Ordering::Relaxed),
- data.current.total_duplicate_read_count.load(Ordering::Relaxed),
- )
- }
- }
-
pub fn finish_encoding(&self) -> FileEncodeResult {
- if let Some(data) = &self.data { data.current.encoder.finish() } else { Ok(0) }
+ if let Some(data) = &self.data { data.current.encoder.finish(&data.current) } else { Ok(0) }
}
pub(crate) fn next_virtual_depnode_index(&self) -> DepNodeIndex {
@@ -1179,8 +1162,8 @@ pub(super) struct CurrentDepGraph<D: Deps> {
/// These are simple counters that are for profiling and
/// debugging and only active with `debug_assertions`.
- total_read_count: AtomicU64,
- total_duplicate_read_count: AtomicU64,
+ pub(super) total_read_count: AtomicU64,
+ pub(super) total_duplicate_read_count: AtomicU64,
}
impl<D: Deps> CurrentDepGraph<D> {
@@ -1188,8 +1171,6 @@ fn new(
session: &Session,
prev_graph_node_count: usize,
encoder: FileEncoder,
- record_graph: bool,
- record_stats: bool,
previous: Arc<SerializedDepGraph>,
) -> Self {
let mut stable_hasher = StableHasher::new();
@@ -1211,14 +1192,7 @@ fn new(
session.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions);
CurrentDepGraph {
- encoder: GraphEncoder::new(
- encoder,
- prev_graph_node_count,
- record_graph,
- record_stats,
- &session.prof,
- previous,
- ),
+ encoder: GraphEncoder::new(session, encoder, prev_graph_node_count, previous),
anon_node_to_index: ShardedHashMap::with_capacity(
// FIXME: The count estimate is off as anon nodes are only a portion of the nodes.
new_node_count_estimate / sharded::shards(),
@@ -1345,6 +1319,7 @@ fn default() -> Self {
// array, using one u32 per entry.
pub(super) struct DepNodeColorMap {
values: IndexVec<SerializedDepNodeIndex, AtomicU32>,
+ sync: bool,
}
const COMPRESSED_NONE: u32 = u32::MAX;
@@ -1353,7 +1328,10 @@ pub(super) struct DepNodeColorMap {
impl DepNodeColorMap {
fn new(size: usize) -> DepNodeColorMap {
debug_assert!(COMPRESSED_RED > DepNodeIndex::MAX_AS_U32);
- DepNodeColorMap { values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect() }
+ DepNodeColorMap {
+ values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(),
+ sync: is_dyn_thread_safe(),
+ }
}
#[inline]
@@ -1362,6 +1340,37 @@ pub(super) fn current(&self, index: SerializedDepNodeIndex) -> Option<DepNodeInd
if value <= DepNodeIndex::MAX_AS_U32 { Some(DepNodeIndex::from_u32(value)) } else { None }
}
+ /// This tries to atomically mark a node green and assign `index` as the new
+ /// index. This returns `Ok` if `index` gets assigned, otherwise it returns
+ /// the alreadly allocated index in `Err`.
+ #[inline]
+ pub(super) fn try_mark_green(
+ &self,
+ prev_index: SerializedDepNodeIndex,
+ index: DepNodeIndex,
+ ) -> Result<(), DepNodeIndex> {
+ let value = &self.values[prev_index];
+ if self.sync {
+ match value.compare_exchange(
+ COMPRESSED_NONE,
+ index.as_u32(),
+ Ordering::Relaxed,
+ Ordering::Relaxed,
+ ) {
+ Ok(_) => Ok(()),
+ Err(v) => Err(DepNodeIndex::from_u32(v)),
+ }
+ } else {
+ let v = value.load(Ordering::Relaxed);
+ if v == COMPRESSED_NONE {
+ value.store(index.as_u32(), Ordering::Relaxed);
+ Ok(())
+ } else {
+ Err(DepNodeIndex::from_u32(v))
+ }
+ }
+ }
+
#[inline]
pub(super) fn get(&self, index: SerializedDepNodeIndex) -> Option<DepNodeColor> {
match self.values[index].load(Ordering::Acquire) {
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index 3a80835..89d1db8 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -12,6 +12,7 @@
pub use graph::{DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result};
pub use query::DepGraphQuery;
use rustc_data_structures::profiling::SelfProfilerRef;
+use rustc_data_structures::sync::DynSync;
use rustc_session::Session;
pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};
use tracing::instrument;
@@ -89,7 +90,7 @@ fn try_load_from_on_disk_cache(self, dep_node: DepNode) {
}
}
-pub trait Deps {
+pub trait Deps: DynSync {
/// Execute the operation with provided dependencies.
fn with_deps<OP, R>(deps: TaskDepsRef<'_>, op: OP) -> R
where
diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs
index 624f4e4..724a013 100644
--- a/compiler/rustc_query_system/src/dep_graph/query.rs
+++ b/compiler/rustc_query_system/src/dep_graph/query.rs
@@ -1,11 +1,11 @@
use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::graph::implementation::{Direction, Graph, INCOMING, NodeIndex};
+use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, LinkedGraph, NodeIndex};
use rustc_index::IndexVec;
use super::{DepNode, DepNodeIndex};
pub struct DepGraphQuery {
- pub graph: Graph<DepNode, ()>,
+ pub graph: LinkedGraph<DepNode, ()>,
pub indices: FxHashMap<DepNode, NodeIndex>,
pub dep_index_to_index: IndexVec<DepNodeIndex, Option<NodeIndex>>,
}
@@ -15,7 +15,7 @@ pub fn new(prev_node_count: usize) -> DepGraphQuery {
let node_count = prev_node_count + prev_node_count / 4;
let edge_count = 6 * node_count;
- let graph = Graph::with_capacity(node_count, edge_count);
+ let graph = LinkedGraph::with_capacity(node_count, edge_count);
let indices = FxHashMap::default();
let dep_index_to_index = IndexVec::new();
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index d2bcde1..f1b609a 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -12,7 +12,7 @@
//! node and edge count are stored at the end of the file, all the arrays can be
//! pre-allocated with the right length.
//!
-//! The encoding of the de-pgraph is generally designed around the fact that fixed-size
+//! The encoding of the dep-graph is generally designed around the fact that fixed-size
//! reads of encoded data are generally faster than variable-sized reads. Ergo we adopt
//! essentially the same varint encoding scheme used in the rmeta format; the edge lists
//! for each node on the graph store a 2-bit integer which is the number of bytes per edge
@@ -34,24 +34,32 @@
//! [`DepKind`], number of edges, and bytes per edge are all bit-packed together, if they fit.
//! If the number of edges in this node does not fit in the bits available in the header, we
//! store it directly after the header with leb128.
+//!
+//! Dep-graph indices are bulk allocated to threads inside `LocalEncoderState`. Having threads
+//! own these indices helps avoid races when they are conditionally used when marking nodes green.
+//! It also reduces congestion on the shared index count.
-use std::iter;
+use std::cell::RefCell;
+use std::cmp::max;
use std::marker::PhantomData;
use std::sync::Arc;
+use std::sync::atomic::Ordering;
+use std::{iter, mem, u64};
use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::outline;
use rustc_data_structures::profiling::SelfProfilerRef;
-use rustc_data_structures::sync::Lock;
+use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal, broadcast};
use rustc_data_structures::unhash::UnhashMap;
-use rustc_index::{Idx, IndexVec};
+use rustc_index::IndexVec;
use rustc_serialize::opaque::mem_encoder::MemEncoder;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use rustc_session::Session;
use tracing::{debug, instrument};
-use super::graph::{DepNodeColor, DepNodeColorMap};
+use super::graph::{CurrentDepGraph, DepNodeColor, DepNodeColorMap};
use super::query::DepGraphQuery;
use super::{DepKind, DepNode, DepNodeIndex, Deps};
use crate::dep_graph::edges::EdgesVec;
@@ -76,6 +84,9 @@ pub struct SerializedDepNodeIndex {}
const DEP_NODE_WIDTH_BITS: usize = DEP_NODE_SIZE / 2;
/// Data for use when recompiling the **current crate**.
+///
+/// There may be unused indices with DEP_KIND_NULL in this graph due to batch allocation of
+/// indices to threads.
#[derive(Debug, Default)]
pub struct SerializedDepGraph {
/// The set of all DepNodes in the graph
@@ -184,26 +195,30 @@ impl SerializedDepGraph {
pub fn decode<D: Deps>(d: &mut MemDecoder<'_>, deps: &D) -> Arc<SerializedDepGraph> {
// The last 16 bytes are the node count and edge count.
debug!("position: {:?}", d.position());
- let (node_count, edge_count) =
- d.with_position(d.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| {
+
+ // `node_max` is the number of indices including empty nodes while `node_count`
+ // is the number of actually encoded nodes.
+ let (node_max, node_count, edge_count) =
+ d.with_position(d.len() - 3 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| {
debug!("position: {:?}", d.position());
+ let node_max = IntEncodedWithFixedSize::decode(d).0 as usize;
let node_count = IntEncodedWithFixedSize::decode(d).0 as usize;
let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize;
- (node_count, edge_count)
+ (node_max, node_count, edge_count)
});
debug!("position: {:?}", d.position());
debug!(?node_count, ?edge_count);
- let graph_bytes = d.len() - (2 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
+ let graph_bytes = d.len() - (3 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
let mut nodes = IndexVec::from_elem_n(
DepNode { kind: D::DEP_KIND_NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) },
- node_count,
+ node_max,
);
- let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_count);
+ let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max);
let mut edge_list_indices =
- IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_count);
+ IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_max);
// This estimation assumes that all of the encoded bytes are for the edge lists or for the
// fixed-size node headers. But that's not necessarily true; if any edge list has a length
@@ -217,7 +232,7 @@ pub fn decode<D: Deps>(d: &mut MemDecoder<'_>, deps: &D) -> Arc<SerializedDepGra
let mut edge_list_data =
Vec::with_capacity(graph_bytes - node_count * size_of::<SerializedNodeHeader<D>>());
- for _index in 0..node_count {
+ for _ in 0..node_count {
// Decode the header for this edge; the header packs together as many of the fixed-size
// fields as possible to limit the number of times we update decoder state.
let node_header =
@@ -263,8 +278,8 @@ pub fn decode<D: Deps>(d: &mut MemDecoder<'_>, deps: &D) -> Arc<SerializedDepGra
for (idx, node) in nodes.iter_enumerated() {
if index[node.kind.as_usize()].insert(node.hash, idx).is_some() {
- // Side effect nodes can have duplicates
- if node.kind != D::DEP_KIND_SIDE_EFFECT {
+ // Empty nodes and side effect nodes can have duplicates
+ if node.kind != D::DEP_KIND_NULL && node.kind != D::DEP_KIND_SIDE_EFFECT {
let name = deps.name(node.kind);
panic!(
"Error: A dep graph node ({name}) does not have an unique index. \
@@ -508,17 +523,32 @@ struct Stat {
edge_counter: u64,
}
-struct EncoderState<D: Deps> {
- previous: Arc<SerializedDepGraph>,
- encoder: FileEncoder,
- total_node_count: usize,
- total_edge_count: usize,
- stats: Option<FxHashMap<DepKind, Stat>>,
-
- mem_encoder: MemEncoder,
+struct LocalEncoderState {
+ next_node_index: u32,
+ remaining_node_index: u32,
+ encoder: MemEncoder,
+ node_count: usize,
+ edge_count: usize,
/// Stores the number of times we've encoded each dep kind.
kind_stats: Vec<u32>,
+}
+
+struct LocalEncoderResult {
+ node_max: u32,
+ node_count: usize,
+ edge_count: usize,
+
+ /// Stores the number of times we've encoded each dep kind.
+ kind_stats: Vec<u32>,
+}
+
+struct EncoderState<D: Deps> {
+ next_node_index: AtomicU64,
+ previous: Arc<SerializedDepGraph>,
+ file: Lock<Option<FileEncoder>>,
+ local: WorkerLocal<RefCell<LocalEncoderState>>,
+ stats: Option<Lock<FxHashMap<DepKind, Stat>>>,
marker: PhantomData<D>,
}
@@ -526,34 +556,63 @@ impl<D: Deps> EncoderState<D> {
fn new(encoder: FileEncoder, record_stats: bool, previous: Arc<SerializedDepGraph>) -> Self {
Self {
previous,
- encoder,
- total_edge_count: 0,
- total_node_count: 0,
- stats: record_stats.then(FxHashMap::default),
- mem_encoder: MemEncoder::new(),
- kind_stats: iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(),
+ next_node_index: AtomicU64::new(0),
+ stats: record_stats.then(|| Lock::new(FxHashMap::default())),
+ file: Lock::new(Some(encoder)),
+ local: WorkerLocal::new(|_| {
+ RefCell::new(LocalEncoderState {
+ next_node_index: 0,
+ remaining_node_index: 0,
+ edge_count: 0,
+ node_count: 0,
+ encoder: MemEncoder::new(),
+ kind_stats: iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(),
+ })
+ }),
marker: PhantomData,
}
}
#[inline]
- fn alloc_index(&mut self) -> DepNodeIndex {
- let index = DepNodeIndex::new(self.total_node_count);
- self.total_node_count += 1;
- index
+ fn next_index(&self, local: &mut LocalEncoderState) -> DepNodeIndex {
+ if local.remaining_node_index == 0 {
+ const COUNT: u32 = 256;
+
+ // We assume that there won't be enough active threads to overflow `u64` from `u32::MAX` here.
+ // This can exceed u32::MAX by at most `N` * `COUNT` where `N` is the thread pool count since
+ // `try_into().unwrap()` will make threads panic when `self.next_node_index` exceeds u32::MAX.
+ local.next_node_index =
+ self.next_node_index.fetch_add(COUNT as u64, Ordering::Relaxed).try_into().unwrap();
+
+ // Check that we'll stay within `u32`
+ local.next_node_index.checked_add(COUNT).unwrap();
+
+ local.remaining_node_index = COUNT;
+ }
+
+ DepNodeIndex::from_u32(local.next_node_index)
+ }
+
+ /// Marks the index previously returned by `next_index` as used.
+ #[inline]
+ fn bump_index(&self, local: &mut LocalEncoderState) {
+ local.remaining_node_index -= 1;
+ local.next_node_index += 1;
+ local.node_count += 1;
}
#[inline]
fn record(
- &mut self,
+ &self,
node: DepNode,
index: DepNodeIndex,
edge_count: usize,
- edges: impl FnOnce(&mut Self) -> Vec<DepNodeIndex>,
+ edges: impl FnOnce(&Self) -> Vec<DepNodeIndex>,
record_graph: &Option<Lock<DepGraphQuery>>,
- ) -> DepNodeIndex {
- self.kind_stats[node.kind.as_usize()] += 1;
- self.total_edge_count += edge_count;
+ local: &mut LocalEncoderState,
+ ) {
+ local.kind_stats[node.kind.as_usize()] += 1;
+ local.edge_count += edge_count;
if let Some(record_graph) = &record_graph {
// Call `edges` before the outlined code to allow the closure to be optimized out.
@@ -568,40 +627,47 @@ fn record(
});
}
- if let Some(stats) = &mut self.stats {
+ if let Some(stats) = &self.stats {
let kind = node.kind;
// Outline the stats code as it's typically disabled and cold.
outline(move || {
+ let mut stats = stats.lock();
let stat =
stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 });
stat.node_counter += 1;
stat.edge_counter += edge_count as u64;
});
}
-
- index
}
#[inline]
- fn flush_mem_encoder(&mut self) {
- let data = &mut self.mem_encoder.data;
+ fn flush_mem_encoder(&self, local: &mut LocalEncoderState) {
+ let data = &mut local.encoder.data;
if data.len() > 64 * 1024 {
- self.encoder.emit_raw_bytes(&data[..]);
+ self.file.lock().as_mut().unwrap().emit_raw_bytes(&data[..]);
data.clear();
}
}
/// Encodes a node to the current graph.
fn encode_node(
- &mut self,
+ &self,
+ index: DepNodeIndex,
node: &NodeInfo,
record_graph: &Option<Lock<DepGraphQuery>>,
- ) -> DepNodeIndex {
- let index = self.alloc_index();
- node.encode::<D>(&mut self.mem_encoder, index);
- self.flush_mem_encoder();
- self.record(node.node, index, node.edges.len(), |_| node.edges[..].to_vec(), record_graph)
+ local: &mut LocalEncoderState,
+ ) {
+ node.encode::<D>(&mut local.encoder, index);
+ self.flush_mem_encoder(&mut *local);
+ self.record(
+ node.node,
+ index,
+ node.edges.len(),
+ |_| node.edges[..].to_vec(),
+ record_graph,
+ &mut *local,
+ );
}
/// Encodes a node that was promoted from the previous graph. It reads the information directly from
@@ -612,16 +678,17 @@ fn encode_node(
/// It expects all edges to already have a new dep node index assigned.
#[inline]
fn encode_promoted_node(
- &mut self,
+ &self,
+ index: DepNodeIndex,
prev_index: SerializedDepNodeIndex,
record_graph: &Option<Lock<DepGraphQuery>>,
colors: &DepNodeColorMap,
- ) -> DepNodeIndex {
- let index = self.alloc_index();
+ local: &mut LocalEncoderState,
+ ) {
let node = self.previous.index_to_node(prev_index);
let fingerprint = self.previous.fingerprint_by_index(prev_index);
let edge_count = NodeInfo::encode_promoted::<D>(
- &mut self.mem_encoder,
+ &mut local.encoder,
node,
index,
fingerprint,
@@ -629,7 +696,7 @@ fn encode_promoted_node(
colors,
&self.previous,
);
- self.flush_mem_encoder();
+ self.flush_mem_encoder(&mut *local);
self.record(
node,
index,
@@ -641,38 +708,60 @@ fn encode_promoted_node(
.collect()
},
record_graph,
+ &mut *local,
);
- index
}
- fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
- let Self {
- mut encoder,
- mem_encoder,
- total_node_count,
- total_edge_count,
- stats: _,
- kind_stats,
- marker: _,
- previous,
- } = self;
+ fn finish(&self, profiler: &SelfProfilerRef, current: &CurrentDepGraph<D>) -> FileEncodeResult {
+ // Prevent more indices from being allocated.
+ self.next_node_index.store(u32::MAX as u64 + 1, Ordering::SeqCst);
- encoder.emit_raw_bytes(&mem_encoder.data);
+ let results = broadcast(|_| {
+ let mut local = self.local.borrow_mut();
- let node_count = total_node_count.try_into().unwrap();
- let edge_count = total_edge_count.try_into().unwrap();
+ // Prevent more indices from being allocated on this thread.
+ local.remaining_node_index = 0;
+
+ let data = mem::replace(&mut local.encoder.data, Vec::new());
+ self.file.lock().as_mut().unwrap().emit_raw_bytes(&data);
+
+ LocalEncoderResult {
+ kind_stats: local.kind_stats.clone(),
+ node_max: local.next_node_index,
+ node_count: local.node_count,
+ edge_count: local.edge_count,
+ }
+ });
+
+ let mut encoder = self.file.lock().take().unwrap();
+
+ let mut kind_stats: Vec<u32> = iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect();
+
+ let mut node_max = 0;
+ let mut node_count = 0;
+ let mut edge_count = 0;
+
+ for result in results {
+ node_max = max(node_max, result.node_max);
+ node_count += result.node_count;
+ edge_count += result.edge_count;
+ for (i, stat) in result.kind_stats.iter().enumerate() {
+ kind_stats[i] += stat;
+ }
+ }
// Encode the number of each dep kind encountered
for count in kind_stats.iter() {
count.encode(&mut encoder);
}
- previous.session_count.checked_add(1).unwrap().encode(&mut encoder);
+ self.previous.session_count.checked_add(1).unwrap().encode(&mut encoder);
- debug!(?node_count, ?edge_count);
+ debug!(?node_max, ?node_count, ?edge_count);
debug!("position: {:?}", encoder.position());
- IntEncodedWithFixedSize(node_count).encode(&mut encoder);
- IntEncodedWithFixedSize(edge_count).encode(&mut encoder);
+ IntEncodedWithFixedSize(node_max.try_into().unwrap()).encode(&mut encoder);
+ IntEncodedWithFixedSize(node_count.try_into().unwrap()).encode(&mut encoder);
+ IntEncodedWithFixedSize(edge_count.try_into().unwrap()).encode(&mut encoder);
debug!("position: {:?}", encoder.position());
// Drop the encoder so that nothing is written after the counts.
let result = encoder.finish();
@@ -681,44 +770,20 @@ fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
// don't need a dependency on rustc_incremental just for that.
profiler.artifact_size("dep_graph", "dep-graph.bin", position as u64);
}
+
+ self.print_incremental_info(current, node_count, edge_count);
+
result
}
-}
-pub(crate) struct GraphEncoder<D: Deps> {
- profiler: SelfProfilerRef,
- status: Lock<Option<EncoderState<D>>>,
- record_graph: Option<Lock<DepGraphQuery>>,
-}
-
-impl<D: Deps> GraphEncoder<D> {
- pub(crate) fn new(
- encoder: FileEncoder,
- prev_node_count: usize,
- record_graph: bool,
- record_stats: bool,
- profiler: &SelfProfilerRef,
- previous: Arc<SerializedDepGraph>,
- ) -> Self {
- let record_graph = record_graph.then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
- let status = Lock::new(Some(EncoderState::new(encoder, record_stats, previous)));
- GraphEncoder { status, record_graph, profiler: profiler.clone() }
- }
-
- pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) {
- if let Some(record_graph) = &self.record_graph {
- f(&record_graph.lock())
- }
- }
-
- pub(crate) fn print_incremental_info(
+ fn print_incremental_info(
&self,
- total_read_count: u64,
- total_duplicate_read_count: u64,
+ current: &CurrentDepGraph<D>,
+ total_node_count: usize,
+ total_edge_count: usize,
) {
- let mut status = self.status.lock();
- let status = status.as_mut().unwrap();
- if let Some(record_stats) = &status.stats {
+ if let Some(record_stats) = &self.stats {
+ let record_stats = record_stats.lock();
let mut stats: Vec<_> = record_stats.values().collect();
stats.sort_by_key(|s| -(s.node_counter as i64));
@@ -730,10 +795,13 @@ pub(crate) fn print_incremental_info(
eprintln!("[incremental] DepGraph Statistics");
eprintln!("{SEPARATOR}");
eprintln!("[incremental]");
- eprintln!("[incremental] Total Node Count: {}", status.total_node_count);
- eprintln!("[incremental] Total Edge Count: {}", status.total_edge_count);
+ eprintln!("[incremental] Total Node Count: {}", total_node_count);
+ eprintln!("[incremental] Total Edge Count: {}", total_edge_count);
if cfg!(debug_assertions) {
+ let total_read_count = current.total_read_count.load(Ordering::Relaxed);
+ let total_duplicate_read_count =
+ current.total_duplicate_read_count.load(Ordering::Relaxed);
eprintln!("[incremental] Total Edge Reads: {total_read_count}");
eprintln!("[incremental] Total Duplicate Edge Reads: {total_duplicate_read_count}");
}
@@ -747,7 +815,7 @@ pub(crate) fn print_incremental_info(
for stat in stats {
let node_kind_ratio =
- (100.0 * (stat.node_counter as f64)) / (status.total_node_count as f64);
+ (100.0 * (stat.node_counter as f64)) / (total_node_count as f64);
let node_kind_avg_edges = (stat.edge_counter as f64) / (stat.node_counter as f64);
eprintln!(
@@ -763,6 +831,35 @@ pub(crate) fn print_incremental_info(
eprintln!("[incremental]");
}
}
+}
+
+pub(crate) struct GraphEncoder<D: Deps> {
+ profiler: SelfProfilerRef,
+ status: EncoderState<D>,
+ record_graph: Option<Lock<DepGraphQuery>>,
+}
+
+impl<D: Deps> GraphEncoder<D> {
+ pub(crate) fn new(
+ sess: &Session,
+ encoder: FileEncoder,
+ prev_node_count: usize,
+ previous: Arc<SerializedDepGraph>,
+ ) -> Self {
+ let record_graph = sess
+ .opts
+ .unstable_opts
+ .query_dep_graph
+ .then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
+ let status = EncoderState::new(encoder, sess.opts.unstable_opts.incremental_info, previous);
+ GraphEncoder { status, record_graph, profiler: sess.prof.clone() }
+ }
+
+ pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) {
+ if let Some(record_graph) = &self.record_graph {
+ f(&record_graph.lock())
+ }
+ }
/// Encodes a node that does not exists in the previous graph.
pub(crate) fn send_new(
@@ -773,7 +870,11 @@ pub(crate) fn send_new(
) -> DepNodeIndex {
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
let node = NodeInfo { node, fingerprint, edges };
- self.status.lock().as_mut().unwrap().encode_node(&node, &self.record_graph)
+ let mut local = self.status.local.borrow_mut();
+ let index = self.status.next_index(&mut *local);
+ self.status.bump_index(&mut *local);
+ self.status.encode_node(index, &node, &self.record_graph, &mut *local);
+ index
}
/// Encodes a node that exists in the previous graph, but was re-executed.
@@ -791,23 +892,24 @@ pub(crate) fn send_and_color(
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
let node = NodeInfo { node, fingerprint, edges };
- let mut status = self.status.lock();
- let status = status.as_mut().unwrap();
+ let mut local = self.status.local.borrow_mut();
- // Check colors inside the lock to avoid racing when `send_promoted` is called concurrently
- // on the same index.
- match colors.get(prev_index) {
- None => {
- let dep_node_index = status.encode_node(&node, &self.record_graph);
- colors.insert(
- prev_index,
- if is_green { DepNodeColor::Green(dep_node_index) } else { DepNodeColor::Red },
- );
- dep_node_index
+ let index = self.status.next_index(&mut *local);
+
+ if is_green {
+ // Use `try_mark_green` to avoid racing when `send_promoted` is called concurrently
+ // on the same index.
+ match colors.try_mark_green(prev_index, index) {
+ Ok(()) => (),
+ Err(dep_node_index) => return dep_node_index,
}
- Some(DepNodeColor::Green(dep_node_index)) => dep_node_index,
- Some(DepNodeColor::Red) => panic!(),
+ } else {
+ colors.insert(prev_index, DepNodeColor::Red);
}
+
+ self.status.bump_index(&mut *local);
+ self.status.encode_node(index, &node, &self.record_graph, &mut *local);
+ index
}
/// Encodes a node that was promoted from the previous graph. It reads the information directly from
@@ -822,26 +924,30 @@ pub(crate) fn send_promoted(
) -> DepNodeIndex {
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
- let mut status = self.status.lock();
- let status = status.as_mut().unwrap();
+ let mut local = self.status.local.borrow_mut();
+ let index = self.status.next_index(&mut *local);
- // Check colors inside the lock to avoid racing when `send_promoted` or `send_and_color`
+ // Use `try_mark_green` to avoid racing when `send_promoted` or `send_and_color`
// is called concurrently on the same index.
- match colors.get(prev_index) {
- None => {
- let dep_node_index =
- status.encode_promoted_node(prev_index, &self.record_graph, colors);
- colors.insert(prev_index, DepNodeColor::Green(dep_node_index));
- dep_node_index
+ match colors.try_mark_green(prev_index, index) {
+ Ok(()) => {
+ self.status.bump_index(&mut *local);
+ self.status.encode_promoted_node(
+ index,
+ prev_index,
+ &self.record_graph,
+ colors,
+ &mut *local,
+ );
+ index
}
- Some(DepNodeColor::Green(dep_node_index)) => dep_node_index,
- Some(DepNodeColor::Red) => panic!(),
+ Err(dep_node_index) => dep_node_index,
}
}
- pub(crate) fn finish(&self) -> FileEncodeResult {
+ pub(crate) fn finish(&self, current: &CurrentDepGraph<D>) -> FileEncodeResult {
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph_finish");
- self.status.lock().take().unwrap().finish(&self.profiler)
+ self.status.finish(&self.profiler, current)
}
}
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index cb32802..3460c53 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -549,7 +549,7 @@ fn build_reduced_graph_for_use_tree(
source = module_path.pop().unwrap();
if rename.is_none() {
// Keep the span of `self`, but the name of `foo`
- ident = Ident { name: source.ident.name, span: self_span };
+ ident = Ident::new(source.ident.name, self_span);
}
}
} else {
@@ -597,7 +597,7 @@ fn build_reduced_graph_for_use_tree(
if let Some(crate_name) = crate_name {
// `crate_name` should not be interpreted as relative.
module_path.push(Segment::from_ident_and_id(
- Ident { name: kw::PathRoot, span: source.ident.span },
+ Ident::new(kw::PathRoot, source.ident.span),
self.r.next_node_id(),
));
source.ident.name = crate_name;
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 7e516d8..4c47e9e 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -2157,13 +2157,24 @@ fn resolve_rustdoc_path(
ns: Namespace,
parent_scope: ParentScope<'ra>,
) -> Option<Res> {
- let mut segments =
- Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident));
- if let Some(segment) = segments.first_mut() {
- if segment.ident.name == kw::Empty {
- segment.ident.name = kw::PathRoot;
- }
- }
+ let segments: Result<Vec<_>, ()> = path_str
+ .split("::")
+ .enumerate()
+ .map(|(i, s)| {
+ let sym = if s.is_empty() {
+ if i == 0 {
+ // For a path like `::a::b`, use `kw::PathRoot` as the leading segment.
+ kw::PathRoot
+ } else {
+ return Err(()); // occurs in cases like `String::`
+ }
+ } else {
+ Symbol::intern(s)
+ };
+ Ok(Segment::from_ident(Ident::with_dummy_span(sym)))
+ })
+ .collect();
+ let Ok(segments) = segments else { return None };
match self.maybe_resolve_path(&segments, Some(ns), &parent_scope, None) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()),
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index f7f354d..47831f2 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -722,6 +722,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
| hir::definitions::DefPathData::Use
| hir::definitions::DefPathData::GlobalAsm
| hir::definitions::DefPathData::MacroNs(..)
+ | hir::definitions::DefPathData::OpaqueLifetime(..)
| hir::definitions::DefPathData::LifetimeNs(..)
| hir::definitions::DefPathData::AnonAssocTy(..) => {
bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data);
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index ab0a802..b621920 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -41,6 +41,7 @@
use crate::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, StableCrateId};
use crate::edition::Edition;
+use crate::source_map::SourceMap;
use crate::symbol::{Symbol, kw, sym};
use crate::{DUMMY_SP, HashStableContext, Span, SpanDecoder, SpanEncoder, with_session_globals};
@@ -907,6 +908,30 @@ pub(crate) fn dollar_crate_name(self) -> Symbol {
pub fn edition(self) -> Edition {
HygieneData::with(|data| data.expn_data(data.outer_expn(self)).edition)
}
+
+ /// Returns whether this context originates in a foreign crate's external macro.
+ ///
+ /// This is used to test whether a lint should not even begin to figure out whether it should
+ /// be reported on the current node.
+ pub fn in_external_macro(self, sm: &SourceMap) -> bool {
+ let expn_data = self.outer_expn_data();
+ match expn_data.kind {
+ ExpnKind::Root
+ | ExpnKind::Desugaring(
+ DesugaringKind::ForLoop
+ | DesugaringKind::WhileLoop
+ | DesugaringKind::OpaqueTy
+ | DesugaringKind::Async
+ | DesugaringKind::Await,
+ ) => false,
+ ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
+ ExpnKind::Macro(MacroKind::Bang, _) => {
+ // Dummy span for the `def_site` means it's an external macro.
+ expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site)
+ }
+ ExpnKind::Macro { .. } => true, // definitely a plugin
+ }
+ }
}
impl fmt::Debug for SyntaxContext {
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 6fcf77e..61c96e6 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -594,28 +594,13 @@ pub fn is_visible(self, sm: &SourceMap) -> bool {
!self.is_dummy() && sm.is_span_accessible(self)
}
- /// Returns whether `span` originates in a foreign crate's external macro.
+ /// Returns whether this span originates in a foreign crate's external macro.
///
/// This is used to test whether a lint should not even begin to figure out whether it should
/// be reported on the current node.
+ #[inline]
pub fn in_external_macro(self, sm: &SourceMap) -> bool {
- let expn_data = self.ctxt().outer_expn_data();
- match expn_data.kind {
- ExpnKind::Root
- | ExpnKind::Desugaring(
- DesugaringKind::ForLoop
- | DesugaringKind::WhileLoop
- | DesugaringKind::OpaqueTy
- | DesugaringKind::Async
- | DesugaringKind::Await,
- ) => false,
- ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
- ExpnKind::Macro(MacroKind::Bang, _) => {
- // Dummy span for the `def_site` means it's an external macro.
- expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site)
- }
- ExpnKind::Macro { .. } => true, // definitely a plugin
- }
+ self.ctxt().in_external_macro(sm)
}
/// Returns `true` if `span` originates in a derive-macro's expansion.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index ea142e3..b6cb611 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -459,6 +459,7 @@
anonymous_lifetime_in_impl_trait,
any,
append_const_msg,
+ apx_target_feature,
arbitrary_enum_discriminant,
arbitrary_self_types,
arbitrary_self_types_pointers,
@@ -2098,7 +2099,6 @@
three_way_compare,
thumb2,
thumb_mode: "thumb-mode",
- time,
tmm_reg,
to_owned_method,
to_string,
@@ -2341,6 +2341,9 @@
#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
pub struct Ident {
+ // `name` should never be the empty symbol. If you are considering that,
+ // you are probably conflating "empty identifer with "no identifier" and
+ // you should use `Option<Ident>` instead.
pub name: Symbol,
pub span: Span,
}
@@ -2348,28 +2351,21 @@ pub struct Ident {
impl Ident {
#[inline]
/// Constructs a new identifier from a symbol and a span.
- pub const fn new(name: Symbol, span: Span) -> Ident {
+ pub fn new(name: Symbol, span: Span) -> Ident {
+ assert_ne!(name, kw::Empty);
Ident { name, span }
}
/// Constructs a new identifier with a dummy span.
#[inline]
- pub const fn with_dummy_span(name: Symbol) -> Ident {
+ pub fn with_dummy_span(name: Symbol) -> Ident {
Ident::new(name, DUMMY_SP)
}
- /// This is best avoided, because it blurs the lines between "empty
- /// identifier" and "no identifier". Using `Option<Ident>` is preferable,
- /// where possible, because that is unambiguous.
- #[inline]
- pub fn empty() -> Ident {
- Ident::with_dummy_span(kw::Empty)
- }
-
// For dummy identifiers that are never used and absolutely must be
- // present, it's better to use `Ident::dummy` than `Ident::Empty`, because
- // it's clearer that it's intended as a dummy value, and more likely to be
- // detected if it accidentally does get used.
+ // present. Note that this does *not* use the empty symbol; `sym::dummy`
+ // makes it clear that it's intended as a dummy value, and is more likely
+ // to be detected if it accidentally does get used.
#[inline]
pub fn dummy() -> Ident {
Ident::with_dummy_span(sym::dummy)
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 1f45440..4a99ce0 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -890,6 +890,7 @@ fn path_append(
| DefPathData::Impl
| DefPathData::MacroNs(_)
| DefPathData::LifetimeNs(_)
+ | DefPathData::OpaqueLifetime(_)
| DefPathData::AnonAssocTy(..) => {
bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data)
}
diff --git a/compiler/rustc_target/src/spec/base/msvc.rs b/compiler/rustc_target/src/spec/base/msvc.rs
index 486d715..bd59678 100644
--- a/compiler/rustc_target/src/spec/base/msvc.rs
+++ b/compiler/rustc_target/src/spec/base/msvc.rs
@@ -5,7 +5,19 @@
pub(crate) fn opts() -> TargetOptions {
// Suppress the verbose logo and authorship debugging output, which would needlessly
// clog any log files.
- let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/NOLOGO"]);
+ let pre_link_args = TargetOptions::link_args(
+ LinkerFlavor::Msvc(Lld::No),
+ &[
+ "/NOLOGO",
+ // "Symbol is marked as dllimport, but defined in an object file"
+ // Harmless warning that flags a potential performance improvement: marking a symbol as
+ // dllimport indirects usage via the `__imp_` symbol, which isn't required if the symbol
+ // is in the current binary. This is tripped by __rust_no_alloc_shim_is_unstable as it
+ // is generated by the compiler, but marked as a foreign item (hence the dllimport) in
+ // the standard library.
+ "/IGNORE:4286",
+ ],
+ );
TargetOptions {
linker_flavor: LinkerFlavor::Msvc(Lld::No),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
index 98d7852..c5704c5 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
@@ -1,10 +1,21 @@
-use crate::spec::{Target, TargetMetadata, base};
+use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, base};
pub(crate) fn target() -> Target {
let mut base = base::windows_msvc::opts();
base.max_atomic_width = Some(128);
base.features = "+v8a,+neon,+fp-armv8".into();
+ // Microsoft recommends enabling frame pointers on Arm64 Windows.
+ // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers
+ // "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW
+ // and other services. It must point to the previous {x29, x30} pair on the stack."
+ base.frame_pointer = FramePointer::NonLeaf;
+
+ // MSVC emits a warning about code that may trip "Cortex-A53 MPCore processor bug #843419" (see
+ // https://developer.arm.com/documentation/epm048406/latest) which is sometimes emitted by LLVM.
+ // Since Arm64 Windows 10+ isn't supported on that processor, it's safe to disable the warning.
+ base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/arm64hazardfree"]);
+
Target {
llvm_target: "aarch64-pc-windows-msvc".into(),
metadata: TargetMetadata {
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index d04c8f3..5a21925 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -393,6 +393,7 @@ pub fn toggle_allowed(&self) -> Result<(), &'static str> {
("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+ ("apxf", Unstable(sym::apx_target_feature), &[]),
("avx", Stable, &["sse4.2"]),
(
"avx10.1",
diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml
index e6de2a3..1071105 100644
--- a/compiler/rustc_trait_selection/Cargo.toml
+++ b/compiler/rustc_trait_selection/Cargo.toml
@@ -20,7 +20,6 @@
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] }
-rustc_type_ir = { path = "../rustc_type_ir" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2"
tracing = "0.1"
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index cf6dd40..00922c6 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -452,8 +452,6 @@
}
.label = type must be known at this point
-trait_selection_type_annotations_needed_error_time = this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`
-
trait_selection_types_declared_different = these two types are declared with different lifetimes...
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index de9a50f..cb1c9c7 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -6,7 +6,7 @@
use rustc_errors::{Diag, IntoDiagArg};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
-use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource};
use rustc_middle::bug;
@@ -17,7 +17,7 @@
self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Term, TermKind,
Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, TypeckResults,
};
-use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym};
+use rustc_span::{BytePos, DUMMY_SP, Ident, Span, sym};
use tracing::{debug, instrument, warn};
use super::nice_region_error::placeholder_error::Highlighted;
@@ -438,7 +438,6 @@ fn bad_inference_failure_err(
bad_label,
was_written: false,
path: Default::default(),
- time_version: false,
}),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span,
@@ -630,10 +629,6 @@ pub fn emit_inference_failure_err(
}
}
}
-
- let time_version =
- self.detect_old_time_crate_version(failure_span, &kind, &mut infer_subdiags);
-
match error_code {
TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
span,
@@ -645,7 +640,6 @@ pub fn emit_inference_failure_err(
bad_label: None,
was_written: path.is_some(),
path: path.unwrap_or_default(),
- time_version,
}),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span,
@@ -671,42 +665,6 @@ pub fn emit_inference_failure_err(
}),
}
}
-
- /// Detect the inference regression on crate `time` <= 0.3.35 and emit a more targeted error.
- /// <https://github.com/rust-lang/rust/issues/127343>
- // FIXME: we should figure out a more generic version of doing this, ideally in cargo itself.
- fn detect_old_time_crate_version(
- &self,
- span: Option<Span>,
- kind: &InferSourceKind<'_>,
- // We will clear the non-actionable suggestion from the error to reduce noise.
- infer_subdiags: &mut Vec<SourceKindSubdiag<'_>>,
- ) -> bool {
- // FIXME(#129461): We are time-boxing this code in the compiler. It'll start failing
- // compilation once we promote 1.89 to beta, which will happen in 9 months from now.
- #[cfg(not(version("1.89")))]
- const fn version_check() {}
- #[cfg(version("1.89"))]
- const fn version_check() {
- panic!("remove this check as presumably the ecosystem has moved from needing it");
- }
- const { version_check() };
- // Only relevant when building the `time` crate.
- if self.infcx.tcx.crate_name(LOCAL_CRATE) == sym::time
- && let Some(span) = span
- && let InferSourceKind::LetBinding { pattern_name, .. } = kind
- && let Some(name) = pattern_name
- && name.as_str() == "items"
- && let FileName::Real(file) = self.infcx.tcx.sess.source_map().span_to_filename(span)
- {
- let path = file.local_path_if_available().to_string_lossy();
- if path.contains("format_description") && path.contains("parse") {
- infer_subdiags.clear();
- return true;
- }
- }
- false
- }
}
#[derive(Debug)]
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs
index f835406..d8b9084 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs
@@ -1,11 +1,12 @@
use std::fmt;
+use std::ops::Range;
use errors::*;
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::print::TraitRefPrintSugared;
use rustc_parse_format::{
- Alignment, Argument, Count, FormatSpec, InnerSpan, ParseError, ParseMode, Parser,
- Piece as RpfPiece, Position,
+ Alignment, Argument, Count, FormatSpec, ParseError, ParseMode, Parser, Piece as RpfPiece,
+ Position,
};
use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use rustc_span::def_id::DefId;
@@ -173,7 +174,7 @@ pub fn parse<'tcx>(
pieces.push(Piece::Lit(lit.into()));
}
RpfPiece::NextArgument(arg) => {
- warn_on_format_spec(arg.format, &mut warnings, span);
+ warn_on_format_spec(arg.format.clone(), &mut warnings, span);
let arg = parse_arg(&arg, ctx, &mut warnings, span);
pieces.push(Piece::Arg(arg));
}
@@ -233,7 +234,7 @@ fn parse_arg<'tcx>(
| Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }) = ctx;
let trait_name = tcx.item_ident(*trait_def_id);
let generics = tcx.generics_of(trait_def_id);
- let span = slice_span(input_span, arg.position_span);
+ let span = slice_span(input_span, arg.position_span.clone());
match arg.position {
// Something like "hello {name}"
@@ -335,14 +336,12 @@ fn warn_on_format_spec(spec: FormatSpec<'_>, warnings: &mut Vec<FormatWarning>,
}
}
-/// Helper function because `Span` and `rustc_parse_format::InnerSpan` don't know about each other
-fn slice_span(input: Span, inner: InnerSpan) -> Span {
- let InnerSpan { start, end } = inner;
+fn slice_span(input: Span, range: Range<usize>) -> Span {
let span = input.data();
Span::new(
- span.lo + BytePos::from_usize(start),
- span.lo + BytePos::from_usize(end),
+ span.lo + BytePos::from_usize(range.start),
+ span.lo + BytePos::from_usize(range.end),
span.ctxt,
span.parent,
)
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index de251ae..8801397 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -1516,6 +1516,12 @@ pub(super) fn suggest_remove_reference(
} else {
expr.span.with_hi(expr.span.lo() + BytePos(1))
};
+
+ match self.tcx.sess.source_map().span_to_snippet(span) {
+ Ok(snippet) if snippet.starts_with("&") => {}
+ _ => break 'outer,
+ }
+
suggestions.push((span, String::new()));
let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else {
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 04cae1c..8ab4d79 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -219,8 +219,6 @@ pub struct AnnotationRequired<'a> {
#[note(trait_selection_full_type_written)]
pub was_written: bool,
pub path: PathBuf,
- #[note(trait_selection_type_annotations_needed_error_time)]
- pub time_version: bool,
}
// Copy of `AnnotationRequired` for E0283
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 908c058..3601c2c 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -104,10 +104,6 @@ fn well_formed_goals(
.map(|obligations| obligations.into_iter().map(|obligation| obligation.as_goal()).collect())
}
- fn clone_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
- self.0.clone_opaque_types_for_query_response()
- }
-
fn make_deduplicated_outlives_constraints(
&self,
) -> Vec<ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>> {
@@ -153,18 +149,6 @@ fn instantiate_canonical_var_with_infer(
self.0.instantiate_canonical_var(span, cv_info, universe_map)
}
- fn register_hidden_type_in_storage(
- &self,
- opaque_type_key: ty::OpaqueTypeKey<'tcx>,
- hidden_ty: <Self::Interner as rustc_type_ir::Interner>::Ty,
- span: <Self::Interner as rustc_type_ir::Interner>::Span,
- ) -> Option<<Self::Interner as rustc_type_ir::Interner>::Ty> {
- self.0.register_hidden_type_in_storage(
- opaque_type_key,
- ty::OpaqueHiddenType { span, ty: hidden_ty },
- )
- }
-
fn add_item_bounds_for_hidden_type(
&self,
def_id: DefId,
@@ -176,10 +160,6 @@ fn add_item_bounds_for_hidden_type(
self.0.add_item_bounds_for_hidden_type(def_id, args, param_env, hidden_ty, goals);
}
- fn reset_opaque_types(&self) {
- let _ = self.take_opaque_types();
- }
-
fn fetch_eligible_assoc_item(
&self,
goal_trait_ref: ty::TraitRef<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
index 2d445dd..f64cd5f 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
@@ -99,7 +99,13 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
(FulfillmentErrorCode::Ambiguity { overflow: None }, true)
}
- Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => (
+ Ok((
+ _,
+ Certainty::Maybe(MaybeCause::Overflow {
+ suggest_increasing_limit,
+ keep_constraints: _,
+ }),
+ )) => (
FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
// Don't look into overflows because we treat overflows weirdly anyways.
// We discard the inference constraints from overflowing goals, so
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 24b8700..9795655 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -382,7 +382,7 @@ fn new(
if let Some(term_hack) = normalizes_to_term_hack {
infcx
.probe(|_| term_hack.constrain(infcx, DUMMY_SP, uncanonicalized_goal.param_env))
- .map(|certainty| ok.value.certainty.unify_with(certainty))
+ .map(|certainty| ok.value.certainty.and(certainty))
} else {
Ok(ok.value.certainty)
}
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index a54eb80..eb34cb1 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -9,7 +9,7 @@
pub use rustc_middle::traits::query::NormalizationResult;
use rustc_middle::ty::{
self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
- TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
+ TypeVisitableExt, TypeVisitor, TypingMode,
};
use rustc_span::DUMMY_SP;
use tracing::{debug, info, instrument};
@@ -127,7 +127,7 @@ struct MaxEscapingBoundVarVisitor {
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
+ fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
self.outer_index.shift_in(1);
t.super_visit_with(self);
self.outer_index.shift_out(1);
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index ea0f6b8..f79b6d4 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -29,10 +29,10 @@
mod instance;
mod layout;
mod needs_drop;
+mod nested_bodies;
mod opaque_types;
mod representability;
pub mod sig_types;
-mod stalled_generators;
mod structural_match;
mod ty;
@@ -51,5 +51,5 @@ pub fn provide(providers: &mut Providers) {
ty::provide(providers);
instance::provide(providers);
structural_match::provide(providers);
- stalled_generators::provide(providers);
+ nested_bodies::provide(providers);
}
diff --git a/compiler/rustc_ty_utils/src/nested_bodies.rs b/compiler/rustc_ty_utils/src/nested_bodies.rs
new file mode 100644
index 0000000..7c74d8e
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/nested_bodies.rs
@@ -0,0 +1,34 @@
+use rustc_hir as hir;
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::intravisit::Visitor;
+use rustc_middle::query::Providers;
+use rustc_middle::ty::{self, TyCtxt};
+
+fn nested_bodies_within<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx ty::List<LocalDefId> {
+ let body = tcx.hir_body_owned_by(item);
+ let mut collector =
+ NestedBodiesVisitor { tcx, root_def_id: item.to_def_id(), nested_bodies: vec![] };
+ collector.visit_body(body);
+ tcx.mk_local_def_ids(&collector.nested_bodies)
+}
+
+struct NestedBodiesVisitor<'tcx> {
+ tcx: TyCtxt<'tcx>,
+ root_def_id: DefId,
+ nested_bodies: Vec<LocalDefId>,
+}
+
+impl<'tcx> Visitor<'tcx> for NestedBodiesVisitor<'tcx> {
+ fn visit_nested_body(&mut self, id: hir::BodyId) {
+ let body_def_id = self.tcx.hir_body_owner_def_id(id);
+ if self.tcx.typeck_root_def_id(body_def_id.to_def_id()) == self.root_def_id {
+ self.nested_bodies.push(body_def_id);
+ let body = self.tcx.hir_body(id);
+ self.visit_body(body);
+ }
+ }
+}
+
+pub(super) fn provide(providers: &mut Providers) {
+ *providers = Providers { nested_bodies_within, ..*providers };
+}
diff --git a/compiler/rustc_ty_utils/src/stalled_generators.rs b/compiler/rustc_ty_utils/src/stalled_generators.rs
deleted file mode 100644
index 8b45e8b..0000000
--- a/compiler/rustc_ty_utils/src/stalled_generators.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::intravisit;
-use rustc_hir::intravisit::Visitor;
-use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, TyCtxt};
-
-fn stalled_generators_within<'tcx>(
- tcx: TyCtxt<'tcx>,
- item: LocalDefId,
-) -> &'tcx ty::List<LocalDefId> {
- if !tcx.next_trait_solver_globally() {
- return ty::List::empty();
- }
-
- let body = tcx.hir_body_owned_by(item);
- let mut collector =
- StalledGeneratorVisitor { tcx, root_def_id: item.to_def_id(), stalled_coroutines: vec![] };
- collector.visit_body(body);
- tcx.mk_local_def_ids(&collector.stalled_coroutines)
-}
-
-struct StalledGeneratorVisitor<'tcx> {
- tcx: TyCtxt<'tcx>,
- root_def_id: DefId,
- stalled_coroutines: Vec<LocalDefId>,
-}
-
-impl<'tcx> Visitor<'tcx> for StalledGeneratorVisitor<'tcx> {
- fn visit_nested_body(&mut self, id: hir::BodyId) {
- if self.tcx.typeck_root_def_id(self.tcx.hir_body_owner_def_id(id).to_def_id())
- == self.root_def_id
- {
- let body = self.tcx.hir_body(id);
- self.visit_body(body);
- }
- }
-
- fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
- if let hir::ExprKind::Closure(&hir::Closure {
- def_id,
- kind: hir::ClosureKind::Coroutine(_),
- ..
- }) = ex.kind
- {
- self.stalled_coroutines.push(def_id);
- }
- intravisit::walk_expr(self, ex);
- }
-}
-
-pub(super) fn provide(providers: &mut Providers) {
- *providers = Providers { stalled_generators_within, ..*providers };
-}
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 31d69ee..0c49ddf 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -7,7 +7,8 @@
use rustc_middle::bug;
use rustc_middle::query::Providers;
use rustc_middle::ty::{
- self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, fold_regions,
+ self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast,
+ fold_regions,
};
use rustc_span::DUMMY_SP;
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
@@ -185,7 +186,7 @@ struct ImplTraitInTraitFinder<'a, 'tcx> {
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, binder: &ty::Binder<'tcx, T>) {
+ fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, binder: &ty::Binder<'tcx, T>) {
self.depth.shift_in(1);
binder.super_visit_with(self);
self.depth.shift_out(1);
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
index 27ea4e2..000cf1e 100644
--- a/compiler/rustc_type_ir/src/binder.rs
+++ b/compiler/rustc_type_ir/src/binder.rs
@@ -128,7 +128,7 @@ fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
}
}
-impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Binder<I, T> {
+impl<I: Interner, T: TypeFoldable<I>> TypeVisitable<I> for Binder<I, T> {
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
visitor.visit_binder(self)
}
@@ -147,7 +147,7 @@ fn super_fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
}
}
-impl<I: Interner, T: TypeVisitable<I>> TypeSuperVisitable<I> for Binder<I, T> {
+impl<I: Interner, T: TypeFoldable<I>> TypeSuperVisitable<I> for Binder<I, T> {
fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
self.as_ref().skip_binder().visit_with(visitor)
}
@@ -292,7 +292,7 @@ pub fn new(bound_vars: I::BoundVarKinds) -> Self {
impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
type Result = ControlFlow<()>;
- fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &Binder<I, T>) -> Self::Result {
+ fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &Binder<I, T>) -> Self::Result {
self.binder_index.shift_in(1);
let result = t.super_visit_with(self);
self.binder_index.shift_out(1);
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index 8fa56c3..c149076 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -1,3 +1,5 @@
+use std::fmt::Debug;
+
use derive_where::derive_where;
#[cfg(feature = "nightly")]
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
@@ -100,7 +102,7 @@ pub fn non_body_analysis() -> TypingMode<I> {
pub fn typeck_for_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
TypingMode::Analysis {
defining_opaque_types_and_generators: cx
- .opaque_types_and_generators_defined_by(body_def_id),
+ .opaque_types_and_coroutines_defined_by(body_def_id),
}
}
@@ -245,4 +247,32 @@ fn register_ty_outlives(
r: <Self::Interner as Interner>::Region,
span: <Self::Interner as Interner>::Span,
);
+
+ type OpaqueTypeStorageEntries: Debug + Copy + Default;
+ fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries;
+ fn clone_opaque_types_lookup_table(
+ &self,
+ ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
+ fn clone_duplicate_opaque_types(
+ &self,
+ ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
+ fn clone_opaque_types_added_since(
+ &self,
+ prev_entries: Self::OpaqueTypeStorageEntries,
+ ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
+
+ fn register_hidden_type_in_storage(
+ &self,
+ opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
+ hidden_ty: <Self::Interner as Interner>::Ty,
+ span: <Self::Interner as Interner>::Span,
+ ) -> Option<<Self::Interner as Interner>::Ty>;
+ fn add_duplicate_opaque_type(
+ &self,
+ opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
+ hidden_ty: <Self::Interner as Interner>::Ty,
+ span: <Self::Interner as Interner>::Span,
+ );
+
+ fn reset_opaque_types(&self);
}
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 6410da1..0fd2d9f 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -341,7 +341,7 @@ fn anonymize_bound_vars<T: TypeFoldable<Self>>(
fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds;
- fn opaque_types_and_generators_defined_by(
+ fn opaque_types_and_coroutines_defined_by(
self,
defining_anchor: Self::LocalDefId,
) -> Self::LocalDefIds;
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index 4e9b87f..2e05c23 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -147,9 +147,8 @@ pub enum CandidateSource<I: Interner> {
/// For a list of all traits with builtin impls, check out the
/// `EvalCtxt::assemble_builtin_impl_candidates` method.
BuiltinImpl(BuiltinImplSource),
- /// An assumption from the environment.
- ///
- /// More precisely we've used the `n-th` assumption in the `param_env`.
+ /// An assumption from the environment. Stores a [`ParamEnvSource`], since we
+ /// prefer non-global param-env candidates in candidate assembly.
///
/// ## Examples
///
@@ -160,7 +159,7 @@ pub enum CandidateSource<I: Interner> {
/// (x.clone(), x)
/// }
/// ```
- ParamEnv(usize),
+ ParamEnv(ParamEnvSource),
/// If the self type is an alias type, e.g. an opaque type or a projection,
/// we know the bounds on that alias to hold even without knowing its concrete
/// underlying type.
@@ -190,6 +189,14 @@ pub enum CandidateSource<I: Interner> {
}
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
+pub enum ParamEnvSource {
+ /// Preferred eagerly.
+ NonGlobal,
+ // Not considered unless there are non-global param-env candidates too.
+ Global,
+}
+
+#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
#[cfg_attr(
feature = "nightly",
derive(HashStable_NoContext, Encodable_NoContext, Decodable_NoContext)
@@ -266,17 +273,17 @@ impl Certainty {
/// however matter for diagnostics. If `T: Foo` resulted in overflow and `T: Bar`
/// in ambiguity without changing the inference state, we still want to tell the
/// user that `T: Baz` results in overflow.
- pub fn unify_with(self, other: Certainty) -> Certainty {
+ pub fn and(self, other: Certainty) -> Certainty {
match (self, other) {
(Certainty::Yes, Certainty::Yes) => Certainty::Yes,
(Certainty::Yes, Certainty::Maybe(_)) => other,
(Certainty::Maybe(_), Certainty::Yes) => self,
- (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.unify_with(b)),
+ (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.and(b)),
}
}
pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
- Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit })
+ Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: false })
}
}
@@ -289,19 +296,58 @@ pub enum MaybeCause {
/// or we hit a case where we just don't bother, e.g. `?x: Trait` goals.
Ambiguity,
/// We gave up due to an overflow, most often by hitting the recursion limit.
- Overflow { suggest_increasing_limit: bool },
+ Overflow { suggest_increasing_limit: bool, keep_constraints: bool },
}
impl MaybeCause {
- fn unify_with(self, other: MaybeCause) -> MaybeCause {
+ fn and(self, other: MaybeCause) -> MaybeCause {
match (self, other) {
(MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
(MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
(MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
(
- MaybeCause::Overflow { suggest_increasing_limit: a },
- MaybeCause::Overflow { suggest_increasing_limit: b },
- ) => MaybeCause::Overflow { suggest_increasing_limit: a || b },
+ MaybeCause::Overflow {
+ suggest_increasing_limit: limit_a,
+ keep_constraints: keep_a,
+ },
+ MaybeCause::Overflow {
+ suggest_increasing_limit: limit_b,
+ keep_constraints: keep_b,
+ },
+ ) => MaybeCause::Overflow {
+ suggest_increasing_limit: limit_a && limit_b,
+ keep_constraints: keep_a && keep_b,
+ },
+ }
+ }
+
+ pub fn or(self, other: MaybeCause) -> MaybeCause {
+ match (self, other) {
+ (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
+
+ // When combining ambiguity + overflow, we can keep constraints.
+ (
+ MaybeCause::Ambiguity,
+ MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
+ ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
+ (
+ MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
+ MaybeCause::Ambiguity,
+ ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
+
+ (
+ MaybeCause::Overflow {
+ suggest_increasing_limit: limit_a,
+ keep_constraints: keep_a,
+ },
+ MaybeCause::Overflow {
+ suggest_increasing_limit: limit_b,
+ keep_constraints: keep_b,
+ },
+ ) => MaybeCause::Overflow {
+ suggest_increasing_limit: limit_a || limit_b,
+ keep_constraints: keep_a || keep_b,
+ },
}
}
}
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs
index d1ca9bd..8ba985d 100644
--- a/compiler/rustc_type_ir/src/ty_kind/closure.rs
+++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -342,7 +342,7 @@ struct HasRegionsBoundAt {
// FIXME: Could be optimized to not walk into components with no escaping bound vars.
impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
type Result = ControlFlow<()>;
- fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+ fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
self.binder.shift_in(1);
t.super_visit_with(self)?;
self.binder.shift_out(1);
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 2285e0e..ccb84e2 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -52,7 +52,7 @@
use thin_vec::ThinVec;
use crate::inherent::*;
-use crate::{self as ty, Interner, TypeFlags};
+use crate::{self as ty, Interner, TypeFlags, TypeFoldable};
/// This trait is implemented for every type that can be visited,
/// providing the skeleton of the traversal.
@@ -94,7 +94,7 @@ pub trait TypeVisitor<I: Interner>: Sized {
#[cfg(not(feature = "nightly"))]
type Result: VisitorResult;
- fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+ fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
t.super_visit_with(self)
}
@@ -401,7 +401,7 @@ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
type Result = ControlFlow<FoundFlags>;
- fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+ fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
// If we're looking for the HAS_BINDER_VARS flag, check if the
// binder has vars. This won't be present in the binder's bound
// value, so we need to check here too.
@@ -510,7 +510,7 @@ struct HasEscapingVarsVisitor {
impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
type Result = ControlFlow<FoundEscapingVars>;
- fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+ fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
self.outer_index.shift_in(1);
let result = t.super_visit_with(self);
self.outer_index.shift_out(1);
diff --git a/library/Cargo.lock b/library/Cargo.lock
index a94ed7b..5100b4d 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -61,9 +61,9 @@
[[package]]
name = "compiler_builtins"
-version = "0.1.157"
+version = "0.1.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74f103f5a97b25e3ed7134dee586e90bbb0496b33ba41816f0e7274e5bb73b50"
+checksum = "164cdc689e4c6d69417f77a5f48be240c291e84fbef0b1281755dc754b19c809"
dependencies = [
"cc",
"rustc-std-workspace-core",
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index ebfcf87..51ddc9b 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -16,7 +16,7 @@
[dependencies]
core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.157", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.158", features = ['rustc-dep-of-std'] }
[features]
compiler-builtins-mem = ['compiler_builtins/mem']
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index f8844e2..712f38a 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1188,6 +1188,73 @@ fn drop(&mut self) {
}
}
+ /// Shortens the deque, keeping the last `len` elements and dropping
+ /// the rest.
+ ///
+ /// If `len` is greater or equal to the deque's current length, this has
+ /// no effect.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #![feature(vec_deque_truncate_front)]
+ /// use std::collections::VecDeque;
+ ///
+ /// let mut buf = VecDeque::new();
+ /// buf.push_front(5);
+ /// buf.push_front(10);
+ /// buf.push_front(15);
+ /// assert_eq!(buf, [15, 10, 5]);
+ /// assert_eq!(buf.as_slices(), (&[15, 10, 5][..], &[][..]));
+ /// buf.truncate_front(1);
+ /// assert_eq!(buf.as_slices(), (&[5][..], &[][..]));
+ /// ```
+ #[unstable(feature = "vec_deque_truncate_front", issue = "140667")]
+ pub fn truncate_front(&mut self, len: usize) {
+ /// Runs the destructor for all items in the slice when it gets dropped (normally or
+ /// during unwinding).
+ struct Dropper<'a, T>(&'a mut [T]);
+
+ impl<'a, T> Drop for Dropper<'a, T> {
+ fn drop(&mut self) {
+ unsafe {
+ ptr::drop_in_place(self.0);
+ }
+ }
+ }
+
+ unsafe {
+ if len >= self.len {
+ // No action is taken
+ return;
+ }
+
+ let (front, back) = self.as_mut_slices();
+ if len > back.len() {
+ // The 'back' slice remains unchanged.
+ // front.len() + back.len() == self.len, so 'end' is non-negative
+ // and end < front.len()
+ let end = front.len() - (len - back.len());
+ let drop_front = front.get_unchecked_mut(..end) as *mut _;
+ self.head += end;
+ self.len = len;
+ ptr::drop_in_place(drop_front);
+ } else {
+ let drop_front = front as *mut _;
+ // 'end' is non-negative by the condition above
+ let end = back.len() - len;
+ let drop_back = back.get_unchecked_mut(..end) as *mut _;
+ self.head = self.to_physical_idx(self.len - len);
+ self.len = len;
+
+ // Make sure the second half is dropped even when a destructor
+ // in the first one panics.
+ let _back_dropper = Dropper(&mut *drop_back);
+ ptr::drop_in_place(drop_front);
+ }
+ }
+ }
+
/// Returns a reference to the underlying allocator.
#[unstable(feature = "allocator_api", issue = "32838")]
#[inline]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 619d9f2..4b8ea70 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -3536,11 +3536,11 @@ fn default() -> Weak<T> {
}
}
-// NOTE: We checked_add here to deal with mem::forget safely. In particular
-// if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
-// you can free the allocation while outstanding Rcs (or Weaks) exist.
-// We abort because this is such a degenerate scenario that we don't care about
-// what happens -- no real program should ever experience this.
+// NOTE: If you mem::forget Rcs (or Weaks), drop is skipped and the ref-count
+// is not decremented, meaning the ref-count can overflow, and then you can
+// free the allocation while outstanding Rcs (or Weaks) exist, which would be
+// unsound. We abort because this is such a degenerate scenario that we don't
+// care about what happens -- no real program should ever experience this.
//
// This should have negligible overhead since you don't actually need to
// clone these much in Rust thanks to ownership and move-semantics.
diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs
index f1f4cc6..3830958 100644
--- a/library/alloctests/tests/lib.rs
+++ b/library/alloctests/tests/lib.rs
@@ -37,6 +37,7 @@
#![feature(str_as_str)]
#![feature(strict_provenance_lints)]
#![feature(vec_deque_pop_if)]
+#![feature(vec_deque_truncate_front)]
#![feature(unique_rc_arc)]
#![feature(macro_metavar_expr_concat)]
#![allow(internal_features)]
diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs
index 1b03c29..b77ea3a 100644
--- a/library/alloctests/tests/vec_deque.rs
+++ b/library/alloctests/tests/vec_deque.rs
@@ -1688,6 +1688,40 @@ fn drop(&mut self) {
#[test]
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+fn truncate_front_leak() {
+ static mut DROPS: i32 = 0;
+
+ struct D(bool);
+
+ impl Drop for D {
+ fn drop(&mut self) {
+ unsafe {
+ DROPS += 1;
+ }
+
+ if self.0 {
+ panic!("panic in `drop`");
+ }
+ }
+ }
+
+ let mut q = VecDeque::new();
+ q.push_back(D(false));
+ q.push_back(D(false));
+ q.push_back(D(false));
+ q.push_back(D(false));
+ q.push_back(D(false));
+ q.push_front(D(true));
+ q.push_front(D(false));
+ q.push_front(D(false));
+
+ catch_unwind(AssertUnwindSafe(|| q.truncate_front(1))).ok();
+
+ assert_eq!(unsafe { DROPS }, 7);
+}
+
+#[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
fn test_drain_leak() {
static mut DROPS: i32 = 0;
@@ -1863,3 +1897,38 @@ fn check(buf: *const i32, last: *const i32, mut it: impl Iterator<Item = i32>) {
assert_eq!(v.capacity(), 13);
}
}
+
+#[test]
+fn test_truncate_front() {
+ let mut v = VecDeque::with_capacity(13);
+ v.extend(0..7);
+ assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+ v.truncate_front(10);
+ assert_eq!(v.len(), 7);
+ assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+ v.truncate_front(7);
+ assert_eq!(v.len(), 7);
+ assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+ v.truncate_front(3);
+ assert_eq!(v.as_slices(), ([4, 5, 6].as_slice(), [].as_slice()));
+ assert_eq!(v.len(), 3);
+ v.truncate_front(0);
+ assert_eq!(v.as_slices(), ([].as_slice(), [].as_slice()));
+ assert_eq!(v.len(), 0);
+
+ v.clear();
+ v.extend(0..7);
+ assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+ v.push_front(9);
+ v.push_front(8);
+ v.push_front(7);
+ assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice()));
+ v.truncate_front(12);
+ assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice()));
+ v.truncate_front(10);
+ assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice()));
+ v.truncate_front(8);
+ assert_eq!(v.as_slices(), ([9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice()));
+ v.truncate_front(5);
+ assert_eq!(v.as_slices(), ([2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+}
diff --git a/library/backtrace b/library/backtrace
index 9d2c34e..6c882eb 160000
--- a/library/backtrace
+++ b/library/backtrace
@@ -1 +1 @@
-Subproject commit 9d2c34e7e63afe1e71c333b247065e3b7ba4d883
+Subproject commit 6c882eb11984d737f62e85f36703effaf34c2453
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 394a3ea..cb83540 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -320,6 +320,10 @@ pub fn spin_loop() {
/// This also means that this function does not offer any guarantees for cryptographic or security
/// purposes.
///
+/// This limitation is not specific to `black_box`; there is no mechanism in the entire Rust
+/// language that can provide the guarantees required for constant-time cryptography.
+/// (There is also no such mechanism in LLVM, so the same is true for every other LLVM-based compiler.)
+///
/// </div>
///
/// [`std::convert::identity`]: crate::convert::identity
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 0d7d786..d1e71f0 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -56,12 +56,12 @@ pub trait Iterator {
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
/// // A call to next() returns the next value...
- /// assert_eq!(Some(&1), iter.next());
- /// assert_eq!(Some(&2), iter.next());
- /// assert_eq!(Some(&3), iter.next());
+ /// assert_eq!(Some(1), iter.next());
+ /// assert_eq!(Some(2), iter.next());
+ /// assert_eq!(Some(3), iter.next());
///
/// // ... and then None once it's over.
/// assert_eq!(None, iter.next());
@@ -239,10 +239,10 @@ fn count(self) -> usize
///
/// ```
/// let a = [1, 2, 3];
- /// assert_eq!(a.iter().last(), Some(&3));
+ /// assert_eq!(a.into_iter().last(), Some(3));
///
/// let a = [1, 2, 3, 4, 5];
- /// assert_eq!(a.iter().last(), Some(&5));
+ /// assert_eq!(a.into_iter().last(), Some(5));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -284,12 +284,12 @@ fn some<T>(_: Option<T>, x: T) -> Option<T> {
/// use std::num::NonZero;
///
/// let a = [1, 2, 3, 4];
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
/// assert_eq!(iter.advance_by(2), Ok(()));
- /// assert_eq!(iter.next(), Some(&3));
+ /// assert_eq!(iter.next(), Some(3));
/// assert_eq!(iter.advance_by(0), Ok(()));
- /// assert_eq!(iter.advance_by(100), Err(NonZero::new(99).unwrap())); // only `&4` was skipped
+ /// assert_eq!(iter.advance_by(100), Err(NonZero::new(99).unwrap())); // only `4` was skipped
/// ```
#[inline]
#[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
@@ -322,7 +322,7 @@ fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
///
/// ```
/// let a = [1, 2, 3];
- /// assert_eq!(a.iter().nth(1), Some(&2));
+ /// assert_eq!(a.into_iter().nth(1), Some(2));
/// ```
///
/// Calling `nth()` multiple times doesn't rewind the iterator:
@@ -330,9 +330,9 @@ fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
- /// assert_eq!(iter.nth(1), Some(&2));
+ /// assert_eq!(iter.nth(1), Some(2));
/// assert_eq!(iter.nth(1), None);
/// ```
///
@@ -340,7 +340,7 @@ fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
///
/// ```
/// let a = [1, 2, 3];
- /// assert_eq!(a.iter().nth(10), None);
+ /// assert_eq!(a.into_iter().nth(10), None);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -385,11 +385,11 @@ fn nth(&mut self, n: usize) -> Option<Self::Item> {
///
/// ```
/// let a = [0, 1, 2, 3, 4, 5];
- /// let mut iter = a.iter().step_by(2);
+ /// let mut iter = a.into_iter().step_by(2);
///
- /// assert_eq!(iter.next(), Some(&0));
- /// assert_eq!(iter.next(), Some(&2));
- /// assert_eq!(iter.next(), Some(&4));
+ /// assert_eq!(iter.next(), Some(0));
+ /// assert_eq!(iter.next(), Some(2));
+ /// assert_eq!(iter.next(), Some(4));
/// assert_eq!(iter.next(), None);
/// ```
#[inline]
@@ -417,37 +417,37 @@ fn step_by(self, step: usize) -> StepBy<Self>
/// Basic usage:
///
/// ```
- /// let a1 = [1, 2, 3];
- /// let a2 = [4, 5, 6];
+ /// let s1 = "abc".chars();
+ /// let s2 = "def".chars();
///
- /// let mut iter = a1.iter().chain(a2.iter());
+ /// let mut iter = s1.chain(s2);
///
- /// assert_eq!(iter.next(), Some(&1));
- /// assert_eq!(iter.next(), Some(&2));
- /// assert_eq!(iter.next(), Some(&3));
- /// assert_eq!(iter.next(), Some(&4));
- /// assert_eq!(iter.next(), Some(&5));
- /// assert_eq!(iter.next(), Some(&6));
+ /// assert_eq!(iter.next(), Some('a'));
+ /// assert_eq!(iter.next(), Some('b'));
+ /// assert_eq!(iter.next(), Some('c'));
+ /// assert_eq!(iter.next(), Some('d'));
+ /// assert_eq!(iter.next(), Some('e'));
+ /// assert_eq!(iter.next(), Some('f'));
/// assert_eq!(iter.next(), None);
/// ```
///
/// Since the argument to `chain()` uses [`IntoIterator`], we can pass
/// anything that can be converted into an [`Iterator`], not just an
- /// [`Iterator`] itself. For example, slices (`&[T]`) implement
+ /// [`Iterator`] itself. For example, arrays (`[T]`) implement
/// [`IntoIterator`], and so can be passed to `chain()` directly:
///
/// ```
- /// let s1 = &[1, 2, 3];
- /// let s2 = &[4, 5, 6];
+ /// let a1 = [1, 2, 3];
+ /// let a2 = [4, 5, 6];
///
- /// let mut iter = s1.iter().chain(s2);
+ /// let mut iter = a1.into_iter().chain(a2);
///
- /// assert_eq!(iter.next(), Some(&1));
- /// assert_eq!(iter.next(), Some(&2));
- /// assert_eq!(iter.next(), Some(&3));
- /// assert_eq!(iter.next(), Some(&4));
- /// assert_eq!(iter.next(), Some(&5));
- /// assert_eq!(iter.next(), Some(&6));
+ /// assert_eq!(iter.next(), Some(1));
+ /// assert_eq!(iter.next(), Some(2));
+ /// assert_eq!(iter.next(), Some(3));
+ /// assert_eq!(iter.next(), Some(4));
+ /// assert_eq!(iter.next(), Some(5));
+ /// assert_eq!(iter.next(), Some(6));
/// assert_eq!(iter.next(), None);
/// ```
///
@@ -496,31 +496,31 @@ fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
/// Basic usage:
///
/// ```
- /// let a1 = [1, 2, 3];
- /// let a2 = [4, 5, 6];
+ /// let s1 = "abc".chars();
+ /// let s2 = "def".chars();
///
- /// let mut iter = a1.iter().zip(a2.iter());
+ /// let mut iter = s1.zip(s2);
///
- /// assert_eq!(iter.next(), Some((&1, &4)));
- /// assert_eq!(iter.next(), Some((&2, &5)));
- /// assert_eq!(iter.next(), Some((&3, &6)));
+ /// assert_eq!(iter.next(), Some(('a', 'd')));
+ /// assert_eq!(iter.next(), Some(('b', 'e')));
+ /// assert_eq!(iter.next(), Some(('c', 'f')));
/// assert_eq!(iter.next(), None);
/// ```
///
/// Since the argument to `zip()` uses [`IntoIterator`], we can pass
/// anything that can be converted into an [`Iterator`], not just an
- /// [`Iterator`] itself. For example, slices (`&[T]`) implement
+ /// [`Iterator`] itself. For example, arrays (`[T]`) implement
/// [`IntoIterator`], and so can be passed to `zip()` directly:
///
/// ```
- /// let s1 = &[1, 2, 3];
- /// let s2 = &[4, 5, 6];
+ /// let a1 = [1, 2, 3];
+ /// let a2 = [4, 5, 6];
///
- /// let mut iter = s1.iter().zip(s2);
+ /// let mut iter = a1.into_iter().zip(a2);
///
- /// assert_eq!(iter.next(), Some((&1, &4)));
- /// assert_eq!(iter.next(), Some((&2, &5)));
- /// assert_eq!(iter.next(), Some((&3, &6)));
+ /// assert_eq!(iter.next(), Some((1, 4)));
+ /// assert_eq!(iter.next(), Some((2, 5)));
+ /// assert_eq!(iter.next(), Some((3, 6)));
/// assert_eq!(iter.next(), None);
/// ```
///
@@ -604,12 +604,12 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
/// ```
/// #![feature(iter_intersperse)]
///
- /// let mut a = [0, 1, 2].iter().intersperse(&100);
- /// assert_eq!(a.next(), Some(&0)); // The first element from `a`.
- /// assert_eq!(a.next(), Some(&100)); // The separator.
- /// assert_eq!(a.next(), Some(&1)); // The next element from `a`.
- /// assert_eq!(a.next(), Some(&100)); // The separator.
- /// assert_eq!(a.next(), Some(&2)); // The last element from `a`.
+ /// let mut a = [0, 1, 2].into_iter().intersperse(100);
+ /// assert_eq!(a.next(), Some(0)); // The first element from `a`.
+ /// assert_eq!(a.next(), Some(100)); // The separator.
+ /// assert_eq!(a.next(), Some(1)); // The next element from `a`.
+ /// assert_eq!(a.next(), Some(100)); // The separator.
+ /// assert_eq!(a.next(), Some(2)); // The last element from `a`.
/// assert_eq!(a.next(), None); // The iterator is finished.
/// ```
///
@@ -617,7 +617,8 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
/// ```
/// #![feature(iter_intersperse)]
///
- /// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
+ /// let words = ["Hello", "World", "!"];
+ /// let hello: String = words.into_iter().intersperse(" ").collect();
/// assert_eq!(hello, "Hello World !");
/// ```
///
@@ -673,7 +674,7 @@ fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
/// let src = ["Hello", "to", "all", "people", "!!"].iter().copied();
///
/// // The closure mutably borrows its context to generate an item.
- /// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied();
+ /// let mut happy_emojis = [" ❤️ ", " 😀 "].into_iter();
/// let separator = || happy_emojis.next().unwrap_or(" 🦀 ");
///
/// let result = src.intersperse_with(separator).collect::<String>();
@@ -734,7 +735,7 @@ fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
///
/// // it won't even execute, as it is lazy. Rust will warn you about this.
///
- /// // Instead, use for:
+ /// // Instead, use a for-loop:
/// for x in 0..5 {
/// println!("{x}");
/// }
@@ -814,10 +815,10 @@ fn call<T>(mut f: impl FnMut(T)) -> impl FnMut((), T) {
/// ```
/// let a = [0i32, 1, 2];
///
- /// let mut iter = a.iter().filter(|x| x.is_positive());
+ /// let mut iter = a.into_iter().filter(|x| x.is_positive());
///
- /// assert_eq!(iter.next(), Some(&1));
- /// assert_eq!(iter.next(), Some(&2));
+ /// assert_eq!(iter.next(), Some(1));
+ /// assert_eq!(iter.next(), Some(2));
/// assert_eq!(iter.next(), None);
/// ```
///
@@ -826,21 +827,20 @@ fn call<T>(mut f: impl FnMut(T)) -> impl FnMut((), T) {
/// situation, where the type of the closure is a double reference:
///
/// ```
- /// let a = [0, 1, 2];
+ /// let s = &[0, 1, 2];
///
- /// let mut iter = a.iter().filter(|x| **x > 1); // need two *s!
+ /// let mut iter = s.iter().filter(|x| **x > 1); // needs two *s!
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
/// ```
///
- /// It's common to instead use destructuring on the argument to strip away
- /// one:
+ /// It's common to instead use destructuring on the argument to strip away one:
///
/// ```
- /// let a = [0, 1, 2];
+ /// let s = &[0, 1, 2];
///
- /// let mut iter = a.iter().filter(|&x| *x > 1); // both & and *
+ /// let mut iter = s.iter().filter(|&x| *x > 1); // both & and *
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
@@ -849,9 +849,9 @@ fn call<T>(mut f: impl FnMut(T)) -> impl FnMut((), T) {
/// or both:
///
/// ```
- /// let a = [0, 1, 2];
+ /// let s = &[0, 1, 2];
///
- /// let mut iter = a.iter().filter(|&&x| x > 1); // two &s
+ /// let mut iter = s.iter().filter(|&&x| x > 1); // two &s
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
@@ -945,11 +945,11 @@ fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
/// ```
/// let a = ['a', 'b', 'c'];
///
- /// let mut iter = a.iter().enumerate();
+ /// let mut iter = a.into_iter().enumerate();
///
- /// assert_eq!(iter.next(), Some((0, &'a')));
- /// assert_eq!(iter.next(), Some((1, &'b')));
- /// assert_eq!(iter.next(), Some((2, &'c')));
+ /// assert_eq!(iter.next(), Some((0, 'a')));
+ /// assert_eq!(iter.next(), Some((1, 'b')));
+ /// assert_eq!(iter.next(), Some((2, 'c')));
/// assert_eq!(iter.next(), None);
/// ```
#[inline]
@@ -980,19 +980,19 @@ fn enumerate(self) -> Enumerate<Self>
/// ```
/// let xs = [1, 2, 3];
///
- /// let mut iter = xs.iter().peekable();
+ /// let mut iter = xs.into_iter().peekable();
///
/// // peek() lets us see into the future
- /// assert_eq!(iter.peek(), Some(&&1));
- /// assert_eq!(iter.next(), Some(&1));
+ /// assert_eq!(iter.peek(), Some(&1));
+ /// assert_eq!(iter.next(), Some(1));
///
- /// assert_eq!(iter.next(), Some(&2));
+ /// assert_eq!(iter.next(), Some(2));
///
/// // we can peek() multiple times, the iterator won't advance
- /// assert_eq!(iter.peek(), Some(&&3));
- /// assert_eq!(iter.peek(), Some(&&3));
+ /// assert_eq!(iter.peek(), Some(&3));
+ /// assert_eq!(iter.peek(), Some(&3));
///
- /// assert_eq!(iter.next(), Some(&3));
+ /// assert_eq!(iter.next(), Some(3));
///
/// // after the iterator is finished, so is peek()
/// assert_eq!(iter.peek(), None);
@@ -1005,21 +1005,21 @@ fn enumerate(self) -> Enumerate<Self>
/// ```
/// let xs = [1, 2, 3];
///
- /// let mut iter = xs.iter().peekable();
+ /// let mut iter = xs.into_iter().peekable();
///
/// // `peek_mut()` lets us see into the future
- /// assert_eq!(iter.peek_mut(), Some(&mut &1));
- /// assert_eq!(iter.peek_mut(), Some(&mut &1));
- /// assert_eq!(iter.next(), Some(&1));
+ /// assert_eq!(iter.peek_mut(), Some(&mut 1));
+ /// assert_eq!(iter.peek_mut(), Some(&mut 1));
+ /// assert_eq!(iter.next(), Some(1));
///
- /// if let Some(mut p) = iter.peek_mut() {
- /// assert_eq!(*p, &2);
+ /// if let Some(p) = iter.peek_mut() {
+ /// assert_eq!(*p, 2);
/// // put a value into the iterator
- /// *p = &1000;
+ /// *p = 1000;
/// }
///
/// // The value reappears as the iterator continues
- /// assert_eq!(iter.collect::<Vec<_>>(), vec![&1000, &3]);
+ /// assert_eq!(iter.collect::<Vec<_>>(), vec![1000, 3]);
/// ```
/// [`peek`]: Peekable::peek
/// [`peek_mut`]: Peekable::peek_mut
@@ -1051,10 +1051,10 @@ fn peekable(self) -> Peekable<Self>
/// ```
/// let a = [-1i32, 0, 1];
///
- /// let mut iter = a.iter().skip_while(|x| x.is_negative());
+ /// let mut iter = a.into_iter().skip_while(|x| x.is_negative());
///
- /// assert_eq!(iter.next(), Some(&0));
- /// assert_eq!(iter.next(), Some(&1));
+ /// assert_eq!(iter.next(), Some(0));
+ /// assert_eq!(iter.next(), Some(1));
/// assert_eq!(iter.next(), None);
/// ```
///
@@ -1063,9 +1063,9 @@ fn peekable(self) -> Peekable<Self>
/// situation, where the type of the closure argument is a double reference:
///
/// ```
- /// let a = [-1, 0, 1];
+ /// let s = &[-1, 0, 1];
///
- /// let mut iter = a.iter().skip_while(|x| **x < 0); // need two *s!
+ /// let mut iter = s.iter().skip_while(|x| **x < 0); // need two *s!
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&1));
@@ -1077,14 +1077,14 @@ fn peekable(self) -> Peekable<Self>
/// ```
/// let a = [-1, 0, 1, -2];
///
- /// let mut iter = a.iter().skip_while(|x| **x < 0);
+ /// let mut iter = a.into_iter().skip_while(|&x| x < 0);
///
- /// assert_eq!(iter.next(), Some(&0));
- /// assert_eq!(iter.next(), Some(&1));
+ /// assert_eq!(iter.next(), Some(0));
+ /// assert_eq!(iter.next(), Some(1));
///
/// // while this would have been false, since we already got a false,
/// // skip_while() isn't used any more
- /// assert_eq!(iter.next(), Some(&-2));
+ /// assert_eq!(iter.next(), Some(-2));
///
/// assert_eq!(iter.next(), None);
/// ```
@@ -1115,9 +1115,9 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
/// ```
/// let a = [-1i32, 0, 1];
///
- /// let mut iter = a.iter().take_while(|x| x.is_negative());
+ /// let mut iter = a.into_iter().take_while(|x| x.is_negative());
///
- /// assert_eq!(iter.next(), Some(&-1));
+ /// assert_eq!(iter.next(), Some(-1));
/// assert_eq!(iter.next(), None);
/// ```
///
@@ -1126,9 +1126,9 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
/// situation, where the type of the closure is a double reference:
///
/// ```
- /// let a = [-1, 0, 1];
+ /// let s = &[-1, 0, 1];
///
- /// let mut iter = a.iter().take_while(|x| **x < 0); // need two *s!
+ /// let mut iter = s.iter().take_while(|x| **x < 0); // need two *s!
///
/// assert_eq!(iter.next(), Some(&-1));
/// assert_eq!(iter.next(), None);
@@ -1139,12 +1139,12 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
/// ```
/// let a = [-1, 0, 1, -2];
///
- /// let mut iter = a.iter().take_while(|x| **x < 0);
+ /// let mut iter = a.into_iter().take_while(|&x| x < 0);
///
- /// assert_eq!(iter.next(), Some(&-1));
+ /// assert_eq!(iter.next(), Some(-1));
///
/// // We have more elements that are less than zero, but since we already
- /// // got a false, take_while() isn't used any more
+ /// // got a false, take_while() ignores the remaining elements.
/// assert_eq!(iter.next(), None);
/// ```
///
@@ -1154,18 +1154,15 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
///
/// ```
/// let a = [1, 2, 3, 4];
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
- /// let result: Vec<i32> = iter.by_ref()
- /// .take_while(|n| **n != 3)
- /// .cloned()
- /// .collect();
+ /// let result: Vec<i32> = iter.by_ref().take_while(|&n| n != 3).collect();
///
- /// assert_eq!(result, &[1, 2]);
+ /// assert_eq!(result, [1, 2]);
///
- /// let result: Vec<i32> = iter.cloned().collect();
+ /// let result: Vec<i32> = iter.collect();
///
- /// assert_eq!(result, &[4]);
+ /// assert_eq!(result, [4]);
/// ```
///
/// The `3` is no longer there, because it was consumed in order to see if
@@ -1193,7 +1190,7 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
/// ```
/// let a = [-1i32, 4, 0, 1];
///
- /// let mut iter = a.iter().map_while(|x| 16i32.checked_div(*x));
+ /// let mut iter = a.into_iter().map_while(|x| 16i32.checked_div(x));
///
/// assert_eq!(iter.next(), Some(-16));
/// assert_eq!(iter.next(), Some(4));
@@ -1208,8 +1205,8 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
/// ```
/// let a = [-1i32, 4, 0, 1];
///
- /// let mut iter = a.iter()
- /// .map(|x| 16i32.checked_div(*x))
+ /// let mut iter = a.into_iter()
+ /// .map(|x| 16i32.checked_div(x))
/// .take_while(|x| x.is_some())
/// .map(|x| x.unwrap());
///
@@ -1223,12 +1220,12 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
/// ```
/// let a = [0, 1, 2, -3, 4, 5, -6];
///
- /// let iter = a.iter().map_while(|x| u32::try_from(*x).ok());
- /// let vec = iter.collect::<Vec<_>>();
+ /// let iter = a.into_iter().map_while(|x| u32::try_from(x).ok());
+ /// let vec: Vec<_> = iter.collect();
///
- /// // We have more elements which could fit in u32 (4, 5), but `map_while` returned `None` for `-3`
+ /// // We have more elements that could fit in u32 (such as 4, 5), but `map_while` returned `None` for `-3`
/// // (as the `predicate` returned `None`) and `collect` stops at the first `None` encountered.
- /// assert_eq!(vec, vec![0, 1, 2]);
+ /// assert_eq!(vec, [0, 1, 2]);
/// ```
///
/// Because `map_while()` needs to look at the value in order to see if it
@@ -1237,17 +1234,17 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
///
/// ```
/// let a = [1, 2, -3, 4];
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
/// let result: Vec<u32> = iter.by_ref()
- /// .map_while(|n| u32::try_from(*n).ok())
+ /// .map_while(|n| u32::try_from(n).ok())
/// .collect();
///
- /// assert_eq!(result, &[1, 2]);
+ /// assert_eq!(result, [1, 2]);
///
- /// let result: Vec<i32> = iter.cloned().collect();
+ /// let result: Vec<i32> = iter.collect();
///
- /// assert_eq!(result, &[4]);
+ /// assert_eq!(result, [4]);
/// ```
///
/// The `-3` is no longer there, because it was consumed in order to see if
@@ -1255,7 +1252,7 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
///
/// Note that unlike [`take_while`] this iterator is **not** fused.
/// It is also not specified what this iterator returns after the first [`None`] is returned.
- /// If you need fused iterator, use [`fuse`].
+ /// If you need a fused iterator, use [`fuse`].
///
/// [`fuse`]: Iterator::fuse
#[inline]
@@ -1282,9 +1279,9 @@ fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.iter().skip(2);
+ /// let mut iter = a.into_iter().skip(2);
///
- /// assert_eq!(iter.next(), Some(&3));
+ /// assert_eq!(iter.next(), Some(3));
/// assert_eq!(iter.next(), None);
/// ```
#[inline]
@@ -1312,10 +1309,10 @@ fn skip(self, n: usize) -> Skip<Self>
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.iter().take(2);
+ /// let mut iter = a.into_iter().take(2);
///
- /// assert_eq!(iter.next(), Some(&1));
- /// assert_eq!(iter.next(), Some(&2));
+ /// assert_eq!(iter.next(), Some(1));
+ /// assert_eq!(iter.next(), Some(2));
/// assert_eq!(iter.next(), None);
/// ```
///
@@ -1389,7 +1386,7 @@ fn take(self, n: usize) -> Take<Self>
/// ```
/// let a = [1, 2, 3, 4];
///
- /// let mut iter = a.iter().scan(1, |state, &x| {
+ /// let mut iter = a.into_iter().scan(1, |state, x| {
/// // each iteration, we'll multiply the state by the element ...
/// *state = *state * x;
///
@@ -1467,8 +1464,8 @@ fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
///
/// ```
/// let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
- /// let flattened = data.into_iter().flatten().collect::<Vec<u8>>();
- /// assert_eq!(flattened, &[1, 2, 3, 4, 5, 6]);
+ /// let flattened: Vec<_> = data.into_iter().flatten().collect();
+ /// assert_eq!(flattened, [1, 2, 3, 4, 5, 6]);
/// ```
///
/// Mapping and then flattening:
@@ -1502,11 +1499,11 @@ fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
/// ```
/// let options = vec![Some(123), Some(321), None, Some(231)];
/// let flattened_options: Vec<_> = options.into_iter().flatten().collect();
- /// assert_eq!(flattened_options, vec![123, 321, 231]);
+ /// assert_eq!(flattened_options, [123, 321, 231]);
///
/// let results = vec![Ok(123), Ok(321), Err(456), Ok(231)];
/// let flattened_results: Vec<_> = results.into_iter().flatten().collect();
- /// assert_eq!(flattened_results, vec![123, 321, 231]);
+ /// assert_eq!(flattened_results, [123, 321, 231]);
/// ```
///
/// Flattening only removes one level of nesting at a time:
@@ -1514,11 +1511,11 @@ fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
/// ```
/// let d3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]];
///
- /// let d2 = d3.iter().flatten().collect::<Vec<_>>();
- /// assert_eq!(d2, [&[1, 2], &[3, 4], &[5, 6], &[7, 8]]);
+ /// let d2: Vec<_> = d3.into_iter().flatten().collect();
+ /// assert_eq!(d2, [[1, 2], [3, 4], [5, 6], [7, 8]]);
///
- /// let d1 = d3.iter().flatten().flatten().collect::<Vec<_>>();
- /// assert_eq!(d1, [&1, &2, &3, &4, &5, &6, &7, &8]);
+ /// let d1: Vec<_> = d3.into_iter().flatten().flatten().collect();
+ /// assert_eq!(d1, [1, 2, 3, 4, 5, 6, 7, 8]);
/// ```
///
/// Here we see that `flatten()` does not perform a "deep" flatten.
@@ -1905,7 +1902,7 @@ fn by_ref(&mut self) -> &mut Self
/// let a = [1, 2, 3];
///
/// let doubled: Vec<i32> = a.iter()
- /// .map(|&x| x * 2)
+ /// .map(|x| x * 2)
/// .collect();
///
/// assert_eq!(vec![2, 4, 6], doubled);
@@ -1921,7 +1918,7 @@ fn by_ref(&mut self) -> &mut Self
///
/// let a = [1, 2, 3];
///
- /// let doubled: VecDeque<i32> = a.iter().map(|&x| x * 2).collect();
+ /// let doubled: VecDeque<i32> = a.iter().map(|x| x * 2).collect();
///
/// assert_eq!(2, doubled[0]);
/// assert_eq!(4, doubled[1]);
@@ -1954,8 +1951,8 @@ fn by_ref(&mut self) -> &mut Self
/// ```
/// let chars = ['g', 'd', 'k', 'k', 'n'];
///
- /// let hello: String = chars.iter()
- /// .map(|&x| x as u8)
+ /// let hello: String = chars.into_iter()
+ /// .map(|x| x as u8)
/// .map(|x| (x + 1) as char)
/// .collect();
///
@@ -1968,14 +1965,14 @@ fn by_ref(&mut self) -> &mut Self
/// ```
/// let results = [Ok(1), Err("nope"), Ok(3), Err("bad")];
///
- /// let result: Result<Vec<_>, &str> = results.iter().cloned().collect();
+ /// let result: Result<Vec<_>, &str> = results.into_iter().collect();
///
/// // gives us the first error
/// assert_eq!(Err("nope"), result);
///
/// let results = [Ok(1), Ok(3)];
///
- /// let result: Result<Vec<_>, &str> = results.iter().cloned().collect();
+ /// let result: Result<Vec<_>, &str> = results.into_iter().collect();
///
/// // gives us the list of answers
/// assert_eq!(Ok(vec![1, 3]), result);
@@ -2106,8 +2103,8 @@ fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
/// let a = [1, 2, 3];
/// let mut vec: Vec::<i32> = vec![0, 1];
///
- /// a.iter().map(|&x| x * 2).collect_into(&mut vec);
- /// a.iter().map(|&x| x * 10).collect_into(&mut vec);
+ /// a.iter().map(|x| x * 2).collect_into(&mut vec);
+ /// a.iter().map(|x| x * 10).collect_into(&mut vec);
///
/// assert_eq!(vec, vec![0, 1, 2, 4, 6, 10, 20, 30]);
/// ```
@@ -2120,8 +2117,8 @@ fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
/// let a = [1, 2, 3];
/// let mut vec: Vec::<i32> = Vec::with_capacity(6);
///
- /// a.iter().map(|&x| x * 2).collect_into(&mut vec);
- /// a.iter().map(|&x| x * 10).collect_into(&mut vec);
+ /// a.iter().map(|x| x * 2).collect_into(&mut vec);
+ /// a.iter().map(|x| x * 10).collect_into(&mut vec);
///
/// assert_eq!(6, vec.capacity());
/// assert_eq!(vec, vec![2, 4, 6, 10, 20, 30]);
@@ -2175,8 +2172,8 @@ fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
/// .into_iter()
/// .partition(|n| n % 2 == 0);
///
- /// assert_eq!(even, vec![2]);
- /// assert_eq!(odd, vec![1, 3]);
+ /// assert_eq!(even, [2]);
+ /// assert_eq!(odd, [1, 3]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn partition<B, F>(self, f: F) -> (B, B)
@@ -2234,11 +2231,11 @@ fn extend<'a, T, B: Extend<T>>(
/// let mut a = [1, 2, 3, 4, 5, 6, 7];
///
/// // Partition in-place between evens and odds
- /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0);
+ /// let i = a.iter_mut().partition_in_place(|n| n % 2 == 0);
///
/// assert_eq!(i, 3);
- /// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens
- /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
+ /// assert!(a[..i].iter().all(|n| n % 2 == 0)); // evens
+ /// assert!(a[i..].iter().all(|n| n % 2 == 1)); // odds
/// ```
#[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")]
fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
@@ -2345,7 +2342,7 @@ fn is_partitioned<P>(mut self, mut predicate: P) -> bool
/// let a = [1, 2, 3];
///
/// // the checked sum of all of the elements of the array
- /// let sum = a.iter().try_fold(0i8, |acc, &x| acc.checked_add(x));
+ /// let sum = a.into_iter().try_fold(0i8, |acc, x| acc.checked_add(x));
///
/// assert_eq!(sum, Some(6));
/// ```
@@ -2354,16 +2351,16 @@ fn is_partitioned<P>(mut self, mut predicate: P) -> bool
///
/// ```
/// let a = [10, 20, 30, 100, 40, 50];
- /// let mut it = a.iter();
+ /// let mut iter = a.into_iter();
///
/// // This sum overflows when adding the 100 element
- /// let sum = it.try_fold(0i8, |acc, &x| acc.checked_add(x));
+ /// let sum = iter.try_fold(0i8, |acc, x| acc.checked_add(x));
/// assert_eq!(sum, None);
///
/// // Because it short-circuited, the remaining elements are still
/// // available through the iterator.
- /// assert_eq!(it.len(), 2);
- /// assert_eq!(it.next(), Some(&40));
+ /// assert_eq!(iter.len(), 2);
+ /// assert_eq!(iter.next(), Some(40));
/// ```
///
/// While you cannot `break` from a closure, the [`ControlFlow`] type allows
@@ -2716,9 +2713,9 @@ fn try_reduce<R>(
/// ```
/// let a = [1, 2, 3];
///
- /// assert!(a.iter().all(|&x| x > 0));
+ /// assert!(a.into_iter().all(|x| x > 0));
///
- /// assert!(!a.iter().all(|&x| x > 2));
+ /// assert!(!a.into_iter().all(|x| x > 2));
/// ```
///
/// Stopping at the first `false`:
@@ -2726,12 +2723,12 @@ fn try_reduce<R>(
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
- /// assert!(!iter.all(|&x| x != 2));
+ /// assert!(!iter.all(|x| x != 2));
///
/// // we can still use `iter`, as there are more elements.
- /// assert_eq!(iter.next(), Some(&3));
+ /// assert_eq!(iter.next(), Some(3));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -2769,9 +2766,9 @@ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()
/// ```
/// let a = [1, 2, 3];
///
- /// assert!(a.iter().any(|&x| x > 0));
+ /// assert!(a.into_iter().any(|x| x > 0));
///
- /// assert!(!a.iter().any(|&x| x > 5));
+ /// assert!(!a.into_iter().any(|x| x > 5));
/// ```
///
/// Stopping at the first `true`:
@@ -2779,12 +2776,12 @@ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
- /// assert!(iter.any(|&x| x != 2));
+ /// assert!(iter.any(|x| x != 2));
///
/// // we can still use `iter`, as there are more elements.
- /// assert_eq!(iter.next(), Some(&2));
+ /// assert_eq!(iter.next(), Some(2));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -2830,9 +2827,8 @@ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()
/// ```
/// let a = [1, 2, 3];
///
- /// assert_eq!(a.iter().find(|&&x| x == 2), Some(&2));
- ///
- /// assert_eq!(a.iter().find(|&&x| x == 5), None);
+ /// assert_eq!(a.into_iter().find(|&x| x == 2), Some(2));
+ /// assert_eq!(a.into_iter().find(|&x| x == 5), None);
/// ```
///
/// Stopping at the first `true`:
@@ -2840,12 +2836,12 @@ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
- /// assert_eq!(iter.find(|&&x| x == 2), Some(&2));
+ /// assert_eq!(iter.find(|&x| x == 2), Some(2));
///
/// // we can still use `iter`, as there are more elements.
- /// assert_eq!(iter.next(), Some(&3));
+ /// assert_eq!(iter.next(), Some(3));
/// ```
///
/// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`.
@@ -2913,13 +2909,13 @@ fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> Contro
/// let a = ["1", "2", "lol", "NaN", "5"];
///
/// let is_my_num = |s: &str, search: i32| -> Result<bool, std::num::ParseIntError> {
- /// Ok(s.parse::<i32>()? == search)
+ /// Ok(s.parse::<i32>()? == search)
/// };
///
- /// let result = a.iter().try_find(|&&s| is_my_num(s, 2));
- /// assert_eq!(result, Ok(Some(&"2")));
+ /// let result = a.into_iter().try_find(|&s| is_my_num(s, 2));
+ /// assert_eq!(result, Ok(Some("2")));
///
- /// let result = a.iter().try_find(|&&s| is_my_num(s, 5));
+ /// let result = a.into_iter().try_find(|&s| is_my_num(s, 5));
/// assert!(result.is_err());
/// ```
///
@@ -2931,11 +2927,11 @@ fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> Contro
/// use std::num::NonZero;
///
/// let a = [3, 5, 7, 4, 9, 0, 11u32];
- /// let result = a.iter().try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two()));
- /// assert_eq!(result, Some(Some(&4)));
- /// let result = a.iter().take(3).try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two()));
+ /// let result = a.into_iter().try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
+ /// assert_eq!(result, Some(Some(4)));
+ /// let result = a.into_iter().take(3).try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
/// assert_eq!(result, Some(None));
- /// let result = a.iter().rev().try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two()));
+ /// let result = a.into_iter().rev().try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
/// assert_eq!(result, None);
/// ```
#[inline]
@@ -3000,9 +2996,9 @@ fn check<I, V, R>(
/// ```
/// let a = [1, 2, 3];
///
- /// assert_eq!(a.iter().position(|&x| x == 2), Some(1));
+ /// assert_eq!(a.into_iter().position(|x| x == 2), Some(1));
///
- /// assert_eq!(a.iter().position(|&x| x == 5), None);
+ /// assert_eq!(a.into_iter().position(|x| x == 5), None);
/// ```
///
/// Stopping at the first `true`:
@@ -3010,15 +3006,15 @@ fn check<I, V, R>(
/// ```
/// let a = [1, 2, 3, 4];
///
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
- /// assert_eq!(iter.position(|&x| x >= 2), Some(1));
+ /// assert_eq!(iter.position(|x| x >= 2), Some(1));
///
/// // we can still use `iter`, as there are more elements.
- /// assert_eq!(iter.next(), Some(&3));
+ /// assert_eq!(iter.next(), Some(3));
///
/// // The returned index depends on iterator state
- /// assert_eq!(iter.position(|&x| x == 4), Some(0));
+ /// assert_eq!(iter.position(|x| x == 4), Some(0));
///
/// ```
#[inline]
@@ -3068,9 +3064,9 @@ fn check<'a, T>(
/// ```
/// let a = [1, 2, 3];
///
- /// assert_eq!(a.iter().rposition(|&x| x == 3), Some(2));
+ /// assert_eq!(a.into_iter().rposition(|x| x == 3), Some(2));
///
- /// assert_eq!(a.iter().rposition(|&x| x == 5), None);
+ /// assert_eq!(a.into_iter().rposition(|x| x == 5), None);
/// ```
///
/// Stopping at the first `true`:
@@ -3078,13 +3074,13 @@ fn check<'a, T>(
/// ```
/// let a = [-1, 2, 3, 4];
///
- /// let mut iter = a.iter();
+ /// let mut iter = a.into_iter();
///
- /// assert_eq!(iter.rposition(|&x| x >= 2), Some(3));
+ /// assert_eq!(iter.rposition(|x| x >= 2), Some(3));
///
/// // we can still use `iter`, as there are more elements.
- /// assert_eq!(iter.next(), Some(&-1));
- /// assert_eq!(iter.next_back(), Some(&3));
+ /// assert_eq!(iter.next(), Some(-1));
+ /// assert_eq!(iter.next_back(), Some(3));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -3130,10 +3126,10 @@ fn check<T>(
///
/// ```
/// let a = [1, 2, 3];
- /// let b: Vec<u32> = Vec::new();
+ /// let b: [u32; 0] = [];
///
- /// assert_eq!(a.iter().max(), Some(&3));
- /// assert_eq!(b.iter().max(), None);
+ /// assert_eq!(a.into_iter().max(), Some(3));
+ /// assert_eq!(b.into_iter().max(), None);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -3166,10 +3162,10 @@ fn max(self) -> Option<Self::Item>
///
/// ```
/// let a = [1, 2, 3];
- /// let b: Vec<u32> = Vec::new();
+ /// let b: [u32; 0] = [];
///
- /// assert_eq!(a.iter().min(), Some(&1));
- /// assert_eq!(b.iter().min(), None);
+ /// assert_eq!(a.into_iter().min(), Some(1));
+ /// assert_eq!(b.into_iter().min(), None);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -3191,7 +3187,7 @@ fn min(self) -> Option<Self::Item>
///
/// ```
/// let a = [-3_i32, 0, 1, 5, -10];
- /// assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10);
+ /// assert_eq!(a.into_iter().max_by_key(|x| x.abs()).unwrap(), -10);
/// ```
#[inline]
#[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
@@ -3224,7 +3220,7 @@ fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering {
///
/// ```
/// let a = [-3_i32, 0, 1, 5, -10];
- /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5);
+ /// assert_eq!(a.into_iter().max_by(|x, y| x.cmp(y)).unwrap(), 5);
/// ```
#[inline]
#[stable(feature = "iter_max_by", since = "1.15.0")]
@@ -3251,7 +3247,7 @@ fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T
///
/// ```
/// let a = [-3_i32, 0, 1, 5, -10];
- /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
+ /// assert_eq!(a.into_iter().min_by_key(|x| x.abs()).unwrap(), 0);
/// ```
#[inline]
#[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
@@ -3284,7 +3280,7 @@ fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering {
///
/// ```
/// let a = [-3_i32, 0, 1, 5, -10];
- /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10);
+ /// assert_eq!(a.into_iter().min_by(|x, y| x.cmp(y)).unwrap(), -10);
/// ```
#[inline]
#[stable(feature = "iter_min_by", since = "1.15.0")]
@@ -3314,11 +3310,11 @@ fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.iter().rev();
+ /// let mut iter = a.into_iter().rev();
///
- /// assert_eq!(iter.next(), Some(&3));
- /// assert_eq!(iter.next(), Some(&2));
- /// assert_eq!(iter.next(), Some(&1));
+ /// assert_eq!(iter.next(), Some(3));
+ /// assert_eq!(iter.next(), Some(2));
+ /// assert_eq!(iter.next(), Some(1));
///
/// assert_eq!(iter.next(), None);
/// ```
@@ -3347,7 +3343,7 @@ fn rev(self) -> Rev<Self>
/// ```
/// let a = [(1, 2), (3, 4), (5, 6)];
///
- /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
+ /// let (left, right): (Vec<_>, Vec<_>) = a.into_iter().unzip();
///
/// assert_eq!(left, [1, 3, 5]);
/// assert_eq!(right, [2, 4, 6]);
@@ -3355,7 +3351,7 @@ fn rev(self) -> Rev<Self>
/// // you can also unzip multiple nested tuples at once
/// let a = [(1, (2, 3)), (4, (5, 6))];
///
- /// let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.iter().cloned().unzip();
+ /// let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.into_iter().unzip();
/// assert_eq!(x, [1, 4]);
/// assert_eq!(y, [2, 5]);
/// assert_eq!(z, [3, 6]);
@@ -3387,8 +3383,8 @@ fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
/// // copied is the same as .map(|&x| x)
/// let v_map: Vec<_> = a.iter().map(|&x| x).collect();
///
- /// assert_eq!(v_copied, vec![1, 2, 3]);
- /// assert_eq!(v_map, vec![1, 2, 3]);
+ /// assert_eq!(v_copied, [1, 2, 3]);
+ /// assert_eq!(v_map, [1, 2, 3]);
/// ```
#[stable(feature = "iter_copied", since = "1.36.0")]
#[rustc_diagnostic_item = "iter_copied"]
@@ -3423,8 +3419,8 @@ fn copied<'a, T: 'a>(self) -> Copied<Self>
/// // cloned is the same as .map(|&x| x), for integers
/// let v_map: Vec<_> = a.iter().map(|&x| x).collect();
///
- /// assert_eq!(v_cloned, vec![1, 2, 3]);
- /// assert_eq!(v_map, vec![1, 2, 3]);
+ /// assert_eq!(v_cloned, [1, 2, 3]);
+ /// assert_eq!(v_map, [1, 2, 3]);
/// ```
///
/// To get the best performance, try to clone late:
@@ -3460,15 +3456,14 @@ fn cloned<'a, T: 'a>(self) -> Cloned<Self>
/// ```
/// let a = [1, 2, 3];
///
- /// let mut it = a.iter().cycle();
+ /// let mut iter = a.into_iter().cycle();
///
- /// assert_eq!(it.next(), Some(&1));
- /// assert_eq!(it.next(), Some(&2));
- /// assert_eq!(it.next(), Some(&3));
- /// assert_eq!(it.next(), Some(&1));
- /// assert_eq!(it.next(), Some(&2));
- /// assert_eq!(it.next(), Some(&3));
- /// assert_eq!(it.next(), Some(&1));
+ /// loop {
+ /// assert_eq!(iter.next(), Some(1));
+ /// assert_eq!(iter.next(), Some(2));
+ /// assert_eq!(iter.next(), Some(3));
+ /// # break;
+ /// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
@@ -3626,9 +3621,9 @@ fn cmp<I>(self, other: I) -> Ordering
/// let xs = [1, 2, 3, 4];
/// let ys = [1, 4, 9, 16];
///
- /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| x.cmp(&y)), Ordering::Less);
- /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (x * x).cmp(&y)), Ordering::Equal);
- /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
+ /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| x.cmp(&y)), Ordering::Less);
+ /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| (x * x).cmp(&y)), Ordering::Equal);
+ /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| (2 * x).cmp(&y)), Ordering::Greater);
/// ```
#[unstable(feature = "iter_order_by", issue = "64295")]
fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
@@ -3710,15 +3705,15 @@ fn partial_cmp<I>(self, other: I) -> Option<Ordering>
/// let ys = [1.0, 4.0, 9.0, 16.0];
///
/// assert_eq!(
- /// xs.iter().partial_cmp_by(&ys, |&x, &y| x.partial_cmp(&y)),
+ /// xs.iter().partial_cmp_by(ys, |x, y| x.partial_cmp(&y)),
/// Some(Ordering::Less)
/// );
/// assert_eq!(
- /// xs.iter().partial_cmp_by(&ys, |&x, &y| (x * x).partial_cmp(&y)),
+ /// xs.iter().partial_cmp_by(ys, |x, y| (x * x).partial_cmp(&y)),
/// Some(Ordering::Equal)
/// );
/// assert_eq!(
- /// xs.iter().partial_cmp_by(&ys, |&x, &y| (2.0 * x).partial_cmp(&y)),
+ /// xs.iter().partial_cmp_by(ys, |x, y| (2.0 * x).partial_cmp(&y)),
/// Some(Ordering::Greater)
/// );
/// ```
@@ -3776,7 +3771,7 @@ fn eq<I>(self, other: I) -> bool
/// let xs = [1, 2, 3, 4];
/// let ys = [1, 4, 9, 16];
///
- /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y));
+ /// assert!(xs.iter().eq_by(ys, |x, y| x * x == y));
/// ```
#[unstable(feature = "iter_order_by", issue = "64295")]
fn eq_by<I, F>(self, other: I, eq: F) -> bool
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 3ad6662..7dc8c06 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1661,7 +1661,6 @@ macro_rules! trace_macros {
#[unstable(
feature = "test",
issue = "50297",
- soft,
reason = "`bench` is a part of custom test frameworks which are unstable"
)]
#[allow_internal_unstable(test, rustc_attrs, coverage_attribute)]
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 36a1c57..79e9b84 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -543,18 +543,18 @@ pub fn column(&self) -> usize {
/// The path to the source file in which this span occurs, for display purposes.
///
/// This might not correspond to a valid file system path.
- /// It might be remapped, or might be an artificial path such as `"<macro expansion>"`.
- #[unstable(feature = "proc_macro_span", issue = "54725")]
+ /// It might be remapped (e.g. `"/src/lib.rs"`) or an artificial path (e.g. `"<command line>"`).
+ #[stable(feature = "proc_macro_span_file", since = "CURRENT_RUSTC_VERSION")]
pub fn file(&self) -> String {
self.0.file()
}
- /// The path to the source file in which this span occurs on disk.
+ /// The path to the source file in which this span occurs on the local file system.
///
/// This is the actual path on disk. It is unaffected by path remapping.
///
/// This path should not be embedded in the output of the macro; prefer `file()` instead.
- #[unstable(feature = "proc_macro_span", issue = "54725")]
+ #[stable(feature = "proc_macro_span_file", since = "CURRENT_RUSTC_VERSION")]
pub fn local_file(&self) -> Option<PathBuf> {
self.0.local_file().map(|s| PathBuf::from(s))
}
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 06bec74..7915196 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.157" }
+compiler_builtins = { version = "=0.1.158" }
unwind = { path = "../unwind" }
hashbrown = { version = "0.15", default-features = false, features = [
'rustc-dep-of-std',
@@ -57,7 +57,7 @@
'archive',
] }
-[target.'cfg(windows)'.dependencies.windows-targets]
+[target.'cfg(any(windows, target_os = "cygwin"))'.dependencies.windows-targets]
path = "../windows_targets"
[dev-dependencies]
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 46b0d83..c81a5ff 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -730,6 +730,10 @@ fn recursive_mkdir_empty() {
}
#[test]
+#[cfg_attr(
+ all(windows, target_arch = "aarch64"),
+ ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94"
+)]
fn recursive_rmdir() {
let tmpdir = tmpdir();
let d1 = tmpdir.join("d1");
@@ -749,6 +753,10 @@ fn recursive_rmdir() {
}
#[test]
+#[cfg_attr(
+ all(windows, target_arch = "aarch64"),
+ ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94"
+)]
fn recursive_rmdir_of_symlink() {
// test we do not recursively delete a symlink but only dirs.
let tmpdir = tmpdir();
@@ -1533,6 +1541,10 @@ fn file_open_not_found() {
}
#[test]
+#[cfg_attr(
+ all(windows, target_arch = "aarch64"),
+ ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94"
+)]
fn create_dir_all_with_junctions() {
let tmpdir = tmpdir();
let target = tmpdir.join("target");
@@ -2011,6 +2023,10 @@ fn test_rename_symlink() {
#[test]
#[cfg(windows)]
+#[cfg_attr(
+ all(windows, target_arch = "aarch64"),
+ ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94"
+)]
fn test_rename_junction() {
let tmpdir = tmpdir();
let original = tmpdir.join("original");
diff --git a/library/std/src/sys/pal/unix/fuchsia.rs b/library/std/src/sys/pal/unix/fuchsia.rs
index 7932bd2..c118dee 100644
--- a/library/std/src/sys/pal/unix/fuchsia.rs
+++ b/library/std/src/sys/pal/unix/fuchsia.rs
@@ -1,48 +1,35 @@
-#![allow(non_camel_case_types, unused)]
+#![expect(non_camel_case_types)]
-use libc::{c_int, c_void, size_t};
+use libc::size_t;
+use crate::ffi::{c_char, c_int, c_void};
use crate::io;
-use crate::mem::MaybeUninit;
-use crate::os::raw::c_char;
+
+//////////
+// Time //
+//////////
+
+pub type zx_time_t = i64;
+
+pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
+
+unsafe extern "C" {
+ pub safe fn zx_clock_get_monotonic() -> zx_time_t;
+}
+
+/////////////
+// Handles //
+/////////////
pub type zx_handle_t = u32;
-pub type zx_vaddr_t = usize;
-pub type zx_rights_t = u32;
-pub type zx_status_t = i32;
pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
-pub type zx_time_t = i64;
-pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
-
-pub type zx_signals_t = u32;
-
-pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
-
-pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
-
-pub const ZX_RIGHT_SAME_RIGHTS: zx_rights_t = 1 << 31;
-
-// The upper four bits gives the minor version.
-pub type zx_object_info_topic_t = u32;
-
-pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28);
-
-pub type zx_info_process_flags_t = u32;
-
-pub fn zx_cvt<T>(t: T) -> io::Result<T>
-where
- T: TryInto<zx_status_t> + Copy,
-{
- if let Ok(status) = TryInto::try_into(t) {
- if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
- } else {
- Err(io::Error::last_os_error())
- }
+unsafe extern "C" {
+ pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
}
-// Safe wrapper around zx_handle_t
+/// A safe wrapper around `zx_handle_t`.
pub struct Handle {
raw: zx_handle_t,
}
@@ -65,6 +52,66 @@ fn drop(&mut self) {
}
}
+///////////
+// Futex //
+///////////
+
+pub type zx_futex_t = crate::sync::atomic::Atomic<u32>;
+
+unsafe extern "C" {
+ pub fn zx_object_wait_one(
+ handle: zx_handle_t,
+ signals: zx_signals_t,
+ timeout: zx_time_t,
+ pending: *mut zx_signals_t,
+ ) -> zx_status_t;
+
+ pub fn zx_futex_wait(
+ value_ptr: *const zx_futex_t,
+ current_value: zx_futex_t,
+ new_futex_owner: zx_handle_t,
+ deadline: zx_time_t,
+ ) -> zx_status_t;
+ pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
+ pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t;
+ pub safe fn zx_thread_self() -> zx_handle_t;
+}
+
+////////////////
+// Properties //
+////////////////
+
+pub const ZX_PROP_NAME: u32 = 3;
+
+unsafe extern "C" {
+ pub fn zx_object_set_property(
+ handle: zx_handle_t,
+ property: u32,
+ value: *const libc::c_void,
+ value_size: libc::size_t,
+ ) -> zx_status_t;
+}
+
+/////////////
+// Signals //
+/////////////
+
+pub type zx_signals_t = u32;
+
+pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
+pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
+
+/////////////////
+// Object info //
+/////////////////
+
+// The upper four bits gives the minor version.
+pub type zx_object_info_topic_t = u32;
+
+pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28);
+
+pub type zx_info_process_flags_t = u32;
+
// Returned for topic ZX_INFO_PROCESS
#[derive(Default)]
#[repr(C)]
@@ -76,25 +123,6 @@ pub struct zx_info_process_t {
}
unsafe extern "C" {
- pub fn zx_job_default() -> zx_handle_t;
-
- pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
-
- pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
-
- pub fn zx_handle_duplicate(
- handle: zx_handle_t,
- rights: zx_rights_t,
- out: *const zx_handle_t,
- ) -> zx_handle_t;
-
- pub fn zx_object_wait_one(
- handle: zx_handle_t,
- signals: zx_signals_t,
- timeout: zx_time_t,
- pending: *mut zx_signals_t,
- ) -> zx_status_t;
-
pub fn zx_object_get_info(
handle: zx_handle_t,
topic: u32,
@@ -105,6 +133,10 @@ pub fn zx_object_get_info(
) -> zx_status_t;
}
+///////////////
+// Processes //
+///////////////
+
#[derive(Default)]
#[repr(C)]
pub struct fdio_spawn_action_t {
@@ -130,6 +162,8 @@ pub fn fdio_spawn_etc(
pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t;
pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t;
+
+ pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
}
// fdio_spawn_etc flags
@@ -137,173 +171,34 @@ pub fn fdio_spawn_etc(
pub const FDIO_SPAWN_CLONE_JOB: u32 = 0x0001;
pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002;
pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004;
-pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008;
pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010;
pub const FDIO_SPAWN_CLONE_UTC_CLOCK: u32 = 0x0020;
-pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF;
// fdio_spawn_etc actions
-pub const FDIO_SPAWN_ACTION_CLONE_FD: u32 = 0x0001;
pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
-// Errors
+////////////
+// Errors //
+////////////
-#[allow(unused)]
-pub const ERR_INTERNAL: zx_status_t = -1;
+pub type zx_status_t = i32;
-// ERR_NOT_SUPPORTED: The operation is not implemented, supported,
-// or enabled.
-#[allow(unused)]
-pub const ERR_NOT_SUPPORTED: zx_status_t = -2;
+pub const ZX_OK: zx_status_t = 0;
+pub const ZX_ERR_NOT_SUPPORTED: zx_status_t = -2;
+pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10;
+pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11;
+pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12;
+pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
+pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
-// ERR_NO_RESOURCES: The system was not able to allocate some resource
-// needed for the operation.
-#[allow(unused)]
-pub const ERR_NO_RESOURCES: zx_status_t = -3;
-
-// ERR_NO_MEMORY: The system was not able to allocate memory needed
-// for the operation.
-#[allow(unused)]
-pub const ERR_NO_MEMORY: zx_status_t = -4;
-
-// ERR_CALL_FAILED: The second phase of zx_channel_call(; did not complete
-// successfully.
-#[allow(unused)]
-pub const ERR_CALL_FAILED: zx_status_t = -5;
-
-// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be
-// retried. This should not be seen outside of the VDSO.
-#[allow(unused)]
-pub const ERR_INTERRUPTED_RETRY: zx_status_t = -6;
-
-// ======= Parameter errors =======
-// ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
-#[allow(unused)]
-pub const ERR_INVALID_ARGS: zx_status_t = -10;
-
-// ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
-#[allow(unused)]
-pub const ERR_BAD_HANDLE: zx_status_t = -11;
-
-// ERR_WRONG_TYPE: The subject of the operation is the wrong type to
-// perform the operation.
-// Example: Attempting a message_read on a thread handle.
-#[allow(unused)]
-pub const ERR_WRONG_TYPE: zx_status_t = -12;
-
-// ERR_BAD_SYSCALL: The specified syscall number is invalid.
-#[allow(unused)]
-pub const ERR_BAD_SYSCALL: zx_status_t = -13;
-
-// ERR_OUT_OF_RANGE: An argument is outside the valid range for this
-// operation.
-#[allow(unused)]
-pub const ERR_OUT_OF_RANGE: zx_status_t = -14;
-
-// ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
-// this operation.
-#[allow(unused)]
-pub const ERR_BUFFER_TOO_SMALL: zx_status_t = -15;
-
-// ======= Precondition or state errors =======
-// ERR_BAD_STATE: operation failed because the current state of the
-// object does not allow it, or a precondition of the operation is
-// not satisfied
-#[allow(unused)]
-pub const ERR_BAD_STATE: zx_status_t = -20;
-
-// ERR_TIMED_OUT: The time limit for the operation elapsed before
-// the operation completed.
-#[allow(unused)]
-pub const ERR_TIMED_OUT: zx_status_t = -21;
-
-// ERR_SHOULD_WAIT: The operation cannot be performed currently but
-// potentially could succeed if the caller waits for a prerequisite
-// to be satisfied, for example waiting for a handle to be readable
-// or writable.
-// Example: Attempting to read from a message pipe that has no
-// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
-// Attempting to read from a message pipe that has no messages waiting
-// and has a closed remote end will return ERR_REMOTE_CLOSED.
-#[allow(unused)]
-pub const ERR_SHOULD_WAIT: zx_status_t = -22;
-
-// ERR_CANCELED: The in-progress operation (e.g., a wait) has been
-// // canceled.
-#[allow(unused)]
-pub const ERR_CANCELED: zx_status_t = -23;
-
-// ERR_PEER_CLOSED: The operation failed because the remote end
-// of the subject of the operation was closed.
-#[allow(unused)]
-pub const ERR_PEER_CLOSED: zx_status_t = -24;
-
-// ERR_NOT_FOUND: The requested entity is not found.
-#[allow(unused)]
-pub const ERR_NOT_FOUND: zx_status_t = -25;
-
-// ERR_ALREADY_EXISTS: An object with the specified identifier
-// already exists.
-// Example: Attempting to create a file when a file already exists
-// with that name.
-#[allow(unused)]
-pub const ERR_ALREADY_EXISTS: zx_status_t = -26;
-
-// ERR_ALREADY_BOUND: The operation failed because the named entity
-// is already owned or controlled by another entity. The operation
-// could succeed later if the current owner releases the entity.
-#[allow(unused)]
-pub const ERR_ALREADY_BOUND: zx_status_t = -27;
-
-// ERR_UNAVAILABLE: The subject of the operation is currently unable
-// to perform the operation.
-// Note: This is used when there's no direct way for the caller to
-// observe when the subject will be able to perform the operation
-// and should thus retry.
-#[allow(unused)]
-pub const ERR_UNAVAILABLE: zx_status_t = -28;
-
-// ======= Permission check errors =======
-// ERR_ACCESS_DENIED: The caller did not have permission to perform
-// the specified operation.
-#[allow(unused)]
-pub const ERR_ACCESS_DENIED: zx_status_t = -30;
-
-// ======= Input-output errors =======
-// ERR_IO: Otherwise unspecified error occurred during I/O.
-#[allow(unused)]
-pub const ERR_IO: zx_status_t = -40;
-
-// ERR_REFUSED: The entity the I/O operation is being performed on
-// rejected the operation.
-// Example: an I2C device NAK'ing a transaction or a disk controller
-// rejecting an invalid command.
-#[allow(unused)]
-pub const ERR_IO_REFUSED: zx_status_t = -41;
-
-// ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
-// check and is possibly corrupted.
-// Example: CRC or Parity error.
-#[allow(unused)]
-pub const ERR_IO_DATA_INTEGRITY: zx_status_t = -42;
-
-// ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
-// and may be permanently lost.
-// Example: A disk block is irrecoverably damaged.
-#[allow(unused)]
-pub const ERR_IO_DATA_LOSS: zx_status_t = -43;
-
-// Filesystem specific errors
-#[allow(unused)]
-pub const ERR_BAD_PATH: zx_status_t = -50;
-#[allow(unused)]
-pub const ERR_NOT_DIR: zx_status_t = -51;
-#[allow(unused)]
-pub const ERR_NOT_FILE: zx_status_t = -52;
-// ERR_FILE_BIG: A file exceeds a filesystem-specific size limit.
-#[allow(unused)]
-pub const ERR_FILE_BIG: zx_status_t = -53;
-// ERR_NO_SPACE: Filesystem or device space is exhausted.
-#[allow(unused)]
-pub const ERR_NO_SPACE: zx_status_t = -54;
+pub fn zx_cvt<T>(t: T) -> io::Result<T>
+where
+ T: TryInto<zx_status_t> + Copy,
+{
+ if let Ok(status) = TryInto::try_into(t) {
+ if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
+ } else {
+ Err(io::Error::last_os_error())
+ }
+}
diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs
index 8d89163..c23278b 100644
--- a/library/std/src/sys/pal/unix/futex.rs
+++ b/library/std/src/sys/pal/unix/futex.rs
@@ -255,66 +255,28 @@ pub fn futex_wake_all(futex: &Atomic<u32>) {
}
#[cfg(target_os = "fuchsia")]
-pub mod zircon {
- pub type zx_futex_t = crate::sync::atomic::Atomic<u32>;
- pub type zx_handle_t = u32;
- pub type zx_status_t = i32;
- pub type zx_time_t = i64;
-
- pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
-
- pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX;
-
- pub const ZX_OK: zx_status_t = 0;
- pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10;
- pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11;
- pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12;
- pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
- pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
-
- unsafe extern "C" {
- pub fn zx_clock_get_monotonic() -> zx_time_t;
- pub fn zx_futex_wait(
- value_ptr: *const zx_futex_t,
- current_value: zx_futex_t,
- new_futex_owner: zx_handle_t,
- deadline: zx_time_t,
- ) -> zx_status_t;
- pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
- pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t;
- pub fn zx_thread_self() -> zx_handle_t;
- }
-}
-
-#[cfg(target_os = "fuchsia")]
pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>) -> bool {
+ use super::fuchsia::*;
+
// Sleep forever if the timeout is longer than fits in a i64.
let deadline = timeout
- .and_then(|d| {
- i64::try_from(d.as_nanos())
- .ok()?
- .checked_add(unsafe { zircon::zx_clock_get_monotonic() })
- })
- .unwrap_or(zircon::ZX_TIME_INFINITE);
+ .and_then(|d| i64::try_from(d.as_nanos()).ok()?.checked_add(zx_clock_get_monotonic()))
+ .unwrap_or(ZX_TIME_INFINITE);
unsafe {
- zircon::zx_futex_wait(
- futex,
- core::sync::atomic::AtomicU32::new(expected),
- zircon::ZX_HANDLE_INVALID,
- deadline,
- ) != zircon::ZX_ERR_TIMED_OUT
+ zx_futex_wait(futex, zx_futex_t::new(expected), ZX_HANDLE_INVALID, deadline)
+ != ZX_ERR_TIMED_OUT
}
}
// Fuchsia doesn't tell us how many threads are woken up, so this always returns false.
#[cfg(target_os = "fuchsia")]
pub fn futex_wake(futex: &Atomic<u32>) -> bool {
- unsafe { zircon::zx_futex_wake(futex, 1) };
+ unsafe { super::fuchsia::zx_futex_wake(futex, 1) };
false
}
#[cfg(target_os = "fuchsia")]
pub fn futex_wake_all(futex: &Atomic<u32>) {
- unsafe { zircon::zx_futex_wake(futex, u32::MAX) };
+ unsafe { super::fuchsia::zx_futex_wake(futex, u32::MAX) };
}
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 4cdc2ea..afda7c6 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -22,23 +22,6 @@
#[cfg(any(target_os = "espidf", target_os = "nuttx"))]
pub const DEFAULT_MIN_STACK_SIZE: usize = 0; // 0 indicates that the stack size configured in the ESP-IDF/NuttX menuconfig system should be used
-#[cfg(target_os = "fuchsia")]
-mod zircon {
- type zx_handle_t = u32;
- type zx_status_t = i32;
- pub const ZX_PROP_NAME: u32 = 3;
-
- unsafe extern "C" {
- pub fn zx_object_set_property(
- handle: zx_handle_t,
- property: u32,
- value: *const libc::c_void,
- value_size: libc::size_t,
- ) -> zx_status_t;
- pub fn zx_thread_self() -> zx_handle_t;
- }
-}
-
pub struct Thread {
id: libc::pthread_t,
}
@@ -216,7 +199,7 @@ fn pthread_setname_np(
#[cfg(target_os = "fuchsia")]
pub fn set_name(name: &CStr) {
- use self::zircon::*;
+ use super::fuchsia::*;
unsafe {
zx_object_set_property(
zx_thread_self(),
diff --git a/library/std/src/sys/process/unix/fuchsia.rs b/library/std/src/sys/process/unix/fuchsia.rs
index fbe06c4..017ab91 100644
--- a/library/std/src/sys/process/unix/fuchsia.rs
+++ b/library/std/src/sys/process/unix/fuchsia.rs
@@ -76,7 +76,7 @@ unsafe fn do_exec(
let mut handle = ZX_HANDLE_INVALID;
let status = fdio_fd_clone(target_fd, &mut handle);
- if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED {
+ if status == ZX_ERR_INVALID_ARGS || status == ZX_ERR_NOT_SUPPORTED {
// This descriptor is closed; skip it rather than generating an
// error.
return Ok(Default::default());
@@ -192,7 +192,7 @@ pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED, 0, ptr::null_mut());
match status {
0 => {} // Success
- x if x == ERR_TIMED_OUT => {
+ x if x == ZX_ERR_TIMED_OUT => {
return Ok(None);
}
_ => {
diff --git a/library/std/src/sys/process/unix/mod.rs b/library/std/src/sys/process/unix/mod.rs
index 2e8b38f..ee8fd8b 100644
--- a/library/std/src/sys/process/unix/mod.rs
+++ b/library/std/src/sys/process/unix/mod.rs
@@ -11,6 +11,7 @@
} else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] {
mod unsupported;
use unsupported as imp;
+ pub use unsupported::output;
} else {
mod unix;
use unix as imp;
diff --git a/library/std/src/sys/sync/mutex/fuchsia.rs b/library/std/src/sys/sync/mutex/fuchsia.rs
index 3d388a4..cbb1926 100644
--- a/library/std/src/sys/sync/mutex/fuchsia.rs
+++ b/library/std/src/sys/sync/mutex/fuchsia.rs
@@ -39,7 +39,7 @@
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use crate::sync::atomic::{Atomic, AtomicU32};
-use crate::sys::futex::zircon::{
+use crate::sys::fuchsia::{
ZX_ERR_BAD_HANDLE, ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE,
ZX_OK, ZX_TIME_INFINITE, zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t,
zx_thread_self,
@@ -83,13 +83,13 @@ pub const fn new() -> Mutex {
#[inline]
pub fn try_lock(&self) -> bool {
- let thread_self = unsafe { zx_thread_self() };
+ let thread_self = zx_thread_self();
self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed).is_ok()
}
#[inline]
pub fn lock(&self) {
- let thread_self = unsafe { zx_thread_self() };
+ let thread_self = zx_thread_self();
if let Err(state) =
self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed)
{
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index acaf026..7f56d1e 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -98,6 +98,15 @@ pub mod test {
// The default console test runner. It accepts the command line
// arguments and a vector of test_descs.
pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Option<Options>) {
+ test_main_with_exit_callback(args, tests, options, || {})
+}
+
+pub fn test_main_with_exit_callback<F: FnOnce()>(
+ args: &[String],
+ tests: Vec<TestDescAndFn>,
+ options: Option<Options>,
+ exit_callback: F,
+) {
let mut opts = match cli::parse_opts(args) {
Some(Ok(o)) => o,
Some(Err(msg)) => {
@@ -151,6 +160,7 @@ pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Option<Opt
let res = console::run_tests_console(&opts, tests);
// Prevent Valgrind from reporting reachable blocks in users' unit tests.
drop(panic::take_hook());
+ exit_callback();
match res {
Ok(true) => {}
Ok(false) => process::exit(ERROR_EXIT_CODE),
diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs
index c7d1585..bce54c5 100644
--- a/library/windows_targets/src/lib.rs
+++ b/library/windows_targets/src/lib.rs
@@ -34,6 +34,7 @@
}
#[cfg(not(feature = "windows_raw_dylib"))]
+#[cfg(not(target_os = "cygwin"))] // Cygwin doesn't need these libs
#[cfg_attr(target_vendor = "win7", link(name = "advapi32"))]
#[link(name = "ntdll")]
#[link(name = "userenv")]
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index cbfe00a..833f802 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -163,7 +163,7 @@ fn check_version(config: &Config) -> Option<String> {
msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n");
msg.push_str("NOTE: to silence this warning, ");
msg.push_str(&format!(
- "add `change-id = {latest_change_id}` or change-id = \"ignore\" at the top of `bootstrap.toml`"
+ "add `change-id = {latest_change_id}` or `change-id = \"ignore\"` at the top of `bootstrap.toml`"
));
return Some(msg);
}
@@ -195,7 +195,7 @@ fn check_version(config: &Config) -> Option<String> {
msg.push_str("NOTE: to silence this warning, ");
msg.push_str(&format!(
- "update `bootstrap.toml` to use `change-id = {latest_change_id}` or change-id = \"ignore\" instead"
+ "update `bootstrap.toml` to use `change-id = {latest_change_id}` or `change-id = \"ignore\"` instead"
));
if io::stdout().is_terminal() {
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 9da8b27..93900a9 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -9,7 +9,7 @@
use build_helper::git::get_git_modified_files;
use ignore::WalkBuilder;
-use crate::core::builder::Builder;
+use crate::core::builder::{Builder, Kind};
use crate::utils::build_stamp::BuildStamp;
use crate::utils::exec::command;
use crate::utils::helpers::{self, t};
@@ -122,6 +122,12 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
}
pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
+ if build.kind == Kind::Format && build.top_stage != 0 {
+ eprintln!("ERROR: `x fmt` only supports stage 0.");
+ eprintln!("HELP: Use `x run rustfmt` to run in-tree rustfmt.");
+ crate::exit!(1);
+ }
+
if !paths.is_empty() {
eprintln!(
"fmt error: path arguments are no longer accepted; use `--all` to format everything"
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index 7ff3850..0bba441 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -420,3 +420,56 @@ fn run(self, builder: &Builder<'_>) {
cmd.run(builder);
}
}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Rustfmt;
+
+impl Step for Rustfmt {
+ type Output = ();
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/rustfmt")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(Rustfmt);
+ }
+
+ fn run(self, builder: &Builder<'_>) {
+ let host = builder.build.build;
+
+ // `x run` uses stage 0 by default but rustfmt does not work well with stage 0.
+ // Change the stage to 1 if it's not set explicitly.
+ let stage = if builder.config.is_explicit_stage() || builder.top_stage >= 1 {
+ builder.top_stage
+ } else {
+ 1
+ };
+
+ if stage == 0 {
+ eprintln!("rustfmt cannot be run at stage 0");
+ eprintln!("HELP: Use `x fmt` to use stage 0 rustfmt.");
+ std::process::exit(1);
+ }
+
+ let compiler = builder.compiler(stage, host);
+ let rustfmt_build = builder.ensure(tool::Rustfmt { compiler, target: host });
+
+ let mut rustfmt = tool::prepare_tool_cargo(
+ builder,
+ rustfmt_build.build_compiler,
+ Mode::ToolRustc,
+ host,
+ Kind::Run,
+ "src/tools/rustfmt",
+ SourceType::InTree,
+ &[],
+ );
+
+ rustfmt.args(["--bin", "rustfmt", "--"]);
+ rustfmt.args(builder.config.args());
+
+ rustfmt.into_cmd().run(builder);
+ }
+}
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 15dc338..75cc5d3 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -1116,6 +1116,7 @@ macro_rules! describe {
run::FeaturesStatusDump,
run::CyclicStep,
run::CoverageDump,
+ run::Rustfmt,
),
Kind::Setup => {
describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor)
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index d926185..1d0ea3e 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -406,4 +406,9 @@ pub fn human_readable_changes(changes: &[ChangeInfo]) -> String {
severity: ChangeSeverity::Info,
summary: "Added a new option `rust.debug-assertions-tools` to control debug asssertions for tools.",
},
+ ChangeInfo {
+ change_id: 140732,
+ severity: ChangeSeverity::Info,
+ summary: "`./x run` now supports running in-tree `rustfmt`, e.g., `./x run rustfmt -- --check /path/to/file.rs`.",
+ },
];
diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md
index f31da5c..85e57dd 100644
--- a/src/doc/rustc-dev-guide/src/mir/dataflow.md
+++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md
@@ -148,8 +148,7 @@
```rust,ignore
let mut results = MyAnalysis::new()
- .into_engine(tcx, body, def_id)
- .iterate_to_fixpoint()
+ .iterate_to_fixpoint(tcx, body, None);
.into_results_cursor(body);
// Inspect the fixpoint state immediately before each `Drop` terminator.
diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md
index c04f296..825be11 100644
--- a/src/doc/rustc-dev-guide/src/tests/ci.md
+++ b/src/doc/rustc-dev-guide/src/tests/ci.md
@@ -135,12 +135,16 @@
- Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it
passes the test suite executed by that job.
-You can select which CI jobs will
-be executed in the try build by adding lines containing `try-job:
-<job pattern>` to the PR description. All such specified jobs will be executed
-in the try build once the `@bors try` command is used on the PR. If no try
-jobs are specified in this way, the jobs defined in the `try` section of
-[`jobs.yml`] will be executed by default.
+By default, if you send a comment with `@bors try`, the jobs defined in the `try` section of
+[`jobs.yml`] will be executed. We call this mode a "fast try build". Such a try build
+will not execute any tests, and it will allow compilation warnings. It is useful when you want to
+get an optimized toolchain as fast as possible, for a crater run or performance benchmarks,
+even if it might not be working fully correctly.
+
+If you want to run a custom CI job in a try build and make sure that it passes all tests and does
+not produce any compilation warnings, you can select CI jobs to be executed by adding lines
+containing `try-job: <job pattern>` to the PR description. All such specified jobs will be executed
+in the try build once the `@bors try` command is used on the PR.
Each pattern can either be an exact name of a job or a glob pattern that matches multiple jobs,
for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index cf41f5b8..a3939e5 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -58,6 +58,7 @@
- [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md)
- [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md)
- [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md)
+ - [armv5te-unknown-linux-gnueabi](platform-support/armv5te-unknown-linux-gnueabi.md)
- [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
- [armv7-rtems-eabihf](platform-support/armv7-rtems-eabihf.md)
- [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 50c7ae3..60002a5 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -156,7 +156,7 @@
[`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ✓ | Arm64EC Windows MSVC
[`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian
[`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat
-`armv5te-unknown-linux-gnueabi` | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23)
+[`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23)
`armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.3
[`armv7-linux-androideabi`](platform-support/android.md) | ✓ | Armv7-A Android
`armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15, glibc 2.27)
diff --git a/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md
new file mode 100644
index 0000000..1baf104
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md
@@ -0,0 +1,29 @@
+# `armv5te-unknown-linux-gnueabi`
+
+**Tier: 2**
+
+This target supports Linux programs with glibc on ARMv5TE CPUs without
+floating-point units.
+
+## Target maintainers
+
+[@koalatux](https://github.com/koalatux)
+
+## Requirements
+
+The target is for cross-compilation only. Host tools are not supported.
+std is fully supported.
+
+## Building the target
+
+Because this target is tier 2, artifacts are available from rustup.
+
+## Building Rust programs
+
+For building rust programs, you might want to specify GCC as linker in
+`.cargo/config.toml` as follows:
+
+```toml
+[target.armv5te-unknown-linux-gnueabi]
+linker = "arm-linux-gnueabi-gcc"
+```
diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md
index 19e62c4..81b7ff5 100644
--- a/src/doc/style-guide/src/editions.md
+++ b/src/doc/style-guide/src/editions.md
@@ -26,6 +26,10 @@
Not all Rust editions have corresponding changes to the Rust style. For
instance, Rust 2015, Rust 2018, and Rust 2021 all use the same style edition.
+## Rust next style edition
+
+- Never break within a nullary function call `func()` or a unit literal `()`.
+
## Rust 2024 style edition
This style guide describes the Rust 2024 style edition. The Rust 2024 style
diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md
index 031e59d..9df5d7d 100644
--- a/src/doc/style-guide/src/expressions.md
+++ b/src/doc/style-guide/src/expressions.md
@@ -183,6 +183,10 @@
};
```
+## Unit literals
+
+Never break between the opening and closing parentheses of the `()` unit literal.
+
## Tuple literals
Use a single-line form where possible. Do not put spaces between the opening
@@ -377,6 +381,11 @@
Prefer not to break a line in the callee expression.
+For a function call with no arguments (a nullary function call like `func()`),
+never break within the parentheses, and never put a space between the
+parentheses. Always write a nullary function call as a single-line call, never
+a multi-line call.
+
### Single-line calls
Do not put a space between the function name and open paren, between the open
diff --git a/src/doc/style-guide/src/nightly.md b/src/doc/style-guide/src/nightly.md
index d870edf..66e7fa3 100644
--- a/src/doc/style-guide/src/nightly.md
+++ b/src/doc/style-guide/src/nightly.md
@@ -5,15 +5,3 @@
Style and formatting for nightly-only syntax should be removed from this chapter and integrated into the appropriate sections of the style guide at the time of stabilization.
There is no guarantee of the stability of this chapter in contrast to the rest of the style guide. Refer to the style team policy for nightly formatting procedure regarding breaking changes to this chapter.
-
-### `feature(precise_capturing)`
-
-A `use<'a, T>` precise capturing bound is formatted as if it were a single path segment with non-turbofished angle-bracketed args, like a trait bound whose identifier is `use`.
-
-```
-fn foo() -> impl Sized + use<'a> {}
-
-// is formatted analogously to:
-
-fn foo() -> impl Sized + Use<'a> {}
-```
diff --git a/src/doc/style-guide/src/types.md b/src/doc/style-guide/src/types.md
index b7921c8..247f05b 100644
--- a/src/doc/style-guide/src/types.md
+++ b/src/doc/style-guide/src/types.md
@@ -59,3 +59,15 @@
+ Debug
>
```
+
+## Precise capturing bounds
+
+A `use<'a, T>` precise capturing bound is formatted as if it were a single path segment with non-turbofished angle-bracketed args, like a trait bound whose identifier is `use`.
+
+```rust
+fn foo() -> impl Sized + use<'a> {}
+
+// is formatted analogously to:
+
+fn foo() -> impl Sized + Use<'a> {}
+```
diff --git a/src/doc/unstable-book/src/language-features/deref-patterns.md b/src/doc/unstable-book/src/language-features/deref-patterns.md
index fb6df29..4c3d456 100644
--- a/src/doc/unstable-book/src/language-features/deref-patterns.md
+++ b/src/doc/unstable-book/src/language-features/deref-patterns.md
@@ -60,8 +60,7 @@
# #![feature(deref_patterns)]
# #![allow(incomplete_features)]
struct NoCopy;
-// Match exhaustiveness analysis is not yet implemented.
-let deref!(x) = Box::new(NoCopy) else { unreachable!() };
+let deref!(x) = Box::new(NoCopy);
drop::<NoCopy>(x);
```
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 27ae055..dbfdd8e 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -14,7 +14,6 @@
itertools = "0.12"
indexmap = "2"
minifier = { version = "0.3.5", default-features = false }
-pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false }
pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] }
regex = "1"
rustdoc-json-types = { path = "../rustdoc-json-types" }
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index e967fd4..d684e6f 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -167,7 +167,7 @@ enum State {
}
fn usually_needs_space_between_keyword_and_open_delim(symbol: Symbol, span: Span) -> bool {
- let ident = Ident { name: symbol, span };
+ let ident = Ident::new(symbol, span);
let is_keyword = ident.is_used_keyword() || ident.is_unused_keyword();
if !is_keyword {
// An identifier that is not a keyword usually does not need a space
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index bbe11bf..15890ff 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -786,7 +786,11 @@ pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, cache: &Cache, is_json: bool) -
// because it isn't public API.
None
}
- _ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)),
+ _ => Some({
+ let mut s = rustc_hir_pretty::attribute_to_string(&tcx, attr);
+ assert_eq!(s.pop(), Some('\n'));
+ s
+ }),
}
} else if attr.has_any_name(ALLOWED_ATTRIBUTES) {
Some(
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 4ef73ff..f93aa8f 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -174,7 +174,7 @@ pub(crate) struct Options {
pub(crate) expanded_args: Vec<String>,
/// Arguments to be used when compiling doctests.
- pub(crate) doctest_compilation_args: Vec<String>,
+ pub(crate) doctest_build_args: Vec<String>,
}
impl fmt::Debug for Options {
@@ -802,7 +802,7 @@ fn println_condition(condition: Condition) {
let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx);
let with_examples = matches.opt_strs("with-examples");
let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx);
- let doctest_compilation_args = matches.opt_strs("doctest-compilation-args");
+ let doctest_build_args = matches.opt_strs("doctest-build-arg");
let unstable_features =
rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
@@ -851,7 +851,7 @@ fn println_condition(condition: Condition) {
scrape_examples_options,
unstable_features,
expanded_args: args,
- doctest_compilation_args,
+ doctest_build_args,
};
let render_options = RenderOptions {
output,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 829a9ca..ef70b86 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -51,46 +51,6 @@ pub(crate) struct GlobalTestOptions {
pub(crate) args_file: PathBuf,
}
-/// Function used to split command line arguments just like a shell would.
-fn split_args(args: &str) -> Vec<String> {
- let mut out = Vec::new();
- let mut iter = args.chars();
- let mut current = String::new();
-
- while let Some(c) = iter.next() {
- if c == '\\' {
- if let Some(c) = iter.next() {
- // If it's escaped, even a quote or a whitespace will be ignored.
- current.push(c);
- }
- } else if c == '"' || c == '\'' {
- while let Some(new_c) = iter.next() {
- if new_c == c {
- break;
- } else if new_c == '\\' {
- if let Some(c) = iter.next() {
- // If it's escaped, even a quote will be ignored.
- current.push(c);
- }
- } else {
- current.push(new_c);
- }
- }
- } else if " \n\t\r".contains(c) {
- if !current.is_empty() {
- out.push(current.clone());
- current.clear();
- }
- } else {
- current.push(c);
- }
- }
- if !current.is_empty() {
- out.push(current);
- }
- out
-}
-
pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> Result<(), String> {
let mut file = File::create(file_path)
.map_err(|error| format!("failed to create args file: {error:?}"))?;
@@ -119,9 +79,7 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) ->
content.push(format!("-Z{unstable_option_str}"));
}
- for compilation_args in &options.doctest_compilation_args {
- content.extend(split_args(compilation_args));
- }
+ content.extend(options.doctest_build_args.clone());
let content = content.join("\n");
@@ -262,11 +220,21 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
Ok(None) => return,
Err(error) => {
eprintln!("{error}");
+ // Since some files in the temporary folder are still owned and alive, we need
+ // to manually remove the folder.
+ let _ = std::fs::remove_dir_all(temp_dir.path());
std::process::exit(1);
}
};
- run_tests(opts, &rustdoc_options, &unused_extern_reports, standalone_tests, mergeable_tests);
+ run_tests(
+ opts,
+ &rustdoc_options,
+ &unused_extern_reports,
+ standalone_tests,
+ mergeable_tests,
+ Some(temp_dir),
+ );
let compiling_test_count = compiling_test_count.load(Ordering::SeqCst);
@@ -316,6 +284,8 @@ pub(crate) fn run_tests(
unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>,
mut standalone_tests: Vec<test::TestDescAndFn>,
mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>,
+ // We pass this argument so we can drop it manually before using `exit`.
+ mut temp_dir: Option<TempDir>,
) {
let mut test_args = Vec::with_capacity(rustdoc_options.test_args.len() + 1);
test_args.insert(0, "rustdoctest".to_string());
@@ -382,9 +352,14 @@ pub(crate) fn run_tests(
// `running 0 tests...`.
if ran_edition_tests == 0 || !standalone_tests.is_empty() {
standalone_tests.sort_by(|a, b| a.desc.name.as_slice().cmp(b.desc.name.as_slice()));
- test::test_main(&test_args, standalone_tests, None);
+ test::test_main_with_exit_callback(&test_args, standalone_tests, None, || {
+ // We ensure temp dir destructor is called.
+ std::mem::drop(temp_dir.take());
+ });
}
if nb_errors != 0 {
+ // We ensure temp dir destructor is called.
+ std::mem::drop(temp_dir);
// libtest::ERROR_EXIT_CODE is not public but it's the same value.
std::process::exit(101);
}
@@ -450,7 +425,7 @@ enum TestFailure {
}
enum DirState {
- Temp(tempfile::TempDir),
+ Temp(TempDir),
Perm(PathBuf),
}
diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs
index 497a8d7..b3a3ce0 100644
--- a/src/librustdoc/doctest/markdown.rs
+++ b/src/librustdoc/doctest/markdown.rs
@@ -116,6 +116,7 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
&Arc::new(Mutex::new(Vec::new())),
standalone_tests,
mergeable_tests,
+ None,
);
Ok(())
}
diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs
index 49add73..618c204 100644
--- a/src/librustdoc/doctest/tests.rs
+++ b/src/librustdoc/doctest/tests.rs
@@ -382,28 +382,6 @@ fn main() {
}
#[test]
-fn check_split_args() {
- fn compare(input: &str, expected: &[&str]) {
- let output = super::split_args(input);
- let expected = expected.iter().map(|s| s.to_string()).collect::<Vec<_>>();
- assert_eq!(expected, output, "test failed for {input:?}");
- }
-
- compare("'a' \"b\"c", &["a", "bc"]);
- compare("'a' \"b \"c d", &["a", "b c", "d"]);
- compare("'a' \"b\\\"c\"", &["a", "b\"c"]);
- compare("'a\"'", &["a\""]);
- compare("\"a'\"", &["a'"]);
- compare("\\ a", &[" a"]);
- compare("\\\\", &["\\"]);
- compare("a'", &["a"]);
- compare("a ", &["a"]);
- compare("a b", &["a", "b"]);
- compare("a\n\t \rb", &["a", "b"]);
- compare("a\n\t1 \rb", &["a", "1", "b"]);
-}
-
-#[test]
fn comment_in_attrs() {
// If there is an inline code comment after attributes, we need to ensure that
// a backline will be added to prevent generating code "inside" it (and thus generating)
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index bca40b8..b4210e7 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -73,9 +73,11 @@
use std::env::{self, VarError};
use std::io::{self, IsTerminal};
+use std::path::Path;
use std::process;
use rustc_errors::DiagCtxtHandle;
+use rustc_hir::def_id::LOCAL_CRATE;
use rustc_interface::interface;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option};
@@ -654,9 +656,9 @@ fn opts() -> Vec<RustcOptGroup> {
Unstable,
Multi,
"",
- "doctest-compilation-args",
- "",
- "add arguments to be used when compiling doctests",
+ "doctest-build-arg",
+ "One argument (of possibly many) to be used when compiling doctests",
+ "ARG",
),
opt(
Unstable,
@@ -904,6 +906,10 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
rustc_interface::passes::write_dep_info(tcx);
}
+ if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
+ dump_feature_usage_metrics(tcx, metrics_dir);
+ }
+
if run_check {
// Since we're in "check" mode, no need to generate anything beyond this point.
return;
@@ -923,3 +929,16 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
})
})
}
+
+fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &Path) {
+ let hash = tcxt.crate_hash(LOCAL_CRATE);
+ let crate_name = tcxt.crate_name(LOCAL_CRATE);
+ let metrics_file_name = format!("unstable_feature_usage_metrics-{crate_name}-{hash}.json");
+ let metrics_path = metrics_dir.join(metrics_file_name);
+ if let Err(error) = tcxt.features().dump_feature_usage_metrics(metrics_path) {
+ // FIXME(yaahc): once metrics can be enabled by default we will want "failure to emit
+ // default metrics" to only produce a warning when metrics are enabled by default and emit
+ // an error only when the user manually enables metrics
+ tcxt.dcx().err(format!("cannot emit feature usage metrics: {error}"));
+ }
+}
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
index dcc27cd..b09ea05 100644
--- a/src/librustdoc/lint.rs
+++ b/src/librustdoc/lint.rs
@@ -196,14 +196,6 @@ macro_rules! declare_rustdoc_lint {
"detects redundant explicit links in doc comments"
}
-declare_rustdoc_lint! {
- /// This compatibility lint checks for Markdown syntax that works in the old engine but not
- /// the new one.
- UNPORTABLE_MARKDOWN,
- Warn,
- "detects markdown that is interpreted differently in different parser"
-}
-
pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
vec![
BROKEN_INTRA_DOC_LINKS,
@@ -217,7 +209,6 @@ macro_rules! declare_rustdoc_lint {
MISSING_CRATE_LEVEL_DOCS,
UNESCAPED_BACKTICKS,
REDUNDANT_EXPLICIT_LINKS,
- UNPORTABLE_MARKDOWN,
]
});
@@ -241,4 +232,5 @@ pub(crate) fn register_lints(_sess: &Session, lint_store: &mut LintStore) {
.register_renamed("intra_doc_link_resolution_failure", "rustdoc::broken_intra_doc_links");
lint_store.register_renamed("non_autolinks", "rustdoc::bare_urls");
lint_store.register_renamed("rustdoc::non_autolinks", "rustdoc::bare_urls");
+ lint_store.register_removed("rustdoc::unportable_markdown", "old parser removed");
}
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 36f5889..f3e2138 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -496,12 +496,21 @@ fn resolve<'path>(
// Try looking for methods and associated items.
// NB: `path_root` could be empty when resolving in the root namespace (e.g. `::std`).
- let (path_root, item_str) = path_str.rsplit_once("::").ok_or_else(|| {
- // If there's no `::`, it's not an associated item.
- // So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
- debug!("found no `::`, assuming {path_str} was correctly not in scope");
- UnresolvedPath { item_id, module_id, partial_res: None, unresolved: path_str.into() }
- })?;
+ let (path_root, item_str) = match path_str.rsplit_once("::") {
+ Some(res @ (_path_root, item_str)) if !item_str.is_empty() => res,
+ _ => {
+ // If there's no `::`, or the `::` is at the end (e.g. `String::`) it's not an
+ // associated item. So we can be sure that `rustc_resolve` was accurate when it
+ // said it wasn't resolved.
+ debug!("`::` missing or at end, assuming {path_str} was not in scope");
+ return Err(UnresolvedPath {
+ item_id,
+ module_id,
+ partial_res: None,
+ unresolved: path_str.into(),
+ });
+ }
+ };
let item_name = Symbol::intern(item_str);
// FIXME(#83862): this arbitrarily gives precedence to primitives over modules to support
diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs
index 1ecb53e..7740d14 100644
--- a/src/librustdoc/passes/lint.rs
+++ b/src/librustdoc/passes/lint.rs
@@ -6,7 +6,6 @@
mod html_tags;
mod redundant_explicit_links;
mod unescaped_backticks;
-mod unportable_markdown;
use super::Pass;
use crate::clean::*;
@@ -49,9 +48,6 @@ fn visit_item(&mut self, item: &Item) {
}
if may_have_block_comment_or_html {
html_tags::visit_item(self.cx, item, hir_id, &dox);
- unportable_markdown::visit_item(self.cx, item, hir_id, &dox);
- } else if may_have_link {
- unportable_markdown::visit_item(self.cx, item, hir_id, &dox);
}
}
diff --git a/src/librustdoc/passes/lint/unportable_markdown.rs b/src/librustdoc/passes/lint/unportable_markdown.rs
deleted file mode 100644
index 9564641..0000000
--- a/src/librustdoc/passes/lint/unportable_markdown.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-//! Detects specific markdown syntax that's different between pulldown-cmark
-//! 0.9 and 0.11.
-//!
-//! This is a mitigation for old parser bugs that affected some
-//! real crates' docs. The old parser claimed to comply with CommonMark,
-//! but it did not. These warnings will eventually be removed,
-//! though some of them may become Clippy lints.
-//!
-//! <https://github.com/rust-lang/rust/pull/121659#issuecomment-1992752820>
-//!
-//! <https://rustc-dev-guide.rust-lang.org/bug-fix-procedure.html#add-the-lint-to-the-list-of-removed-lists>
-
-use std::collections::{BTreeMap, BTreeSet};
-
-use rustc_hir::HirId;
-use rustc_lint_defs::Applicability;
-use rustc_resolve::rustdoc::source_span_for_markdown_range;
-use {pulldown_cmark as cmarkn, pulldown_cmark_old as cmarko};
-
-use crate::clean::Item;
-use crate::core::DocContext;
-
-pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
- let tcx = cx.tcx;
-
- // P1: unintended strikethrough was fixed by requiring single-tildes to flank
- // the same way underscores do, so nothing is done here
-
- // P2: block quotes without following space parsed wrong
- //
- // This is the set of starting points for block quotes with no space after
- // the `>`. It is populated by the new parser, and if the old parser fails to
- // clear it out, it'll produce a warning.
- let mut spaceless_block_quotes = BTreeSet::new();
-
- // P3: missing footnote references
- //
- // This is populated by listening for FootnoteReference from
- // the new parser and old parser.
- let mut missing_footnote_references = BTreeMap::new();
- let mut found_footnote_references = BTreeSet::new();
-
- // populate problem cases from new parser
- {
- pub fn main_body_opts_new() -> cmarkn::Options {
- cmarkn::Options::ENABLE_TABLES
- | cmarkn::Options::ENABLE_FOOTNOTES
- | cmarkn::Options::ENABLE_STRIKETHROUGH
- | cmarkn::Options::ENABLE_TASKLISTS
- | cmarkn::Options::ENABLE_SMART_PUNCTUATION
- }
- let parser_new = cmarkn::Parser::new_ext(dox, main_body_opts_new()).into_offset_iter();
- for (event, span) in parser_new {
- if let cmarkn::Event::Start(cmarkn::Tag::BlockQuote(_)) = event {
- if !dox[span.clone()].starts_with("> ") {
- spaceless_block_quotes.insert(span.start);
- }
- }
- if let cmarkn::Event::FootnoteReference(_) = event {
- found_footnote_references.insert(span.start + 1);
- }
- }
- }
-
- // remove cases where they don't actually differ
- {
- pub fn main_body_opts_old() -> cmarko::Options {
- cmarko::Options::ENABLE_TABLES
- | cmarko::Options::ENABLE_FOOTNOTES
- | cmarko::Options::ENABLE_STRIKETHROUGH
- | cmarko::Options::ENABLE_TASKLISTS
- | cmarko::Options::ENABLE_SMART_PUNCTUATION
- }
- let parser_old = cmarko::Parser::new_ext(dox, main_body_opts_old()).into_offset_iter();
- for (event, span) in parser_old {
- if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event
- && !dox[span.clone()].starts_with("> ")
- {
- spaceless_block_quotes.remove(&span.start);
- }
- if let cmarko::Event::FootnoteReference(_) = event
- && !found_footnote_references.contains(&(span.start + 1))
- {
- missing_footnote_references.insert(span.start + 1, span);
- }
- }
- }
-
- for start in spaceless_block_quotes {
- let (span, precise) =
- source_span_for_markdown_range(tcx, dox, &(start..start + 1), &item.attrs.doc_strings)
- .map(|span| (span, true))
- .unwrap_or_else(|| (item.attr_span(tcx), false));
-
- tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, span, |lint| {
- lint.primary_message("unportable markdown");
- lint.help("confusing block quote with no space after the `>` marker".to_string());
- if precise {
- lint.span_suggestion(
- span.shrink_to_hi(),
- "if the quote is intended, add a space",
- " ",
- Applicability::MaybeIncorrect,
- );
- lint.span_suggestion(
- span.shrink_to_lo(),
- "if it should not be a quote, escape it",
- "\\",
- Applicability::MaybeIncorrect,
- );
- }
- });
- }
- for (_caret, span) in missing_footnote_references {
- let (ref_span, precise) =
- source_span_for_markdown_range(tcx, dox, &span, &item.attrs.doc_strings)
- .map(|span| (span, true))
- .unwrap_or_else(|| (item.attr_span(tcx), false));
-
- tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, ref_span, |lint| {
- lint.primary_message("unportable markdown");
- if precise {
- lint.span_suggestion(
- ref_span.shrink_to_lo(),
- "if it should not be a footnote, escape it",
- "\\",
- Applicability::MaybeIncorrect,
- );
- }
- if dox.as_bytes().get(span.end) == Some(&b'[') {
- lint.help("confusing footnote reference and link");
- if precise {
- lint.span_suggestion(
- ref_span.shrink_to_hi(),
- "if the footnote is intended, add a space",
- " ",
- Applicability::MaybeIncorrect,
- );
- } else {
- lint.help("there should be a space between the link and the footnote");
- }
- }
- });
- }
-}
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index 8db9cd5..da09edd 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -20,8 +20,8 @@
use rustc_middle::ty::layout::ValidityRequirement;
use rustc_middle::ty::{
self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
- GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
- TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
+ GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
+ TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
};
use rustc_span::symbol::Ident;
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
@@ -915,7 +915,7 @@ fn visit_region(&mut self, r: Region<'tcx>) -> Self::Result {
ControlFlow::Continue(())
}
}
- fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result {
+ fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result {
self.index += 1;
let res = t.super_visit_with(self);
self.index -= 1;
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index 1449e9a..5757e42 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -35,6 +35,7 @@
"ignore-32bit",
"ignore-64bit",
"ignore-aarch64",
+ "ignore-aarch64-pc-windows-msvc",
"ignore-aarch64-unknown-linux-gnu",
"ignore-aix",
"ignore-android",
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index d6c69d3..cacce01 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -312,6 +312,7 @@ fn generate_output_example(&self, lint: &mut Lint) -> Result<(), Box<dyn Error>>
if matches!(
lint.name.as_str(),
"unused_features" // broken lint
+ | "soft_unstable" // cannot have a stable example
) {
return Ok(());
}
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
index 7aaf9c2..731d8b5 100644
--- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
@@ -1,5 +1,6 @@
// We're testing x86 target specific features
//@only-target: x86_64 i686
+#![allow(unnecessary_transmutes)]
#[cfg(target_arch = "x86")]
use std::arch::x86::*;
diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml
index b0db834..dfa884b 100644
--- a/src/tools/opt-dist/Cargo.toml
+++ b/src/tools/opt-dist/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "opt-dist"
version = "0.1.0"
-edition = "2021"
+edition = "2024"
[dependencies]
build_helper = { path = "../../build_helper" }
@@ -15,7 +15,6 @@
camino = "1"
tar = "0.4"
xz = { version = "0.1", package = "xz2" }
-serde = { version = "1", features = ["derive"] }
serde_json = "1"
glob = "0.3"
tempfile = "3.5"
diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs
index 9342d16..946e926 100644
--- a/src/tools/opt-dist/src/environment.rs
+++ b/src/tools/opt-dist/src/environment.rs
@@ -26,6 +26,7 @@ pub struct Environment {
use_bolt: bool,
shared_llvm: bool,
run_tests: bool,
+ fast_try_build: bool,
}
impl Environment {
@@ -106,6 +107,10 @@ pub fn benchmark_cargo_config(&self) -> &[String] {
pub fn run_tests(&self) -> bool {
self.run_tests
}
+
+ pub fn is_fast_try_build(&self) -> bool {
+ self.fast_try_build
+ }
}
/// What is the extension of binary executables on this platform?
diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs
index deff69a..64ce5cc 100644
--- a/src/tools/opt-dist/src/exec.rs
+++ b/src/tools/opt-dist/src/exec.rs
@@ -113,13 +113,16 @@ pub fn build(env: &Environment) -> Self {
"library/std",
])
.env("RUST_BACKTRACE", "full");
+ let cmd = add_shared_x_flags(env, cmd);
+
Self { cmd, metrics_path }
}
pub fn dist(env: &Environment, dist_args: &[String]) -> Self {
let metrics_path = env.build_root().join("build").join("metrics.json");
- let cmd = cmd(&dist_args.iter().map(|arg| arg.as_str()).collect::<Vec<_>>())
- .env("RUST_BACKTRACE", "full");
+ let args = dist_args.iter().map(|arg| arg.as_str()).collect::<Vec<_>>();
+ let cmd = cmd(&args).env("RUST_BACKTRACE", "full");
+ let cmd = add_shared_x_flags(env, cmd);
Self { cmd, metrics_path }
}
@@ -184,3 +187,7 @@ pub fn run(self, timer: &mut TimerSection) -> anyhow::Result<()> {
Ok(())
}
}
+
+fn add_shared_x_flags(env: &Environment, cmd: CmdBuilder) -> CmdBuilder {
+ if env.is_fast_try_build() { cmd.arg("--set").arg("rust.deny-warnings=false") } else { cmd }
+}
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index d5e6640..d2827ec 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -95,7 +95,7 @@ enum EnvironmentCmd {
#[arg(long)]
benchmark_cargo_config: Vec<String>,
- /// Perform tests after final build if it's not a try build
+ /// Perform tests after final build if it's not a fast try build
#[arg(long)]
run_tests: bool,
},
@@ -111,11 +111,14 @@ enum EnvironmentCmd {
},
}
-fn is_try_build() -> bool {
+/// For a fast try build, we want to only build the bare minimum of components to get a
+/// working toolchain, and not run any tests.
+fn is_fast_try_build() -> bool {
std::env::var("DIST_TRY_BUILD").unwrap_or_else(|_| "0".to_string()) != "0"
}
fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)> {
+ let is_fast_try_build = is_fast_try_build();
let (env, args) = match args.env {
EnvironmentCmd::Local {
target_triple,
@@ -144,6 +147,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
.skipped_tests(skipped_tests)
.benchmark_cargo_config(benchmark_cargo_config)
.run_tests(run_tests)
+ .fast_try_build(is_fast_try_build)
.build()?;
(env, shared.build_args)
@@ -167,6 +171,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
.use_bolt(!is_aarch64)
.skipped_tests(vec![])
.run_tests(true)
+ .fast_try_build(is_fast_try_build)
.build()?;
(env, shared.build_args)
@@ -187,6 +192,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
.use_bolt(false)
.skipped_tests(vec![])
.run_tests(true)
+ .fast_try_build(is_fast_try_build)
.build()?;
(env, shared.build_args)
@@ -350,9 +356,8 @@ fn execute_pipeline(
// After dist has finished, run a subset of the test suite on the optimized artifacts to discover
// possible regressions.
- // The tests are not executed for try builds, which can be in various broken states, so we don't
- // want to gatekeep them with tests.
- if !is_try_build() && env.run_tests() {
+ // The tests are not executed for fast try builds, which can be broken and might not pass them.
+ if !is_fast_try_build() && env.run_tests() {
timer.section("Run tests", |_| run_tests(env))?;
}
@@ -361,7 +366,10 @@ fn execute_pipeline(
fn main() -> anyhow::Result<()> {
// Make sure that we get backtraces for easier debugging in CI
- std::env::set_var("RUST_BACKTRACE", "1");
+ unsafe {
+ // SAFETY: we are the only thread running at this point
+ std::env::set_var("RUST_BACKTRACE", "1");
+ }
env_logger::builder()
.filter_level(LevelFilter::Info)
@@ -393,9 +401,9 @@ fn main() -> anyhow::Result<()> {
let (env, mut build_args) = create_environment(args).context("Cannot create environment")?;
- // Skip components that are not needed for try builds to speed them up
- if is_try_build() {
- log::info!("Skipping building of unimportant components for a try build");
+ // Skip components that are not needed for fast try builds to speed them up
+ if is_fast_try_build() {
+ log::info!("Skipping building of unimportant components for a fast try build");
for target in [
"rust-docs",
"rustc-docs",
diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs
index 70a72bd..b46ddd1 100644
--- a/src/tools/run-make-support/src/command.rs
+++ b/src/tools/run-make-support/src/command.rs
@@ -63,6 +63,12 @@ pub fn new<P: AsRef<OsStr>>(program: P) -> Self {
}
}
+ // Internal-only.
+ pub(crate) fn into_raw_command(mut self) -> std::process::Command {
+ self.drop_bomb.defuse();
+ self.cmd
+ }
+
/// Specify a stdin input buffer. This is a convenience helper,
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice());
diff --git a/src/tools/run-make-support/src/external_deps/cargo.rs b/src/tools/run-make-support/src/external_deps/cargo.rs
index e91d101..8da9f00 100644
--- a/src/tools/run-make-support/src/external_deps/cargo.rs
+++ b/src/tools/run-make-support/src/external_deps/cargo.rs
@@ -1,8 +1,11 @@
use crate::command::Command;
use crate::env_var;
+use crate::util::set_host_compiler_dylib_path;
/// Returns a command that can be used to invoke cargo. The cargo is provided by compiletest
/// through the `CARGO` env var.
pub fn cargo() -> Command {
- Command::new(env_var("CARGO"))
+ let mut cmd = Command::new(env_var("CARGO"));
+ set_host_compiler_dylib_path(&mut cmd);
+ cmd
}
diff --git a/src/tools/run-make-support/src/external_deps/rustdoc.rs b/src/tools/run-make-support/src/external_deps/rustdoc.rs
index 433a57c..7040fb6 100644
--- a/src/tools/run-make-support/src/external_deps/rustdoc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs
@@ -5,7 +5,7 @@
use crate::env::env_var;
use crate::util::set_host_compiler_dylib_path;
-/// Construct a new `rustdoc` invocation.
+/// Construct a new `rustdoc` invocation. This will configure the host compiler runtime libs.
#[track_caller]
pub fn rustdoc() -> Rustdoc {
Rustdoc::new()
@@ -28,7 +28,7 @@ fn setup_common() -> Command {
}
impl Rustdoc {
- /// Construct a bare `rustdoc` invocation.
+ /// Construct a bare `rustdoc` invocation. This will configure the host compiler runtime libs.
#[track_caller]
pub fn new() -> Self {
let cmd = setup_common();
diff --git a/src/tools/run-make-support/src/macros.rs b/src/tools/run-make-support/src/macros.rs
index 94955ae..9d5cc4e 100644
--- a/src/tools/run-make-support/src/macros.rs
+++ b/src/tools/run-make-support/src/macros.rs
@@ -28,6 +28,18 @@
macro_rules! impl_common_helpers {
($wrapper: ident) => {
impl $wrapper {
+ /// In very rare circumstances, you may need a e.g. `bare_rustc()` or `bare_rustdoc()`
+ /// with host runtime libs configured, but want the underlying raw
+ /// [`std::process::Command`] (e.g. for manipulating pipes or whatever). This function
+ /// will consume the command wrapper and extract the underlying
+ /// [`std::process::Command`].
+ ///
+ /// Caution: this will mean that you can no longer use the convenience methods on the
+ /// command wrapper. Use as a last resort.
+ pub fn into_raw_command(self) -> ::std::process::Command {
+ self.cmd.into_raw_command()
+ }
+
/// Specify an environment variable.
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
where
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
index 9ef0306..d36e520 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
@@ -224,7 +224,7 @@ pub(super) fn lower_inline_asm(
curarg = parser.curarg;
- let to_span = |inner_span: rustc_parse_format::InnerSpan| {
+ let to_span = |inner_span: std::ops::Range<usize>| {
is_direct_literal.then(|| {
TextRange::new(
inner_span.start.try_into().unwrap(),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs
index 2fd21bb..f27a406 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs
@@ -214,7 +214,7 @@ pub(crate) fn parse(
};
}
- let to_span = |inner_span: parse::InnerSpan| {
+ let to_span = |inner_span: std::ops::Range<usize>| {
is_source_literal.then(|| {
TextRange::new(inner_span.start.try_into().unwrap(), inner_span.end.try_into().unwrap())
})
@@ -297,7 +297,7 @@ enum ArgRef<'a> {
unfinished_literal.clear();
}
- let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s));
+ let span = parser.arg_places.get(placeholder_index).and_then(|s| to_span(s.clone()));
placeholder_index += 1;
let position_span = to_span(position_span);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index 6323d8b..068fc22 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -301,6 +301,7 @@ pub(crate) fn hoist_witness_pat(&self, pat: &WitnessPat<'db>) -> Pat {
// ignore this issue.
Ref => PatKind::Deref { subpattern: subpatterns.next().unwrap() },
Slice(_) => unimplemented!(),
+ DerefPattern(_) => unimplemented!(),
&Str(void) => match void {},
Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind::Wild,
Never => PatKind::Never,
@@ -351,6 +352,7 @@ fn ctor_arity(
},
Ref => 1,
Slice(..) => unimplemented!(),
+ DerefPattern(..) => unimplemented!(),
Never | Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
| F128Range(..) | Str(..) | Opaque(..) | NonExhaustive | PrivateUninhabited
| Hidden | Missing | Wildcard => 0,
@@ -411,6 +413,7 @@ fn ctor_sub_tys(
}
},
Slice(_) => unreachable!("Found a `Slice` constructor in match checking"),
+ DerefPattern(_) => unreachable!("Found a `DerefPattern` constructor in match checking"),
Never | Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
| F128Range(..) | Str(..) | Opaque(..) | NonExhaustive | PrivateUninhabited
| Hidden | Missing | Wildcard => {
diff --git a/src/version b/src/version
index 59be592..636ea71 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.88.0
+1.89.0
diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map
index 4021537..4d8ea87 100644
--- a/tests/coverage/abort.cov-map
+++ b/tests/coverage/abort.cov-map
@@ -1,5 +1,5 @@
Function name: abort::main
-Raw bytes (83): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 0d, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
+Raw bytes (98): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 10, 01, 0d, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/abort.rs
Number of expressions: 7
@@ -10,9 +10,11 @@
- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
- expression 5 operands: lhs = Counter(1), rhs = Expression(6, Add)
- expression 6 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24)
- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 25)
= (c1 - c0)
- Code(Counter(2)) at (prev + 0, 26) to (start + 2, 10)
@@ -30,19 +32,25 @@
= (c1 - (c0 + c4))
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
= (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c4
Function name: abort::might_abort
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02]
+Raw bytes (41): 0x[01, 01, 01, 01, 05, 07, 01, 03, 01, 00, 2e, 01, 01, 08, 00, 14, 05, 01, 09, 00, 11, 05, 00, 12, 00, 1f, 05, 01, 09, 00, 0f, 02, 01, 0c, 02, 06, 02, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/abort.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 20)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 31)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 2, 6)
+ = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2)
= (c0 - c1)
Highest counter ID seen: c1
diff --git a/tests/coverage/assert-ne.cov-map b/tests/coverage/assert-ne.cov-map
index 4bee7d7..fde0d51 100644
--- a/tests/coverage/assert-ne.cov-map
+++ b/tests/coverage/assert-ne.cov-map
@@ -1,16 +1,23 @@
Function name: assert_ne::main
-Raw bytes (28): 0x[01, 01, 02, 01, 05, 01, 09, 04, 01, 08, 01, 03, 15, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 06, 03, 05, 01, 02]
+Raw bytes (55): 0x[01, 01, 03, 01, 05, 01, 09, 01, 09, 09, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 12, 01, 00, 13, 00, 19, 01, 01, 0c, 00, 15, 05, 01, 0d, 00, 13, 02, 02, 0d, 00, 13, 0a, 03, 05, 00, 07, 0a, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/assert-ne.rs
-Number of expressions: 2
+Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 21)
-- Code(Counter(1)) at (prev + 4, 13) to (start + 0, 19)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 19)
- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19)
= (c0 - c1)
-- Code(Expression(1, Sub)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Expression(2, Sub)) at (prev + 3, 5) to (start + 0, 7)
+ = (c0 - c2)
+- Code(Expression(2, Sub)) at (prev + 1, 1) to (start + 0, 2)
= (c0 - c2)
Highest counter ID seen: c1
diff --git a/tests/coverage/assert.cov-map b/tests/coverage/assert.cov-map
index e7ee919..07a0d4c 100644
--- a/tests/coverage/assert.cov-map
+++ b/tests/coverage/assert.cov-map
@@ -1,5 +1,5 @@
Function name: assert::main
-Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 09, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
+Raw bytes (76): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 0c, 01, 09, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/assert.rs
Number of expressions: 6
@@ -9,9 +9,11 @@
- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
- expression 5 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24)
- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
= (c1 - c0)
- Code(Counter(2)) at (prev + 0, 27) to (start + 2, 10)
@@ -22,18 +24,22 @@
= (c1 - ((c0 + c2) + c3))
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
= (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: assert::might_fail_assert
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 02, 0f, 02, 02, 25, 00, 3d, 05, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 04, 01, 00, 28, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 01, 01, 05, 00, 0f, 02, 00, 25, 00, 3d, 05, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/assert.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 37) to (start + 0, 61)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 0, 37) to (start + 0, 61)
= (c0 - c1)
- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map
index d3ef867..e0ec381 100644
--- a/tests/coverage/assert_not.cov-map
+++ b/tests/coverage/assert_not.cov-map
@@ -1,13 +1,18 @@
Function name: assert_not::main
-Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 11, 01, 02, 05, 00, 13, 01, 01, 05, 00, 13, 01, 01, 05, 00, 15, 01, 01, 01, 00, 02]
+Raw bytes (54): 0x[01, 01, 00, 0a, 01, 06, 01, 00, 0a, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 11, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 13, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 13, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 15, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/assert_not.rs
Number of expressions: 0
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 17)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 19)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 21)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 21)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map
index 8d8dd24..c528ad5 100644
--- a/tests/coverage/async.cov-map
+++ b/tests/coverage/async.cov-map
@@ -1,115 +1,125 @@
Function name: async::c
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 18]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 24)
Highest counter ID seen: c0
Function name: async::c::{closure#0}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0b, 19, 00, 1a, 01, 01, 08, 00, 0e, 05, 01, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 11, 25) to (start + 1, 14)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 10)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 11, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: async::d
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 13]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 19)
Highest counter ID seen: c0
Function name: async::d::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 13, 14, 00, 15, 01, 00, 16, 00, 17, 01, 00, 18, 00, 19]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 25)
Highest counter ID seen: c0
Function name: async::e (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 13]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 1) to (start + 0, 20)
+- Code(Zero) at (prev + 21, 1) to (start + 0, 19)
Highest counter ID seen: (none)
Function name: async::e::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 14, 00, 19]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 15, 14, 00, 15, 00, 00, 16, 00, 17, 00, 00, 18, 00, 19]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 20) to (start + 0, 25)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 21, 20) to (start + 0, 21)
+- Code(Zero) at (prev + 0, 22) to (start + 0, 23)
+- Code(Zero) at (prev + 0, 24) to (start + 0, 25)
Highest counter ID seen: (none)
Function name: async::f
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 13]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 19)
Highest counter ID seen: c0
Function name: async::f::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 14, 00, 19]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 17, 14, 00, 15, 01, 00, 16, 00, 17, 01, 00, 18, 00, 19]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 20) to (start + 0, 25)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 23, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 25)
Highest counter ID seen: c0
Function name: async::foo (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 00, 1e]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 00, 1d]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Zero) at (prev + 25, 1) to (start + 0, 30)
+- Code(Zero) at (prev + 25, 1) to (start + 0, 29)
Highest counter ID seen: (none)
Function name: async::foo::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 1e, 00, 2d]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 19, 1e, 00, 1f, 00, 00, 20, 00, 2b, 00, 00, 2c, 00, 2d]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 25, 30) to (start + 0, 45)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 25, 30) to (start + 0, 31)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 43)
+- Code(Zero) at (prev + 0, 44) to (start + 0, 45)
Highest counter ID seen: (none)
Function name: async::g
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 00, 16]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 22)
Highest counter ID seen: c0
Function name: async::g::{closure#0} (unused)
-Raw bytes (59): 0x[01, 01, 00, 0b, 00, 1b, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (64): 0x[01, 01, 00, 0c, 00, 1b, 17, 00, 18, 00, 01, 0b, 00, 0c, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 11
-- Code(Zero) at (prev + 27, 23) to (start + 1, 12)
-- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
+Number of file 0 mappings: 12
+- Code(Zero) at (prev + 27, 23) to (start + 0, 24)
+- Code(Zero) at (prev + 1, 11) to (start + 0, 12)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 10)
- Code(Zero) at (prev + 0, 14) to (start + 0, 23)
- Code(Zero) at (prev + 0, 27) to (start + 0, 28)
- Code(Zero) at (prev + 0, 32) to (start + 0, 34)
@@ -122,22 +132,23 @@
Highest counter ID seen: (none)
Function name: async::h
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 00, 16]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 00, 15]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 21)
Highest counter ID seen: c0
Function name: async::h::{closure#0} (unused)
-Raw bytes (39): 0x[01, 01, 00, 07, 00, 23, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (44): 0x[01, 01, 00, 08, 00, 23, 16, 00, 17, 00, 03, 0b, 00, 0c, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 7
-- Code(Zero) at (prev + 35, 22) to (start + 3, 12)
-- Code(Zero) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 8
+- Code(Zero) at (prev + 35, 22) to (start + 0, 23)
+- Code(Zero) at (prev + 3, 11) to (start + 0, 12)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 10)
- Code(Zero) at (prev + 0, 14) to (start + 0, 25)
- Code(Zero) at (prev + 0, 26) to (start + 0, 27)
- Code(Zero) at (prev + 0, 32) to (start + 0, 34)
@@ -146,25 +157,27 @@
Highest counter ID seen: (none)
Function name: async::i
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 00, 13]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 00, 12]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 18)
Highest counter ID seen: c0
Function name: async::i::{closure#0}
-Raw bytes (65): 0x[01, 01, 03, 05, 09, 11, 15, 0d, 11, 0b, 01, 2c, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 02, 00, 0e, 00, 17, 11, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 06, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
+Raw bytes (75): 0x[01, 01, 03, 05, 09, 11, 15, 0d, 11, 0d, 01, 2c, 13, 00, 14, 01, 04, 0b, 00, 0c, 09, 01, 09, 00, 0a, 01, 00, 0e, 00, 0f, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 02, 00, 0e, 00, 17, 11, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 06, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
- expression 1 operands: lhs = Counter(4), rhs = Counter(5)
- expression 2 operands: lhs = Counter(3), rhs = Counter(4)
-Number of file 0 mappings: 11
-- Code(Counter(0)) at (prev + 44, 19) to (start + 4, 12)
-- Code(Counter(2)) at (prev + 5, 9) to (start + 0, 10)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 44, 19) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 4, 11) to (start + 0, 12)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 15)
- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 24)
- Code(Counter(1)) at (prev + 0, 28) to (start + 0, 33)
- Code(Counter(2)) at (prev + 0, 39) to (start + 0, 48)
@@ -180,17 +193,18 @@
Highest counter ID seen: c5
Function name: async::j
-Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 37, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 02, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 06, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0b, 01, 37, 01, 00, 0c, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 0f, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 02, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 06, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 13)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 12)
- Code(Counter(0)) at (prev + 11, 11) to (start + 0, 12)
- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 15)
- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27)
- Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39)
- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10)
@@ -203,60 +217,67 @@
Highest counter ID seen: c2
Function name: async::j::c
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 39, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 39, 05, 00, 16, 01, 01, 0c, 00, 12, 05, 01, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 57, 5) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 57, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 14)
- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 14)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6)
Highest counter ID seen: c1
Function name: async::j::d
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 40, 05, 00, 17]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 40, 05, 00, 11, 01, 00, 14, 00, 15, 01, 00, 16, 00, 17]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 64, 5) to (start + 0, 23)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 64, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
Highest counter ID seen: c0
Function name: async::j::f
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 41, 05, 00, 17]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 41, 05, 00, 11, 01, 00, 14, 00, 15, 01, 00, 16, 00, 17]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 23)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
Highest counter ID seen: c0
Function name: async::k (unused)
-Raw bytes (29): 0x[01, 01, 00, 05, 00, 49, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 00, 49, 01, 00, 0c, 00, 01, 0b, 00, 0c, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 5
-- Code(Zero) at (prev + 73, 1) to (start + 1, 12)
-- Code(Zero) at (prev + 2, 14) to (start + 0, 16)
+Number of file 0 mappings: 6
+- Code(Zero) at (prev + 73, 1) to (start + 0, 12)
+- Code(Zero) at (prev + 1, 11) to (start + 0, 12)
+- Code(Zero) at (prev + 1, 14) to (start + 0, 16)
- Code(Zero) at (prev + 1, 14) to (start + 0, 16)
- Code(Zero) at (prev + 1, 14) to (start + 0, 16)
- Code(Zero) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: (none)
Function name: async::l
-Raw bytes (33): 0x[01, 01, 02, 01, 07, 05, 09, 05, 01, 51, 01, 01, 0c, 02, 02, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 02, 01, 07, 05, 09, 06, 01, 51, 01, 00, 0c, 01, 01, 0b, 00, 0c, 02, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 81, 1) to (start + 1, 12)
-- Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 81, 1) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 12)
+- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 16)
= (c0 - (c1 + c2))
- Code(Counter(2)) at (prev + 1, 14) to (start + 0, 16)
- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16)
@@ -264,29 +285,43 @@
Highest counter ID seen: c2
Function name: async::m
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 00, 18]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 89, 1) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 89, 1) to (start + 0, 24)
Highest counter ID seen: c0
Function name: async::m::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 59, 19, 00, 22]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 59, 19, 00, 1a, 00, 00, 1b, 00, 20, 00, 00, 21, 00, 22]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 89, 25) to (start + 0, 34)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 89, 25) to (start + 0, 26)
+- Code(Zero) at (prev + 0, 27) to (start + 0, 32)
+- Code(Zero) at (prev + 0, 33) to (start + 0, 34)
Highest counter ID seen: (none)
Function name: async::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 08, 02]
+Raw bytes (69): 0x[01, 01, 00, 0d, 01, 5b, 01, 00, 0a, 01, 01, 0d, 00, 12, 01, 01, 0d, 00, 11, 01, 01, 09, 00, 13, 01, 00, 16, 00, 1e, 01, 00, 1f, 00, 20, 01, 01, 05, 00, 06, 01, 01, 05, 00, 06, 01, 01, 0d, 00, 11, 01, 01, 05, 00, 17, 01, 00, 18, 00, 1e, 01, 00, 1f, 00, 25, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 91, 1) to (start + 8, 2)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 91, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 0, 31) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 0, 31) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage
index aee76b0..9fca1b6 100644
--- a/tests/coverage/async.coverage
+++ b/tests/coverage/async.coverage
@@ -25,6 +25,7 @@
LL| 0|async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
LL| |
LL| 1|pub async fn g(x: u8) {
+ ^0
LL| 0| match x {
LL| 0| y if e().await == y => (),
LL| 0| y if f().await == y => (),
@@ -33,8 +34,9 @@
LL| 0|}
LL| |
LL| 1|async fn h(x: usize) { // The function signature is counted when called, but the body is not
- LL| 0| // executed (not awaited) so the open brace has a `0` count (at least when
- LL| 0| // displayed with `llvm-cov show` in color-mode).
+ ^0
+ LL| | // executed (not awaited) so the open brace has a `0` count (at least when
+ LL| | // displayed with `llvm-cov show` in color-mode).
LL| 0| match x {
LL| 0| y if foo().await[y] => (),
LL| 0| _ => (),
@@ -42,9 +44,9 @@
LL| 0|}
LL| |
LL| 1|async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
- LL| 1| // (a) the function signature, counted when the function is called; and
- LL| 1| // (b) the open brace for the function body, counted once when the body is
- LL| 1| // executed asynchronously.
+ LL| | // (a) the function signature, counted when the function is called; and
+ LL| | // (b) the open brace for the function body, counted once when the body is
+ LL| | // executed asynchronously.
LL| 1| match x {
LL| 1| y if c(x).await == y + 1 => { d().await; }
^0 ^0
@@ -91,7 +93,7 @@
LL| 1|}
LL| |
LL| 1|async fn m(x: u8) -> u8 { x - 1 }
- ^0
+ ^0^0 ^0
LL| |
LL| 1|fn main() {
LL| 1| let _ = g(10);
diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map
index 43ec9f3..cc62951 100644
--- a/tests/coverage/async2.cov-map
+++ b/tests/coverage/async2.cov-map
@@ -1,59 +1,80 @@
Function name: async2::async_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 16]
Number of files: 1
- file 0 => $DIR/async2.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 22)
Highest counter ID seen: c0
Function name: async2::async_func::{closure#0}
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 17, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 01, 0f, 17, 00, 18, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 26, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 11, 01, 01, 08, 00, 09, 01, 00, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async2.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 15, 23) to (start + 3, 9)
-- Code(Counter(0)) at (prev + 3, 10) to (start + 2, 6)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 15, 23) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 0, 10) to (start + 2, 6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: async2::async_func_just_println
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 24]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 23]
Number of files: 1
- file 0 => $DIR/async2.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 35)
Highest counter ID seen: c0
Function name: async2::async_func_just_println::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 24, 02, 02]
-Number of files: 1
-- file 0 => $DIR/async2.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 36) to (start + 2, 2)
-Highest counter ID seen: c0
-
-Function name: async2::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 07, 02]
-Number of files: 1
-- file 0 => $DIR/async2.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 27, 1) to (start + 7, 2)
-Highest counter ID seen: c0
-
-Function name: async2::non_async_func
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 01, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 17, 24, 00, 25, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 33, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async2.rs
Number of expressions: 0
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 7, 1) to (start + 3, 9)
-- Code(Counter(0)) at (prev + 3, 10) to (start + 2, 6)
+- Code(Counter(0)) at (prev + 23, 36) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 51)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
+Highest counter ID seen: c0
+
+Function name: async2::main
+Raw bytes (49): 0x[01, 01, 00, 09, 01, 1b, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 23, 01, 02, 05, 00, 13, 01, 02, 05, 00, 17, 01, 00, 18, 00, 22, 01, 01, 05, 00, 17, 01, 00, 18, 00, 2f, 01, 01, 01, 00, 02]
+Number of files: 1
+- file 0 => $DIR/async2.rs
+Number of expressions: 0
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 47)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
+Highest counter ID seen: c0
+
+Function name: async2::non_async_func
+Raw bytes (49): 0x[01, 01, 00, 09, 01, 07, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 2a, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 11, 01, 01, 08, 00, 09, 01, 00, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Number of files: 1
+- file 0 => $DIR/async2.rs
+Number of expressions: 0
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 0, 10) to (start + 2, 6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage
index fa56072..e9ed825 100644
--- a/tests/coverage/async2.coverage
+++ b/tests/coverage/async2.coverage
@@ -28,9 +28,9 @@
LL| |
LL| 1|fn main() {
LL| 1| println!("codecovsample::main");
- LL| 1|
+ LL| |
LL| 1| non_async_func();
- LL| 1|
+ LL| |
LL| 1| executor::block_on(async_func());
LL| 1| executor::block_on(async_func_just_println());
LL| 1|}
diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map
index 9e76bb9..07d4c0e 100644
--- a/tests/coverage/async_block.cov-map
+++ b/tests/coverage/async_block.cov-map
@@ -1,30 +1,33 @@
Function name: async_block::main
-Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 07, 01, 00, 0b, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 22, 01, 02, 01, 00, 02]
+Raw bytes (41): 0x[01, 01, 01, 05, 01, 07, 01, 07, 01, 00, 0a, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 1b, 02, 00, 1c, 00, 22, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async_block.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 11)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10)
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
= (c1 - c0)
- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19)
- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19)
= (c1 - c0)
-- Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 34)
+- Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 27)
+ = (c1 - c0)
+- Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 34)
= (c1 - c0)
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: async_block::main::{closure#0}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 09, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 09, 1c, 00, 1d, 01, 01, 10, 00, 17, 05, 00, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/async_block.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 9, 28) to (start + 1, 23)
-- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 9, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 0, 24) to (start + 2, 14)
- Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14)
= (c0 - c1)
- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map
index 10b6db0..9f8dc8d 100644
--- a/tests/coverage/async_closure.cov-map
+++ b/tests/coverage/async_closure.cov-map
@@ -1,32 +1,39 @@
Function name: async_closure::call_once::<async_closure::main::{closure#0}>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2b]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2a]
Number of files: 1
- file 0 => $DIR/async_closure.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 42)
Highest counter ID seen: c0
Function name: async_closure::call_once::<async_closure::main::{closure#0}>::{closure#0}
-Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 06, 2b, 01, 0e, 02, 02, 01, 00, 02]
+Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 2b, 00, 2c, 01, 01, 05, 00, 0e, 02, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async_closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 6, 43) to (start + 1, 14)
-- Code(Expression(0, Sub)) at (prev + 2, 1) to (start + 0, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 6, 43) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
= (c1 - c2)
Highest counter ID seen: c0
Function name: async_closure::main
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 01, 16, 01, 02, 05, 02, 02]
+Raw bytes (44): 0x[01, 01, 00, 08, 01, 0a, 01, 00, 0e, 01, 01, 09, 00, 16, 01, 01, 05, 00, 17, 01, 00, 18, 00, 27, 01, 01, 05, 00, 17, 01, 00, 18, 00, 21, 01, 00, 22, 00, 2f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/async_closure.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 10, 1) to (start + 1, 22)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 2, 2)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 39)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 0, 34) to (start + 0, 47)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: async_closure::main::{closure#0}
@@ -50,11 +57,12 @@
Highest counter ID seen: c0
Function name: async_closure::main::{closure#0}::{closure#0}::<i16>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24]
Number of files: 1
- file 0 => $DIR/async_closure.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 36)
Highest counter ID seen: c0
diff --git a/tests/coverage/async_closure.coverage b/tests/coverage/async_closure.coverage
index 5aed131..14f0434 100644
--- a/tests/coverage/async_closure.coverage
+++ b/tests/coverage/async_closure.coverage
@@ -8,7 +8,8 @@
LL| 1|}
LL| |
LL| 1|pub fn main() {
- LL| 2| let async_closure = async || {};
+ LL| 3| let async_closure = async || {};
+ ^1
------------------
| async_closure::main::{closure#0}:
| LL| 1| let async_closure = async || {};
diff --git a/tests/coverage/attr/impl.cov-map b/tests/coverage/attr/impl.cov-map
index ad24dfb..0562c29 100644
--- a/tests/coverage/attr/impl.cov-map
+++ b/tests/coverage/attr/impl.cov-map
@@ -1,27 +1,30 @@
Function name: <impl::MyStruct>::off_on (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 05, 00, 13]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 0f, 05, 00, 10, 00, 00, 12, 00, 13]
Number of files: 1
- file 0 => $DIR/impl.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 15, 5) to (start + 0, 19)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 15, 5) to (start + 0, 16)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 19)
Highest counter ID seen: (none)
Function name: <impl::MyStruct>::on_inherit (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 05, 00, 17]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 17, 05, 00, 14, 00, 00, 16, 00, 17]
Number of files: 1
- file 0 => $DIR/impl.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 23, 5) to (start + 0, 23)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 23, 5) to (start + 0, 20)
+- Code(Zero) at (prev + 0, 22) to (start + 0, 23)
Highest counter ID seen: (none)
Function name: <impl::MyStruct>::on_on (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1a, 05, 00, 12]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 1a, 05, 00, 0f, 00, 00, 11, 00, 12]
Number of files: 1
- file 0 => $DIR/impl.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 26, 5) to (start + 0, 18)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 26, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 17) to (start + 0, 18)
Highest counter ID seen: (none)
diff --git a/tests/coverage/attr/module.cov-map b/tests/coverage/attr/module.cov-map
index eba24da..88f4915 100644
--- a/tests/coverage/attr/module.cov-map
+++ b/tests/coverage/attr/module.cov-map
@@ -1,27 +1,30 @@
Function name: module::off::on (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0d, 05, 00, 0f]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 0d, 05, 00, 0c, 00, 00, 0e, 00, 0f]
Number of files: 1
- file 0 => $DIR/module.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 13, 5) to (start + 0, 15)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 13, 5) to (start + 0, 12)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 15)
Highest counter ID seen: (none)
Function name: module::on::inherit (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 05, 00, 14]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 15, 05, 00, 11, 00, 00, 13, 00, 14]
Number of files: 1
- file 0 => $DIR/module.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 5) to (start + 0, 20)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 21, 5) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 19) to (start + 0, 20)
Highest counter ID seen: (none)
Function name: module::on::on (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 05, 00, 0f]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 18, 05, 00, 0c, 00, 00, 0e, 00, 0f]
Number of files: 1
- file 0 => $DIR/module.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 24, 5) to (start + 0, 15)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 24, 5) to (start + 0, 12)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 15)
Highest counter ID seen: (none)
diff --git a/tests/coverage/attr/nested.cov-map b/tests/coverage/attr/nested.cov-map
index a831340..8ca218f 100644
--- a/tests/coverage/attr/nested.cov-map
+++ b/tests/coverage/attr/nested.cov-map
@@ -1,20 +1,24 @@
Function name: nested::closure_expr
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 40, 01, 01, 0f, 01, 0b, 05, 01, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 40, 01, 00, 12, 01, 01, 09, 00, 0f, 01, 0a, 05, 00, 0d, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/nested.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 64, 1) to (start + 1, 15)
-- Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 64, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: nested::closure_tail
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 4f, 01, 01, 0f, 01, 11, 05, 01, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 4f, 01, 00, 12, 01, 01, 09, 00, 0f, 01, 10, 05, 00, 0d, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/nested.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 79, 1) to (start + 1, 15)
-- Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 79, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 16, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map
index d26f06b..c0c6eab 100644
--- a/tests/coverage/attr/off-on-sandwich.cov-map
+++ b/tests/coverage/attr/off-on-sandwich.cov-map
@@ -1,30 +1,36 @@
Function name: off_on_sandwich::dense_a::dense_b
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 05, 02, 10, 01, 07, 05, 00, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 10, 05, 00, 11, 01, 01, 09, 00, 10, 01, 01, 09, 00, 10, 01, 05, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/off-on-sandwich.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 5) to (start + 2, 16)
-- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 16, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 6)
Highest counter ID seen: c0
Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 22, 09, 02, 15, 01, 0b, 09, 00, 0a]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 22, 09, 00, 16, 01, 01, 0d, 00, 15, 01, 01, 0d, 00, 15, 01, 09, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/off-on-sandwich.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 34, 9) to (start + 2, 21)
-- Code(Counter(0)) at (prev + 11, 9) to (start + 0, 10)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 34, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 9, 9) to (start + 0, 10)
Highest counter ID seen: c0
Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 25, 0d, 02, 19, 01, 07, 0d, 00, 0e]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 25, 0d, 00, 1a, 01, 01, 11, 00, 19, 01, 01, 11, 00, 19, 01, 05, 0d, 00, 0e]
Number of files: 1
- file 0 => $DIR/off-on-sandwich.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 37, 13) to (start + 2, 25)
-- Code(Counter(0)) at (prev + 7, 13) to (start + 0, 14)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 37, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 5, 13) to (start + 0, 14)
Highest counter ID seen: c0
diff --git a/tests/coverage/attr/trait-impl-inherit.cov-map b/tests/coverage/attr/trait-impl-inherit.cov-map
index b3e8757..bf10083 100644
--- a/tests/coverage/attr/trait-impl-inherit.cov-map
+++ b/tests/coverage/attr/trait-impl-inherit.cov-map
@@ -1,9 +1,12 @@
Function name: <trait_impl_inherit::S as trait_impl_inherit::T>::f
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 10, 01, 01, 09, 00, 11, 01, 00, 12, 00, 1a, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/trait-impl-inherit.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c0
diff --git a/tests/coverage/await_ready.cov-map b/tests/coverage/await_ready.cov-map
index 7bff6a4..a7eb051 100644
--- a/tests/coverage/await_ready.cov-map
+++ b/tests/coverage/await_ready.cov-map
@@ -1,21 +1,22 @@
Function name: await_ready::await_ready
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 1e]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 1d]
Number of files: 1
- file 0 => $DIR/await_ready.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 29)
Highest counter ID seen: c0
Function name: await_ready::await_ready::{closure#0}
-Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 0e, 1e, 03, 0f, 02, 04, 01, 00, 02]
+Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 0e, 1e, 00, 1f, 01, 02, 05, 01, 0f, 02, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/await_ready.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 14, 30) to (start + 3, 15)
-- Code(Expression(0, Sub)) at (prev + 4, 1) to (start + 0, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 14, 30) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 15)
+- Code(Expression(0, Sub)) at (prev + 2, 1) to (start + 0, 2)
= (c1 - c2)
Highest counter ID seen: c0
diff --git a/tests/coverage/await_ready.coverage b/tests/coverage/await_ready.coverage
index 1150d80..9a2d8f5 100644
--- a/tests/coverage/await_ready.coverage
+++ b/tests/coverage/await_ready.coverage
@@ -12,7 +12,7 @@
LL| |#[coverage(on)]
LL| |#[rustfmt::skip]
LL| 1|async fn await_ready() -> u8 {
- LL| 1| // await should be covered even if the function never yields
+ LL| | // await should be covered even if the function never yields
LL| 1| ready()
LL| 1| .await
LL| 1|}
diff --git a/tests/coverage/bad_counter_ids.cov-map b/tests/coverage/bad_counter_ids.cov-map
index 2ef2993..8b1b177 100644
--- a/tests/coverage/bad_counter_ids.cov-map
+++ b/tests/coverage/bad_counter_ids.cov-map
@@ -1,84 +1,108 @@
Function name: bad_counter_ids::eq_bad
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 01, 02, 0f, 00, 03, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 24, 01, 00, 0c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/bad_counter_ids.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 15)
-- Code(Zero) at (prev + 3, 1) to (start + 0, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: bad_counter_ids::eq_bad_message
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 29, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 29, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 00, 20, 00, 2b, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/bad_counter_ids.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 41, 1) to (start + 2, 15)
-- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 43)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: bad_counter_ids::eq_good
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 0f, 01, 03, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 10, 01, 00, 0d, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/bad_counter_ids.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 1) to (start + 2, 15)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: bad_counter_ids::eq_good_message
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 15, 01, 00, 15, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 2b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/bad_counter_ids.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 21, 1) to (start + 2, 15)
-- Code(Zero) at (prev + 2, 32) to (start + 0, 43)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 43)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: bad_counter_ids::ne_bad
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 2e, 01, 02, 0f, 00, 03, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 2e, 01, 00, 0c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/bad_counter_ids.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 46, 1) to (start + 2, 15)
-- Code(Zero) at (prev + 3, 1) to (start + 0, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 46, 1) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: bad_counter_ids::ne_bad_message
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 33, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 00, 20, 00, 2b, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/bad_counter_ids.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 51, 1) to (start + 2, 15)
-- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 51, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 43)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: bad_counter_ids::ne_good
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 0f, 01, 03, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 1a, 01, 00, 0d, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/bad_counter_ids.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 15)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: bad_counter_ids::ne_good_message
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 1f, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 1f, 01, 00, 15, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 2b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/bad_counter_ids.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 15)
-- Code(Zero) at (prev + 2, 32) to (start + 0, 43)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 43)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/bench.cov-map b/tests/coverage/bench.cov-map
index 1707957..f2b21dd 100644
--- a/tests/coverage/bench.cov-map
+++ b/tests/coverage/bench.cov-map
@@ -1,9 +1,10 @@
Function name: bench::my_bench
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 00, 27]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 08, 01, 00, 24, 01, 00, 26, 00, 27]
Number of files: 1
- file 0 => $DIR/bench.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 39)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 0, 38) to (start + 0, 39)
Highest counter ID seen: c0
diff --git a/tests/coverage/branch/generics.cov-map b/tests/coverage/branch/generics.cov-map
index 50e6eed..cb03f2a 100644
--- a/tests/coverage/branch/generics.cov-map
+++ b/tests/coverage/branch/generics.cov-map
@@ -1,12 +1,13 @@
Function name: generics::print_size::<()>
-Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/generics.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36)
true = c1
false = (c0 - c1)
- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
@@ -16,14 +17,15 @@
Highest counter ID seen: c1
Function name: generics::print_size::<u32>
-Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/generics.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36)
true = c1
false = (c0 - c1)
- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
@@ -33,14 +35,15 @@
Highest counter ID seen: c1
Function name: generics::print_size::<u64>
-Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/generics.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36)
true = c1
false = (c0 - c1)
- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
diff --git a/tests/coverage/branch/guard.cov-map b/tests/coverage/branch/guard.cov-map
index c1a275b..9c6a9bf 100644
--- a/tests/coverage/branch/guard.cov-map
+++ b/tests/coverage/branch/guard.cov-map
@@ -1,5 +1,5 @@
Function name: guard::branch_match_guard
-Raw bytes (89): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 0d, 01, 0c, 01, 01, 0e, 02, 03, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02]
+Raw bytes (104): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 10, 01, 0c, 01, 00, 26, 01, 01, 05, 00, 0e, 02, 02, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 00, 1e, 0d, 00, 22, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 00, 1e, 11, 00, 22, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/guard.rs
Number of expressions: 8
@@ -11,9 +11,10 @@
- expression 5 operands: lhs = Counter(0), rhs = Counter(1)
- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4)
- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Code(Expression(0, Sub)) at (prev + 3, 11) to (start + 0, 12)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Expression(0, Sub)) at (prev + 2, 11) to (start + 0, 12)
= (c1 - c3)
- Code(Expression(1, Sub)) at (prev + 1, 20) to (start + 2, 10)
= (c2 - c1)
@@ -22,14 +23,16 @@
- Branch { true: Counter(3), false: Expression(0, Sub) } at (prev + 0, 20) to (start + 0, 30)
true = c3
false = (c1 - c3)
-- Code(Counter(3)) at (prev + 0, 29) to (start + 2, 10)
+- Code(Counter(3)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 0, 34) to (start + 2, 10)
- Code(Counter(4)) at (prev + 3, 14) to (start + 0, 15)
- Code(Expression(0, Sub)) at (prev + 0, 20) to (start + 0, 25)
= (c1 - c3)
- Branch { true: Counter(4), false: Expression(2, Sub) } at (prev + 0, 20) to (start + 0, 30)
true = c4
false = (c1 - (c3 + c4))
-- Code(Counter(4)) at (prev + 0, 29) to (start + 2, 10)
+- Code(Counter(4)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(4)) at (prev + 0, 34) to (start + 2, 10)
- Code(Expression(4, Sub)) at (prev + 3, 14) to (start + 2, 10)
= ((c0 + c1) - ((c2 + c3) + c4))
- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
diff --git a/tests/coverage/branch/guard.coverage b/tests/coverage/branch/guard.coverage
index f89b965..465aefb 100644
--- a/tests/coverage/branch/guard.coverage
+++ b/tests/coverage/branch/guard.coverage
@@ -17,7 +17,7 @@
LL| 1| println!("zero");
LL| 1| }
LL| 3| Some(x) if x % 2 == 0 => {
- ^2
+ ^2 ^2
------------------
| Branch (LL:20): [True: 2, False: 1]
------------------
diff --git a/tests/coverage/branch/if-let.cov-map b/tests/coverage/branch/if-let.cov-map
index a792322..86bfcad 100644
--- a/tests/coverage/branch/if-let.cov-map
+++ b/tests/coverage/branch/if-let.cov-map
@@ -1,12 +1,13 @@
Function name: if_let::if_let
-Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 01, 02]
+Raw bytes (58): 0x[01, 01, 01, 01, 05, 0a, 01, 0c, 01, 00, 1f, 01, 01, 05, 00, 0e, 20, 02, 05, 02, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 00, 08, 01, 00, 09, 00, 0f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if-let.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 12) to (start + 0, 19)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 2, 12) to (start + 0, 19)
true = (c0 - c1)
false = c1
- Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 0, 18)
@@ -15,41 +16,53 @@
- Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 2, 6)
= (c0 - c1)
- Code(Counter(1)) at (prev + 2, 12) to (start + 2, 6)
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: if_let::if_let_chain
-Raw bytes (74): 0x[01, 01, 08, 01, 05, 01, 1f, 05, 09, 01, 1f, 05, 09, 01, 1f, 05, 09, 05, 09, 0a, 01, 17, 01, 00, 33, 20, 02, 05, 01, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 17, 20, 16, 09, 01, 10, 00, 17, 16, 00, 15, 00, 16, 02, 00, 1a, 00, 1b, 16, 01, 05, 03, 06, 1f, 03, 0c, 02, 06, 01, 03, 05, 01, 02]
+Raw bytes (102): 0x[01, 01, 0c, 01, 05, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 05, 09, 0e, 01, 17, 01, 00, 32, 20, 02, 05, 01, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 17, 20, 26, 09, 01, 10, 00, 17, 26, 00, 15, 00, 16, 02, 00, 1a, 00, 1b, 26, 01, 05, 03, 06, 26, 01, 09, 00, 0c, 26, 00, 0d, 00, 0e, 2f, 02, 0c, 02, 06, 01, 03, 05, 00, 08, 01, 00, 09, 00, 0f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if-let.rs
-Number of expressions: 8
+Number of expressions: 12
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Expression(7, Add)
+- expression 1 operands: lhs = Counter(0), rhs = Expression(11, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(0), rhs = Expression(7, Add)
+- expression 3 operands: lhs = Counter(0), rhs = Expression(11, Add)
- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 5 operands: lhs = Counter(0), rhs = Expression(7, Add)
+- expression 5 operands: lhs = Counter(0), rhs = Expression(11, Add)
- expression 6 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 51)
+- expression 7 operands: lhs = Counter(0), rhs = Expression(11, Add)
+- expression 8 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 9 operands: lhs = Counter(0), rhs = Expression(11, Add)
+- expression 10 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 11 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 50)
- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 1, 12) to (start + 0, 19)
true = (c0 - c1)
false = c1
- Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 0, 18)
= (c0 - c1)
- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
-- Branch { true: Expression(5, Sub), false: Counter(2) } at (prev + 1, 16) to (start + 0, 23)
+- Branch { true: Expression(9, Sub), false: Counter(2) } at (prev + 1, 16) to (start + 0, 23)
true = (c0 - (c1 + c2))
false = c2
-- Code(Expression(5, Sub)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Expression(9, Sub)) at (prev + 0, 21) to (start + 0, 22)
= (c0 - (c1 + c2))
- Code(Expression(0, Sub)) at (prev + 0, 26) to (start + 0, 27)
= (c0 - c1)
-- Code(Expression(5, Sub)) at (prev + 1, 5) to (start + 3, 6)
+- Code(Expression(9, Sub)) at (prev + 1, 5) to (start + 3, 6)
= (c0 - (c1 + c2))
-- Code(Expression(7, Add)) at (prev + 3, 12) to (start + 2, 6)
+- Code(Expression(9, Sub)) at (prev + 1, 9) to (start + 0, 12)
+ = (c0 - (c1 + c2))
+- Code(Expression(9, Sub)) at (prev + 0, 13) to (start + 0, 14)
+ = (c0 - (c1 + c2))
+- Code(Expression(11, Add)) at (prev + 2, 12) to (start + 2, 6)
= (c1 + c2)
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c2
diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map
index 64b13fc..09a014c 100644
--- a/tests/coverage/branch/if.cov-map
+++ b/tests/coverage/branch/if.cov-map
@@ -1,14 +1,15 @@
Function name: if::branch_and
-Raw bytes (54): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 2b, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (59): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 2b, 01, 00, 20, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 43, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 43, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -23,7 +24,7 @@
Highest counter ID seen: c2
Function name: if::branch_not
-Raw bytes (116): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 12, 01, 0c, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 10, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (126): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 14, 01, 0c, 01, 00, 17, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 0c, 05, 00, 0d, 00, 10, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 7
@@ -34,13 +35,15 @@
- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
- expression 5 operands: lhs = Counter(0), rhs = Counter(4)
- expression 6 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 18
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+Number of file 0 mappings: 20
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 16)
- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 10)
@@ -68,7 +71,7 @@
Highest counter ID seen: c4
Function name: if::branch_not_as
-Raw bytes (90): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0e, 01, 1d, 01, 01, 0e, 01, 03, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (95): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0f, 01, 1d, 01, 00, 1a, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 5
@@ -77,9 +80,10 @@
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
- expression 3 operands: lhs = Counter(0), rhs = Counter(3)
- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 20)
+Number of file 0 mappings: 15
+- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 20)
- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 0, 8) to (start + 0, 20)
true = (c0 - c1)
false = c1
@@ -104,7 +108,7 @@
Highest counter ID seen: c3
Function name: if::branch_or
-Raw bytes (60): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 08, 01, 35, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 09, 01, 35, 01, 00, 1f, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 6
@@ -114,9 +118,10 @@
- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
- expression 4 operands: lhs = Counter(0), rhs = Expression(5, Add)
- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 53, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 53, 1) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
diff --git a/tests/coverage/branch/lazy-boolean.cov-map b/tests/coverage/branch/lazy-boolean.cov-map
index b01ca5c..9ec7c9a 100644
--- a/tests/coverage/branch/lazy-boolean.cov-map
+++ b/tests/coverage/branch/lazy-boolean.cov-map
@@ -1,40 +1,46 @@
Function name: lazy_boolean::branch_and
-Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 13, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (53): 0x[01, 01, 01, 01, 05, 09, 01, 13, 01, 00, 20, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/lazy-boolean.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
true = c1
false = (c0 - c1)
- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: lazy_boolean::branch_or
-Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 1b, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (53): 0x[01, 01, 01, 01, 05, 09, 01, 1b, 01, 00, 1f, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/lazy-boolean.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 27, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
true = c1
false = (c0 - c1)
- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: lazy_boolean::chain
-Raw bytes (141): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 13, 01, 24, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 01, 02]
+Raw bytes (161): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 17, 01, 24, 01, 00, 11, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/lazy-boolean.rs
Number of expressions: 15
@@ -53,9 +59,10 @@
- expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add)
- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(6)
- expression 14 operands: lhs = Counter(4), rhs = Counter(5)
-Number of file 0 mappings: 19
-- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 23
+- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 18)
true = c1
@@ -69,7 +76,8 @@
true = c3
false = (c2 - c3)
- Code(Counter(3)) at (prev + 0, 40) to (start + 0, 45)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
- Branch { true: Counter(4), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 18)
@@ -87,11 +95,13 @@
false = (c0 - ((c4 + c5) + c6))
- Code(Expression(12, Sub)) at (prev + 0, 40) to (start + 0, 45)
= (c0 - ((c4 + c5) + c6))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c6
Function name: lazy_boolean::nested_mixed
-Raw bytes (137): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 13, 01, 31, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 01, 02]
+Raw bytes (157): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 17, 01, 31, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/lazy-boolean.rs
Number of expressions: 13
@@ -108,9 +118,10 @@
- expression 10 operands: lhs = Counter(0), rhs = Counter(5)
- expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add)
- expression 12 operands: lhs = Counter(5), rhs = Counter(6)
-Number of file 0 mappings: 19
-- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 23
+- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 14) to (start + 0, 19)
true = c1
@@ -127,7 +138,8 @@
false = ((c1 + c2) - c3)
- Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 51)
= ((c1 + c2) - c3)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
- Branch { true: Counter(4), false: Expression(8, Sub) } at (prev + 0, 14) to (start + 0, 19)
@@ -143,6 +155,8 @@
true = c6
false = (c0 - (c5 + c6))
- Code(Counter(6)) at (prev + 0, 44) to (start + 0, 51)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c6
diff --git a/tests/coverage/branch/let-else.cov-map b/tests/coverage/branch/let-else.cov-map
index 2af5e91..61bedbf 100644
--- a/tests/coverage/branch/let-else.cov-map
+++ b/tests/coverage/branch/let-else.cov-map
@@ -1,19 +1,24 @@
Function name: let_else::let_else
-Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 01, 0f, 02, 04, 05, 00, 0a, 01, 01, 01, 00, 02]
+Raw bytes (63): 0x[01, 01, 01, 01, 05, 0b, 01, 0c, 01, 00, 21, 01, 01, 05, 00, 0e, 20, 02, 05, 02, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 00, 0c, 05, 00, 0d, 00, 13, 05, 01, 09, 00, 0f, 02, 03, 05, 00, 08, 02, 00, 09, 00, 0a, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/let-else.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 9) to (start + 0, 16)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 2, 9) to (start + 0, 16)
true = (c0 - c1)
false = c1
- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 15)
= (c0 - c1)
- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 24)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 10)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 19)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 8)
+ = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 0, 9) to (start + 0, 10)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map
index 3f753f1..a2ed0d8 100644
--- a/tests/coverage/branch/match-arms.cov-map
+++ b/tests/coverage/branch/match-arms.cov-map
@@ -1,5 +1,5 @@
Function name: match_arms::guards
-Raw bytes (88): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 0c, 01, 30, 01, 01, 0e, 21, 03, 0b, 00, 10, 05, 01, 11, 00, 28, 20, 05, 02, 00, 17, 00, 1b, 09, 01, 11, 00, 28, 20, 09, 06, 00, 17, 00, 1b, 0d, 01, 11, 00, 28, 20, 0d, 0a, 00, 17, 00, 1b, 11, 01, 11, 00, 28, 20, 11, 0e, 00, 17, 00, 1b, 12, 01, 0e, 00, 15, 01, 03, 05, 01, 02]
+Raw bytes (158): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 1a, 01, 30, 01, 00, 23, 01, 01, 05, 00, 0e, 21, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 20, 05, 02, 00, 17, 00, 1b, 05, 00, 1a, 00, 1b, 05, 00, 1f, 00, 26, 05, 00, 27, 00, 28, 09, 01, 11, 00, 12, 20, 09, 06, 00, 17, 00, 1b, 09, 00, 1a, 00, 1b, 09, 00, 1f, 00, 26, 09, 00, 27, 00, 28, 0d, 01, 11, 00, 12, 20, 0d, 0a, 00, 17, 00, 1b, 0d, 00, 1a, 00, 1b, 0d, 00, 1f, 00, 26, 0d, 00, 27, 00, 28, 11, 01, 11, 00, 12, 20, 11, 0e, 00, 17, 00, 1b, 11, 00, 1a, 00, 1b, 11, 00, 1f, 00, 26, 11, 00, 27, 00, 28, 12, 01, 0e, 00, 15, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/match-arms.rs
Number of expressions: 8
@@ -11,70 +11,103 @@
- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(4)
- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3)
- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 12
-- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 14)
-- Code(Counter(8)) at (prev + 3, 11) to (start + 0, 16)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 40)
+Number of file 0 mappings: 26
+- Code(Counter(0)) at (prev + 48, 1) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(8)) at (prev + 2, 11) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 23) to (start + 0, 27)
true = c1
false = (c5 - c1)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 40)
+- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 31) to (start + 0, 38)
+- Code(Counter(1)) at (prev + 0, 39) to (start + 0, 40)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
- Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 23) to (start + 0, 27)
true = c2
false = (c6 - c2)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 40)
+- Code(Counter(2)) at (prev + 0, 26) to (start + 0, 27)
+- Code(Counter(2)) at (prev + 0, 31) to (start + 0, 38)
+- Code(Counter(2)) at (prev + 0, 39) to (start + 0, 40)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
- Branch { true: Counter(3), false: Expression(2, Sub) } at (prev + 0, 23) to (start + 0, 27)
true = c3
false = (c7 - c3)
-- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 40)
+- Code(Counter(3)) at (prev + 0, 26) to (start + 0, 27)
+- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 38)
+- Code(Counter(3)) at (prev + 0, 39) to (start + 0, 40)
+- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18)
- Branch { true: Counter(4), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 27)
true = c4
false = (c8 - c4)
+- Code(Counter(4)) at (prev + 0, 26) to (start + 0, 27)
+- Code(Counter(4)) at (prev + 0, 31) to (start + 0, 38)
+- Code(Counter(4)) at (prev + 0, 39) to (start + 0, 40)
- Code(Expression(4, Sub)) at (prev + 1, 14) to (start + 0, 21)
= (c0 - (((c1 + c2) + c3) + c4))
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c8
Function name: match_arms::match_arms
-Raw bytes (45): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 07, 01, 18, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 20, 09, 01, 11, 00, 20, 0d, 01, 11, 00, 20, 02, 01, 11, 00, 20, 01, 03, 05, 01, 02]
+Raw bytes (95): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 11, 01, 18, 01, 00, 1b, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 05, 00, 17, 00, 1e, 05, 00, 1f, 00, 20, 09, 01, 11, 00, 12, 09, 00, 17, 00, 1e, 09, 00, 1f, 00, 20, 0d, 01, 11, 00, 12, 0d, 00, 17, 00, 1e, 0d, 00, 1f, 00, 20, 02, 01, 11, 00, 12, 02, 00, 17, 00, 1e, 02, 00, 1f, 00, 20, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/match-arms.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 32)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 32)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 32)
-- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 32)
+Number of file 0 mappings: 17
+- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(1)) at (prev + 0, 31) to (start + 0, 32)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(2)) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(2)) at (prev + 0, 31) to (start + 0, 32)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 32)
+- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 18)
= (c0 - ((c1 + c2) + c3))
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Expression(0, Sub)) at (prev + 0, 23) to (start + 0, 30)
+ = (c0 - ((c1 + c2) + c3))
+- Code(Expression(0, Sub)) at (prev + 0, 31) to (start + 0, 32)
+ = (c0 - ((c1 + c2) + c3))
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: match_arms::or_patterns
-Raw bytes (57): 0x[01, 01, 04, 05, 09, 01, 0b, 03, 0d, 01, 03, 09, 01, 25, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2d, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2d, 01, 03, 05, 01, 02]
+Raw bytes (79): 0x[01, 01, 05, 05, 09, 01, 0b, 03, 0d, 01, 03, 01, 03, 0d, 01, 25, 01, 00, 1c, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2b, 03, 00, 2c, 00, 2d, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 12, 00, 24, 00, 2b, 12, 00, 2c, 00, 2d, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/match-arms.rs
-Number of expressions: 4
+Number of expressions: 5
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 3 operands: lhs = Counter(0), rhs = Expression(0, Add)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16)
+- expression 4 operands: lhs = Counter(0), rhs = Expression(0, Add)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 16)
- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18)
- Code(Counter(2)) at (prev + 0, 30) to (start + 0, 31)
-- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 45)
+- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 43)
+ = (c1 + c2)
+- Code(Expression(0, Add)) at (prev + 0, 44) to (start + 0, 45)
= (c1 + c2)
- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
- Code(Expression(1, Sub)) at (prev + 0, 30) to (start + 0, 31)
= (c0 - ((c1 + c2) + c3))
-- Code(Expression(3, Sub)) at (prev + 0, 36) to (start + 0, 45)
+- Code(Expression(4, Sub)) at (prev + 0, 36) to (start + 0, 43)
= (c0 - (c1 + c2))
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Expression(4, Sub)) at (prev + 0, 44) to (start + 0, 45)
+ = (c0 - (c1 + c2))
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
diff --git a/tests/coverage/branch/match-trivial.cov-map b/tests/coverage/branch/match-trivial.cov-map
index dd05ae4..a88e895 100644
--- a/tests/coverage/branch/match-trivial.cov-map
+++ b/tests/coverage/branch/match-trivial.cov-map
@@ -1,19 +1,24 @@
Function name: match_trivial::_uninhabited (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 0e]
-Number of files: 1
-- file 0 => $DIR/match-trivial.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 22, 1) to (start + 1, 14)
-Highest counter ID seen: (none)
-
-Function name: match_trivial::trivial
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 0e, 01, 03, 0b, 05, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 16, 01, 00, 20, 00, 01, 05, 00, 0e]
Number of files: 1
- file 0 => $DIR/match-trivial.rs
Number of expressions: 0
Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 11) to (start + 5, 2)
+- Code(Zero) at (prev + 22, 1) to (start + 0, 32)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 14)
+Highest counter ID seen: (none)
+
+Function name: match_trivial::trivial
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 1e, 01, 00, 17, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 0c, 01, 01, 1b, 00, 22, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02]
+Number of files: 1
+- file 0 => $DIR/match-trivial.rs
+Number of expressions: 0
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 27) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/branch/match-trivial.coverage b/tests/coverage/branch/match-trivial.coverage
index 4ffb172..6e7bf2d 100644
--- a/tests/coverage/branch/match-trivial.coverage
+++ b/tests/coverage/branch/match-trivial.coverage
@@ -32,8 +32,8 @@
LL| |
LL| 1| match x {
LL| 1| Trivial::Value => consume("trivial"),
- LL| 1| }
- LL| 1|
+ LL| | }
+ LL| |
LL| 1| consume("done");
LL| 1|}
LL| |
diff --git a/tests/coverage/branch/no-mir-spans.cov-map b/tests/coverage/branch/no-mir-spans.cov-map
index d28e6a5..4f893cb 100644
--- a/tests/coverage/branch/no-mir-spans.cov-map
+++ b/tests/coverage/branch/no-mir-spans.cov-map
@@ -1,31 +1,31 @@
Function name: no_mir_spans::while_cond
-Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 11, 20, 02, 01, 04, 0b, 00, 10]
+Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 10, 20, 02, 01, 04, 0b, 00, 10]
Number of files: 1
- file 0 => $DIR/no-mir-spans.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 16)
- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 16)
true = (c1 - c0)
false = c0
Highest counter ID seen: c0
Function name: no_mir_spans::while_cond_not
-Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 15, 20, 02, 01, 04, 0b, 00, 14]
+Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 14, 20, 02, 01, 04, 0b, 00, 14]
Number of files: 1
- file 0 => $DIR/no-mir-spans.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 25, 1) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 25, 1) to (start + 0, 20)
- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 20)
true = (c1 - c0)
false = c0
Highest counter ID seen: c0
Function name: no_mir_spans::while_op_and
-Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 13, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19]
+Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19]
Number of files: 1
- file 0 => $DIR/no-mir-spans.rs
Number of expressions: 4
@@ -34,7 +34,7 @@
- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(2)
- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 18)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16)
true = c1
false = (c2 - c1)
@@ -44,7 +44,7 @@
Highest counter ID seen: c1
Function name: no_mir_spans::while_op_or
-Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19]
+Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 11, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19]
Number of files: 1
- file 0 => $DIR/no-mir-spans.rs
Number of expressions: 3
@@ -52,7 +52,7 @@
- expression 1 operands: lhs = Counter(2), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 45, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 45, 1) to (start + 0, 17)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16)
true = c1
false = (c2 - c1)
diff --git a/tests/coverage/branch/while.cov-map b/tests/coverage/branch/while.cov-map
index e5fda26..767a7e4 100644
--- a/tests/coverage/branch/while.cov-map
+++ b/tests/coverage/branch/while.cov-map
@@ -1,12 +1,14 @@
Function name: while::while_cond
-Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 0c, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (48): 0x[01, 01, 01, 05, 01, 08, 01, 0c, 01, 00, 10, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/while.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16)
- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 16)
true = (c1 - c0)
@@ -17,14 +19,16 @@
Highest counter ID seen: c1
Function name: while::while_cond_not
-Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 15, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (48): 0x[01, 01, 01, 05, 01, 08, 01, 15, 01, 00, 14, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/while.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 21, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 20)
- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 20)
true = (c1 - c0)
@@ -35,7 +39,7 @@
Highest counter ID seen: c1
Function name: while::while_op_and
-Raw bytes (58): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 08, 01, 1e, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
+Raw bytes (78): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 0c, 01, 1e, 01, 00, 12, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/while.rs
Number of expressions: 5
@@ -44,10 +48,14 @@
- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(1)
- expression 3 operands: lhs = Counter(0), rhs = Counter(2)
- expression 4 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16)
- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16)
true = c2
false = (c1 - c2)
@@ -61,7 +69,7 @@
Highest counter ID seen: c2
Function name: while::while_op_or
-Raw bytes (56): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 08, 01, 29, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
+Raw bytes (76): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 0c, 01, 29, 01, 00, 11, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/while.rs
Number of expressions: 4
@@ -69,10 +77,14 @@
- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
- expression 3 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16)
- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16)
true = c2
false = (c1 - c2)
diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map
index 096be9e..5f7e4ce 100644
--- a/tests/coverage/closure.cov-map
+++ b/tests/coverage/closure.cov-map
@@ -1,18 +1,56 @@
Function name: closure::main
-Raw bytes (126): 0x[01, 01, 01, 01, 05, 18, 01, 09, 01, 0d, 1b, 01, 1a, 05, 02, 0a, 01, 0c, 05, 11, 1b, 01, 1e, 05, 02, 0a, 01, 0c, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 05, 00, 06, 01, 01, 05, 03, 02]
+Raw bytes (336): 0x[01, 01, 01, 01, 05, 42, 01, 09, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 11, 01, 00, 14, 00, 1c, 01, 02, 09, 00, 18, 01, 00, 1b, 00, 43, 01, 01, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 0d, 05, 00, 10, 01, 00, 13, 00, 3b, 01, 02, 09, 00, 0a, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 02, 0d, 00, 0e, 01, 04, 05, 00, 10, 01, 00, 13, 00, 17, 01, 01, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 0d, 05, 00, 10, 01, 00, 13, 00, 17, 01, 02, 09, 00, 0a, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 02, 0d, 00, 0e, 01, 05, 09, 00, 16, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 28, 01, 02, 09, 00, 1a, 01, 01, 0e, 00, 12, 01, 01, 0e, 00, 11, 01, 02, 0d, 00, 1a, 01, 02, 0e, 00, 15, 01, 04, 09, 00, 18, 01, 0c, 09, 00, 16, 01, 00, 19, 00, 1b, 01, 01, 09, 00, 1e, 01, 03, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 05, 01, 09, 00, 30, 02, 03, 05, 00, 06, 01, 01, 05, 00, 28, 01, 01, 05, 00, 46, 01, 01, 05, 00, 43, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 24
-- Code(Counter(0)) at (prev + 9, 1) to (start + 13, 27)
-- Code(Counter(0)) at (prev + 26, 5) to (start + 2, 10)
-- Code(Counter(0)) at (prev + 12, 5) to (start + 17, 27)
-- Code(Counter(0)) at (prev + 30, 5) to (start + 2, 10)
-- Code(Counter(0)) at (prev + 12, 5) to (start + 12, 22)
-- Code(Counter(0)) at (prev + 22, 5) to (start + 13, 24)
-- Code(Counter(0)) at (prev + 25, 9) to (start + 1, 30)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 41)
+Number of file 0 mappings: 66
+- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 59)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 14) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 12, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 41)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 45)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 36)
- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 36)
@@ -27,238 +65,277 @@
- Code(Counter(0)) at (prev + 8, 9) to (start + 0, 68)
- Code(Counter(0)) at (prev + 10, 8) to (start + 0, 16)
- Code(Counter(1)) at (prev + 0, 17) to (start + 4, 6)
-- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 48)
+- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 3, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: closure::main::{closure#0}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 28, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 28, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 17, 01, 00, 18, 00, 20, 01, 01, 05, 00, 06]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 1
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 40, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
+ = (c0 - c1)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c1
+
+Function name: closure::main::{closure#10} (unused)
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 9b, 01, 07, 00, 08, 00, 00, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 00, 20, 00, 21]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 0
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 155, 7) to (start + 0, 8)
+- Code(Zero) at (prev + 0, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 30)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 33)
+Highest counter ID seen: (none)
+
+Function name: closure::main::{closure#11} (unused)
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 9f, 01, 07, 00, 08, 00, 00, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 00, 20, 00, 21]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 0
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 159, 7) to (start + 0, 8)
+- Code(Zero) at (prev + 0, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 30)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 33)
+Highest counter ID seen: (none)
+
+Function name: closure::main::{closure#12} (unused)
+Raw bytes (10): 0x[01, 01, 00, 01, 00, a7, 01, 0a, 00, 16]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Zero) at (prev + 167, 10) to (start + 0, 22)
+Highest counter ID seen: (none)
+
+Function name: closure::main::{closure#13} (unused)
+Raw bytes (10): 0x[01, 01, 00, 01, 00, ad, 01, 11, 00, 1d]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Zero) at (prev + 173, 17) to (start + 0, 29)
+Highest counter ID seen: (none)
+
+Function name: closure::main::{closure#14}
+Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, b4, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 40, 5) to (start + 2, 20)
-- Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
- = (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6)
-Highest counter ID seen: c1
-
-Function name: closure::main::{closure#10} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 9b, 01, 07, 00, 21]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 155, 7) to (start + 0, 33)
-Highest counter ID seen: (none)
-
-Function name: closure::main::{closure#11} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 9f, 01, 07, 00, 21]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 159, 7) to (start + 0, 33)
-Highest counter ID seen: (none)
-
-Function name: closure::main::{closure#12} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, a7, 01, 01, 00, 17]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 167, 1) to (start + 0, 23)
-Highest counter ID seen: (none)
-
-Function name: closure::main::{closure#13} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, ac, 01, 0d, 02, 0e]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 172, 13) to (start + 2, 14)
-Highest counter ID seen: (none)
-
-Function name: closure::main::{closure#14}
-Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, b3, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 179, 13) to (start + 2, 27)
-- Code(Counter(1)) at (prev + 2, 30) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 180, 17) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37)
- Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
= (c0 - c1)
Highest counter ID seen: c1
Function name: closure::main::{closure#15}
-Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a]
+Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
+Number of file 0 mappings: 7
- Code(Counter(0)) at (prev + 187, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21)
-- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37)
- Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
Highest counter ID seen: c1
Function name: closure::main::{closure#16}
-Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, c5, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33]
+Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, c6, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 197, 13) to (start + 2, 27)
-- Code(Counter(1)) at (prev + 2, 30) to (start + 0, 37)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 198, 17) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37)
- Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
= (c0 - c1)
Highest counter ID seen: c1
Function name: closure::main::{closure#17}
-Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a]
+Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
+Number of file 0 mappings: 7
- Code(Counter(0)) at (prev + 205, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21)
-- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37)
- Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
Highest counter ID seen: c1
Function name: closure::main::{closure#18}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 19, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 19, 0d, 00, 0e, 01, 01, 15, 00, 22, 01, 00, 25, 00, 26, 01, 01, 14, 00, 1c, 05, 00, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 00, 1f, 01, 00, 20, 00, 28, 01, 01, 0d, 00, 0e]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 25, 13) to (start + 2, 28)
-- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 25, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 0, 37) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 28)
+- Code(Counter(1)) at (prev + 0, 29) to (start + 2, 18)
- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 14)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
Highest counter ID seen: c1
Function name: closure::main::{closure#19}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 43, 0d, 00, 0e, 01, 01, 15, 00, 22, 01, 00, 25, 00, 26, 01, 01, 14, 00, 1c, 05, 00, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 00, 1f, 01, 00, 20, 00, 28, 01, 01, 0d, 00, 0e]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 67, 13) to (start + 2, 28)
-- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 67, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 0, 37) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 28)
+- Code(Counter(1)) at (prev + 0, 29) to (start + 2, 18)
- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 14)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
Highest counter ID seen: c1
Function name: closure::main::{closure#1}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 52, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 52, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 17, 01, 00, 18, 00, 20, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 82, 5) to (start + 2, 20)
-- Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 82, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10)
- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c1
Function name: closure::main::{closure#2}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 68, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 68, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 11, 00, 17, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 104, 5) to (start + 2, 20)
-- Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 104, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10)
- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c1
Function name: closure::main::{closure#3} (unused)
-Raw bytes (25): 0x[01, 01, 00, 04, 00, 81, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 09, 00, 0a, 00, 01, 09, 01, 06]
+Raw bytes (40): 0x[01, 01, 00, 07, 00, 81, 01, 05, 00, 06, 00, 01, 0c, 00, 14, 00, 00, 15, 02, 0a, 00, 02, 09, 00, 0a, 00, 01, 09, 00, 23, 00, 00, 24, 00, 2c, 00, 01, 05, 00, 06]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 0
+Number of file 0 mappings: 7
+- Code(Zero) at (prev + 129, 5) to (start + 0, 6)
+- Code(Zero) at (prev + 1, 12) to (start + 0, 20)
+- Code(Zero) at (prev + 0, 21) to (start + 2, 10)
+- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 35)
+- Code(Zero) at (prev + 0, 36) to (start + 0, 44)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: (none)
+
+Function name: closure::main::{closure#5}
+Raw bytes (10): 0x[01, 01, 00, 01, 01, 8c, 01, 46, 00, 4e]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Counter(0)) at (prev + 140, 70) to (start + 0, 78)
+Highest counter ID seen: c0
+
+Function name: closure::main::{closure#6}
+Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 4a, 00, 56]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Counter(0)) at (prev + 141, 74) to (start + 0, 86)
+Highest counter ID seen: c0
+
+Function name: closure::main::{closure#7} (unused)
+Raw bytes (10): 0x[01, 01, 00, 01, 00, 8e, 01, 44, 00, 50]
+Number of files: 1
+- file 0 => $DIR/closure.rs
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Zero) at (prev + 142, 68) to (start + 0, 80)
+Highest counter ID seen: (none)
+
+Function name: closure::main::{closure#8} (unused)
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 93, 01, 3b, 00, 3c, 00, 00, 3d, 00, 45, 00, 00, 46, 00, 52, 00, 00, 54, 00, 55]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 0
Number of file 0 mappings: 4
-- Code(Zero) at (prev + 129, 5) to (start + 1, 20)
-- Code(Zero) at (prev + 1, 21) to (start + 2, 10)
-- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
-- Code(Zero) at (prev + 1, 9) to (start + 1, 6)
-Highest counter ID seen: (none)
-
-Function name: closure::main::{closure#4} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 89, 01, 35, 00, 43]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 137, 53) to (start + 0, 67)
-Highest counter ID seen: (none)
-
-Function name: closure::main::{closure#5}
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 8c, 01, 3d, 00, 4f]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 140, 61) to (start + 0, 79)
-Highest counter ID seen: c0
-
-Function name: closure::main::{closure#6}
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 41, 00, 57]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 141, 65) to (start + 0, 87)
-Highest counter ID seen: c0
-
-Function name: closure::main::{closure#7} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 8e, 01, 3b, 00, 51]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 142, 59) to (start + 0, 81)
-Highest counter ID seen: (none)
-
-Function name: closure::main::{closure#8} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 93, 01, 3b, 00, 55]
-Number of files: 1
-- file 0 => $DIR/closure.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 147, 59) to (start + 0, 85)
+- Code(Zero) at (prev + 147, 59) to (start + 0, 60)
+- Code(Zero) at (prev + 0, 61) to (start + 0, 69)
+- Code(Zero) at (prev + 0, 70) to (start + 0, 82)
+- Code(Zero) at (prev + 0, 84) to (start + 0, 85)
Highest counter ID seen: (none)
Function name: closure::main::{closure#9} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 95, 01, 38, 02, 06]
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 95, 01, 38, 00, 39, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/closure.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 149, 56) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 149, 56) to (start + 0, 57)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 30)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: (none)
diff --git a/tests/coverage/closure.coverage b/tests/coverage/closure.coverage
index 2deeb98..1428526 100644
--- a/tests/coverage/closure.coverage
+++ b/tests/coverage/closure.coverage
@@ -7,18 +7,18 @@
LL| |
LL| |#[rustfmt::skip]
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
LL| 1| let is_false = !is_true;
- LL| 1|
+ LL| |
LL| 1| let mut some_string = Some(String::from("the string content"));
LL| 1| println!(
LL| 1| "The string or alt: {}"
- LL| 1| ,
+ LL| | ,
LL| 1| some_string
- LL| 1| .
+ LL| | .
LL| 1| unwrap_or_else
LL| | (
LL| | ||
@@ -33,7 +33,7 @@
LL| | );
LL| |
LL| 1| some_string = Some(String::from("the string content"));
- LL| 1| let
+ LL| | let
LL| 1| a
LL| | =
LL| | ||
@@ -46,21 +46,21 @@
LL| 0| };
LL| 1| println!(
LL| 1| "The string or alt: {}"
- LL| 1| ,
+ LL| | ,
LL| 1| some_string
- LL| 1| .
+ LL| | .
LL| 1| unwrap_or_else
- LL| 1| (
+ LL| | (
LL| 1| a
- LL| 1| )
- LL| 1| );
- LL| 1|
+ LL| | )
+ LL| | );
+ LL| |
LL| 1| some_string = None;
LL| 1| println!(
LL| 1| "The string or alt: {}"
- LL| 1| ,
+ LL| | ,
LL| 1| some_string
- LL| 1| .
+ LL| | .
LL| 1| unwrap_or_else
LL| | (
LL| | ||
@@ -75,7 +75,7 @@
LL| | );
LL| |
LL| 1| some_string = None;
- LL| 1| let
+ LL| | let
LL| 1| a
LL| | =
LL| | ||
@@ -88,16 +88,16 @@
LL| 1| };
LL| 1| println!(
LL| 1| "The string or alt: {}"
- LL| 1| ,
+ LL| | ,
LL| 1| some_string
- LL| 1| .
+ LL| | .
LL| 1| unwrap_or_else
- LL| 1| (
+ LL| | (
LL| 1| a
- LL| 1| )
- LL| 1| );
- LL| 1|
- LL| 1| let
+ LL| | )
+ LL| | );
+ LL| |
+ LL| | let
LL| 1| quote_closure
LL| | =
LL| | |val|
@@ -110,17 +110,17 @@
LL| 5| };
LL| 1| println!(
LL| 1| "Repeated, quoted string: {:?}"
- LL| 1| ,
+ LL| | ,
LL| 1| std::iter::repeat("repeat me")
LL| 1| .take(5)
LL| 1| .map
- LL| 1| (
+ LL| | (
LL| 1| quote_closure
- LL| 1| )
+ LL| | )
LL| 1| .collect::<Vec<_>>()
- LL| 1| );
- LL| 1|
- LL| 1| let
+ LL| | );
+ LL| |
+ LL| | let
LL| 1| _unused_closure
LL| | =
LL| | |
@@ -135,22 +135,22 @@
LL| |
LL| 1| let mut countdown = 10;
LL| 1| let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
- ^0
LL| |
LL| |
LL| 1| let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
LL| 1| let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
- ^0
+ ^0
LL| 1| let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
- ^0
+ ^0
LL| |
LL| |
LL| |
LL| |
LL| 1| let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
- ^0
+ ^0^0 ^0 ^0
LL| |
LL| 1| let _shortish_unused_closure = | _unused_arg: u8 | {
+ ^0
LL| 0| println!("not called")
LL| 0| };
LL| |
@@ -173,14 +173,14 @@
LL| |
LL| 1| let _short_unused_closure_line_break_no_block2 =
LL| | | _unused_arg: u8 |
- LL| 0| println!(
+ LL| | println!(
LL| 0| "not called"
- LL| 0| )
+ LL| | )
LL| | ;
LL| |
LL| 1| let short_used_not_covered_closure_line_break_no_block_embedded_branch =
LL| | | _unused_arg: u8 |
- LL| 0| println!(
+ LL| | println!(
LL| 0| "not called: {}",
LL| 0| if is_true { "check" } else { "me" }
LL| | )
@@ -198,7 +198,7 @@
LL| |
LL| 1| let short_used_covered_closure_line_break_no_block_embedded_branch =
LL| | | _unused_arg: u8 |
- LL| 1| println!(
+ LL| | println!(
LL| 1| "not called: {}",
LL| 1| if is_true { "check" } else { "me" }
^0
diff --git a/tests/coverage/closure_bug.cov-map b/tests/coverage/closure_bug.cov-map
index 8355cbf..a7087c6 100644
--- a/tests/coverage/closure_bug.cov-map
+++ b/tests/coverage/closure_bug.cov-map
@@ -1,5 +1,5 @@
Function name: closure_bug::main
-Raw bytes (97): 0x[01, 01, 04, 01, 05, 01, 09, 01, 0d, 01, 11, 11, 01, 07, 01, 03, 0a, 01, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, 02, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, 06, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, 0a, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, 0e, 00, 16, 00, 17, 01, 01, 01, 00, 02]
+Raw bytes (132): 0x[01, 01, 04, 01, 05, 01, 09, 01, 0d, 01, 11, 18, 01, 07, 01, 00, 0a, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 2d, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 05, 00, 0f, 00, 17, 02, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 09, 00, 0f, 00, 17, 06, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 0d, 00, 0f, 00, 17, 0a, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 11, 00, 0f, 00, 17, 0e, 00, 16, 00, 17, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/closure_bug.rs
Number of expressions: 4
@@ -7,38 +7,45 @@
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
- expression 2 operands: lhs = Counter(0), rhs = Counter(3)
- expression 3 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 17
-- Code(Counter(0)) at (prev + 7, 1) to (start + 3, 10)
-- Code(Counter(0)) at (prev + 9, 5) to (start + 1, 14)
-- Code(Counter(1)) at (prev + 1, 15) to (start + 0, 23)
+Number of file 0 mappings: 24
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 23)
- Code(Expression(0, Sub)) at (prev + 0, 22) to (start + 0, 23)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14)
-- Code(Counter(2)) at (prev + 1, 15) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 0, 15) to (start + 0, 23)
- Code(Expression(1, Sub)) at (prev + 0, 22) to (start + 0, 23)
= (c0 - c2)
- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14)
-- Code(Counter(3)) at (prev + 1, 15) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(3)) at (prev + 0, 15) to (start + 0, 23)
- Code(Expression(2, Sub)) at (prev + 0, 22) to (start + 0, 23)
= (c0 - c3)
- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14)
-- Code(Counter(4)) at (prev + 1, 15) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(4)) at (prev + 0, 15) to (start + 0, 23)
- Code(Expression(3, Sub)) at (prev + 0, 22) to (start + 0, 23)
= (c0 - c4)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c4
Function name: closure_bug::main::{closure#0}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
Number of files: 1
- file 0 => $DIR/closure_bug.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 14, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 14, 12) to (start + 0, 18)
- Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25)
- Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40)
= (c0 - c1)
@@ -46,13 +53,13 @@
Highest counter ID seen: c1
Function name: closure_bug::main::{closure#1}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 17, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 17, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
Number of files: 1
- file 0 => $DIR/closure_bug.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 23, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 23, 12) to (start + 0, 18)
- Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25)
- Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40)
= (c0 - c1)
@@ -60,13 +67,13 @@
Highest counter ID seen: c1
Function name: closure_bug::main::{closure#2}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 20, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 20, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
Number of files: 1
- file 0 => $DIR/closure_bug.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 32, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 32, 12) to (start + 0, 18)
- Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25)
- Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40)
= (c0 - c1)
@@ -74,13 +81,13 @@
Highest counter ID seen: c1
Function name: closure_bug::main::{closure#3}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
Number of files: 1
- file 0 => $DIR/closure_bug.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 41, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 41, 12) to (start + 0, 18)
- Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25)
- Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40)
= (c0 - c1)
diff --git a/tests/coverage/closure_bug.coverage b/tests/coverage/closure_bug.coverage
index cc64470..b85375d 100644
--- a/tests/coverage/closure_bug.coverage
+++ b/tests/coverage/closure_bug.coverage
@@ -6,7 +6,7 @@
LL| |#[rustfmt::skip]
LL| 1|fn main() {
LL| 1| let truthy = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let a
LL| | =
LL| | |
diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map
index c624896..3ab1d7f 100644
--- a/tests/coverage/closure_macro.cov-map
+++ b/tests/coverage/closure_macro.cov-map
@@ -1,41 +1,57 @@
Function name: closure_macro::load_configuration_files
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 1d, 01, 00, 38, 01, 01, 05, 00, 1f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/closure_macro.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 56)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: closure_macro::main
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 21, 01, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
+Raw bytes (66): 0x[01, 01, 01, 01, 05, 0c, 01, 21, 01, 00, 24, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 02, 01, 09, 00, 0f, 01, 00, 12, 00, 1b, 01, 00, 1c, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 00, 1f, 02, 00, 22, 00, 2e, 02, 01, 0d, 00, 2d, 02, 01, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/closure_macro.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 32)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 52)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 52)
- Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 31)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 46)
+ = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 45)
+ = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 11)
+ = (c0 - c1)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: closure_macro::main::{closure#0}
-Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a]
+Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 10, 1c, 00, 1d, 01, 02, 11, 00, 18, 01, 00, 1b, 00, 22, 01, 01, 10, 00, 21, 05, 01, 11, 00, 19, 05, 00, 1a, 00, 1e, 05, 01, 11, 00, 27, 02, 02, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/closure_macro.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 16, 28) to (start + 3, 33)
-- Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39)
-- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 16, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 2, 17) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 33)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 25)
+- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 30)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 39)
+- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 22)
= (c0 - c1)
- Code(Expression(1, Sub)) at (prev + 0, 23) to (start + 0, 30)
= (c0 - (c1 + c2))
diff --git a/tests/coverage/closure_macro.coverage b/tests/coverage/closure_macro.coverage
index 00022bb..b1d7a83 100644
--- a/tests/coverage/closure_macro.coverage
+++ b/tests/coverage/closure_macro.coverage
@@ -14,7 +14,7 @@
LL| |macro_rules! on_error {
LL| | ($value:expr, $error_message:expr) => {
LL| 0| $value.or_else(|e| {
- LL| 0| // This closure, which is declared in a macro, should be instrumented.
+ LL| | // This closure, which is declared in a macro, should be instrumented.
LL| 0| let message = format!($error_message, e);
LL| 0| if message.len() > 0 {
LL| 0| println!("{}", message);
diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map
index 77bf31d..b5f4cee 100644
--- a/tests/coverage/closure_macro_async.cov-map
+++ b/tests/coverage/closure_macro_async.cov-map
@@ -1,50 +1,66 @@
Function name: closure_macro_async::load_configuration_files
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 21, 01, 00, 38, 01, 01, 05, 00, 1f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/closure_macro_async.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 56)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: closure_macro_async::test
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 00, 2b]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 00, 2a]
Number of files: 1
- file 0 => $DIR/closure_macro_async.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 42)
Highest counter ID seen: c0
Function name: closure_macro_async::test::{closure#0}
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 25, 2b, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
+Raw bytes (66): 0x[01, 01, 01, 01, 05, 0c, 01, 25, 2b, 00, 2c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 02, 01, 09, 00, 0f, 01, 00, 12, 00, 1b, 01, 00, 1c, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 00, 1f, 02, 00, 22, 00, 2e, 02, 01, 0d, 00, 2d, 02, 01, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/closure_macro_async.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 37, 43) to (start + 1, 32)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 37, 43) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 52)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 52)
- Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 31)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 46)
+ = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 45)
+ = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 11)
+ = (c0 - c1)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: closure_macro_async::test::{closure#0}::{closure#0}
-Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 14, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a]
+Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 14, 1c, 00, 1d, 01, 02, 11, 00, 18, 01, 00, 1b, 00, 22, 01, 01, 10, 00, 21, 05, 01, 11, 00, 19, 05, 00, 1a, 00, 1e, 05, 01, 11, 00, 27, 02, 02, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/closure_macro_async.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 20, 28) to (start + 3, 33)
-- Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39)
-- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 20, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 2, 17) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 33)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 25)
+- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 30)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 39)
+- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 22)
= (c0 - c1)
- Code(Expression(1, Sub)) at (prev + 0, 23) to (start + 0, 30)
= (c0 - (c1 + c2))
diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage
index 1e1ffec..7bfea3c 100644
--- a/tests/coverage/closure_macro_async.coverage
+++ b/tests/coverage/closure_macro_async.coverage
@@ -18,7 +18,7 @@
LL| |macro_rules! on_error {
LL| | ($value:expr, $error_message:expr) => {
LL| 0| $value.or_else(|e| {
- LL| 0| // This closure, which is declared in a macro, should be instrumented.
+ LL| | // This closure, which is declared in a macro, should be instrumented.
LL| 0| let message = format!($error_message, e);
LL| 0| if message.len() > 0 {
LL| 0| println!("{}", message);
diff --git a/tests/coverage/closure_unit_return.cov-map b/tests/coverage/closure_unit_return.cov-map
index c751190..f665d93 100644
--- a/tests/coverage/closure_unit_return.cov-map
+++ b/tests/coverage/closure_unit_return.cov-map
@@ -1,38 +1,49 @@
Function name: closure_unit_return::explicit_unit
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 01, 01, 10, 01, 05, 05, 02, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 07, 01, 00, 13, 01, 01, 09, 00, 10, 01, 04, 05, 00, 09, 01, 00, 0a, 00, 11, 01, 01, 05, 00, 07, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/closure_unit_return.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 16)
-- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 0, 10) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 7)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: closure_unit_return::explicit_unit::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 08, 16, 02, 06]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 08, 16, 00, 17, 00, 01, 09, 00, 0b, 00, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/closure_unit_return.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 8, 22) to (start + 2, 6)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 8, 22) to (start + 0, 23)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 11)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: (none)
Function name: closure_unit_return::implicit_unit
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 01, 10, 01, 05, 05, 02, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 10, 01, 00, 13, 01, 01, 09, 00, 10, 01, 04, 05, 00, 09, 01, 00, 0a, 00, 11, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/closure_unit_return.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 16)
-- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 0, 10) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: closure_unit_return::implicit_unit::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 16, 02, 06]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 11, 16, 00, 17, 00, 01, 09, 00, 0b, 00, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/closure_unit_return.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 17, 22) to (start + 2, 6)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 17, 22) to (start + 0, 23)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 11)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: (none)
diff --git a/tests/coverage/closure_unit_return.coverage b/tests/coverage/closure_unit_return.coverage
index 5e57e0d..02ea63b 100644
--- a/tests/coverage/closure_unit_return.coverage
+++ b/tests/coverage/closure_unit_return.coverage
@@ -6,6 +6,7 @@
LL| |
LL| 1|fn explicit_unit() {
LL| 1| let closure = || {
+ ^0
LL| 0| ();
LL| 0| };
LL| |
@@ -15,11 +16,12 @@
LL| |
LL| 1|fn implicit_unit() {
LL| 1| let closure = || {
+ ^0
LL| 0| ();
LL| 0| };
LL| |
LL| 1| drop(closure);
- LL| 1| // implicit return of `()`
+ LL| | // implicit return of `()`
LL| 1|}
LL| |
LL| |#[coverage(off)]
diff --git a/tests/coverage/condition/conditions.cov-map b/tests/coverage/condition/conditions.cov-map
index 1bcf045..fda5dd1 100644
--- a/tests/coverage/condition/conditions.cov-map
+++ b/tests/coverage/condition/conditions.cov-map
@@ -1,5 +1,5 @@
Function name: conditions::assign_3_and_or
-Raw bytes (65): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 09, 01, 1c, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (75): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0b, 01, 1c, 01, 00, 2e, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
Number of expressions: 5
@@ -8,8 +8,8 @@
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
- expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 28, 1) to (start + 0, 47)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 28, 1) to (start + 0, 46)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -24,11 +24,13 @@
- Branch { true: Counter(3), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 24)
true = c3
false = (c0 - (c2 + c3))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: conditions::assign_3_or_and
-Raw bytes (63): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 09, 01, 17, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (73): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0b, 01, 17, 01, 00, 2e, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
Number of expressions: 4
@@ -36,8 +38,8 @@
- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 47)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 46)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -52,18 +54,20 @@
- Branch { true: Counter(3), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 24)
true = c3
false = (c2 - c3)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: conditions::assign_and
-Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 0d, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (57): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 0d, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 33)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 32)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -73,19 +77,21 @@
- Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 18) to (start + 0, 19)
true = c2
false = (c1 - c2)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c2
Function name: conditions::assign_or
-Raw bytes (49): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 07, 01, 12, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (59): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 09, 01, 12, 01, 00, 1f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 32)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 31)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -96,27 +102,32 @@
- Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 18) to (start + 0, 19)
true = c2
false = (c0 - (c1 + c2))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c2
Function name: conditions::foo
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: conditions::func_call
-Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 25, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 20, 05, 02, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
+Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 25, 01, 00, 1f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 20, 05, 02, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 31)
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 9) to (start + 0, 10)
@@ -130,11 +141,16 @@
Highest counter ID seen: c2
Function name: conditions::simple_assign
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 08, 01, 00, 1a, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map
index 86a3179..29d9604 100644
--- a/tests/coverage/conditions.cov-map
+++ b/tests/coverage/conditions.cov-map
@@ -1,8 +1,8 @@
Function name: conditions::main
-Raw bytes (533): 0x[01, 01, 47, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 97, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 97, 01, 15, 0d, 11, 19, 45, 19, 8f, 01, 45, 49, 8f, 01, 4d, 45, 49, 19, 8b, 01, 8f, 01, 4d, 45, 49, 97, 01, db, 01, 0d, 11, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, db, 01, 1d, 15, 19, 21, 39, 21, d3, 01, 39, 3d, d3, 01, 41, 39, 3d, 21, cf, 01, d3, 01, 41, 39, 3d, db, 01, 97, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, 97, 02, 25, 1d, 21, 29, 2d, 29, 8f, 02, 2d, 31, 8f, 02, 35, 2d, 31, 29, 8b, 02, 8f, 02, 35, 2d, 31, 97, 02, 9b, 02, 1d, 21, 25, 29, 44, 01, 03, 01, 02, 0c, 01, 02, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 01, 0a, 06, 02, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 01, 12, 2a, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 03, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 97, 01, 03, 08, 00, 0c, 97, 01, 01, 0d, 01, 10, 97, 01, 01, 11, 02, 0a, 00, 02, 09, 00, 0a, 97, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 6a, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 72, 00, 21, 00, 2e, 76, 00, 32, 00, 40, 8b, 01, 00, 41, 02, 0e, 86, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 92, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, db, 01, 02, 09, 01, 0c, db, 01, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 97, 02, 02, 09, 00, 0a, db, 01, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, ae, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, b6, 01, 00, 1d, 00, 2a, ba, 01, 00, 2e, 00, 3c, cf, 01, 00, 3d, 02, 0a, ca, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, d6, 01, 02, 0d, 02, 0f, 9b, 02, 05, 09, 00, 0a, 97, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, ea, 01, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, f2, 01, 00, 1d, 00, 2a, f6, 01, 00, 2e, 00, 3c, 8b, 02, 00, 3d, 02, 0a, 86, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, 92, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
+Raw bytes (656): 0x[01, 01, 57, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 9f, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 9f, 01, 15, 0d, 11, 19, 45, 19, 97, 01, 45, 49, 97, 01, 4d, 45, 49, 19, 93, 01, 97, 01, 4d, 45, 49, 9f, 01, 9b, 02, 0d, 11, 15, 19, 15, 19, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, 9b, 02, 1d, 15, 19, 21, 39, 21, e3, 01, 39, 3d, e3, 01, 41, 39, 3d, 21, df, 01, e3, 01, 41, 39, 3d, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, d7, 02, 25, 1d, 21, 29, 2d, 29, cf, 02, 2d, 31, cf, 02, 35, 2d, 31, 29, cb, 02, cf, 02, 35, 2d, 31, d7, 02, db, 02, 1d, 21, 25, 29, 53, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0c, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 00, 17, 05, 01, 09, 00, 0a, 06, 01, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 00, 17, 09, 01, 09, 00, 12, 2a, 02, 09, 00, 0f, 03, 03, 09, 00, 16, 03, 00, 19, 00, 1a, 03, 01, 08, 00, 0c, 03, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 9f, 01, 03, 08, 00, 0c, 9f, 01, 01, 0d, 00, 1a, 9f, 01, 00, 1d, 00, 1e, 9f, 01, 01, 0c, 00, 10, 9f, 01, 00, 11, 02, 0a, 00, 02, 09, 00, 0a, 9f, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 72, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 7a, 00, 21, 00, 2e, 7e, 00, 32, 00, 40, 93, 01, 00, 41, 02, 0e, 8e, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 9a, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, 9b, 02, 02, 09, 00, 16, 9b, 02, 00, 19, 00, 1a, 9b, 02, 01, 08, 00, 0c, 9b, 02, 00, 0d, 02, 06, 00, 02, 05, 00, 06, d7, 02, 02, 09, 00, 0a, 9b, 02, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, be, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, c6, 01, 00, 1d, 00, 2a, ca, 01, 00, 2e, 00, 3c, df, 01, 00, 3d, 02, 0a, da, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, 96, 02, 02, 0d, 00, 20, 96, 02, 00, 23, 00, 2c, 96, 02, 01, 09, 00, 11, 96, 02, 00, 12, 00, 1b, 96, 02, 01, 09, 00, 0f, db, 02, 03, 09, 00, 0a, d7, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, aa, 02, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, b2, 02, 00, 1d, 00, 2a, b6, 02, 00, 2e, 00, 3c, cb, 02, 00, 3d, 02, 0a, c6, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, d2, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
-Number of expressions: 71
+Number of expressions: 87
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
- expression 2 operands: lhs = Counter(2), rhs = Counter(23)
@@ -23,66 +23,86 @@
- expression 17 operands: lhs = Counter(4), rhs = Expression(18, Add)
- expression 18 operands: lhs = Expression(19, Add), rhs = Counter(22)
- expression 19 operands: lhs = Counter(20), rhs = Counter(21)
-- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(37, Add)
+- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(39, Add)
- expression 21 operands: lhs = Counter(3), rhs = Counter(4)
- expression 22 operands: lhs = Counter(3), rhs = Counter(4)
- expression 23 operands: lhs = Counter(3), rhs = Counter(4)
- expression 24 operands: lhs = Counter(3), rhs = Counter(4)
- expression 25 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 26 operands: lhs = Expression(37, Add), rhs = Counter(5)
+- expression 26 operands: lhs = Counter(3), rhs = Counter(4)
- expression 27 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 28 operands: lhs = Counter(6), rhs = Counter(17)
-- expression 29 operands: lhs = Counter(6), rhs = Expression(35, Add)
-- expression 30 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 31 operands: lhs = Expression(35, Add), rhs = Counter(19)
+- expression 28 operands: lhs = Expression(39, Add), rhs = Counter(5)
+- expression 29 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 30 operands: lhs = Counter(6), rhs = Counter(17)
+- expression 31 operands: lhs = Counter(6), rhs = Expression(37, Add)
- expression 32 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 33 operands: lhs = Counter(6), rhs = Expression(34, Add)
-- expression 34 operands: lhs = Expression(35, Add), rhs = Counter(19)
-- expression 35 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 36 operands: lhs = Expression(37, Add), rhs = Expression(54, Add)
-- expression 37 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 38 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 39 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 33 operands: lhs = Expression(37, Add), rhs = Counter(19)
+- expression 34 operands: lhs = Counter(17), rhs = Counter(18)
+- expression 35 operands: lhs = Counter(6), rhs = Expression(36, Add)
+- expression 36 operands: lhs = Expression(37, Add), rhs = Counter(19)
+- expression 37 operands: lhs = Counter(17), rhs = Counter(18)
+- expression 38 operands: lhs = Expression(39, Add), rhs = Expression(70, Add)
+- expression 39 operands: lhs = Counter(3), rhs = Counter(4)
- expression 40 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 41 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 41 operands: lhs = Counter(5), rhs = Counter(6)
- expression 42 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 43 operands: lhs = Expression(54, Add), rhs = Counter(7)
+- expression 43 operands: lhs = Counter(5), rhs = Counter(6)
- expression 44 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 45 operands: lhs = Counter(8), rhs = Counter(14)
-- expression 46 operands: lhs = Counter(8), rhs = Expression(52, Add)
-- expression 47 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 48 operands: lhs = Expression(52, Add), rhs = Counter(16)
-- expression 49 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 50 operands: lhs = Counter(8), rhs = Expression(51, Add)
-- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(16)
-- expression 52 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 53 operands: lhs = Expression(54, Add), rhs = Expression(69, Add)
-- expression 54 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 55 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 56 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 57 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 58 operands: lhs = Expression(69, Add), rhs = Counter(9)
+- expression 45 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 46 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 47 operands: lhs = Expression(70, Add), rhs = Counter(7)
+- expression 48 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 49 operands: lhs = Counter(8), rhs = Counter(14)
+- expression 50 operands: lhs = Counter(8), rhs = Expression(56, Add)
+- expression 51 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 52 operands: lhs = Expression(56, Add), rhs = Counter(16)
+- expression 53 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 54 operands: lhs = Counter(8), rhs = Expression(55, Add)
+- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(16)
+- expression 56 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 57 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 58 operands: lhs = Counter(5), rhs = Counter(6)
- expression 59 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 60 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 61 operands: lhs = Counter(10), rhs = Expression(67, Add)
-- expression 62 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 63 operands: lhs = Expression(67, Add), rhs = Counter(13)
-- expression 64 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 65 operands: lhs = Counter(10), rhs = Expression(66, Add)
-- expression 66 operands: lhs = Expression(67, Add), rhs = Counter(13)
-- expression 67 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 68 operands: lhs = Expression(69, Add), rhs = Expression(70, Add)
-- expression 69 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 70 operands: lhs = Counter(9), rhs = Counter(10)
-Number of file 0 mappings: 68
-- Code(Counter(0)) at (prev + 3, 1) to (start + 2, 12)
-- Code(Counter(0)) at (prev + 2, 13) to (start + 2, 6)
+- expression 60 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 61 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 62 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 63 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 64 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 65 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 66 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 67 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 68 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 69 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 70 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 71 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 72 operands: lhs = Counter(9), rhs = Counter(10)
+- expression 73 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 74 operands: lhs = Expression(85, Add), rhs = Counter(9)
+- expression 75 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 76 operands: lhs = Counter(10), rhs = Counter(11)
+- expression 77 operands: lhs = Counter(10), rhs = Expression(83, Add)
+- expression 78 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 79 operands: lhs = Expression(83, Add), rhs = Counter(13)
+- expression 80 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 81 operands: lhs = Counter(10), rhs = Expression(82, Add)
+- expression 82 operands: lhs = Expression(83, Add), rhs = Counter(13)
+- expression 83 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 84 operands: lhs = Expression(85, Add), rhs = Expression(86, Add)
+- expression 85 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 86 operands: lhs = Counter(9), rhs = Counter(10)
+Number of file 0 mappings: 83
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 2, 6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 10)
= (c1 + c2)
- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 29)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 1, 10)
-- Code(Expression(1, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Expression(1, Sub)) at (prev + 1, 15) to (start + 0, 28)
= (c0 - c1)
- Code(Counter(2)) at (prev + 1, 12) to (start + 0, 25)
- Code(Expression(2, Sub)) at (prev + 0, 29) to (start + 0, 42)
@@ -93,12 +113,17 @@
= ((c23 + c24) + c25)
- Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c2 - ((c23 + c24) + c25))
-- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 18)
-- Code(Expression(10, Sub)) at (prev + 3, 9) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 18)
+- Code(Expression(10, Sub)) at (prev + 2, 9) to (start + 0, 15)
= (c0 - (c1 + c2))
-- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 1, 12)
+- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 22)
= (c1 + c2)
-- Code(Expression(0, Add)) at (prev + 1, 13) to (start + 2, 6)
+- Code(Expression(0, Add)) at (prev + 0, 25) to (start + 0, 26)
+ = (c1 + c2)
+- Code(Expression(0, Add)) at (prev + 1, 8) to (start + 0, 12)
+ = (c1 + c2)
+- Code(Expression(0, Add)) at (prev + 0, 13) to (start + 2, 6)
= (c1 + c2)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Expression(0, Add)) at (prev + 2, 8) to (start + 0, 21)
@@ -118,73 +143,89 @@
- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 23)
- Code(Expression(20, Sub)) at (prev + 2, 9) to (start + 0, 15)
= ((c1 + c2) - (c3 + c4))
-- Code(Expression(37, Add)) at (prev + 3, 8) to (start + 0, 12)
+- Code(Expression(39, Add)) at (prev + 3, 8) to (start + 0, 12)
= (c3 + c4)
-- Code(Expression(37, Add)) at (prev + 1, 13) to (start + 1, 16)
+- Code(Expression(39, Add)) at (prev + 1, 13) to (start + 0, 26)
= (c3 + c4)
-- Code(Expression(37, Add)) at (prev + 1, 17) to (start + 2, 10)
+- Code(Expression(39, Add)) at (prev + 0, 29) to (start + 0, 30)
+ = (c3 + c4)
+- Code(Expression(39, Add)) at (prev + 1, 12) to (start + 0, 16)
+ = (c3 + c4)
+- Code(Expression(39, Add)) at (prev + 0, 17) to (start + 2, 10)
= (c3 + c4)
- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
-- Code(Expression(37, Add)) at (prev + 2, 12) to (start + 0, 25)
+- Code(Expression(39, Add)) at (prev + 2, 12) to (start + 0, 25)
= (c3 + c4)
- Code(Counter(5)) at (prev + 0, 26) to (start + 2, 10)
-- Code(Expression(26, Sub)) at (prev + 4, 17) to (start + 0, 30)
+- Code(Expression(28, Sub)) at (prev + 4, 17) to (start + 0, 30)
= ((c3 + c4) - c5)
- Code(Counter(6)) at (prev + 1, 16) to (start + 0, 29)
-- Code(Expression(28, Sub)) at (prev + 0, 33) to (start + 0, 46)
+- Code(Expression(30, Sub)) at (prev + 0, 33) to (start + 0, 46)
= (c6 - c17)
-- Code(Expression(29, Sub)) at (prev + 0, 50) to (start + 0, 64)
+- Code(Expression(31, Sub)) at (prev + 0, 50) to (start + 0, 64)
= (c6 - (c17 + c18))
-- Code(Expression(34, Add)) at (prev + 0, 65) to (start + 2, 14)
+- Code(Expression(36, Add)) at (prev + 0, 65) to (start + 2, 14)
= ((c17 + c18) + c19)
-- Code(Expression(33, Sub)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Expression(35, Sub)) at (prev + 2, 13) to (start + 0, 14)
= (c6 - ((c17 + c18) + c19))
- Code(Counter(6)) at (prev + 1, 13) to (start + 0, 27)
-- Code(Expression(36, Sub)) at (prev + 2, 13) to (start + 0, 19)
+- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 19)
= ((c3 + c4) - (c5 + c6))
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
-- Code(Expression(54, Add)) at (prev + 2, 9) to (start + 1, 12)
+- Code(Expression(70, Add)) at (prev + 2, 9) to (start + 0, 22)
= (c5 + c6)
-- Code(Expression(54, Add)) at (prev + 1, 13) to (start + 2, 6)
+- Code(Expression(70, Add)) at (prev + 0, 25) to (start + 0, 26)
+ = (c5 + c6)
+- Code(Expression(70, Add)) at (prev + 1, 8) to (start + 0, 12)
+ = (c5 + c6)
+- Code(Expression(70, Add)) at (prev + 0, 13) to (start + 2, 6)
= (c5 + c6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
-- Code(Expression(69, Add)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(85, Add)) at (prev + 2, 9) to (start + 0, 10)
= (c7 + c8)
-- Code(Expression(54, Add)) at (prev + 0, 16) to (start + 0, 29)
+- Code(Expression(70, Add)) at (prev + 0, 16) to (start + 0, 29)
= (c5 + c6)
- Code(Counter(7)) at (prev + 0, 30) to (start + 2, 6)
-- Code(Expression(43, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Expression(47, Sub)) at (prev + 2, 15) to (start + 0, 28)
= ((c5 + c6) - c7)
- Code(Counter(8)) at (prev + 1, 12) to (start + 0, 25)
-- Code(Expression(45, Sub)) at (prev + 0, 29) to (start + 0, 42)
+- Code(Expression(49, Sub)) at (prev + 0, 29) to (start + 0, 42)
= (c8 - c14)
-- Code(Expression(46, Sub)) at (prev + 0, 46) to (start + 0, 60)
+- Code(Expression(50, Sub)) at (prev + 0, 46) to (start + 0, 60)
= (c8 - (c14 + c15))
-- Code(Expression(51, Add)) at (prev + 0, 61) to (start + 2, 10)
+- Code(Expression(55, Add)) at (prev + 0, 61) to (start + 2, 10)
= ((c14 + c15) + c16)
-- Code(Expression(50, Sub)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(54, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c8 - ((c14 + c15) + c16))
- Code(Counter(8)) at (prev + 1, 9) to (start + 0, 23)
-- Code(Expression(53, Sub)) at (prev + 2, 13) to (start + 2, 15)
+- Code(Expression(69, Sub)) at (prev + 2, 13) to (start + 0, 32)
= ((c5 + c6) - (c7 + c8))
-- Code(Expression(70, Add)) at (prev + 5, 9) to (start + 0, 10)
+- Code(Expression(69, Sub)) at (prev + 0, 35) to (start + 0, 44)
+ = ((c5 + c6) - (c7 + c8))
+- Code(Expression(69, Sub)) at (prev + 1, 9) to (start + 0, 17)
+ = ((c5 + c6) - (c7 + c8))
+- Code(Expression(69, Sub)) at (prev + 0, 18) to (start + 0, 27)
+ = ((c5 + c6) - (c7 + c8))
+- Code(Expression(69, Sub)) at (prev + 1, 9) to (start + 0, 15)
+ = ((c5 + c6) - (c7 + c8))
+- Code(Expression(86, Add)) at (prev + 3, 9) to (start + 0, 10)
= (c9 + c10)
-- Code(Expression(69, Add)) at (prev + 0, 16) to (start + 0, 29)
+- Code(Expression(85, Add)) at (prev + 0, 16) to (start + 0, 29)
= (c7 + c8)
- Code(Counter(9)) at (prev + 0, 30) to (start + 2, 6)
-- Code(Expression(58, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Expression(74, Sub)) at (prev + 2, 15) to (start + 0, 28)
= ((c7 + c8) - c9)
- Code(Counter(10)) at (prev + 1, 12) to (start + 0, 25)
-- Code(Expression(60, Sub)) at (prev + 0, 29) to (start + 0, 42)
+- Code(Expression(76, Sub)) at (prev + 0, 29) to (start + 0, 42)
= (c10 - c11)
-- Code(Expression(61, Sub)) at (prev + 0, 46) to (start + 0, 60)
+- Code(Expression(77, Sub)) at (prev + 0, 46) to (start + 0, 60)
= (c10 - (c11 + c12))
-- Code(Expression(66, Add)) at (prev + 0, 61) to (start + 2, 10)
+- Code(Expression(82, Add)) at (prev + 0, 61) to (start + 2, 10)
= ((c11 + c12) + c13)
-- Code(Expression(65, Sub)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(81, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c10 - ((c11 + c12) + c13))
- Code(Counter(10)) at (prev + 1, 9) to (start + 0, 23)
-- Code(Expression(68, Sub)) at (prev + 2, 9) to (start + 0, 15)
+- Code(Expression(84, Sub)) at (prev + 2, 9) to (start + 0, 15)
= ((c7 + c8) - (c9 + c10))
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c10
diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map
index a8077a3..1a839f1 100644
--- a/tests/coverage/continue.cov-map
+++ b/tests/coverage/continue.cov-map
@@ -1,75 +1,88 @@
Function name: continue::main
-Raw bytes (198): 0x[01, 01, 16, 05, 01, 05, 0b, 01, 09, 0d, 01, 0d, 1f, 01, 11, 0d, 1f, 01, 11, 15, 01, 15, 2b, 01, 19, 1d, 01, 1d, 37, 01, 21, 25, 01, 25, 43, 01, 29, 25, 01, 2d, 01, 53, 2d, 01, 31, 2d, 01, 1e, 01, 03, 01, 03, 12, 05, 04, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 06, 02, 12, 04, 0e, 0d, 06, 0e, 00, 13, 0e, 01, 0f, 00, 16, 1a, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 1a, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 22, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 26, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 2e, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 32, 01, 0a, 01, 0e, 25, 03, 0e, 00, 13, 46, 01, 0f, 00, 16, 3e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 46, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 56, 01, 16, 02, 0e, 4e, 04, 11, 00, 16, 56, 03, 09, 00, 0e, 01, 02, 0d, 01, 02]
+Raw bytes (241): 0x[01, 01, 1a, 05, 01, 05, 13, 01, 09, 05, 13, 01, 09, 0d, 01, 0d, 27, 01, 11, 0d, 27, 01, 11, 15, 01, 15, 33, 01, 19, 1d, 01, 1d, 47, 01, 21, 1d, 47, 01, 21, 25, 01, 25, 53, 01, 29, 25, 01, 2d, 01, 63, 2d, 01, 31, 2d, 01, 25, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 0e, 02, 12, 02, 0e, 0e, 04, 09, 00, 0e, 0d, 02, 0e, 00, 13, 16, 01, 0f, 00, 16, 22, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 22, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 2e, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 36, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 42, 01, 09, 00, 0a, 42, 01, 09, 00, 0e, 25, 02, 0e, 00, 13, 56, 01, 0f, 00, 16, 4e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 56, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 66, 01, 16, 02, 0e, 5e, 04, 11, 00, 16, 66, 03, 09, 00, 0e, 01, 02, 0d, 00, 0e, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/continue.rs
-Number of expressions: 22
+Number of expressions: 26
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(4, Add)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(3), rhs = Counter(0)
-- expression 4 operands: lhs = Counter(3), rhs = Expression(7, Add)
-- expression 5 operands: lhs = Counter(0), rhs = Counter(4)
-- expression 6 operands: lhs = Counter(3), rhs = Expression(7, Add)
+- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 5 operands: lhs = Counter(3), rhs = Counter(0)
+- expression 6 operands: lhs = Counter(3), rhs = Expression(9, Add)
- expression 7 operands: lhs = Counter(0), rhs = Counter(4)
-- expression 8 operands: lhs = Counter(5), rhs = Counter(0)
-- expression 9 operands: lhs = Counter(5), rhs = Expression(10, Add)
-- expression 10 operands: lhs = Counter(0), rhs = Counter(6)
-- expression 11 operands: lhs = Counter(7), rhs = Counter(0)
-- expression 12 operands: lhs = Counter(7), rhs = Expression(13, Add)
-- expression 13 operands: lhs = Counter(0), rhs = Counter(8)
-- expression 14 operands: lhs = Counter(9), rhs = Counter(0)
-- expression 15 operands: lhs = Counter(9), rhs = Expression(16, Add)
-- expression 16 operands: lhs = Counter(0), rhs = Counter(10)
-- expression 17 operands: lhs = Counter(9), rhs = Counter(0)
-- expression 18 operands: lhs = Counter(11), rhs = Counter(0)
-- expression 19 operands: lhs = Expression(20, Add), rhs = Counter(11)
-- expression 20 operands: lhs = Counter(0), rhs = Counter(12)
-- expression 21 operands: lhs = Counter(11), rhs = Counter(0)
-Number of file 0 mappings: 30
-- Code(Counter(0)) at (prev + 3, 1) to (start + 3, 18)
-- Code(Counter(1)) at (prev + 4, 14) to (start + 0, 19)
+- expression 8 operands: lhs = Counter(3), rhs = Expression(9, Add)
+- expression 9 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 10 operands: lhs = Counter(5), rhs = Counter(0)
+- expression 11 operands: lhs = Counter(5), rhs = Expression(12, Add)
+- expression 12 operands: lhs = Counter(0), rhs = Counter(6)
+- expression 13 operands: lhs = Counter(7), rhs = Counter(0)
+- expression 14 operands: lhs = Counter(7), rhs = Expression(17, Add)
+- expression 15 operands: lhs = Counter(0), rhs = Counter(8)
+- expression 16 operands: lhs = Counter(7), rhs = Expression(17, Add)
+- expression 17 operands: lhs = Counter(0), rhs = Counter(8)
+- expression 18 operands: lhs = Counter(9), rhs = Counter(0)
+- expression 19 operands: lhs = Counter(9), rhs = Expression(20, Add)
+- expression 20 operands: lhs = Counter(0), rhs = Counter(10)
+- expression 21 operands: lhs = Counter(9), rhs = Counter(0)
+- expression 22 operands: lhs = Counter(11), rhs = Counter(0)
+- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(11)
+- expression 24 operands: lhs = Counter(0), rhs = Counter(12)
+- expression 25 operands: lhs = Counter(11), rhs = Counter(0)
+Number of file 0 mappings: 37
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 19)
- Code(Expression(0, Sub)) at (prev + 1, 15) to (start + 0, 22)
= (c1 - c0)
- Code(Counter(2)) at (prev + 2, 17) to (start + 0, 25)
-- Code(Expression(1, Sub)) at (prev + 2, 18) to (start + 4, 14)
+- Code(Expression(3, Sub)) at (prev + 2, 18) to (start + 2, 14)
= (c1 - (c0 + c2))
-- Code(Counter(3)) at (prev + 6, 14) to (start + 0, 19)
-- Code(Expression(3, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- Code(Expression(3, Sub)) at (prev + 4, 9) to (start + 0, 14)
+ = (c1 - (c0 + c2))
+- Code(Counter(3)) at (prev + 2, 14) to (start + 0, 19)
+- Code(Expression(5, Sub)) at (prev + 1, 15) to (start + 0, 22)
= (c3 - c0)
-- Code(Expression(6, Sub)) at (prev + 1, 22) to (start + 2, 14)
+- Code(Expression(8, Sub)) at (prev + 1, 22) to (start + 2, 14)
= (c3 - (c0 + c4))
- Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25)
-- Code(Expression(6, Sub)) at (prev + 3, 9) to (start + 0, 14)
+- Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 14)
= (c3 - (c0 + c4))
- Code(Counter(5)) at (prev + 2, 14) to (start + 0, 19)
-- Code(Expression(8, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- Code(Expression(10, Sub)) at (prev + 1, 15) to (start + 0, 22)
= (c5 - c0)
- Code(Counter(6)) at (prev + 1, 21) to (start + 2, 14)
-- Code(Expression(9, Sub)) at (prev + 4, 17) to (start + 0, 25)
+- Code(Expression(11, Sub)) at (prev + 4, 17) to (start + 0, 25)
= (c5 - (c0 + c6))
- Code(Counter(6)) at (prev + 3, 9) to (start + 0, 14)
- Code(Counter(7)) at (prev + 2, 14) to (start + 0, 19)
-- Code(Expression(11, Sub)) at (prev + 1, 12) to (start + 0, 19)
+- Code(Expression(13, Sub)) at (prev + 1, 12) to (start + 0, 19)
= (c7 - c0)
- Code(Counter(8)) at (prev + 1, 13) to (start + 0, 21)
-- Code(Expression(12, Sub)) at (prev + 1, 10) to (start + 1, 14)
+- Code(Expression(16, Sub)) at (prev + 1, 9) to (start + 0, 10)
= (c7 - (c0 + c8))
-- Code(Counter(9)) at (prev + 3, 14) to (start + 0, 19)
-- Code(Expression(17, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- Code(Expression(16, Sub)) at (prev + 1, 9) to (start + 0, 14)
+ = (c7 - (c0 + c8))
+- Code(Counter(9)) at (prev + 2, 14) to (start + 0, 19)
+- Code(Expression(21, Sub)) at (prev + 1, 15) to (start + 0, 22)
= (c9 - c0)
-- Code(Expression(15, Sub)) at (prev + 1, 22) to (start + 2, 14)
+- Code(Expression(19, Sub)) at (prev + 1, 22) to (start + 2, 14)
= (c9 - (c0 + c10))
- Code(Counter(10)) at (prev + 3, 18) to (start + 2, 14)
-- Code(Expression(17, Sub)) at (prev + 4, 9) to (start + 0, 14)
+- Code(Expression(21, Sub)) at (prev + 4, 9) to (start + 0, 14)
= (c9 - c0)
- Code(Counter(11)) at (prev + 2, 14) to (start + 0, 19)
- Code(Counter(12)) at (prev + 1, 15) to (start + 0, 22)
-- Code(Expression(21, Sub)) at (prev + 1, 22) to (start + 2, 14)
+- Code(Expression(25, Sub)) at (prev + 1, 22) to (start + 2, 14)
= (c11 - c0)
-- Code(Expression(19, Sub)) at (prev + 4, 17) to (start + 0, 22)
+- Code(Expression(23, Sub)) at (prev + 4, 17) to (start + 0, 22)
= ((c0 + c12) - c11)
-- Code(Expression(21, Sub)) at (prev + 3, 9) to (start + 0, 14)
+- Code(Expression(25, Sub)) at (prev + 3, 9) to (start + 0, 14)
= (c11 - c0)
-- Code(Counter(0)) at (prev + 2, 13) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c12
diff --git a/tests/coverage/continue.coverage b/tests/coverage/continue.coverage
index 4916cac..17fe487 100644
--- a/tests/coverage/continue.coverage
+++ b/tests/coverage/continue.coverage
@@ -2,7 +2,7 @@
LL| |
LL| 1|fn main() {
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let mut x = 0;
LL| 11| for _ in 0..10 {
LL| 10| match is_true {
@@ -12,7 +12,7 @@
LL| 0| _ => {
LL| 0| x = 1;
LL| 0| }
- LL| 0| }
+ LL| | }
LL| 0| x = 3;
LL| | }
LL| 11| for _ in 0..10 {
diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map
index 0ce9155..daa4291 100644
--- a/tests/coverage/coroutine.cov-map
+++ b/tests/coverage/coroutine.cov-map
@@ -1,31 +1,40 @@
Function name: coroutine::get_u32
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 01, 01, 0b, 05, 02, 09, 00, 0e, 02, 02, 09, 00, 28, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0b, 01, 00, 2d, 01, 01, 08, 00, 0b, 05, 01, 09, 00, 0e, 02, 02, 09, 00, 28, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/coroutine.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 11)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 14)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 11)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 14)
- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 40)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: coroutine::main
-Raw bytes (53): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2d, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 02, 01, 00, 02]
+Raw bytes (93): 0x[01, 01, 02, 01, 05, 05, 09, 11, 01, 13, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 06, 0b, 00, 13, 01, 00, 14, 00, 22, 01, 00, 24, 00, 2a, 01, 00, 2b, 00, 2d, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 13, 05, 00, 0b, 00, 2e, 05, 00, 14, 00, 22, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/coroutine.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 22)
-- Code(Counter(0)) at (prev + 8, 11) to (start + 0, 45)
+Number of file 0 mappings: 17
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 6, 11) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 0, 36) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 0, 43) to (start + 0, 45)
- Code(Counter(1)) at (prev + 1, 43) to (start + 0, 45)
- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 20)
= (c0 - c1)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 19)
+- Code(Counter(1)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 0, 20) to (start + 0, 34)
- Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39)
- Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46)
- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 20)
@@ -34,12 +43,14 @@
Highest counter ID seen: c3
Function name: coroutine::main::{closure#0}
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 16, 08, 01, 1f, 05, 02, 10, 01, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 08, 00, 09, 01, 01, 09, 00, 1f, 05, 01, 10, 00, 15, 05, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/coroutine.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 22, 8) to (start + 1, 31)
-- Code(Counter(1)) at (prev + 2, 16) to (start + 1, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 22, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 31)
+- Code(Counter(1)) at (prev + 1, 16) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c1
diff --git a/tests/coverage/coverage_attr_closure.cov-map b/tests/coverage/coverage_attr_closure.cov-map
index e029a3b..deba65f 100644
--- a/tests/coverage/coverage_attr_closure.cov-map
+++ b/tests/coverage/coverage_attr_closure.cov-map
@@ -1,38 +1,48 @@
Function name: coverage_attr_closure::GLOBAL_CLOSURE_ON::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 0f, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 06, 0f, 00, 10, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 17, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/coverage_attr_closure.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 6, 15) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 6, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: coverage_attr_closure::contains_closures_off::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1d, 13, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 1d, 13, 00, 14, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1b, 00, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/coverage_attr_closure.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 29, 19) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 29, 19) to (start + 0, 20)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: (none)
Function name: coverage_attr_closure::contains_closures_on
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 0f, 01, 01, 1a, 01, 05, 09, 00, 1b, 01, 04, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 01, 00, 1a, 01, 01, 09, 00, 1a, 01, 04, 09, 00, 1b, 01, 04, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/coverage_attr_closure.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 26)
-- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 27)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 27)
- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: coverage_attr_closure::contains_closures_on::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 13, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 11, 13, 00, 14, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1b, 00, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/coverage_attr_closure.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 17, 19) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 17, 19) to (start + 0, 20)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: (none)
diff --git a/tests/coverage/dead_code.cov-map b/tests/coverage/dead_code.cov-map
index 4cb3114..ae4146d 100644
--- a/tests/coverage/dead_code.cov-map
+++ b/tests/coverage/dead_code.cov-map
@@ -1,37 +1,52 @@
Function name: dead_code::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 1b, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 1b, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/dead_code.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 27, 1) to (start + 7, 15)
-- Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: dead_code::unused_fn (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 00, 0f, 01, 00, 0f, 00, 04, 09, 00, 10, 00, 00, 13, 00, 2e, 00, 02, 09, 00, 16, 00, 00, 19, 00, 1a, 00, 01, 08, 00, 0f, 00, 00, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/dead_code.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Zero) at (prev + 15, 1) to (start + 7, 15)
-- Code(Zero) at (prev + 7, 16) to (start + 2, 6)
+Number of file 0 mappings: 9
+- Code(Zero) at (prev + 15, 1) to (start + 0, 15)
+- Code(Zero) at (prev + 4, 9) to (start + 0, 16)
+- Code(Zero) at (prev + 0, 19) to (start + 0, 46)
+- Code(Zero) at (prev + 2, 9) to (start + 0, 22)
+- Code(Zero) at (prev + 0, 25) to (start + 0, 26)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 16) to (start + 2, 6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
Function name: dead_code::unused_pub_fn_not_in_library (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 00, 03, 01, 00, 26, 00, 04, 09, 00, 10, 00, 00, 13, 00, 2e, 00, 02, 09, 00, 16, 00, 00, 19, 00, 1a, 00, 01, 08, 00, 0f, 00, 00, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/dead_code.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Zero) at (prev + 3, 1) to (start + 7, 15)
-- Code(Zero) at (prev + 7, 16) to (start + 2, 6)
+Number of file 0 mappings: 9
+- Code(Zero) at (prev + 3, 1) to (start + 0, 38)
+- Code(Zero) at (prev + 4, 9) to (start + 0, 16)
+- Code(Zero) at (prev + 0, 19) to (start + 0, 46)
+- Code(Zero) at (prev + 2, 9) to (start + 0, 22)
+- Code(Zero) at (prev + 0, 25) to (start + 0, 26)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 16) to (start + 2, 6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
diff --git a/tests/coverage/dead_code.coverage b/tests/coverage/dead_code.coverage
index 55d196f..fbb4a00 100644
--- a/tests/coverage/dead_code.coverage
+++ b/tests/coverage/dead_code.coverage
@@ -1,11 +1,11 @@
LL| |#![allow(dead_code, unused_assignments, unused_variables)]
LL| |
LL| 0|pub fn unused_pub_fn_not_in_library() {
- LL| 0| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 0| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 0| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 0| let is_true = std::env::args().len() == 1;
- LL| 0|
+ LL| |
LL| 0| let mut countdown = 0;
LL| 0| if is_true {
LL| 0| countdown = 10;
@@ -13,11 +13,11 @@
LL| 0|}
LL| |
LL| 0|fn unused_fn() {
- LL| 0| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 0| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 0| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 0| let is_true = std::env::args().len() == 1;
- LL| 0|
+ LL| |
LL| 0| let mut countdown = 0;
LL| 0| if is_true {
LL| 0| countdown = 10;
@@ -25,11 +25,11 @@
LL| 0|}
LL| |
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let mut countdown = 0;
LL| 1| if is_true {
LL| 1| countdown = 10;
diff --git a/tests/coverage/drop_trait.cov-map b/tests/coverage/drop_trait.cov-map
index a52ebd8..dcf9dbd 100644
--- a/tests/coverage/drop_trait.cov-map
+++ b/tests/coverage/drop_trait.cov-map
@@ -1,21 +1,33 @@
Function name: <drop_trait::Firework as core::ops::drop::Drop>::drop
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 05, 02, 06]
-Number of files: 1
-- file 0 => $DIR/drop_trait.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 9, 5) to (start + 2, 6)
-Highest counter ID seen: c0
-
-Function name: drop_trait::main
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 0e, 01, 05, 0c, 01, 06, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/drop_trait.rs
Number of expressions: 0
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 14, 1) to (start + 5, 12)
-- Code(Counter(0)) at (prev + 6, 9) to (start + 1, 22)
-- Code(Zero) at (prev + 2, 6) to (start + 4, 11)
-- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2)
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c0
+
+Function name: drop_trait::main
+Raw bytes (69): 0x[01, 01, 00, 0d, 01, 0e, 01, 00, 1c, 01, 01, 09, 00, 15, 01, 00, 18, 00, 30, 01, 02, 09, 00, 0d, 01, 00, 10, 00, 2a, 01, 02, 08, 00, 0c, 01, 01, 09, 00, 11, 01, 00, 12, 00, 29, 01, 01, 10, 00, 16, 00, 01, 05, 00, 06, 00, 02, 0d, 00, 28, 00, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
+Number of files: 1
+- file 0 => $DIR/drop_trait.rs
+Number of expressions: 0
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 48)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 22)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
+- Code(Zero) at (prev + 2, 13) to (start + 0, 40)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/drop_trait.coverage b/tests/coverage/drop_trait.coverage
index 85d55757..10ed8c0 100644
--- a/tests/coverage/drop_trait.coverage
+++ b/tests/coverage/drop_trait.coverage
@@ -13,16 +13,16 @@
LL| |
LL| 1|fn main() -> Result<(), u8> {
LL| 1| let _firecracker = Firework { strength: 1 };
- LL| 1|
+ LL| |
LL| 1| let _tnt = Firework { strength: 100 };
- LL| 1|
+ LL| |
LL| 1| if true {
LL| 1| println!("Exiting with error...");
LL| 1| return Err(1);
LL| 0| }
- LL| 0|
+ LL| |
LL| 0| let _ = Firework { strength: 1000 };
- LL| 0|
+ LL| |
LL| 0| Ok(())
LL| 1|}
LL| |
diff --git a/tests/coverage/fn_sig_into_try.cov-map b/tests/coverage/fn_sig_into_try.cov-map
index 465baa7..fc57a48 100644
--- a/tests/coverage/fn_sig_into_try.cov-map
+++ b/tests/coverage/fn_sig_into_try.cov-map
@@ -1,44 +1,52 @@
Function name: fn_sig_into_try::a
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 05, 02]
-Number of files: 1
-- file 0 => $DIR/fn_sig_into_try.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 1) to (start + 5, 2)
-Highest counter ID seen: c0
-
-Function name: fn_sig_into_try::b
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 01, 03, 0f, 00, 03, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 0a, 01, 00, 16, 01, 03, 05, 00, 0f, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/fn_sig_into_try.rs
Number of expressions: 0
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 17, 1) to (start + 3, 15)
-- Code(Zero) at (prev + 3, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
+Highest counter ID seen: c0
+
+Function name: fn_sig_into_try::b
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 11, 01, 00, 16, 01, 03, 05, 00, 0f, 00, 00, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Number of files: 1
+- file 0 => $DIR/fn_sig_into_try.rs
+Number of expressions: 0
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 15) to (start + 0, 16)
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: fn_sig_into_try::c
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 01, 03, 17, 00, 03, 17, 00, 18, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 18, 01, 00, 16, 01, 03, 0d, 00, 17, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/fn_sig_into_try.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 24, 1) to (start + 3, 23)
-- Code(Zero) at (prev + 3, 23) to (start + 0, 24)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 3, 13) to (start + 0, 23)
+- Code(Zero) at (prev + 0, 23) to (start + 0, 24)
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: fn_sig_into_try::d
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 04, 0f, 00, 04, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (39): 0x[01, 01, 00, 07, 01, 1f, 01, 00, 16, 01, 03, 0c, 00, 0e, 01, 00, 11, 00, 13, 01, 01, 05, 00, 0f, 00, 00, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/fn_sig_into_try.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 31, 1) to (start + 4, 15)
-- Code(Zero) at (prev + 4, 15) to (start + 0, 16)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 3, 12) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 15) to (start + 0, 16)
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/fn_sig_into_try.coverage b/tests/coverage/fn_sig_into_try.coverage
index cabe747..bc744db 100644
--- a/tests/coverage/fn_sig_into_try.coverage
+++ b/tests/coverage/fn_sig_into_try.coverage
@@ -8,31 +8,31 @@
LL| |// signature should be handled in the same way.
LL| |
LL| 1|fn a() -> Option<i32>
- LL| 1|//
- LL| 1|{
+ LL| |//
+ LL| |{
LL| 1| Some(7i32);
LL| 1| Some(0)
LL| 1|}
LL| |
LL| 1|fn b() -> Option<i32>
- LL| 1|//
- LL| 1|{
+ LL| |//
+ LL| |{
LL| 1| Some(7i32)?;
^0
LL| 1| Some(0)
LL| 1|}
LL| |
LL| 1|fn c() -> Option<i32>
- LL| 1|//
- LL| 1|{
+ LL| |//
+ LL| |{
LL| 1| let _ = Some(7i32)?;
^0
LL| 1| Some(0)
LL| 1|}
LL| |
LL| 1|fn d() -> Option<i32>
- LL| 1|//
- LL| 1|{
+ LL| |//
+ LL| |{
LL| 1| let _: () = ();
LL| 1| Some(7i32)?;
^0
diff --git a/tests/coverage/generic-unused-impl.cov-map b/tests/coverage/generic-unused-impl.cov-map
index 119c426..da9e549 100644
--- a/tests/coverage/generic-unused-impl.cov-map
+++ b/tests/coverage/generic-unused-impl.cov-map
@@ -1,18 +1,23 @@
Function name: <generic_unused_impl::W<_> as core::convert::From<[<_ as generic_unused_impl::Foo>::Assoc; 1]>>::from (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0b, 05, 03, 06]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 0b, 05, 00, 29, 00, 01, 0e, 00, 12, 00, 00, 16, 00, 1a, 00, 01, 09, 00, 1b, 00, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/generic-unused-impl.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 11, 5) to (start + 3, 6)
+Number of file 0 mappings: 5
+- Code(Zero) at (prev + 11, 5) to (start + 0, 41)
+- Code(Zero) at (prev + 1, 14) to (start + 0, 18)
+- Code(Zero) at (prev + 0, 22) to (start + 0, 26)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: (none)
Function name: generic_unused_impl::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => $DIR/generic-unused-impl.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0
diff --git a/tests/coverage/generics.cov-map b/tests/coverage/generics.cov-map
index 92c6ad0..7f9b7ee 100644
--- a/tests/coverage/generics.cov-map
+++ b/tests/coverage/generics.cov-map
@@ -1,48 +1,73 @@
Function name: <generics::Firework<f64> as core::ops::drop::Drop>::drop
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06]
-Number of files: 1
-- file 0 => $DIR/generics.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6)
-Highest counter ID seen: c0
-
-Function name: <generics::Firework<f64>>::set_strength
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 05, 02, 06]
-Number of files: 1
-- file 0 => $DIR/generics.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 5) to (start + 2, 6)
-Highest counter ID seen: c0
-
-Function name: <generics::Firework<i32> as core::ops::drop::Drop>::drop
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06]
-Number of files: 1
-- file 0 => $DIR/generics.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6)
-Highest counter ID seen: c0
-
-Function name: <generics::Firework<i32>>::set_strength
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 05, 02, 06]
-Number of files: 1
-- file 0 => $DIR/generics.rs
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 5) to (start + 2, 6)
-Highest counter ID seen: c0
-
-Function name: generics::main
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 01, 08, 0c, 01, 09, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/generics.rs
Number of expressions: 0
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 22, 1) to (start + 8, 12)
-- Code(Counter(0)) at (prev + 9, 9) to (start + 1, 22)
-- Code(Zero) at (prev + 2, 6) to (start + 4, 11)
-- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2)
+- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c0
+
+Function name: <generics::Firework<f64>>::set_strength
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 05, 00, 30, 01, 01, 09, 00, 25, 01, 01, 05, 00, 06]
+Number of files: 1
+- file 0 => $DIR/generics.rs
+Number of expressions: 0
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 48)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c0
+
+Function name: <generics::Firework<i32> as core::ops::drop::Drop>::drop
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06]
+Number of files: 1
+- file 0 => $DIR/generics.rs
+Number of expressions: 0
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c0
+
+Function name: <generics::Firework<i32>>::set_strength
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 05, 00, 30, 01, 01, 09, 00, 25, 01, 01, 05, 00, 06]
+Number of files: 1
+- file 0 => $DIR/generics.rs
+Number of expressions: 0
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 48)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c0
+
+Function name: generics::main
+Raw bytes (99): 0x[01, 01, 00, 13, 01, 16, 01, 00, 1c, 01, 01, 09, 00, 18, 01, 00, 1b, 00, 33, 01, 01, 05, 00, 10, 01, 00, 11, 00, 1d, 01, 02, 09, 00, 10, 01, 00, 13, 00, 2f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 15, 01, 01, 05, 00, 08, 01, 00, 09, 00, 15, 01, 02, 08, 00, 0c, 01, 01, 09, 00, 11, 01, 00, 12, 00, 29, 01, 01, 10, 00, 16, 00, 01, 05, 00, 06, 00, 02, 0d, 00, 28, 00, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
+Number of files: 1
+- file 0 => $DIR/generics.rs
+Number of expressions: 0
+Number of file 0 mappings: 19
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 51)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 47)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 22)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
+- Code(Zero) at (prev + 2, 13) to (start + 0, 40)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/generics.coverage b/tests/coverage/generics.coverage
index a2cd146..43697ca 100644
--- a/tests/coverage/generics.coverage
+++ b/tests/coverage/generics.coverage
@@ -44,18 +44,18 @@
LL| 1|fn main() -> Result<(), u8> {
LL| 1| let mut firecracker = Firework { strength: 1 };
LL| 1| firecracker.set_strength(2);
- LL| 1|
+ LL| |
LL| 1| let mut tnt = Firework { strength: 100.1 };
LL| 1| tnt.set_strength(200.1);
LL| 1| tnt.set_strength(300.3);
- LL| 1|
+ LL| |
LL| 1| if true {
LL| 1| println!("Exiting with error...");
LL| 1| return Err(1);
LL| 0| }
- LL| 0|
+ LL| |
LL| 0| let _ = Firework { strength: 1000 };
- LL| 0|
+ LL| |
LL| 0| Ok(())
LL| 1|}
LL| |
diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map
index 5298c2d..c2158c4 100644
--- a/tests/coverage/holes.cov-map
+++ b/tests/coverage/holes.cov-map
@@ -1,57 +1,81 @@
Function name: <holes::main::MyStruct>::_method (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 2b, 09, 00, 1d]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 2b, 09, 00, 1a, 00, 00, 1c, 00, 1d]
Number of files: 1
- file 0 => $DIR/holes.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 43, 9) to (start + 0, 29)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 43, 9) to (start + 0, 26)
+- Code(Zero) at (prev + 0, 28) to (start + 0, 29)
Highest counter ID seen: (none)
Function name: holes::main
-Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 11, 01, 05, 05, 00, 11, 01, 07, 09, 00, 11, 01, 09, 05, 00, 11, 01, 04, 05, 00, 11, 01, 07, 05, 00, 11, 01, 06, 05, 00, 11, 01, 04, 05, 00, 11, 01, 04, 05, 00, 11, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 06, 27, 01, 13, 05, 01, 02]
+Raw bytes (154): 0x[01, 01, 00, 1e, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 07, 09, 00, 11, 01, 09, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 03, 09, 00, 0f, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 03, 09, 00, 0f, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 09, 00, 27, 01, 0d, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/holes.rs
Number of expressions: 0
-Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 17)
-- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 17)
+Number of file 0 mappings: 30
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
- Code(Counter(0)) at (prev + 7, 9) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 3, 15)
-- Code(Counter(0)) at (prev + 10, 5) to (start + 3, 15)
-- Code(Counter(0)) at (prev + 10, 5) to (start + 6, 39)
-- Code(Counter(0)) at (prev + 19, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 6, 9) to (start + 0, 39)
+- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: holes::main::_unused_fn (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 05, 00, 17]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 1f, 05, 00, 14, 00, 00, 16, 00, 17]
Number of files: 1
- file 0 => $DIR/holes.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 31, 5) to (start + 0, 23)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 31, 5) to (start + 0, 20)
+- Code(Zero) at (prev + 0, 22) to (start + 0, 23)
Highest counter ID seen: (none)
Function name: holes::main::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 09, 02, 0a]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 18, 09, 00, 0a, 00, 01, 0d, 00, 16, 00, 00, 17, 00, 19, 00, 01, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/holes.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 24, 9) to (start + 2, 10)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 24, 9) to (start + 0, 10)
+- Code(Zero) at (prev + 1, 13) to (start + 0, 22)
+- Code(Zero) at (prev + 0, 23) to (start + 0, 25)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 10)
Highest counter ID seen: (none)
Function name: holes::main::{closure#1} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 4b, 09, 02, 0a]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 4b, 09, 00, 0a, 00, 01, 0d, 00, 12, 00, 01, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/holes.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 75, 9) to (start + 2, 10)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 75, 9) to (start + 0, 10)
+- Code(Zero) at (prev + 1, 13) to (start + 0, 18)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 10)
Highest counter ID seen: (none)
diff --git a/tests/coverage/holes.coverage b/tests/coverage/holes.coverage
index a6a02f1..1ea6049 100644
--- a/tests/coverage/holes.coverage
+++ b/tests/coverage/holes.coverage
@@ -58,8 +58,8 @@
LL| | }
LL| |
LL| 1| black_box(());
- LL| 1|
- LL| 1| #[rustfmt::skip]
+ LL| |
+ LL| | #[rustfmt::skip]
LL| 1| let _const =
LL| | const
LL| | {
@@ -68,8 +68,8 @@
LL| | ;
LL| |
LL| 1| black_box(());
- LL| 1|
- LL| 1| #[rustfmt::skip]
+ LL| |
+ LL| | #[rustfmt::skip]
LL| 1| let _async =
LL| | async
LL| 0| {
@@ -78,11 +78,11 @@
LL| | ;
LL| |
LL| 1| black_box(());
- LL| 1|
- LL| 1| // This tests the edge case of a const block nested inside an "anon const",
- LL| 1| // such as the length of an array literal. Handling this case requires
- LL| 1| // `nested_filter::OnlyBodies` or equivalent.
- LL| 1| #[rustfmt::skip]
+ LL| |
+ LL| | // This tests the edge case of a const block nested inside an "anon const",
+ LL| | // such as the length of an array literal. Handling this case requires
+ LL| | // `nested_filter::OnlyBodies` or equivalent.
+ LL| | #[rustfmt::skip]
LL| 1| let _const_block_inside_anon_const =
LL| | [
LL| | 0
diff --git a/tests/coverage/if.cov-map b/tests/coverage/if.cov-map
index 611dd2e..044c0f2 100644
--- a/tests/coverage/if.cov-map
+++ b/tests/coverage/if.cov-map
@@ -1,12 +1,17 @@
Function name: if::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 04, 01, 12, 10, 05, 13, 05, 05, 06, 02, 05, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 04, 01, 00, 0a, 01, 05, 05, 00, 0c, 01, 02, 09, 02, 0a, 01, 05, 09, 01, 0e, 01, 03, 09, 00, 0a, 01, 03, 09, 00, 10, 05, 01, 05, 05, 06, 02, 05, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 4, 1) to (start + 18, 16)
-- Code(Counter(1)) at (prev + 19, 5) to (start + 5, 6)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 2, 10)
+- Code(Counter(0)) at (prev + 5, 9) to (start + 1, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6)
- Code(Expression(0, Sub)) at (prev + 5, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
diff --git a/tests/coverage/if.coverage b/tests/coverage/if.coverage
index 0762418..c3c8a1b 100644
--- a/tests/coverage/if.coverage
+++ b/tests/coverage/if.coverage
@@ -2,23 +2,23 @@
LL| |
LL| |#[rustfmt::skip]
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
- LL| 1| let
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
+ LL| | let
LL| 1| is_true
- LL| 1| =
+ LL| | =
LL| 1| std::env::args().len()
LL| 1| ==
LL| 1| 1
- LL| 1| ;
- LL| 1| let
+ LL| | ;
+ LL| | let
LL| 1| mut
LL| 1| countdown
- LL| 1| =
+ LL| | =
LL| 1| 0
- LL| 1| ;
- LL| 1| if
+ LL| | ;
+ LL| | if
LL| 1| is_true
LL| 1| {
LL| 1| countdown
diff --git a/tests/coverage/if_else.cov-map b/tests/coverage/if_else.cov-map
index 35096d8..1d8ca18 100644
--- a/tests/coverage/if_else.cov-map
+++ b/tests/coverage/if_else.cov-map
@@ -1,13 +1,18 @@
Function name: if_else::main
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 04, 01, 08, 10, 05, 09, 05, 05, 06, 02, 08, 09, 02, 10, 01, 06, 09, 00, 10, 09, 01, 05, 05, 06, 06, 07, 05, 05, 06, 01, 06, 01, 00, 02]
+Raw bytes (68): 0x[01, 01, 02, 01, 05, 01, 09, 0c, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 02, 09, 00, 10, 05, 01, 05, 05, 06, 02, 08, 09, 02, 10, 01, 06, 09, 00, 10, 09, 01, 05, 05, 06, 06, 07, 05, 05, 06, 01, 06, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if_else.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 4, 1) to (start + 8, 16)
-- Code(Counter(1)) at (prev + 9, 5) to (start + 5, 6)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6)
- Code(Expression(0, Sub)) at (prev + 8, 9) to (start + 2, 16)
= (c0 - c1)
- Code(Counter(0)) at (prev + 6, 9) to (start + 0, 16)
diff --git a/tests/coverage/if_else.coverage b/tests/coverage/if_else.coverage
index 2bf9348..148e2b1 100644
--- a/tests/coverage/if_else.coverage
+++ b/tests/coverage/if_else.coverage
@@ -2,13 +2,13 @@
LL| |
LL| |#[rustfmt::skip]
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let mut countdown = 0;
- LL| 1| if
+ LL| | if
LL| 1| is_true
LL| 1| {
LL| 1| countdown
diff --git a/tests/coverage/if_not.cov-map b/tests/coverage/if_not.cov-map
index 0fd35c5..1b1a1b3 100644
--- a/tests/coverage/if_not.cov-map
+++ b/tests/coverage/if_not.cov-map
@@ -1,14 +1,15 @@
Function name: if_not::if_not
-Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0a, 01, 05, 01, 03, 0d, 02, 04, 05, 02, 06, 05, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0b, 01, 05, 01, 00, 16, 01, 02, 09, 01, 0d, 02, 02, 05, 02, 06, 05, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if_not.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
- expression 2 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 5, 1) to (start + 3, 13)
-- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 2, 6)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 1, 13)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 2, 6)
= (c0 - c1)
- Code(Counter(1)) at (prev + 2, 5) to (start + 0, 6)
- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 13)
diff --git a/tests/coverage/if_not.coverage b/tests/coverage/if_not.coverage
index 678ccf9..8478e86 100644
--- a/tests/coverage/if_not.coverage
+++ b/tests/coverage/if_not.coverage
@@ -3,7 +3,7 @@
LL| |
LL| |#[rustfmt::skip]
LL| 12|fn if_not(cond: bool) {
- LL| 12| if
+ LL| | if
LL| 12| !
LL| 12| cond
LL| 4| {
diff --git a/tests/coverage/ignore_run.cov-map b/tests/coverage/ignore_run.cov-map
index a93fff7..0d8245c 100644
--- a/tests/coverage/ignore_run.cov-map
+++ b/tests/coverage/ignore_run.cov-map
@@ -1,9 +1,10 @@
Function name: ignore_run::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 03, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => $DIR/ignore_run.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0
diff --git a/tests/coverage/inline-dead.cov-map b/tests/coverage/inline-dead.cov-map
index 450fb75b..95a5f6b 100644
--- a/tests/coverage/inline-dead.cov-map
+++ b/tests/coverage/inline-dead.cov-map
@@ -1,44 +1,53 @@
Function name: inline_dead::dead (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 17, 01, 00, 11, 00, 01, 05, 00, 07, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline-dead.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 23, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 23, 1) to (start + 0, 17)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 7)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
Function name: inline_dead::live::<false>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 01, 01, 09, 05, 02, 09, 00, 0d, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0e, 01, 00, 20, 01, 01, 08, 00, 09, 05, 01, 09, 00, 0d, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline-dead.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 13)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 13)
- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: inline_dead::main
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0a, 01, 06, 05, 01, 02]
+Raw bytes (39): 0x[01, 01, 00, 07, 01, 04, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 12, 01, 00, 14, 00, 21, 01, 02, 09, 00, 0a, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline-dead.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 4, 1) to (start + 3, 10)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 2)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: inline_dead::main::{closure#0}
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 01, 01, 05, 00, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 17, 00, 18, 01, 01, 09, 00, 16, 00, 00, 17, 00, 18, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/inline-dead.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 7, 23) to (start + 1, 22)
-- Code(Zero) at (prev + 1, 23) to (start + 0, 24)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 7, 23) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Zero) at (prev + 0, 23) to (start + 0, 24)
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c0
diff --git a/tests/coverage/inline-dead.coverage b/tests/coverage/inline-dead.coverage
index c12668c..d75aaf3 100644
--- a/tests/coverage/inline-dead.coverage
+++ b/tests/coverage/inline-dead.coverage
@@ -3,7 +3,7 @@
LL| |
LL| 1|fn main() {
LL| 1| println!("{}", live::<false>());
- LL| 1|
+ LL| |
LL| 1| let f = |x: bool| {
LL| 1| debug_assert!(x);
^0
diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map
index 5aa57e1..4c67dd9 100644
--- a/tests/coverage/inline.cov-map
+++ b/tests/coverage/inline.cov-map
@@ -1,86 +1,137 @@
Function name: inline::display::<char>
-Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 29, 01, 00, 22, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 01, 02]
+Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 29, 01, 00, 21, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 34)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 33)
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
= (c1 - c0)
- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 16)
- Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 2, 6)
= (c1 - c0)
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: inline::error
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 01, 0b]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 31, 01, 00, 0b, 01, 01, 05, 00, 0b]
Number of files: 1
- file 0 => $DIR/inline.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 11)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
Highest counter ID seen: c0
Function name: inline::length::<char>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1e, 01, 00, 20, 01, 01, 05, 00, 07, 01, 00, 08, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 30, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 7)
+- Code(Counter(0)) at (prev + 0, 8) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: inline::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 05, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 05, 01, 00, 0a, 01, 01, 05, 00, 11, 01, 00, 12, 00, 22, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 5, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: inline::permutate::<char>
-Raw bytes (54): 0x[01, 01, 05, 01, 05, 0d, 09, 0d, 09, 01, 13, 05, 09, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 0a, 01, 0d, 00, 0e, 09, 00, 12, 00, 16, 0a, 00, 17, 04, 0a, 0e, 05, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (142): 0x[01, 01, 0e, 01, 05, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 01, 37, 05, 09, 16, 01, 0f, 01, 00, 38, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 13, 01, 00, 14, 00, 16, 01, 01, 08, 00, 0e, 05, 00, 0f, 02, 06, 02, 02, 0f, 00, 14, 2e, 01, 0d, 00, 0e, 09, 00, 12, 00, 13, 09, 00, 15, 00, 16, 2e, 00, 17, 04, 0a, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 2e, 00, 16, 00, 17, 2e, 00, 19, 00, 1a, 2e, 01, 0d, 00, 16, 2e, 00, 17, 00, 19, 2e, 00, 1b, 00, 20, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 32, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline.rs
-Number of expressions: 5
+Number of expressions: 14
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(3), rhs = Counter(2)
- expression 2 operands: lhs = Counter(3), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 15, 1) to (start + 2, 14)
-- Code(Counter(1)) at (prev + 2, 15) to (start + 2, 6)
+- expression 3 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 5 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 6 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 7 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 8 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 9 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 10 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 11 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add)
+- expression 13 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 22
+- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 56)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(1)) at (prev + 0, 15) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 15) to (start + 0, 20)
= (c0 - c1)
-- Code(Expression(2, Sub)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 14)
= (c3 - c2)
-- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 22)
-- Code(Expression(2, Sub)) at (prev + 0, 23) to (start + 4, 10)
+- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 19)
+- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Expression(11, Sub)) at (prev + 0, 23) to (start + 4, 10)
= (c3 - c2)
-- Code(Expression(3, Sub)) at (prev + 5, 12) to (start + 2, 6)
+- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 17)
+ = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 18) to (start + 0, 20)
+ = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 22) to (start + 0, 23)
+ = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 25) to (start + 0, 26)
+ = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 22)
+ = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 23) to (start + 0, 25)
+ = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 27) to (start + 0, 32)
+ = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 17)
+ = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 18) to (start + 0, 20)
+ = (c3 - c2)
+- Code(Expression(12, Sub)) at (prev + 2, 12) to (start + 2, 6)
= (c0 - (c1 + c2))
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c2
Function name: inline::permutations::<char>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 03, 02]
+Raw bytes (39): 0x[01, 01, 00, 07, 01, 0a, 01, 00, 2d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 14, 01, 00, 15, 00, 1d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 16, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 1) to (start + 3, 2)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: inline::swap::<char>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 04, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 23, 01, 00, 33, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 12, 01, 01, 05, 00, 12, 01, 01, 05, 00, 0e, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inline.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 35, 1) to (start + 4, 2)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 51)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/inline.coverage b/tests/coverage/inline.coverage
index 3d32212..5fe069d 100644
--- a/tests/coverage/inline.coverage
+++ b/tests/coverage/inline.coverage
@@ -18,7 +18,7 @@
LL| 6| display(xs);
LL| 10| } else if k < n {
LL| 15| for i in k..n {
- ^10
+ ^10^10
LL| 15| swap(xs, i, k);
LL| 15| permutate(xs, k + 1);
LL| 15| swap(xs, i, k);
diff --git a/tests/coverage/inner_items.cov-map b/tests/coverage/inner_items.cov-map
index a9e19fe..ca6ddfd 100644
--- a/tests/coverage/inner_items.cov-map
+++ b/tests/coverage/inner_items.cov-map
@@ -1,46 +1,70 @@
Function name: <inner_items::main::InStruct as inner_items::main::InTrait>::default_trait_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 09, 03, 0a]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 21, 09, 00, 29, 01, 01, 0d, 00, 14, 01, 01, 0d, 00, 11, 01, 00, 12, 00, 1c, 01, 01, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/inner_items.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 9) to (start + 3, 10)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 33, 9) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
Highest counter ID seen: c0
Function name: <inner_items::main::InStruct as inner_items::main::InTrait>::trait_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 28, 09, 03, 0a]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 28, 09, 00, 2c, 01, 01, 0d, 00, 29, 01, 01, 0d, 00, 14, 01, 00, 15, 00, 29, 01, 01, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/inner_items.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 40, 9) to (start + 3, 10)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 40, 9) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
Highest counter ID seen: c0
Function name: inner_items::main
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 01, 24, 08, 00, 0f, 09, 00, 10, 02, 06, 06, 02, 05, 00, 06, 01, 02, 09, 05, 02]
+Raw bytes (88): 0x[01, 01, 02, 01, 05, 01, 09, 10, 01, 03, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 24, 08, 00, 0f, 09, 00, 10, 02, 06, 06, 02, 05, 00, 06, 01, 02, 09, 00, 10, 01, 00, 13, 02, 06, 01, 04, 05, 00, 08, 01, 00, 09, 00, 1b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inner_items.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15)
-- Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 36, 8) to (start + 0, 15)
- Code(Counter(2)) at (prev + 0, 16) to (start + 2, 6)
- Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 0, 6)
= (c0 - c2)
-- Code(Counter(0)) at (prev + 2, 9) to (start + 5, 2)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 2, 6)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c2
Function name: inner_items::main::in_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 12, 05, 04, 06]
+Raw bytes (44): 0x[01, 01, 00, 08, 01, 12, 05, 00, 17, 01, 01, 0d, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 0d, 00, 0e, 01, 00, 11, 00, 16, 01, 01, 09, 00, 11, 01, 00, 12, 00, 1a, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/inner_items.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 18, 5) to (start + 4, 6)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 18, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c0
diff --git a/tests/coverage/inner_items.coverage b/tests/coverage/inner_items.coverage
index 8244d34..8503cc1 100644
--- a/tests/coverage/inner_items.coverage
+++ b/tests/coverage/inner_items.coverage
@@ -1,11 +1,11 @@
LL| |#![allow(unused_assignments, unused_variables, dead_code)]
LL| |
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let mut countdown = 0;
LL| 1| if is_true {
LL| 1| countdown = 10;
@@ -54,7 +54,7 @@
LL| 1| let mut val = InStruct {
LL| 1| in_struct_field: 101, //
LL| 1| };
- LL| 1|
+ LL| |
LL| 1| val.default_trait_func();
LL| 1|}
diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map
index 4e45db8..d1d751f 100644
--- a/tests/coverage/issue-83601.cov-map
+++ b/tests/coverage/issue-83601.cov-map
@@ -1,13 +1,30 @@
Function name: issue_83601::main
-Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 0f, 05, 03, 09, 01, 0f, 02, 02, 05, 03, 02]
+Raw bytes (76): 0x[01, 01, 01, 05, 09, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/issue-83601.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 15)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 3, 2)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13)
+ = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20)
+ = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13)
+ = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20)
+ = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13)
+ = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20)
+ = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
= (c1 - c2)
Highest counter ID seen: c1
diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map
index 1ed5edb..2b643ea 100644
--- a/tests/coverage/issue-84561.cov-map
+++ b/tests/coverage/issue-84561.cov-map
@@ -1,65 +1,79 @@
Function name: <issue_84561::Foo as core::fmt::Debug>::fmt
-Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, 8a, 01, 05, 01, 24, 05, 01, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, 8a, 01, 05, 00, 43, 01, 01, 09, 00, 0f, 01, 00, 10, 00, 11, 01, 00, 13, 00, 24, 05, 00, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/issue-84561.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 138, 5) to (start + 1, 36)
-- Code(Counter(1)) at (prev + 1, 37) to (start + 0, 38)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 138, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 36)
+- Code(Counter(1)) at (prev + 0, 37) to (start + 0, 38)
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c1
Function name: issue_84561::main
-Raw bytes (10): 0x[01, 01, 00, 01, 01, b4, 01, 01, 04, 02]
+Raw bytes (30): 0x[01, 01, 00, 05, 01, b4, 01, 01, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/issue-84561.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 180, 1) to (start + 4, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 180, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: issue_84561::test1
-Raw bytes (50): 0x[01, 01, 00, 09, 01, 9a, 01, 01, 01, 0b, 05, 01, 0c, 00, 1e, 01, 01, 05, 00, 0b, 09, 00, 0c, 00, 1e, 01, 01, 0d, 01, 0b, 0d, 01, 0c, 00, 1e, 01, 01, 05, 03, 0b, 11, 03, 0c, 00, 1e, 01, 01, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 00, 0c, 01, 9a, 01, 01, 00, 0b, 01, 01, 05, 00, 0b, 05, 00, 0c, 00, 1e, 01, 01, 05, 00, 0b, 09, 00, 0c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 05, 00, 0b, 0d, 00, 0c, 00, 1e, 01, 01, 05, 02, 06, 01, 03, 05, 00, 0b, 11, 00, 0c, 00, 1e, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/issue-84561.rs
Number of expressions: 0
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 154, 1) to (start + 1, 11)
-- Code(Counter(1)) at (prev + 1, 12) to (start + 0, 30)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 154, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
+- Code(Counter(1)) at (prev + 0, 12) to (start + 0, 30)
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
- Code(Counter(2)) at (prev + 0, 12) to (start + 0, 30)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 1, 11)
-- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 30)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 3, 11)
-- Code(Counter(4)) at (prev + 3, 12) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
+- Code(Counter(3)) at (prev + 0, 12) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 2, 6)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 11)
+- Code(Counter(4)) at (prev + 0, 12) to (start + 0, 30)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c4
Function name: issue_84561::test2
-Raw bytes (20): 0x[01, 01, 00, 03, 01, b0, 01, 01, 01, 10, 05, 01, 11, 00, 23, 01, 01, 01, 00, 02]
+Raw bytes (25): 0x[01, 01, 00, 04, 01, b0, 01, 01, 00, 0b, 01, 01, 05, 00, 10, 05, 00, 11, 00, 23, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/issue-84561.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 176, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 35)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 176, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 0, 17) to (start + 0, 35)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: issue_84561::test2::call_print
-Raw bytes (10): 0x[01, 01, 00, 01, 01, a7, 01, 09, 02, 0a]
+Raw bytes (25): 0x[01, 01, 00, 04, 01, a7, 01, 09, 00, 1f, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 18, 01, 01, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/issue-84561.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 167, 9) to (start + 2, 10)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 167, 9) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
Highest counter ID seen: c0
Function name: issue_84561::test3
-Raw bytes (279): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 33, 01, 08, 01, 03, 0f, 05, 04, 09, 01, 0f, 09, 02, 05, 04, 0f, 09, 05, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 01, 0f, 0d, 02, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 02, 0f, 0d, 06, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 01, 0f, 0d, 05, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 02, 13, 21, 03, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02]
+Raw bytes (409): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 4d, 01, 08, 01, 00, 0b, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 02, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 00, 0c, 09, 00, 0f, 00, 15, 09, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 02, 05, 00, 0f, 00, 00, 20, 00, 24, 00, 00, 29, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 00, 0d, 00, 03, 09, 00, 10, 00, 02, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 00, 10, 0d, 00, 13, 00, 2e, 0d, 02, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 00, 0c, 0d, 00, 0f, 00, 15, 0d, 01, 05, 00, 0f, 0d, 04, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 00, 0f, 1d, 02, 0c, 00, 13, 21, 01, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/issue-84561.rs
Number of expressions: 10
@@ -73,29 +87,54 @@
- expression 7 operands: lhs = Counter(9), rhs = Counter(10)
- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(12)
- expression 9 operands: lhs = Counter(10), rhs = Counter(11)
-Number of file 0 mappings: 51
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 15)
-- Code(Counter(1)) at (prev + 4, 9) to (start + 1, 15)
-- Code(Counter(2)) at (prev + 2, 5) to (start + 4, 15)
-- Code(Counter(2)) at (prev + 5, 5) to (start + 0, 15)
+Number of file 0 mappings: 77
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 15)
- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15)
-- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 15)
-- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(2)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
- Code(Zero) at (prev + 0, 32) to (start + 0, 48)
-- Code(Counter(3)) at (prev + 1, 5) to (start + 3, 15)
-- Code(Zero) at (prev + 3, 32) to (start + 0, 48)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 36)
+- Code(Zero) at (prev + 0, 41) to (start + 0, 48)
- Code(Zero) at (prev + 0, 51) to (start + 0, 65)
- Code(Zero) at (prev + 0, 75) to (start + 0, 90)
- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
-- Code(Zero) at (prev + 5, 9) to (start + 3, 16)
-- Code(Zero) at (prev + 5, 13) to (start + 0, 27)
+- Code(Zero) at (prev + 5, 9) to (start + 0, 13)
+- Code(Zero) at (prev + 3, 9) to (start + 0, 16)
+- Code(Zero) at (prev + 2, 13) to (start + 0, 27)
- Code(Zero) at (prev + 2, 13) to (start + 0, 28)
-- Code(Counter(3)) at (prev + 4, 9) to (start + 2, 15)
-- Code(Counter(3)) at (prev + 6, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(3)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15)
- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15)
-- Code(Counter(3)) at (prev + 4, 9) to (start + 1, 15)
-- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 12)
+- Code(Counter(3)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 8) to (start + 0, 15)
- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 19)
- Code(Expression(0, Sub)) at (prev + 5, 9) to (start + 0, 19)
= (c3 - c4)
@@ -110,8 +149,9 @@
- Code(Counter(6)) at (prev + 1, 13) to (start + 0, 19)
- Code(Expression(2, Sub)) at (prev + 2, 13) to (start + 0, 19)
= (c3 - c6)
-- Code(Counter(7)) at (prev + 4, 5) to (start + 2, 19)
-- Code(Counter(8)) at (prev + 3, 13) to (start + 0, 19)
+- Code(Counter(7)) at (prev + 4, 5) to (start + 0, 15)
+- Code(Counter(7)) at (prev + 2, 12) to (start + 0, 19)
+- Code(Counter(8)) at (prev + 1, 13) to (start + 0, 19)
- Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 19)
= (c7 - c8)
- Code(Expression(9, Add)) at (prev + 3, 5) to (start + 0, 15)
diff --git a/tests/coverage/issue-84561.coverage b/tests/coverage/issue-84561.coverage
index a55f42a..781f1e9 100644
--- a/tests/coverage/issue-84561.coverage
+++ b/tests/coverage/issue-84561.coverage
@@ -14,7 +14,7 @@
LL| 1| println!("{:?}", Foo(1));
LL| 1| println!("{:?}", bar);
LL| 1| println!("{:?}", baz);
- LL| 1|
+ LL| |
LL| 1| assert_eq!(Foo(1), Foo(1));
LL| 1| assert_ne!(Foo(0), Foo(1));
LL| 1| assert_eq!(Foo(2), Foo(2));
@@ -25,17 +25,17 @@
^0
LL| 1| println!("{:?}", bar);
LL| 1| println!("{:?}", Foo(1));
- LL| 1|
+ LL| |
LL| 1| assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
- ^0 ^0 ^0
+ ^0 ^0 ^0 ^0
LL| 1| assert_ne!(
LL| | Foo(0)
LL| | ,
LL| | Foo(5)
LL| | ,
LL| 0| "{}"
- LL| 0| ,
- LL| 0| if
+ LL| | ,
+ LL| | if
LL| 0| is_true
LL| | {
LL| 0| "true message"
@@ -45,7 +45,7 @@
LL| | );
LL| |
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| assert_eq!(
LL| | Foo(1),
LL| | Foo(1)
@@ -96,7 +96,7 @@
LL| | Foo(5)
LL| | );
LL| 1| assert_ne!(
- LL| 1| Foo(5),
+ LL| | Foo(5),
LL| 1| if is_true {
LL| 1| Foo(0)
LL| | } else {
diff --git a/tests/coverage/issue-85461.cov-map b/tests/coverage/issue-85461.cov-map
index 566206a..b08d703 100644
--- a/tests/coverage/issue-85461.cov-map
+++ b/tests/coverage/issue-85461.cov-map
@@ -1,9 +1,12 @@
Function name: issue_85461::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 11, 01, 01, 05, 00, 11, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/issue-85461.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/issue-93054.cov-map b/tests/coverage/issue-93054.cov-map
index 3cb54d8..17f3daf 100644
--- a/tests/coverage/issue-93054.cov-map
+++ b/tests/coverage/issue-93054.cov-map
@@ -1,27 +1,30 @@
Function name: issue_93054::foo2 (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1d]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1c]
Number of files: 1
- file 0 => $DIR/issue-93054.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 1) to (start + 0, 29)
+- Code(Zero) at (prev + 21, 1) to (start + 0, 28)
Highest counter ID seen: (none)
Function name: issue_93054::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 1d, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => $DIR/issue-93054.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0
Function name: issue_93054::make (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 19, 01, 00, 1b, 00, 01, 05, 00, 09, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/issue-93054.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 25, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 25, 1) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 9)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
diff --git a/tests/coverage/lazy_boolean.cov-map b/tests/coverage/lazy_boolean.cov-map
index 9722b4c..cbbe6a8 100644
--- a/tests/coverage/lazy_boolean.cov-map
+++ b/tests/coverage/lazy_boolean.cov-map
@@ -1,5 +1,5 @@
Function name: lazy_boolean::main
-Raw bytes (158): 0x[01, 01, 07, 01, 05, 01, 25, 01, 21, 01, 11, 01, 15, 01, 19, 01, 1d, 1c, 01, 04, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 05, 00, 06, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 09, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 0d, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 11, 03, 05, 00, 06, 01, 03, 09, 00, 10, 15, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 19, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 1d, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (198): 0x[01, 01, 07, 01, 05, 01, 25, 01, 21, 01, 11, 01, 15, 01, 19, 01, 1d, 24, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 0a, 00, 0f, 01, 00, 11, 00, 16, 01, 00, 18, 00, 1d, 01, 00, 21, 00, 2a, 01, 01, 08, 00, 0f, 05, 00, 10, 04, 06, 05, 01, 09, 00, 0e, 02, 03, 05, 00, 06, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 09, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 0d, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 11, 03, 05, 00, 06, 01, 03, 09, 00, 10, 15, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 19, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 1d, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/lazy_boolean.rs
Number of expressions: 7
@@ -10,10 +10,18 @@
- expression 4 operands: lhs = Counter(0), rhs = Counter(5)
- expression 5 operands: lhs = Counter(0), rhs = Counter(6)
- expression 6 operands: lhs = Counter(0), rhs = Counter(7)
-Number of file 0 mappings: 28
-- Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15)
-- Code(Counter(1)) at (prev + 7, 16) to (start + 4, 6)
-- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 6)
+Number of file 0 mappings: 36
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 10) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 0, 33) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 4, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 17)
- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 18)
diff --git a/tests/coverage/lazy_boolean.coverage b/tests/coverage/lazy_boolean.coverage
index 828ba2a..0a30038 100644
--- a/tests/coverage/lazy_boolean.coverage
+++ b/tests/coverage/lazy_boolean.coverage
@@ -2,11 +2,11 @@
LL| |
LL| |#[rustfmt::skip]
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let (mut a, mut b, mut c) = (0, 0, 0);
LL| 1| if is_true {
LL| 1| a = 1;
diff --git a/tests/coverage/let_else_loop.cov-map b/tests/coverage/let_else_loop.cov-map
index f55e5a9..169d4a5 100644
--- a/tests/coverage/let_else_loop.cov-map
+++ b/tests/coverage/let_else_loop.cov-map
@@ -1,33 +1,36 @@
Function name: let_else_loop::_if (unused)
-Raw bytes (19): 0x[01, 01, 00, 03, 00, 16, 01, 01, 0c, 00, 01, 0f, 00, 16, 00, 00, 20, 00, 27]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 16, 01, 00, 13, 00, 01, 08, 00, 0c, 00, 00, 0f, 00, 16, 00, 00, 20, 00, 27]
Number of files: 1
- file 0 => $DIR/let_else_loop.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Zero) at (prev + 22, 1) to (start + 1, 12)
-- Code(Zero) at (prev + 1, 15) to (start + 0, 22)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 22, 1) to (start + 0, 19)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 12)
+- Code(Zero) at (prev + 0, 15) to (start + 0, 22)
- Code(Zero) at (prev + 0, 32) to (start + 0, 39)
Highest counter ID seen: (none)
Function name: let_else_loop::_loop_either_way (unused)
-Raw bytes (19): 0x[01, 01, 00, 03, 00, 0f, 01, 01, 14, 00, 01, 1c, 00, 23, 00, 01, 05, 00, 0c]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 00, 20, 00, 01, 10, 00, 14, 00, 00, 1c, 00, 23, 00, 01, 05, 00, 0c]
Number of files: 1
- file 0 => $DIR/let_else_loop.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Zero) at (prev + 15, 1) to (start + 1, 20)
-- Code(Zero) at (prev + 1, 28) to (start + 0, 35)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 15, 1) to (start + 0, 32)
+- Code(Zero) at (prev + 1, 16) to (start + 0, 20)
+- Code(Zero) at (prev + 0, 28) to (start + 0, 35)
- Code(Zero) at (prev + 1, 5) to (start + 0, 12)
Highest counter ID seen: (none)
Function name: let_else_loop::loopy
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 09, 01, 01, 14, 09, 01, 1c, 00, 23, 05, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 01, 00, 15, 01, 01, 10, 00, 14, 09, 00, 1c, 00, 23, 05, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/let_else_loop.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 20)
-- Code(Counter(2)) at (prev + 1, 28) to (start + 0, 35)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 20)
+- Code(Counter(2)) at (prev + 0, 28) to (start + 0, 35)
- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c2
diff --git a/tests/coverage/long_and_wide.cov-map b/tests/coverage/long_and_wide.cov-map
index c8194cc..93466a9 100644
--- a/tests/coverage/long_and_wide.cov-map
+++ b/tests/coverage/long_and_wide.cov-map
@@ -1,36 +1,44 @@
Function name: long_and_wide::far_function
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 96, 01, 01, 00, 15]
+Raw bytes (15): 0x[01, 01, 00, 02, 01, 96, 01, 01, 00, 12, 01, 00, 14, 00, 15]
Number of files: 1
- file 0 => $DIR/long_and_wide.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 150, 1) to (start + 0, 21)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 150, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
Highest counter ID seen: c0
Function name: long_and_wide::long_function
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 10, 01, 84, 01, 02]
+Raw bytes (15): 0x[01, 01, 00, 02, 01, 10, 01, 00, 13, 01, 84, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/long_and_wide.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 16, 1) to (start + 132, 2)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 132, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: long_and_wide::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 04, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 07, 01, 00, 0a, 01, 01, 05, 00, 12, 01, 01, 05, 00, 12, 01, 01, 05, 00, 11, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/long_and_wide.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 7, 1) to (start + 4, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: long_and_wide::wide_function
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 8b, 01]
+Raw bytes (23): 0x[01, 01, 00, 03, 01, 0e, 01, 00, 13, 01, 00, 86, 01, 00, 88, 01, 01, 00, 8a, 01, 00, 8b, 01]
Number of files: 1
- file 0 => $DIR/long_and_wide.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 139)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 134) to (start + 0, 136)
+- Code(Counter(0)) at (prev + 0, 138) to (start + 0, 139)
Highest counter ID seen: c0
diff --git a/tests/coverage/long_and_wide.coverage b/tests/coverage/long_and_wide.coverage
index f0898d9..d9bacdf 100644
--- a/tests/coverage/long_and_wide.coverage
+++ b/tests/coverage/long_and_wide.coverage
@@ -14,137 +14,137 @@
LL| 1|fn wide_function() { /* */ (); }
LL| |
LL| 1|fn long_function() {
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
- LL| 1| //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
+ LL| | //
LL| 1|}
LL| |
LL| 1|fn far_function() {}
diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map
index 8edb6d0..3981623 100644
--- a/tests/coverage/loop-break.cov-map
+++ b/tests/coverage/loop-break.cov-map
@@ -1,11 +1,11 @@
Function name: loop_break::main
-Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0b, 05, 02, 0c, 00, 21, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0a, 05, 02, 0c, 00, 21, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/loop-break.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
- Code(Counter(1)) at (prev + 2, 12) to (start + 0, 33)
- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18)
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
diff --git a/tests/coverage/loop_break_value.cov-map b/tests/coverage/loop_break_value.cov-map
index d16335a..cf355ec 100644
--- a/tests/coverage/loop_break_value.cov-map
+++ b/tests/coverage/loop_break_value.cov-map
@@ -1,9 +1,12 @@
Function name: loop_break_value::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 01, 0a, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 04, 01, 00, 0a, 01, 01, 09, 00, 0f, 01, 02, 0d, 05, 0a, 01, 07, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/loop_break_value.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 4, 1) to (start + 10, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 5, 10)
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/loop_break_value.coverage b/tests/coverage/loop_break_value.coverage
index 7d45339..5e80168 100644
--- a/tests/coverage/loop_break_value.coverage
+++ b/tests/coverage/loop_break_value.coverage
@@ -3,13 +3,13 @@
LL| |#[rustfmt::skip]
LL| 1|fn main() {
LL| 1| let result
- LL| 1| =
+ LL| | =
LL| 1| loop
LL| 1| {
LL| 1| break
LL| 1| 10
LL| 1| ;
LL| 1| }
- LL| 1| ;
+ LL| | ;
LL| 1|}
diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map
index d414710..78fdaa5 100644
--- a/tests/coverage/loops_branches.cov-map
+++ b/tests/coverage/loops_branches.cov-map
@@ -1,5 +1,5 @@
Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
-Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 14, 01, 09, 05, 01, 10, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 19, 01, 09, 05, 00, 43, 01, 01, 0c, 00, 10, 01, 01, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 17, 0d, 00, 18, 00, 19, 0d, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/loops_branches.rs
Number of expressions: 4
@@ -7,13 +7,16 @@
- expression 1 operands: lhs = Counter(0), rhs = Counter(3)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 9, 5) to (start + 1, 16)
-- Code(Counter(0)) at (prev + 2, 16) to (start + 0, 21)
+Number of file 0 mappings: 25
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 21)
- Code(Zero) at (prev + 1, 23) to (start + 0, 27)
- Code(Zero) at (prev + 0, 28) to (start + 0, 30)
- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29)
- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31)
- Code(Zero) at (prev + 1, 16) to (start + 1, 10)
- Code(Counter(3)) at (prev + 3, 13) to (start + 0, 14)
@@ -23,7 +26,9 @@
- Code(Zero) at (prev + 1, 27) to (start + 0, 31)
- Code(Zero) at (prev + 0, 32) to (start + 0, 34)
- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 23)
+- Code(Counter(3)) at (prev + 0, 24) to (start + 0, 25)
+- Code(Counter(3)) at (prev + 0, 27) to (start + 0, 33)
- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35)
= ((c0 + c3) - (c1 + c2))
- Code(Zero) at (prev + 1, 20) to (start + 1, 14)
@@ -33,7 +38,7 @@
Highest counter ID seen: c3
Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
-Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 19, 01, 22, 05, 00, 43, 01, 01, 0c, 00, 11, 00, 00, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/loops_branches.rs
Number of expressions: 4
@@ -41,14 +46,17 @@
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
- expression 2 operands: lhs = Counter(1), rhs = Counter(3)
- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17)
-- Code(Zero) at (prev + 1, 18) to (start + 1, 10)
+Number of file 0 mappings: 25
+- Code(Counter(0)) at (prev + 34, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 1, 10)
- Code(Counter(0)) at (prev + 2, 16) to (start + 0, 21)
- Code(Zero) at (prev + 1, 23) to (start + 0, 27)
- Code(Zero) at (prev + 0, 28) to (start + 0, 30)
- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29)
- Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31)
- Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14)
- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 23)
@@ -58,7 +66,9 @@
- Code(Zero) at (prev + 1, 27) to (start + 0, 31)
- Code(Zero) at (prev + 0, 32) to (start + 0, 34)
- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23)
+- Code(Counter(2)) at (prev + 0, 24) to (start + 0, 25)
+- Code(Counter(2)) at (prev + 0, 27) to (start + 0, 33)
- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35)
= ((c0 + c2) - (c1 + c3))
- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15)
@@ -67,11 +77,20 @@
Highest counter ID seen: c3
Function name: loops_branches::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02]
+Raw bytes (54): 0x[01, 01, 00, 0a, 01, 37, 01, 00, 0a, 01, 01, 09, 00, 13, 01, 00, 16, 00, 1f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 09, 00, 15, 01, 00, 18, 00, 23, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 12, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/loops_branches.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 55, 1) to (start + 5, 2)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/macro_in_closure.cov-map b/tests/coverage/macro_in_closure.cov-map
index 3e71ed8..4544aa5 100644
--- a/tests/coverage/macro_in_closure.cov-map
+++ b/tests/coverage/macro_in_closure.cov-map
@@ -1,18 +1,21 @@
Function name: macro_in_closure::NO_BLOCK::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 1c, 00, 2d]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 25, 00, 2c]
Number of files: 1
- file 0 => $DIR/macro_in_closure.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 7, 28) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 7, 37) to (start + 0, 44)
Highest counter ID seen: c0
Function name: macro_in_closure::WITH_BLOCK::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 1e, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 1e, 00, 1f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 15, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/macro_in_closure.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 9, 30) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 9, 30) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/macro_name_span.cov-map b/tests/coverage/macro_name_span.cov-map
index 18b4e28..c96cb75 100644
--- a/tests/coverage/macro_name_span.cov-map
+++ b/tests/coverage/macro_name_span.cov-map
@@ -1,18 +1,21 @@
Function name: macro_name_span::affected_function
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 01, 3e]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 16, 1c, 00, 1d, 01, 01, 09, 00, 3e]
Number of files: 1
- file 0 => $DIR/macro_name_span.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 62)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 22, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 62)
Highest counter ID seen: c0
Function name: macro_name_span::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0b, 01, 00, 0a, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/macro_name_span.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/match_or_pattern.cov-map b/tests/coverage/match_or_pattern.cov-map
index a29c712..0bb126b 100644
--- a/tests/coverage/match_or_pattern.cov-map
+++ b/tests/coverage/match_or_pattern.cov-map
@@ -1,5 +1,5 @@
Function name: match_or_pattern::main
-Raw bytes (145): 0x[01, 01, 08, 01, 05, 01, 09, 01, 0d, 01, 11, 01, 15, 01, 19, 01, 1d, 01, 21, 19, 01, 01, 01, 08, 0f, 05, 08, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 06, 03, 1b, 00, 1d, 09, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 0d, 00, 10, 03, 06, 0a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 0e, 01, 1b, 00, 1d, 11, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 16, 01, 1b, 00, 1d, 19, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 1d, 00, 10, 03, 06, 1a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 1e, 01, 1b, 00, 1d, 21, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
+Raw bytes (190): 0x[01, 01, 08, 01, 05, 01, 09, 01, 0d, 01, 11, 01, 15, 01, 19, 01, 1d, 01, 21, 22, 01, 01, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 10, 00, 12, 01, 00, 15, 00, 16, 01, 01, 09, 00, 0e, 01, 00, 10, 00, 12, 01, 00, 15, 00, 16, 01, 01, 08, 00, 0f, 05, 00, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 06, 03, 1b, 00, 1d, 09, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 0d, 00, 10, 03, 06, 0a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 0e, 01, 1b, 00, 1d, 11, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 16, 01, 1b, 00, 1d, 19, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 1d, 00, 10, 03, 06, 1a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 1e, 01, 1b, 00, 1d, 21, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/match_or_pattern.rs
Number of expressions: 8
@@ -11,9 +11,18 @@
- expression 5 operands: lhs = Counter(0), rhs = Counter(6)
- expression 6 operands: lhs = Counter(0), rhs = Counter(7)
- expression 7 operands: lhs = Counter(0), rhs = Counter(8)
-Number of file 0 mappings: 25
-- Code(Counter(0)) at (prev + 1, 1) to (start + 8, 15)
-- Code(Counter(1)) at (prev + 8, 16) to (start + 3, 6)
+Number of file 0 mappings: 34
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 3, 6)
- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 17)
diff --git a/tests/coverage/match_or_pattern.coverage b/tests/coverage/match_or_pattern.coverage
index a65c226..50540bc 100644
--- a/tests/coverage/match_or_pattern.coverage
+++ b/tests/coverage/match_or_pattern.coverage
@@ -1,9 +1,9 @@
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let mut a: u8 = 0;
LL| 1| let mut b: u8 = 0;
LL| 1| if is_true {
diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map
index f966d75..ffee97c 100644
--- a/tests/coverage/mcdc/condition-limit.cov-map
+++ b/tests/coverage/mcdc/condition-limit.cov-map
@@ -1,5 +1,5 @@
Function name: condition_limit::accept_7_conditions
-Raw bytes (147): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 12, 01, 06, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (192): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 1b, 01, 06, 01, 00, 2c, 01, 01, 0a, 00, 0b, 01, 00, 0d, 00, 0e, 01, 00, 10, 00, 11, 01, 00, 13, 00, 14, 01, 00, 16, 00, 17, 01, 00, 19, 00, 1a, 01, 00, 1c, 00, 1d, 01, 00, 21, 00, 29, 01, 01, 08, 00, 09, 28, 08, 07, 00, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/condition-limit.rs
Number of expressions: 8
@@ -11,9 +11,18 @@
- expression 5 operands: lhs = Counter(5), rhs = Counter(6)
- expression 6 operands: lhs = Counter(6), rhs = Counter(7)
- expression 7 operands: lhs = Counter(0), rhs = Counter(7)
-Number of file 0 mappings: 18
-- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 9)
-- MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 2, 8) to (start + 0, 39)
+Number of file 0 mappings: 27
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 10) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 0, 33) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 0, 8) to (start + 0, 39)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 7, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map
index de4ea77..dac1eb4 100644
--- a/tests/coverage/mcdc/if.cov-map
+++ b/tests/coverage/mcdc/if.cov-map
@@ -1,14 +1,15 @@
Function name: if::mcdc_check_a
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 0e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 0e, 01, 00, 22, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -23,16 +24,17 @@
Highest counter ID seen: c2
Function name: if::mcdc_check_b
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 16, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 16, 01, 00, 22, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 22, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -47,16 +49,17 @@
Highest counter ID seen: c2
Function name: if::mcdc_check_both
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 1e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 1e, 01, 00, 25, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -71,16 +74,17 @@
Highest counter ID seen: c2
Function name: if::mcdc_check_neither
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 06, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 06, 01, 00, 28, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -95,7 +99,7 @@
Highest counter ID seen: c2
Function name: if::mcdc_check_not_tree_decision
-Raw bytes (85): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0a, 01, 30, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (90): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0b, 01, 30, 01, 00, 3b, 28, 05, 03, 03, 08, 00, 15, 01, 00, 09, 00, 0a, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 7
@@ -106,9 +110,10 @@
- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
- expression 6 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 48, 1) to (start + 3, 10)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 48, 1) to (start + 0, 59)
- MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 3 } at (prev + 0, 9) to (start + 0, 10)
true = c1
false = (c0 - c1)
@@ -129,7 +134,7 @@
Highest counter ID seen: c3
Function name: if::mcdc_check_tree_decision
-Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0a, 01, 26, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (92): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0b, 01, 26, 01, 00, 37, 01, 03, 08, 00, 09, 28, 04, 03, 00, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
Number of expressions: 8
@@ -141,9 +146,10 @@
- expression 5 operands: lhs = Counter(2), rhs = Counter(3)
- expression 6 operands: lhs = Counter(0), rhs = Expression(7, Add)
- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 38, 1) to (start + 3, 9)
-- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 38, 1) to (start + 0, 55)
+- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 8) to (start + 0, 21)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -164,46 +170,53 @@
Highest counter ID seen: c3
Function name: if::mcdc_nested_if
-Raw bytes (120): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 2b, 0d, 05, 09, 0d, 11, 2b, 11, 05, 09, 01, 2b, 05, 09, 0e, 01, 3a, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 26, 02, 00, 00, 00, 0d, 00, 0e, 2b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 0d, 12, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 1a, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 1e, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (139): 0x[01, 01, 0d, 01, 05, 01, 33, 05, 09, 05, 09, 05, 09, 05, 09, 33, 0d, 05, 09, 0d, 11, 33, 11, 05, 09, 01, 33, 05, 09, 11, 01, 3a, 01, 00, 2d, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 2e, 02, 00, 00, 00, 0d, 00, 0e, 33, 01, 09, 00, 0c, 33, 00, 0d, 00, 15, 33, 01, 0c, 00, 0d, 28, 06, 02, 00, 0c, 00, 12, 30, 0d, 1a, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 22, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 26, 02, 09, 00, 0a, 2e, 01, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/if.rs
-Number of expressions: 11
+Number of expressions: 13
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Expression(10, Add)
+- expression 1 operands: lhs = Counter(0), rhs = Expression(12, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 4 operands: lhs = Expression(10, Add), rhs = Counter(3)
+- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 6 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 7 operands: lhs = Expression(10, Add), rhs = Counter(4)
-- expression 8 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 9 operands: lhs = Counter(0), rhs = Expression(10, Add)
+- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(3)
+- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 8 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 9 operands: lhs = Expression(12, Add), rhs = Counter(4)
- expression 10 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 58, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+- expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add)
+- expression 12 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 17
+- Code(Counter(0)) at (prev + 58, 1) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
- Code(Expression(0, Sub)) at (prev + 0, 13) to (start + 0, 14)
= (c0 - c1)
-- MCDCBranch { true: Counter(2), false: Expression(9, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14)
+- MCDCBranch { true: Counter(2), false: Expression(11, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14)
true = c2
false = (c0 - (c1 + c2))
-- Code(Expression(10, Add)) at (prev + 1, 9) to (start + 1, 13)
+- Code(Expression(12, Add)) at (prev + 1, 9) to (start + 0, 12)
= (c1 + c2)
-- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 12) to (start + 0, 18)
-- MCDCBranch { true: Counter(3), false: Expression(4, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13)
+- Code(Expression(12, Add)) at (prev + 0, 13) to (start + 0, 21)
+ = (c1 + c2)
+- Code(Expression(12, Add)) at (prev + 1, 12) to (start + 0, 13)
+ = (c1 + c2)
+- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 12) to (start + 0, 18)
+- MCDCBranch { true: Counter(3), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13)
true = c3
false = ((c1 + c2) - c3)
- Code(Counter(3)) at (prev + 0, 17) to (start + 0, 18)
-- MCDCBranch { true: Counter(4), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18)
+- MCDCBranch { true: Counter(4), false: Expression(8, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18)
true = c4
false = (c3 - c4)
- Code(Counter(4)) at (prev + 0, 19) to (start + 2, 10)
-- Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(9, Sub)) at (prev + 2, 9) to (start + 0, 10)
= ((c1 + c2) - c4)
-- Code(Expression(9, Sub)) at (prev + 1, 12) to (start + 2, 6)
+- Code(Expression(11, Sub)) at (prev + 1, 12) to (start + 2, 6)
= (c0 - (c1 + c2))
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c4
diff --git a/tests/coverage/mcdc/if.coverage b/tests/coverage/mcdc/if.coverage
index 51917d0..fda5525 100644
--- a/tests/coverage/mcdc/if.coverage
+++ b/tests/coverage/mcdc/if.coverage
@@ -123,8 +123,8 @@
LL| 3|}
LL| |
LL| 4|fn mcdc_check_tree_decision(a: bool, b: bool, c: bool) {
- LL| 4| // This expression is intentionally written in a way
- LL| 4| // where 100% branch coverage indicates 100% mcdc coverage.
+ LL| | // This expression is intentionally written in a way
+ LL| | // where 100% branch coverage indicates 100% mcdc coverage.
LL| 4| if a && (b || c) {
^3 ^2
------------------
@@ -160,8 +160,8 @@
LL| 4|}
LL| |
LL| 4|fn mcdc_check_not_tree_decision(a: bool, b: bool, c: bool) {
- LL| 4| // Contradict to `mcdc_check_tree_decision`,
- LL| 4| // 100% branch coverage of this expression does not indicate 100% mcdc coverage.
+ LL| | // Contradict to `mcdc_check_tree_decision`,
+ LL| | // 100% branch coverage of this expression does not indicate 100% mcdc coverage.
LL| 4| if (a || b) && c {
^1
------------------
diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map
index 714d168..d05ef36 100644
--- a/tests/coverage/mcdc/inlined_expressions.cov-map
+++ b/tests/coverage/mcdc/inlined_expressions.cov-map
@@ -1,13 +1,14 @@
Function name: inlined_expressions::inlined_instance
-Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 07, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (55): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 07, 01, 00, 2e, 01, 01, 05, 00, 06, 28, 03, 02, 00, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/inlined_expressions.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 6)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 5) to (start + 0, 11)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6)
true = c1
false = (c0 - c1)
diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map
index 7232e4f..853cdf2 100644
--- a/tests/coverage/mcdc/nested_if.cov-map
+++ b/tests/coverage/mcdc/nested_if.cov-map
@@ -1,5 +1,5 @@
Function name: nested_if::doubly_nested_if_in_condition
-Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 14, 01, 0e, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (175): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 15, 01, 0e, 01, 00, 45, 01, 01, 08, 00, 09, 28, 09, 02, 00, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/nested_if.rs
Number of expressions: 15
@@ -18,9 +18,10 @@
- expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add)
- expression 13 operands: lhs = Counter(2), rhs = Counter(3)
- expression 14 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78)
+Number of file 0 mappings: 21
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 69)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 78)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -59,7 +60,7 @@
Highest counter ID seen: c6
Function name: nested_if::nested_if_in_condition
-Raw bytes (118): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0e, 01, 06, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (123): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0f, 01, 06, 01, 00, 35, 01, 01, 08, 00, 09, 28, 06, 02, 00, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/nested_if.rs
Number of expressions: 10
@@ -73,9 +74,10 @@
- expression 7 operands: lhs = Counter(1), rhs = Expression(8, Add)
- expression 8 operands: lhs = Counter(2), rhs = Counter(3)
- expression 9 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46)
+Number of file 0 mappings: 15
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 53)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 46)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -103,7 +105,7 @@
Highest counter ID seen: c4
Function name: nested_if::nested_in_then_block_in_condition
-Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 14, 01, 21, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (175): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 15, 01, 21, 01, 00, 52, 01, 01, 08, 00, 09, 28, 09, 02, 00, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/nested_if.rs
Number of expressions: 15
@@ -122,9 +124,10 @@
- expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add)
- expression 13 operands: lhs = Counter(2), rhs = Counter(3)
- expression 14 operands: lhs = Counter(0), rhs = Counter(6)
-Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75)
+Number of file 0 mappings: 21
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 82)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 75)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
@@ -163,7 +166,7 @@
Highest counter ID seen: c6
Function name: nested_if::nested_single_condition_decision
-Raw bytes (83): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0b, 01, 16, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (88): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0c, 01, 16, 01, 00, 36, 01, 04, 08, 00, 09, 28, 03, 02, 00, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/nested_if.rs
Number of expressions: 5
@@ -172,9 +175,10 @@
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 11
-- Code(Counter(0)) at (prev + 22, 1) to (start + 4, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 54)
+- Code(Counter(0)) at (prev + 4, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 41)
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
true = c1
false = (c0 - c1)
diff --git a/tests/coverage/mcdc/nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage
index c3ac30d..8b5179b 100644
--- a/tests/coverage/mcdc/nested_if.coverage
+++ b/tests/coverage/mcdc/nested_if.coverage
@@ -122,9 +122,9 @@
LL| 4|}
LL| |
LL| 3|fn nested_single_condition_decision(a: bool, b: bool) {
- LL| 3| // Decision with only 1 decision should not be instrumented by MCDC because
- LL| 3| // branch-coverage is equivalent to MCDC coverage in this case, and we don't
- LL| 3| // want to waste bitmap space for this.
+ LL| | // Decision with only 1 decision should not be instrumented by MCDC because
+ LL| | // branch-coverage is equivalent to MCDC coverage in this case, and we don't
+ LL| | // want to waste bitmap space for this.
LL| 3| if a && if b { false } else { true } {
^2 ^1 ^1
------------------
diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map
index 02251e6..f06bc2e 100644
--- a/tests/coverage/mcdc/non_control_flow.cov-map
+++ b/tests/coverage/mcdc/non_control_flow.cov-map
@@ -1,5 +1,5 @@
Function name: non_control_flow::assign_3
-Raw bytes (79): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0a, 01, 15, 01, 00, 28, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (89): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0c, 01, 15, 01, 00, 27, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/non_control_flow.rs
Number of expressions: 4
@@ -7,8 +7,8 @@
- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 40)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 39)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24)
@@ -24,11 +24,13 @@
- MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24)
true = c3
false = (c2 - c3)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: non_control_flow::assign_3_bis
-Raw bytes (81): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0a, 01, 1a, 01, 00, 2c, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (91): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0c, 01, 1a, 01, 00, 2b, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/non_control_flow.rs
Number of expressions: 5
@@ -37,8 +39,8 @@
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
- expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 44)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 43)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24)
@@ -54,18 +56,20 @@
- MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24)
true = c3
false = (c0 - (c2 + c3))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: non_control_flow::assign_and
-Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 0b, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (70): 0x[01, 01, 02, 01, 05, 05, 09, 0a, 01, 0b, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/non_control_flow.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 33)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 32)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19)
@@ -76,19 +80,21 @@
- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19)
true = c2
false = (c1 - c2)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c2
Function name: non_control_flow::assign_or
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 08, 01, 10, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (72): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 10, 01, 00, 1f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/non_control_flow.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 32)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 31)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19)
@@ -100,27 +106,32 @@
- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19)
true = c2
false = (c0 - (c1 + c2))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c2
Function name: non_control_flow::foo
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 24, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/non_control_flow.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: non_control_flow::func_call
-Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
+Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 1f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/non_control_flow.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 31)
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10)
- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 9) to (start + 0, 15)
@@ -135,7 +146,7 @@
Highest counter ID seen: c2
Function name: non_control_flow::right_comb_tree
-Raw bytes (111): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 0e, 01, 1f, 01, 00, 41, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 01, 02]
+Raw bytes (121): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 10, 01, 1f, 01, 00, 40, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/non_control_flow.rs
Number of expressions: 5
@@ -144,8 +155,8 @@
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
- expression 3 operands: lhs = Counter(3), rhs = Counter(4)
- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
-Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 65)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 64)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
- MCDCDecision { bitmap_idx: 6, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42)
@@ -168,6 +179,8 @@
- MCDCBranch { true: Counter(5), false: Expression(4, Sub), condition_id: 5, true_next_id: 0, false_next_id: 0 } at (prev + 0, 36) to (start + 0, 39)
true = c5
false = (c4 - c5)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c5
diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map
index 4a35da1..649c65d 100644
--- a/tests/coverage/nested_loops.cov-map
+++ b/tests/coverage/nested_loops.cov-map
@@ -1,40 +1,60 @@
Function name: nested_loops::main
-Raw bytes (97): 0x[01, 01, 0e, 07, 2f, 05, 11, 01, 0d, 2f, 05, 01, 0d, 27, 05, 01, 09, 33, 27, 05, 15, 01, 09, 2f, 33, 01, 0d, 05, 15, 05, 01, 0d, 01, 01, 01, 02, 1b, 05, 04, 13, 00, 20, 09, 01, 0d, 01, 18, 0d, 02, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 0e, 01, 0e, 03, 16, 15, 04, 11, 01, 1b, 16, 02, 15, 00, 21, 1e, 01, 18, 02, 12, 2a, 03, 0d, 00, 0e, 36, 02, 09, 00, 17, 01, 02, 01, 00, 02]
+Raw bytes (164): 0x[01, 01, 14, 07, 47, 05, 11, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 3f, 05, 01, 09, 4b, 3f, 05, 15, 01, 09, 47, 4b, 01, 0d, 05, 15, 05, 01, 18, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 13, 00, 20, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 0d, 01, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 26, 01, 0d, 00, 0e, 26, 01, 0d, 00, 13, 26, 01, 0d, 00, 13, 26, 01, 10, 00, 16, 15, 01, 11, 00, 18, 15, 01, 14, 00, 1b, 2e, 01, 15, 00, 21, 36, 01, 18, 02, 12, 42, 03, 0d, 00, 0e, 4e, 02, 09, 00, 17, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/nested_loops.rs
-Number of expressions: 14
-- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(11, Add)
+Number of expressions: 20
+- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(17, Add)
- expression 1 operands: lhs = Counter(1), rhs = Counter(4)
- expression 2 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 3 operands: lhs = Expression(11, Add), rhs = Counter(1)
+- expression 3 operands: lhs = Expression(17, Add), rhs = Counter(1)
- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(1)
-- expression 6 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 7 operands: lhs = Expression(12, Add), rhs = Expression(9, Add)
-- expression 8 operands: lhs = Counter(1), rhs = Counter(5)
-- expression 9 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 10 operands: lhs = Expression(11, Add), rhs = Expression(12, Add)
-- expression 11 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 12 operands: lhs = Counter(1), rhs = Counter(5)
-- expression 13 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 1, 1) to (start + 2, 27)
-- Code(Counter(1)) at (prev + 4, 19) to (start + 0, 32)
-- Code(Counter(2)) at (prev + 1, 13) to (start + 1, 24)
-- Code(Counter(3)) at (prev + 2, 18) to (start + 0, 23)
+- expression 5 operands: lhs = Expression(17, Add), rhs = Counter(1)
+- expression 6 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 7 operands: lhs = Expression(17, Add), rhs = Counter(1)
+- expression 8 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 9 operands: lhs = Expression(17, Add), rhs = Counter(1)
+- expression 10 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 11 operands: lhs = Expression(15, Add), rhs = Counter(1)
+- expression 12 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 13 operands: lhs = Expression(18, Add), rhs = Expression(15, Add)
+- expression 14 operands: lhs = Counter(1), rhs = Counter(5)
+- expression 15 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 16 operands: lhs = Expression(17, Add), rhs = Expression(18, Add)
+- expression 17 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 18 operands: lhs = Counter(1), rhs = Counter(5)
+- expression 19 operands: lhs = Counter(1), rhs = Counter(0)
+Number of file 0 mappings: 24
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 2, 19) to (start + 0, 32)
+- Code(Counter(2)) at (prev + 1, 13) to (start + 0, 18)
+- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24)
+- Code(Counter(2)) at (prev + 1, 13) to (start + 0, 18)
+- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24)
+- Code(Counter(3)) at (prev + 1, 18) to (start + 0, 23)
- Code(Counter(4)) at (prev + 1, 16) to (start + 0, 22)
- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 22)
= ((c1 + c4) - (c0 + c3))
-- Code(Expression(3, Sub)) at (prev + 1, 14) to (start + 3, 22)
+- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 14)
= ((c0 + c3) - c1)
-- Code(Counter(5)) at (prev + 4, 17) to (start + 1, 27)
-- Code(Expression(5, Sub)) at (prev + 2, 21) to (start + 0, 33)
+- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19)
+ = ((c0 + c3) - c1)
+- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19)
+ = ((c0 + c3) - c1)
+- Code(Expression(9, Sub)) at (prev + 1, 16) to (start + 0, 22)
+ = ((c0 + c3) - c1)
+- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 24)
+- Code(Counter(5)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Expression(11, Sub)) at (prev + 1, 21) to (start + 0, 33)
= ((c0 + c2) - c1)
-- Code(Expression(7, Sub)) at (prev + 1, 24) to (start + 2, 18)
+- Code(Expression(13, Sub)) at (prev + 1, 24) to (start + 2, 18)
= ((c1 + c5) - (c0 + c2))
-- Code(Expression(10, Sub)) at (prev + 3, 13) to (start + 0, 14)
+- Code(Expression(16, Sub)) at (prev + 3, 13) to (start + 0, 14)
= ((c0 + c3) - (c1 + c5))
-- Code(Expression(13, Sub)) at (prev + 2, 9) to (start + 0, 23)
+- Code(Expression(19, Sub)) at (prev + 2, 9) to (start + 0, 23)
= (c1 - c0)
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c5
diff --git a/tests/coverage/no-core.cov-map b/tests/coverage/no-core.cov-map
index 89012b0..f286700 100644
--- a/tests/coverage/no-core.cov-map
+++ b/tests/coverage/no-core.cov-map
@@ -1,9 +1,10 @@
Function name: no_core::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0c, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => $DIR/no-core.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0
diff --git a/tests/coverage/no_cov_crate.cov-map b/tests/coverage/no_cov_crate.cov-map
index caef093..ca3c95f 100644
--- a/tests/coverage/no_cov_crate.cov-map
+++ b/tests/coverage/no_cov_crate.cov-map
@@ -1,68 +1,99 @@
Function name: no_cov_crate::add_coverage_1
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 22, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/no_cov_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 22, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: no_cov_crate::add_coverage_2
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1a, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 22, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/no_cov_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: no_cov_crate::add_coverage_not_called (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 00, 1d, 00, 01, 05, 00, 0d, 00, 00, 0e, 00, 26, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/no_cov_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 31, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 31, 1) to (start + 0, 29)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 13)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 38)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
Function name: no_cov_crate::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 4f, 01, 0b, 02]
+Raw bytes (74): 0x[01, 01, 00, 0e, 01, 4f, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 05, 00, 1a, 01, 01, 05, 00, 1a, 01, 01, 05, 00, 13, 01, 01, 05, 00, 13, 01, 02, 05, 00, 22, 01, 00, 23, 00, 2a, 01, 01, 05, 00, 16, 01, 00, 17, 00, 1e, 01, 01, 05, 00, 23, 01, 00, 24, 00, 2b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/no_cov_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 79, 1) to (start + 11, 2)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 79, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 0, 36) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: no_cov_crate::nested_fns::outer
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 33, 05, 02, 22, 01, 0c, 05, 00, 06]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 33, 05, 00, 20, 01, 01, 09, 00, 11, 01, 00, 12, 00, 26, 01, 01, 09, 00, 1a, 01, 00, 1b, 00, 22, 01, 0a, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/no_cov_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 51, 5) to (start + 2, 34)
-- Code(Counter(0)) at (prev + 12, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 51, 5) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 6)
Highest counter ID seen: c0
Function name: no_cov_crate::nested_fns::outer_both_covered
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 41, 05, 02, 16, 01, 0b, 05, 00, 06]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 41, 05, 00, 2d, 01, 01, 09, 00, 11, 01, 00, 12, 00, 26, 01, 01, 09, 00, 0e, 01, 00, 0f, 00, 16, 01, 09, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/no_cov_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 65, 5) to (start + 2, 22)
-- Code(Counter(0)) at (prev + 11, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 6)
Highest counter ID seen: c0
Function name: no_cov_crate::nested_fns::outer_both_covered::inner
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 45, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 45, 09, 00, 20, 01, 01, 10, 00, 17, 05, 00, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
Number of files: 1
- file 0 => $DIR/no_cov_crate.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 69, 9) to (start + 1, 23)
-- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 69, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 0, 24) to (start + 2, 14)
- Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14)
= (c0 - c1)
- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
diff --git a/tests/coverage/no_cov_crate.coverage b/tests/coverage/no_cov_crate.coverage
index 2a8961e..c6453e6 100644
--- a/tests/coverage/no_cov_crate.coverage
+++ b/tests/coverage/no_cov_crate.coverage
@@ -78,12 +78,12 @@
LL| |
LL| 1|fn main() {
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| do_not_add_coverage_1();
LL| 1| do_not_add_coverage_2();
LL| 1| add_coverage_1();
LL| 1| add_coverage_2();
- LL| 1|
+ LL| |
LL| 1| nested_fns::outer_not_covered(is_true);
LL| 1| nested_fns::outer(is_true);
LL| 1| nested_fns::outer_both_covered(is_true);
diff --git a/tests/coverage/no_spans.cov-map b/tests/coverage/no_spans.cov-map
index 992247f..821976b 100644
--- a/tests/coverage/no_spans.cov-map
+++ b/tests/coverage/no_spans.cov-map
@@ -1,18 +1,20 @@
Function name: no_spans::affected_function
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 1c, 00, 1d]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 1c, 00, 1d]
Number of files: 1
- file 0 => $DIR/no_spans.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 26, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 21, 28) to (start + 0, 29)
Highest counter ID seen: c0
-Function name: no_spans::affected_function::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e]
+Function name: no_spans::main
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 01, 00, 0a, 01, 01, 05, 00, 1a, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/no_spans.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 27, 12) to (start + 0, 14)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/no_spans.coverage b/tests/coverage/no_spans.coverage
index 19e8c2f..cf0e476 100644
--- a/tests/coverage/no_spans.coverage
+++ b/tests/coverage/no_spans.coverage
@@ -1,20 +1,15 @@
LL| |#![feature(coverage_attribute)]
LL| |//@ edition: 2021
LL| |
- LL| |// If the span extractor can't find any relevant spans for a function, the
- LL| |// refinement loop will terminate with nothing in its `prev` slot. If the
- LL| |// subsequent code tries to unwrap `prev`, it will panic.
+ LL| |// Test that coverage instrumentation can gracefully handle functions that end
+ LL| |// up having no relevant spans, without crashing the compiler or causing
+ LL| |// `llvm-cov` to fail.
LL| |//
- LL| |// This scenario became more likely after #118525 started discarding spans that
- LL| |// can't be un-expanded back to within the function body.
- LL| |//
- LL| |// Regression test for "invalid attempt to unwrap a None some_prev", as seen
- LL| |// in issues such as #118643 and #118662.
+ LL| |// This was originally a regression test for issues such as #118643 and #118662.
LL| |
- LL| |#[coverage(off)]
- LL| |fn main() {
- LL| | affected_function()();
- LL| |}
+ LL| 1|fn main() {
+ LL| 1| affected_function()();
+ LL| 1|}
LL| |
LL| |macro_rules! macro_that_defines_a_function {
LL| | (fn $name:ident () $body:tt) => {
@@ -24,7 +19,7 @@
LL| |
LL| |macro_that_defines_a_function! {
LL| 1| fn affected_function() {
- LL| 1| || ()
+ LL| | || ()
LL| | }
LL| |}
diff --git a/tests/coverage/no_spans.rs b/tests/coverage/no_spans.rs
index e531240..979b407 100644
--- a/tests/coverage/no_spans.rs
+++ b/tests/coverage/no_spans.rs
@@ -1,17 +1,12 @@
#![feature(coverage_attribute)]
//@ edition: 2021
-// If the span extractor can't find any relevant spans for a function, the
-// refinement loop will terminate with nothing in its `prev` slot. If the
-// subsequent code tries to unwrap `prev`, it will panic.
+// Test that coverage instrumentation can gracefully handle functions that end
+// up having no relevant spans, without crashing the compiler or causing
+// `llvm-cov` to fail.
//
-// This scenario became more likely after #118525 started discarding spans that
-// can't be un-expanded back to within the function body.
-//
-// Regression test for "invalid attempt to unwrap a None some_prev", as seen
-// in issues such as #118643 and #118662.
+// This was originally a regression test for issues such as #118643 and #118662.
-#[coverage(off)]
fn main() {
affected_function()();
}
diff --git a/tests/coverage/no_spans_if_not.cov-map b/tests/coverage/no_spans_if_not.cov-map
index 9d4fc07..c8aa5c7 100644
--- a/tests/coverage/no_spans_if_not.cov-map
+++ b/tests/coverage/no_spans_if_not.cov-map
@@ -1,20 +1,23 @@
Function name: no_spans_if_not::affected_function
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 16, 1c, 01, 12, 01, 02, 0d, 00, 0f, 00, 02, 0d, 00, 0f]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 1c, 00, 1d, 01, 01, 0c, 00, 12, 01, 01, 0d, 00, 0f, 00, 02, 0d, 00, 0f]
Number of files: 1
- file 0 => $DIR/no_spans_if_not.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 18)
-- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 15)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 22, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 15)
- Code(Zero) at (prev + 2, 13) to (start + 0, 15)
Highest counter ID seen: c0
Function name: no_spans_if_not::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0b, 01, 00, 0a, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/no_spans_if_not.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/overflow.cov-map b/tests/coverage/overflow.cov-map
index 9bb68ee..18b0503 100644
--- a/tests/coverage/overflow.cov-map
+++ b/tests/coverage/overflow.cov-map
@@ -1,5 +1,5 @@
Function name: overflow::main
-Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 10, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 03, 0a, 06, 03, 13, 00, 20, 0d, 00, 21, 03, 0a, 0e, 03, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
+Raw bytes (96): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 10, 01, 10, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 03, 0a, 09, 01, 11, 00, 17, 09, 00, 1a, 00, 28, 06, 02, 13, 00, 20, 0d, 00, 21, 03, 0a, 0d, 01, 11, 00, 17, 0d, 00, 1a, 00, 28, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/overflow.rs
Number of expressions: 6
@@ -9,33 +9,50 @@
- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
- expression 5 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24)
- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
= (c1 - c0)
- Code(Counter(2)) at (prev + 0, 27) to (start + 3, 10)
-- Code(Expression(1, Sub)) at (prev + 3, 19) to (start + 0, 32)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23)
+- Code(Counter(2)) at (prev + 0, 26) to (start + 0, 40)
+- Code(Expression(1, Sub)) at (prev + 2, 19) to (start + 0, 32)
= (c1 - (c0 + c2))
- Code(Counter(3)) at (prev + 0, 33) to (start + 3, 10)
-- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 10)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 23)
+- Code(Counter(3)) at (prev + 0, 26) to (start + 0, 40)
+- Code(Expression(3, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c1 - ((c0 + c2) + c3))
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
= (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: overflow::might_overflow
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 12, 05, 01, 13, 02, 06, 02, 02, 05, 00, 06, 01, 01, 09, 05, 02]
+Raw bytes (76): 0x[01, 01, 01, 01, 05, 0e, 01, 05, 01, 00, 26, 01, 01, 08, 00, 12, 05, 00, 13, 02, 06, 02, 02, 05, 00, 06, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1e, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 26, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 21, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 2f, 01, 01, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/overflow.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 1, 19) to (start + 2, 6)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 0, 19) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 9) to (start + 5, 2)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 47)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
diff --git a/tests/coverage/panic_unwind.cov-map b/tests/coverage/panic_unwind.cov-map
index f6d1fe5..ff656d3 100644
--- a/tests/coverage/panic_unwind.cov-map
+++ b/tests/coverage/panic_unwind.cov-map
@@ -1,5 +1,5 @@
Function name: panic_unwind::main
-Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
+Raw bytes (76): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 0c, 01, 0d, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/panic_unwind.rs
Number of expressions: 6
@@ -9,9 +9,11 @@
- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
- expression 5 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24)
- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
= (c1 - c0)
- Code(Counter(2)) at (prev + 0, 27) to (start + 2, 10)
@@ -22,19 +24,25 @@
= (c1 - ((c0 + c2) + c3))
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
= (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: panic_unwind::might_panic
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02]
+Raw bytes (41): 0x[01, 01, 01, 01, 05, 07, 01, 04, 01, 00, 23, 01, 01, 08, 00, 14, 05, 01, 09, 00, 11, 05, 00, 12, 00, 20, 05, 01, 09, 00, 0f, 02, 01, 0c, 02, 06, 02, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/panic_unwind.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 4, 1) to (start + 1, 20)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 32)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 2, 6)
+ = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2)
= (c0 - c1)
Highest counter ID seen: c1
diff --git a/tests/coverage/partial_eq.cov-map b/tests/coverage/partial_eq.cov-map
index 02054aa..0a81be7 100644
--- a/tests/coverage/partial_eq.cov-map
+++ b/tests/coverage/partial_eq.cov-map
@@ -1,18 +1,29 @@
Function name: <partial_eq::Version>::new
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 05, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 0c, 05, 00, 41, 01, 01, 09, 00, 25, 01, 00, 10, 00, 15, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/partial_eq.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 5) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 12, 5) to (start + 0, 65)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c0
Function name: partial_eq::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 0a, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 01, 11, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 25, 01, 01, 09, 00, 16, 01, 00, 19, 00, 25, 01, 02, 05, 00, 0d, 01, 01, 09, 00, 1b, 01, 03, 09, 00, 26, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/partial_eq.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 1) to (start + 10, 2)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/partial_eq.coverage b/tests/coverage/partial_eq.coverage
index dc5b82b..0662ce2 100644
--- a/tests/coverage/partial_eq.coverage
+++ b/tests/coverage/partial_eq.coverage
@@ -17,13 +17,13 @@
LL| 1|fn main() {
LL| 1| let version_3_2_1 = Version::new(3, 2, 1);
LL| 1| let version_3_3_0 = Version::new(3, 3, 0);
- LL| 1|
+ LL| |
LL| 1| println!(
LL| 1| "{:?} < {:?} = {}",
- LL| 1| version_3_2_1,
- LL| 1| version_3_3_0,
+ LL| | version_3_2_1,
+ LL| | version_3_3_0,
LL| 1| version_3_2_1 < version_3_3_0, //
- LL| 1| );
+ LL| | );
LL| 1|}
LL| |
LL| |/*
diff --git a/tests/coverage/simple_loop.cov-map b/tests/coverage/simple_loop.cov-map
index 542c93c..5447ffd 100644
--- a/tests/coverage/simple_loop.cov-map
+++ b/tests/coverage/simple_loop.cov-map
@@ -1,19 +1,27 @@
Function name: simple_loop::main
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 09, 01, 07, 01, 04, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 05, 00, 06, 09, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 06, 02, 0a, 03, 0a, 01, 06, 01, 00, 02]
+Raw bytes (75): 0x[01, 01, 03, 01, 05, 09, 01, 09, 01, 0d, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 03, 09, 00, 10, 05, 01, 05, 05, 06, 02, 05, 05, 00, 06, 09, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 0a, 02, 09, 00, 0a, 0a, 01, 09, 02, 0a, 01, 05, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/simple_loop.rs
-Number of expressions: 2
+Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(2), rhs = Counter(0)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 4, 1) to (start + 9, 16)
-- Code(Counter(1)) at (prev + 10, 5) to (start + 5, 6)
+- expression 2 operands: lhs = Counter(2), rhs = Counter(0)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6)
- Code(Expression(0, Sub)) at (prev + 5, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(2)) at (prev + 5, 13) to (start + 2, 14)
- Code(Counter(0)) at (prev + 4, 13) to (start + 0, 18)
-- Code(Expression(1, Sub)) at (prev + 2, 10) to (start + 3, 10)
+- Code(Expression(2, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c2 - c0)
-- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 2)
+- Code(Expression(2, Sub)) at (prev + 1, 9) to (start + 2, 10)
+ = (c2 - c0)
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2)
Highest counter ID seen: c2
diff --git a/tests/coverage/simple_loop.coverage b/tests/coverage/simple_loop.coverage
index 237e509..a75263f 100644
--- a/tests/coverage/simple_loop.coverage
+++ b/tests/coverage/simple_loop.coverage
@@ -2,14 +2,14 @@
LL| |
LL| |#[rustfmt::skip]
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let mut countdown = 0;
- LL| 1|
- LL| 1| if
+ LL| |
+ LL| | if
LL| 1| is_true
LL| 1| {
LL| 1| countdown
diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map
index a96ddc2..cbd6c7c 100644
--- a/tests/coverage/simple_match.cov-map
+++ b/tests/coverage/simple_match.cov-map
@@ -1,5 +1,5 @@
Function name: simple_match::main
-Raw bytes (64): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0e, 0a, 0d, 00, 0f, 01, 03, 01, 00, 02]
+Raw bytes (99): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 11, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0d, 01, 11, 00, 1e, 0d, 02, 15, 00, 16, 0e, 07, 0d, 00, 0f, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/simple_match.rs
Number of expressions: 5
@@ -8,9 +8,14 @@
- expression 2 operands: lhs = Counter(2), rhs = Counter(0)
- expression 3 operands: lhs = Counter(2), rhs = Expression(4, Add)
- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15)
-- Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6)
+Number of file 0 mappings: 17
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(2)) at (prev + 5, 9) to (start + 0, 13)
@@ -20,7 +25,9 @@
- Code(Expression(2, Sub)) at (prev + 2, 17) to (start + 2, 18)
= (c2 - c0)
- Code(Counter(3)) at (prev + 4, 13) to (start + 7, 14)
-- Code(Expression(3, Sub)) at (prev + 10, 13) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 2, 21) to (start + 0, 22)
+- Code(Expression(3, Sub)) at (prev + 7, 13) to (start + 0, 15)
= (c2 - (c0 + c3))
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c3
diff --git a/tests/coverage/simple_match.coverage b/tests/coverage/simple_match.coverage
index e1d5e48..0ed7e8d 100644
--- a/tests/coverage/simple_match.coverage
+++ b/tests/coverage/simple_match.coverage
@@ -2,11 +2,11 @@
LL| |
LL| |#[rustfmt::skip]
LL| 1|fn main() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
- LL| 1|
+ LL| |
LL| 1| let mut countdown = 1;
LL| 1| if is_true {
LL| 1| countdown = 0;
diff --git a/tests/coverage/sort_groups.cov-map b/tests/coverage/sort_groups.cov-map
index b0d260e..70cf7cf 100644
--- a/tests/coverage/sort_groups.cov-map
+++ b/tests/coverage/sort_groups.cov-map
@@ -1,79 +1,98 @@
Function name: sort_groups::generic_fn::<&str>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/sort_groups.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12)
-- Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: sort_groups::generic_fn::<()>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/sort_groups.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12)
-- Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: sort_groups::generic_fn::<char>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/sort_groups.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12)
-- Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: sort_groups::generic_fn::<i32>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/sort_groups.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12)
-- Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: sort_groups::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 06, 01, 04, 1c, 05, 04, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 02, 02]
+Raw bytes (76): 0x[01, 01, 01, 01, 05, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0d, 01, 00, 10, 00, 2a, 01, 01, 05, 00, 15, 01, 00, 16, 00, 1a, 01, 01, 05, 00, 1f, 01, 00, 20, 00, 25, 01, 01, 08, 00, 1c, 05, 00, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 00, 16, 01, 00, 17, 00, 1b, 01, 01, 05, 00, 0d, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/sort_groups.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 6, 1) to (start + 4, 28)
-- Code(Counter(1)) at (prev + 4, 36) to (start + 2, 6)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 28)
+- Code(Counter(1)) at (prev + 0, 36) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 2, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: sort_groups::other_fn
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 11]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 17, 01, 00, 0e, 01, 00, 10, 00, 11]
Number of files: 1
- file 0 => $DIR/sort_groups.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 17)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17)
Highest counter ID seen: c0
diff --git a/tests/coverage/test_harness.cov-map b/tests/coverage/test_harness.cov-map
index 50654fb..691332a 100644
--- a/tests/coverage/test_harness.cov-map
+++ b/tests/coverage/test_harness.cov-map
@@ -1,18 +1,20 @@
Function name: test_harness::my_test
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 00, 10]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 00, 0d, 01, 00, 0f, 00, 10]
Number of files: 1
- file 0 => $DIR/test_harness.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 16)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
Highest counter ID seen: c0
Function name: test_harness::unused (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 07, 01, 00, 0f]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 07, 01, 00, 0c, 00, 00, 0e, 00, 0f]
Number of files: 1
- file 0 => $DIR/test_harness.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 7, 1) to (start + 0, 15)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 7, 1) to (start + 0, 12)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 15)
Highest counter ID seen: (none)
diff --git a/tests/coverage/tight_inf_loop.cov-map b/tests/coverage/tight_inf_loop.cov-map
index 31581f0..c6bee3b 100644
--- a/tests/coverage/tight_inf_loop.cov-map
+++ b/tests/coverage/tight_inf_loop.cov-map
@@ -1,11 +1,13 @@
Function name: tight_inf_loop::main
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 01, 01, 01, 0d, 00, 02, 09, 00, 10, 01, 01, 06, 01, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 01, 01, 00, 0a, 01, 01, 08, 00, 0d, 00, 01, 09, 00, 10, 01, 01, 05, 00, 06, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/tight_inf_loop.rs
Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 1, 1) to (start + 1, 13)
-- Code(Zero) at (prev + 2, 9) to (start + 0, 16)
-- Code(Counter(0)) at (prev + 1, 6) to (start + 1, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 13)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/trivial.cov-map b/tests/coverage/trivial.cov-map
index 0064b20..fff10df 100644
--- a/tests/coverage/trivial.cov-map
+++ b/tests/coverage/trivial.cov-map
@@ -1,9 +1,10 @@
Function name: trivial::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 03, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => $DIR/trivial.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0
diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map
index a6ecc68a..e08f429 100644
--- a/tests/coverage/try_error_result.cov-map
+++ b/tests/coverage/try_error_result.cov-map
@@ -1,61 +1,68 @@
Function name: <try_error_result::Thing1>::get_thing_2
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 05, 01, 18, 05, 02, 0d, 00, 14, 02, 02, 0d, 00, 1a, 01, 02, 05, 00, 06]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 29, 05, 00, 44, 01, 01, 0c, 00, 18, 05, 01, 0d, 00, 14, 02, 02, 0d, 00, 1a, 01, 02, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/try_error_result.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 41, 5) to (start + 1, 24)
-- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 20)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 41, 5) to (start + 0, 68)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 24)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 20)
- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 26)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6)
Highest counter ID seen: c1
Function name: <try_error_result::Thing2>::call
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 34, 05, 01, 18, 05, 02, 0d, 00, 14, 02, 02, 0d, 00, 13, 01, 02, 05, 00, 06]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 34, 05, 00, 3a, 01, 01, 0c, 00, 18, 05, 01, 0d, 00, 14, 02, 02, 0d, 00, 13, 01, 02, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/try_error_result.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 52, 5) to (start + 1, 24)
-- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 20)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 52, 5) to (start + 0, 58)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 24)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 20)
- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6)
Highest counter ID seen: c1
Function name: try_error_result::call
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 14, 05, 02, 09, 00, 10, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 05, 01, 00, 2e, 01, 01, 08, 00, 14, 05, 01, 09, 00, 10, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/try_error_result.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 20)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 16)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16)
- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
= (c0 - c1)
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: try_error_result::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 71, 01, 02, 0a, 05, 03, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (46): 0x[01, 01, 01, 01, 05, 08, 01, 71, 01, 00, 1c, 01, 01, 05, 00, 0a, 01, 00, 0d, 00, 17, 01, 00, 18, 00, 2b, 01, 01, 05, 00, 0a, 05, 01, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/try_error_result.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 113, 1) to (start + 2, 10)
-- Code(Counter(1)) at (prev + 3, 5) to (start + 0, 6)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 113, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6)
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 11)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: try_error_result::test1
-Raw bytes (67): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0b, 01, 0d, 01, 02, 17, 05, 07, 09, 00, 0e, 09, 02, 09, 04, 1a, 02, 06, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (82): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0e, 01, 0d, 01, 00, 1d, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 02, 02, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/try_error_result.rs
Number of expressions: 4
@@ -63,11 +70,14 @@
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
- expression 2 operands: lhs = Counter(1), rhs = Counter(0)
- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 11
-- Code(Counter(0)) at (prev + 13, 1) to (start + 2, 23)
-- Code(Counter(1)) at (prev + 7, 9) to (start + 0, 14)
-- Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26)
-- Code(Expression(0, Sub)) at (prev + 6, 13) to (start + 0, 17)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18)
+- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17)
+- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26)
+- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 17)
= ((c0 + c2) - c1)
- Code(Expression(0, Sub)) at (prev + 0, 41) to (start + 0, 42)
= ((c0 + c2) - c1)
@@ -82,125 +92,157 @@
Highest counter ID seen: c2
Function name: try_error_result::test2
-Raw bytes (336): 0x[01, 01, 36, 0d, 11, 0d, 3f, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 0d, 3f, 11, 15, 0d, 3b, 3f, 19, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 41, 53, 21, 25, 41, 21, 41, 53, 21, 25, 09, 73, 77, 2d, 0d, 29, 09, 0d, 09, 77, 0d, 29, 09, 73, 77, 2d, 0d, 29, 45, 8b, 01, 31, 35, 45, 31, 45, 8b, 01, 31, 35, 49, 9f, 01, 39, 3d, 49, 39, 49, 9f, 01, 39, 3d, 05, 09, ab, 01, 09, af, 01, 3d, b3, 01, 39, b7, 01, 35, bb, 01, 31, bf, 01, 2d, c3, 01, 29, c7, 01, 25, cb, 01, 21, cf, 01, 1d, d3, 01, 19, d7, 01, 15, 05, 11, 28, 01, 3d, 01, 03, 17, 05, 08, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 03, 1c, 15, 04, 11, 00, 12, 1e, 02, 11, 03, 27, 32, 05, 11, 00, 14, 1e, 00, 17, 00, 29, 19, 00, 41, 00, 42, 26, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 32, 01, 0d, 00, 17, 4e, 01, 11, 00, 14, 41, 00, 17, 00, 29, 21, 00, 41, 00, 42, 4a, 00, 43, 00, 47, 25, 00, 60, 00, 61, 4e, 01, 0d, 00, 17, 6e, 04, 11, 00, 14, 62, 00, 17, 00, 29, 29, 00, 42, 00, 43, 66, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 6e, 01, 0d, 00, 17, 86, 01, 01, 11, 00, 14, 45, 00, 17, 01, 1d, 31, 01, 36, 00, 37, 82, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, 86, 01, 01, 0d, 00, 17, 9a, 01, 01, 11, 00, 14, 49, 00, 17, 01, 1d, 39, 02, 11, 00, 12, 96, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, 9a, 01, 02, 0d, 00, 17, a2, 01, 03, 05, 00, 0b, a6, 01, 01, 01, 00, 02]
+Raw bytes (443): 0x[01, 01, 3d, 0d, 11, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 53, 57, 19, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 41, 6b, 21, 25, 41, 21, 41, 6b, 21, 25, 09, 8f, 01, 93, 01, 2d, 0d, 29, 09, 0d, 09, 0d, 09, 93, 01, 0d, 29, 09, 8f, 01, 93, 01, 2d, 0d, 29, 45, a7, 01, 31, 35, 45, 31, 45, a7, 01, 31, 35, 49, bb, 01, 39, 3d, 49, 39, 49, bb, 01, 39, 3d, 05, 09, c7, 01, 09, cb, 01, 3d, cf, 01, 39, d3, 01, 35, d7, 01, 31, db, 01, 2d, df, 01, 29, e3, 01, 25, e7, 01, 21, eb, 01, 1d, ef, 01, 19, f3, 01, 15, 05, 11, 39, 01, 3d, 01, 00, 1d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1a, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 0d, 02, 0d, 00, 13, 0d, 00, 14, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 00, 35, 02, 00, 45, 00, 4f, 02, 00, 50, 00, 62, 02, 01, 0d, 00, 13, 02, 02, 11, 00, 1c, 15, 01, 11, 00, 12, 36, 02, 11, 00, 15, 36, 02, 11, 00, 1b, 36, 01, 15, 00, 27, 4a, 02, 11, 00, 14, 36, 00, 17, 00, 1d, 36, 00, 1e, 00, 29, 19, 00, 41, 00, 42, 3e, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 4a, 01, 0d, 00, 17, 66, 01, 11, 00, 14, 41, 00, 17, 00, 1d, 41, 00, 1e, 00, 29, 21, 00, 41, 00, 42, 62, 00, 43, 00, 47, 25, 00, 60, 00, 61, 66, 01, 0d, 00, 17, 8a, 01, 04, 11, 00, 14, 7e, 00, 17, 00, 1d, 7e, 00, 1e, 00, 29, 29, 00, 42, 00, 43, 82, 01, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 8a, 01, 01, 0d, 00, 17, a2, 01, 01, 11, 00, 14, 45, 00, 17, 00, 1d, 45, 01, 12, 00, 1d, 31, 00, 36, 00, 37, 9e, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 17, b6, 01, 01, 11, 00, 14, 49, 00, 17, 00, 1d, 49, 01, 12, 00, 1d, 39, 01, 11, 00, 12, b2, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 17, be, 01, 03, 05, 00, 0b, c2, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/try_error_result.rs
-Number of expressions: 54
+Number of expressions: 61
- expression 0 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 1 operands: lhs = Counter(3), rhs = Expression(15, Add)
+- expression 1 operands: lhs = Counter(3), rhs = Expression(21, Add)
- expression 2 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 3 operands: lhs = Counter(3), rhs = Expression(13, Add)
-- expression 4 operands: lhs = Expression(14, Add), rhs = Counter(7)
-- expression 5 operands: lhs = Expression(15, Add), rhs = Counter(6)
+- expression 3 operands: lhs = Counter(3), rhs = Expression(21, Add)
+- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 5 operands: lhs = Counter(3), rhs = Expression(21, Add)
- expression 6 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 7 operands: lhs = Counter(3), rhs = Expression(15, Add)
-- expression 8 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 9 operands: lhs = Counter(3), rhs = Expression(14, Add)
-- expression 10 operands: lhs = Expression(15, Add), rhs = Counter(6)
-- expression 11 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 12 operands: lhs = Counter(3), rhs = Expression(13, Add)
-- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(7)
-- expression 14 operands: lhs = Expression(15, Add), rhs = Counter(6)
-- expression 15 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 16 operands: lhs = Counter(16), rhs = Expression(20, Add)
-- expression 17 operands: lhs = Counter(8), rhs = Counter(9)
-- expression 18 operands: lhs = Counter(16), rhs = Counter(8)
-- expression 19 operands: lhs = Counter(16), rhs = Expression(20, Add)
-- expression 20 operands: lhs = Counter(8), rhs = Counter(9)
-- expression 21 operands: lhs = Counter(2), rhs = Expression(28, Add)
-- expression 22 operands: lhs = Expression(29, Add), rhs = Counter(11)
-- expression 23 operands: lhs = Counter(3), rhs = Counter(10)
-- expression 24 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 25 operands: lhs = Counter(2), rhs = Expression(29, Add)
-- expression 26 operands: lhs = Counter(3), rhs = Counter(10)
-- expression 27 operands: lhs = Counter(2), rhs = Expression(28, Add)
-- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(11)
+- expression 7 operands: lhs = Counter(3), rhs = Expression(19, Add)
+- expression 8 operands: lhs = Expression(20, Add), rhs = Counter(7)
+- expression 9 operands: lhs = Expression(21, Add), rhs = Counter(6)
+- expression 10 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 11 operands: lhs = Counter(3), rhs = Expression(21, Add)
+- expression 12 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 13 operands: lhs = Counter(3), rhs = Expression(21, Add)
+- expression 14 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 15 operands: lhs = Counter(3), rhs = Expression(20, Add)
+- expression 16 operands: lhs = Expression(21, Add), rhs = Counter(6)
+- expression 17 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 18 operands: lhs = Counter(3), rhs = Expression(19, Add)
+- expression 19 operands: lhs = Expression(20, Add), rhs = Counter(7)
+- expression 20 operands: lhs = Expression(21, Add), rhs = Counter(6)
+- expression 21 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 22 operands: lhs = Counter(16), rhs = Expression(26, Add)
+- expression 23 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 24 operands: lhs = Counter(16), rhs = Counter(8)
+- expression 25 operands: lhs = Counter(16), rhs = Expression(26, Add)
+- expression 26 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 27 operands: lhs = Counter(2), rhs = Expression(35, Add)
+- expression 28 operands: lhs = Expression(36, Add), rhs = Counter(11)
- expression 29 operands: lhs = Counter(3), rhs = Counter(10)
-- expression 30 operands: lhs = Counter(17), rhs = Expression(34, Add)
-- expression 31 operands: lhs = Counter(12), rhs = Counter(13)
-- expression 32 operands: lhs = Counter(17), rhs = Counter(12)
-- expression 33 operands: lhs = Counter(17), rhs = Expression(34, Add)
-- expression 34 operands: lhs = Counter(12), rhs = Counter(13)
-- expression 35 operands: lhs = Counter(18), rhs = Expression(39, Add)
-- expression 36 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 37 operands: lhs = Counter(18), rhs = Counter(14)
-- expression 38 operands: lhs = Counter(18), rhs = Expression(39, Add)
-- expression 39 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 40 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(2)
-- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(15)
-- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(14)
-- expression 44 operands: lhs = Expression(45, Add), rhs = Counter(13)
-- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(12)
-- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(11)
-- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(10)
-- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(9)
-- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(8)
-- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(7)
-- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(6)
-- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(5)
-- expression 53 operands: lhs = Counter(1), rhs = Counter(4)
-Number of file 0 mappings: 40
-- Code(Counter(0)) at (prev + 61, 1) to (start + 3, 23)
-- Code(Counter(1)) at (prev + 8, 9) to (start + 0, 14)
-- Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26)
-- Code(Counter(3)) at (prev + 6, 13) to (start + 0, 31)
+- expression 30 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 31 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 32 operands: lhs = Counter(2), rhs = Expression(36, Add)
+- expression 33 operands: lhs = Counter(3), rhs = Counter(10)
+- expression 34 operands: lhs = Counter(2), rhs = Expression(35, Add)
+- expression 35 operands: lhs = Expression(36, Add), rhs = Counter(11)
+- expression 36 operands: lhs = Counter(3), rhs = Counter(10)
+- expression 37 operands: lhs = Counter(17), rhs = Expression(41, Add)
+- expression 38 operands: lhs = Counter(12), rhs = Counter(13)
+- expression 39 operands: lhs = Counter(17), rhs = Counter(12)
+- expression 40 operands: lhs = Counter(17), rhs = Expression(41, Add)
+- expression 41 operands: lhs = Counter(12), rhs = Counter(13)
+- expression 42 operands: lhs = Counter(18), rhs = Expression(46, Add)
+- expression 43 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 44 operands: lhs = Counter(18), rhs = Counter(14)
+- expression 45 operands: lhs = Counter(18), rhs = Expression(46, Add)
+- expression 46 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 47 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(2)
+- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(15)
+- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(14)
+- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(13)
+- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(12)
+- expression 53 operands: lhs = Expression(54, Add), rhs = Counter(11)
+- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(10)
+- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(9)
+- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(8)
+- expression 57 operands: lhs = Expression(58, Add), rhs = Counter(7)
+- expression 58 operands: lhs = Expression(59, Add), rhs = Counter(6)
+- expression 59 operands: lhs = Expression(60, Add), rhs = Counter(5)
+- expression 60 operands: lhs = Counter(1), rhs = Counter(4)
+Number of file 0 mappings: 57
+- Code(Counter(0)) at (prev + 61, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18)
+- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17)
+- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26)
+- Code(Counter(3)) at (prev + 2, 13) to (start + 0, 19)
+- Code(Counter(3)) at (prev + 0, 20) to (start + 0, 31)
- Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 3, 28)
+- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 0, 53)
= (c3 - c4)
-- Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18)
-- Code(Expression(7, Sub)) at (prev + 2, 17) to (start + 3, 39)
+- Code(Expression(0, Sub)) at (prev + 0, 69) to (start + 0, 79)
+ = (c3 - c4)
+- Code(Expression(0, Sub)) at (prev + 0, 80) to (start + 0, 98)
+ = (c3 - c4)
+- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19)
+ = (c3 - c4)
+- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 28)
+ = (c3 - c4)
+- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 21)
= (c3 - (c4 + c5))
-- Code(Expression(12, Sub)) at (prev + 5, 17) to (start + 0, 20)
+- Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 27)
+ = (c3 - (c4 + c5))
+- Code(Expression(13, Sub)) at (prev + 1, 21) to (start + 0, 39)
+ = (c3 - (c4 + c5))
+- Code(Expression(18, Sub)) at (prev + 2, 17) to (start + 0, 20)
= (c3 - (((c4 + c5) + c6) + c7))
-- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 41)
+- Code(Expression(13, Sub)) at (prev + 0, 23) to (start + 0, 29)
+ = (c3 - (c4 + c5))
+- Code(Expression(13, Sub)) at (prev + 0, 30) to (start + 0, 41)
= (c3 - (c4 + c5))
- Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(9, Sub)) at (prev + 0, 67) to (start + 0, 71)
+- Code(Expression(15, Sub)) at (prev + 0, 67) to (start + 0, 71)
= (c3 - ((c4 + c5) + c6))
- Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96)
-- Code(Expression(12, Sub)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Expression(18, Sub)) at (prev + 1, 13) to (start + 0, 23)
= (c3 - (((c4 + c5) + c6) + c7))
-- Code(Expression(19, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(25, Sub)) at (prev + 1, 17) to (start + 0, 20)
= (c16 - (c8 + c9))
-- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 41)
+- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 29)
+- Code(Counter(16)) at (prev + 0, 30) to (start + 0, 41)
- Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(18, Sub)) at (prev + 0, 67) to (start + 0, 71)
+- Code(Expression(24, Sub)) at (prev + 0, 67) to (start + 0, 71)
= (c16 - c8)
- Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97)
-- Code(Expression(19, Sub)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Expression(25, Sub)) at (prev + 1, 13) to (start + 0, 23)
= (c16 - (c8 + c9))
-- Code(Expression(27, Sub)) at (prev + 4, 17) to (start + 0, 20)
+- Code(Expression(34, Sub)) at (prev + 4, 17) to (start + 0, 20)
= (c2 - ((c3 + c10) + c11))
-- Code(Expression(24, Sub)) at (prev + 0, 23) to (start + 0, 41)
+- Code(Expression(31, Sub)) at (prev + 0, 23) to (start + 0, 29)
+ = (c2 - c3)
+- Code(Expression(31, Sub)) at (prev + 0, 30) to (start + 0, 41)
= (c2 - c3)
- Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67)
-- Code(Expression(25, Sub)) at (prev + 0, 68) to (start + 0, 72)
+- Code(Expression(32, Sub)) at (prev + 0, 68) to (start + 0, 72)
= (c2 - (c3 + c10))
- Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98)
-- Code(Expression(27, Sub)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Expression(34, Sub)) at (prev + 1, 13) to (start + 0, 23)
= (c2 - ((c3 + c10) + c11))
-- Code(Expression(33, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20)
= (c17 - (c12 + c13))
-- Code(Counter(17)) at (prev + 0, 23) to (start + 1, 29)
-- Code(Counter(12)) at (prev + 1, 54) to (start + 0, 55)
-- Code(Expression(32, Sub)) at (prev + 1, 18) to (start + 0, 22)
+- Code(Counter(17)) at (prev + 0, 23) to (start + 0, 29)
+- Code(Counter(17)) at (prev + 1, 18) to (start + 0, 29)
+- Code(Counter(12)) at (prev + 0, 54) to (start + 0, 55)
+- Code(Expression(39, Sub)) at (prev + 1, 18) to (start + 0, 22)
= (c17 - c12)
- Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Expression(40, Sub)) at (prev + 1, 13) to (start + 0, 23)
= (c17 - (c12 + c13))
-- Code(Expression(38, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20)
= (c18 - (c14 + c15))
-- Code(Counter(18)) at (prev + 0, 23) to (start + 1, 29)
-- Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18)
-- Code(Expression(37, Sub)) at (prev + 1, 18) to (start + 0, 22)
+- Code(Counter(18)) at (prev + 0, 23) to (start + 0, 29)
+- Code(Counter(18)) at (prev + 1, 18) to (start + 0, 29)
+- Code(Counter(14)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 22)
= (c18 - c14)
- Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 23)
+- Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 23)
= (c18 - (c14 + c15))
-- Code(Expression(40, Sub)) at (prev + 3, 5) to (start + 0, 11)
+- Code(Expression(47, Sub)) at (prev + 3, 5) to (start + 0, 11)
= (c1 - c2)
-- Code(Expression(41, Sub)) at (prev + 1, 1) to (start + 0, 2)
+- Code(Expression(48, Sub)) at (prev + 1, 1) to (start + 0, 2)
= (((((((((((((c1 + c4) + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) - c2)
Highest counter ID seen: c18
diff --git a/tests/coverage/try_error_result.coverage b/tests/coverage/try_error_result.coverage
index 7a89c04..f2ec82f 100644
--- a/tests/coverage/try_error_result.coverage
+++ b/tests/coverage/try_error_result.coverage
@@ -21,8 +21,8 @@
LL| | {
LL| 6| countdown
LL| 6| -= 1
- LL| 6| ;
- LL| 6| if
+ LL| | ;
+ LL| | if
LL| 6| countdown < 5
LL| | {
LL| 1| call(/*return_error=*/ true)?;
@@ -71,19 +71,19 @@
LL| | {
LL| 6| countdown
LL| 6| -= 1
- LL| 6| ;
- LL| 6| if
+ LL| | ;
+ LL| | if
LL| 6| countdown < 5
LL| | {
LL| 1| thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
^0
LL| 1| thing1
- LL| 1| .
+ LL| | .
LL| 1| get_thing_2(/*return_error=*/ false)
LL| 0| ?
LL| | .
LL| 1| call(/*return_error=*/ true)
- LL| 1| .
+ LL| | .
LL| 1| expect_err(
LL| 1| "call should fail"
LL| | );
diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map
index 7ad439549..bbfa8b94 100644
--- a/tests/coverage/unicode.cov-map
+++ b/tests/coverage/unicode.cov-map
@@ -1,12 +1,12 @@
Function name: unicode::main
-Raw bytes (53): 0x[01, 01, 02, 05, 01, 01, 0d, 09, 01, 0e, 01, 00, 0b, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 01, 02]
+Raw bytes (58): 0x[01, 01, 02, 05, 01, 01, 0d, 0a, 01, 0e, 01, 00, 0a, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unicode.rs
Number of expressions: 2
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
- expression 1 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 11)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 10)
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 12)
= (c1 - c0)
- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 27)
@@ -17,24 +17,28 @@
- Code(Counter(3)) at (prev + 0, 71) to (start + 2, 6)
- Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 0, 6)
= (c0 - c3)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
Function name: unicode::他 (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1e, 19, 00, 25]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 1e, 19, 00, 22, 00, 00, 24, 00, 25]
Number of files: 1
- file 0 => $DIR/unicode.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 30, 25) to (start + 0, 37)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 30, 25) to (start + 0, 34)
+- Code(Zero) at (prev + 0, 36) to (start + 0, 37)
Highest counter ID seen: (none)
Function name: unicode::申し訳ございません
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 18, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 18, 01, 00, 29, 01, 01, 05, 00, 19, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unicode.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 24, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/unicode.coverage b/tests/coverage/unicode.coverage
index 4434995..4646cc9 100644
--- a/tests/coverage/unicode.coverage
+++ b/tests/coverage/unicode.coverage
@@ -29,7 +29,7 @@
LL| |
LL| |macro_rules! macro_that_defines_a_function {
LL| | (fn $名:ident () $体:tt) => {
- LL| 0| fn $名 () $体 [0;41mfn 他 () {}[0m
+ LL| [0;35m0[0m| fn $名 () $体 [0;41mfn 他 ()[0m {[0;41m}[0m
LL| | }
LL| |}
LL| |
diff --git a/tests/coverage/unreachable.cov-map b/tests/coverage/unreachable.cov-map
index fd9a1ab..c38786e 100644
--- a/tests/coverage/unreachable.cov-map
+++ b/tests/coverage/unreachable.cov-map
@@ -1,27 +1,29 @@
Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 27, 00, 45]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 30, 00, 45]
Number of files: 1
- file 0 => $DIR/unreachable.rs
Number of expressions: 0
Number of file 0 mappings: 1
-- Code(Zero) at (prev + 14, 39) to (start + 0, 69)
+- Code(Zero) at (prev + 14, 48) to (start + 0, 69)
Highest counter ID seen: (none)
Function name: unreachable::unreachable_function (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 10, 01, 01, 23]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 10, 01, 00, 1a, 00, 01, 0e, 00, 23]
Number of files: 1
- file 0 => $DIR/unreachable.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 16, 1) to (start + 1, 35)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 16, 1) to (start + 0, 26)
+- Code(Zero) at (prev + 1, 14) to (start + 0, 35)
Highest counter ID seen: (none)
Function name: unreachable::unreachable_intrinsic (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 01, 2a]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 15, 01, 00, 1b, 00, 01, 0e, 00, 2a]
Number of files: 1
- file 0 => $DIR/unreachable.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 1) to (start + 1, 42)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 21, 1) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 14) to (start + 0, 42)
Highest counter ID seen: (none)
diff --git a/tests/coverage/unused.cov-map b/tests/coverage/unused.cov-map
index 8946b43..3380997 100644
--- a/tests/coverage/unused.cov-map
+++ b/tests/coverage/unused.cov-map
@@ -1,14 +1,16 @@
Function name: unused::foo::<f32>
-Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
+Raw bytes (50): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 08, 01, 03, 01, 00, 10, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unused.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 17)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 17)
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
= (c1 - c0)
- Code(Expression(1, Sub)) at (prev + 0, 19) to (start + 0, 25)
@@ -19,16 +21,18 @@
Highest counter ID seen: c1
Function name: unused::foo::<u32>
-Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
+Raw bytes (50): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 08, 01, 03, 01, 00, 10, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unused.rs
Number of expressions: 3
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 17)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 17)
- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
= (c1 - c0)
- Code(Expression(1, Sub)) at (prev + 0, 19) to (start + 0, 25)
@@ -39,58 +43,67 @@
Highest counter ID seen: c1
Function name: unused::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 04, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 25, 01, 00, 1c, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unused.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 37, 1) to (start + 4, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: unused::unused_func (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 13, 01, 00, 1b, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unused.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Zero) at (prev + 19, 1) to (start + 1, 14)
-- Code(Zero) at (prev + 1, 15) to (start + 2, 6)
+Number of file 0 mappings: 5
+- Code(Zero) at (prev + 19, 1) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 14)
+- Code(Zero) at (prev + 0, 15) to (start + 2, 6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
Function name: unused::unused_func2 (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 19, 01, 00, 1c, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unused.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Zero) at (prev + 25, 1) to (start + 1, 14)
-- Code(Zero) at (prev + 1, 15) to (start + 2, 6)
+Number of file 0 mappings: 5
+- Code(Zero) at (prev + 25, 1) to (start + 0, 28)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 14)
+- Code(Zero) at (prev + 0, 15) to (start + 2, 6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
Function name: unused::unused_func3 (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 1f, 01, 00, 1c, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unused.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Zero) at (prev + 31, 1) to (start + 1, 14)
-- Code(Zero) at (prev + 1, 15) to (start + 2, 6)
+Number of file 0 mappings: 5
+- Code(Zero) at (prev + 31, 1) to (start + 0, 28)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 14)
+- Code(Zero) at (prev + 0, 15) to (start + 2, 6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
Function name: unused::unused_template_func::<_> (unused)
-Raw bytes (34): 0x[01, 01, 00, 06, 00, 0b, 01, 01, 12, 00, 02, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02]
+Raw bytes (44): 0x[01, 01, 00, 08, 00, 0b, 01, 00, 21, 00, 01, 09, 00, 0e, 00, 00, 11, 00, 12, 00, 01, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unused.rs
Number of expressions: 0
-Number of file 0 mappings: 6
-- Code(Zero) at (prev + 11, 1) to (start + 1, 18)
-- Code(Zero) at (prev + 2, 11) to (start + 0, 17)
+Number of file 0 mappings: 8
+- Code(Zero) at (prev + 11, 1) to (start + 0, 33)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 14)
+- Code(Zero) at (prev + 0, 17) to (start + 0, 18)
+- Code(Zero) at (prev + 1, 11) to (start + 0, 17)
- Code(Zero) at (prev + 1, 9) to (start + 0, 15)
- Code(Zero) at (prev + 0, 19) to (start + 0, 25)
- Code(Zero) at (prev + 1, 9) to (start + 0, 15)
diff --git a/tests/coverage/unused_mod.cov-map b/tests/coverage/unused_mod.cov-map
index 790cd70..ea419ed 100644
--- a/tests/coverage/unused_mod.cov-map
+++ b/tests/coverage/unused_mod.cov-map
@@ -1,18 +1,24 @@
Function name: unused_mod::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 04, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 1c, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/unused_mod.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: unused_mod::unused_module::never_called_function (unused)
-Raw bytes (9): 0x[01, 02, 00, 01, 00, 02, 01, 02, 02]
+Raw bytes (24): 0x[01, 02, 00, 04, 00, 02, 01, 00, 1f, 00, 01, 05, 00, 0d, 00, 00, 0e, 00, 21, 00, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/unused_mod_helper.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 2, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 2, 1) to (start + 0, 31)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 13)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 33)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: (none)
diff --git a/tests/coverage/uses_crate.cov-map b/tests/coverage/uses_crate.cov-map
index 238226f..8f3c63a 100644
--- a/tests/coverage/uses_crate.cov-map
+++ b/tests/coverage/uses_crate.cov-map
@@ -1,45 +1,67 @@
Function name: used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1b, 01, 00, 4c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 4f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 27, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 76)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 79)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 13, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: used_crate::used_only_from_bin_crate_generic_function::<&str>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 13, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 00, 5b, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 5e, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 91)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 94)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: uses_crate::main
-Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 07, 02]
+Raw bytes (59): 0x[01, 02, 00, 0b, 01, 0c, 01, 00, 0a, 01, 01, 05, 00, 1e, 01, 01, 09, 00, 11, 01, 00, 14, 00, 18, 01, 01, 05, 00, 3a, 01, 00, 3b, 00, 44, 01, 01, 05, 00, 3a, 01, 01, 05, 00, 43, 01, 00, 44, 00, 4c, 01, 01, 05, 00, 52, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/uses_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 1) to (start + 7, 2)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 58)
+- Code(Counter(0)) at (prev + 0, 59) to (start + 0, 68)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 58)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 0, 68) to (start + 0, 76)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 82)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/uses_crate.coverage b/tests/coverage/uses_crate.coverage
index d1b0dad..145c064 100644
--- a/tests/coverage/uses_crate.coverage
+++ b/tests/coverage/uses_crate.coverage
@@ -6,9 +6,9 @@
LL| |use std::fmt::Debug;
LL| |
LL| 1|pub fn used_function() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
LL| 1| let mut countdown = 0;
LL| 1| if is_true {
@@ -104,8 +104,8 @@
LL| 1|fn use_this_lib_crate() {
LL| 1| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
LL| 1| used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
- LL| 1| "used from library used_crate.rs",
- LL| 1| );
+ LL| | "used from library used_crate.rs",
+ LL| | );
LL| 1| let some_vec = vec![5, 6, 7, 8];
LL| 1| used_only_from_this_lib_crate_generic_function(some_vec);
LL| 1| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
diff --git a/tests/coverage/uses_inline_crate.cov-map b/tests/coverage/uses_inline_crate.cov-map
index fd14ea3..52f3f94 100644
--- a/tests/coverage/uses_inline_crate.cov-map
+++ b/tests/coverage/uses_inline_crate.cov-map
@@ -1,59 +1,88 @@
Function name: used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 2c, 01, 00, 4c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 4f, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_inline_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 44, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 76)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 79)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: used_inline_crate::used_inline_function
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 14, 01, 06, 0f, 05, 06, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 01, 02]
+Raw bytes (56): 0x[01, 01, 01, 01, 05, 0a, 01, 14, 01, 00, 1e, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 00, 17, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_inline_crate.rs
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 20, 1) to (start + 6, 15)
-- Code(Counter(1)) at (prev + 6, 16) to (start + 2, 6)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 20, 1) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
= (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_inline_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&str>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_inline_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 31, 01, 00, 5b, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 5e, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/auxiliary/used_inline_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 49, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 91)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 94)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c0
Function name: uses_inline_crate::main
-Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 0a, 02]
+Raw bytes (64): 0x[01, 02, 00, 0c, 01, 0c, 01, 00, 0a, 01, 01, 05, 00, 25, 01, 01, 05, 00, 2c, 01, 01, 09, 00, 11, 01, 00, 14, 00, 18, 01, 01, 05, 00, 41, 01, 00, 42, 00, 4b, 01, 01, 05, 00, 41, 01, 01, 05, 00, 4a, 01, 00, 4b, 00, 53, 01, 01, 05, 00, 59, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/uses_inline_crate.rs
Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 1) to (start + 10, 2)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 65)
+- Code(Counter(0)) at (prev + 0, 66) to (start + 0, 75)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 65)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 74)
+- Code(Counter(0)) at (prev + 0, 75) to (start + 0, 83)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 89)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/uses_inline_crate.coverage b/tests/coverage/uses_inline_crate.coverage
index 4671c95..15084bc 100644
--- a/tests/coverage/uses_inline_crate.coverage
+++ b/tests/coverage/uses_inline_crate.coverage
@@ -6,9 +6,9 @@
LL| |use std::fmt::Debug;
LL| |
LL| 1|pub fn used_function() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
LL| 1| let mut countdown = 0;
LL| 1| if is_true {
@@ -20,9 +20,9 @@
LL| |
LL| |#[inline(always)]
LL| 1|pub fn used_inline_function() {
- LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure
- LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
- LL| 1| // dependent conditions.
+ LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure
+ LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+ LL| | // dependent conditions.
LL| 1| let is_true = std::env::args().len() == 1;
LL| 1| let mut countdown = 0;
LL| 1| if is_true {
@@ -126,8 +126,8 @@
LL| 2|fn use_this_lib_crate() {
LL| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
LL| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
- LL| 2| "used from library used_crate.rs",
- LL| 2| );
+ LL| | "used from library used_crate.rs",
+ LL| | );
LL| 2| let some_vec = vec![5, 6, 7, 8];
LL| 2| used_only_from_this_lib_crate_generic_function(some_vec);
LL| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
@@ -153,7 +153,7 @@
LL| 1| used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
LL| 1| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
LL| 1| used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
- LL| 1| "interesting?",
- LL| 1| );
+ LL| | "interesting?",
+ LL| | );
LL| 1|}
diff --git a/tests/coverage/while.cov-map b/tests/coverage/while.cov-map
index 8ad7392..c4183e1 100644
--- a/tests/coverage/while.cov-map
+++ b/tests/coverage/while.cov-map
@@ -1,11 +1,13 @@
Function name: while::main
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 01, 01, 01, 10, 01, 02, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 10, 01, 01, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/while.rs
Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 1, 1) to (start + 1, 16)
-- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 20)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 20)
- Code(Zero) at (prev + 0, 21) to (start + 2, 6)
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c0
diff --git a/tests/coverage/while_early_ret.cov-map b/tests/coverage/while_early_ret.cov-map
index 6e3db66..b29b5d4 100644
--- a/tests/coverage/while_early_ret.cov-map
+++ b/tests/coverage/while_early_ret.cov-map
@@ -1,27 +1,32 @@
Function name: while_early_ret::main
-Raw bytes (63): 0x[01, 01, 07, 0f, 05, 01, 09, 0f, 13, 01, 09, 05, 0d, 05, 01, 05, 09, 09, 01, 05, 01, 01, 1b, 05, 03, 09, 02, 0a, 09, 05, 0d, 02, 0e, 02, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0a, 04, 15, 00, 1b, 16, 03, 0a, 03, 0a, 1a, 06, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (80): 0x[01, 01, 08, 0f, 05, 01, 09, 0f, 13, 01, 09, 05, 0d, 05, 01, 05, 01, 05, 09, 0c, 01, 05, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 09, 02, 0a, 09, 05, 0d, 02, 0e, 02, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0a, 04, 15, 00, 1b, 1a, 03, 09, 00, 0a, 1a, 01, 09, 02, 0a, 1e, 05, 05, 00, 0b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/while_early_ret.rs
-Number of expressions: 7
+Number of expressions: 8
- expression 0 operands: lhs = Expression(3, Add), rhs = Counter(1)
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
- expression 2 operands: lhs = Expression(3, Add), rhs = Expression(4, Add)
- expression 3 operands: lhs = Counter(0), rhs = Counter(2)
- expression 4 operands: lhs = Counter(1), rhs = Counter(3)
- expression 5 operands: lhs = Counter(1), rhs = Counter(0)
-- expression 6 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 2, 10)
+- expression 6 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 2, 9) to (start + 2, 10)
- Code(Counter(2)) at (prev + 5, 13) to (start + 2, 14)
- Code(Expression(0, Sub)) at (prev + 6, 21) to (start + 2, 22)
= ((c0 + c2) - c1)
- Code(Counter(3)) at (prev + 4, 21) to (start + 0, 27)
- Code(Expression(2, Sub)) at (prev + 4, 21) to (start + 0, 27)
= ((c0 + c2) - (c1 + c3))
-- Code(Expression(5, Sub)) at (prev + 3, 10) to (start + 3, 10)
+- Code(Expression(6, Sub)) at (prev + 3, 9) to (start + 0, 10)
= (c1 - c0)
-- Code(Expression(6, Sub)) at (prev + 6, 5) to (start + 0, 11)
+- Code(Expression(6, Sub)) at (prev + 1, 9) to (start + 2, 10)
+ = (c1 - c0)
+- Code(Expression(7, Sub)) at (prev + 5, 5) to (start + 0, 11)
= (c1 - c2)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c3
diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map
index db82c9d..87d0a04 100644
--- a/tests/coverage/yield.cov-map
+++ b/tests/coverage/yield.cov-map
@@ -1,5 +1,5 @@
Function name: yield::main
-Raw bytes (94): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 2e, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 14, 11, 02, 0b, 00, 2e, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 14, 12, 02, 01, 00, 02]
+Raw bytes (139): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 19, 01, 07, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 06, 0b, 00, 13, 01, 00, 0b, 00, 2e, 01, 00, 14, 00, 22, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 13, 05, 00, 0b, 00, 2e, 05, 00, 14, 00, 22, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 13, 09, 00, 0b, 00, 2e, 09, 00, 14, 00, 22, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 14, 11, 02, 0b, 00, 13, 11, 00, 0b, 00, 2e, 11, 00, 14, 00, 22, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 14, 12, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/yield.rs
Number of expressions: 5
@@ -8,23 +8,32 @@
- expression 2 operands: lhs = Counter(2), rhs = Counter(4)
- expression 3 operands: lhs = Counter(4), rhs = Counter(5)
- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
-Number of file 0 mappings: 16
-- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 22)
-- Code(Counter(0)) at (prev + 7, 11) to (start + 0, 46)
+Number of file 0 mappings: 25
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 6, 11) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 34)
- Code(Counter(1)) at (prev + 1, 39) to (start + 0, 41)
- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 20)
= (c0 - c1)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 19)
+- Code(Counter(1)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 0, 20) to (start + 0, 34)
- Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39)
- Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46)
- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 20)
= (c1 - c2)
- Code(Counter(2)) at (prev + 3, 9) to (start + 0, 22)
-- Code(Counter(2)) at (prev + 8, 11) to (start + 0, 46)
+- Code(Counter(2)) at (prev + 8, 11) to (start + 0, 19)
+- Code(Counter(2)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(2)) at (prev + 0, 20) to (start + 0, 34)
- Code(Counter(4)) at (prev + 1, 39) to (start + 0, 41)
- Code(Expression(2, Sub)) at (prev + 1, 14) to (start + 0, 20)
= (c2 - c4)
-- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 19)
+- Code(Counter(4)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(4)) at (prev + 0, 20) to (start + 0, 34)
- Code(Expression(4, Sub)) at (prev + 1, 39) to (start + 0, 41)
= (c4 - c5)
- Code(Counter(5)) at (prev + 1, 14) to (start + 0, 20)
@@ -33,24 +42,28 @@
Highest counter ID seen: c5
Function name: yield::main::{closure#0}
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 09, 08, 01, 10, 05, 02, 10, 01, 06]
-Number of files: 1
-- file 0 => $DIR/yield.rs
-Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 9, 8) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 2, 16) to (start + 1, 6)
-Highest counter ID seen: c1
-
-Function name: yield::main::{closure#1}
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 08, 01, 10, 05, 02, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 01, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 08, 00, 09, 01, 01, 09, 00, 10, 05, 01, 10, 00, 15, 05, 01, 05, 00, 06]
Number of files: 1
- file 0 => $DIR/yield.rs
Number of expressions: 0
Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 24, 8) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 9, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 16) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c1
+
+Function name: yield::main::{closure#1}
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 18, 08, 00, 09, 01, 01, 09, 00, 10, 05, 01, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 00, 15, 0d, 01, 05, 00, 06]
+Number of files: 1
+- file 0 => $DIR/yield.rs
+Number of expressions: 0
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 24, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16)
- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 16)
-- Code(Counter(3)) at (prev + 1, 16) to (start + 1, 6)
+- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 21)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 6)
Highest counter ID seen: c3
diff --git a/tests/debuginfo/step-into-match.rs b/tests/debuginfo/step-into-match.rs
index 577e553..d4b7ea2 100644
--- a/tests/debuginfo/step-into-match.rs
+++ b/tests/debuginfo/step-into-match.rs
@@ -1,6 +1,10 @@
//@ compile-flags: -g
//@ ignore-android: FIXME(#10381)
+// On Arm64 Windows, stepping at the end of a function on goes to the callsite, not the instruction
+// after it.
+//@ ignore-aarch64-pc-windows-msvc: Stepping out of functions behaves differently.
+
// === GDB TESTS ==============================================================
// gdb-command: r
diff --git a/tests/debuginfo/type-names.rs b/tests/debuginfo/type-names.rs
index 4df6daf..3c7eab7 100644
--- a/tests/debuginfo/type-names.rs
+++ b/tests/debuginfo/type-names.rs
@@ -1,5 +1,7 @@
//@ ignore-lldb
+//@ ignore-aarch64-pc-windows-msvc: Arm64 Windows cdb doesn't support JavaScript extensions.
+
// GDB changed the way that it formatted Foreign types
//@ min-gdb-version: 9.2
diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
index 542b70b..d465b8b 100644
--- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
@@ -26,11 +26,20 @@
debug a => _9;
}
-+ coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 15:21 (#0);
-+ coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:32 (#0);
-+ coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:32 (#0);
-+ coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:32 (#0);
-+ coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:32 (#0);
++ coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 14:10 (#0);
++ coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:15:11: 15:21 (#0);
++ coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:18 (#0);
++ coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:23: 16:30 (#0);
++ coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:31: 16:32 (#0);
++ coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:18 (#0);
++ coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:23: 17:30 (#0);
++ coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:31: 17:32 (#0);
++ coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:18 (#0);
++ coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:23: 18:30 (#0);
++ coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:31: 18:32 (#0);
++ coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:18 (#0);
++ coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:23: 19:30 (#0);
++ coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:31: 19:32 (#0);
+ coverage Code { bcb: bcb2 } => $DIR/branch_match_arms.rs:21:2: 21:2 (#0);
+
bb0: {
diff --git a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
index 06e5f01..cf6d85a 100644
--- a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
@@ -4,7 +4,9 @@
fn bar() -> bool {
let mut _0: bool;
-+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:27:1: 29:2 (#0);
++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:27:1: 27:17 (#0);
++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:28:5: 28:9 (#0);
++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:29:2: 29:2 (#0);
+
bb0: {
+ Coverage::VirtualCounter(bcb0);
diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
index 30de92f..980c5e2 100644
--- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
@@ -7,7 +7,7 @@
let mut _2: bool;
let mut _3: !;
-+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:11 (#0);
++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:10 (#0);
+ coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:15:12: 15:15 (#0);
+ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:16:13: 16:18 (#0);
+ coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:17:10: 17:10 (#0);
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
index 1a22ade..b707cd4 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
@@ -7,7 +7,8 @@
coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
- coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 13:10 (#0);
+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
index b77969a..239b845 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
@@ -7,7 +7,8 @@
coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
-+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 13:10 (#0);
++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
+ coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
+ coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
+ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
diff --git a/tests/run-make/arm64ec-import-export-static/export.rs b/tests/run-make/arm64ec-import-export-static/export.rs
new file mode 100644
index 0000000..98b3a66
--- /dev/null
+++ b/tests/run-make/arm64ec-import-export-static/export.rs
@@ -0,0 +1,23 @@
+#![crate_type = "dylib"]
+#![allow(internal_features)]
+#![feature(no_core, lang_items)]
+#![no_core]
+#![no_std]
+
+// This is needed because of #![no_core]:
+#[lang = "sized"]
+trait Sized {}
+#[lang = "sync"]
+trait Sync {}
+impl Sync for i32 {}
+#[lang = "copy"]
+pub trait Copy {}
+impl Copy for i32 {}
+#[lang = "drop_in_place"]
+pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}
+#[no_mangle]
+extern "system" fn _DllMainCRTStartup(_: *const u8, _: u32, _: *const u8) -> u32 {
+ 1
+}
+
+pub static VALUE: i32 = 42;
diff --git a/tests/run-make/arm64ec-import-export-static/import.rs b/tests/run-make/arm64ec-import-export-static/import.rs
new file mode 100644
index 0000000..9d52db2
--- /dev/null
+++ b/tests/run-make/arm64ec-import-export-static/import.rs
@@ -0,0 +1,12 @@
+#![crate_type = "cdylib"]
+#![allow(internal_features)]
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+extern crate export;
+
+#[no_mangle]
+pub extern "C" fn func() -> i32 {
+ export::VALUE
+}
diff --git a/tests/run-make/arm64ec-import-export-static/rmake.rs b/tests/run-make/arm64ec-import-export-static/rmake.rs
new file mode 100644
index 0000000..7fa3114
--- /dev/null
+++ b/tests/run-make/arm64ec-import-export-static/rmake.rs
@@ -0,0 +1,15 @@
+// Test that a static can be exported from one crate and imported into another.
+//
+// This was broken for Arm64EC as only functions, not variables, should be
+// decorated with `#`.
+// See https://github.com/rust-lang/rust/issues/138541
+
+//@ needs-llvm-components: aarch64
+//@ only-windows
+
+use run_make_support::rustc;
+
+fn main() {
+ rustc().input("export.rs").target("aarch64-pc-windows-msvc").panic("abort").run();
+ rustc().input("import.rs").target("aarch64-pc-windows-msvc").panic("abort").run();
+}
diff --git a/tests/run-make/broken-pipe-no-ice/rmake.rs b/tests/run-make/broken-pipe-no-ice/rmake.rs
index 0521b39..b0a28b6 100644
--- a/tests/run-make/broken-pipe-no-ice/rmake.rs
+++ b/tests/run-make/broken-pipe-no-ice/rmake.rs
@@ -14,7 +14,7 @@
use std::io::Read;
use std::process::{Command, Stdio};
-use run_make_support::env_var;
+use run_make_support::{bare_rustc, rustdoc};
#[derive(Debug, PartialEq)]
enum Binary {
@@ -67,11 +67,13 @@ fn check_broken_pipe_handled_gracefully(bin: Binary, mut cmd: Command) {
}
fn main() {
- let mut rustc = Command::new(env_var("RUSTC"));
+ let mut rustc = bare_rustc();
rustc.arg("--print=sysroot");
+ let rustc = rustc.into_raw_command();
check_broken_pipe_handled_gracefully(Binary::Rustc, rustc);
- let mut rustdoc = Command::new(env_var("RUSTDOC"));
+ let mut rustdoc = rustdoc();
rustdoc.arg("--version");
+ let rustdoc = rustdoc.into_raw_command();
check_broken_pipe_handled_gracefully(Binary::Rustdoc, rustdoc);
}
diff --git a/tests/run-make/pointer-auth-link-with-c/test.rs b/tests/run-make/pointer-auth-link-with-c/test.rs
index 1a3be80..795c6a4 100644
--- a/tests/run-make/pointer-auth-link-with-c/test.rs
+++ b/tests/run-make/pointer-auth-link-with-c/test.rs
@@ -1,4 +1,4 @@
-#[link(name = "test")]
+#[link(name = "test", kind = "static")]
extern "C" {
fn foo() -> i32;
}
diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout
index 78ca8c8..506f135 100644
--- a/tests/run-make/rustdoc-default-output/output-default.stdout
+++ b/tests/run-make/rustdoc-default-output/output-default.stdout
@@ -188,8 +188,9 @@
from provided path. Only use with --merge=finalize
--html-no-source
Disable HTML source code pages generation
- --doctest-compilation-args add arguments to be used when compiling doctests
-
+ --doctest-build-arg ARG
+ One argument (of possibly many) to be used when
+ compiling doctests
--disable-minification
disable the minification of CSS/JS files
(perma-unstable, do not use with cached files)
diff --git a/tests/run-make/rustdoc-tempdir-removal/compile-error.rs b/tests/run-make/rustdoc-tempdir-removal/compile-error.rs
new file mode 100644
index 0000000..66a3b3f
--- /dev/null
+++ b/tests/run-make/rustdoc-tempdir-removal/compile-error.rs
@@ -0,0 +1,5 @@
+#![doc(test(attr(deny(warnings))))]
+
+//! ```
+//! let a = 12;
+//! ```
diff --git a/tests/run-make/rustdoc-tempdir-removal/rmake.rs b/tests/run-make/rustdoc-tempdir-removal/rmake.rs
new file mode 100644
index 0000000..9ad369a
--- /dev/null
+++ b/tests/run-make/rustdoc-tempdir-removal/rmake.rs
@@ -0,0 +1,42 @@
+// This test ensures that no temporary folder is "left behind" when doctests fail for any reason.
+
+//@ ignore-cross-compile
+
+use std::path::Path;
+
+use run_make_support::{path, rfs, rustdoc};
+
+fn run_doctest_and_check_tmpdir(tmp_dir: &Path, doctest: &str, edition: &str) {
+ let mut runner = rustdoc();
+ runner.input(doctest).arg("--test").edition(edition);
+ let output = if cfg!(unix) {
+ runner.env("TMPDIR", tmp_dir)
+ } else if cfg!(windows) {
+ runner.env("TEMP", tmp_dir).env("TMP", tmp_dir)
+ } else {
+ panic!("unsupported OS")
+ }
+ .run_fail();
+
+ output.assert_exit_code(101).assert_stdout_contains(
+ "test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out",
+ );
+
+ rfs::read_dir_entries(tmp_dir, |entry| {
+ panic!("Found an item inside the temporary folder: {entry:?}");
+ });
+}
+
+fn run_doctest_and_check_tmpdir_for_edition(tmp_dir: &Path, edition: &str) {
+ run_doctest_and_check_tmpdir(tmp_dir, "compile-error.rs", edition);
+ run_doctest_and_check_tmpdir(tmp_dir, "run-error.rs", edition);
+}
+
+fn main() {
+ let tmp_dir = path("tmp");
+ rfs::create_dir(&tmp_dir);
+
+ run_doctest_and_check_tmpdir_for_edition(&tmp_dir, "2018");
+ // We use the 2024 edition to check that it's also working for merged doctests.
+ run_doctest_and_check_tmpdir_for_edition(&tmp_dir, "2024");
+}
diff --git a/tests/run-make/rustdoc-tempdir-removal/run-error.rs b/tests/run-make/rustdoc-tempdir-removal/run-error.rs
new file mode 100644
index 0000000..4ac95f6
--- /dev/null
+++ b/tests/run-make/rustdoc-tempdir-removal/run-error.rs
@@ -0,0 +1,3 @@
+//! ```
+//! panic!();
+//! ```
diff --git a/tests/run-make/sanitizer-dylib-link/program.rs b/tests/run-make/sanitizer-dylib-link/program.rs
index 1026c7f..dbf885d3 100644
--- a/tests/run-make/sanitizer-dylib-link/program.rs
+++ b/tests/run-make/sanitizer-dylib-link/program.rs
@@ -1,4 +1,4 @@
-#[cfg_attr(windows, link(name = "library.dll.lib", modifiers = "+verbatim"))]
+#[cfg_attr(windows, link(name = "library", kind = "raw-dylib"))]
#[cfg_attr(not(windows), link(name = "library"))]
extern "C" {
fn overflow();
diff --git a/tests/rustdoc-json/attrs/automatically_derived.rs b/tests/rustdoc-json/attrs/automatically_derived.rs
index 6c90d63..4e1ab3d 100644
--- a/tests/rustdoc-json/attrs/automatically_derived.rs
+++ b/tests/rustdoc-json/attrs/automatically_derived.rs
@@ -9,5 +9,5 @@ fn default() -> Self {
}
}
-//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]\n"]'
+//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]"]'
//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Manual" && @.inner.impl.trait.path == "Default")].attrs' '[]'
diff --git a/tests/rustdoc-json/attrs/export_name_2021.rs b/tests/rustdoc-json/attrs/export_name_2021.rs
index 4e65264..254e9f6 100644
--- a/tests/rustdoc-json/attrs/export_name_2021.rs
+++ b/tests/rustdoc-json/attrs/export_name_2021.rs
@@ -1,6 +1,6 @@
//@ edition: 2021
#![no_std]
-//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]\n"]'
+//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]'
#[export_name = "altered"]
pub extern "C" fn example() {}
diff --git a/tests/rustdoc-json/attrs/export_name_2024.rs b/tests/rustdoc-json/attrs/export_name_2024.rs
index f6a2a92..8129c10 100644
--- a/tests/rustdoc-json/attrs/export_name_2024.rs
+++ b/tests/rustdoc-json/attrs/export_name_2024.rs
@@ -4,6 +4,6 @@
// The representation of `#[unsafe(export_name = ..)]` in rustdoc in edition 2024
// is still `#[export_name = ..]` without the `unsafe` attribute wrapper.
-//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]\n"]'
+//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]'
#[unsafe(export_name = "altered")]
pub extern "C" fn example() {}
diff --git a/tests/rustdoc-json/attrs/must_use.rs b/tests/rustdoc-json/attrs/must_use.rs
index 20696dc..64df8e5 100644
--- a/tests/rustdoc-json/attrs/must_use.rs
+++ b/tests/rustdoc-json/attrs/must_use.rs
@@ -1,9 +1,9 @@
#![no_std]
-//@ is "$.index[?(@.name=='example')].attrs" '["#[must_use]\n"]'
+//@ is "$.index[?(@.name=='example')].attrs" '["#[must_use]"]'
#[must_use]
pub fn example() -> impl Iterator<Item = i64> {}
-//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]\n"]'
+//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]"]'
#[must_use = "does nothing if you do not use it"]
pub fn explicit_message() -> impl Iterator<Item = i64> {}
diff --git a/tests/rustdoc-json/attrs/no_mangle_2021.rs b/tests/rustdoc-json/attrs/no_mangle_2021.rs
index 10a3725..588be72 100644
--- a/tests/rustdoc-json/attrs/no_mangle_2021.rs
+++ b/tests/rustdoc-json/attrs/no_mangle_2021.rs
@@ -1,6 +1,6 @@
//@ edition: 2021
#![no_std]
-//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]\n"]'
+//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]'
#[no_mangle]
pub extern "C" fn example() {}
diff --git a/tests/rustdoc-json/attrs/no_mangle_2024.rs b/tests/rustdoc-json/attrs/no_mangle_2024.rs
index 8f3a14c..0d500e2 100644
--- a/tests/rustdoc-json/attrs/no_mangle_2024.rs
+++ b/tests/rustdoc-json/attrs/no_mangle_2024.rs
@@ -4,6 +4,6 @@
// The representation of `#[unsafe(no_mangle)]` in rustdoc in edition 2024
// is still `#[no_mangle]` without the `unsafe` attribute wrapper.
-//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]\n"]'
+//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]'
#[unsafe(no_mangle)]
pub extern "C" fn example() {}
diff --git a/tests/rustdoc-json/attrs/non_exhaustive.rs b/tests/rustdoc-json/attrs/non_exhaustive.rs
index 3064b86..b95f1a8 100644
--- a/tests/rustdoc-json/attrs/non_exhaustive.rs
+++ b/tests/rustdoc-json/attrs/non_exhaustive.rs
@@ -1,18 +1,18 @@
#![no_std]
-//@ is "$.index[?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]\n"]'
+//@ is "$.index[?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]"]'
#[non_exhaustive]
pub enum MyEnum {
First,
}
pub enum NonExhaustiveVariant {
- //@ is "$.index[?(@.name=='Variant')].attrs" '["#[non_exhaustive]\n"]'
+ //@ is "$.index[?(@.name=='Variant')].attrs" '["#[non_exhaustive]"]'
#[non_exhaustive]
Variant(i64),
}
-//@ is "$.index[?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]\n"]'
+//@ is "$.index[?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]"]'
#[non_exhaustive]
pub struct MyStruct {
pub x: i64,
diff --git a/tests/rustdoc-json/keyword_private.rs b/tests/rustdoc-json/keyword_private.rs
index 5e9a2c1..fea546c 100644
--- a/tests/rustdoc-json/keyword_private.rs
+++ b/tests/rustdoc-json/keyword_private.rs
@@ -5,7 +5,7 @@
//@ !has "$.index[?(@.name=='match')]"
//@ has "$.index[?(@.name=='foo')]"
-//@ is "$.index[?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]\n"]'
+//@ is "$.index[?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]"]'
//@ is "$.index[?(@.name=='foo')].docs" '"this is a test!"'
#[doc(keyword = "match")]
/// this is a test!
@@ -13,7 +13,7 @@ pub mod foo {}
//@ !has "$.index[?(@.name=='break')]"
//@ has "$.index[?(@.name=='bar')]"
-//@ is "$.index[?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]\n"]'
+//@ is "$.index[?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]"]'
//@ is "$.index[?(@.name=='bar')].docs" '"hello"'
#[doc(keyword = "break")]
/// hello
diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs
index 8d8c60e..88e2e0c 100644
--- a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs
+++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs
@@ -1,9 +1,8 @@
-// This test checks that the test behave when `--doctest-compilation-args` is passed
-// multiple times.
+// This test checks that the test behave when `--doctest-build-arg` is passed multiple times.
//@ check-pass
-//@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present
-//@ compile-flags: --doctest-compilation-args=--cfg=another
+//@ compile-flags: --test -Zunstable-options --doctest-build-arg=--cfg=testcase_must_be_present
+//@ compile-flags: --doctest-build-arg=--cfg=another
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout b/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout
index 0e8a9e1..f6b8ad6 100644
--- a/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout
+++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout
@@ -1,6 +1,6 @@
running 1 test
-test $DIR/rustflags-multiple-args.rs - Bar (line 10) ... ok
+test $DIR/rustflags-multiple-args.rs - Bar (line 9) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
diff --git a/tests/rustdoc-ui/doctest/rustflags.rs b/tests/rustdoc-ui/doctest/rustflags.rs
index 9f1e601..f030158 100644
--- a/tests/rustdoc-ui/doctest/rustflags.rs
+++ b/tests/rustdoc-ui/doctest/rustflags.rs
@@ -1,5 +1,5 @@
//@ check-pass
-//@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present
+//@ compile-flags: --test -Zunstable-options --doctest-build-arg=--cfg=testcase_must_be_present
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
diff --git a/tests/rustdoc-ui/unportable-markdown.rs b/tests/rustdoc-ui/unportable-markdown.rs
deleted file mode 100644
index 105fc1e..0000000
--- a/tests/rustdoc-ui/unportable-markdown.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-// https://internals.rust-lang.org/t/proposal-migrate-the-syntax-of-rustdoc-markdown-footnotes-to-be-compatible-with-the-syntax-used-in-github/18929
-//
-// A series of test cases for CommonMark corner cases that pulldown-cmark 0.11 fixes.
-//
-// This version of the lint is targeted at two especially-common cases where docs got broken.
-// Other differences in parsing should not warn.
-#![allow(rustdoc::broken_intra_doc_links)]
-#![deny(rustdoc::unportable_markdown)]
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/654>
-///
-/// Test footnote [^foot].
-///
-/// [^foot]: This is nested within the footnote now, but didn't used to be.
-///
-/// This is a multi-paragraph footnote.
-pub struct GfmFootnotes;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/773>
-///
-/// test [^foo][^bar]
-///
-/// [^foo]: test
-/// [^bar]: test2
-pub struct FootnoteSmashedName;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/829>
-///
-/// - _t
-/// # test
-/// t_
-pub struct NestingCornerCase;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/650>
-///
-/// *~~__emphasis strike strong__~~* ~~*__strike emphasis strong__*~~
-pub struct Emphasis1;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/732>
-///
-/// |
-/// |
-pub struct NotEnoughTable;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/675>
-///
-/// foo
-/// >bar
-//~^ ERROR unportable markdown
-pub struct BlockQuoteNoSpace;
-
-/// Negative test.
-///
-/// foo
-/// > bar
-pub struct BlockQuoteSpace;
-
-/// Negative test.
-///
-/// >bar
-/// baz
-pub struct BlockQuoteNoSpaceStart;
diff --git a/tests/rustdoc-ui/unportable-markdown.stderr b/tests/rustdoc-ui/unportable-markdown.stderr
deleted file mode 100644
index 952ae4b..0000000
--- a/tests/rustdoc-ui/unportable-markdown.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error: unportable markdown
- --> $DIR/unportable-markdown.rs:48:5
- |
-LL | /// >bar
- | ^
- |
- = help: confusing block quote with no space after the `>` marker
-note: the lint level is defined here
- --> $DIR/unportable-markdown.rs:8:9
- |
-LL | #![deny(rustdoc::unportable_markdown)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: if the quote is intended, add a space
- |
-LL | /// > bar
- | +
-help: if it should not be a quote, escape it
- |
-LL | /// \>bar
- | +
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs
index 141ad5b..7c0378e 100644
--- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs
+++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs
@@ -17,11 +17,11 @@ pub trait Foo<'a, 't> {
impl<'a, 't> Foo<'a, 't> for &'a isize {
fn no_bound<'b:'a>(self, b: Inv<'b>) {
- //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match
+ //~^ ERROR lifetime parameters do not match the trait definition
}
fn has_bound<'b>(self, b: Inv<'b>) {
- //~^ ERROR lifetime parameters or bounds on method `has_bound` do not match
+ //~^ ERROR lifetime parameters do not match the trait definition
}
fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
@@ -40,7 +40,7 @@ fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
}
fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
- //~^ ERROR lifetime parameters or bounds on method `wrong_bound2` do not match the trait
+ //~^ ERROR lifetime parameters do not match the trait definition
}
fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
index 5f0347b..207ca57 100644
--- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
+++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
@@ -1,20 +1,48 @@
-error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration
- --> $DIR/regions-bound-missing-bound-in-impl.rs:19:16
+error[E0195]: lifetime parameters do not match the trait definition
+ --> $DIR/regions-bound-missing-bound-in-impl.rs:19:17
|
-LL | fn no_bound<'b>(self, b: Inv<'b>);
- | ---- lifetimes in impl do not match this method in trait
-...
LL | fn no_bound<'b:'a>(self, b: Inv<'b>) {
- | ^^^^^^^ lifetimes do not match method in trait
-
-error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration
- --> $DIR/regions-bound-missing-bound-in-impl.rs:23:17
+ | ^^
|
+ = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'b` differs between the trait and impl
+ --> $DIR/regions-bound-missing-bound-in-impl.rs:10:17
+ |
+LL | pub trait Foo<'a, 't> {
+ | --------------------- in this trait...
+LL | fn no_bound<'b>(self, b: Inv<'b>);
+ | ^^ `'b` is late-bound
+...
+LL | impl<'a, 't> Foo<'a, 't> for &'a isize {
+ | -------------------------------------- in this impl...
+LL | fn no_bound<'b:'a>(self, b: Inv<'b>) {
+ | ^^ -- this lifetime bound makes `'b` early-bound
+ | |
+ | `'b` is early-bound
+
+error[E0195]: lifetime parameters do not match the trait definition
+ --> $DIR/regions-bound-missing-bound-in-impl.rs:23:18
+ |
+LL | fn has_bound<'b>(self, b: Inv<'b>) {
+ | ^^
+ |
+ = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'b` differs between the trait and impl
+ --> $DIR/regions-bound-missing-bound-in-impl.rs:11:18
+ |
+LL | pub trait Foo<'a, 't> {
+ | --------------------- in this trait...
+LL | fn no_bound<'b>(self, b: Inv<'b>);
LL | fn has_bound<'b:'a>(self, b: Inv<'b>);
- | ------- lifetimes in impl do not match this method in trait
+ | ^^ -- this lifetime bound makes `'b` early-bound
+ | |
+ | `'b` is early-bound
+...
+LL | impl<'a, 't> Foo<'a, 't> for &'a isize {
+ | -------------------------------------- in this impl...
...
LL | fn has_bound<'b>(self, b: Inv<'b>) {
- | ^^^^ lifetimes do not match method in trait
+ | ^^ `'b` is late-bound
error[E0308]: method not compatible with trait
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:5
@@ -54,14 +82,45 @@
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
| ^^
-error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration
- --> $DIR/regions-bound-missing-bound-in-impl.rs:42:20
+error[E0195]: lifetime parameters do not match the trait definition
+ --> $DIR/regions-bound-missing-bound-in-impl.rs:42:30
|
+LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
+ | ^^^ ^^^
+ |
+ = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'_` differs between the trait and impl
+ --> $DIR/regions-bound-missing-bound-in-impl.rs:13:21
+ |
+LL | pub trait Foo<'a, 't> {
+ | --------------------- in this trait...
+...
LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
- | ---------------- lifetimes in impl do not match this method in trait
+ | ^^ -- this lifetime bound makes `'b` early-bound
+ | |
+ | `'b` is early-bound
+...
+LL | impl<'a, 't> Foo<'a, 't> for &'a isize {
+ | -------------------------------------- in this impl...
...
LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
- | ^ lifetimes do not match method in trait
+ | ^^^ `'_` is late-bound
+note: `'_` differs between the trait and impl
+ --> $DIR/regions-bound-missing-bound-in-impl.rs:13:27
+ |
+LL | pub trait Foo<'a, 't> {
+ | --------------------- in this trait...
+...
+LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
+ | ^^ -- this lifetime bound makes `'d` early-bound
+ | |
+ | `'d` is early-bound
+...
+LL | impl<'a, 't> Foo<'a, 't> for &'a isize {
+ | -------------------------------------- in this impl...
+...
+LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
+ | ^^^ `'_` is late-bound
error[E0276]: impl has stricter requirements than trait
--> $DIR/regions-bound-missing-bound-in-impl.rs:49:26
diff --git a/tests/ui/cast/cast-alias-of-array-to-element.rs b/tests/ui/cast/cast-alias-of-array-to-element.rs
new file mode 100644
index 0000000..124d0e0
--- /dev/null
+++ b/tests/ui/cast/cast-alias-of-array-to-element.rs
@@ -0,0 +1,22 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/203>.
+// Test that we structually normalize in the hacky `&[T; N] -> *const T` in cast.
+
+trait Mirror {
+ type Assoc: ?Sized;
+}
+impl<T: ?Sized> Mirror for T {
+ type Assoc = T;
+}
+
+struct W<'a>(&'a <[f32; 0] as Mirror>::Assoc);
+
+fn foo(x: W<'_>) -> *const f32 {
+ x.0 as *const f32
+}
+
+fn main() {}
diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr
index 3d73232..eb66633 100644
--- a/tests/ui/check-cfg/target_feature.stderr
+++ b/tests/ui/check-cfg/target_feature.stderr
@@ -27,6 +27,7 @@
`amx-tf32`
`amx-tile`
`amx-transpose`
+`apxf`
`atomics`
`avx`
`avx10.1`
diff --git a/tests/ui/error-codes/E0195.rs b/tests/ui/error-codes/E0195.rs
index a7e51df..66968f7 100644
--- a/tests/ui/error-codes/E0195.rs
+++ b/tests/ui/error-codes/E0195.rs
@@ -1,13 +1,25 @@
trait Trait {
+//~^ NOTE in this trait...
+//~| NOTE in this trait...
fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
- //~^ NOTE lifetimes in impl do not match this associated function in trait
+ //~^ NOTE `'a` is early-bound
+ //~| NOTE this lifetime bound makes `'a` early-bound
+ //~| NOTE `'b` is early-bound
+ //~| NOTE this lifetime bound makes `'b` early-bound
}
struct Foo;
impl Trait for Foo {
- fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
- //~^ NOTE lifetimes do not match associated function in trait
+//~^ NOTE in this impl...
+//~| NOTE in this impl...
+ fn bar<'a,'b>(x: &'a str, y: &'b str) {
+ //~^ ERROR E0195
+ //~| NOTE `'a` differs between the trait and impl
+ //~| NOTE `'a` is late-bound
+ //~| NOTE `'b` differs between the trait and impl
+ //~| NOTE `'b` is late-bound
+ //~| NOTE lifetime parameters differ in whether they are early- or late-bound
}
}
diff --git a/tests/ui/error-codes/E0195.stderr b/tests/ui/error-codes/E0195.stderr
index 9767dee..d0295b3 100644
--- a/tests/ui/error-codes/E0195.stderr
+++ b/tests/ui/error-codes/E0195.stderr
@@ -1,11 +1,42 @@
-error[E0195]: lifetime parameters or bounds on associated function `bar` do not match the trait declaration
- --> $DIR/E0195.rs:9:11
+error[E0195]: lifetime parameters do not match the trait definition
+ --> $DIR/E0195.rs:16:12
|
+LL | fn bar<'a,'b>(x: &'a str, y: &'b str) {
+ | ^^ ^^
+ |
+ = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'a` differs between the trait and impl
+ --> $DIR/E0195.rs:4:12
+ |
+LL | trait Trait {
+ | ----------- in this trait...
+...
LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
- | ---------- lifetimes in impl do not match this associated function in trait
+ | ^^ -- this lifetime bound makes `'a` early-bound
+ | |
+ | `'a` is early-bound
+...
+LL | impl Trait for Foo {
+ | ------------------ in this impl...
...
LL | fn bar<'a,'b>(x: &'a str, y: &'b str) {
- | ^^^^^^^ lifetimes do not match associated function in trait
+ | ^^ `'a` is late-bound
+note: `'b` differs between the trait and impl
+ --> $DIR/E0195.rs:4:15
+ |
+LL | trait Trait {
+ | ----------- in this trait...
+...
+LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
+ | ^^ -- this lifetime bound makes `'b` early-bound
+ | |
+ | `'b` is early-bound
+...
+LL | impl Trait for Foo {
+ | ------------------ in this impl...
+...
+LL | fn bar<'a,'b>(x: &'a str, y: &'b str) {
+ | ^^ `'b` is late-bound
error: aborting due to 1 previous error
diff --git a/tests/ui/errors/auxiliary/file-debuginfo.rs b/tests/ui/errors/auxiliary/file-debuginfo.rs
new file mode 100644
index 0000000..08113ec
--- /dev/null
+++ b/tests/ui/errors/auxiliary/file-debuginfo.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=debuginfo
+
+#[macro_export]
+macro_rules! my_file {
+ () => { file!() }
+}
+
+pub fn file() -> &'static str {
+ file!()
+}
diff --git a/tests/ui/errors/auxiliary/file-diag.rs b/tests/ui/errors/auxiliary/file-diag.rs
new file mode 100644
index 0000000..f29c349
--- /dev/null
+++ b/tests/ui/errors/auxiliary/file-diag.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=diagnostics
+
+#[macro_export]
+macro_rules! my_file {
+ () => { file!() }
+}
+
+pub fn file() -> &'static str {
+ file!()
+}
diff --git a/tests/ui/errors/auxiliary/file-macro.rs b/tests/ui/errors/auxiliary/file-macro.rs
new file mode 100644
index 0000000..11abc05
--- /dev/null
+++ b/tests/ui/errors/auxiliary/file-macro.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=macro
+
+#[macro_export]
+macro_rules! my_file {
+ () => { file!() }
+}
+
+pub fn file() -> &'static str {
+ file!()
+}
diff --git a/tests/ui/errors/auxiliary/file.rs b/tests/ui/errors/auxiliary/file.rs
new file mode 100644
index 0000000..63a7b3b
--- /dev/null
+++ b/tests/ui/errors/auxiliary/file.rs
@@ -0,0 +1,8 @@
+#[macro_export]
+macro_rules! my_file {
+ () => { file!() }
+}
+
+pub fn file() -> &'static str {
+ file!()
+}
diff --git a/tests/ui/errors/auxiliary/trait-debuginfo.rs b/tests/ui/errors/auxiliary/trait-debuginfo.rs
new file mode 100644
index 0000000..d5a0825
--- /dev/null
+++ b/tests/ui/errors/auxiliary/trait-debuginfo.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=debuginfo
+
+pub trait Trait: std::fmt::Display {}
diff --git a/tests/ui/errors/auxiliary/trait-diag.rs b/tests/ui/errors/auxiliary/trait-diag.rs
new file mode 100644
index 0000000..e07961a
--- /dev/null
+++ b/tests/ui/errors/auxiliary/trait-diag.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=diagnostics
+
+pub trait Trait: std::fmt::Display {}
diff --git a/tests/ui/errors/auxiliary/trait-macro.rs b/tests/ui/errors/auxiliary/trait-macro.rs
new file mode 100644
index 0000000..48673d0
--- /dev/null
+++ b/tests/ui/errors/auxiliary/trait-macro.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=macro
+
+pub trait Trait: std::fmt::Display {}
diff --git a/tests/ui/errors/auxiliary/trait.rs b/tests/ui/errors/auxiliary/trait.rs
new file mode 100644
index 0000000..0e7e540
--- /dev/null
+++ b/tests/ui/errors/auxiliary/trait.rs
@@ -0,0 +1 @@
+pub trait Trait: std::fmt::Display {}
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr
new file mode 100644
index 0000000..3ddff11
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+ --> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL
+ |
+LL | impl r#trait::Trait for A {}
+ | ^ `A` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `A`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+ --> $DIR/auxiliary/trait.rs:LL:COL
+ |
+LL | pub trait Trait: std::fmt::Display {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr
new file mode 100644
index 0000000..85c7814
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+ --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+ |
+LL | impl r#trait::Trait for A {}
+ | ^ `A` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `A`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+ --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
+ |
+LL | pub trait Trait: std::fmt::Display {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr
new file mode 100644
index 0000000..792ea79
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+ --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+ |
+LL | impl r#trait::Trait for A {}
+ | ^ `A` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `A`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+ --> $DIR/auxiliary/trait-diag.rs:LL:COL
+ |
+LL | pub trait Trait: std::fmt::Display {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr
new file mode 100644
index 0000000..d13333d
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+ --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+ |
+LL | impl r#trait::Trait for A {}
+ | ^ `A` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `A`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+ --> $DIR/auxiliary/trait-macro.rs:LL:COL
+ |
+LL | pub trait Trait: std::fmt::Display {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.rs b/tests/ui/errors/remap-path-prefix-diagnostics.rs
new file mode 100644
index 0000000..fac7e93
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.rs
@@ -0,0 +1,57 @@
+// This test exercises `-Zremap-path-scope`, diagnostics printing paths and dependency.
+//
+// We test different combinations with/without remap in deps, with/without remap in this
+// crate but always in deps and always here but never in deps.
+
+//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps
+//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps
+//@ revisions: not-diag-in-deps
+
+//@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[not-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+
+//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
+//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro
+//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo
+//@[not-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
+
+//@[with-diag-in-deps] aux-build:trait-diag.rs
+//@[with-macro-in-deps] aux-build:trait-macro.rs
+//@[with-debuginfo-in-deps] aux-build:trait-debuginfo.rs
+//@[only-diag-in-deps] aux-build:trait-diag.rs
+//@[only-macro-in-deps] aux-build:trait-macro.rs
+//@[only-debuginfo-in-deps] aux-build:trait-debuginfo.rs
+//@[not-diag-in-deps] aux-build:trait.rs
+
+// The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically
+// as the remapped revision will not begin with $SRC_DIR_REAL,
+// so we have to do it ourselves.
+//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:COL"
+
+#[cfg(any(with_diag_in_deps, only_diag_in_deps))]
+extern crate trait_diag as r#trait;
+
+#[cfg(any(with_macro_in_deps, only_macro_in_deps))]
+extern crate trait_macro as r#trait;
+
+#[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))]
+extern crate trait_debuginfo as r#trait;
+
+#[cfg(not_diag_in_deps)]
+extern crate r#trait as r#trait;
+
+struct A;
+
+impl r#trait::Trait for A {}
+//[with-macro-in-deps]~^ ERROR `A` doesn't implement `std::fmt::Display`
+//[with-debuginfo-in-deps]~^^ ERROR `A` doesn't implement `std::fmt::Display`
+//[only-diag-in-deps]~^^^ ERROR `A` doesn't implement `std::fmt::Display`
+//[only-macro-in-deps]~^^^^ ERROR `A` doesn't implement `std::fmt::Display`
+//[only-debuginfo-in-deps]~^^^^^ ERROR `A` doesn't implement `std::fmt::Display`
+
+//[with-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display`
+//[not-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display`
+
+fn main() {}
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr
new file mode 100644
index 0000000..85c7814
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+ --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+ |
+LL | impl r#trait::Trait for A {}
+ | ^ `A` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `A`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+ --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
+ |
+LL | pub trait Trait: std::fmt::Display {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr
new file mode 100644
index 0000000..08f7fb2
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+ --> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL
+ |
+LL | impl r#trait::Trait for A {}
+ | ^ `A` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `A`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+ --> remapped/errors/auxiliary/trait-diag.rs:LL:COL
+ |
+LL | pub trait Trait: std::fmt::Display {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr
new file mode 100644
index 0000000..d13333d
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+ --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+ |
+LL | impl r#trait::Trait for A {}
+ | ^ `A` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `A`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+ --> $DIR/auxiliary/trait-macro.rs:LL:COL
+ |
+LL | pub trait Trait: std::fmt::Display {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout b/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout
deleted file mode 100644
index 3bbdcbb..0000000
--- a/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout
+++ /dev/null
@@ -1 +0,0 @@
-remapped/errors/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout
new file mode 100644
index 0000000..13d4611
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = remapped/errors/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file.rs
+file!() = remapped/errors/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout
new file mode 100644
index 0000000..b2c62ac
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file-debuginfo.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout
new file mode 100644
index 0000000..e64cc07
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file-diag.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout
new file mode 100644
index 0000000..b1a93a5
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = remapped/errors/auxiliary/file-macro.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.rs b/tests/ui/errors/remap-path-prefix-macro.rs
index 6651560..3e93843 100644
--- a/tests/ui/errors/remap-path-prefix-macro.rs
+++ b/tests/ui/errors/remap-path-prefix-macro.rs
@@ -1,12 +1,47 @@
+// This test exercises `-Zremap-path-scope`, macros (like file!()) and dependency.
+//
+// We test different combinations with/without remap in deps, with/without remap in
+// this crate but always in deps and always here but never in deps.
+
//@ run-pass
//@ check-run-results
-//@ revisions: normal with-macro-scope without-macro-scope
-//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
-//@ [with-macro-scope]compile-flags: -Zremap-path-scope=macro,diagnostics
-//@ [without-macro-scope]compile-flags: -Zremap-path-scope=diagnostics
-// no-remap-src-base: Manually remap, so the remapped path remains in .stderr file.
+//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps
+//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps
+//@ revisions: not-macro-in-deps
+
+//@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[not-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+
+//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
+//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro
+//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo
+//@[not-macro-in-deps] compile-flags: -Zremap-path-scope=macro
+
+//@[with-diag-in-deps] aux-build:file-diag.rs
+//@[with-macro-in-deps] aux-build:file-macro.rs
+//@[with-debuginfo-in-deps] aux-build:file-debuginfo.rs
+//@[only-diag-in-deps] aux-build:file-diag.rs
+//@[only-macro-in-deps] aux-build:file-macro.rs
+//@[only-debuginfo-in-deps] aux-build:file-debuginfo.rs
+//@[not-macro-in-deps] aux-build:file.rs
+
+#[cfg(any(with_diag_in_deps, only_diag_in_deps))]
+extern crate file_diag as file;
+
+#[cfg(any(with_macro_in_deps, only_macro_in_deps))]
+extern crate file_macro as file;
+
+#[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))]
+extern crate file_debuginfo as file;
+
+#[cfg(not_macro_in_deps)]
+extern crate file;
fn main() {
- println!("{}", file!());
+ println!("file::my_file!() = {}", file::my_file!());
+ println!("file::file() = {}", file::file());
+ println!("file!() = {}", file!());
}
diff --git a/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout
new file mode 100644
index 0000000..b2c62ac
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file-debuginfo.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout
new file mode 100644
index 0000000..e64cc07
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file-diag.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout
new file mode 100644
index 0000000..5c1781d
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = remapped/errors/remap-path-prefix-macro.rs
+file::file() = remapped/errors/auxiliary/file-macro.rs
+file!() = remapped/errors/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout
deleted file mode 100644
index 3bbdcbb..0000000
--- a/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout
+++ /dev/null
@@ -1 +0,0 @@
-remapped/errors/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout b/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout
deleted file mode 100644
index 642823f..0000000
--- a/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout
+++ /dev/null
@@ -1 +0,0 @@
-$DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/explain.rs b/tests/ui/explain/basic.rs
similarity index 100%
rename from tests/ui/explain.rs
rename to tests/ui/explain/basic.rs
diff --git a/tests/ui/explain.stdout b/tests/ui/explain/basic.stdout
similarity index 100%
rename from tests/ui/explain.stdout
rename to tests/ui/explain/basic.stdout
diff --git a/tests/ui/explain/error-with-no-explanation.rs b/tests/ui/explain/error-with-no-explanation.rs
new file mode 100644
index 0000000..383820e
--- /dev/null
+++ b/tests/ui/explain/error-with-no-explanation.rs
@@ -0,0 +1,3 @@
+// It's a valid error with no added explanation
+//@ compile-flags: --explain E9999
+//~? ERROR: E9999 is not a valid error code
diff --git a/tests/ui/explain/error-with-no-explanation.stderr b/tests/ui/explain/error-with-no-explanation.stderr
new file mode 100644
index 0000000..afb738c
--- /dev/null
+++ b/tests/ui/explain/error-with-no-explanation.stderr
@@ -0,0 +1,2 @@
+error: E9999 is not a valid error code
+
diff --git a/tests/ui/explain/invalid-error-code.rs b/tests/ui/explain/invalid-error-code.rs
new file mode 100644
index 0000000..114118d
--- /dev/null
+++ b/tests/ui/explain/invalid-error-code.rs
@@ -0,0 +1,2 @@
+//@ compile-flags: --explain error_code
+//~? ERROR: error_code is not a valid error code
diff --git a/tests/ui/explain/invalid-error-code.stderr b/tests/ui/explain/invalid-error-code.stderr
new file mode 100644
index 0000000..c33122e
--- /dev/null
+++ b/tests/ui/explain/invalid-error-code.stderr
@@ -0,0 +1,2 @@
+error: error_code is not a valid error code
+
diff --git a/tests/ui/explain/no-E-prefix.rs b/tests/ui/explain/no-E-prefix.rs
new file mode 100644
index 0000000..39c9122
--- /dev/null
+++ b/tests/ui/explain/no-E-prefix.rs
@@ -0,0 +1,2 @@
+//@ compile-flags: --explain 425
+//@ check-pass
diff --git a/tests/ui/explain/no-E-prefix.stdout b/tests/ui/explain/no-E-prefix.stdout
new file mode 100644
index 0000000..756b970
--- /dev/null
+++ b/tests/ui/explain/no-E-prefix.stdout
@@ -0,0 +1,57 @@
+An unresolved name was used.
+
+Erroneous code examples:
+
+```
+something_that_doesnt_exist::foo;
+// error: unresolved name `something_that_doesnt_exist::foo`
+
+// or:
+
+trait Foo {
+ fn bar() {
+ Self; // error: unresolved name `Self`
+ }
+}
+
+// or:
+
+let x = unknown_variable; // error: unresolved name `unknown_variable`
+```
+
+Please verify that the name wasn't misspelled and ensure that the
+identifier being referred to is valid for the given situation. Example:
+
+```
+enum something_that_does_exist {
+ Foo,
+}
+```
+
+Or:
+
+```
+mod something_that_does_exist {
+ pub static foo : i32 = 0i32;
+}
+
+something_that_does_exist::foo; // ok!
+```
+
+Or:
+
+```
+let unknown_variable = 12u32;
+let x = unknown_variable; // ok!
+```
+
+If the item is not defined in the current module, it must be imported using a
+`use` statement, like so:
+
+```
+use foo::bar;
+bar();
+```
+
+If the item you are importing is not defined in some super-module of the
+current module, then it must also be declared as public (e.g., `pub fn`).
diff --git a/tests/ui/explain/overflow-error-code.rs b/tests/ui/explain/overflow-error-code.rs
new file mode 100644
index 0000000..284d5cd
--- /dev/null
+++ b/tests/ui/explain/overflow-error-code.rs
@@ -0,0 +1,4 @@
+// Check that we don't crash on error codes exceeding our internal limit.
+// issue: <https://github.com/rust-lang/rust/issues/140647>
+//@ compile-flags: --explain E10000
+//~? ERROR: E10000 is not a valid error code
diff --git a/tests/ui/explain/overflow-error-code.stderr b/tests/ui/explain/overflow-error-code.stderr
new file mode 100644
index 0000000..67e584e
--- /dev/null
+++ b/tests/ui/explain/overflow-error-code.stderr
@@ -0,0 +1,2 @@
+error: E10000 is not a valid error code
+
diff --git a/tests/ui/feature-gates/bench.rs b/tests/ui/feature-gates/bench.rs
index 12e646f7..94c8992 100644
--- a/tests/ui/feature-gates/bench.rs
+++ b/tests/ui/feature-gates/bench.rs
@@ -1,9 +1,7 @@
//@ edition:2018
#[bench] //~ ERROR use of unstable library feature `test`
- //~| WARN this was previously accepted
fn bench() {}
use bench as _; //~ ERROR use of unstable library feature `test`
- //~| WARN this was previously accepted
fn main() {}
diff --git a/tests/ui/feature-gates/bench.stderr b/tests/ui/feature-gates/bench.stderr
index de78e86..f5fc579 100644
--- a/tests/ui/feature-gates/bench.stderr
+++ b/tests/ui/feature-gates/bench.stderr
@@ -1,43 +1,23 @@
-error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
+error[E0658]: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
--> $DIR/bench.rs:3:3
|
LL | #[bench]
| ^^^^^
|
- = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
- = note: `#[deny(soft_unstable)]` on by default
+ = note: see issue #50297 <https://github.com/rust-lang/rust/issues/50297> for more information
+ = help: add `#![feature(test)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
- --> $DIR/bench.rs:7:5
+error[E0658]: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
+ --> $DIR/bench.rs:6:5
|
LL | use bench as _;
| ^^^^^
|
- = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
+ = note: see issue #50297 <https://github.com/rust-lang/rust/issues/50297> for more information
+ = help: add `#![feature(test)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 2 previous errors
-Future incompatibility report: Future breakage diagnostic:
-error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
- --> $DIR/bench.rs:3:3
- |
-LL | #[bench]
- | ^^^^^
- |
- = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
- = note: `#[deny(soft_unstable)]` on by default
-
-Future breakage diagnostic:
-error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
- --> $DIR/bench.rs:7:5
- |
-LL | use bench as _;
- | ^^^^^
- |
- = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
- = note: `#[deny(soft_unstable)]` on by default
-
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-apx-target-feature.rs b/tests/ui/feature-gates/feature-gate-apx-target-feature.rs
new file mode 100644
index 0000000..a2ac4ac
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-apx-target-feature.rs
@@ -0,0 +1,6 @@
+//@ only-x86_64
+#[target_feature(enable = "apxf")]
+//~^ ERROR: currently unstable
+unsafe fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr b/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr
new file mode 100644
index 0000000..1999ab5
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr
@@ -0,0 +1,13 @@
+error[E0658]: the target feature `apxf` is currently unstable
+ --> $DIR/feature-gate-apx-target-feature.rs:2:18
+ |
+LL | #[target_feature(enable = "apxf")]
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: see issue #139284 <https://github.com/rust-lang/rust/issues/139284> for more information
+ = help: add `#![feature(apx_target_feature)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs
new file mode 100644
index 0000000..218450a
--- /dev/null
+++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs
@@ -0,0 +1,12 @@
+fn f1(_: fn(a: u8)) {}
+fn f2(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters
+fn f3(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters
+fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
+//~^ ERROR `Trait(...)` syntax does not support named parameters
+//~| ERROR `Trait(...)` syntax does not support named parameters
+fn f5(_: impl Fn(u8, ...)) {}
+//~^ ERROR `Trait(...)` syntax does not support c_variadic parameters
+fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {}
+//~^ ERROR `Trait(...)` syntax does not support attributes in parameters
+
+fn main(){}
diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr
new file mode 100644
index 0000000..b72d5b7
--- /dev/null
+++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr
@@ -0,0 +1,38 @@
+error: `Trait(...)` syntax does not support named parameters
+ --> $DIR/fn-trait-use-named-params-issue-140169.rs:2:22
+ |
+LL | fn f2(_: impl Fn(u8, vvvv: u8)) {}
+ | ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support named parameters
+ --> $DIR/fn-trait-use-named-params-issue-140169.rs:3:18
+ |
+LL | fn f3(_: impl Fn(aaaa: u8, u8)) {}
+ | ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support named parameters
+ --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:18
+ |
+LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
+ | ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support named parameters
+ --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:28
+ |
+LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
+ | ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support c_variadic parameters
+ --> $DIR/fn-trait-use-named-params-issue-140169.rs:7:22
+ |
+LL | fn f5(_: impl Fn(u8, ...)) {}
+ | ^^^ help: remove the `...`
+
+error: `Trait(...)` syntax does not support attributes in parameters
+ --> $DIR/fn-trait-use-named-params-issue-140169.rs:9:22
+ |
+LL | fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the attributes
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr
index bf4ba47..fa05c0c 100644
--- a/tests/ui/imports/reexports.stderr
+++ b/tests/ui/imports/reexports.stderr
@@ -62,7 +62,7 @@
LL | pub use super::*;
| ^^^^^^^^
|
-note: the most public imported item is `pub(a)`
+note: the most public imported item is `pub(in crate::a)`
--> $DIR/reexports.rs:11:17
|
LL | pub use super::*;
diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.rs b/tests/ui/inference/detect-old-time-version-format_description-parse.rs
deleted file mode 100644
index 386b2a3..0000000
--- a/tests/ui/inference/detect-old-time-version-format_description-parse.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#![crate_name = "time"]
-#![crate_type = "lib"]
-
-// This code compiled without error in Rust 1.79, but started failing in 1.80
-// after the addition of several `impl FromIterator<_> for Box<str>`.
-
-pub fn parse() -> Option<Vec<()>> {
- let iter = std::iter::once(Some(())).map(|o| o.map(Into::into));
- let items = iter.collect::<Option<Box<_>>>()?; //~ ERROR E0282
- //~^ NOTE this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35`
- Some(items.into())
- //~^ NOTE type must be known at this point
-}
diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.stderr b/tests/ui/inference/detect-old-time-version-format_description-parse.stderr
deleted file mode 100644
index a70ce9d..0000000
--- a/tests/ui/inference/detect-old-time-version-format_description-parse.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0282]: type annotations needed for `Box<_>`
- --> $DIR/detect-old-time-version-format_description-parse.rs:9:9
- |
-LL | let items = iter.collect::<Option<Box<_>>>()?;
- | ^^^^^
-LL |
-LL | Some(items.into())
- | ---- type must be known at this point
- |
- = note: this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/lint/expansion-time.rs b/tests/ui/lint/expansion-time.rs
index 3cb4b91..5ffb0c7 100644
--- a/tests/ui/lint/expansion-time.rs
+++ b/tests/ui/lint/expansion-time.rs
@@ -9,13 +9,6 @@ macro_rules! foo {
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`
- //~| WARN this was previously accepted
- fn foo() {}
-}
-
#[deprecated = "reason"]
macro_rules! deprecated {
() => {}
diff --git a/tests/ui/lint/expansion-time.stderr b/tests/ui/lint/expansion-time.stderr
index f65627c..f24d1b6 100644
--- a/tests/ui/lint/expansion-time.stderr
+++ b/tests/ui/lint/expansion-time.stderr
@@ -26,20 +26,6 @@
LL | #[warn(missing_fragment_specifier)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
-warning: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
- --> $DIR/expansion-time.rs:14:7
- |
-LL | #[bench]
- | ^^^^^
- |
- = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-note: the lint level is defined here
- --> $DIR/expansion-time.rs:12:8
- |
-LL | #[warn(soft_unstable)]
- | ^^^^^^^^^^^^^
-
warning: include macro expected single expression in source
--> $DIR/expansion-time-include.rs:4:1
|
@@ -47,12 +33,12 @@
| ^
|
note: the lint level is defined here
- --> $DIR/expansion-time.rs:29:8
+ --> $DIR/expansion-time.rs:22:8
|
LL | #[warn(incomplete_include)]
| ^^^^^^^^^^^^^^^^^^
-warning: 4 warnings emitted
+warning: 3 warnings emitted
Future incompatibility report: Future breakage diagnostic:
warning: missing fragment specifier
@@ -69,18 +55,3 @@
LL | #[warn(missing_fragment_specifier)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
-Future breakage diagnostic:
-warning: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
- --> $DIR/expansion-time.rs:14:7
- |
-LL | #[bench]
- | ^^^^^
- |
- = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-note: the lint level is defined here
- --> $DIR/expansion-time.rs:12:8
- |
-LL | #[warn(soft_unstable)]
- | ^^^^^^^^^^^^^
-
diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs
new file mode 100644
index 0000000..33a89ce
--- /dev/null
+++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs
@@ -0,0 +1,10 @@
+#![forbid(for_loops_over_fallibles)]
+
+fn main() {
+ macro_rules! x {
+ () => {
+ None::<i32>
+ };
+ }
+ for _ in x! {} {} //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles]
+}
diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr
new file mode 100644
index 0000000..550d260
--- /dev/null
+++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr
@@ -0,0 +1,24 @@
+error: for loop over an `Option`. This is more readably written as an `if let` statement
+ --> $DIR/macro-issue-140747.rs:9:14
+ |
+LL | for _ in x! {} {}
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/macro-issue-140747.rs:1:11
+ |
+LL | #![forbid(for_loops_over_fallibles)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+help: to check pattern in a loop use `while let`
+ |
+LL - for _ in x! {} {}
+LL + while let Some(_) = x! {} {}
+ |
+help: consider using `if let` to clear intent
+ |
+LL - for _ in x! {} {}
+LL + if let Some(_) = x! {} {}
+ |
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/nll/nested-bodies-in-dead-code.rs b/tests/ui/nll/nested-bodies-in-dead-code.rs
new file mode 100644
index 0000000..6ac68f5
--- /dev/null
+++ b/tests/ui/nll/nested-bodies-in-dead-code.rs
@@ -0,0 +1,28 @@
+//@ edition: 2024
+
+// Regression test for #140583. We want to borrowck nested
+// bodies even if they are in dead code. While not necessary for
+// soundness, it is desirable to error in such cases.
+
+fn main() {
+ return;
+ |x: &str| -> &'static str { x };
+ //~^ ERROR lifetime may not live long enough
+ || {
+ || {
+ let temp = 1;
+ let p: &'static u32 = &temp;
+ //~^ ERROR `temp` does not live long enough
+ };
+ };
+ const {
+ let temp = 1;
+ let p: &'static u32 = &temp;
+ //~^ ERROR `temp` does not live long enough
+ };
+ async {
+ let temp = 1;
+ let p: &'static u32 = &temp;
+ //~^ ERROR `temp` does not live long enough
+ };
+}
diff --git a/tests/ui/nll/nested-bodies-in-dead-code.stderr b/tests/ui/nll/nested-bodies-in-dead-code.stderr
new file mode 100644
index 0000000..da6ccff
--- /dev/null
+++ b/tests/ui/nll/nested-bodies-in-dead-code.stderr
@@ -0,0 +1,50 @@
+error: lifetime may not live long enough
+ --> $DIR/nested-bodies-in-dead-code.rs:9:33
+ |
+LL | |x: &str| -> &'static str { x };
+ | - ^ returning this value requires that `'1` must outlive `'static`
+ | |
+ | let's call the lifetime of this reference `'1`
+
+error[E0597]: `temp` does not live long enough
+ --> $DIR/nested-bodies-in-dead-code.rs:14:35
+ |
+LL | let temp = 1;
+ | ---- binding `temp` declared here
+LL | let p: &'static u32 = &temp;
+ | ------------ ^^^^^ borrowed value does not live long enough
+ | |
+ | type annotation requires that `temp` is borrowed for `'static`
+LL |
+LL | };
+ | - `temp` dropped here while still borrowed
+
+error[E0597]: `temp` does not live long enough
+ --> $DIR/nested-bodies-in-dead-code.rs:20:31
+ |
+LL | let temp = 1;
+ | ---- binding `temp` declared here
+LL | let p: &'static u32 = &temp;
+ | ------------ ^^^^^ borrowed value does not live long enough
+ | |
+ | type annotation requires that `temp` is borrowed for `'static`
+LL |
+LL | };
+ | - `temp` dropped here while still borrowed
+
+error[E0597]: `temp` does not live long enough
+ --> $DIR/nested-bodies-in-dead-code.rs:25:31
+ |
+LL | let temp = 1;
+ | ---- binding `temp` declared here
+LL | let p: &'static u32 = &temp;
+ | ------------ ^^^^^ borrowed value does not live long enough
+ | |
+ | type annotation requires that `temp` is borrowed for `'static`
+LL |
+LL | };
+ | - `temp` dropped here while still borrowed
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/or-patterns/fn-param-wrap-parens.fixed b/tests/ui/or-patterns/fn-param-wrap-parens.fixed
index fbf6006..608f826 100644
--- a/tests/ui/or-patterns/fn-param-wrap-parens.fixed
+++ b/tests/ui/or-patterns/fn-param-wrap-parens.fixed
@@ -10,4 +10,4 @@
use E::*;
#[cfg(false)]
-fn fun1((A | B): E) {} //~ ERROR top-level or-patterns are not allowed
+fn fun1((A | B): E) {} //~ ERROR function parameters require top-level or-patterns in parentheses
diff --git a/tests/ui/or-patterns/fn-param-wrap-parens.rs b/tests/ui/or-patterns/fn-param-wrap-parens.rs
index d796f99..d6fe7e9 100644
--- a/tests/ui/or-patterns/fn-param-wrap-parens.rs
+++ b/tests/ui/or-patterns/fn-param-wrap-parens.rs
@@ -10,4 +10,4 @@ enum E { A, B }
use E::*;
#[cfg(false)]
-fn fun1(A | B: E) {} //~ ERROR top-level or-patterns are not allowed
+fn fun1(A | B: E) {} //~ ERROR function parameters require top-level or-patterns in parentheses
diff --git a/tests/ui/or-patterns/fn-param-wrap-parens.stderr b/tests/ui/or-patterns/fn-param-wrap-parens.stderr
index da2832e..e0307b4 100644
--- a/tests/ui/or-patterns/fn-param-wrap-parens.stderr
+++ b/tests/ui/or-patterns/fn-param-wrap-parens.stderr
@@ -1,4 +1,4 @@
-error: top-level or-patterns are not allowed in function parameters
+error: function parameters require top-level or-patterns in parentheses
--> $DIR/fn-param-wrap-parens.rs:13:9
|
LL | fn fun1(A | B: E) {}
diff --git a/tests/ui/or-patterns/nested-undelimited-precedence.rs b/tests/ui/or-patterns/nested-undelimited-precedence.rs
index 0478362..73f72cb 100644
--- a/tests/ui/or-patterns/nested-undelimited-precedence.rs
+++ b/tests/ui/or-patterns/nested-undelimited-precedence.rs
@@ -17,7 +17,7 @@ fn foo() {
let b @ (A | B): E = A;
let b @ A | B: E = A; //~ERROR `b` is not bound in all patterns
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR `let` bindings require top-level or-patterns in parentheses
}
enum F {
@@ -32,13 +32,13 @@ fn bar() {
let (A(x) | B(x)): F = A(3);
let &A(_) | B(_): F = A(3); //~ERROR mismatched types
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR `let` bindings require top-level or-patterns in parentheses
let &&A(_) | B(_): F = A(3); //~ERROR mismatched types
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR `let` bindings require top-level or-patterns in parentheses
let &mut A(_) | B(_): F = A(3); //~ERROR mismatched types
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR `let` bindings require top-level or-patterns in parentheses
let &&mut A(_) | B(_): F = A(3); //~ERROR mismatched types
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR `let` bindings require top-level or-patterns in parentheses
}
fn main() {}
diff --git a/tests/ui/or-patterns/nested-undelimited-precedence.stderr b/tests/ui/or-patterns/nested-undelimited-precedence.stderr
index f16d83e..0835ca1 100644
--- a/tests/ui/or-patterns/nested-undelimited-precedence.stderr
+++ b/tests/ui/or-patterns/nested-undelimited-precedence.stderr
@@ -1,4 +1,4 @@
-error: top-level or-patterns are not allowed in `let` bindings
+error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:19:9
|
LL | let b @ A | B: E = A;
@@ -9,7 +9,7 @@
LL | let (b @ A | B): E = A;
| + +
-error: top-level or-patterns are not allowed in `let` bindings
+error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:34:9
|
LL | let &A(_) | B(_): F = A(3);
@@ -20,7 +20,7 @@
LL | let (&A(_) | B(_)): F = A(3);
| + +
-error: top-level or-patterns are not allowed in `let` bindings
+error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:36:9
|
LL | let &&A(_) | B(_): F = A(3);
@@ -31,7 +31,7 @@
LL | let (&&A(_) | B(_)): F = A(3);
| + +
-error: top-level or-patterns are not allowed in `let` bindings
+error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:38:9
|
LL | let &mut A(_) | B(_): F = A(3);
@@ -42,7 +42,7 @@
LL | let (&mut A(_) | B(_)): F = A(3);
| + +
-error: top-level or-patterns are not allowed in `let` bindings
+error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:40:9
|
LL | let &&mut A(_) | B(_): F = A(3);
diff --git a/tests/ui/or-patterns/or-patterns-syntactic-fail.rs b/tests/ui/or-patterns/or-patterns-syntactic-fail.rs
index 23dbb57..bc4babe 100644
--- a/tests/ui/or-patterns/or-patterns-syntactic-fail.rs
+++ b/tests/ui/or-patterns/or-patterns-syntactic-fail.rs
@@ -16,18 +16,18 @@ fn no_top_level_or_patterns() {
fn no_top_level_or_patterns_2() {
// ...and for now neither do we allow or-patterns at the top level of functions.
fn fun1(A | B: E) {}
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR function parameters require top-level or-patterns in parentheses
fn fun2(| A | B: E) {}
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR function parameters require top-level or-patterns in parentheses
// We don't allow top-level or-patterns before type annotation in let-statements because we
// want to reserve this syntactic space for possible future type ascription.
let A | B: E = A;
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR `let` bindings require top-level or-patterns in parentheses
let | A | B: E = A;
- //~^ ERROR top-level or-patterns are not allowed
+ //~^ ERROR `let` bindings require top-level or-patterns in parentheses
let (A | B): E = A; // ok -- wrapped in parens
}
diff --git a/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr b/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr
index 74e4cea..f6b7d42 100644
--- a/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr
+++ b/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr
@@ -11,7 +11,7 @@
LL | let _ = |A | { B: E| ();
| +
-error: top-level or-patterns are not allowed in function parameters
+error: function parameters require top-level or-patterns in parentheses
--> $DIR/or-patterns-syntactic-fail.rs:18:13
|
LL | fn fun1(A | B: E) {}
@@ -22,7 +22,7 @@
LL | fn fun1((A | B): E) {}
| + +
-error: top-level or-patterns are not allowed in function parameters
+error: function parameters require top-level or-patterns in parentheses
--> $DIR/or-patterns-syntactic-fail.rs:21:13
|
LL | fn fun2(| A | B: E) {}
@@ -33,7 +33,7 @@
LL | fn fun2((| A | B): E) {}
| + +
-error: top-level or-patterns are not allowed in `let` bindings
+error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/or-patterns-syntactic-fail.rs:26:9
|
LL | let A | B: E = A;
@@ -44,7 +44,7 @@
LL | let (A | B): E = A;
| + +
-error: top-level or-patterns are not allowed in `let` bindings
+error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/or-patterns-syntactic-fail.rs:29:9
|
LL | let | A | B: E = A;
diff --git a/tests/ui/or-patterns/remove-leading-vert.fixed b/tests/ui/or-patterns/remove-leading-vert.fixed
index 136ca57..2851b8f 100644
--- a/tests/ui/or-patterns/remove-leading-vert.fixed
+++ b/tests/ui/or-patterns/remove-leading-vert.fixed
@@ -8,7 +8,7 @@
#[cfg(false)]
fn leading() {
- fn fun1( A: E) {} //~ ERROR top-level or-patterns are not allowed
+ fn fun1( A: E) {} //~ ERROR function parameters require top-level or-patterns in parentheses
fn fun2( A: E) {} //~ ERROR unexpected `||` before function parameter
let ( | A): E;
let ( | A): (E); //~ ERROR unexpected token `||` in pattern
diff --git a/tests/ui/or-patterns/remove-leading-vert.rs b/tests/ui/or-patterns/remove-leading-vert.rs
index d9e9c9f..1e1dbfb 100644
--- a/tests/ui/or-patterns/remove-leading-vert.rs
+++ b/tests/ui/or-patterns/remove-leading-vert.rs
@@ -8,7 +8,7 @@ fn main() {}
#[cfg(false)]
fn leading() {
- fn fun1( | A: E) {} //~ ERROR top-level or-patterns are not allowed
+ fn fun1( | A: E) {} //~ ERROR function parameters require top-level or-patterns in parentheses
fn fun2( || A: E) {} //~ ERROR unexpected `||` before function parameter
let ( | A): E;
let ( || A): (E); //~ ERROR unexpected token `||` in pattern
diff --git a/tests/ui/or-patterns/remove-leading-vert.stderr b/tests/ui/or-patterns/remove-leading-vert.stderr
index b92fcb8..0323c64 100644
--- a/tests/ui/or-patterns/remove-leading-vert.stderr
+++ b/tests/ui/or-patterns/remove-leading-vert.stderr
@@ -1,4 +1,4 @@
-error: top-level or-patterns are not allowed in function parameters
+error: function parameters require top-level or-patterns in parentheses
--> $DIR/remove-leading-vert.rs:11:14
|
LL | fn fun1( | A: E) {}
diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
index 6bfe16a..db25ce4 100644
--- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
+++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
@@ -2,8 +2,10 @@
fn main() {
unsafe {
- dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
- //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
- //~| NOTE while parsing this parenthesized list of type arguments starting here
+ dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR `Trait(...)` syntax does not support named parameters
+ //~^ ERROR cannot find function `dealloc` in this scope [E0425]
+ //~| ERROR cannot find value `ptr2` in this scope [E0425]
+ //~| ERROR the `!` type is experimental [E0658]
+ //~| ERROR cannot find function, tuple struct or tuple variant `Layout` in this scope [E0425]
}
}
diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
index c12bf7f..a083883 100644
--- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
+++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
@@ -1,16 +1,43 @@
-error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
- --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:33
+error: `Trait(...)` syntax does not support named parameters
+ --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:32
|
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
- | --- ^ expected one of 7 possible tokens
- | |
- | while parsing this parenthesized list of type arguments starting here
+ | ^ help: remove the parameter name
-error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
- --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:43
+error[E0425]: cannot find function `dealloc` in this scope
+ --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:9
|
LL | dealloc(ptr2, Layout::(x: !)(1, 1));
- | ^ expected one of `.`, `;`, `?`, `}`, or an operator
+ | ^^^^^^^ not found in this scope
+ |
+help: consider importing this function
+ |
+LL + use std::alloc::dealloc;
+ |
-error: aborting due to 2 previous errors
+error[E0425]: cannot find value `ptr2` in this scope
+ --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:17
+ |
+LL | dealloc(ptr2, Layout::(x: !)(1, 1));
+ | ^^^^ not found in this scope
+error[E0658]: the `!` type is experimental
+ --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:35
+ |
+LL | dealloc(ptr2, Layout::(x: !)(1, 1));
+ | ^
+ |
+ = note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
+ = help: add `#![feature(never_type)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0425]: cannot find function, tuple struct or tuple variant `Layout` in this scope
+ --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:23
+ |
+LL | dealloc(ptr2, Layout::(x: !)(1, 1));
+ | ^^^^^^ not found in this scope
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0425, E0658.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
index 1c28c06..60dd88e 100644
--- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
+++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
@@ -2,7 +2,4 @@
struct Apple((Apple, Option(Banana ? Citron)));
//~^ ERROR invalid `?` in type
-//~| ERROR expected one of `)` or `,`, found `Citron`
-//~| ERROR cannot find type `Citron` in this scope [E0412]
-//~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214]
-//~| ERROR `Apple` has infinite size
+//~| ERROR unexpected token: `Citron`
diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
index 97a73b4..c92535c 100644
--- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
+++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
@@ -10,44 +10,11 @@
LL + struct Apple((Apple, Option(Option<Banana > Citron)));
|
-error: expected one of `)` or `,`, found `Citron`
+error: unexpected token: `Citron`
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
|
LL | struct Apple((Apple, Option(Banana ? Citron)));
- | -^^^^^^ expected one of `)` or `,`
- | |
- | help: missing `,`
+ | ^^^^^^ unexpected token after this
-error[E0412]: cannot find type `Citron` in this scope
- --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
- |
-LL | struct Apple((Apple, Option(Banana ? Citron)));
- | ^^^^^^ not found in this scope
+error: aborting due to 2 previous errors
-error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
- --> $DIR/issue-103748-ICE-wrong-braces.rs:3:22
- |
-LL | struct Apple((Apple, Option(Banana ? Citron)));
- | ^^^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
- |
-help: use angle brackets instead
- |
-LL - struct Apple((Apple, Option(Banana ? Citron)));
-LL + struct Apple((Apple, Option<Banana ? Citron>));
- |
-
-error[E0072]: recursive type `Apple` has infinite size
- --> $DIR/issue-103748-ICE-wrong-braces.rs:3:1
- |
-LL | struct Apple((Apple, Option(Banana ? Citron)));
- | ^^^^^^^^^^^^ ----- recursive without indirection
- |
-help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
- |
-LL | struct Apple((Box<Apple>, Option(Banana ? Citron)));
- | ++++ +
-
-error: aborting due to 5 previous errors
-
-Some errors have detailed explanations: E0072, E0214, E0412.
-For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/pattern/deref-patterns/bindings.rs b/tests/ui/pattern/deref-patterns/bindings.rs
index ac48e3f..92c01d7 100644
--- a/tests/ui/pattern/deref-patterns/bindings.rs
+++ b/tests/ui/pattern/deref-patterns/bindings.rs
@@ -13,7 +13,6 @@ fn simple_vec(vec: Vec<u32>) -> u32 {
deref!([x]) => x,
deref!([1, x]) => x + 200,
deref!(ref slice) => slice.iter().sum(),
- _ => 2000,
}
}
@@ -25,7 +24,6 @@ fn simple_vec(vec: Vec<u32>) -> u32 {
[x] => x,
[1, x] => x + 200,
deref!(ref slice) => slice.iter().sum(),
- _ => 2000,
}
}
diff --git a/tests/ui/pattern/deref-patterns/closure_capture.rs b/tests/ui/pattern/deref-patterns/closure_capture.rs
index cf78eed..497ec62 100644
--- a/tests/ui/pattern/deref-patterns/closure_capture.rs
+++ b/tests/ui/pattern/deref-patterns/closure_capture.rs
@@ -9,7 +9,7 @@
fn main() {
let b = Rc::new("aaa".to_string());
let f = || {
- let deref!(ref s) = b else { unreachable!() };
+ let deref!(ref s) = b;
assert_eq!(s.len(), 3);
};
assert_eq!(b.len(), 3);
@@ -26,7 +26,7 @@ fn main() {
let mut b = "aaa".to_string();
let mut f = || {
- let deref!(ref mut s) = b else { unreachable!() };
+ let deref!(ref mut s) = b;
s.make_ascii_uppercase();
};
f();
@@ -53,7 +53,7 @@ fn main() {
let b = Box::new(NoCopy);
let f = || {
// this should move out of the box rather than borrow.
- let deref!(x) = b else { unreachable!() };
+ let deref!(x) = b;
drop::<NoCopy>(x);
};
f();
@@ -61,7 +61,7 @@ fn main() {
let b = Box::new((NoCopy,));
let f = || {
// this should move out of the box rather than borrow.
- let (x,) = b else { unreachable!() };
+ let (x,) = b;
drop::<NoCopy>(x);
};
f();
diff --git a/tests/ui/pattern/deref-patterns/deref-box.rs b/tests/ui/pattern/deref-patterns/deref-box.rs
index 2d0a8d0..39b23dc 100644
--- a/tests/ui/pattern/deref-patterns/deref-box.rs
+++ b/tests/ui/pattern/deref-patterns/deref-box.rs
@@ -6,18 +6,18 @@
#![expect(incomplete_features)]
fn unbox_1<T>(b: Box<T>) -> T {
- let deref!(x) = b else { unreachable!() };
+ let deref!(x) = b;
x
}
fn unbox_2<T>(b: Box<(T,)>) -> T {
- let (x,) = b else { unreachable!() };
+ let (x,) = b;
x
}
fn unbox_separately<T>(b: Box<(T, T)>) -> (T, T) {
- let (x, _) = b else { unreachable!() };
- let (_, y) = b else { unreachable!() };
+ let (x, _) = b;
+ let (_, y) = b;
(x, y)
}
@@ -31,7 +31,7 @@ fn main() {
// test that borrowing from a box also works
let mut b = "hi".to_owned().into_boxed_str();
- let deref!(ref mut s) = b else { unreachable!() };
+ let deref!(ref mut s) = b;
s.make_ascii_uppercase();
assert_eq!(&*b, "HI");
}
diff --git a/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs b/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs
index 04c83d4..2477026 100644
--- a/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs
+++ b/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs
@@ -11,7 +11,6 @@ fn main() {
match cow {
[..] => {}
- _ => unreachable!(),
}
match cow {
@@ -22,14 +21,12 @@ fn main() {
match Rc::new(&cow) {
Cow::Borrowed { 0: _ } => {}
Cow::Owned { 0: _ } => unreachable!(),
- _ => unreachable!(),
}
let cow_of_cow: Cow<'_, Cow<'static, [u8]>> = Cow::Owned(cow);
match cow_of_cow {
[..] => {}
- _ => unreachable!(),
}
// This matches on the outer `Cow` (the owned one).
@@ -41,6 +38,5 @@ fn main() {
match Rc::new(&cow_of_cow) {
Cow::Borrowed { 0: _ } => unreachable!(),
Cow::Owned { 0: _ } => {}
- _ => unreachable!(),
}
}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs b/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs
new file mode 100644
index 0000000..0341903
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs
@@ -0,0 +1,47 @@
+//! Test that the place behind a deref pattern is treated as maybe-invalid, and thus empty arms
+//! cannot be omitted. This is handled the same as for refs and union fields, so this leaves the
+//! bulk of the testing to `tests/ui/pattern/usefulness/empty-types.rs`.
+// FIXME(deref_patterns): On stabilization, cases for deref patterns could be worked into that file
+// to keep the tests for empty types in one place and test more thoroughly.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+enum Void {}
+
+fn main() {
+ // Sanity check: matching on an empty type without pointer indirection lets us omit arms.
+ let opt_void: Option<Void> = None;
+ match opt_void {
+ None => {}
+ }
+
+ // But if we hide it behind a smart pointer, we need an arm.
+ let box_opt_void: Box<Option<Void>> = Box::new(None);
+ match box_opt_void {
+ //~^ ERROR non-exhaustive patterns: `deref!(Some(_))` not covered
+ None => {}
+ }
+ match box_opt_void {
+ None => {}
+ Some(_) => {}
+ }
+ match box_opt_void {
+ None => {}
+ _ => {}
+ }
+
+ // For consistency, this behaves the same as if we manually dereferenced the scrutinee.
+ match *box_opt_void {
+ //~^ ERROR non-exhaustive patterns: `Some(_)` not covered
+ None => {}
+ }
+ match *box_opt_void {
+ None => {}
+ Some(_) => {}
+ }
+ match *box_opt_void {
+ None => {}
+ _ => {}
+ }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr b/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr
new file mode 100644
index 0000000..e324770
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr
@@ -0,0 +1,38 @@
+error[E0004]: non-exhaustive patterns: `deref!(Some(_))` not covered
+ --> $DIR/empty-types.rs:21:11
+ |
+LL | match box_opt_void {
+ | ^^^^^^^^^^^^ pattern `deref!(Some(_))` not covered
+ |
+note: `Box<Option<Void>>` defined here
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ = note: the matched value is of type `Box<Option<Void>>`
+ = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL ~ None => {},
+LL + deref!(Some(_)) => todo!()
+ |
+
+error[E0004]: non-exhaustive patterns: `Some(_)` not covered
+ --> $DIR/empty-types.rs:35:11
+ |
+LL | match *box_opt_void {
+ | ^^^^^^^^^^^^^ pattern `Some(_)` not covered
+ |
+note: `Option<Void>` defined here
+ --> $SRC_DIR/core/src/option.rs:LL:COL
+ ::: $SRC_DIR/core/src/option.rs:LL:COL
+ |
+ = note: not covered
+ = note: the matched value is of type `Option<Void>`
+ = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL ~ None => {},
+LL + Some(_) => todo!()
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs
new file mode 100644
index 0000000..f567dc0
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs
@@ -0,0 +1,48 @@
+//! Test matches with a mix of ADT constructors and deref patterns. Currently, usefulness analysis
+//! doesn't support this, so make sure we catch it beforehand. As a consequence, it takes priority
+//! over non-exhaustive match and unreachable pattern errors.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+use std::borrow::Cow;
+
+fn main() {
+ let cow: Cow<'static, bool> = Cow::Borrowed(&false);
+
+ match cow {
+ true => {}
+ //~v ERROR mix of deref patterns and normal constructors
+ false => {}
+ Cow::Borrowed(_) => {}
+ }
+
+ match cow {
+ Cow::Owned(_) => {}
+ Cow::Borrowed(_) => {}
+ true => {}
+ //~^ ERROR mix of deref patterns and normal constructors
+ }
+
+ match cow {
+ _ => {}
+ Cow::Owned(_) => {}
+ false => {}
+ //~^ ERROR mix of deref patterns and normal constructors
+ }
+
+ match (cow, 0) {
+ (Cow::Owned(_), 0) => {}
+ (Cow::Borrowed(_), 0) => {}
+ (true, 0) => {}
+ //~^ ERROR mix of deref patterns and normal constructors
+ }
+
+ match (0, cow) {
+ (0, Cow::Owned(_)) => {}
+ (0, Cow::Borrowed(_)) => {}
+ _ => {}
+ (1, true) => {}
+ //~^ ERROR mix of deref patterns and normal constructors
+ }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr
new file mode 100644
index 0000000..5ad2416
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr
@@ -0,0 +1,43 @@
+error: mix of deref patterns and normal constructors
+ --> $DIR/mixed-constructors.rs:16:9
+ |
+LL | false => {}
+ | ^^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+LL | Cow::Borrowed(_) => {}
+ | ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+ --> $DIR/mixed-constructors.rs:22:9
+ |
+LL | Cow::Borrowed(_) => {}
+ | ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL | true => {}
+ | ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+ --> $DIR/mixed-constructors.rs:29:9
+ |
+LL | Cow::Owned(_) => {}
+ | ^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL | false => {}
+ | ^^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+ --> $DIR/mixed-constructors.rs:36:10
+ |
+LL | (Cow::Borrowed(_), 0) => {}
+ | ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL | (true, 0) => {}
+ | ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+ --> $DIR/mixed-constructors.rs:43:13
+ |
+LL | (0, Cow::Borrowed(_)) => {}
+ | ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL | _ => {}
+LL | (1, true) => {}
+ | ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs
new file mode 100644
index 0000000..704cae8
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs
@@ -0,0 +1,28 @@
+//! Test non-exhaustive matches involving deref patterns.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+fn main() {
+ match Box::new(false) {
+ //~^ ERROR non-exhaustive patterns: `deref!(true)` not covered
+ false => {}
+ }
+
+ match Box::new(Box::new(false)) {
+ //~^ ERROR non-exhaustive patterns: `deref!(deref!(false))` not covered
+ true => {}
+ }
+
+ match Box::new((true, Box::new(false))) {
+ //~^ ERROR non-exhaustive patterns: `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered
+ (true, false) => {}
+ (false, true) => {}
+ }
+
+ enum T { A, B, C }
+ match Box::new((Box::new(T::A), Box::new(T::A))) {
+ //~^ ERROR non-exhaustive patterns: `deref!((deref!(T::C), _))` not covered
+ (T::A | T::B, T::C) => {}
+ }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr
new file mode 100644
index 0000000..55fa84b
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr
@@ -0,0 +1,63 @@
+error[E0004]: non-exhaustive patterns: `deref!(true)` not covered
+ --> $DIR/non-exhaustive.rs:7:11
+ |
+LL | match Box::new(false) {
+ | ^^^^^^^^^^^^^^^ pattern `deref!(true)` not covered
+ |
+note: `Box<bool>` defined here
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ = note: the matched value is of type `Box<bool>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL ~ false => {},
+LL + deref!(true) => todo!()
+ |
+
+error[E0004]: non-exhaustive patterns: `deref!(deref!(false))` not covered
+ --> $DIR/non-exhaustive.rs:12:11
+ |
+LL | match Box::new(Box::new(false)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `deref!(deref!(false))` not covered
+ |
+note: `Box<Box<bool>>` defined here
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ = note: the matched value is of type `Box<Box<bool>>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL ~ true => {},
+LL + deref!(deref!(false)) => todo!()
+ |
+
+error[E0004]: non-exhaustive patterns: `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered
+ --> $DIR/non-exhaustive.rs:17:11
+ |
+LL | match Box::new((true, Box::new(false))) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ patterns `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered
+ |
+note: `Box<(bool, Box<bool>)>` defined here
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ = note: the matched value is of type `Box<(bool, Box<bool>)>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+ |
+LL ~ (false, true) => {},
+LL + deref!((false, deref!(false))) | deref!((true, deref!(true))) => todo!()
+ |
+
+error[E0004]: non-exhaustive patterns: `deref!((deref!(T::C), _))` not covered
+ --> $DIR/non-exhaustive.rs:24:11
+ |
+LL | match Box::new((Box::new(T::A), Box::new(T::A))) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `deref!((deref!(T::C), _))` not covered
+ |
+note: `Box<(Box<T>, Box<T>)>` defined here
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ = note: the matched value is of type `Box<(Box<T>, Box<T>)>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL ~ (T::A | T::B, T::C) => {},
+LL + deref!((deref!(T::C), _)) => todo!()
+ |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs
new file mode 100644
index 0000000..2677fc5
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs
@@ -0,0 +1,33 @@
+//! Test unreachable patterns involving deref patterns.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+fn main() {
+ match Box::new(false) {
+ true => {}
+ false => {}
+ false => {} //~ ERROR unreachable pattern
+ }
+
+ match Box::new(Box::new(false)) {
+ true => {}
+ false => {}
+ true => {} //~ ERROR unreachable pattern
+ }
+
+ match Box::new((true, Box::new(false))) {
+ (true, _) => {}
+ (_, true) => {}
+ (false, false) => {}
+ _ => {} //~ ERROR unreachable pattern
+ }
+
+ enum T { A, B, C }
+ match Box::new((Box::new(T::A), Box::new(T::A))) {
+ (T::A | T::B, T::A | T::C) => {}
+ (T::A, T::C) => {} //~ ERROR unreachable pattern
+ (T::B, T::A) => {} //~ ERROR unreachable pattern
+ _ => {}
+ }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr
new file mode 100644
index 0000000..045e11b
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr
@@ -0,0 +1,60 @@
+error: unreachable pattern
+ --> $DIR/unreachable-patterns.rs:10:9
+ |
+LL | false => {}
+ | ----- matches all the relevant values
+LL | false => {}
+ | ^^^^^ no value can reach this
+ |
+note: the lint level is defined here
+ --> $DIR/unreachable-patterns.rs:4:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/unreachable-patterns.rs:16:9
+ |
+LL | true => {}
+ | ---- matches all the relevant values
+LL | false => {}
+LL | true => {}
+ | ^^^^ no value can reach this
+
+error: unreachable pattern
+ --> $DIR/unreachable-patterns.rs:23:9
+ |
+LL | _ => {}
+ | ^ no value can reach this
+ |
+note: multiple earlier patterns match some of the same values
+ --> $DIR/unreachable-patterns.rs:23:9
+ |
+LL | (true, _) => {}
+ | --------- matches some of the same values
+LL | (_, true) => {}
+ | --------- matches some of the same values
+LL | (false, false) => {}
+ | -------------- matches some of the same values
+LL | _ => {}
+ | ^ collectively making this unreachable
+
+error: unreachable pattern
+ --> $DIR/unreachable-patterns.rs:29:9
+ |
+LL | (T::A | T::B, T::A | T::C) => {}
+ | -------------------------- matches all the relevant values
+LL | (T::A, T::C) => {}
+ | ^^^^^^^^^^^^ no value can reach this
+
+error: unreachable pattern
+ --> $DIR/unreachable-patterns.rs:30:9
+ |
+LL | (T::A | T::B, T::A | T::C) => {}
+ | -------------------------- matches all the relevant values
+LL | (T::A, T::C) => {}
+LL | (T::B, T::A) => {}
+ | ^^^^^^^^^^^^ no value can reach this
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/pattern/normalize-ty-in-range.rs b/tests/ui/pattern/normalize-ty-in-range.rs
new file mode 100644
index 0000000..f0d2236
--- /dev/null
+++ b/tests/ui/pattern/normalize-ty-in-range.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/200>.
+// Make sure we structurally normalize in range pattern checking in HIR typeck.
+
+trait Foo {
+ type Bar;
+}
+
+impl Foo for () {
+ type Bar = i32;
+}
+
+fn main() {
+ const X: <() as Foo>::Bar = 0;
+
+ match 0 {
+ X..=X => {}
+ _ => {}
+ }
+}
diff --git a/tests/ui/pub/pub-restricted-warning.rs b/tests/ui/pub/pub-restricted-warning.rs
new file mode 100644
index 0000000..80384af
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-warning.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+
+#![allow(dead_code)]
+
+mod outer {
+ pub mod inner {
+ pub(in crate::outer) struct Foo;
+ pub fn bar() -> Foo {
+ //~^ WARNING type `Foo` is more private than the item `outer::inner::bar` [private_interfaces]
+ Foo
+ }
+ }
+
+ pub mod nested {
+ pub mod inner {
+ pub(in crate::outer::nested) struct NestedFoo;
+ pub fn bar() -> NestedFoo {
+ //~^ WARNING type `NestedFoo` is more private than the item `nested::inner::bar` [private_interfaces]
+ NestedFoo
+ }
+ }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/pub/pub-restricted-warning.stderr b/tests/ui/pub/pub-restricted-warning.stderr
new file mode 100644
index 0000000..74f32d3
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-warning.stderr
@@ -0,0 +1,27 @@
+warning: type `Foo` is more private than the item `outer::inner::bar`
+ --> $DIR/pub-restricted-warning.rs:8:9
+ |
+LL | pub fn bar() -> Foo {
+ | ^^^^^^^^^^^^^^^^^^^ function `outer::inner::bar` is reachable at visibility `pub(crate)`
+ |
+note: but type `Foo` is only usable at visibility `pub(in crate::outer)`
+ --> $DIR/pub-restricted-warning.rs:7:9
+ |
+LL | pub(in crate::outer) struct Foo;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: `#[warn(private_interfaces)]` on by default
+
+warning: type `NestedFoo` is more private than the item `nested::inner::bar`
+ --> $DIR/pub-restricted-warning.rs:17:13
+ |
+LL | pub fn bar() -> NestedFoo {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `nested::inner::bar` is reachable at visibility `pub(crate)`
+ |
+note: but type `NestedFoo` is only usable at visibility `pub(in crate::outer::nested)`
+ --> $DIR/pub-restricted-warning.rs:16:13
+ |
+LL | pub(in crate::outer::nested) struct NestedFoo;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/parse.rs b/tests/ui/rfcs/rfc-0000-never_patterns/parse.rs
index 566bb07..e004e66 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/parse.rs
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/parse.rs
@@ -65,7 +65,7 @@ fn parse(x: Void) {
let res: Result<bool, Void> = Ok(false);
let Ok(_) = res;
let Ok(_) | Err(!) = &res; // Disallowed; see #82048.
- //~^ ERROR top-level or-patterns are not allowed in `let` bindings
+ //~^ ERROR `let` bindings require top-level or-patterns in parentheses
let (Ok(_) | Err(!)) = &res;
let (Ok(_) | Err(&!)) = res.as_ref();
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/parse.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/parse.stderr
index 0598051..320e157 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/parse.stderr
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/parse.stderr
@@ -26,7 +26,7 @@
LL | Some(!) <=
| ^^ expected one of `,`, `=>`, `if`, `|`, or `}`
-error: top-level or-patterns are not allowed in `let` bindings
+error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/parse.rs:67:9
|
LL | let Ok(_) | Err(!) = &res; // Disallowed; see #82048.
diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs
index afc96d6..37fce27 100644
--- a/tests/ui/runtime/backtrace-debuginfo.rs
+++ b/tests/ui/runtime/backtrace-debuginfo.rs
@@ -42,9 +42,13 @@ macro_rules! dump_and_die {
// there, even on i686-pc-windows-msvc. We do the best we can in
// rust-lang/rust to test it as well, but sometimes we just gotta keep
// landing PRs.
+ //
+ // aarch64-msvc is broken as its backtraces are truncated.
+ // See https://github.com/rust-lang/rust/issues/140489
if cfg!(any(target_os = "android",
all(target_os = "linux", target_arch = "arm"),
all(target_env = "msvc", target_arch = "x86"),
+ all(target_env = "msvc", target_arch = "aarch64"),
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd")) {
diff --git a/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
index e26cb22..f8a6252 100644
--- a/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
+++ b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
@@ -10,26 +10,53 @@
LL | fn foo<'a, K>(self, _: (), _: K) where {
| ^^^^^^^ lifetimes do not match method in trait
-error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
- --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:23:11
+error[E0195]: lifetime parameters do not match the trait definition
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:23:12
|
-LL | fn foo<'a>(&self, state: &'a State) -> &'a T
- | ---- lifetimes in impl do not match this method in trait
-LL | where
-LL | T: 'a;
- | -- this bound might be missing in the impl
-...
LL | fn foo<'a>(&self, state: &'a State) -> &'a T {
- | ^^^^ lifetimes do not match method in trait
-
-error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
- --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:33:11
+ | ^^
|
-LL | fn foo<'a>(&'a self) {}
- | ---- lifetimes in impl do not match this method in trait
+ = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'a` differs between the trait and impl
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:14:12
+ |
+LL | trait Foo<T> {
+ | ------------ in this trait...
+LL | fn foo<'a>(&self, state: &'a State) -> &'a T
+ | ^^ `'a` is early-bound
+LL | where
+LL | T: 'a;
+ | -- this lifetime bound makes `'a` early-bound
...
+LL | / impl<F, T> Foo<T> for F
+LL | | where
+LL | | F: Fn(&State) -> &T,
+ | |________________________- in this impl...
+LL | {
+LL | fn foo<'a>(&self, state: &'a State) -> &'a T {
+ | ^^ `'a` is late-bound
+
+error[E0195]: lifetime parameters do not match the trait definition
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:33:12
+ |
LL | fn foo<'a: 'a>(&'a self) {}
- | ^^^^^^^^ lifetimes do not match method in trait
+ | ^^
+ |
+ = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'a` differs between the trait and impl
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:29:12
+ |
+LL | trait Bar {
+ | --------- in this trait...
+LL | fn foo<'a>(&'a self) {}
+ | ^^ `'a` is late-bound
+...
+LL | impl Bar for () {
+ | --------------- in this impl...
+LL | fn foo<'a: 'a>(&'a self) {}
+ | ^^ -- this lifetime bound makes `'a` early-bound
+ | |
+ | `'a` is early-bound
error: aborting due to 3 previous errors
diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs
new file mode 100644
index 0000000..f90ff91
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs
@@ -0,0 +1,32 @@
+// This test demonstrates an ICE that may occur when we try to resolve the instance
+// of a impl that has different generics than the trait it's implementing. This ensures
+// we first check that the args are compatible before resolving the body, just like
+// we do in projection before substituting a GAT.
+//
+// Regression test for issue #125877.
+
+//@ compile-flags: -Znext-solver
+
+#![feature(const_trait_impl, effects)]
+//~^ ERROR feature has been removed
+
+#[const_trait]
+trait Main {
+ fn compute<T: ~const Aux>() -> u32;
+}
+
+impl const Main for () {
+ fn compute<'x>() -> u32 {
+ //~^ ERROR associated function `compute` has 0 type parameters but its trait declaration has 1 type parameter
+ 0
+ }
+}
+
+#[const_trait]
+trait Aux {}
+
+impl const Aux for () {}
+
+fn main() {
+ const _: u32 = <()>::compute::<()>();
+}
diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr
new file mode 100644
index 0000000..d45c4cb
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr
@@ -0,0 +1,21 @@
+error[E0557]: feature has been removed
+ --> $DIR/const-trait-impl-parameter-mismatch.rs:10:30
+ |
+LL | #![feature(const_trait_impl, effects)]
+ | ^^^^^^^ feature has been removed
+ |
+ = note: removed, redundant with `#![feature(const_trait_impl)]`
+
+error[E0049]: associated function `compute` has 0 type parameters but its trait declaration has 1 type parameter
+ --> $DIR/const-trait-impl-parameter-mismatch.rs:19:16
+ |
+LL | fn compute<T: ~const Aux>() -> u32;
+ | - expected 1 type parameter
+...
+LL | fn compute<'x>() -> u32 {
+ | ^^ found 0 type parameters
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0049, E0557.
+For more information about an error, try `rustc --explain E0049`.
diff --git a/tests/ui/traits/next-solver/global-param-env-after-norm.rs b/tests/ui/traits/next-solver/global-param-env-after-norm.rs
new file mode 100644
index 0000000..0d098db
--- /dev/null
+++ b/tests/ui/traits/next-solver/global-param-env-after-norm.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+
+struct NewSolver;
+struct OldSolver;
+
+fn foo<T>()
+where
+ T: Iterator<Item = NewSolver>,
+ OldSolver: Into<T::Item>,
+{
+ let x: OldSolver = OldSolver.into();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr
index e91a48f..f5fd9ce 100644
--- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr
+++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr
@@ -4,24 +4,6 @@
LL | <T as Trait>::Assoc: Trait,
| ^^^^^
-error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed`
- --> $DIR/normalize-param-env-4.rs:19:26
- |
-LL | <T as Trait>::Assoc: Trait,
- | ^^^^^
-
-error[E0275]: overflow evaluating the requirement `T: Trait`
- --> $DIR/normalize-param-env-4.rs:32:19
- |
-LL | impls_trait::<T>();
- | ^
- |
-note: required by a bound in `impls_trait`
- --> $DIR/normalize-param-env-4.rs:15:19
- |
-LL | fn impls_trait<T: Trait>() {}
- | ^^^^^ required by this bound in `impls_trait`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs b/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs
new file mode 100644
index 0000000..e0668ac
--- /dev/null
+++ b/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs
@@ -0,0 +1,25 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@ check-pass
+#![crate_type = "lib"]
+trait Eq<T> {}
+impl<T> Eq<T> for T {}
+trait ConstrainAndEq<T> {}
+impl<T, U> ConstrainAndEq<T> for U
+where
+ T: FnOnce() -> u32,
+ U: FnOnce() -> u32,
+ T: Eq<U>,
+{}
+
+fn constrain_and_eq<T: ConstrainAndEq<U>, U>(_: T, _: U) {}
+fn foo<'a>() -> impl Sized + use<'a> {
+ // This proves `foo<'a>: FnOnce() -> u32` and `foo<'1>: FnOnce() -> u32`,
+ // We constrain both `opaque<'a>` and `opaque<'1>` to `u32`, resulting in
+ // two distinct opaque type uses. Proving `foo<'a>: Eq<foo<'1>>` then
+ // equates the two regions at which point the two opaque type keys are now
+ // equal. This previously caused an ICE.
+ constrain_and_eq(foo::<'a>, foo::<'_>);
+ 1u32
+}
diff --git a/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs b/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs
new file mode 100644
index 0000000..4b20cd1
--- /dev/null
+++ b/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs
@@ -0,0 +1,56 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/201>.
+// See comment below on `fn main`.
+
+trait Intersect<U> {
+ type Output;
+}
+
+impl<T, U> Intersect<Vec<U>> for T
+where
+ T: Intersect<U>,
+{
+ type Output = T;
+}
+
+impl Intersect<Cuboid> for Cuboid {
+ type Output = Cuboid;
+}
+
+fn intersect<T, U>(_: &T, _: &U) -> T::Output
+where
+ T: Intersect<U>,
+{
+ todo!()
+}
+
+struct Cuboid;
+impl Cuboid {
+ fn method(&self) {}
+}
+
+fn main() {
+ let x = vec![];
+ // Here we end up trying to normalize `<Cuboid as Intersect<Vec<?0>>>::Output`
+ // for the return type of the function, to constrain `y`. The impl then requires
+ // `Cuboid: Intersect<?0>`, which has two candidates. One that constrains
+ // `?0 = Vec<?1>`, which itself has the same two candidates and ends up leading
+ // to a recursion depth overflow. In the second impl, we constrain `?0 = Cuboid`.
+ //
+ // Floundering leads to us combining the overflow candidate and yes candidate to
+ // overflow. Because the response was overflow, we used to bubble it up to the
+ // parent normalizes-to goal, which caused us to drop its constraint that would
+ // guide us to normalize the associated type mentioned before.
+ //
+ // After this PR, we implement a new floundering "algebra" such that `Overflow OR Maybe`
+ // returns anew `Overflow { keep_constraints: true }`, which means that we don't
+ // need to drop constraints in the parent normalizes-to goal. This allows us to
+ // normalize `y` to `Cuboid`, and allows us to call the method successfully. We
+ // then constrain the `?0` in `let x: Vec<Cuboid> = x` below, so that we don't have
+ // a left over ambiguous goal.
+ let y = intersect(&Cuboid, &x);
+ y.method();
+ let x: Vec<Cuboid> = x;
+}
diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.rs b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs
new file mode 100644
index 0000000..4640d6b
--- /dev/null
+++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/rust/issues/140645>.
+// Test that we lower impossible-to-satisfy associated type bounds, which
+// may for example constrain impl parameters.
+
+pub trait Other {}
+
+pub trait Trait {
+ type Assoc
+ where
+ Self: Sized;
+}
+
+impl Other for dyn Trait {}
+// `dyn Trait<Assoc = ()>` is a different "nominal type" than `dyn Trait`.
+impl Other for dyn Trait<Assoc = ()> {}
+//~^ WARN unnecessary associated type bound for dyn-incompatible associated type
+
+// I hope it's clear that `dyn Trait` (w/o `Assoc`) wouldn't match this impl.
+impl<T> dyn Trait<Assoc = T> {}
+//~^ WARN unnecessary associated type bound for dyn-incompatible associated type
+
+fn main() {}
diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr b/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr
new file mode 100644
index 0000000..4383ca8
--- /dev/null
+++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr
@@ -0,0 +1,19 @@
+warning: unnecessary associated type bound for dyn-incompatible associated type
+ --> $DIR/constrain-via-unnecessary-bound.rs:17:26
+ |
+LL | impl Other for dyn Trait<Assoc = ()> {}
+ | ^^^^^^^^^^ help: remove this bound
+ |
+ = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
+ = note: `#[warn(unused_associated_type_bounds)]` on by default
+
+warning: unnecessary associated type bound for dyn-incompatible associated type
+ --> $DIR/constrain-via-unnecessary-bound.rs:21:19
+ |
+LL | impl<T> dyn Trait<Assoc = T> {}
+ | ^^^^^^^^^ help: remove this bound
+ |
+ = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr
index 37fe142..2f9fdf1 100644
--- a/tests/ui/traits/object/pretty.stderr
+++ b/tests/ui/traits/object/pretty.stderr
@@ -154,12 +154,12 @@
--> $DIR/pretty.rs:41:56
|
LL | fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x }
- | - ^ expected `()`, found `&dyn HasGat<u8>`
+ | - ^ expected `()`, found `&dyn HasGat<u8, Assoc<bool> = ()>`
| |
- | help: try adding a return type: `-> &dyn HasGat<u8>`
+ | help: try adding a return type: `-> &dyn HasGat<u8, Assoc<bool> = ()>`
|
= note: expected unit type `()`
- found reference `&dyn HasGat<u8>`
+ found reference `&dyn HasGat<u8, Assoc<bool> = ()>`
error: aborting due to 14 previous errors; 1 warning emitted
diff --git a/tests/ui/traits/suggest-remove-deref-issue-140166.rs b/tests/ui/traits/suggest-remove-deref-issue-140166.rs
new file mode 100644
index 0000000..1b832c7
--- /dev/null
+++ b/tests/ui/traits/suggest-remove-deref-issue-140166.rs
@@ -0,0 +1,18 @@
+trait Trait {}
+
+struct Chars;
+impl Trait for Chars {}
+
+struct FlatMap<T>(T);
+impl<T: Trait> std::fmt::Debug for FlatMap<T> {
+ fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ unimplemented!()
+ }
+}
+
+fn lol() {
+ format_args!("{:?}", FlatMap(&Chars));
+ //~^ ERROR the trait bound `&Chars: Trait` is not satisfied [E0277]
+}
+
+fn main() {}
diff --git a/tests/ui/traits/suggest-remove-deref-issue-140166.stderr b/tests/ui/traits/suggest-remove-deref-issue-140166.stderr
new file mode 100644
index 0000000..90f24d8
--- /dev/null
+++ b/tests/ui/traits/suggest-remove-deref-issue-140166.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `&Chars: Trait` is not satisfied
+ --> $DIR/suggest-remove-deref-issue-140166.rs:14:26
+ |
+LL | format_args!("{:?}", FlatMap(&Chars));
+ | ---- ^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `&Chars`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Trait` is implemented for `Chars`
+note: required for `FlatMap<&Chars>` to implement `Debug`
+ --> $DIR/suggest-remove-deref-issue-140166.rs:7:16
+ |
+LL | impl<T: Trait> std::fmt::Debug for FlatMap<T> {
+ | ----- ^^^^^^^^^^^^^^^ ^^^^^^^^^^
+ | |
+ | unsatisfied trait bound introduced here
+note: required by a bound in `core::fmt::rt::Argument::<'_>::new_debug`
+ --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmute/unnecessary-transmutation.fixed b/tests/ui/transmute/unnecessary-transmutation.fixed
index 1a0df14..bf7d769 100644
--- a/tests/ui/transmute/unnecessary-transmutation.fixed
+++ b/tests/ui/transmute/unnecessary-transmutation.fixed
@@ -49,6 +49,10 @@
//~^ ERROR
let y: char = char::from_u32_unchecked(y);
//~^ ERROR
+ let y: i32 = u32::from('🐱').cast_signed();
+ //~^ ERROR
+ let y: char = char::from_u32_unchecked(i32::cast_unsigned(y));
+ //~^ ERROR
let x: u16 = i16::cast_unsigned(8i16);
//~^ ERROR
@@ -72,6 +76,11 @@
let y: u64 = f64::to_bits(2.0);
//~^ ERROR
+ let y: f64 = f64::from_bits(i64::cast_unsigned(1i64));
+ //~^ ERROR
+ let y: i64 = f64::to_bits(1f64).cast_signed();
+ //~^ ERROR
+
let z: bool = (1u8 == 1);
//~^ ERROR
let z: u8 = (z) as u8;
diff --git a/tests/ui/transmute/unnecessary-transmutation.rs b/tests/ui/transmute/unnecessary-transmutation.rs
index 6b97926..b9de529 100644
--- a/tests/ui/transmute/unnecessary-transmutation.rs
+++ b/tests/ui/transmute/unnecessary-transmutation.rs
@@ -49,6 +49,10 @@ fn main() {
//~^ ERROR
let y: char = transmute(y);
//~^ ERROR
+ let y: i32 = transmute('🐱');
+ //~^ ERROR
+ let y: char = transmute(y);
+ //~^ ERROR
let x: u16 = transmute(8i16);
//~^ ERROR
@@ -72,6 +76,11 @@ fn main() {
let y: u64 = transmute(2.0);
//~^ ERROR
+ let y: f64 = transmute(1i64);
+ //~^ ERROR
+ let y: i64 = transmute(1f64);
+ //~^ ERROR
+
let z: bool = transmute(1u8);
//~^ ERROR
let z: u8 = transmute(z);
diff --git a/tests/ui/transmute/unnecessary-transmutation.stderr b/tests/ui/transmute/unnecessary-transmutation.stderr
index b661aa1..a19f1be 100644
--- a/tests/ui/transmute/unnecessary-transmutation.stderr
+++ b/tests/ui/transmute/unnecessary-transmutation.stderr
@@ -154,82 +154,108 @@
= help: consider `char::from_u32(…).unwrap()`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:53:22
+ --> $DIR/unnecessary-transmutation.rs:52:22
+ |
+LL | let y: i32 = transmute('🐱');
+ | ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🐱').cast_signed()`
+
+error: unnecessary transmute
+ --> $DIR/unnecessary-transmutation.rs:54:23
+ |
+LL | let y: char = transmute(y);
+ | ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(i32::cast_unsigned(y))`
+ |
+ = help: consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`
+
+error: unnecessary transmute
+ --> $DIR/unnecessary-transmutation.rs:57:22
|
LL | let x: u16 = transmute(8i16);
| ^^^^^^^^^^^^^^^ help: replace this with: `i16::cast_unsigned(8i16)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:55:22
+ --> $DIR/unnecessary-transmutation.rs:59:22
|
LL | let x: i16 = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u16::cast_signed(x)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:57:22
+ --> $DIR/unnecessary-transmutation.rs:61:22
|
LL | let x: u32 = transmute(4i32);
| ^^^^^^^^^^^^^^^ help: replace this with: `i32::cast_unsigned(4i32)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:59:22
+ --> $DIR/unnecessary-transmutation.rs:63:22
|
LL | let x: i32 = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u32::cast_signed(x)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:61:22
+ --> $DIR/unnecessary-transmutation.rs:65:22
|
LL | let x: u64 = transmute(7i64);
| ^^^^^^^^^^^^^^^ help: replace this with: `i64::cast_unsigned(7i64)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:63:22
+ --> $DIR/unnecessary-transmutation.rs:67:22
|
LL | let x: i64 = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u64::cast_signed(x)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:66:22
+ --> $DIR/unnecessary-transmutation.rs:70:22
|
LL | let y: f32 = transmute(1u32);
| ^^^^^^^^^^^^^^^ help: replace this with: `f32::from_bits(1u32)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:68:22
+ --> $DIR/unnecessary-transmutation.rs:72:22
|
LL | let y: u32 = transmute(y);
| ^^^^^^^^^^^^ help: replace this with: `f32::to_bits(y)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:70:22
+ --> $DIR/unnecessary-transmutation.rs:74:22
|
LL | let y: f64 = transmute(3u64);
| ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(3u64)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:72:22
+ --> $DIR/unnecessary-transmutation.rs:76:22
|
LL | let y: u64 = transmute(2.0);
| ^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(2.0)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:75:23
+ --> $DIR/unnecessary-transmutation.rs:79:22
+ |
+LL | let y: f64 = transmute(1i64);
+ | ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(i64::cast_unsigned(1i64))`
+
+error: unnecessary transmute
+ --> $DIR/unnecessary-transmutation.rs:81:22
+ |
+LL | let y: i64 = transmute(1f64);
+ | ^^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(1f64).cast_signed()`
+
+error: unnecessary transmute
+ --> $DIR/unnecessary-transmutation.rs:84:23
|
LL | let z: bool = transmute(1u8);
| ^^^^^^^^^^^^^^ help: replace this with: `(1u8 == 1)`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:77:21
+ --> $DIR/unnecessary-transmutation.rs:86:21
|
LL | let z: u8 = transmute(z);
| ^^^^^^^^^^^^ help: replace this with: `(z) as u8`
error: unnecessary transmute
- --> $DIR/unnecessary-transmutation.rs:82:21
+ --> $DIR/unnecessary-transmutation.rs:91:21
|
LL | let z: i8 = transmute(z);
| ^^^^^^^^^^^^ help: replace this with: `(z) as i8`
-error: aborting due to 32 previous errors
+error: aborting due to 36 previous errors
diff --git a/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs
new file mode 100644
index 0000000..bfaa485
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs
@@ -0,0 +1,16 @@
+// https://github.com/rust-lang/rust/issues/140731
+// This tests that there's no def path conflict between the
+// remapped lifetime and the lifetime present in the source.
+
+#![feature(impl_trait_in_assoc_type)]
+
+trait Trait<'a> {}
+
+impl<'a> Trait<'a> for u32 {
+ type Opq2 = impl for<'a> Trait<'a>;
+ //~^ ERROR: unconstrained opaque type
+ //~| ERROR: type `Opq2` is not a member of trait `Trait`
+ //~| ERROR: lifetime name `'a` shadows a lifetime name that is already in scope
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr
new file mode 100644
index 0000000..e1544c5
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr
@@ -0,0 +1,26 @@
+error[E0437]: type `Opq2` is not a member of trait `Trait`
+ --> $DIR/lifetime-def-path-conflict-40731.rs:10:5
+ |
+LL | type Opq2 = impl for<'a> Trait<'a>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Trait`
+
+error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
+ --> $DIR/lifetime-def-path-conflict-40731.rs:10:26
+ |
+LL | impl<'a> Trait<'a> for u32 {
+ | -- first declared here
+LL | type Opq2 = impl for<'a> Trait<'a>;
+ | ^^ lifetime `'a` already in scope
+
+error: unconstrained opaque type
+ --> $DIR/lifetime-def-path-conflict-40731.rs:10:17
+ |
+LL | type Opq2 = impl for<'a> Trait<'a>;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Opq2` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0437, E0496.
+For more information about an error, try `rustc --explain E0437`.
diff --git a/triagebot.toml b/triagebot.toml
index 422996c..1f0afdc 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1001,7 +1001,15 @@
message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the corresponding `ui` subdir and add 'Fixes #<issueNr>' to the PR description to autoclose the issue upon merge."
[mentions."tests/rustdoc-json"]
-cc = ["@aDotInTheVoid"]
+message = """
+These commits modify `tests/rustdoc-json`.
+rustdoc-json is a **public** (but unstable) interface.
+
+Please ensure that if you've changed the output:
+- It's intentional.
+- The `FORMAT_VERSION` in `src/librustdoc-json-types` is bumped if necessary.
+"""
+cc = ["@aDotInTheVoid", "@obi1kenobi"]
[mentions."tests/ui/deriving/deriving-all-codegen.stdout"]
message = "Changes to the code generated for builtin derived traits."
@@ -1161,7 +1169,6 @@
"@BoxyUwU",
"@compiler-errors",
"@davidtwco",
- "@estebank",
"@fee1-dead",
"@fmease",
"@jieyouxu",
@@ -1221,14 +1228,12 @@
diagnostics = [
"@compiler-errors",
"@davidtwco",
- "@estebank",
"@oli-obk",
"@chenyukang",
]
parser = [
"@compiler-errors",
"@davidtwco",
- "@estebank",
"@nnethercote",
"@petrochenkov",
"@spastorino",
@@ -1236,7 +1241,6 @@
lexer = [
"@nnethercote",
"@petrochenkov",
- "@estebank",
"@chenyukang",
]
arena = [
@@ -1268,7 +1272,6 @@
]
ast_lowering = [
"@compiler-errors",
- "@estebank",
"@spastorino",
]
debuginfo = [
@@ -1394,3 +1397,7 @@
# Enable issue transfers within the org
# Documentation at: https://forge.rust-lang.org/triagebot/transfer.html
[transfer]
+
+# Enable `@rustbot note` functionality
+# Documentation at: https://forge.rust-lang.org/triagebot/note.html
+[note]