Question:
Found with a <details<summary<strongFull output including backtrace</strong</summary<p</p</detailsRegression in nightly-2022-09-18 from ( <details<summaryBisect info</summarysearched nightlies: from nightly-2022-09-04 to nightly-2022-11-07 regressed nightly: nightly-2022-09-18 searched commit range: regressed commit: bisected with <a href=''cargo-bisect-rustc</av0.6.4 Host triple: x86_64-apple-darwin </details
For the record, this isn't dependent on return type, which is a separate error. This also ICEs:
This don't ICE: I guess it's because terminated because the error type error.
Yeah, still needs to implement the trait in the -- this ICEs, for example:
I can take a look at this, unless you're already working on this
I think compiler-errors already submitted a PR to fix this, PR linked above, but he did not claim this issue.
Oh thanks, didn't see this.

<ins> error: expected at least one digit in exponent --> $DIR/invalid-const-in-body.rs:2:5 | LL |     2.0E |     ^^^^ error: aborting due to previous error </ins>


Question:
To reproduce, navigate to and click the the "source" link for any of the methods. Nothing at all happens when I do that. I tried Firefox and Chromium. This seems to be a fairly recent regression.
It's because it's under the for some reason. Let's see what changed in the last few days.
I think it's because of I'll try to send a fix today.
It's because a to have a correct positioning of the tooltip on mobile devices.

font-weight: 600; margin: 0; padding: 0; <del> /* position notable traits in mobile mode within the header */ position: relative; </del> } #crate-search,


Question:
To reproduce, navigate to and click the the "source" link for any of the methods. Nothing at all happens when I do that. I tried Firefox and Chromium. This seems to be a fairly recent regression.
It's because it's under the for some reason. Let's see what changed in the last few days.
I think it's because of I'll try to send a fix today.
It's because a to have a correct positioning of the tooltip on mobile devices.

// Check the impl items. assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL) assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px", "font-weight": 600}, ALL) <ins> // Check that we can click on source link store-document-property: (url, "URL") click: ".impl-items .has-srclink .srclink" assert-document-property-false: {"URL": |url|} </ins>


Question: Currently all of its functions immediately . We need to either remove this or implement it. I vote for implementing it.

//! //! * Should probably have something like this for strings. //! * Should they implement Closable? Would take extra state. <ins> use cmp::max; </ins> use cmp::min; use prelude::*; use super::*;


Question: Currently all of its functions immediately . We need to either remove this or implement it. I vote for implementing it.

} } <ins> // FIXME(#10432) </ins> impl Seek for MemWriter { fn tell(&self) -> u64 { self.pos as u64 } fn seek(&mut self, pos: i64, style: SeekStyle) { <del> match style { SeekSet => { self.pos = pos as uint; } SeekEnd => { self.pos = self.buf.len() + pos as uint; } SeekCur => { self.pos += pos as uint; } } </del> <ins> // compute offset as signed and clamp to prevent overflow let offset = match style { SeekSet => { 0 } SeekEnd => { self.buf.len() } SeekCur => { self.pos } } as i64; self.pos = max(0, offset+pos) as uint; </ins> } }


Question: Currently all of its functions immediately . We need to either remove this or implement it. I vote for implementing it.

/// Writes to a fixed-size byte slice <ins> /// /// If a write will not fit in the buffer, it raises the `io_error` /// condition and does not write any data. </ins> pub struct BufWriter<'self> { priv buf: &'self mut [u8], priv pos: uint


Question: Currently all of its functions immediately . We need to either remove this or implement it. I vote for implementing it.

} impl<'self> Writer for BufWriter<'self> { <del> fn write(&mut self, _buf: &[u8]) { fail!() } </del> <ins> fn write(&mut self, buf: &[u8]) { // raises a condition if the entire write does not fit in the buffer let max_size = self.buf.len(); if self.pos >= max_size || (self.pos + buf.len()) > max_size { io_error::cond.raise(IoError { kind: OtherIoError, desc: "Trying to write past end of buffer", detail: None }); return; } </ins> <del> fn flush(&mut self) { fail!() } </del> <ins> vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos), buf, buf.len()); self.pos += buf.len(); } </ins> } <ins> // FIXME(#10432) </ins> impl<'self> Seek for BufWriter<'self> { <del> fn tell(&self) -> u64 { fail!() } </del> <ins> fn tell(&self) -> u64 { self.pos as u64 } </ins> <del> fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() } </del> <ins> fn seek(&mut self, pos: i64, style: SeekStyle) { // compute offset as signed and clamp to prevent overflow let offset = match style { SeekSet => { 0 } SeekEnd => { self.buf.len() } SeekCur => { self.pos } } as i64; self.pos = max(0, offset+pos) as uint; } </ins> }


Question: Currently all of its functions immediately . We need to either remove this or implement it. I vote for implementing it.

} #[test] <ins> fn test_buf_writer() { let mut buf = [0 as u8, ..8]; { let mut writer = BufWriter::new(buf); assert_eq!(writer.tell(), 0); writer.write([0]); assert_eq!(writer.tell(), 1); writer.write([1, 2, 3]); writer.write([4, 5, 6, 7]); assert_eq!(writer.tell(), 8); } assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7]); } #[test] fn test_buf_writer_seek() { let mut buf = [0 as u8, ..8]; { let mut writer = BufWriter::new(buf); assert_eq!(writer.tell(), 0); writer.write([1]); assert_eq!(writer.tell(), 1); writer.seek(2, SeekSet); assert_eq!(writer.tell(), 2); writer.write([2]); assert_eq!(writer.tell(), 3); writer.seek(-2, SeekCur); assert_eq!(writer.tell(), 1); writer.write([3]); assert_eq!(writer.tell(), 2); writer.seek(-1, SeekEnd); assert_eq!(writer.tell(), 7); writer.write([4]); assert_eq!(writer.tell(), 8); } assert_eq!(buf, [1, 3, 2, 0, 0, 0, 0, 4]); } #[test] fn test_buf_writer_error() { let mut buf = [0 as u8, ..2]; let mut writer = BufWriter::new(buf); writer.write([0]); let mut called = false; do io_error::cond.trap(|err| { assert_eq!(err.kind, OtherIoError); called = true; }).inside { writer.write([0, 0]); } assert!(called); } #[test] </ins> fn test_mem_reader() { let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]); let mut buf = [];


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --: : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The real error isn't the unemitted diagnostic, it's the unwrap. The unemitted diagnostic only happens bc this unwrap occurs during diagnostics code, I think.
cc I think this might be and we try to suggest .clone() which is not available for the type though?
If you add ... to the example you no longer ICE and just hit the normalerror[E0382]: use of moved value: 'x' `
claim
Please use this minimized repro:

Every time I think "surely this will be fine", it bites me in the read as sure as the sun coming up.
Are we fixing ICEs? Not so sure we should bother...
This one was particularly easy to fix () and probably shouldn't've have been an in the first place (unwraps in diagnostics code are generally a code smell, since they should fail gracefully in strange situations) -- but I generally agree, had this fix required some large refactoring or implemented extra checks on a performance-sensitive path, then I think this should've been closed w/ a wontfix.

let tcx = self.infcx.tcx; // Try to find predicates on *generic params* that would allow copying `ty` let infcx = tcx.infer_ctxt().build(); <del> if infcx .type_implements_trait( tcx.lang_items().clone_trait().unwrap(), [tcx.erase_regions(ty)], self.param_env, ) .must_apply_modulo_regions() </del> <ins> if let Some(clone_trait_def) = tcx.lang_items().clone_trait() && infcx .type_implements_trait( clone_trait_def, [tcx.erase_regions(ty)], self.param_env, ) .must_apply_modulo_regions() </ins> { err.span_suggestion_verbose( span.shrink_to_hi(),


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --: : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The real error isn't the unemitted diagnostic, it's the unwrap. The unemitted diagnostic only happens bc this unwrap occurs during diagnostics code, I think.
cc I think this might be and we try to suggest .clone() which is not available for the type though?
If you add ... to the example you no longer ICE and just hit the normalerror[E0382]: use of moved value: 'x' `
claim
Please use this minimized repro:

Every time I think "surely this will be fine", it bites me in the read as sure as the sun coming up.
Are we fixing ICEs? Not so sure we should bother...
This one was particularly easy to fix () and probably shouldn't've have been an in the first place (unwraps in diagnostics code are generally a code smell, since they should fail gracefully in strange situations) -- but I generally agree, had this fix required some large refactoring or implemented extra checks on a performance-sensitive path, then I think this should've been closed w/ a wontfix.

<ins> // Avoid panicking if the Clone trait is not found while building error suggestions // See #104870 #![feature(no_core, lang_items)] #![no_core] #[lang = "sized"] trait Sized {} #[lang = "copy"] trait Copy {} fn g<T>(x: T) {} fn f(x: *mut u8) { g(x); g(x); //~ ERROR use of moved value: `x` } fn main() {} </ins>


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --: : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The real error isn't the unemitted diagnostic, it's the unwrap. The unemitted diagnostic only happens bc this unwrap occurs during diagnostics code, I think.
cc I think this might be and we try to suggest .clone() which is not available for the type though?
If you add ... to the example you no longer ICE and just hit the normalerror[E0382]: use of moved value: 'x' `
claim
Please use this minimized repro:

Every time I think "surely this will be fine", it bites me in the read as sure as the sun coming up.
Are we fixing ICEs? Not so sure we should bother...
This one was particularly easy to fix () and probably shouldn't've have been an in the first place (unwraps in diagnostics code are generally a code smell, since they should fail gracefully in strange situations) -- but I generally agree, had this fix required some large refactoring or implemented extra checks on a performance-sensitive path, then I think this should've been closed w/ a wontfix.

<ins> error[E0382]: use of moved value: `x` --> $DIR/missing-clone-for-suggestion.rs:17:7 | LL | fn f(x: *mut u8) { |      - move occurs because `x` has type `*mut u8`, which does not implement the `Copy` trait LL |     g(x); |       - value moved here LL |     g(x); |       ^ value used here after move | note: consider changing this parameter type in function `g` to borrow instead if owning the value isn't necessary --> $DIR/missing-clone-for-suggestion.rs:13:12 | LL | fn g<T>(x: T) {} |    -       ^ this parameter takes ownership of the value |    | |    in this function error: aborting due to previous error For more information about this error, try `rustc --explain E0382`. </ins>


Question:
Given the following code: current output is: The last part of the suggestion is not valid Rust code and therefore should not be suggested like this. This problem occurs on the Playground on both stable and nightly with basically identical error messages. serde v1.0.147 requires such that will be . Otherwise the problem does not seem serde specific. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
do you know how to create a minimal case without ? so we may add it to unit testing. I give a fix and verified it's OK with my local testing, but I'm struggle to construct a minimal case without to reproduce it.
I assume this reproduces when using the same setup of derive macro implementing a trait while the implementation is missing bounds. I don't know if it is relevant that the derive macro produces a trait. Something along these lines, with the proc macro crate omitted.
yes, it's caused by derive macro.
emmmet this error

)); } <ins> // FIXME: remove the suggestions that are from derive, as the span is not correct suggestions = suggestions .into_iter() .filter(|(span, _, _)| !span.in_derive_expansion()) .collect::<Vec<_>>(); </ins> if suggestions.len() == 1 { let (span, suggestion, msg) = suggestions.pop().unwrap();


Question:
Given the following code: current output is: The last part of the suggestion is not valid Rust code and therefore should not be suggested like this. This problem occurs on the Playground on both stable and nightly with basically identical error messages. serde v1.0.147 requires such that will be . Otherwise the problem does not seem serde specific. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
do you know how to create a minimal case without ? so we may add it to unit testing. I give a fix and verified it's OK with my local testing, but I'm struggle to construct a minimal case without to reproduce it.
I assume this reproduces when using the same setup of derive macro implementing a trait while the implementation is missing bounds. I don't know if it is relevant that the derive macro produces a trait. Something along these lines, with the proc macro crate omitted.
yes, it's caused by derive macro.
emmmet this error

<ins> // force-host // no-prefer-dynamic #![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::TokenStream; #[proc_macro_derive(AddImpl)] pub fn derive(input: TokenStream) -> TokenStream { "use std::cmp::Ordering; impl<T> Ord for PriorityQueue<T> { fn cmp(&self, other: &Self) -> Ordering { self.0.cmp(&self.height) } } " .parse() .unwrap() } </ins>


Question:
Given the following code: current output is: The last part of the suggestion is not valid Rust code and therefore should not be suggested like this. This problem occurs on the Playground on both stable and nightly with basically identical error messages. serde v1.0.147 requires such that will be . Otherwise the problem does not seem serde specific. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
do you know how to create a minimal case without ? so we may add it to unit testing. I give a fix and verified it's OK with my local testing, but I'm struggle to construct a minimal case without to reproduce it.
I assume this reproduces when using the same setup of derive macro implementing a trait while the implementation is missing bounds. I don't know if it is relevant that the derive macro produces a trait. Something along these lines, with the proc macro crate omitted.
yes, it's caused by derive macro.
emmmet this error

<ins> // aux-build:issue-104884.rs use std::collections::BinaryHeap; #[macro_use] extern crate issue_104884; #[derive(PartialEq, Eq, PartialOrd, Ord)] struct PriorityQueueEntry<T> { value: T, } #[derive(PartialOrd, AddImpl)] //~^ ERROR can't compare `PriorityQueue<T>` with `PriorityQueue<T>` //~| ERROR the trait bound `PriorityQueue<T>: Eq` is not satisfied //~| ERROR can't compare `T` with `T` struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>); fn main() {} </ins>


Question:
Given the following code: current output is: The last part of the suggestion is not valid Rust code and therefore should not be suggested like this. This problem occurs on the Playground on both stable and nightly with basically identical error messages. serde v1.0.147 requires such that will be . Otherwise the problem does not seem serde specific. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
do you know how to create a minimal case without ? so we may add it to unit testing. I give a fix and verified it's OK with my local testing, but I'm struggle to construct a minimal case without to reproduce it.
I assume this reproduces when using the same setup of derive macro implementing a trait while the implementation is missing bounds. I don't know if it is relevant that the derive macro produces a trait. Something along these lines, with the proc macro crate omitted.
yes, it's caused by derive macro.
emmmet this error

<ins> error[E0277]: can't compare `PriorityQueue<T>` with `PriorityQueue<T>` --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:10 | LL | #[derive(PartialOrd, AddImpl)] |          ^^^^^^^^^^ no implementation for `PriorityQueue<T> == PriorityQueue<T>` | = help: the trait `PartialEq` is not implemented for `PriorityQueue<T>` note: required by a bound in `PartialOrd` --> $SRC_DIR/core/src/cmp.rs:LL:COL | LL | pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { |                                           ^^^^^^^^^^^^^^ required by this bound in `PartialOrd` = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `PriorityQueue<T>: Eq` is not satisfied --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 | LL | #[derive(PartialOrd, AddImpl)] |                      ^^^^^^^ the trait `Eq` is not implemented for `PriorityQueue<T>` | note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL | LL | pub trait Ord: Eq + PartialOrd<Self> { |                ^^ required by this bound in `Ord` = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `T` with `T` --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 | LL | #[derive(PartialOrd, AddImpl)] |                      ^^^^^^^ no implementation for `T < T` and `T > T` | note: required for `PriorityQueue<T>` to implement `PartialOrd` --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:10 | LL | #[derive(PartialOrd, AddImpl)] |          ^^^^^^^^^^ note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL | LL | pub trait Ord: Eq + PartialOrd<Self> { |                     ^^^^^^^^^^^^^^^^ required by this bound in `Ord` = note: this error originates in the derive macro `AddImpl` which comes from the expansion of the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. </ins>


Question:
Any ideas?
Regressed with
cc
Is there more information available from the error? The module should not be part of the FreeBSD build. Also, an error in resolving doesn't make much sense to me because that module should exist regardless of whether the feature is enabled. Is it possible that there's either (1) another error further up in the build log, or (2) an existing incorrect dependency that's been exposed by the recent change?
The full log is available here:
It only happens if I build the documentation. Is it possible to fix this problem before rust 1.67 lands?
Reproduced with the following command: could you please see if the patch in fixes the build for you?
Your patch fixes the issue. Many thanks!

//! OS-specific networking functionality. <ins> // See cfg macros in `library/std/src/os/mod.rs` for why these platforms must // be special-cased during rustdoc generation. #[cfg(not(all( doc, any( all(target_arch = "wasm32", not(target_os = "wasi")), all(target_vendor = "fortanix", target_env = "sgx") ) )))] </ins> #[cfg(any(target_os = "linux", target_os = "android", doc))] pub(super) mod linux_ext;


Question:
I tried this code (): I expected to see this happen: Instead, this happened: This is just a very specific instance where the suggestion to add some code, while "technically correct", is less useful than the better suggestion to remove some code. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
label +A-diagnostics
it seems that given an expression, you can generically check if removing the last method call if present would give you the right type, so this could be implemented in a very generic way instead of special casing &str/String.
This looks awesome, thank you so much!
This is how it looks now . Very cool.

// Use `||` to give these suggestions a precedence let _ = self.suggest_missing_parentheses(err, expr) <ins> || self.suggest_remove_last_method_call(err, expr, expected) </ins> || self.suggest_associated_const(err, expr, expected) || self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr) || self.suggest_option_to_bool(err, expr, expr_ty, expected)


Question:
I tried this code (): I expected to see this happen: Instead, this happened: This is just a very specific instance where the suggestion to add some code, while "technically correct", is less useful than the better suggestion to remove some code. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
label +A-diagnostics
it seems that given an expression, you can generically check if removing the last method call if present would give you the right type, so this could be implemented in a very generic way instead of special casing &str/String.
This looks awesome, thank you so much!
This is how it looks now . Very cool.

} } <ins> pub fn suggest_remove_last_method_call( &self, err: &mut Diagnostic, expr: &hir::Expr<'tcx>, expected: Ty<'tcx>, ) -> bool { if let hir::ExprKind::MethodCall(hir::PathSegment { ident: method, .. }, recv_expr, &[], _) = expr.kind && let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr) && self.can_coerce(recv_ty, expected) { let span = if let Some(recv_span) = recv_expr.span.find_ancestor_inside(expr.span) { expr.span.with_lo(recv_span.hi()) } else { expr.span.with_lo(method.span.lo() - rustc_span::BytePos(1)) }; err.span_suggestion_verbose( span, "try removing the method call", "", Applicability::MachineApplicable, ); return true; } false } </ins> pub fn suggest_deref_ref_or_into( &self, err: &mut Diagnostic,


Question:
I tried this code (): I expected to see this happen: Instead, this happened: This is just a very specific instance where the suggestion to add some code, while "technically correct", is less useful than the better suggestion to remove some code. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
label +A-diagnostics
it seems that given an expression, you can generically check if removing the last method call if present would give you the right type, so this could be implemented in a very generic way instead of special casing &str/String.
This looks awesome, thank you so much!
This is how it looks now . Very cool.

<ins> fn test1() { let _v: i32 = (1 as i32).to_string(); //~ ERROR mismatched types // won't suggestion let _v: i32 = (1 as i128).to_string(); //~ ERROR mismatched types let _v: &str = "foo".to_string(); //~ ERROR mismatched types } fn test2() { let mut path: String = "/usr".to_string(); let folder: String = "lib".to_string(); path = format!("{}/{}", path, folder).as_str(); //~ ERROR mismatched types println!("{}", &path); } fn main() { test1(); test2(); } </ins>


Question:
I tried this code (): I expected to see this happen: Instead, this happened: This is just a very specific instance where the suggestion to add some code, while "technically correct", is less useful than the better suggestion to remove some code. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
label +A-diagnostics
it seems that given an expression, you can generically check if removing the last method call if present would give you the right type, so this could be implemented in a very generic way instead of special casing &str/String.
This looks awesome, thank you so much!
This is how it looks now . Very cool.

<ins> error[E0308]: mismatched types --> $DIR/issue-105494.rs:2:19 | LL |     let _v: i32 = (1 as i32).to_string(); |             ---   ^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `String` |             | |             expected due to this | help: try removing the method call | LL -     let _v: i32 = (1 as i32).to_string(); LL +     let _v: i32 = (1 as i32); | error[E0308]: mismatched types --> $DIR/issue-105494.rs:5:19 | LL |     let _v: i32 = (1 as i128).to_string(); |             ---   ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `String` |             | |             expected due to this error[E0308]: mismatched types --> $DIR/issue-105494.rs:7:20 | LL |     let _v: &str = "foo".to_string(); |             ----   ^^^^^^^^^^^^^^^^^ expected `&str`, found struct `String` |             | |             expected due to this | help: try removing the method call | LL -     let _v: &str = "foo".to_string(); LL +     let _v: &str = "foo"; | error[E0308]: mismatched types --> $DIR/issue-105494.rs:14:12 | LL |     let mut path: String = "/usr".to_string(); |                   ------ expected due to this type ... LL |     path = format!("{}/{}", path, folder).as_str(); |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&str` | help: try removing the method call | LL -     path = format!("{}/{}", path, folder).as_str(); LL +     path = format!("{}/{}", path, folder); | error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


Question:
In debug mode, this prints But with optimizations, this prints: With optimizations and , this prints: This check in the MIR inliner is hiding this problem from the track-caller UI tests: label +A-mir-opt +A-mir-opt-inlining :
Nevermind that, the panic here is correct actually :D
Ignoring changes in the standard library and optimization level at which MIR inliner is enabled, bisection points to cc
WG-prioritization assigning priority (). label -I-prioritize +P-medium

) -> OperandRef<'tcx, Bx::Value> { let tcx = bx.tcx(); <del> let mut span_to_caller_location = |span: Span| { </del> <ins> let mut span_to_caller_location = |mut span: Span| { // Remove `Inlined` marks as they pollute `expansion_cause`. while span.is_inlined() { span.remove_mark(); } </ins> let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = tcx.sess.source_map().lookup_char_pos(topmost.lo()); let const_loc = tcx.const_caller_location((


Question:
In debug mode, this prints But with optimizations, this prints: With optimizations and , this prints: This check in the MIR inliner is hiding this problem from the track-caller UI tests: label +A-mir-opt +A-mir-opt-inlining :
Nevermind that, the panic here is correct actually :D
Ignoring changes in the standard library and optimization level at which MIR inliner is enabled, bisection points to cc
WG-prioritization assigning priority (). label -I-prioritize +P-medium

location } <del> pub(crate) fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) { </del> <ins> pub(crate) fn location_triple_for_span(&self, mut span: Span) -> (Symbol, u32, u32) { // Remove `Inlined` marks as they pollute `expansion_cause`. while span.is_inlined() { span.remove_mark(); } </ins> let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); (


Question:
In debug mode, this prints But with optimizations, this prints: With optimizations and , this prints: This check in the MIR inliner is hiding this problem from the track-caller UI tests: label +A-mir-opt +A-mir-opt-inlining :
Nevermind that, the panic here is correct actually :D
Ignoring changes in the standard library and optimization level at which MIR inliner is enabled, bisection points to cc
WG-prioritization assigning priority (). label -I-prioritize +P-medium

pub fn fresh_expansion(self, expn_id: LocalExpnId) -> Span { HygieneData::with(|data| { self.with_ctxt(data.apply_mark( <del> SyntaxContext::root(), </del> <ins> self.ctxt(), </ins> expn_id.to_expn_id(), Transparency::Transparent, ))


Question:
In debug mode, this prints But with optimizations, this prints: With optimizations and , this prints: This check in the MIR inliner is hiding this problem from the track-caller UI tests: label +A-mir-opt +A-mir-opt-inlining :
Nevermind that, the panic here is correct actually :D
Ignoring changes in the standard library and optimization level at which MIR inliner is enabled, bisection points to cc
WG-prioritization assigning priority (). label -I-prioritize +P-medium

// run-pass // revisions: default mir-opt <ins> //[default] compile-flags: -Zinline-mir=no </ins> //[mir-opt] compile-flags: -Zmir-opt-level=4 macro_rules! caller_location_from_macro {


Question:
In debug mode, this prints But with optimizations, this prints: With optimizations and , this prints: This check in the MIR inliner is hiding this problem from the track-caller UI tests: label +A-mir-opt +A-mir-opt-inlining :
Nevermind that, the panic here is correct actually :D
Ignoring changes in the standard library and optimization level at which MIR inliner is enabled, bisection points to cc
WG-prioritization assigning priority (). label -I-prioritize +P-medium

fn main() { let loc = core::panic::Location::caller(); assert_eq!(loc.file(), file!()); <del> assert_eq!(loc.line(), 10); </del> <ins> assert_eq!(loc.line(), 11); </ins> assert_eq!(loc.column(), 15); // `Location::caller()` in a macro should behave similarly to `file!` and `line!`, // i.e. point to where the macro was invoked, instead of the macro itself. let loc2 = caller_location_from_macro!(); assert_eq!(loc2.file(), file!()); <del> assert_eq!(loc2.line(), 17); </del> <ins> assert_eq!(loc2.line(), 18); </ins> assert_eq!(loc2.column(), 16); }


Question:
In debug mode, this prints But with optimizations, this prints: With optimizations and , this prints: This check in the MIR inliner is hiding this problem from the track-caller UI tests: label +A-mir-opt +A-mir-opt-inlining :
Nevermind that, the panic here is correct actually :D
Ignoring changes in the standard library and optimization level at which MIR inliner is enabled, bisection points to cc
WG-prioritization assigning priority (). label -I-prioritize +P-medium

<ins> // run-pass // revisions: default mir-opt //[default] compile-flags: -Zinline-mir=no //[mir-opt] compile-flags: -Zmir-opt-level=4 use std::panic::Location; macro_rules! f { () => { Location::caller() }; } #[inline(always)] fn g() -> &'static Location<'static> { f!() } fn main() { let loc = g(); assert_eq!(loc.line(), 16); assert_eq!(loc.column(), 5); } </ins>


Question:
Given the following The current output is: The second error is not reasonable, since we don't allow associated items in auto trait. Ideally the output should look like: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I spent some time to investigate it, I tried to filter the candidates from auto trait. But seems here have two predicates, and the message for the second error comes from the first : I'm still trying to understand the code.
claim

}); } else { debug_assert!(self.tcx.is_trait(trait_def_id)); <ins> if self.tcx.trait_is_auto(trait_def_id) { return; } </ins> for item in self.impl_or_trait_item(trait_def_id) { // Check whether `trait_def_id` defines a method with suitable name. if !self.has_applicable_self(&item) {


Question:
Given the following The current output is: The second error is not reasonable, since we don't allow associated items in auto trait. Ideally the output should look like: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I spent some time to investigate it, I tried to filter the candidates from auto trait. But seems here have two predicates, and the message for the second error comes from the first : I'm still trying to understand the code.
claim

_ => false, } }) && (type_is_local || info.def_id.is_local()) <ins> && !self.tcx.trait_is_auto(info.def_id) </ins> && self .associated_value(info.def_id, item_name) .filter(|item| {


Question:
Given the following The current output is: The second error is not reasonable, since we don't allow associated items in auto trait. Ideally the output should look like: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I spent some time to investigate it, I tried to filter the candidates from auto trait. But seems here have two predicates, and the message for the second error comes from the first : I'm still trying to understand the code.
claim

trait Bar { fn f(&self) { <del> self.g(); //~ ERROR the method `g` exists for reference `&Self`, but its trait bounds were not satisfied </del> <ins> // issue #105788 self.g(); //~ ERROR no method named `g` found for reference `&Self` in the current scope </ins> } }


Question:
Given the following The current output is: The second error is not reasonable, since we don't allow associated items in auto trait. Ideally the output should look like: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I spent some time to investigate it, I tried to filter the candidates from auto trait. But seems here have two predicates, and the message for the second error comes from the first : I'm still trying to understand the code.
claim

LL |     fn g(&self); |     ---^-------- help: remove these associated items <del> error[E0599]: the method `g` exists for reference `&Self`, but its trait bounds were not satisfied --> $DIR/issue-105732.rs:9:14 </del> <ins> error[E0599]: no method named `g` found for reference `&Self` in the current scope --> $DIR/issue-105732.rs:10:14 </ins> | LL |         self.g(); <del> |              ^ | = note: the following trait bounds were not satisfied: `Self: Foo` which is required by `&Self: Foo` `&Self: Foo` = help: items from traits can only be used if the type parameter is bounded by the trait help: the following trait defines an item `g`, perhaps you need to add a supertrait for it: | LL | trait Bar: Foo { |          +++++ </del> <ins> |              ^ help: there is a method with a similar name: `f` </ins> error: aborting due to 2 previous errors


Question:
Spawned off of I tried this code: I expected to see this happen: I expected the to be mapped to the local paths in the installed component, rather than being left as raw Instead, this happened: is showing up in the output. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
see related discussion from wg-debugging triage
in particular, pointed out that that this remapping should be happening if one has the component installed, and that the code doing the remapping should be executed here: and there is corresponding code in bootstrap dist code: There's some useful statements mixed in there, I bet we might be able to figure out what's going on here without too much trickery...
But this is currently a remapping at runtime only when using like in UI tests, right ? Otherwise it's optionally done at compile-time on the dist builders if they set .
is , right? That is what it is mapped from, not what it is mapped to.
Its and 's presence seem to control (at rustc build-time and at runtime respectively) whether the remapping happens in the code you listed above (otherwise would be "empty" and would be a no-op), so I may be missing how this could already remap to the local component according to Felix's comment above ?
I believe these are not being remapped on purpose (based on ). I think currently the remapping only happens for diagnostics (and not things that end up in the binary). There's some more discussion in (and and to some degree). There's also concerns about how it can affect binary size (). also discusses it some.
These paths are also not being remapped even when explicitly requested with

); for virtual_dir in virtual_rust_source_base_dir.iter().flatten() { <del> if let Some(real_dir) = &sess.opts.real_rust_source_base_dir { if let rustc_span::FileName::Real(old_name) = name { if let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } = old_name { if let Ok(rest) = virtual_name.strip_prefix(virtual_dir) { let virtual_name = virtual_name.clone(); // The std library crates are in // `$sysroot/lib/rustlib/src/rust/library`, whereas other crates // may be in `$sysroot/lib/rustlib/src/rust/` directly. So we // detect crates from the std libs and handle them specially. const STD_LIBS: &[&str] = &[ "core", "alloc", "std", "test", "term", "unwind", "proc_macro", "panic_abort", "panic_unwind", "profiler_builtins", "rtstartup", "rustc-std-workspace-core", "rustc-std-workspace-alloc", "rustc-std-workspace-std", "backtrace", ]; let is_std_lib = STD_LIBS.iter().any(|l| rest.starts_with(l)); let new_path = if is_std_lib { real_dir.join("library").join(rest) } else { real_dir.join(rest) }; debug!( "try_to_translate_virtual_to_real: `{}` -> `{}`", virtual_name.display(), new_path.display(), ); let new_name = rustc_span::RealFileName::Remapped { local_path: Some(new_path), virtual_name, }; *old_name = new_name; } </del> <ins> if let Some(real_dir) = &sess.opts.real_rust_source_base_dir && let rustc_span::FileName::Real(old_name) = name && let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } = old_name && let Ok(rest) = virtual_name.strip_prefix(virtual_dir) { // The std library crates are in // `$sysroot/lib/rustlib/src/rust/library`, whereas other crates // may be in `$sysroot/lib/rustlib/src/rust/` directly. So we // detect crates from the std libs and handle them specially. const STD_LIBS: &[&str] = &[ "core", "alloc", "std", "test", "term", "unwind", "proc_macro", "panic_abort", "panic_unwind", "profiler_builtins", "rtstartup", "rustc-std-workspace-core", "rustc-std-workspace-alloc", "rustc-std-workspace-std", "backtrace", ]; let is_std_lib = STD_LIBS.iter().any(|l| rest.starts_with(l)); let new_path = if is_std_lib { real_dir.join("library").join(rest) } else { real_dir.join(rest) }; debug!( "try_to_translate_virtual_to_real: `{}` -> `{}`", virtual_name.display(), new_path.display(), ); // Check if the translated real path is affected by any user-requested // remaps via --remap-path-prefix. Apply them if so. // Note that this is a special case for imported rust-src paths specified by // https://rust-lang.github.io/rfcs/3127-trim-paths.html#handling-sysroot-paths. // Other imported paths are not currently remapped (see #66251). let (user_remapped, applied) = sess.source_map().path_mapping().map_prefix(&new_path); let new_name = if applied { rustc_span::RealFileName::Remapped { local_path: Some(new_path.clone()), virtual_name: user_remapped.to_path_buf(), </ins> } <del> } </del> <ins> } else { rustc_span::RealFileName::LocalPath(new_path) }; *old_name = new_name; </ins> } } };


Question:
Spawned off of I tried this code: I expected to see this happen: I expected the to be mapped to the local paths in the installed component, rather than being left as raw Instead, this happened: is showing up in the output. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
see related discussion from wg-debugging triage
in particular, pointed out that that this remapping should be happening if one has the component installed, and that the code doing the remapping should be executed here: and there is corresponding code in bootstrap dist code: There's some useful statements mixed in there, I bet we might be able to figure out what's going on here without too much trickery...
But this is currently a remapping at runtime only when using like in UI tests, right ? Otherwise it's optionally done at compile-time on the dist builders if they set .
is , right? That is what it is mapped from, not what it is mapped to.
Its and 's presence seem to control (at rustc build-time and at runtime respectively) whether the remapping happens in the code you listed above (otherwise would be "empty" and would be a no-op), so I may be missing how this could already remap to the local component according to Felix's comment above ?
I believe these are not being remapped on purpose (based on ). I think currently the remapping only happens for diagnostics (and not things that end up in the binary). There's some more discussion in (and and to some degree). There's also concerns about how it can affect binary size (). also discusses it some.
These paths are also not being remapped even when explicitly requested with

const CWD: &str = "{{cwd}}"; const SRC_BASE: &str = "{{src-base}}"; const BUILD_BASE: &str = "{{build-base}}"; <ins> const RUST_SRC_BASE: &str = "{{rust-src-base}}"; </ins> const SYSROOT_BASE: &str = "{{sysroot-base}}"; const TARGET_LINKER: &str = "{{target-linker}}"; const TARGET: &str = "{{target}}";


Question:
Spawned off of I tried this code: I expected to see this happen: I expected the to be mapped to the local paths in the installed component, rather than being left as raw Instead, this happened: is showing up in the output. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
see related discussion from wg-debugging triage
in particular, pointed out that that this remapping should be happening if one has the component installed, and that the code doing the remapping should be executed here: and there is corresponding code in bootstrap dist code: There's some useful statements mixed in there, I bet we might be able to figure out what's going on here without too much trickery...
But this is currently a remapping at runtime only when using like in UI tests, right ? Otherwise it's optionally done at compile-time on the dist builders if they set .
is , right? That is what it is mapped from, not what it is mapped to.
Its and 's presence seem to control (at rustc build-time and at runtime respectively) whether the remapping happens in the code you listed above (otherwise would be "empty" and would be a no-op), so I may be missing how this could already remap to the local component according to Felix's comment above ?
I believe these are not being remapped on purpose (based on ). I think currently the remapping only happens for diagnostics (and not things that end up in the binary). There's some more discussion in (and and to some degree). There's also concerns about how it can affect binary size (). also discusses it some.
These paths are also not being remapped even when explicitly requested with

value = value.replace(TARGET, &config.target); } <ins> if value.contains(RUST_SRC_BASE) { let src_base = config.sysroot_base.join("lib/rustlib/src/rust"); src_base.try_exists().expect(&*format!("{} should exists", src_base.display())); let src_base = src_base.read_link().unwrap_or(src_base); value = value.replace(RUST_SRC_BASE, &src_base.to_string_lossy()); } </ins> value }


Question:
Spawned off of I tried this code: I expected to see this happen: I expected the to be mapped to the local paths in the installed component, rather than being left as raw Instead, this happened: is showing up in the output. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
see related discussion from wg-debugging triage
in particular, pointed out that that this remapping should be happening if one has the component installed, and that the code doing the remapping should be executed here: and there is corresponding code in bootstrap dist code: There's some useful statements mixed in there, I bet we might be able to figure out what's going on here without too much trickery...
But this is currently a remapping at runtime only when using like in UI tests, right ? Otherwise it's optionally done at compile-time on the dist builders if they set .
is , right? That is what it is mapped from, not what it is mapped to.
Its and 's presence seem to control (at rustc build-time and at runtime respectively) whether the remapping happens in the code you listed above (otherwise would be "empty" and would be a no-op), so I may be missing how this could already remap to the local component according to Felix's comment above ?
I believe these are not being remapped on purpose (based on ). I think currently the remapping only happens for diagnostics (and not things that end up in the binary). There's some more discussion in (and and to some degree). There's also concerns about how it can affect binary size (). also discusses it some.
These paths are also not being remapped even when explicitly requested with

} let base_dir = Path::new("/rustc/FAKE_PREFIX"); <del> // Paths into the libstd/libcore </del> <ins> // Fake paths into the libstd/libcore </ins> normalize_path(&base_dir.join("library"), "$SRC_DIR"); // `ui-fulldeps` tests can show paths to the compiler source when testing macros from // `rustc_macros` // eg. /home/user/rust/compiler normalize_path(&base_dir.join("compiler"), "$COMPILER_DIR"); <ins> // Real paths into the libstd/libcore let rust_src_dir = &self.config.sysroot_base.join("lib/rustlib/src/rust"); rust_src_dir.try_exists().expect(&*format!("{} should exists", rust_src_dir.display())); let rust_src_dir = rust_src_dir.read_link().unwrap_or(rust_src_dir.to_path_buf()); normalize_path(&rust_src_dir.join("library"), "$SRC_DIR_REAL"); </ins> // Paths into the build directory let test_build_dir = &self.config.build_base; let parent_build_dir = test_build_dir.parent().unwrap().parent().unwrap().parent().unwrap();


Question:
Spawned off of I tried this code: I expected to see this happen: I expected the to be mapped to the local paths in the installed component, rather than being left as raw Instead, this happened: is showing up in the output. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
see related discussion from wg-debugging triage
in particular, pointed out that that this remapping should be happening if one has the component installed, and that the code doing the remapping should be executed here: and there is corresponding code in bootstrap dist code: There's some useful statements mixed in there, I bet we might be able to figure out what's going on here without too much trickery...
But this is currently a remapping at runtime only when using like in UI tests, right ? Otherwise it's optionally done at compile-time on the dist builders if they set .
is , right? That is what it is mapped from, not what it is mapped to.
Its and 's presence seem to control (at rustc build-time and at runtime respectively) whether the remapping happens in the code you listed above (otherwise would be "empty" and would be a no-op), so I may be missing how this could already remap to the local component according to Felix's comment above ?
I believe these are not being remapped on purpose (based on ). I think currently the remapping only happens for diagnostics (and not things that end up in the binary). There's some more discussion in (and and to some degree). There's also concerns about how it can affect binary size (). also discusses it some.
These paths are also not being remapped even when explicitly requested with

// eg. /home/user/rust/build normalize_path(parent_build_dir, "$BUILD_DIR"); <del> // Paths into lib directory. normalize_path(&parent_build_dir.parent().unwrap().join("lib"), "$LIB_DIR"); </del> if json { // escaped newlines in json strings should be readable // in the stderr files. There's no point int being correct,


Question:
Spawned off of I tried this code: I expected to see this happen: I expected the to be mapped to the local paths in the installed component, rather than being left as raw Instead, this happened: is showing up in the output. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
see related discussion from wg-debugging triage
in particular, pointed out that that this remapping should be happening if one has the component installed, and that the code doing the remapping should be executed here: and there is corresponding code in bootstrap dist code: There's some useful statements mixed in there, I bet we might be able to figure out what's going on here without too much trickery...
But this is currently a remapping at runtime only when using like in UI tests, right ? Otherwise it's optionally done at compile-time on the dist builders if they set .
is , right? That is what it is mapped from, not what it is mapped to.
Its and 's presence seem to control (at rustc build-time and at runtime respectively) whether the remapping happens in the code you listed above (otherwise would be "empty" and would be a no-op), so I may be missing how this could already remap to the local component according to Felix's comment above ?
I believe these are not being remapped on purpose (based on ). I think currently the remapping only happens for diagnostics (and not things that end up in the binary). There's some more discussion in (and and to some degree). There's also concerns about how it can affect binary size (). also discusses it some.
These paths are also not being remapped even when explicitly requested with

<ins> //@ revisions: with-remap without-remap //@ compile-flags: -g -Ztranslate-remapped-path-to-local-path=yes //@ [with-remap]compile-flags: --remap-path-prefix={{rust-src-base}}=remapped //@ [with-remap]compile-flags: --remap-path-prefix={{src-base}}=remapped-tests-ui //@ [without-remap]compile-flags: //@ error-pattern: E0507 // The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically // as the remapped revision will not begin with $SRC_DIR_REAL, // so we have to do it ourselves. //@ normalize-stderr-test: ".rs:d+:d+" -> ".rs:LL:COL" use std::thread; struct Worker { thread: thread::JoinHandle<()>, } impl Drop for Worker { fn drop(&mut self) { self.thread.join().unwrap(); } } pub fn main(){} </ins>


Question:
Spawned off of I tried this code: I expected to see this happen: I expected the to be mapped to the local paths in the installed component, rather than being left as raw Instead, this happened: is showing up in the output. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
see related discussion from wg-debugging triage
in particular, pointed out that that this remapping should be happening if one has the component installed, and that the code doing the remapping should be executed here: and there is corresponding code in bootstrap dist code: There's some useful statements mixed in there, I bet we might be able to figure out what's going on here without too much trickery...
But this is currently a remapping at runtime only when using like in UI tests, right ? Otherwise it's optionally done at compile-time on the dist builders if they set .
is , right? That is what it is mapped from, not what it is mapped to.
Its and 's presence seem to control (at rustc build-time and at runtime respectively) whether the remapping happens in the code you listed above (otherwise would be "empty" and would be a no-op), so I may be missing how this could already remap to the local component according to Felix's comment above ?
I believe these are not being remapped on purpose (based on ). I think currently the remapping only happens for diagnostics (and not things that end up in the binary). There's some more discussion in (and and to some degree). There's also concerns about how it can affect binary size (). also discusses it some.
These paths are also not being remapped even when explicitly requested with

<ins> error[E0507]: cannot move out of `self.thread` which is behind a mutable reference --> remapped-tests-ui/errors/remap-path-prefix-sysroot.rs:LL:COL | LL |         self.thread.join().unwrap(); |         ^^^^^^^^^^^ ------ `self.thread` moved due to this method call |         | |         move occurs because `self.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait | note: `JoinHandle::<T>::join` takes ownership of the receiver `self`, which moves `self.thread` --> remapped/library/std/src/thread/mod.rs:LL:COL | LL |     pub fn join(self) -> Result<T> { |                 ^^^^ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0507`. </ins>


Question:
Spawned off of I tried this code: I expected to see this happen: I expected the to be mapped to the local paths in the installed component, rather than being left as raw Instead, this happened: is showing up in the output. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
see related discussion from wg-debugging triage
in particular, pointed out that that this remapping should be happening if one has the component installed, and that the code doing the remapping should be executed here: and there is corresponding code in bootstrap dist code: There's some useful statements mixed in there, I bet we might be able to figure out what's going on here without too much trickery...
But this is currently a remapping at runtime only when using like in UI tests, right ? Otherwise it's optionally done at compile-time on the dist builders if they set .
is , right? That is what it is mapped from, not what it is mapped to.
Its and 's presence seem to control (at rustc build-time and at runtime respectively) whether the remapping happens in the code you listed above (otherwise would be "empty" and would be a no-op), so I may be missing how this could already remap to the local component according to Felix's comment above ?
I believe these are not being remapped on purpose (based on ). I think currently the remapping only happens for diagnostics (and not things that end up in the binary). There's some more discussion in (and and to some degree). There's also concerns about how it can affect binary size (). also discusses it some.
These paths are also not being remapped even when explicitly requested with

<ins> error[E0507]: cannot move out of `self.thread` which is behind a mutable reference --> $DIR/remap-path-prefix-sysroot.rs:LL:COL | LL |         self.thread.join().unwrap(); |         ^^^^^^^^^^^ ------ `self.thread` moved due to this method call |         | |         move occurs because `self.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait | note: `JoinHandle::<T>::join` takes ownership of the receiver `self`, which moves `self.thread` --> $SRC_DIR_REAL/std/src/thread/mod.rs:LL:COL | LL |     pub fn join(self) -> Result<T> { |                 ^^^^ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0507`. </ins>


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

|| self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty) || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected) || self.suggest_copied_or_cloned(err, expr, expr_ty, expected) <ins> || self.suggest_clone_for_ref(err, expr, expr_ty, expected) </ins> || self.suggest_into(err, expr, expr_ty, expected) || self.suggest_floating_point_literal(err, expr, expected); if !suggested {


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

} } <ins> pub(crate) fn suggest_clone_for_ref( &self, diag: &mut Diagnostic, expr: &hir::Expr<'_>, expr_ty: Ty<'tcx>, expected_ty: Ty<'tcx>, ) -> bool { if let ty::Ref(_, inner_ty, hir::Mutability::Not) = expr_ty.kind() && let Some(clone_trait_def) = self.tcx.lang_items().clone_trait() && expected_ty == *inner_ty && self .infcx .type_implements_trait( clone_trait_def, [self.tcx.erase_regions(expected_ty)], self.param_env ) .must_apply_modulo_regions() { diag.span_suggestion_verbose( expr.span.shrink_to_hi(), "consider using clone here", ".clone()", Applicability::MachineApplicable, ); return true; } false } </ins> pub(crate) fn suggest_copied_or_cloned( &self, diag: &mut Diagnostic,


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

); } <ins> if self.suggest_add_clone_to_arg(&obligation, &mut err, trait_predicate) { err.emit(); return; } </ins> if self.suggest_impl_trait(&mut err, span, &obligation, trait_predicate) { err.emit(); return;


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

use crate::traits::{NormalizeExt, ObligationCtxt}; use hir::def::CtorOf; <del> use hir::HirId; </del> <ins> use hir::{Expr, HirId}; </ins> use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

trait_pred: ty::PolyTraitPredicate<'tcx>, ); <ins> fn suggest_add_clone_to_arg( &self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool; </ins> fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>,


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

} } <ins> fn suggest_add_clone_to_arg( &self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); let ty = self.tcx.erase_late_bound_regions(self_ty); let owner = self.tcx.hir().get_parent_item(obligation.cause.body_id); let Some(generics) = self.tcx.hir().get_generics(owner.def_id) else { return false }; let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false }; let ty::Param(param) = inner_ty.kind() else { return false }; let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { return false }; let arg_node = self.tcx.hir().get(*arg_hir_id); let Node::Expr(Expr { kind: hir::ExprKind::Path(_), ..}) = arg_node else { return false }; let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None); let has_clone = |ty| { self.type_implements_trait(clone_trait, [ty], obligation.param_env) .must_apply_modulo_regions() }; let new_obligation = self.mk_trait_obligation_with_new_self_ty( obligation.param_env, trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)), ); if self.predicate_may_hold(&new_obligation) && has_clone(ty) { if !has_clone(param.to_ty(self.tcx)) { suggest_constraining_type_param( self.tcx, generics, err, param.name.as_str(), "Clone", Some(clone_trait), ); } err.span_suggestion_verbose( obligation.cause.span.shrink_to_hi(), "consider using clone here", ".clone()".to_string(), Applicability::MaybeIncorrect, ); return true; } false } </ins> fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>,


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

<ins> #[derive(Clone)] struct S; // without Clone struct T; fn foo(_: S) {} fn test1() { let s = &S; foo(s); //~ ERROR mismatched types } fn bar(_: T) {} fn test2() { let t = &T; bar(t); //~ ERROR mismatched types } fn main() { test1(); test2(); } </ins>


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

<ins> error[E0308]: mismatched types --> $DIR/issue-106443-sugg-clone-for-arg.rs:11:9 | LL |     foo(s); |     --- ^ expected struct `S`, found `&S` |     | |     arguments to this function are incorrect | note: function defined here --> $DIR/issue-106443-sugg-clone-for-arg.rs:7:4 | LL | fn foo(_: S) {} |    ^^^ ---- help: consider using clone here | LL |     foo(s.clone()); |          ++++++++ error[E0308]: mismatched types --> $DIR/issue-106443-sugg-clone-for-arg.rs:17:9 | LL |     bar(t); |     --- ^ expected struct `T`, found `&T` |     | |     arguments to this function are incorrect | note: function defined here --> $DIR/issue-106443-sugg-clone-for-arg.rs:14:4 | LL | fn bar(_: T) {} |    ^^^ ---- error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

<ins> #[derive(Clone)] struct S; trait X {} impl X for S {} fn foo<T: X>(_: T) {} fn bar<T: X>(s: &T) { foo(s); //~ ERROR the trait bound `&T: X` is not satisfied } fn bar_with_clone<T: X + Clone>(s: &T) { foo(s); //~ ERROR the trait bound `&T: X` is not satisfied } fn main() { let s = &S; bar(s); } </ins>


Question:
we should suggest cloning. Also, we should suggest <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
If we suggest add bound, we don't need dervie , This code will compile:

<ins> error[E0277]: the trait bound `&T: X` is not satisfied --> $DIR/issue-106443-sugg-clone-for-bound.rs:10:9 | LL |     foo(s); |         ^ the trait `X` is not implemented for `&T` | help: consider further restricting this bound | LL | fn bar<T: X + Clone>(s: &T) { |             +++++++ help: consider using clone here | LL |     foo(s.clone()); |          ++++++++ error[E0277]: the trait bound `&T: X` is not satisfied --> $DIR/issue-106443-sugg-clone-for-bound.rs:14:9 | LL |     foo(s); |         ^ the trait `X` is not implemented for `&T` | help: consider using clone here | LL |     foo(s.clone()); |          ++++++++ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. </ins>


Question:
There is a latent bug in rustdoc that hangs in when is enabled.
From the thread on :
Interestingly, also gets stuck. I believe that runs the beta (non-parallel) rustdoc. So that'd mean that rustdoc gets stuck when documenting parallel rustc, not that parallel rustdoc gets stuck when documenting rustc.
Both of the PRs that are blocked by this issue are changes that change the ast.
It seems it's not an infinite loop, but just bad (exponential?) time complexity somewhere. suggested trying out what happens when explicitly implementing Send and Sync for the new ast node, and that indeed 'fixes' the problem in So this issue has almost nothing to do with parallel compiler. It occurs in regular non-parallel rustdoc. It's just that with , the ast is Send and Sync, and apparently that takes a huge amount of time to prove when documenting rustcmiddle. (Oli is investigating.)
Data point: Adding the following snippet to will not stop it from compiling successfully, even though documenting the crate will never stop. This makes me think the issue is very much rustdoc related, as it appears to get stuck on proving .
WG-prioritization assigning priority () (note: seems not a regression) label -I-prioritize +P-high
cc
and , https://rust-
[Edit] I'm trying to solve this problem and what I'm currently observing is that the does not store all the information when using rustdoc. This causes rustdoc to recalculate many times when collecting auto trait impl and blanket trait impl. I guess it may be that rustdoc does not calculate the trait implementation on some data structures (such as ) in advance, which resulting in too deep recursion
A revealing phenomenon: The following struct in will cause rustdoc to block while proving that is : But when the generics are instantiated, it will not cause blocking: So I guess it is that causes the values in to not be reused. Because this cache needs inserting (predictions, ).
does this happen even with disabled?
If so, this is probably related to . This is how we determine the paramenv:
I can't reproduce this issue , including my local test Have there been any recent changes?

names: FxHashMap<Symbol, usize>, } <del> // FIXME: Rustdoc has trouble proving Send/Sync for this. See #106930. #[cfg(parallel_compiler)] unsafe impl Sync for FormatArguments {} #[cfg(parallel_compiler)] unsafe impl Send for FormatArguments {} </del> impl FormatArguments { pub fn new() -> Self { Self {


Question:
There is a latent bug in rustdoc that hangs in when is enabled.
From the thread on :
Interestingly, also gets stuck. I believe that runs the beta (non-parallel) rustdoc. So that'd mean that rustdoc gets stuck when documenting parallel rustc, not that parallel rustdoc gets stuck when documenting rustc.
Both of the PRs that are blocked by this issue are changes that change the ast.
It seems it's not an infinite loop, but just bad (exponential?) time complexity somewhere. suggested trying out what happens when explicitly implementing Send and Sync for the new ast node, and that indeed 'fixes' the problem in So this issue has almost nothing to do with parallel compiler. It occurs in regular non-parallel rustdoc. It's just that with , the ast is Send and Sync, and apparently that takes a huge amount of time to prove when documenting rustcmiddle. (Oli is investigating.)
Data point: Adding the following snippet to will not stop it from compiling successfully, even though documenting the crate will never stop. This makes me think the issue is very much rustdoc related, as it appears to get stuck on proving .
WG-prioritization assigning priority () (note: seems not a regression) label -I-prioritize +P-high
cc
and , https://rust-
[Edit] I'm trying to solve this problem and what I'm currently observing is that the does not store all the information when using rustdoc. This causes rustdoc to recalculate many times when collecting auto trait impl and blanket trait impl. I guess it may be that rustdoc does not calculate the trait implementation on some data structures (such as ) in advance, which resulting in too deep recursion
A revealing phenomenon: The following struct in will cause rustdoc to block while proving that is : But when the generics are instantiated, it will not cause blocking: So I guess it is that causes the values in to not be reused. Because this cache needs inserting (predictions, ).
does this happen even with disabled?
If so, this is probably related to . This is how we determine the paramenv:
I can't reproduce this issue , including my local test Have there been any recent changes?

cx: &mut DocContext<'_>, item_def_id: DefId, ) -> impl Iterator<Item = Item> { <del> // FIXME: To be removed once `parallel_compiler` bugs are fixed! // More information in <https://github.com/rust-lang/rust/pull/106930>. if cfg!(parallel_compiler) { return vec![].into_iter().chain(vec![].into_iter()); } </del> let auto_impls = cx .sess() .prof


Question:
This is one of those ICEs that are terribly hard to minimize because they happen cache-dependently, [update: see below for repro instructions]. If nothing else, notice that there is a panic while trying to print the query stack; it might be desirable to look into making that not happen so as to be able to get more information. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --Occurred while running or . : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details label +A-incr-comp
On looking more closely at the backtrace, it seems that this error results from attempting to load corrupted (truncated) query cache files, and therefore it would be valuable to obtain a trace from the file having been written (assuming that they are truncated due to a panic during write; if they're silently corrupted that's even harder to notice). I will update this issue if I manage to catch such a case.
Looking at the first panic observed since a and it is still the above in , so it's not that I missed the writing event but that it didn't panic.
I have made some progress on reproducing the problem with a minimal incremental change (but not yet a minimal standalone code sample), and expressed some interest in looking at the problem, so I've published branches with the work I have so far. Repro steps: The second build will ICE. The differences between the two branches are shuffling code between modules, adding a module, and deleting a module; the code in them is as identical as it can be.
Note: I cannot reproduce this ICE on x86_64-unknown-linux-gnu with the latest nightly by default, but makes it ICE. <details<summarybacktrace</summary</details
I've created a new branch which slighly simplifies the diff application: ( at the time of writing).
I've tried to find out a bit more about this, but didn't get very far. From what I can tell: In the second session refers to the derived impl for . And refers to the const generic of that impl. It has the span of the CHUNKSIZE const generic of the type definition. In the first session, as far as I can tell, the def-path refers to the , which also has a generic const. The query should not evaluate to green, but for some reason all of its dependencies are marked as green.
Maybe is too broken (it needed some fixing to show more than just DepKinds), but is it possible that has no dependencies at all during the first session?
It does indeed have no dependencies. I imagine that this is the culprit: I'm not really up-to-date with query feeding but this looks fishy. When a dep-node has no dependencies, it will trivially evaluate to green. Don't we need at least a dependency on the query that does the feeding? cc &
Given what we've learned about this bug, it's likely that this is purely about incremental compilation cache keying, i.e. neither state of the code is more likely to be miscompiled than the other, right? In other words, I as the author of the original code probably don't need to worry that I'm making my compiled code less reliable if I make the change that caused the ICE, as long as I after that point?
Yes, as far as I can tell, this is a bug in incremental compilation's dependency tracking and does not affect non-incremental builds.
Hey, I'm back with a repro! Thanks go out to , without which I would have never been able to minimize this. A one-command minimization is available at with . Basically: must be enabled. Running . Then applying Then running again panics. <details</detailsFor some strange reason I am unable to reproduce the changes when applying the diff in vscode via WSL. and work though.
I will unassign myself as I mostly assigned myself for the MCVE.
It looks like some things, like lowering to HIR, are run within a context, which leads to this call being ignored too -- and thus never making it into the we are trying to duplicate during . As a consequence, the feed queries in question go from explicitly "re-compute unconditionally" to effectively "re-use unconditionally" The reason seems to be that we . That's fine for those queries themselves because we make sure to re-compute those explicitly. But we fail to "inherit" the eval-always-ness to nested feed-queries. I'll look into fixing this some time this week.

use rustc_middle::ty::TyCtxt; pub fn check_crate(tcx: TyCtxt<'_>) { <del> tcx.dep_graph.assert_ignored(); </del> if tcx.sess.opts.unstable_opts.hir_stats { crate::hir_stats::print_hir_stats(tcx); }


Question:
This is one of those ICEs that are terribly hard to minimize because they happen cache-dependently, [update: see below for repro instructions]. If nothing else, notice that there is a panic while trying to print the query stack; it might be desirable to look into making that not happen so as to be able to get more information. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --Occurred while running or . : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details label +A-incr-comp
On looking more closely at the backtrace, it seems that this error results from attempting to load corrupted (truncated) query cache files, and therefore it would be valuable to obtain a trace from the file having been written (assuming that they are truncated due to a panic during write; if they're silently corrupted that's even harder to notice). I will update this issue if I manage to catch such a case.
Looking at the first panic observed since a and it is still the above in , so it's not that I missed the writing event but that it didn't panic.
I have made some progress on reproducing the problem with a minimal incremental change (but not yet a minimal standalone code sample), and expressed some interest in looking at the problem, so I've published branches with the work I have so far. Repro steps: The second build will ICE. The differences between the two branches are shuffling code between modules, adding a module, and deleting a module; the code in them is as identical as it can be.
Note: I cannot reproduce this ICE on x86_64-unknown-linux-gnu with the latest nightly by default, but makes it ICE. <details<summarybacktrace</summary</details
I've created a new branch which slighly simplifies the diff application: ( at the time of writing).
I've tried to find out a bit more about this, but didn't get very far. From what I can tell: In the second session refers to the derived impl for . And refers to the const generic of that impl. It has the span of the CHUNKSIZE const generic of the type definition. In the first session, as far as I can tell, the def-path refers to the , which also has a generic const. The query should not evaluate to green, but for some reason all of its dependencies are marked as green.
Maybe is too broken (it needed some fixing to show more than just DepKinds), but is it possible that has no dependencies at all during the first session?
It does indeed have no dependencies. I imagine that this is the culprit: I'm not really up-to-date with query feeding but this looks fishy. When a dep-node has no dependencies, it will trivially evaluate to green. Don't we need at least a dependency on the query that does the feeding? cc &
Given what we've learned about this bug, it's likely that this is purely about incremental compilation cache keying, i.e. neither state of the code is more likely to be miscompiled than the other, right? In other words, I as the author of the original code probably don't need to worry that I'm making my compiled code less reliable if I make the change that caused the ICE, as long as I after that point?
Yes, as far as I can tell, this is a bug in incremental compilation's dependency tracking and does not affect non-incremental builds.
Hey, I'm back with a repro! Thanks go out to , without which I would have never been able to minimize this. A one-command minimization is available at with . Basically: must be enabled. Running . Then applying Then running again panics. <details</detailsFor some strange reason I am unable to reproduce the changes when applying the diff in vscode via WSL. and work though.
I will unassign myself as I mostly assigned myself for the MCVE.
It looks like some things, like lowering to HIR, are run within a context, which leads to this call being ignored too -- and thus never making it into the we are trying to duplicate during . As a consequence, the feed queries in question go from explicitly "re-compute unconditionally" to effectively "re-use unconditionally" The reason seems to be that we . That's fine for those queries themselves because we make sure to re-compute those explicitly. But we fail to "inherit" the eval-always-ness to nested feed-queries. I'll look into fixing this some time this week.

assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_DEPENDENCYLESS_ANON_NODE); // Instantiate a dependy-less red node only once for anonymous queries. <del> let (_red_node_index, _prev_and_index) = current.intern_node( </del> <ins> let (red_node_index, red_node_prev_index_and_color) = current.intern_node( </ins> profiler, &prev_graph, DepNode { kind: DepKind::RED, hash: Fingerprint::ZERO.into() },


Question:
This is one of those ICEs that are terribly hard to minimize because they happen cache-dependently, [update: see below for repro instructions]. If nothing else, notice that there is a panic while trying to print the query stack; it might be desirable to look into making that not happen so as to be able to get more information. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --Occurred while running or . : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details label +A-incr-comp
On looking more closely at the backtrace, it seems that this error results from attempting to load corrupted (truncated) query cache files, and therefore it would be valuable to obtain a trace from the file having been written (assuming that they are truncated due to a panic during write; if they're silently corrupted that's even harder to notice). I will update this issue if I manage to catch such a case.
Looking at the first panic observed since a and it is still the above in , so it's not that I missed the writing event but that it didn't panic.
I have made some progress on reproducing the problem with a minimal incremental change (but not yet a minimal standalone code sample), and expressed some interest in looking at the problem, so I've published branches with the work I have so far. Repro steps: The second build will ICE. The differences between the two branches are shuffling code between modules, adding a module, and deleting a module; the code in them is as identical as it can be.
Note: I cannot reproduce this ICE on x86_64-unknown-linux-gnu with the latest nightly by default, but makes it ICE. <details<summarybacktrace</summary</details
I've created a new branch which slighly simplifies the diff application: ( at the time of writing).
I've tried to find out a bit more about this, but didn't get very far. From what I can tell: In the second session refers to the derived impl for . And refers to the const generic of that impl. It has the span of the CHUNKSIZE const generic of the type definition. In the first session, as far as I can tell, the def-path refers to the , which also has a generic const. The query should not evaluate to green, but for some reason all of its dependencies are marked as green.
Maybe is too broken (it needed some fixing to show more than just DepKinds), but is it possible that has no dependencies at all during the first session?
It does indeed have no dependencies. I imagine that this is the culprit: I'm not really up-to-date with query feeding but this looks fishy. When a dep-node has no dependencies, it will trivially evaluate to green. Don't we need at least a dependency on the query that does the feeding? cc &
Given what we've learned about this bug, it's likely that this is purely about incremental compilation cache keying, i.e. neither state of the code is more likely to be miscompiled than the other, right? In other words, I as the author of the original code probably don't need to worry that I'm making my compiled code less reliable if I make the change that caused the ICE, as long as I after that point?
Yes, as far as I can tell, this is a bug in incremental compilation's dependency tracking and does not affect non-incremental builds.
Hey, I'm back with a repro! Thanks go out to , without which I would have never been able to minimize this. A one-command minimization is available at with . Basically: must be enabled. Running . Then applying Then running again panics. <details</detailsFor some strange reason I am unable to reproduce the changes when applying the diff in vscode via WSL. and work though.
I will unassign myself as I mostly assigned myself for the MCVE.
It looks like some things, like lowering to HIR, are run within a context, which leads to this call being ignored too -- and thus never making it into the we are trying to duplicate during . As a consequence, the feed queries in question go from explicitly "re-compute unconditionally" to effectively "re-use unconditionally" The reason seems to be that we . That's fine for those queries themselves because we make sure to re-compute those explicitly. But we fail to "inherit" the eval-always-ness to nested feed-queries. I'll look into fixing this some time this week.

None, false, ); <del> assert_eq!(_red_node_index, DepNodeIndex::FOREVER_RED_NODE); assert!(matches!(_prev_and_index, None | Some((_, DepNodeColor::Red)))); </del> <ins> assert_eq!(red_node_index, DepNodeIndex::FOREVER_RED_NODE); match red_node_prev_index_and_color { None => { // This is expected when we have no previous compilation session. assert!(prev_graph_node_count == 0); } Some((prev_red_node_index, DepNodeColor::Red)) => { assert_eq!(prev_red_node_index.as_usize(), red_node_index.as_usize()); colors.insert(prev_red_node_index, DepNodeColor::Red); } Some((_, DepNodeColor::Green(_))) => { // There must be a logic error somewhere if we hit this branch. panic!("DepNodeIndex::FOREVER_RED_NODE evaluated to DepNodeColor::Green") } } </ins> DepGraph { data: Some(Lrc::new(DepGraphData {


Question:
This is one of those ICEs that are terribly hard to minimize because they happen cache-dependently, [update: see below for repro instructions]. If nothing else, notice that there is a panic while trying to print the query stack; it might be desirable to look into making that not happen so as to be able to get more information. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --Occurred while running or . : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details label +A-incr-comp
On looking more closely at the backtrace, it seems that this error results from attempting to load corrupted (truncated) query cache files, and therefore it would be valuable to obtain a trace from the file having been written (assuming that they are truncated due to a panic during write; if they're silently corrupted that's even harder to notice). I will update this issue if I manage to catch such a case.
Looking at the first panic observed since a and it is still the above in , so it's not that I missed the writing event but that it didn't panic.
I have made some progress on reproducing the problem with a minimal incremental change (but not yet a minimal standalone code sample), and expressed some interest in looking at the problem, so I've published branches with the work I have so far. Repro steps: The second build will ICE. The differences between the two branches are shuffling code between modules, adding a module, and deleting a module; the code in them is as identical as it can be.
Note: I cannot reproduce this ICE on x86_64-unknown-linux-gnu with the latest nightly by default, but makes it ICE. <details<summarybacktrace</summary</details
I've created a new branch which slighly simplifies the diff application: ( at the time of writing).
I've tried to find out a bit more about this, but didn't get very far. From what I can tell: In the second session refers to the derived impl for . And refers to the const generic of that impl. It has the span of the CHUNKSIZE const generic of the type definition. In the first session, as far as I can tell, the def-path refers to the , which also has a generic const. The query should not evaluate to green, but for some reason all of its dependencies are marked as green.
Maybe is too broken (it needed some fixing to show more than just DepKinds), but is it possible that has no dependencies at all during the first session?
It does indeed have no dependencies. I imagine that this is the culprit: I'm not really up-to-date with query feeding but this looks fishy. When a dep-node has no dependencies, it will trivially evaluate to green. Don't we need at least a dependency on the query that does the feeding? cc &
Given what we've learned about this bug, it's likely that this is purely about incremental compilation cache keying, i.e. neither state of the code is more likely to be miscompiled than the other, right? In other words, I as the author of the original code probably don't need to worry that I'm making my compiled code less reliable if I make the change that caused the ICE, as long as I after that point?
Yes, as far as I can tell, this is a bug in incremental compilation's dependency tracking and does not affect non-incremental builds.
Hey, I'm back with a repro! Thanks go out to , without which I would have never been able to minimize this. A one-command minimization is available at with . Basically: must be enabled. Running . Then applying Then running again panics. <details</detailsFor some strange reason I am unable to reproduce the changes when applying the diff in vscode via WSL. and work though.
I will unassign myself as I mostly assigned myself for the MCVE.
It looks like some things, like lowering to HIR, are run within a context, which leads to this call being ignored too -- and thus never making it into the we are trying to duplicate during . As a consequence, the feed queries in question go from explicitly "re-compute unconditionally" to effectively "re-use unconditionally" The reason seems to be that we . That's fine for those queries themselves because we make sure to re-compute those explicitly. But we fail to "inherit" the eval-always-ness to nested feed-queries. I'll look into fixing this some time this week.

})) }; <del> let task_deps_ref = match &task_deps { Some(deps) => TaskDepsRef::Allow(deps), None => TaskDepsRef::Ignore, }; </del> <ins> let task_deps_ref = task_deps.as_ref().map(TaskDepsRef::Allow).unwrap_or(TaskDepsRef::EvalAlways); </ins> let result = K::with_deps(task_deps_ref, || task(cx, arg)); let edges = task_deps.map_or_else(|| smallvec![], |lock| lock.into_inner().reads);


Question:
This is one of those ICEs that are terribly hard to minimize because they happen cache-dependently, [update: see below for repro instructions]. If nothing else, notice that there is a panic while trying to print the query stack; it might be desirable to look into making that not happen so as to be able to get more information. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --Occurred while running or . : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details label +A-incr-comp
On looking more closely at the backtrace, it seems that this error results from attempting to load corrupted (truncated) query cache files, and therefore it would be valuable to obtain a trace from the file having been written (assuming that they are truncated due to a panic during write; if they're silently corrupted that's even harder to notice). I will update this issue if I manage to catch such a case.
Looking at the first panic observed since a and it is still the above in , so it's not that I missed the writing event but that it didn't panic.
I have made some progress on reproducing the problem with a minimal incremental change (but not yet a minimal standalone code sample), and expressed some interest in looking at the problem, so I've published branches with the work I have so far. Repro steps: The second build will ICE. The differences between the two branches are shuffling code between modules, adding a module, and deleting a module; the code in them is as identical as it can be.
Note: I cannot reproduce this ICE on x86_64-unknown-linux-gnu with the latest nightly by default, but makes it ICE. <details<summarybacktrace</summary</details
I've created a new branch which slighly simplifies the diff application: ( at the time of writing).
I've tried to find out a bit more about this, but didn't get very far. From what I can tell: In the second session refers to the derived impl for . And refers to the const generic of that impl. It has the span of the CHUNKSIZE const generic of the type definition. In the first session, as far as I can tell, the def-path refers to the , which also has a generic const. The query should not evaluate to green, but for some reason all of its dependencies are marked as green.
Maybe is too broken (it needed some fixing to show more than just DepKinds), but is it possible that has no dependencies at all during the first session?
It does indeed have no dependencies. I imagine that this is the culprit: I'm not really up-to-date with query feeding but this looks fishy. When a dep-node has no dependencies, it will trivially evaluate to green. Don't we need at least a dependency on the query that does the feeding? cc &
Given what we've learned about this bug, it's likely that this is purely about incremental compilation cache keying, i.e. neither state of the code is more likely to be miscompiled than the other, right? In other words, I as the author of the original code probably don't need to worry that I'm making my compiled code less reliable if I make the change that caused the ICE, as long as I after that point?
Yes, as far as I can tell, this is a bug in incremental compilation's dependency tracking and does not affect non-incremental builds.
Hey, I'm back with a repro! Thanks go out to , without which I would have never been able to minimize this. A one-command minimization is available at with . Basically: must be enabled. Running . Then applying Then running again panics. <details</detailsFor some strange reason I am unable to reproduce the changes when applying the diff in vscode via WSL. and work though.
I will unassign myself as I mostly assigned myself for the MCVE.
It looks like some things, like lowering to HIR, are run within a context, which leads to this call being ignored too -- and thus never making it into the we are trying to duplicate during . As a consequence, the feed queries in question go from explicitly "re-compute unconditionally" to effectively "re-use unconditionally" The reason seems to be that we . That's fine for those queries themselves because we make sure to re-compute those explicitly. But we fail to "inherit" the eval-always-ness to nested feed-queries. I'll look into fixing this some time this week.

K::read_deps(|task_deps| { let mut task_deps = match task_deps { TaskDepsRef::Allow(deps) => deps.lock(), <ins> TaskDepsRef::EvalAlways => { // We don't need to record dependencies of eval_always // queries. They are re-evaluated unconditionally anyway. return; } </ins> TaskDepsRef::Ignore => return, TaskDepsRef::Forbid => { panic!("Illegal read of: {dep_node_index:?}")