From a917fd5f98913a04b839cccca43558f4e4fc831b Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 11 Feb 2025 22:16:07 +0800 Subject: [PATCH 01/16] Fix diagnostic when using = instead of : in let bindings --- .../rustc_resolve/src/late/diagnostics.rs | 23 +++++++++++++++- .../let-binding-suggest-issue-133713.fixed | 12 +++++++++ .../let-binding-suggest-issue-133713.rs | 12 +++++++++ .../let-binding-suggest-issue-133713.stderr | 27 +++++++++++++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 tests/ui/suggestions/let-binding-suggest-issue-133713.fixed create mode 100644 tests/ui/suggestions/let-binding-suggest-issue-133713.rs create mode 100644 tests/ui/suggestions/let-binding-suggest-issue-133713.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a80b68d9773d..0962865e7f19 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2347,9 +2347,14 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // try to give a suggestion for this pattern: `name = blah`, which is common in other languages // suggest `let name = blah` to introduce a new binding fn let_binding_suggestion(&mut self, err: &mut Diag<'_>, ident_span: Span) -> bool { + if ident_span.from_expansion() { + return false; + } + + // only suggest when the code is a assignment without prefix code if let Some(Expr { kind: ExprKind::Assign(lhs, ..), .. }) = self.diag_metadata.in_assignment && let ast::ExprKind::Path(None, ref path) = lhs.kind - && !ident_span.from_expansion() + && self.r.tcx.sess.source_map().is_line_before_span_empty(ident_span) { let (span, text) = match path.segments.first() { Some(seg) if let Some(name) = seg.ident.as_str().strip_prefix("let") => { @@ -2368,6 +2373,22 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); return true; } + + // a special case for #133713 + // '=' maybe a typo of `:`, which is a type annotation instead of assignment + if err.code == Some(E0423) + && let Some((let_span, None, Some(val_span))) = self.diag_metadata.current_let_binding + && val_span.contains(ident_span) + && val_span.lo() == ident_span.lo() + { + err.span_suggestion_verbose( + let_span.shrink_to_hi().to(val_span.shrink_to_lo()), + "you might have meant to use `:` for type annotation", + ": ", + Applicability::MaybeIncorrect, + ); + return true; + } false } diff --git a/tests/ui/suggestions/let-binding-suggest-issue-133713.fixed b/tests/ui/suggestions/let-binding-suggest-issue-133713.fixed new file mode 100644 index 000000000000..9f9c1d1bc5aa --- /dev/null +++ b/tests/ui/suggestions/let-binding-suggest-issue-133713.fixed @@ -0,0 +1,12 @@ +//@ run-rustfix +#![allow(dead_code)] + +fn demo1() { + let _last: u64 = 0; //~ ERROR expected value, found builtin type `u64` +} + +fn demo2() { + let _val: u64; //~ ERROR expected value, found builtin type `u64` +} + +fn main() {} diff --git a/tests/ui/suggestions/let-binding-suggest-issue-133713.rs b/tests/ui/suggestions/let-binding-suggest-issue-133713.rs new file mode 100644 index 000000000000..ae218237a8d5 --- /dev/null +++ b/tests/ui/suggestions/let-binding-suggest-issue-133713.rs @@ -0,0 +1,12 @@ +//@ run-rustfix +#![allow(dead_code)] + +fn demo1() { + let _last = u64 = 0; //~ ERROR expected value, found builtin type `u64` +} + +fn demo2() { + let _val = u64; //~ ERROR expected value, found builtin type `u64` +} + +fn main() {} diff --git a/tests/ui/suggestions/let-binding-suggest-issue-133713.stderr b/tests/ui/suggestions/let-binding-suggest-issue-133713.stderr new file mode 100644 index 000000000000..185ad9c928b4 --- /dev/null +++ b/tests/ui/suggestions/let-binding-suggest-issue-133713.stderr @@ -0,0 +1,27 @@ +error[E0423]: expected value, found builtin type `u64` + --> $DIR/let-binding-suggest-issue-133713.rs:5:17 + | +LL | let _last = u64 = 0; + | ^^^ + | +help: you might have meant to use `:` for type annotation + | +LL - let _last = u64 = 0; +LL + let _last: u64 = 0; + | + +error[E0423]: expected value, found builtin type `u64` + --> $DIR/let-binding-suggest-issue-133713.rs:9:16 + | +LL | let _val = u64; + | ^^^ + | +help: you might have meant to use `:` for type annotation + | +LL - let _val = u64; +LL + let _val: u64; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0423`. From d82219a4fa06bfa47fc5aac64844c461905ae77d Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Wed, 12 Feb 2025 00:37:33 +0000 Subject: [PATCH 02/16] debuginfo: Set bitwidth appropriately in enum variant tags Previously, we unconditionally set the bitwidth to 128-bits, the largest an discrimnator would possibly be. Then, LLVM would cut down the constant by chopping off leading zeroes before emitting the DWARF. LLVM only supported 64-bit descriminators, so this would also have occasionally resulted in truncated data (or an assert) if more than 64-bits were used. LLVM added support for 128-bit enumerators in llvm/llvm-project#125578 That patchset also trusts the constant to describe how wide the variant tag is. As a result, we went from emitting tags that looked like: DW_AT_discr_value (0xfe) (`form1`) to emitting tags that looked like: DW_AT_discr_value (<0x10> fe ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ) This makes the `DW_AT_discr_value` encode at the bitwidth of the tag, which: 1. Is probably closer to our intentions in terms of describing the data. 2. Doesn't invoke the 128-bit support which may not be supported by all debuggers / downstream tools. 3. Will result in smaller debug information. --- .../src/debuginfo/metadata/enums/native.rs | 8 +++++++- tests/codegen/enum/enum-debug-niche-2.rs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 11824398f243..187d97c54c87 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -437,6 +437,12 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>( .source_info .unwrap_or_else(|| (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)); + let discr = discr_value.opt_single_val().map(|value| { + let tag_base_type = tag_base_type(cx.tcx, enum_type_and_layout); + let size = cx.size_of(tag_base_type); + cx.const_uint_big(cx.type_ix(size.bits()), value) + }); + unsafe { llvm::LLVMRustDIBuilderCreateVariantMemberType( DIB(cx), @@ -448,7 +454,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>( enum_type_and_layout.size.bits(), enum_type_and_layout.align.abi.bits() as u32, Size::ZERO.bits(), - discr_value.opt_single_val().map(|value| cx.const_u128(value)), + discr, DIFlags::FlagZero, variant_member_info.variant_struct_type_di_node, ) diff --git a/tests/codegen/enum/enum-debug-niche-2.rs b/tests/codegen/enum/enum-debug-niche-2.rs index 58f43fe3ec6b..80a4081f15b1 100644 --- a/tests/codegen/enum/enum-debug-niche-2.rs +++ b/tests/codegen/enum/enum-debug-niche-2.rs @@ -5,8 +5,8 @@ //@ ignore-msvc // // CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_variant_part,{{.*}}size: 32,{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i128 4294967295{{[,)].*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i128 0{{[,)].*}} +// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i32 -1{{[,)].*}} +// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i32 0{{[,)].*}} #![feature(never_type)] #[derive(Copy, Clone)] From e663819856d605df63ea798f969aff123ead7e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 12 Feb 2025 20:02:21 +0100 Subject: [PATCH 03/16] Move `llvm.ccache` to `build.ccache` (S)ccache can be useful for more things that just LLVM. For example, we will soon want to use it also for GCC, and theoretically also for building stage0 Rust tools. --- config.example.toml | 5 +++++ src/bootstrap/configure.py | 12 ++++++++---- src/bootstrap/src/core/config/config.rs | 20 ++++++++++++-------- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/config.example.toml b/config.example.toml index 1a8f42428ab8..ad79f5d5a80c 100644 --- a/config.example.toml +++ b/config.example.toml @@ -424,6 +424,11 @@ # What custom diff tool to use for displaying compiletest tests. #compiletest-diff-tool = +# Indicates whether ccache is used when building certain artifacts (e.g. LLVM). +# Set to `true` to use the first `ccache` in PATH, or set an absolute path to use +# a specific version. +#ccache = false + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index a86c20d46bda..ac971a64d7c2 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -44,10 +44,14 @@ o("optimize-tests", "rust.optimize-tests", "build tests with optimizations") o("verbose-tests", "rust.verbose-tests", "enable verbose output when running tests") o( "ccache", - "llvm.ccache", - "invoke gcc/clang via ccache to reuse object files between builds", + "build.ccache", + "invoke gcc/clang/rustc via ccache to reuse object files between builds", +) +o( + "sccache", + None, + "invoke gcc/clang/rustc via sccache to reuse object files between builds", ) -o("sccache", None, "invoke gcc/clang via sccache to reuse object files between builds") o("local-rust", None, "use an installed rustc rather than downloading a snapshot") v("local-rust-root", None, "set prefix for local rust binary") o( @@ -510,7 +514,7 @@ def apply_args(known_args, option_checking, config): build_triple = build(known_args) if option.name == "sccache": - set("llvm.ccache", "sccache", config) + set("build.ccache", "sccache", config) elif option.name == "local-rust": for path in os.environ["PATH"].split(os.pathsep): if os.path.exists(path + "/rustc"): diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index d3ed7ecddd3d..0ee476d19c9d 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -935,6 +935,7 @@ define_config! { optimized_compiler_builtins: Option = "optimized-compiler-builtins", jobs: Option = "jobs", compiletest_diff_tool: Option = "compiletest-diff-tool", + ccache: Option = "ccache", } } @@ -1622,6 +1623,7 @@ impl Config { optimized_compiler_builtins, jobs, compiletest_diff_tool, + mut ccache, } = toml.build.unwrap_or_default(); config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0)))); @@ -2006,7 +2008,7 @@ impl Config { tests, enzyme, plugins, - ccache, + ccache: llvm_ccache, static_libstdcpp, libzstd, ninja, @@ -2029,13 +2031,7 @@ impl Config { download_ci_llvm, build_config, } = llvm; - match ccache { - Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), - Some(StringOrBool::Bool(true)) => { - config.ccache = Some("ccache".to_string()); - } - Some(StringOrBool::Bool(false)) | None => {} - } + ccache = ccache.or(llvm_ccache); set(&mut config.ninja_in_file, ninja); llvm_tests = tests; llvm_enzyme = enzyme; @@ -2189,6 +2185,14 @@ impl Config { } } + match ccache { + Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), + Some(StringOrBool::Bool(true)) => { + config.ccache = Some("ccache".to_string()); + } + Some(StringOrBool::Bool(false)) | None => {} + } + if config.llvm_from_ci { let triple = &config.build.triple; let ci_llvm_bin = config.ci_llvm_root().join("bin"); diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 6f62df28e494..9b23cf1843ef 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -345,4 +345,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "Rustdoc now respects the value of rust.lto.", }, + ChangeInfo { + change_id: 136941, + severity: ChangeSeverity::Info, + summary: "The llvm.ccache option has moved to build.ccache. llvm.ccache is now deprecated.", + }, ]; From 2c4922cf29beb8c3742c5d8dee4a9d89367b4ff2 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 12 Feb 2025 15:13:34 -0700 Subject: [PATCH 04/16] rustdoc: use better, consistent SVG icons for scraped examples This continues two ongoing projects: - Replacing ascii art with real icons that don't look like syntax, are understandable to people who're familiar with desktop computers and smart devices, and aren't ugly. - Using labels and tooltips to clarify these icons, when the limits of popular iconography hit us. In this case, I've added tooltips, because, unfortunately, there's not room for always-visible labels. --- src/librustdoc/html/static/css/rustdoc.css | 43 ++++++++++++++++++- .../html/static/js/scrape-examples.js | 12 ++++-- .../scrape-examples-button-focus.goml | 26 +++++++++++ 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index f39c0e4a3140..4f5f8f92264c 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -41,6 +41,19 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ --font-family: "Source Serif 4", NanumBarunGothic, serif; --font-family-code: "Source Code Pro", monospace; --line-number-padding: 4px; + /* scraped examples icons (34x33px) */ + --prev-arrow-image: url('data:image/svg+xml,'); + --next-arrow-image: url('data:image/svg+xml,'); + --expand-arrow-image: url('data:image/svg+xml,'); + --collapse-arrow-image: url('data:image/svg+xml,'); } :root.sans-serif { @@ -1729,7 +1742,10 @@ instead, we check that it's not a "finger" cursor. padding: 2px 0 0 4px; } .example-wrap .button-holder .copy-button::before, -.example-wrap .test-arrow::before { +.example-wrap .test-arrow::before, +.example-wrap .button-holder .prev::before, +.example-wrap .button-holder .next::before, +.example-wrap .button-holder .expand::before { filter: var(--copy-path-img-filter); } .example-wrap .button-holder .copy-button::before { @@ -1744,6 +1760,24 @@ instead, we check that it's not a "finger" cursor. padding-right: 5px; } +.example-wrap .button-holder .prev, +.example-wrap .button-holder .next, +.example-wrap .button-holder .expand { + line-height: 0px; +} +.example-wrap .button-holder .prev::before { + content: var(--prev-arrow-image); +} +.example-wrap .button-holder .next::before { + content: var(--next-arrow-image); +} +.example-wrap .button-holder .expand::before { + content: var(--expand-arrow-image); +} +.example-wrap .button-holder .expand.collapse::before { + content: var(--collapse-arrow-image); +} + .code-attribute { font-weight: 300; color: var(--code-attribute-color); @@ -2012,6 +2046,13 @@ button#toggle-all-docs:before { filter: var(--settings-menu-filter); } +button#toggle-all-docs.will-expand:before { + /* Custom arrow icon */ + content: url('data:image/svg+xml,\ + '); +} + #help-button > a:before { /* Question mark with circle */ content: url('data:image/svg+xml, 1) { - const next = createScrapeButton(buttonHolder, "next", "≻"); - const prev = createScrapeButton(buttonHolder, "prev", "≺"); + const next = createScrapeButton(buttonHolder, "next", "Next usage"); + const prev = createScrapeButton(buttonHolder, "prev", "Previous usage"); // Toggle through list of examples in a given file const onChangeLoc = changeIndex => { @@ -94,9 +94,13 @@ expandButton.addEventListener("click", () => { if (hasClass(example, "expanded")) { removeClass(example, "expanded"); + removeClass(expandButton, "collapse"); + expandButton.title = "Show all"; scrollToLoc(example, locs[0][0], isHidden); } else { addClass(example, "expanded"); + addClass(expandButton, "collapse"); + expandButton.title = "Show single example"; } }); } diff --git a/tests/rustdoc-gui/scrape-examples-button-focus.goml b/tests/rustdoc-gui/scrape-examples-button-focus.goml index d53993ac08ba..12246a376615 100644 --- a/tests/rustdoc-gui/scrape-examples-button-focus.goml +++ b/tests/rustdoc-gui/scrape-examples-button-focus.goml @@ -19,3 +19,29 @@ press-key: "Enter" assert-property: (".scraped-example-list > .scraped-example .rust", { "scrollTop": |initialScrollTop| }, NEAR) + +// Make sure all the buttons are the same size +store-property: (".scraped-example-list > .scraped-example .prev", { + "offsetWidth": buttonWidth, + "offsetHeight": buttonHeight, +}) +assert-property: (".scraped-example-list > .scraped-example .prev", { + "offsetWidth": |buttonWidth|, + "offsetHeight": |buttonHeight|, + "title": "Previous usage", +}) +assert-property: (".scraped-example-list > .scraped-example .next", { + "offsetWidth": |buttonWidth|, + "offsetHeight": |buttonHeight|, + "title": "Next usage", +}) +assert-property: (".scraped-example-list > .scraped-example .expand", { + "offsetWidth": |buttonWidth|, + "offsetHeight": |buttonHeight|, + "title": "Show all", +}) +assert-property: (".scraped-example-list > .scraped-example .copy-button", { + "offsetWidth": |buttonWidth|, + "offsetHeight": |buttonHeight|, + "title": "Copy code to clipboard", +}) From ab786d3b98d640b1208eff371c1184e3e8ce1d17 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 11 Feb 2025 14:09:11 +1100 Subject: [PATCH 05/16] coverage: Eliminate more counters by giving them to unreachable nodes When preparing a function's coverage counters and metadata during codegen, any part of the original coverage graph that was removed by MIR optimizations can be treated as having an execution count of zero. Somewhat counter-intuitively, if we give those unreachable nodes a _higher_ priority for receiving physical counters (instead of counter expressions), that ends up reducing the total number of physical counters needed. This works because if a node is unreachable, we don't actually create a physical counter for it. Instead that node gets a fixed zero counter, and any other node that would have relied on that physical counter in its counter expression can just ignore that term completely. --- .../src/coverage/counters.rs | 8 +- .../rustc_mir_transform/src/coverage/query.rs | 19 +- tests/coverage/assert_not.cov-map | 12 +- tests/coverage/async2.cov-map | 12 +- tests/coverage/bad_counter_ids.cov-map | 18 +- tests/coverage/conditions.cov-map | 321 +++++++++--------- tests/coverage/drop_trait.cov-map | 6 +- tests/coverage/generics.cov-map | 6 +- tests/coverage/loops_branches.cov-map | 34 +- tests/coverage/try_error_result.cov-map | 24 +- tests/coverage/while.cov-map | 6 +- 11 files changed, 237 insertions(+), 229 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index 6f9984d5d0ac..039f346495be 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -114,12 +114,8 @@ pub(crate) fn transcribe_counters( let mut new_counters_for_sites = |sites: Vec| { sites.into_iter().map(|node| new.ensure_phys_counter(node)).collect::>() }; - let mut pos = new_counters_for_sites(pos); - let mut neg = new_counters_for_sites(neg); - - // These sorts are also not strictly necessary; see above. - pos.sort(); - neg.sort(); + let pos = new_counters_for_sites(pos); + let neg = new_counters_for_sites(neg); let pos_counter = new.make_sum(&pos).unwrap_or(CovTerm::Zero); let new_counter = new.make_subtracted_sum(pos_counter, &neg); diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index cd89fbe772d4..ef86358b2057 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -123,11 +123,20 @@ fn coverage_ids_info<'tcx>( } } - // FIXME(Zalathar): It should be possible to sort `priority_list[1..]` by - // `!bcbs_seen.contains(bcb)` to simplify the mappings even further, at the - // expense of some churn in the tests. When doing so, also consider removing - // the sorts in `transcribe_counters`. - let node_counters = make_node_counters(&fn_cov_info.node_flow_data, &fn_cov_info.priority_list); + // Clone the priority list so that we can re-sort it. + let mut priority_list = fn_cov_info.priority_list.clone(); + // The first ID in the priority list represents the synthetic "sink" node, + // and must remain first so that it _never_ gets a physical counter. + debug_assert_eq!(priority_list[0], priority_list.iter().copied().max().unwrap()); + assert!(!bcbs_seen.contains(priority_list[0])); + // Partition the priority list, so that unreachable nodes (removed by MIR opts) + // are sorted later and therefore are _more_ likely to get a physical counter. + // This is counter-intuitive, but it means that `transcribe_counters` can + // easily skip those unused physical counters and replace them with zero. + // (The original ordering remains in effect within both partitions.) + priority_list[1..].sort_by_key(|&bcb| !bcbs_seen.contains(bcb)); + + let node_counters = make_node_counters(&fn_cov_info.node_flow_data, &priority_list); let coverage_counters = transcribe_counters(&node_counters, &bcb_needs_counter, &bcbs_seen); let CoverageCounters { diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map index 35568a98af44..526110ebbb76 100644 --- a/tests/coverage/assert_not.cov-map +++ b/tests/coverage/assert_not.cov-map @@ -1,13 +1,13 @@ Function name: assert_not::main -Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 12, 05, 02, 05, 00, 14, 09, 01, 05, 00, 14, 0d, 01, 05, 00, 16, 0d, 01, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 12, 01, 02, 05, 00, 14, 01, 01, 05, 00, 14, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 6, 1) to (start + 1, 18) -- Code(Counter(1)) at (prev + 2, 5) to (start + 0, 20) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 20) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 22) -- Code(Counter(3)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c3 +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 20) +- 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/async2.cov-map b/tests/coverage/async2.cov-map index 7660f917b65a..c2a0645ee9a8 100644 --- a/tests/coverage/async2.cov-map +++ b/tests/coverage/async2.cov-map @@ -8,16 +8,16 @@ Number of file 0 mappings: 1 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, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] +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] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 15, 23) to (start + 3, 9) -- Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6) +- Code(Counter(0)) at (prev + 3, 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: c1 +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] @@ -47,14 +47,14 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: async2::non_async_func -Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] +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] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 7, 1) to (start + 3, 9) -- Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6) +- Code(Counter(0)) at (prev + 3, 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: c1 +Highest counter ID seen: c0 diff --git a/tests/coverage/bad_counter_ids.cov-map b/tests/coverage/bad_counter_ids.cov-map index ba3062784493..baac0073fcbe 100644 --- a/tests/coverage/bad_counter_ids.cov-map +++ b/tests/coverage/bad_counter_ids.cov-map @@ -20,25 +20,25 @@ Number of file 0 mappings: 3 Highest counter ID seen: c0 Function name: bad_counter_ids::eq_good -Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 1f, 05, 03, 01, 00, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 1f, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 16, 1) to (start + 2, 31) -- Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c1 +- Code(Counter(0)) at (prev + 3, 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, 05, 01, 01, 00, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 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) -- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c1 +- 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, 1f, 00, 03, 01, 00, 02] @@ -51,15 +51,15 @@ Number of file 0 mappings: 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, 05, 02, 20, 00, 2b, 00, 01, 01, 00, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 51, 1) to (start + 2, 15) -- Code(Counter(1)) at (prev + 2, 32) to (start + 0, 43) +- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c1 +Highest counter ID seen: c0 Function name: bad_counter_ids::ne_good Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 1f, 01, 03, 01, 00, 02] diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map index 549b8bb0a209..2d12f4bf7744 100644 --- a/tests/coverage/conditions.cov-map +++ b/tests/coverage/conditions.cov-map @@ -1,192 +1,191 @@ Function name: conditions::main -Raw bytes (545): 0x[01, 01, 4d, 09, 0d, 01, 09, 0d, 71, 0d, 27, 71, 75, 27, 79, 71, 75, 0d, 23, 27, 79, 71, 75, 01, 03, 03, 15, 19, 65, 19, 4f, 65, 69, 4f, 6d, 65, 69, 19, 4b, 4f, 6d, 65, 69, 03, ef, 01, 15, 19, 15, 19, 1d, 25, 29, 59, 29, 7f, 59, 5d, 7f, 61, 59, 5d, 29, 7b, 7f, 61, 59, 5d, 1d, 87, 01, 25, 29, e7, 01, 1d, eb, 01, 29, ef, 01, 25, 15, 19, 31, 35, e7, 01, 1d, eb, 01, 29, ef, 01, 25, 15, 19, e7, 01, f7, 01, eb, 01, 29, ef, 01, 25, 15, 19, 1d, 31, 35, 4d, 35, df, 01, 4d, 51, df, 01, 55, 4d, 51, 35, db, 01, df, 01, 55, 4d, 51, e7, 01, f3, 01, eb, 01, 29, ef, 01, 25, 15, 19, f7, 01, 35, 1d, 31, 39, 3d, 31, 35, af, 02, 39, 31, 35, 3d, 41, 3d, a7, 02, 41, 45, a7, 02, 49, 41, 45, 3d, a3, 02, a7, 02, 49, 41, 45, af, 02, b3, 02, 31, 35, 39, 3d, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, 06, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 0d, 01, 09, 01, 12, 2a, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 11, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 15, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 19, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 19, 01, 09, 00, 17, 52, 02, 09, 00, 0f, ef, 01, 03, 08, 00, 0c, 1d, 01, 0d, 01, 10, 21, 01, 11, 02, 0a, 00, 02, 09, 00, 0a, 1d, 02, 0c, 00, 19, 25, 00, 1a, 02, 0a, 5e, 04, 11, 00, 1e, 29, 01, 10, 00, 1d, 62, 00, 21, 00, 2e, 66, 00, 32, 00, 40, 7b, 00, 41, 02, 0e, 76, 02, 0d, 00, 0e, 29, 01, 0d, 00, 1b, 82, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, 9e, 01, 02, 09, 01, 0c, 2d, 01, 0d, 02, 06, 00, 02, 05, 00, 06, af, 02, 02, 09, 00, 0a, 9e, 01, 00, 10, 00, 1d, 31, 00, 1e, 02, 06, ae, 01, 02, 0f, 00, 1c, 35, 01, 0c, 00, 19, c2, 01, 00, 1d, 00, 2a, c6, 01, 00, 2e, 00, 3c, db, 01, 00, 3d, 02, 0a, d6, 01, 02, 09, 00, 0a, 35, 01, 09, 00, 17, e2, 01, 02, 0d, 02, 0f, b3, 02, 05, 09, 00, 0a, af, 02, 00, 10, 00, 1d, 39, 00, 1e, 02, 06, 82, 02, 02, 0f, 00, 1c, 3d, 01, 0c, 00, 19, 8a, 02, 00, 1d, 00, 2a, 8e, 02, 00, 2e, 00, 3c, a3, 02, 00, 3d, 02, 0a, 9e, 02, 02, 09, 00, 0a, 3d, 01, 09, 00, 17, aa, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] +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] Number of files: 1 - file 0 => global file 1 -Number of expressions: 77 -- expression 0 operands: lhs = Counter(2), rhs = Counter(3) -- expression 1 operands: lhs = Counter(0), rhs = Counter(2) -- expression 2 operands: lhs = Counter(3), rhs = Counter(28) -- expression 3 operands: lhs = Counter(3), rhs = Expression(9, Add) -- expression 4 operands: lhs = Counter(28), rhs = Counter(29) -- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(30) -- expression 6 operands: lhs = Counter(28), rhs = Counter(29) -- expression 7 operands: lhs = Counter(3), rhs = Expression(8, Add) -- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(30) -- expression 9 operands: lhs = Counter(28), rhs = Counter(29) +Number of expressions: 71 +- 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) +- expression 3 operands: lhs = Counter(2), rhs = Expression(9, Add) +- expression 4 operands: lhs = Counter(23), rhs = Counter(24) +- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(25) +- expression 6 operands: lhs = Counter(23), rhs = Counter(24) +- expression 7 operands: lhs = Counter(2), rhs = Expression(8, Add) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(25) +- expression 9 operands: lhs = Counter(23), rhs = Counter(24) - expression 10 operands: lhs = Counter(0), rhs = Expression(0, Add) -- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(5) -- expression 12 operands: lhs = Counter(6), rhs = Counter(25) -- expression 13 operands: lhs = Counter(6), rhs = Expression(19, Add) -- expression 14 operands: lhs = Counter(25), rhs = Counter(26) -- expression 15 operands: lhs = Expression(19, Add), rhs = Counter(27) -- expression 16 operands: lhs = Counter(25), rhs = Counter(26) -- expression 17 operands: lhs = Counter(6), rhs = Expression(18, Add) -- expression 18 operands: lhs = Expression(19, Add), rhs = Counter(27) -- expression 19 operands: lhs = Counter(25), rhs = Counter(26) -- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(59, Add) -- expression 21 operands: lhs = Counter(5), rhs = Counter(6) -- expression 22 operands: lhs = Counter(5), rhs = Counter(6) -- expression 23 operands: lhs = Counter(7), rhs = Counter(9) -- expression 24 operands: lhs = Counter(10), rhs = Counter(22) -- expression 25 operands: lhs = Counter(10), rhs = Expression(31, Add) -- expression 26 operands: lhs = Counter(22), rhs = Counter(23) -- expression 27 operands: lhs = Expression(31, Add), rhs = Counter(24) -- expression 28 operands: lhs = Counter(22), rhs = Counter(23) -- expression 29 operands: lhs = Counter(10), rhs = Expression(30, Add) -- expression 30 operands: lhs = Expression(31, Add), rhs = Counter(24) -- expression 31 operands: lhs = Counter(22), rhs = Counter(23) -- expression 32 operands: lhs = Counter(7), rhs = Expression(33, Add) -- expression 33 operands: lhs = Counter(9), rhs = Counter(10) -- expression 34 operands: lhs = Expression(57, Add), rhs = Counter(7) -- expression 35 operands: lhs = Expression(58, Add), rhs = Counter(10) -- expression 36 operands: lhs = Expression(59, Add), rhs = Counter(9) -- expression 37 operands: lhs = Counter(5), rhs = Counter(6) -- expression 38 operands: lhs = Counter(12), rhs = Counter(13) -- expression 39 operands: lhs = Expression(57, Add), rhs = Counter(7) -- expression 40 operands: lhs = Expression(58, Add), rhs = Counter(10) -- expression 41 operands: lhs = Expression(59, Add), rhs = Counter(9) +- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 12 operands: lhs = Counter(4), rhs = Counter(20) +- expression 13 operands: lhs = Counter(4), rhs = Expression(19, Add) +- expression 14 operands: lhs = Counter(20), rhs = Counter(21) +- expression 15 operands: lhs = Expression(19, Add), rhs = Counter(22) +- expression 16 operands: lhs = Counter(20), rhs = Counter(21) +- 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 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 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 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 40 operands: lhs = Counter(5), rhs = Counter(6) +- expression 41 operands: lhs = Counter(7), rhs = Counter(8) - expression 42 operands: lhs = Counter(5), rhs = Counter(6) -- expression 43 operands: lhs = Expression(57, Add), rhs = Expression(61, Add) -- expression 44 operands: lhs = Expression(58, Add), rhs = Counter(10) -- expression 45 operands: lhs = Expression(59, Add), rhs = Counter(9) -- expression 46 operands: lhs = Counter(5), rhs = Counter(6) -- expression 47 operands: lhs = Counter(7), rhs = Counter(12) -- expression 48 operands: lhs = Counter(13), rhs = Counter(19) -- expression 49 operands: lhs = Counter(13), rhs = Expression(55, Add) -- expression 50 operands: lhs = Counter(19), rhs = Counter(20) -- expression 51 operands: lhs = Expression(55, Add), rhs = Counter(21) -- expression 52 operands: lhs = Counter(19), rhs = Counter(20) -- expression 53 operands: lhs = Counter(13), rhs = Expression(54, Add) -- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(21) -- expression 55 operands: lhs = Counter(19), rhs = Counter(20) -- expression 56 operands: lhs = Expression(57, Add), rhs = Expression(60, Add) -- expression 57 operands: lhs = Expression(58, Add), rhs = Counter(10) -- expression 58 operands: lhs = Expression(59, Add), rhs = Counter(9) -- expression 59 operands: lhs = Counter(5), rhs = Counter(6) -- expression 60 operands: lhs = Expression(61, Add), rhs = Counter(13) -- expression 61 operands: lhs = Counter(7), rhs = Counter(12) -- expression 62 operands: lhs = Counter(14), rhs = Counter(15) -- expression 63 operands: lhs = Counter(12), rhs = Counter(13) -- expression 64 operands: lhs = Expression(75, Add), rhs = Counter(14) -- expression 65 operands: lhs = Counter(12), rhs = Counter(13) -- expression 66 operands: lhs = Counter(15), rhs = Counter(16) -- expression 67 operands: lhs = Counter(15), rhs = Expression(73, Add) -- expression 68 operands: lhs = Counter(16), rhs = Counter(17) -- expression 69 operands: lhs = Expression(73, Add), rhs = Counter(18) -- expression 70 operands: lhs = Counter(16), rhs = Counter(17) -- expression 71 operands: lhs = Counter(15), rhs = Expression(72, Add) -- expression 72 operands: lhs = Expression(73, Add), rhs = Counter(18) -- expression 73 operands: lhs = Counter(16), rhs = Counter(17) -- expression 74 operands: lhs = Expression(75, Add), rhs = Expression(76, Add) -- expression 75 operands: lhs = Counter(12), rhs = Counter(13) -- expression 76 operands: lhs = Counter(14), rhs = Counter(15) +- expression 43 operands: lhs = Expression(54, Add), rhs = Counter(7) +- 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 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(1)) at (prev + 2, 13) to (start + 2, 6) +- Code(Counter(0)) at (prev + 2, 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) - = (c2 + c3) + = (c1 + c2) - Code(Counter(0)) at (prev + 0, 16) to (start + 0, 29) -- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 10) +- Code(Counter(1)) at (prev + 1, 9) to (start + 1, 10) - Code(Expression(1, Sub)) at (prev + 2, 15) to (start + 0, 28) - = (c0 - c2) -- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 25) + = (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) - = (c3 - c28) + = (c2 - c23) - Code(Expression(3, Sub)) at (prev + 0, 46) to (start + 0, 60) - = (c3 - (c28 + c29)) + = (c2 - (c23 + c24)) - Code(Expression(8, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c28 + c29) + c30) + = ((c23 + c24) + c25) - Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c3 - ((c28 + c29) + c30)) -- Code(Counter(3)) at (prev + 1, 9) to (start + 1, 18) + = (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) - = (c0 - (c2 + c3)) + = (c0 - (c1 + c2)) - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 1, 12) - = (c2 + c3) -- Code(Counter(4)) at (prev + 1, 13) to (start + 2, 6) + = (c1 + c2) +- Code(Expression(0, Add)) at (prev + 1, 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) - = (c2 + c3) -- Code(Counter(5)) at (prev + 0, 22) to (start + 2, 6) + = (c1 + c2) +- Code(Counter(3)) at (prev + 0, 22) to (start + 2, 6) - Code(Expression(11, Sub)) at (prev + 2, 15) to (start + 0, 28) - = ((c2 + c3) - c5) -- Code(Counter(6)) at (prev + 1, 12) to (start + 0, 25) + = ((c1 + c2) - c3) +- Code(Counter(4)) at (prev + 1, 12) to (start + 0, 25) - Code(Expression(12, Sub)) at (prev + 0, 29) to (start + 0, 42) - = (c6 - c25) + = (c4 - c20) - Code(Expression(13, Sub)) at (prev + 0, 46) to (start + 0, 60) - = (c6 - (c25 + c26)) + = (c4 - (c20 + c21)) - Code(Expression(18, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c25 + c26) + c27) + = ((c20 + c21) + c22) - Code(Expression(17, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c6 - ((c25 + c26) + c27)) -- Code(Counter(6)) at (prev + 1, 9) to (start + 0, 23) + = (c4 - ((c20 + c21) + c22)) +- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 23) - Code(Expression(20, Sub)) at (prev + 2, 9) to (start + 0, 15) - = ((c2 + c3) - (c5 + c6)) -- Code(Expression(59, Add)) at (prev + 3, 8) to (start + 0, 12) - = (c5 + c6) -- Code(Counter(7)) at (prev + 1, 13) to (start + 1, 16) -- Code(Counter(8)) at (prev + 1, 17) to (start + 2, 10) + = ((c1 + c2) - (c3 + c4)) +- Code(Expression(37, Add)) at (prev + 3, 8) to (start + 0, 12) + = (c3 + c4) +- Code(Expression(37, Add)) at (prev + 1, 13) to (start + 1, 16) + = (c3 + c4) +- Code(Expression(37, Add)) at (prev + 1, 17) to (start + 2, 10) + = (c3 + c4) - Code(Zero) at (prev + 2, 9) to (start + 0, 10) -- Code(Counter(7)) at (prev + 2, 12) to (start + 0, 25) -- Code(Counter(9)) at (prev + 0, 26) to (start + 2, 10) -- Code(Expression(23, Sub)) at (prev + 4, 17) to (start + 0, 30) - = (c7 - c9) -- Code(Counter(10)) at (prev + 1, 16) to (start + 0, 29) -- Code(Expression(24, Sub)) at (prev + 0, 33) to (start + 0, 46) - = (c10 - c22) -- Code(Expression(25, Sub)) at (prev + 0, 50) to (start + 0, 64) - = (c10 - (c22 + c23)) -- Code(Expression(30, Add)) at (prev + 0, 65) to (start + 2, 14) - = ((c22 + c23) + c24) -- Code(Expression(29, Sub)) at (prev + 2, 13) to (start + 0, 14) - = (c10 - ((c22 + c23) + c24)) -- Code(Counter(10)) at (prev + 1, 13) to (start + 0, 27) -- Code(Expression(32, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (c7 - (c9 + c10)) +- Code(Expression(37, 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) + = ((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) + = (c6 - c17) +- Code(Expression(29, Sub)) at (prev + 0, 50) to (start + 0, 64) + = (c6 - (c17 + c18)) +- Code(Expression(34, Add)) at (prev + 0, 65) to (start + 2, 14) + = ((c17 + c18) + c19) +- Code(Expression(33, 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) + = ((c3 + c4) - (c5 + c6)) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) -- Code(Expression(39, Sub)) at (prev + 2, 9) to (start + 1, 12) - = ((((c5 + c6) + c9) + c10) - c7) -- Code(Counter(11)) at (prev + 1, 13) to (start + 2, 6) +- Code(Expression(54, Add)) at (prev + 2, 9) to (start + 1, 12) + = (c5 + c6) +- Code(Expression(54, Add)) at (prev + 1, 13) to (start + 2, 6) + = (c5 + c6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) -- Code(Expression(75, Add)) at (prev + 2, 9) to (start + 0, 10) - = (c12 + c13) -- Code(Expression(39, Sub)) at (prev + 0, 16) to (start + 0, 29) - = ((((c5 + c6) + c9) + c10) - c7) -- Code(Counter(12)) at (prev + 0, 30) to (start + 2, 6) +- Code(Expression(69, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c7 + c8) +- Code(Expression(54, 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) - = ((((c5 + c6) + c9) + c10) - (c7 + c12)) -- Code(Counter(13)) at (prev + 1, 12) to (start + 0, 25) -- Code(Expression(48, Sub)) at (prev + 0, 29) to (start + 0, 42) - = (c13 - c19) -- Code(Expression(49, Sub)) at (prev + 0, 46) to (start + 0, 60) - = (c13 - (c19 + c20)) -- Code(Expression(54, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c19 + c20) + c21) -- Code(Expression(53, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c13 - ((c19 + c20) + c21)) -- Code(Counter(13)) at (prev + 1, 9) to (start + 0, 23) -- Code(Expression(56, Sub)) at (prev + 2, 13) to (start + 2, 15) - = ((((c5 + c6) + c9) + c10) - ((c7 + c12) + c13)) -- Code(Expression(76, Add)) at (prev + 5, 9) to (start + 0, 10) - = (c14 + c15) -- Code(Expression(75, Add)) at (prev + 0, 16) to (start + 0, 29) - = (c12 + c13) -- Code(Counter(14)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(64, Sub)) at (prev + 2, 15) to (start + 0, 28) - = ((c12 + c13) - c14) -- Code(Counter(15)) at (prev + 1, 12) to (start + 0, 25) -- Code(Expression(66, Sub)) at (prev + 0, 29) to (start + 0, 42) - = (c15 - c16) -- Code(Expression(67, Sub)) at (prev + 0, 46) to (start + 0, 60) - = (c15 - (c16 + c17)) -- Code(Expression(72, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c16 + c17) + c18) -- Code(Expression(71, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c15 - ((c16 + c17) + c18)) -- Code(Counter(15)) at (prev + 1, 9) to (start + 0, 23) -- Code(Expression(74, Sub)) at (prev + 2, 9) to (start + 0, 15) - = ((c12 + c13) - (c14 + c15)) + = ((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) + = (c8 - c14) +- Code(Expression(46, Sub)) at (prev + 0, 46) to (start + 0, 60) + = (c8 - (c14 + c15)) +- Code(Expression(51, Add)) at (prev + 0, 61) to (start + 2, 10) + = ((c14 + c15) + c16) +- Code(Expression(50, 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) + = ((c5 + c6) - (c7 + c8)) +- Code(Expression(70, Add)) at (prev + 5, 9) to (start + 0, 10) + = (c9 + c10) +- Code(Expression(69, 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) + = ((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) + = (c10 - c11) +- Code(Expression(61, Sub)) at (prev + 0, 46) to (start + 0, 60) + = (c10 - (c11 + c12)) +- Code(Expression(66, Add)) at (prev + 0, 61) to (start + 2, 10) + = ((c11 + c12) + c13) +- Code(Expression(65, 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) + = ((c7 + c8) - (c9 + c10)) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) -Highest counter ID seen: c15 +Highest counter ID seen: c10 diff --git a/tests/coverage/drop_trait.cov-map b/tests/coverage/drop_trait.cov-map index a97c0f8794c4..16facf2eddf2 100644 --- a/tests/coverage/drop_trait.cov-map +++ b/tests/coverage/drop_trait.cov-map @@ -8,14 +8,14 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: drop_trait::main -Raw bytes (24): 0x[01, 01, 00, 04, 01, 0e, 01, 05, 0c, 05, 06, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02] +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] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 14, 1) to (start + 5, 12) -- Code(Counter(1)) at (prev + 6, 9) to (start + 1, 22) +- 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) -Highest counter ID seen: c1 +Highest counter ID seen: c0 diff --git a/tests/coverage/generics.cov-map b/tests/coverage/generics.cov-map index d082bd54493d..bc5661afdc19 100644 --- a/tests/coverage/generics.cov-map +++ b/tests/coverage/generics.cov-map @@ -35,14 +35,14 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: generics::main -Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 01, 08, 0c, 05, 09, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02] +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] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 22, 1) to (start + 8, 12) -- Code(Counter(1)) at (prev + 9, 9) to (start + 1, 22) +- 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) -Highest counter ID seen: c1 +Highest counter ID seen: c0 diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map index 640d5f15be0e..2cb0f948b3e1 100644 --- a/tests/coverage/loops_branches.cov-map +++ b/tests/coverage/loops_branches.cov-map @@ -1,36 +1,36 @@ Function name: ::fmt -Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 11, 09, 0d, 0d, 11, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 05, 01, 0d, 00, 0e, 05, 01, 0d, 00, 1e, 09, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 11, 03, 0d, 00, 0e, 0d, 00, 12, 00, 17, 11, 01, 10, 00, 14, 15, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 15, 01, 11, 00, 12, 15, 01, 11, 00, 22, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] +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, 1e, 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, 22, 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 => global file 1 Number of expressions: 4 - expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add) -- expression 1 operands: lhs = Counter(0), rhs = Counter(4) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) -- expression 3 operands: lhs = Counter(3), rhs = Counter(4) +- 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(1)) at (prev + 2, 16) to (start + 0, 21) +- 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(1)) at (prev + 1, 13) to (start + 0, 14) -- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 30) -- Code(Counter(2)) at (prev + 0, 30) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 30) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31) - Code(Zero) at (prev + 1, 16) to (start + 1, 10) -- Code(Counter(4)) at (prev + 3, 13) to (start + 0, 14) -- Code(Counter(3)) at (prev + 0, 18) to (start + 0, 23) -- Code(Counter(4)) at (prev + 1, 16) to (start + 0, 20) -- Code(Counter(5)) at (prev + 1, 20) to (start + 0, 25) +- Code(Counter(3)) at (prev + 3, 13) to (start + 0, 14) +- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 23) +- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 20) +- Code(Counter(3)) at (prev + 1, 20) to (start + 0, 25) - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) -- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 18) -- Code(Counter(5)) at (prev + 1, 17) 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, 34) - Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35) - = ((c0 + c4) - (c2 + c3)) + = ((c0 + c3) - (c1 + c2)) - Code(Zero) at (prev + 1, 20) to (start + 1, 14) - Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15) - = (c3 - c4) + = (c2 - c3) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) -Highest counter ID seen: c5 +Highest counter ID seen: c3 Function name: ::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, 1e, 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, 22, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map index 03012f744c18..35b2c36a5751 100644 --- a/tests/coverage/try_error_result.cov-map +++ b/tests/coverage/try_error_result.cov-map @@ -55,27 +55,31 @@ Number of file 0 mappings: 4 Highest counter ID seen: c1 Function name: try_error_result::test1 -Raw bytes (63): 0x[01, 01, 02, 09, 0d, 05, 09, 0b, 01, 0d, 01, 02, 17, 05, 07, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 29, 11, 00, 29, 00, 2a, 00, 01, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 02, 04, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 06, 03, 05, 00, 0b, 01, 01, 01, 00, 02] +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, 29, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 2 -- expression 0 operands: lhs = Counter(2), rhs = Counter(3) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +Number of expressions: 4 +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(1) +- 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(Counter(3)) at (prev + 6, 13) to (start + 0, 41) -- Code(Counter(4)) at (prev + 0, 41) to (start + 0, 42) +- Code(Expression(0, Sub)) at (prev + 6, 13) to (start + 0, 41) + = ((c0 + c2) - c1) +- Code(Expression(0, Sub)) at (prev + 0, 41) to (start + 0, 42) + = ((c0 + c2) - c1) - Code(Zero) at (prev + 1, 13) to (start + 0, 42) - Code(Zero) at (prev + 0, 42) to (start + 0, 43) -- Code(Expression(0, Sub)) at (prev + 4, 13) to (start + 0, 42) - = (c2 - c3) +- Code(Expression(2, Sub)) at (prev + 4, 13) to (start + 0, 42) + = (c1 - c0) - Code(Zero) at (prev + 0, 42) to (start + 0, 43) -- Code(Expression(1, Sub)) at (prev + 3, 5) to (start + 0, 11) +- Code(Expression(3, Sub)) at (prev + 3, 5) to (start + 0, 11) = (c1 - c2) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c4 +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, 2f, 11, 00, 2f, 00, 30, 02, 00, 31, 03, 35, 15, 04, 11, 00, 12, 1e, 02, 11, 04, 12, 32, 05, 11, 00, 14, 1e, 00, 17, 00, 41, 19, 00, 41, 00, 42, 26, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 32, 01, 0d, 00, 20, 4e, 01, 11, 00, 14, 41, 00, 17, 00, 41, 21, 00, 41, 00, 42, 4a, 00, 43, 00, 60, 25, 00, 60, 00, 61, 4e, 01, 0d, 00, 20, 6e, 04, 11, 00, 14, 62, 00, 17, 00, 42, 29, 00, 42, 00, 43, 66, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 6e, 01, 0d, 00, 20, 86, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, 82, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, 86, 01, 01, 0d, 00, 20, 9a, 01, 01, 11, 00, 14, 49, 00, 17, 01, 36, 39, 02, 11, 00, 12, 96, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, 9a, 01, 02, 0d, 00, 20, a2, 01, 03, 05, 00, 0b, a6, 01, 01, 01, 00, 02] diff --git a/tests/coverage/while.cov-map b/tests/coverage/while.cov-map index d42aa8a7b847..5a6698128cbd 100644 --- a/tests/coverage/while.cov-map +++ b/tests/coverage/while.cov-map @@ -1,12 +1,12 @@ Function name: while::main -Raw bytes (24): 0x[01, 01, 00, 04, 01, 01, 01, 01, 10, 05, 02, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02] +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] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 1, 1) to (start + 1, 16) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 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: c1 +Highest counter ID seen: c0 From 66ebee4dd2f55dadca0eaad72139eb3c5ea4c6ea Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 12 Feb 2025 23:01:22 -0500 Subject: [PATCH 06/16] Compiletest should not inherit all host RUSTFLAGS I told rhelmot to do this in #134913. But it's not correct; compiletest shouldn't inherit RUSTFLAGS at all. Pass a single new --host-rustcflags to compiletest instead, without overwriting any existing arguments. Fixes the following failure, which only happens when building llvm from source and then running `x test --stage 1 ui-fulldeps`: ``` diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr index 0b3bb14ce51..978ac46c5a2 100644 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ b/tests/ui-fulldeps/fluent-messages/test.stderr @@ -1,3 +1,8 @@ +warning[E0602]: unknown lint: `linker_messages` + | + = note: requested on the command line with `-A linker_messages` + = note: `#[warn(unknown_lints)]` on by default ``` --- src/bootstrap/src/core/build_steps/test.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 509875a469f1..2b4e9d48a245 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1969,13 +1969,12 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the if !builder.config.dry_run() && suite.ends_with("fulldeps") { let llvm_libdir = command(&llvm_config).arg("--libdir").run_capture_stdout(builder).stdout(); - let mut rustflags = env::var("RUSTFLAGS").unwrap_or_default(); - if target.is_msvc() { - rustflags.push_str(&format!("-Clink-arg=-LIBPATH:{llvm_libdir}")); + let link_llvm = if target.is_msvc() { + format!("-Clink-arg=-LIBPATH:{llvm_libdir}") } else { - rustflags.push_str(&format!("-Clink-arg=-L{llvm_libdir}")); - } - cmd.env("RUSTFLAGS", rustflags); + format!("-Clink-arg=-L{llvm_libdir}") + }; + cmd.arg("--host-rustcflags").arg(link_llvm); } if !builder.config.dry_run() && matches!(mode, "run-make" | "coverage-run") { From a1a6fd74d248242e3c4c6db195f4070165b743bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 13 Feb 2025 09:41:23 +0100 Subject: [PATCH 07/16] Add warning about using llvm.ccache and add FIXME note --- src/bootstrap/src/core/config/config.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 0ee476d19c9d..62625fc3660f 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -962,6 +962,7 @@ define_config! { tests: Option = "tests", enzyme: Option = "enzyme", plugins: Option = "plugins", + // FIXME: Remove this field at Q2 2025, it has been replaced by build.ccache ccache: Option = "ccache", static_libstdcpp: Option = "static-libstdcpp", libzstd: Option = "libzstd", @@ -2031,6 +2032,10 @@ impl Config { download_ci_llvm, build_config, } = llvm; + if llvm_ccache.is_some() { + eprintln!("Warning: llvm.ccache is deprecated. Use build.ccache instead."); + } + ccache = ccache.or(llvm_ccache); set(&mut config.ninja_in_file, ninja); llvm_tests = tests; From 8ff3639dffe3cd7802d407d8f43eb1788d3de661 Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:29:55 +0100 Subject: [PATCH 08/16] ci: move `x86_64-gnu-debug` job to the free runner --- src/ci/github-actions/jobs.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index c08104e796b9..48814f7dd8a1 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -294,9 +294,7 @@ auto: <<: *job-linux-4c - name: x86_64-gnu-debug - # This seems to be needed because a full stage 2 build + run-make tests - # overwhelms the storage capacity of the standard 4c runner. - <<: *job-linux-4c-largedisk + <<: *job-linux-4c - name: x86_64-gnu-distcheck <<: *job-linux-8c From bd4f80c44912ce1a78bb3027d0e1711a5c4272ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 13 Feb 2025 13:35:03 +0100 Subject: [PATCH 09/16] Remove `llvm.ccache` option from `config.example.toml` --- config.example.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config.example.toml b/config.example.toml index ad79f5d5a80c..86d40db3ded7 100644 --- a/config.example.toml +++ b/config.example.toml @@ -87,10 +87,6 @@ # Whether to build LLVM with support for it's gpu offload runtime. #offload = false -# Indicates whether ccache is used when building LLVM. Set to `true` to use the first `ccache` in -# PATH, or set an absolute path to use a specific version. -#ccache = false - # When true, link libstdc++ statically into the rustc_llvm. # This is useful if you don't want to use the dynamic version of that # library provided by LLVM. From 0709ba3e7bd2eece4a15d5ed88b9304cb8c2f001 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 13 Feb 2025 10:40:15 +0300 Subject: [PATCH 10/16] unify LLVM version finding logic Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 5 +++-- src/bootstrap/src/core/build_steps/llvm.rs | 17 ++++++++++++----- src/bootstrap/src/core/build_steps/test.rs | 4 ++-- src/bootstrap/src/core/builder/mod.rs | 2 +- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index a2375842bdde..bee0da0eb904 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1092,9 +1092,10 @@ pub fn rustc_cargo( // We want to link against registerEnzyme and in the future we want to use additional // functionality from Enzyme core. For that we need to link against Enzyme. - // FIXME(ZuseZ4): Get the LLVM version number automatically instead of hardcoding it. if builder.config.llvm_enzyme { - cargo.rustflag("-l").rustflag("Enzyme-19"); + let llvm_config = builder.llvm_config(builder.config.build).unwrap(); + let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); + cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}")); } // Building with protected visibility reduces the number of dynamic relocations needed, giving diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index ee60dbef7b98..18da0e8252b9 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -571,10 +571,7 @@ impl Step for Llvm { // Helper to find the name of LLVM's shared library on darwin and linux. let find_llvm_lib_name = |extension| { - let version = - command(&res.llvm_config).arg("--version").run_capture_stdout(builder).stdout(); - let major = version.split('.').next().unwrap(); - + let major = get_llvm_version_major(builder, &res.llvm_config); match &llvm_version_suffix { Some(version_suffix) => format!("libLLVM-{major}{version_suffix}.{extension}"), None => format!("libLLVM-{major}.{extension}"), @@ -624,12 +621,22 @@ impl Step for Llvm { } } +pub fn get_llvm_version(builder: &Builder<'_>, llvm_config: &Path) -> String { + command(llvm_config).arg("--version").run_capture_stdout(builder).stdout().trim().to_owned() +} + +pub fn get_llvm_version_major(builder: &Builder<'_>, llvm_config: &Path) -> u8 { + let version = get_llvm_version(builder, llvm_config); + let major_str = version.split_once('.').expect("Failed to parse LLVM version").0; + major_str.parse().unwrap() +} + fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { if builder.config.dry_run() { return; } - let version = command(llvm_config).arg("--version").run_capture_stdout(builder).stdout(); + let version = get_llvm_version(builder, llvm_config); let mut parts = version.split('.').take(2).filter_map(|s| s.parse::().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { if major >= 18 { diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 509875a469f1..fdbb48ca4e65 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -12,6 +12,7 @@ use clap_complete::shells; use crate::core::build_steps::compile::run_cargo; use crate::core::build_steps::doc::DocumentationFormat; +use crate::core::build_steps::llvm::get_llvm_version; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; use crate::core::build_steps::tool::{self, SourceType, Tool}; use crate::core::build_steps::toolstate::ToolState; @@ -1945,8 +1946,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target: builder.config.build }); if !builder.config.dry_run() { - let llvm_version = - command(&llvm_config).arg("--version").run_capture_stdout(builder).stdout(); + let llvm_version = get_llvm_version(builder, &llvm_config); let llvm_components = command(&llvm_config).arg("--components").run_capture_stdout(builder).stdout(); // Remove trailing newline from llvm-config output. diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 8e767a8dcc69..ecec589fc32e 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1431,7 +1431,7 @@ impl<'a> Builder<'a> { /// /// Note that this returns `None` if LLVM is disabled, or if we're in a /// check build or dry-run, where there's no need to build all of LLVM. - fn llvm_config(&self, target: TargetSelection) -> Option { + pub fn llvm_config(&self, target: TargetSelection) -> Option { if self.config.llvm_enabled(target) && self.kind != Kind::Check && !self.config.dry_run() { let llvm::LlvmResult { llvm_config, .. } = self.ensure(llvm::Llvm { target }); if llvm_config.is_file() { From f7a03d075fa203eceaee81d730a78913c9ece2d4 Mon Sep 17 00:00:00 2001 From: jyn Date: Thu, 13 Feb 2025 09:57:05 -0500 Subject: [PATCH 11/16] Fix `x test --stage 1 ui-fulldeps` on macOS (until the next beta bump) "stage 1" for fulldeps means "compile with stage 0, link against stage 1". But this code wanted to switch on the compiler that's building, not the compiler that's being tested. Fix the check. Previously, it would fail with a warning about linker-messages: ``` --- stderr ------------------------------- warning[E0602]: unknown lint: `linker_messages` | = note: requested on the command line with `-A linker_messages` = note: `#[warn(unknown_lints)]` on by default ``` --- src/bootstrap/src/core/build_steps/test.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 825e5452f0e6..f645b0e83862 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1840,6 +1840,14 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } } + // FIXME(136096): on macOS, we get linker warnings about duplicate `-lm` flags. + // NOTE: `stage > 1` here because `test --stage 1 ui-fulldeps` is a hack that compiles + // with stage 0, but links the tests against stage 1. + // cfg(bootstrap) - remove only the `stage > 1` check, leave everything else. + if suite == "ui-fulldeps" && compiler.stage > 1 && target.ends_with("darwin") { + flags.push("-Alinker_messages".into()); + } + let mut hostflags = flags.clone(); hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display())); hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No)); @@ -1847,12 +1855,6 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let mut targetflags = flags; targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display())); - // FIXME: on macOS, we get linker warnings about duplicate `-lm` flags. We should investigate why this happens. - if suite == "ui-fulldeps" && target.ends_with("darwin") { - hostflags.push("-Alinker_messages".into()); - targetflags.push("-Alinker_messages".into()); - } - for flag in hostflags { cmd.arg("--host-rustcflags").arg(flag); } From de273e459e4b0cbbcf7be68294a7d1fb25632b29 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 11 Feb 2025 10:37:04 +0100 Subject: [PATCH 12/16] normalizes-to rework rigid alias handling --- .../src/solve/assembly/mod.rs | 31 +++-- .../src/solve/effect_goals.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 108 ++++++------------ .../src/solve/normalizes_to/opaque_types.rs | 28 ++--- .../src/solve/inspect/analyse.rs | 2 - .../rustc_trait_selection/src/solve/select.rs | 3 +- compiler/rustc_type_ir/src/solve/inspect.rs | 2 - 7 files changed, 77 insertions(+), 99 deletions(-) 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 a3274fb40115..23fe88b16802 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -797,11 +797,12 @@ where /// treat the alias as rigid. /// /// See trait-system-refactor-initiative#124 for more details. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "debug", skip(self, inject_normalize_to_rigid_candidate), ret)] pub(super) fn merge_candidates( &mut self, proven_via: Option, candidates: Vec>, + inject_normalize_to_rigid_candidate: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, ) -> QueryResult { let Some(proven_via) = proven_via else { // We don't care about overflow. If proving the trait goal overflowed, then @@ -818,13 +819,27 @@ where // FIXME(const_trait_impl): should this behavior also be used by // constness checking. Doing so is *at least theoretically* breaking, // see github.com/rust-lang/rust/issues/133044#issuecomment-2500709754 - TraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound => candidates - .iter() - .filter(|c| { - matches!(c.source, CandidateSource::AliasBound | CandidateSource::ParamEnv(_)) - }) - .map(|c| c.result) - .collect(), + TraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound => { + let mut candidates_from_env: Vec<_> = candidates + .iter() + .filter(|c| { + matches!( + c.source, + CandidateSource::AliasBound | CandidateSource::ParamEnv(_) + ) + }) + .map(|c| c.result) + .collect(); + + // If the trait goal has been proven by using the environment, we want to treat + // aliases as rigid if there are no applicable projection bounds in the environment. + if candidates_from_env.is_empty() { + if let Ok(response) = inject_normalize_to_rigid_candidate(self) { + candidates_from_env.push(response); + } + } + candidates_from_env + } TraitGoalProvenVia::Misc => candidates.iter().map(|c| c.result).collect(), }; 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 eb398e8724d4..0b61c368d8e8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -405,6 +405,6 @@ where goal.with(ecx.cx(), goal.predicate.trait_ref); ecx.compute_trait_goal(trait_goal) })?; - self.merge_candidates(proven_via, candidates) + self.merge_candidates(proven_via, candidates, |_ecx| Err(NoSolution)) } } 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 1d0ec7b45ca1..e3d16719e283 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 @@ -30,75 +30,26 @@ where ) -> QueryResult { self.set_is_normalizes_to_goal(); debug_assert!(self.term_is_fully_unconstrained(goal)); - let normalize_result = self - .probe(|&result| ProbeKind::TryNormalizeNonRigid { result }) - .enter(|this| this.normalize_at_least_one_step(goal)); - - match normalize_result { - Ok(res) => Ok(res), - Err(NoSolution) => { - self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| { - let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; - this.add_rigid_constraints(param_env, alias)?; - this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; - this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }) - } - } - } - - /// Register any obligations that are used to validate that an alias should be - /// treated as rigid. - /// - /// An alias may be considered rigid if it fails normalization, but we also don't - /// want to consider aliases that are not well-formed to be rigid simply because - /// they fail normalization. - /// - /// For example, some `::Assoc` where `T: Trait` does not hold, or an - /// opaque type whose hidden type doesn't actually satisfy the opaque item bounds. - fn add_rigid_constraints( - &mut self, - param_env: I::ParamEnv, - rigid_alias: ty::AliasTerm, - ) -> Result<(), NoSolution> { - let cx = self.cx(); - match rigid_alias.kind(cx) { - // Projections are rigid only if their trait ref holds, - // and the GAT where-clauses hold. - ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { - let trait_ref = rigid_alias.trait_ref(cx); - self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref)); - Ok(()) - } - ty::AliasTermKind::OpaqueTy => { - if self.opaque_type_is_rigid(rigid_alias.def_id) { - Ok(()) - } else { - Err(NoSolution) - } - } - // FIXME(generic_const_exprs): we would need to support generic consts here - ty::AliasTermKind::UnevaluatedConst => Err(NoSolution), - // Inherent and weak types are never rigid. This type must not be well-formed. - ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution), - } - } - - /// Normalize the given alias by at least one step. If the alias is rigid, this - /// returns `NoSolution`. - #[instrument(level = "trace", skip(self), ret)] - fn normalize_at_least_one_step(&mut self, goal: Goal>) -> QueryResult { let cx = self.cx(); match goal.predicate.alias.kind(cx) { ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { let candidates = self.assemble_and_evaluate_candidates(goal); + let trait_ref = goal.predicate.alias.trait_ref(cx); let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { - let trait_goal: Goal> = - goal.with(cx, goal.predicate.alias.trait_ref(cx)); + let trait_goal: Goal> = goal.with(cx, trait_ref); ecx.compute_trait_goal(trait_goal) })?; - self.merge_candidates(proven_via, candidates) + self.merge_candidates(proven_via, candidates, |ecx| { + ecx.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| { + this.structurally_instantiate_normalizes_to_term( + goal, + goal.predicate.alias, + ); + this.add_goal(GoalSource::AliasWellFormed, goal.with(cx, trait_ref)); + this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + }) } ty::AliasTermKind::InherentTy => self.normalize_inherent_associated_type(goal), ty::AliasTermKind::OpaqueTy => self.normalize_opaque_type(goal), @@ -120,6 +71,17 @@ where self.eq(goal.param_env, goal.predicate.term, term) .expect("expected goal term to be fully unconstrained"); } + + /// Unlike `instantiate_normalizes_to_term` this instantiates the expected term + /// with a rigid alias. Using this is pretty much always wrong. + pub fn structurally_instantiate_normalizes_to_term( + &mut self, + goal: Goal>, + term: ty::AliasTerm, + ) { + self.relate_rigid_alias_non_alias(goal.param_env, term, ty::Invariant, goal.predicate.term) + .expect("expected goal term to be fully unconstrained"); + } } impl assembly::GoalKind for NormalizesTo @@ -850,12 +812,14 @@ where todo!("discr subgoal...") } - // We do not call `Ty::discriminant_ty` on alias, param, or placeholder - // types, which return `::Discriminant` - // (or ICE in the case of placeholders). Projecting a type to itself - // is never really productive. + // Given an alias, parameter, or placeholder we add an impl candidate normalizing to a rigid + // alias. In case there's a where-bound further constraining this alias it is preferred over + // this impl candidate anyways. It's still a bit scuffed. ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { - return Err(NoSolution); + return ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }); } ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) @@ -902,12 +866,14 @@ where todo!() } - // We do not call `Ty::async_destructor_ty` on alias, param, or placeholder - // types, which return `::AsyncDestructor` - // (or ICE in the case of placeholders). Projecting a type to itself - // is never really productive. + // Given an alias, parameter, or placeholder we add an impl candidate normalizing to a rigid + // alias. In case there's a where-bound further constraining this alias it is preferred over + // this impl candidate anyways. It's still a bit scuffed. ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { - return Err(NoSolution); + return ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }); } ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index 26a8a22d77eb..60c20762a30a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -35,14 +35,15 @@ where self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } TypingMode::Analysis { defining_opaque_types } => { - let Some(def_id) = opaque_ty.def_id.as_local() else { - return Err(NoSolution); + let Some(def_id) = opaque_ty + .def_id + .as_local() + .filter(|&def_id| defining_opaque_types.contains(&def_id)) + else { + self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); }; - if !defining_opaque_types.contains(&def_id) { - return Err(NoSolution); - } - // FIXME: This may have issues when the args contain aliases... match uses_unique_placeholders_ignoring_regions(self.cx(), opaque_ty.args) { Err(NotUniqueParam::NotParam(param)) if param.is_non_region_infer() => { @@ -97,15 +98,16 @@ where self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } TypingMode::PostBorrowckAnalysis { defined_opaque_types } => { - let Some(def_id) = opaque_ty.def_id.as_local() else { - return Err(NoSolution); + let Some(def_id) = opaque_ty + .def_id + .as_local() + .filter(|&def_id| defined_opaque_types.contains(&def_id)) + else { + self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); }; - if !defined_opaque_types.contains(&def_id) { - return Err(NoSolution); - } - - let actual = cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args); + let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args); // FIXME: Actually use a proper binder here instead of relying on `ReErased`. // // This is also probably unsound or sth :shrug: diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 9f4ee54bd4c6..9fbc1d64d742 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -300,7 +300,6 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { inspect::ProbeKind::NormalizedSelfTyAssembly | inspect::ProbeKind::UnsizeAssembly | inspect::ProbeKind::Root { .. } - | inspect::ProbeKind::TryNormalizeNonRigid { .. } | inspect::ProbeKind::TraitCandidate { .. } | inspect::ProbeKind::OpaqueTypeStorageLookup { .. } | inspect::ProbeKind::RigidAlias { .. } => { @@ -325,7 +324,6 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { // We add a candidate even for the root evaluation if there // is only one way to prove a given goal, e.g. for `WellFormed`. inspect::ProbeKind::Root { result } - | inspect::ProbeKind::TryNormalizeNonRigid { result } | inspect::ProbeKind::TraitCandidate { source: _, result } | inspect::ProbeKind::OpaqueTypeStorageLookup { result } | inspect::ProbeKind::RigidAlias { result } => { diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs index b0b6274907d0..4437fc5b0295 100644 --- a/compiler/rustc_trait_selection/src/solve/select.rs +++ b/compiler/rustc_trait_selection/src/solve/select.rs @@ -175,8 +175,7 @@ fn to_selection<'tcx>( span_bug!(span, "didn't expect to select an unknowable candidate") } }, - ProbeKind::TryNormalizeNonRigid { result: _ } - | ProbeKind::NormalizedSelfTyAssembly + ProbeKind::NormalizedSelfTyAssembly | ProbeKind::UnsizeAssembly | ProbeKind::UpcastProjectionCompatibility | ProbeKind::OpaqueTypeStorageLookup { result: _ } diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs index d0e618dc6f96..18fb71dd290e 100644 --- a/compiler/rustc_type_ir/src/solve/inspect.rs +++ b/compiler/rustc_type_ir/src/solve/inspect.rs @@ -111,8 +111,6 @@ pub enum ProbeStep { pub enum ProbeKind { /// The root inference context while proving a goal. Root { result: QueryResult }, - /// Trying to normalize an alias by at least one step in `NormalizesTo`. - TryNormalizeNonRigid { result: QueryResult }, /// Probe entered when normalizing the self ty during candidate assembly NormalizedSelfTyAssembly, /// A candidate for proving a trait or alias-relate goal. From 05bd5ced2d9af5f155ed8a72b5c1399838c1d653 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 11 Feb 2025 13:09:15 +0100 Subject: [PATCH 13/16] rework pointee handling for the new rigid alias approach --- .../src/solve/normalizes_to/mod.rs | 158 ++++++++++-------- 1 file changed, 85 insertions(+), 73 deletions(-) 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 e3d16719e283..88002e1a88a8 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 @@ -538,80 +538,92 @@ where let cx = ecx.cx(); let metadata_def_id = cx.require_lang_item(TraitSolverLangItem::Metadata); assert_eq!(metadata_def_id, goal.predicate.def_id()); + let metadata_ty = match goal.predicate.self_ty().kind() { + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Array(..) + | ty::Pat(..) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Never + | ty::Foreign(..) + | ty::Dynamic(_, _, ty::DynStar) => Ty::new_unit(cx), + + ty::Error(e) => Ty::new_error(cx, e), + + ty::Str | ty::Slice(_) => Ty::new_usize(cx), + + ty::Dynamic(_, _, ty::Dyn) => { + let dyn_metadata = cx.require_lang_item(TraitSolverLangItem::DynMetadata); + cx.type_of(dyn_metadata) + .instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())]) + } + + ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { + // This is the "fallback impl" for type parameters, unnormalizable projections + // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`. + // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't + // exist. Instead, `Pointee` should be a supertrait of `Sized`. + let alias_bound_result = + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + let sized_predicate = ty::TraitRef::new( + cx, + cx.require_lang_item(TraitSolverLangItem::Sized), + [I::GenericArg::from(goal.predicate.self_ty())], + ); + ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate)); + ecx.instantiate_normalizes_to_term(goal, Ty::new_unit(cx).into()); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }); + // In case the dummy alias-bound candidate does not apply, we instead treat this projection + // as rigid. + return alias_bound_result.or_else(|NoSolution| { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|this| { + this.structurally_instantiate_normalizes_to_term( + goal, + goal.predicate.alias, + ); + this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + }); + } + + ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(cx) { + None => Ty::new_unit(cx), + Some(tail_ty) => { + Ty::new_projection(cx, metadata_def_id, [tail_ty.instantiate(cx, args)]) + } + }, + ty::Adt(_, _) => Ty::new_unit(cx), + + ty::Tuple(elements) => match elements.last() { + None => Ty::new_unit(cx), + Some(tail_ty) => Ty::new_projection(cx, metadata_def_id, [tail_ty]), + }, + + ty::UnsafeBinder(_) => { + // FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders. + todo!() + } + + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) + | ty::Bound(..) => panic!( + "unexpected self ty `{:?}` when normalizing `::Metadata`", + goal.predicate.self_ty() + ), + }; + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { - let metadata_ty = match goal.predicate.self_ty().kind() { - ty::Bool - | ty::Char - | ty::Int(..) - | ty::Uint(..) - | ty::Float(..) - | ty::Array(..) - | ty::Pat(..) - | ty::RawPtr(..) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Never - | ty::Foreign(..) - | ty::Dynamic(_, _, ty::DynStar) => Ty::new_unit(cx), - - ty::Error(e) => Ty::new_error(cx, e), - - ty::Str | ty::Slice(_) => Ty::new_usize(cx), - - ty::Dynamic(_, _, ty::Dyn) => { - let dyn_metadata = cx.require_lang_item(TraitSolverLangItem::DynMetadata); - cx.type_of(dyn_metadata) - .instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())]) - } - - ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { - // This is the "fallback impl" for type parameters, unnormalizable projections - // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`. - // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't - // exist. Instead, `Pointee` should be a supertrait of `Sized`. - let sized_predicate = ty::TraitRef::new( - cx, - cx.require_lang_item(TraitSolverLangItem::Sized), - [I::GenericArg::from(goal.predicate.self_ty())], - ); - // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`? - ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate)); - Ty::new_unit(cx) - } - - ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(cx) { - None => Ty::new_unit(cx), - Some(tail_ty) => { - Ty::new_projection(cx, metadata_def_id, [tail_ty.instantiate(cx, args)]) - } - }, - ty::Adt(_, _) => Ty::new_unit(cx), - - ty::Tuple(elements) => match elements.last() { - None => Ty::new_unit(cx), - Some(tail_ty) => Ty::new_projection(cx, metadata_def_id, [tail_ty]), - }, - - ty::UnsafeBinder(_) => { - // FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders. - todo!() - } - - ty::Infer( - ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_), - ) - | ty::Bound(..) => panic!( - "unexpected self ty `{:?}` when normalizing `::Metadata`", - goal.predicate.self_ty() - ), - }; - ecx.instantiate_normalizes_to_term(goal, metadata_ty.into()); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) From 059288ed442f34c336c759486bfe4373b61288a0 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 12 Feb 2025 11:41:53 +0100 Subject: [PATCH 14/16] adjust derive_error --- .../src/solve/assembly/mod.rs | 20 --- .../traits/fulfillment_errors.rs | 4 + .../src/error_reporting/traits/mod.rs | 2 +- .../src/solve/fulfill/derive_errors.rs | 128 ++++++++++++++---- tests/crashes/134905.rs | 16 --- tests/ui/auto-traits/assoc-ty.next.stderr | 25 ++-- tests/ui/auto-traits/assoc-ty.rs | 4 +- ...nsubstituting-in-region-112823.next.stderr | 14 +- ...-type-whensubstituting-in-region-112823.rs | 8 +- .../fuzzed/fuzzing-ice-134905.rs | 22 +++ .../fuzzed/fuzzing-ice-134905.stderr | 40 ++++++ 11 files changed, 204 insertions(+), 79 deletions(-) delete mode 100644 tests/crashes/134905.rs create mode 100644 tests/ui/specialization/fuzzed/fuzzing-ice-134905.rs create mode 100644 tests/ui/specialization/fuzzed/fuzzing-ice-134905.stderr 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 23fe88b16802..b0f59ed1474c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -6,7 +6,6 @@ use derive_where::derive_where; use rustc_type_ir::fold::TypeFoldable; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; -use rustc_type_ir::solve::inspect; use rustc_type_ir::visit::TypeVisitableExt as _; use rustc_type_ir::{self as ty, Interner, TypingMode, Upcast as _, elaborate}; use tracing::{debug, instrument}; @@ -297,25 +296,6 @@ where let Ok(normalized_self_ty) = self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty()) else { - // FIXME: We register a fake candidate when normalization fails so that - // we can point at the reason for *why*. I'm tempted to say that this - // is the wrong way to do this, though. - let result = - self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| { - let normalized_ty = this.next_ty_infer(); - let alias_relate_goal = Goal::new( - this.cx(), - goal.param_env, - ty::PredicateKind::AliasRelate( - goal.predicate.self_ty().into(), - normalized_ty.into(), - ty::AliasRelationDirection::Equate, - ), - ); - this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal); - this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) - }); - assert_eq!(result, Err(NoSolution)); return vec![]; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 1b43820bac0c..49fa21e50c05 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -585,6 +585,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => { let ty = self.resolve_vars_if_possible(ty); if self.next_trait_solver() { + if let Err(guar) = ty.error_reported() { + return guar; + } + // FIXME: we'll need a better message which takes into account // which bounds actually failed to hold. self.dcx().struct_span_err( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 658fb4009d50..e4f250ca4f54 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -172,8 +172,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { 1 } - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3, ty::PredicateKind::Coerce(_) => 2, + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3, _ => 0, }); 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 7364b4aa3438..982782bc57c1 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -7,7 +7,7 @@ use rustc_infer::traits::{ PredicateObligation, SelectionError, }; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_next_trait_solver::solve::{GenerateProofTree, SolverDelegateEvalExt as _}; use rustc_type_ir::solve::{Goal, NoSolution}; @@ -139,6 +139,7 @@ pub(super) fn fulfillment_error_for_overflow<'tcx>( } } +#[instrument(level = "debug", skip(infcx), ret)] fn find_best_leaf_obligation<'tcx>( infcx: &InferCtxt<'tcx>, obligation: &PredicateObligation<'tcx>, @@ -197,6 +198,9 @@ impl<'tcx> BestObligation<'tcx> { candidates.retain(|candidate| candidate.result().is_ok()); } false => { + // We always handle rigid alias candidates separately as we may not add them for + // aliases whose trait bound doesn't hold. + candidates.retain(|c| !matches!(c.kind(), inspect::ProbeKind::RigidAlias { .. })); // If we have >1 candidate, one may still be due to "boring" reasons, like // an alias-relate that failed to hold when deeply evaluated. We really // don't care about reasons like this. @@ -211,23 +215,12 @@ impl<'tcx> BestObligation<'tcx> { | GoalSource::AliasBoundConstCondition | GoalSource::InstantiateHigherRanked | GoalSource::AliasWellFormed - ) && match (self.consider_ambiguities, nested_goal.result()) { - (true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) - | (false, Err(_)) => true, - _ => false, - } + ) && nested_goal.result().is_err() }, ) }) }); } - - // Prefer a non-rigid candidate if there is one. - if candidates.len() > 1 { - candidates.retain(|candidate| { - !matches!(candidate.kind(), inspect::ProbeKind::RigidAlias { .. }) - }); - } } } @@ -266,6 +259,90 @@ impl<'tcx> BestObligation<'tcx> { ControlFlow::Break(self.obligation.clone()) } + + /// If a normalization of an associated item or a trait goal fails without trying any + /// candidates it's likely that normalizing its self type failed. We manually detect + /// such cases here. + fn detect_error_in_self_ty_normalization( + &mut self, + goal: &inspect::InspectGoal<'_, 'tcx>, + self_ty: Ty<'tcx>, + ) -> ControlFlow> { + assert!(!self.consider_ambiguities); + let tcx = goal.infcx().tcx; + if let ty::Alias(..) = self_ty.kind() { + let infer_term = goal.infcx().next_ty_var(self.obligation.cause.span); + let pred = ty::PredicateKind::AliasRelate( + self_ty.into(), + infer_term.into(), + ty::AliasRelationDirection::Equate, + ); + let obligation = + Obligation::new(tcx, self.obligation.cause.clone(), goal.goal().param_env, pred); + self.with_derived_obligation(obligation, |this| { + goal.infcx().visit_proof_tree_at_depth( + goal.goal().with(tcx, pred), + goal.depth() + 1, + this, + ) + }) + } else { + ControlFlow::Continue(()) + } + } + + /// It is likely that `NormalizesTo` failed without any applicable candidates + /// because the alias is not well-formed. + /// + /// As we only enter `RigidAlias` candidates if the trait bound of the associated type + /// holds, we discard these candidates in `non_trivial_candidates` and always manually + /// check this here. + fn detect_non_well_formed_assoc_item( + &mut self, + goal: &inspect::InspectGoal<'_, 'tcx>, + alias: ty::AliasTerm<'tcx>, + ) -> ControlFlow> { + let tcx = goal.infcx().tcx; + let obligation = Obligation::new( + tcx, + self.obligation.cause.clone(), + goal.goal().param_env, + alias.trait_ref(tcx), + ); + self.with_derived_obligation(obligation, |this| { + goal.infcx().visit_proof_tree_at_depth( + goal.goal().with(tcx, alias.trait_ref(tcx)), + goal.depth() + 1, + this, + ) + }) + } + + /// If we have no candidates, then it's likely that there is a + /// non-well-formed alias in the goal. + fn detect_error_from_empty_candidates( + &mut self, + goal: &inspect::InspectGoal<'_, 'tcx>, + ) -> ControlFlow> { + let tcx = goal.infcx().tcx; + let pred_kind = goal.goal().predicate.kind(); + + match pred_kind.no_bound_vars() { + Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))) => { + self.detect_error_in_self_ty_normalization(goal, pred.self_ty())?; + } + Some(ty::PredicateKind::NormalizesTo(pred)) + if let ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst = + pred.alias.kind(tcx) => + { + self.detect_error_in_self_ty_normalization(goal, pred.alias.self_ty())?; + self.detect_non_well_formed_assoc_item(goal, pred.alias)?; + } + Some(_) | None => {} + } + + ControlFlow::Break(self.obligation.clone()) + } } impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { @@ -277,11 +354,19 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { #[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))] fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result { - let candidates = self.non_trivial_candidates(goal); - trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::>()); + let tcx = goal.infcx().tcx; + // Skip goals that aren't the *reason* for our goal's failure. + match (self.consider_ambiguities, goal.result()) { + (true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {} + _ => return ControlFlow::Continue(()), + } + let pred_kind = goal.goal().predicate.kind(); - let [candidate] = candidates.as_slice() else { - return ControlFlow::Break(self.obligation.clone()); + let candidates = self.non_trivial_candidates(goal); + let candidate = match candidates.as_slice() { + [candidate] => candidate, + [] => return self.detect_error_from_empty_candidates(goal), + _ => return ControlFlow::Break(self.obligation.clone()), }; // Don't walk into impls that have `do_not_recommend`. @@ -291,13 +376,12 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { } = candidate.kind() && goal.infcx().tcx.do_not_recommend_impl(impl_def_id) { + trace!("#[do_not_recommend] -> exit"); return ControlFlow::Break(self.obligation.clone()); } - let tcx = goal.infcx().tcx; // FIXME: Also, what about considering >1 layer up the stack? May be necessary // for normalizes-to. - let pred_kind = goal.goal().predicate.kind(); let child_mode = match pred_kind.skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { ChildMode::Trait(pred_kind.rebind(pred)) @@ -390,12 +474,6 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { } } - // Skip nested goals that aren't the *reason* for our goal's failure. - match (self.consider_ambiguities, nested_goal.result()) { - (true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {} - _ => continue, - } - self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?; } diff --git a/tests/crashes/134905.rs b/tests/crashes/134905.rs deleted file mode 100644 index 9f0f0f4b3f22..000000000000 --- a/tests/crashes/134905.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #134905 - -trait Iterate<'a> { - type Ty: Valid; -} -impl<'a, T> Iterate<'a> for T -where - T: Check, -{ - default type Ty = (); -} - -trait Check {} -impl<'a, T> Eq for T where >::Ty: Valid {} - -trait Valid {} diff --git a/tests/ui/auto-traits/assoc-ty.next.stderr b/tests/ui/auto-traits/assoc-ty.next.stderr index b9f56d6c99c4..4ce00d174756 100644 --- a/tests/ui/auto-traits/assoc-ty.next.stderr +++ b/tests/ui/auto-traits/assoc-ty.next.stderr @@ -21,20 +21,21 @@ LL | | } = help: add `#![feature(auto_traits)]` 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[E0308]: mismatched types - --> $DIR/assoc-ty.rs:15:36 +error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _` + --> $DIR/assoc-ty.rs:15:12 | LL | let _: <() as Trait>::Output = (); - | --------------------- ^^ types differ - | | - | expected due to this + | ^^^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _` + --> $DIR/assoc-ty.rs:15:12 | - = note: expected associated type `<() as Trait>::Output` - found unit type `()` - = help: consider constraining the associated type `<() as Trait>::Output` to `()` or calling a method that returns `<() as Trait>::Output` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +LL | let _: <() as Trait>::Output = (); + | ^^^^^^^^^^^^^^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0308, E0380, E0658. -For more information about an error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0271, E0380, E0658. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/auto-traits/assoc-ty.rs b/tests/ui/auto-traits/assoc-ty.rs index ada75147f6ea..efbfead9cd03 100644 --- a/tests/ui/auto-traits/assoc-ty.rs +++ b/tests/ui/auto-traits/assoc-ty.rs @@ -13,5 +13,7 @@ auto trait Trait { fn main() { let _: <() as Trait>::Output = (); - //~^ ERROR mismatched types + //[current]~^ ERROR mismatched types + //[next]~^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _` + //[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _` } diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr index 3c24eb9adbee..ce64a022214e 100644 --- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr +++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr @@ -23,7 +23,19 @@ error[E0271]: type mismatch resolving `::LineStreamFut<'a, Repr> == ()` LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ -error: aborting due to 3 previous errors +error[E0271]: type mismatch resolving `::LineStreamFut<'a, Repr> normalizes-to _` + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:73 + | +LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} + | ^^ types differ + +error[E0271]: type mismatch resolving `::LineStreamFut<'a, Repr> normalizes-to _` + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5 + | +LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 5 previous errors Some errors have detailed explanations: E0049, E0271, E0407. For more information about an error, try `rustc --explain E0049`. diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs index c97bd1799436..cb32723b22dd 100644 --- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs +++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs @@ -26,9 +26,11 @@ impl X for Y { //~^ ERROR type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter type LineStreamFut<'a, Repr> = impl Future>; fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} - //[current]~^ ERROR `()` is not a future - //[next]~^^ ERROR type mismatch resolving `::LineStreamFut<'a, Repr> == ()` - //~^^^ method `line_stream` is not a member of trait `X` + //~^ method `line_stream` is not a member of trait `X` + //[current]~^^ ERROR `()` is not a future + //[next]~^^^ ERROR type mismatch resolving `::LineStreamFut<'a, Repr> == ()` + //[next]~| ERROR type mismatch resolving `::LineStreamFut<'a, Repr> normalizes-to _` + //[next]~| ERROR type mismatch resolving `::LineStreamFut<'a, Repr> normalizes-to _` } pub fn main() {} diff --git a/tests/ui/specialization/fuzzed/fuzzing-ice-134905.rs b/tests/ui/specialization/fuzzed/fuzzing-ice-134905.rs new file mode 100644 index 000000000000..559c23455275 --- /dev/null +++ b/tests/ui/specialization/fuzzed/fuzzing-ice-134905.rs @@ -0,0 +1,22 @@ +// This test previously tried to use a tainted `EvalCtxt` when emitting +// an error during coherence. +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete +trait Iterate<'a> { + type Ty: Valid; +} +impl<'a, T> Iterate<'a> for T +where + T: Check, +{ + default type Ty = (); + //~^ ERROR the trait bound `(): Valid` is not satisfied +} + +trait Check {} +impl<'a, T> Eq for T where >::Ty: Valid {} +//~^ ERROR type parameter `T` must be used as the type parameter for some local type + +trait Valid {} + +fn main() {} diff --git a/tests/ui/specialization/fuzzed/fuzzing-ice-134905.stderr b/tests/ui/specialization/fuzzed/fuzzing-ice-134905.stderr new file mode 100644 index 000000000000..611fef1df66b --- /dev/null +++ b/tests/ui/specialization/fuzzed/fuzzing-ice-134905.stderr @@ -0,0 +1,40 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/fuzzing-ice-134905.rs:3:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `(): Valid` is not satisfied + --> $DIR/fuzzing-ice-134905.rs:12:23 + | +LL | default type Ty = (); + | ^^ the trait `Valid` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/fuzzing-ice-134905.rs:20:1 + | +LL | trait Valid {} + | ^^^^^^^^^^^ +note: required by a bound in `Iterate::Ty` + --> $DIR/fuzzing-ice-134905.rs:6:14 + | +LL | type Ty: Valid; + | ^^^^^ required by this bound in `Iterate::Ty` + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/fuzzing-ice-134905.rs:17:10 + | +LL | impl<'a, T> Eq for T where >::Ty: Valid {} + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0210, E0277. +For more information about an error, try `rustc --explain E0210`. From 81c6d5ec9ba239ebe892fc974a8c66094242f08d Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 12 Feb 2025 15:52:02 +0100 Subject: [PATCH 15/16] eagerly prove WF when resolving fully qualified paths --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 33 ++++------------ .../method/path_lookup_wf_constraints.rs | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+), 25 deletions(-) create mode 100644 tests/ui/traits/next-solver/method/path_lookup_wf_constraints.rs diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e74ffeff343a..1113f7f70953 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -798,13 +798,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`") } }; + + self.register_wf_obligation( + ty.raw.into(), + qself.span, + ObligationCauseCode::WellFormed(None), + ); + self.select_obligations_where_possible(|_| {}); + if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id) { - self.register_wf_obligation( - ty.raw.into(), - qself.span, - ObligationCauseCode::WellFormed(None), - ); // Return directly on cache hit. This is useful to avoid doubly reporting // errors with default match binding modes. See #44614. let def = cached_result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)); @@ -824,18 +827,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_missing_method = matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait(); - // If we have a path like `MyTrait::missing_method`, then don't register - // a WF obligation for `dyn MyTrait` when method lookup fails. Otherwise, - // register a WF obligation so that we can detect any additional - // errors in the self type. - if !trait_missing_method { - self.register_wf_obligation( - ty.raw.into(), - qself.span, - ObligationCauseCode::WellFormed(None), - ); - } - if item_name.name != kw::Empty { self.report_method_error( hir_id, @@ -849,14 +840,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { result }); - if result.is_ok() { - self.register_wf_obligation( - ty.raw.into(), - qself.span, - ObligationCauseCode::WellFormed(None), - ); - } - // Write back the new resolution. self.write_resolution(hir_id, result); ( diff --git a/tests/ui/traits/next-solver/method/path_lookup_wf_constraints.rs b/tests/ui/traits/next-solver/method/path_lookup_wf_constraints.rs new file mode 100644 index 000000000000..fbe170b1990e --- /dev/null +++ b/tests/ui/traits/next-solver/method/path_lookup_wf_constraints.rs @@ -0,0 +1,39 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// A regression test for trait-system-refactor-initiative#161 + +trait Constrain { + type Assoc; +} +impl Constrain for () { + type Assoc = (); +} +struct Foo>::Assoc>(T, U); + +impl Foo { + fn foo() {} +} +struct B; +impl Foo { + fn foo() {} +} + +type Alias = Foo; +fn via_guidance() +where + (): Constrain, +{ + // Method selection on `Foo>::Assoc>` is ambiguous. + // only by unnecessarily constraining `?t` to `T` when proving `(): Constrain` + // are we able to select the first impl. + // + // This happens in the old solver when normalizing `Alias`. The new solver doesn't try + // to eagerly normalize `<() as Constrain>::Assoc` so we instead always prove that the + // self type is well-formed before method lookup. + Alias::foo(); +} + +fn main() { + via_guidance::<()>(); +} From 83a02619d582349fd8d39233263c916033053c0a Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 12 Feb 2025 15:52:15 +0100 Subject: [PATCH 16/16] fallout :skull_emoji: --- .../associated-const-in-trait.rs | 1 + .../associated-const-in-trait.stderr | 18 ++++- ...tion-self-ty-invalid-bivariant-arg2.stderr | 24 +++--- .../hr-associated-type-bound-object.rs | 1 + .../hr-associated-type-bound-object.stderr | 21 ++++- .../hr-associated-type-bound-param-2.rs | 1 + .../hr-associated-type-bound-param-2.stderr | 22 ++++- .../defaults/doesnt_infer.stderr | 32 ++++---- .../generic_arg_infer/issue-91614.stderr | 26 +++--- .../issue-62504.full.stderr | 32 ++++---- .../issue-62504.min.stderr | 32 ++++---- .../generic_const_exprs/issue-80742.stderr | 2 +- .../const-needs_drop-monomorphic.stderr | 18 ++--- ...y_owner_parent_found_in_diagnostics.stderr | 18 ++--- .../assoc_type_bounds_sized_used.stderr | 28 +++---- tests/ui/impl-trait/issues/issue-62742.stderr | 42 +++++----- .../need_type_info/type-alias.stderr | 4 +- tests/ui/issues/issue-58734.rs | 1 + tests/ui/issues/issue-58734.stderr | 30 ++++++- .../ui/methods/inherent-bound-in-probe.stderr | 13 +-- tests/ui/traits/item-privacy.rs | 9 ++- tests/ui/traits/item-privacy.stderr | 80 +++++++++++++++---- .../constrain_in_projection.current.stderr | 11 ++- .../constrain_in_projection.rs | 1 + .../constrain_in_projection2.current.stderr | 12 ++- .../constrain_in_projection2.rs | 1 + 26 files changed, 319 insertions(+), 161 deletions(-) diff --git a/tests/ui/associated-consts/associated-const-in-trait.rs b/tests/ui/associated-consts/associated-const-in-trait.rs index 90ad596b23ee..4d88f4ff5316 100644 --- a/tests/ui/associated-consts/associated-const-in-trait.rs +++ b/tests/ui/associated-consts/associated-const-in-trait.rs @@ -8,6 +8,7 @@ impl dyn Trait { //~^ ERROR the trait `Trait` is not dyn compatible [E0038] const fn n() -> usize { Self::N } //~^ ERROR the trait `Trait` is not dyn compatible [E0038] + //~| ERROR the trait `Trait` is not dyn compatible } fn main() {} diff --git a/tests/ui/associated-consts/associated-const-in-trait.stderr b/tests/ui/associated-consts/associated-const-in-trait.stderr index 5aaa6f6be057..fba7f53c097f 100644 --- a/tests/ui/associated-consts/associated-const-in-trait.stderr +++ b/tests/ui/associated-consts/associated-const-in-trait.stderr @@ -30,6 +30,22 @@ LL | const N: usize; | ^ ...because it contains this associated `const` = help: consider moving `N` to another trait -error: aborting due to 2 previous errors +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/associated-const-in-trait.rs:9:29 + | +LL | const fn n() -> usize { Self::N } + | ^^^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/associated-const-in-trait.rs:4:11 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +LL | const N: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `N` to another trait + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr index 18d458aea809..165e89010b68 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr @@ -1,15 +1,3 @@ -error[E0599]: no associated item named `C` found for struct `Fail` in the current scope - --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:23 - | -LL | struct Fail, U>(T); - | ---------------------------------- associated item `C` not found for this struct -... -LL | Fail::::C - | ^ associated item not found in `Fail` - | - = note: the associated item was found for - - `Fail` - error[E0271]: type mismatch resolving `::Assoc == u32` --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:5 | @@ -27,6 +15,18 @@ note: required by a bound in `Fail` LL | struct Fail, U>(T); | ^^^^^^^^^ required by this bound in `Fail` +error[E0599]: no associated item named `C` found for struct `Fail` in the current scope + --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:23 + | +LL | struct Fail, U>(T); + | ---------------------------------- associated item `C` not found for this struct +... +LL | Fail::::C + | ^ associated item not found in `Fail` + | + = note: the associated item was found for + - `Fail` + error: aborting due to 2 previous errors Some errors have detailed explanations: E0271, E0599. diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.rs b/tests/ui/associated-types/hr-associated-type-bound-object.rs index fec253f9289a..825e129dbbda 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-object.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-object.rs @@ -9,6 +9,7 @@ fn f<'a, T: X<'a> + ?Sized>(x: &>::U) { <>::U>::clone(x); //~^ ERROR the trait bound `for<'b> >::U: Clone` is not satisfied //~| ERROR the trait bound `for<'b> >::U: Clone` is not satisfied + //~| ERROR the trait bound `for<'b> >::U: Clone` is not satisfied //~| ERROR the trait bound `>::U: Clone` is not satisfied } diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.stderr b/tests/ui/associated-types/hr-associated-type-bound-object.stderr index 322d6e7b947c..5144cfe6d3e7 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-object.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-object.stderr @@ -47,6 +47,25 @@ help: consider further restricting the associated type LL | fn f<'a, T: X<'a> + ?Sized>(x: &>::U) where >::U: Clone { | ++++++++++++++++++++++++++++ +error[E0277]: the trait bound `for<'b> >::U: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-object.rs:9:5 + | +LL | <>::U>::clone(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> Clone` is not implemented for `>::U` + | +note: required by a bound in `X` + --> $DIR/hr-associated-type-bound-object.rs:3:33 + | +LL | trait X<'a> + | - required by a bound in this trait +LL | where +LL | for<'b> >::U: Clone, + | ^^^^^ required by this bound in `X` +help: consider further restricting the associated type + | +LL | fn f<'a, T: X<'a> + ?Sized>(x: &>::U) where for<'b> >::U: Clone { + | ++++++++++++++++++++++++++++++++++++ + error[E0277]: the trait bound `for<'b> >::U: Clone` is not satisfied --> $DIR/hr-associated-type-bound-object.rs:9:5 | @@ -66,6 +85,6 @@ help: consider further restricting the associated type LL | fn f<'a, T: X<'a> + ?Sized>(x: &>::U) where for<'b> >::U: Clone { | ++++++++++++++++++++++++++++++++++++ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.rs b/tests/ui/associated-types/hr-associated-type-bound-param-2.rs index b1a6fe871594..673f02c7cd0e 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-2.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.rs @@ -10,6 +10,7 @@ where ::clone(x); //~^ the trait bound `str: Clone` is not satisfied //~| the trait bound `str: Clone` is not satisfied + //~| the trait bound `str: Clone` is not satisfied } } diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr index 74cc2083d26f..8997832ab52a 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr @@ -15,7 +15,7 @@ LL | for<'b> >::W: Clone, | ^^^^^ required by this bound in `Z` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-2.rs:17:14 + --> $DIR/hr-associated-type-bound-param-2.rs:18:14 | LL | type W = str; | ^^^ the trait `Clone` is not implemented for `str` @@ -63,6 +63,22 @@ LL | { LL | type W: ?Sized; | - required by a bound in this associated type +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-param-2.rs:10:9 + | +LL | ::clone(x); + | ^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `Z` + --> $DIR/hr-associated-type-bound-param-2.rs:6:35 + | +LL | trait Z<'a, T: ?Sized> + | - required by a bound in this trait +... +LL | for<'b> >::W: Clone, + | ^^^^^ required by this bound in `Z` + error[E0277]: the trait bound `str: Clone` is not satisfied --> $DIR/hr-associated-type-bound-param-2.rs:10:9 | @@ -80,7 +96,7 @@ LL | for<'b> >::W: Clone, | ^^^^^ required by this bound in `Z` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-2.rs:22:10 + --> $DIR/hr-associated-type-bound-param-2.rs:23:10 | LL | 1u16.h("abc"); | ^ the trait `Clone` is not implemented for `str` @@ -95,6 +111,6 @@ LL | for<'b> >::W: Clone, LL | fn h(&self, x: &T::W) { | - required by a bound in this associated function -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/defaults/doesnt_infer.stderr b/tests/ui/const-generics/defaults/doesnt_infer.stderr index c17f57f36bc5..ef39cef70cbc 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -1,3 +1,19 @@ +error[E0284]: type annotations needed for `Foo<_>` + --> $DIR/doesnt_infer.rs:13:9 + | +LL | let foo = Foo::foo(); + | ^^^ --- type must be known at this point + | +note: required by a const generic parameter in `Foo` + --> $DIR/doesnt_infer.rs:3:12 + | +LL | struct Foo; + | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` +help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified + | +LL | let foo: Foo = Foo::foo(); + | ++++++++ + error[E0284]: type annotations needed for `Foo<_>` --> $DIR/doesnt_infer.rs:13:9 | @@ -16,22 +32,6 @@ help: consider giving `foo` an explicit type, where the value of const parameter LL | let foo: Foo = Foo::foo(); | ++++++++ -error[E0284]: type annotations needed for `Foo<_>` - --> $DIR/doesnt_infer.rs:13:9 - | -LL | let foo = Foo::foo(); - | ^^^ --- type must be known at this point - | -note: required by a const generic parameter in `Foo` - --> $DIR/doesnt_infer.rs:3:12 - | -LL | struct Foo; - | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` -help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified - | -LL | let foo: Foo = Foo::foo(); - | ++++++++ - error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index b88fe966b77c..b07e1f29d0d9 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -1,16 +1,3 @@ -error[E0284]: type annotations needed for `Mask<_, _>` - --> $DIR/issue-91614.rs:6:9 - | -LL | let y = Mask::<_, _>::splat(false); - | ^ -------------------------- type must be known at this point - | -note: required by a const generic parameter in `Mask::::splat` - --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL -help: consider giving `y` an explicit type, where the value of const parameter `N` is specified - | -LL | let y: Mask<_, N> = Mask::<_, _>::splat(false); - | ++++++++++++ - error[E0284]: type annotations needed for `Mask<_, _>` --> $DIR/issue-91614.rs:6:9 | @@ -24,6 +11,19 @@ help: consider giving `y` an explicit type, where the value of const parameter ` LL | let y: Mask<_, N> = Mask::<_, _>::splat(false); | ++++++++++++ +error[E0284]: type annotations needed for `Mask<_, _>` + --> $DIR/issue-91614.rs:6:9 + | +LL | let y = Mask::<_, _>::splat(false); + | ^ -------------------------- type must be known at this point + | +note: required by a const generic parameter in `Mask::::splat` + --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL +help: consider giving `y` an explicit type, where the value of const parameter `N` is specified + | +LL | let y: Mask<_, N> = Mask::<_, _>::splat(false); + | ++++++++++++ + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr index 3739637c2795..6b79b32d13e3 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr @@ -18,6 +18,22 @@ help: try adding a `where` bound LL | pub const fn new() -> Self where [(); Self::SIZE]: { | +++++++++++++++++++++++ +error[E0284]: type annotations needed for `ArrayHolder<_>` + --> $DIR/issue-62504.rs:26:9 + | +LL | let mut array = ArrayHolder::new(); + | ^^^^^^^^^ ----------- type must be known at this point + | +note: required by a const generic parameter in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 + | +LL | struct ArrayHolder([u32; X]); + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` +help: consider giving `array` an explicit type, where the value of const parameter `X` is specified + | +LL | let mut array: ArrayHolder = ArrayHolder::new(); + | ++++++++++++++++ + error[E0284]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | @@ -36,22 +52,6 @@ help: consider giving `array` an explicit type, where the value of const paramet LL | let mut array: ArrayHolder = ArrayHolder::new(); | ++++++++++++++++ -error[E0284]: type annotations needed for `ArrayHolder<_>` - --> $DIR/issue-62504.rs:26:9 - | -LL | let mut array = ArrayHolder::new(); - | ^^^^^^^^^ ----------- type must be known at this point - | -note: required by a const generic parameter in `ArrayHolder` - --> $DIR/issue-62504.rs:14:20 - | -LL | struct ArrayHolder([u32; X]); - | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` -help: consider giving `array` an explicit type, where the value of const parameter `X` is specified - | -LL | let mut array: ArrayHolder = ArrayHolder::new(); - | ++++++++++++++++ - error: aborting due to 4 previous errors Some errors have detailed explanations: E0284, E0308. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index 8efd433fd1fe..c53a6598d34e 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -20,6 +20,22 @@ note: tuple struct defined here LL | struct ArrayHolder([u32; X]); | ^^^^^^^^^^^ +error[E0284]: type annotations needed for `ArrayHolder<_>` + --> $DIR/issue-62504.rs:26:9 + | +LL | let mut array = ArrayHolder::new(); + | ^^^^^^^^^ ----------- type must be known at this point + | +note: required by a const generic parameter in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 + | +LL | struct ArrayHolder([u32; X]); + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` +help: consider giving `array` an explicit type, where the value of const parameter `X` is specified + | +LL | let mut array: ArrayHolder = ArrayHolder::new(); + | ++++++++++++++++ + error[E0284]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | @@ -38,22 +54,6 @@ help: consider giving `array` an explicit type, where the value of const paramet LL | let mut array: ArrayHolder = ArrayHolder::new(); | ++++++++++++++++ -error[E0284]: type annotations needed for `ArrayHolder<_>` - --> $DIR/issue-62504.rs:26:9 - | -LL | let mut array = ArrayHolder::new(); - | ^^^^^^^^^ ----------- type must be known at this point - | -note: required by a const generic parameter in `ArrayHolder` - --> $DIR/issue-62504.rs:14:20 - | -LL | struct ArrayHolder([u32; X]); - | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` -help: consider giving `array` an explicit type, where the value of const parameter `X` is specified - | -LL | let mut array: ArrayHolder = ArrayHolder::new(); - | ++++++++++++++++ - error: aborting due to 4 previous errors Some errors have detailed explanations: E0284, E0308. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index d90380396c1f..07fd231cb7ae 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -4,7 +4,7 @@ error: internal compiler error: compiler/rustc_const_eval/src/interpret/operator Box query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating + checking `::{constant#0}` +#0 [eval_to_allocation_raw] const-evaluating + checking `Inline::{constant#0}` #1 [eval_to_valtree] evaluating type-level constant ... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-needs_drop-monomorphic.stderr b/tests/ui/consts/const-needs_drop-monomorphic.stderr index 446d34810c59..17f197cdd5d2 100644 --- a/tests/ui/consts/const-needs_drop-monomorphic.stderr +++ b/tests/ui/consts/const-needs_drop-monomorphic.stderr @@ -1,12 +1,3 @@ -error[E0599]: no function or associated item named `assert` found for struct `Bool<{ std::mem::needs_drop::() }>` in the current scope - --> $DIR/const-needs_drop-monomorphic.rs:11:46 - | -LL | struct Bool {} - | -------------------------- function or associated item `assert` not found for this struct -... -LL | Bool::<{ std::mem::needs_drop::() }>::assert(); - | ^^^^^^ function or associated item cannot be called on `Bool<{ std::mem::needs_drop::() }>` due to unsatisfied trait bounds - error: unconstrained generic constant --> $DIR/const-needs_drop-monomorphic.rs:11:5 | @@ -18,6 +9,15 @@ help: try adding a `where` bound LL | fn f() where [(); { std::mem::needs_drop::() } as usize]: { | +++++++++++++++++++++++++++++++++++++++++++++++++++++ +error[E0599]: no function or associated item named `assert` found for struct `Bool<{ std::mem::needs_drop::() }>` in the current scope + --> $DIR/const-needs_drop-monomorphic.rs:11:46 + | +LL | struct Bool {} + | -------------------------- function or associated item `assert` not found for this struct +... +LL | Bool::<{ std::mem::needs_drop::() }>::assert(); + | ^^^^^^ function or associated item cannot be called on `Bool<{ std::mem::needs_drop::() }>` due to unsatisfied trait bounds + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr index 2ce3b388073c..61e2a8f64dd5 100644 --- a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr +++ b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr @@ -52,6 +52,14 @@ LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>); LL | pub const NEW: Self = InvariantRef::new(&()); | ^^^ function or associated item not found in `InvariantRef<'_, _>` +error[E0277]: the trait bound `u8: Trait` is not satisfied + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:22:12 + | +LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW } } + | ^^ the trait `Trait` is not implemented for `u8` + | + = help: the trait `Trait` is implemented for `Z` + error[E0308]: mismatched types --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:22:53 | @@ -68,6 +76,7 @@ LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW | ^^ the trait `Trait` is not implemented for `u8` | = help: the trait `Trait` is implemented for `Z` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0308]: mismatched types --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:22:53 @@ -98,15 +107,6 @@ LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW found struct `InvariantRef<'_, ()>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0277]: the trait bound `u8: Trait` is not satisfied - --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:22:12 - | -LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW } } - | ^^ the trait `Trait` is not implemented for `u8` - | - = help: the trait `Trait` is implemented for `Z` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error: aborting due to 10 previous errors Some errors have detailed explanations: E0261, E0277, E0308, E0599. diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.stderr index b67a1244ecea..7b152adea492 100644 --- a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.stderr +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.stderr @@ -1,17 +1,3 @@ -error[E0599]: the function or associated item `default` exists for associated type `::Bar`, but its trait bounds were not satisfied - --> $DIR/assoc_type_bounds_sized_used.rs:11:30 - | -LL | let _ = ::Bar::default(); - | ^^^^^^^ function or associated item cannot be called on `::Bar` due to unsatisfied trait bounds - | - = note: the following trait bounds were not satisfied: - `T: Sized` - which is required by `::Bar: Default` -help: consider restricting the type parameter to satisfy the trait bound - | -LL | fn bop() where T: Sized { - | ++++++++++++++ - error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/assoc_type_bounds_sized_used.rs:11:14 | @@ -38,6 +24,20 @@ help: consider relaxing the implicit `Sized` restriction LL | type Bar: Default + ?Sized | ++++++++ +error[E0599]: the function or associated item `default` exists for associated type `::Bar`, but its trait bounds were not satisfied + --> $DIR/assoc_type_bounds_sized_used.rs:11:30 + | +LL | let _ = ::Bar::default(); + | ^^^^^^^ function or associated item cannot be called on `::Bar` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `T: Sized` + which is required by `::Bar: Default` +help: consider restricting the type parameter to satisfy the trait bound + | +LL | fn bop() where T: Sized { + | ++++++++++++++ + error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0599. diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index 98d17b02536c..ee4eb98f4eaf 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -1,3 +1,17 @@ +error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied + --> $DIR/issue-62742.rs:4:5 + | +LL | WrongImpl::foo(0i32); + | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` + | + = help: the trait `Raw<_>` is not implemented for `RawImpl<_>` + but trait `Raw<[_]>` is implemented for it +note: required by a bound in `SafeImpl` + --> $DIR/issue-62742.rs:33:35 + | +LL | pub struct SafeImpl>(PhantomData<(A, T)>); + | ^^^^^^ required by this bound in `SafeImpl` + error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied --> $DIR/issue-62742.rs:4:16 | @@ -23,14 +37,15 @@ note: the trait `Raw` must be implemented LL | pub trait Raw { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied - --> $DIR/issue-62742.rs:4:5 +error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied + --> $DIR/issue-62742.rs:10:5 | -LL | WrongImpl::foo(0i32); - | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` +LL | WrongImpl::<()>::foo(0i32); + | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` | - = help: the trait `Raw<_>` is not implemented for `RawImpl<_>` - but trait `Raw<[_]>` is implemented for it + = help: the trait `Raw<()>` is not implemented for `RawImpl<()>` + but trait `Raw<[()]>` is implemented for it + = help: for that trait implementation, expected `[()]`, found `()` note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:33:35 | @@ -62,21 +77,6 @@ note: the trait `Raw` must be implemented LL | pub trait Raw { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied - --> $DIR/issue-62742.rs:10:5 - | -LL | WrongImpl::<()>::foo(0i32); - | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` - | - = help: the trait `Raw<()>` is not implemented for `RawImpl<()>` - but trait `Raw<[()]>` is implemented for it - = help: for that trait implementation, expected `[()]`, found `()` -note: required by a bound in `SafeImpl` - --> $DIR/issue-62742.rs:33:35 - | -LL | pub struct SafeImpl>(PhantomData<(A, T)>); - | ^^^^^^ required by this bound in `SafeImpl` - error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0599. diff --git a/tests/ui/inference/need_type_info/type-alias.stderr b/tests/ui/inference/need_type_info/type-alias.stderr index 2c39a3f56466..47393557828f 100644 --- a/tests/ui/inference/need_type_info/type-alias.stderr +++ b/tests/ui/inference/need_type_info/type-alias.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/type-alias.rs:12:5 | LL | DirectAlias::new() - | ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectAlias` error[E0282]: type annotations needed --> $DIR/type-alias.rs:18:5 @@ -14,7 +14,7 @@ error[E0282]: type annotations needed --> $DIR/type-alias.rs:32:5 | LL | DirectButWithDefaultAlias::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectButWithDefaultAlias` error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-58734.rs b/tests/ui/issues/issue-58734.rs index 9b630666baf8..ee23be87b6b7 100644 --- a/tests/ui/issues/issue-58734.rs +++ b/tests/ui/issues/issue-58734.rs @@ -21,4 +21,5 @@ fn main() { //~^ ERROR no function or associated item named `nonexistent` found //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition + //~| ERROR the trait `Trait` is not dyn compatible } diff --git a/tests/ui/issues/issue-58734.stderr b/tests/ui/issues/issue-58734.stderr index a2acd9dcf818..c4624cecc621 100644 --- a/tests/ui/issues/issue-58734.stderr +++ b/tests/ui/issues/issue-58734.stderr @@ -12,12 +12,38 @@ help: if this is a dyn-compatible trait, use `dyn` LL | ::nonexistent(()); | ++++ + +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/issue-58734.rs:20:5 + | +LL | Trait::nonexistent(()); + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/issue-58734.rs:4:8 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +... +LL | fn dyn_incompatible() -> Self; + | ^^^^^^^^^^^^^^^^ ...because associated function `dyn_incompatible` has no `self` parameter + = help: only type `()` implements `Trait`; consider using it directly instead. +help: consider turning `dyn_incompatible` into a method by giving it a `&self` argument + | +LL | fn dyn_incompatible(&self) -> Self; + | +++++ +help: alternatively, consider constraining `dyn_incompatible` so it does not apply to trait objects + | +LL | fn dyn_incompatible() -> Self where Self: Sized; + | +++++++++++++++++ + error[E0599]: no function or associated item named `nonexistent` found for trait object `dyn Trait` in the current scope --> $DIR/issue-58734.rs:20:12 | LL | Trait::nonexistent(()); | ^^^^^^^^^^^ function or associated item not found in `dyn Trait` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0599`. +Some errors have detailed explanations: E0038, E0599. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/methods/inherent-bound-in-probe.stderr b/tests/ui/methods/inherent-bound-in-probe.stderr index 8d7cc462280d..433ef02a2aa4 100644 --- a/tests/ui/methods/inherent-bound-in-probe.stderr +++ b/tests/ui/methods/inherent-bound-in-probe.stderr @@ -9,10 +9,10 @@ note: required by a bound in `std::iter::IntoIterator::IntoIter` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL error[E0275]: overflow evaluating the requirement `&_: IntoIterator` - --> $DIR/inherent-bound-in-probe.rs:44:17 + --> $DIR/inherent-bound-in-probe.rs:44:9 | LL | Helper::new(&self.0) - | ^^^ + | ^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_bound_in_probe`) note: required for `&BitReaderWrapper<_>` to implement `IntoIterator` @@ -25,11 +25,14 @@ LL | &'a T: IntoIterator, | ------------- unsatisfied trait bound introduced here = note: 126 redundant requirements hidden = note: required for `&BitReaderWrapper>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `IntoIterator` -note: required by a bound in `Helper<'a, T>` - --> $DIR/inherent-bound-in-probe.rs:25:25 +note: required by a bound in `Helper` + --> $DIR/inherent-bound-in-probe.rs:18:12 | +LL | struct Helper<'a, T> + | ------ required by a bound in this struct +LL | where LL | &'a T: IntoIterator, - | ^^^^^^^^^^^^^ required by this bound in `Helper<'a, T>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Helper` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/item-privacy.rs b/tests/ui/traits/item-privacy.rs index f5c741ccaa51..cdfd667a6f12 100644 --- a/tests/ui/traits/item-privacy.rs +++ b/tests/ui/traits/item-privacy.rs @@ -98,9 +98,12 @@ fn check_assoc_const() { S::B; //~ ERROR no associated item named `B` found S::C; // OK // A, B, C are resolved as inherent items, their traits don't need to be in scope - ::A; //~ ERROR associated constant `A` is private - //~^ ERROR the trait `assoc_const::C` is not dyn compatible - ::B; // ERROR the trait `assoc_const::C` is not dyn compatible + ::A; + //~^ ERROR associated constant `A` is private + //~| ERROR the trait `assoc_const::C` is not dyn compatible + //~| ERROR the trait `assoc_const::C` is not dyn compatible + ::B; + //~^ ERROR the trait `assoc_const::C` is not dyn compatible C::C; // OK } diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index ddead3fdfd36..4fd9ef911925 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -130,15 +130,6 @@ help: trait `B` which provides `B` is implemented but not in scope; perhaps you LL + use assoc_const::B; | -error[E0624]: associated constant `A` is private - --> $DIR/item-privacy.rs:101:14 - | -LL | const A: u8 = 0; - | ----------- private associated constant defined here -... -LL | ::A; - | ^ private associated constant - error[E0038]: the trait `assoc_const::C` is not dyn compatible --> $DIR/item-privacy.rs:101:6 | @@ -164,8 +155,67 @@ LL | const C: u8 = 0; = help: consider moving `B` to another trait = help: only type `S` implements `assoc_const::C`; consider using it directly instead. +error[E0624]: associated constant `A` is private + --> $DIR/item-privacy.rs:101:14 + | +LL | const A: u8 = 0; + | ----------- private associated constant defined here +... +LL | ::A; + | ^ private associated constant + +error[E0038]: the trait `assoc_const::C` is not dyn compatible + --> $DIR/item-privacy.rs:101:5 + | +LL | ::A; + | ^^^^^^^^^^ `assoc_const::C` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/item-privacy.rs:25:15 + | +LL | const A: u8 = 0; + | ^ ...because it contains this associated `const` +... +LL | const B: u8 = 0; + | ^ ...because it contains this associated `const` +... +LL | pub trait C: A + B { + | - this trait is not dyn compatible... +LL | const C: u8 = 0; + | ^ ...because it contains this associated `const` + = help: consider moving `C` to another trait + = help: consider moving `A` to another trait + = help: consider moving `B` to another trait + = help: only type `S` implements `assoc_const::C`; consider using it directly instead. + +error[E0038]: the trait `assoc_const::C` is not dyn compatible + --> $DIR/item-privacy.rs:105:5 + | +LL | ::B; + | ^^^^^^^^^^ `assoc_const::C` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/item-privacy.rs:25:15 + | +LL | const A: u8 = 0; + | ^ ...because it contains this associated `const` +... +LL | const B: u8 = 0; + | ^ ...because it contains this associated `const` +... +LL | pub trait C: A + B { + | - this trait is not dyn compatible... +LL | const C: u8 = 0; + | ^ ...because it contains this associated `const` + = help: consider moving `C` to another trait + = help: consider moving `A` to another trait + = help: consider moving `B` to another trait + = help: only type `S` implements `assoc_const::C`; consider using it directly instead. + error[E0223]: ambiguous associated type - --> $DIR/item-privacy.rs:115:12 + --> $DIR/item-privacy.rs:118:12 | LL | let _: S::A; | ^^^^ @@ -177,19 +227,19 @@ LL + let _: ::A; | error[E0223]: ambiguous associated type - --> $DIR/item-privacy.rs:116:12 + --> $DIR/item-privacy.rs:119:12 | LL | let _: S::B; | ^^^^ help: use fully-qualified syntax: `::B` error[E0223]: ambiguous associated type - --> $DIR/item-privacy.rs:117:12 + --> $DIR/item-privacy.rs:120:12 | LL | let _: S::C; | ^^^^ help: use fully-qualified syntax: `::C` error[E0624]: associated type `A` is private - --> $DIR/item-privacy.rs:119:12 + --> $DIR/item-privacy.rs:122:12 | LL | type A = u8; | ------ the associated type is defined here @@ -198,7 +248,7 @@ LL | let _: T::A; | ^^^^ private associated type error[E0624]: associated type `A` is private - --> $DIR/item-privacy.rs:128:9 + --> $DIR/item-privacy.rs:131:9 | LL | type A = u8; | ------ the associated type is defined here @@ -206,7 +256,7 @@ LL | type A = u8; LL | A = u8, | ^^^^^^ private associated type -error: aborting due to 15 previous errors +error: aborting due to 17 previous errors Some errors have detailed explanations: E0038, E0223, E0599, E0624. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr index d96c86a2e6f1..580258bbb28e 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr @@ -7,6 +7,15 @@ LL | let x = >::Assoc::default(); = help: the trait `Trait` is not implemented for `Foo` but trait `Trait<()>` is implemented for it -error: aborting due to 1 previous error +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/constrain_in_projection.rs:24:13 + | +LL | let x = >::Assoc::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Foo` + | + = help: the trait `Trait` is not implemented for `Foo` + but trait `Trait<()>` is implemented for it + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs index 7d7d16361ae6..355c0e1692b2 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -23,6 +23,7 @@ impl Trait<()> for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); //[current]~^ `Foo: Trait` is not satisfied + //[current]~| `Foo: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr index 909f1f6d61cb..777fe1e2788c 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -8,6 +8,16 @@ LL | let x = >::Assoc::default(); `Foo` implements `Trait<()>` `Foo` implements `Trait` -error: aborting due to 1 previous error +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/constrain_in_projection2.rs:27:13 + | +LL | let x = >::Assoc::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Foo` + | + = help: the following other types implement trait `Trait`: + `Foo` implements `Trait<()>` + `Foo` implements `Trait` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs index af222f6c1534..16b1329b52f3 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -27,6 +27,7 @@ fn bop(_: Bar) { let x = >::Assoc::default(); //[next]~^ ERROR: cannot satisfy `Foo: Trait` //[current]~^^ ERROR: `Foo: Trait` is not satisfied + //[current]~| ERROR: `Foo: Trait` is not satisfied } fn main() {}