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 a80b68d9773d4..0962865e7f190 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 0000000000000..9f9c1d1bc5aa1 --- /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 0000000000000..ae218237a8d5c --- /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 0000000000000..185ad9c928b48 --- /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 11824398f243e..187d97c54c873 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 58f43fe3ec6bf..80a4081f15b10 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 1a8f42428ab87..ad79f5d5a80c0 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 a86c20d46bda5..ac971a64d7c22 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -44,10 +44,14 @@ def v(*args): 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 d3ed7ecddd3d7..0ee476d19c9d3 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 6f62df28e4949..9b23cf1843ef5 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 f39c0e4a31400..4f5f8f92264c1 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 d53993ac08bae..12246a3766151 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 6f9984d5d0ac3..039f346495be0 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 cd89fbe772d4c..ef86358b2057a 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 35568a98af444..526110ebbb764 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 7660f917b65aa..c2a0645ee9a8c 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 ba30627844937..baac0073fcbec 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 549b8bb0a2096..2d12f4bf7744a 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 a97c0f8794c43..16facf2eddf26 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 d082bd54493d7..bc5661afdc194 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 640d5f15be0ee..2cb0f948b3e1d 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 03012f744c18c..35b2c36a57519 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 d42aa8a7b847d..5a6698128cbd3 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 509875a469f1f..2b4e9d48a2456 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 0ee476d19c9d3..62625fc3660f9 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 c08104e796b93..48814f7dd8a19 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 ad79f5d5a80c0..86d40db3ded74 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 a2375842bddef..bee0da0eb9048 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 ee60dbef7b98e..18da0e8252b90 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 509875a469f1f..fdbb48ca4e65e 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 8e767a8dcc695..ecec589fc32eb 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 825e5452f0e6a..f645b0e838625 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 a3274fb401156..23fe88b16802d 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 eb398e8724d44..0b61c368d8e8d 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 1d0ec7b45ca19..e3d16719e283d 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 26a8a22d77ebe..60c20762a30ab 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 9f4ee54bd4c66..9fbc1d64d7429 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 b0b6274907d0c..4437fc5b0295f 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 d0e618dc6f96d..18fb71dd290e7 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 | 146 ++++++++++-------- 1 file changed, 79 insertions(+), 67 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 e3d16719e283d..88002e1a88a87 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()); - 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())]) - } + 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::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::Error(e) => Ty::new_error(cx, e), - 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::Str | ty::Slice(_) => Ty::new_usize(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::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::UnsafeBinder(_) => { - // FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders. - todo!() + 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::Infer( - ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_), - ) - | ty::Bound(..) => panic!( - "unexpected self ty `{:?}` when normalizing `::Metadata`", - goal.predicate.self_ty() - ), - }; + 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| { 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 23fe88b16802d..b0f59ed1474c2 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 1b43820bac0c5..49fa21e50c059 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 658fb4009d508..e4f250ca4f540 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 7364b4aa34380..982782bc57c18 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 9f0f0f4b3f227..0000000000000 --- 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 b9f56d6c99c4c..4ce00d1747564 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 + | +LL | let _: <() as Trait>::Output = (); + | ^^^^^^^^^^^^^^^^^^^^^ types differ | - = 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 + = 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 ada75147f6ea6..efbfead9cd037 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 3c24eb9adbee7..ce64a022214ea 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 c97bd1799436f..cb32723b22dd1 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 0000000000000..559c23455275b --- /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 0000000000000..611fef1df66bf --- /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 e74ffeff343a2..1113f7f70953b 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 0000000000000..fbe170b1990e7 --- /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 | 24 +++---- .../generic_arg_infer/issue-91614.stderr | 8 +-- .../issue-62504.full.stderr | 24 +++---- .../issue-62504.min.stderr | 24 +++---- .../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 | 66 ++++++++++++++++--- .../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, 291 insertions(+), 133 deletions(-) diff --git a/tests/ui/associated-consts/associated-const-in-trait.rs b/tests/ui/associated-consts/associated-const-in-trait.rs index 90ad596b23ee1..4d88f4ff53161 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 5aaa6f6be057e..fba7f53c097f2 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 18d458aea809b..165e89010b687 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 fec253f9289ac..825e129dbbda1 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 322d6e7b947c8..5144cfe6d3e7d 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 b1a6fe871594b..673f02c7cd0e5 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 74cc2083d26fe..8997832ab52a4 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 c17f57f36bc5f..ef39cef70cbc2 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -2,15 +2,13 @@ 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 + | ^^^ --- type must be known at this point | -note: required by a const generic parameter in `Foo::::foo` - --> $DIR/doesnt_infer.rs:5:6 +note: required by a const generic parameter in `Foo` + --> $DIR/doesnt_infer.rs:3:12 | -LL | impl Foo { - | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::::foo` -LL | fn foo() -> Self { - | --- required by a bound in this associated function +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(); @@ -20,13 +18,15 @@ 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 + | ^^^ ---------- type must be known at this point | -note: required by a const generic parameter in `Foo` - --> $DIR/doesnt_infer.rs:3:12 +note: required by a const generic parameter in `Foo::::foo` + --> $DIR/doesnt_infer.rs:5:6 | -LL | struct Foo; - | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` +LL | impl Foo { + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::::foo` +LL | fn foo() -> Self { + | --- required by a bound in this associated function help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified | LL | let foo: Foo = Foo::foo(); 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 b88fe966b77ce..b07e1f29d0d90 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -2,9 +2,9 @@ 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 + | ^ ------------ type must be known at this point | -note: required by a const generic parameter in `Mask::::splat` +note: required by a const generic parameter in `Mask` --> $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 | @@ -15,9 +15,9 @@ 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 + | ^ -------------------------- type must be known at this point | -note: required by a const generic parameter in `Mask` +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 | 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 3739637c27951..6b79b32d13e3b 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 @@ -22,15 +22,13 @@ 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 + | ^^^^^^^^^ ----------- type must be known at this point | -note: required by a const generic parameter in `ArrayHolder::::new` - --> $DIR/issue-62504.rs:16:6 +note: required by a const generic parameter in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 | -LL | impl ArrayHolder { - | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::::new` -LL | pub const fn new() -> Self { - | --- required by a bound in this associated function +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(); @@ -40,13 +38,15 @@ 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 + | ^^^^^^^^^ ------------------ type must be known at this point | -note: required by a const generic parameter in `ArrayHolder` - --> $DIR/issue-62504.rs:14:20 +note: required by a const generic parameter in `ArrayHolder::::new` + --> $DIR/issue-62504.rs:16:6 | -LL | struct ArrayHolder([u32; X]); - | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` +LL | impl ArrayHolder { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::::new` +LL | pub const fn new() -> Self { + | --- required by a bound in this associated function help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); 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 8efd433fd1fe9..c53a6598d34ed 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 @@ -24,15 +24,13 @@ 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 + | ^^^^^^^^^ ----------- type must be known at this point | -note: required by a const generic parameter in `ArrayHolder::::new` - --> $DIR/issue-62504.rs:16:6 +note: required by a const generic parameter in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 | -LL | impl ArrayHolder { - | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::::new` -LL | pub const fn new() -> Self { - | --- required by a bound in this associated function +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(); @@ -42,13 +40,15 @@ 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 + | ^^^^^^^^^ ------------------ type must be known at this point | -note: required by a const generic parameter in `ArrayHolder` - --> $DIR/issue-62504.rs:14:20 +note: required by a const generic parameter in `ArrayHolder::::new` + --> $DIR/issue-62504.rs:16:6 | -LL | struct ArrayHolder([u32; X]); - | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` +LL | impl ArrayHolder { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::::new` +LL | pub const fn new() -> Self { + | --- required by a bound in this associated function help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); 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 d90380396c1f3..07fd231cb7ae9 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 446d34810c59c..17f197cdd5d2b 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 2ce3b388073c4..61e2a8f64dd52 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 b67a1244eceab..7b152adea4925 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 98d17b02536cc..ee4eb98f4eaf5 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 2c39a3f56466f..47393557828fd 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 9b630666baf85..ee23be87b6b79 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 a2acd9dcf8189..c4624cecc621c 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 8d7cc462280d6..433ef02a2aa4c 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 f5c741ccaa514..cdfd667a6f12e 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 ddead3fdfd366..4fd9ef9119257 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -130,6 +130,31 @@ help: trait `B` which provides `B` is implemented but not in scope; perhaps you LL + use assoc_const::B; | +error[E0038]: the trait `assoc_const::C` is not dyn compatible + --> $DIR/item-privacy.rs:101:6 + | +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[E0624]: associated constant `A` is private --> $DIR/item-privacy.rs:101:14 | @@ -140,10 +165,35 @@ LL | ::A; | ^ private associated constant error[E0038]: the trait `assoc_const::C` is not dyn compatible - --> $DIR/item-privacy.rs:101:6 + --> $DIR/item-privacy.rs:101:5 | LL | ::A; - | ^^^^^ `assoc_const::C` is not dyn compatible + | ^^^^^^^^^^ `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 @@ -165,7 +215,7 @@ LL | const C: u8 = 0; = 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 d96c86a2e6f16..580258bbb28e4 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 7d7d16361ae6d..355c0e1692b2a 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 909f1f6d61cbe..777fe1e2788ce 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 af222f6c15347..16b1329b52f3d 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() {}