Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: Program does not panic. Instead, this happened: Program panics with the error . <!-- 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</detailsTo clarify: This problem occurs with all trait implementations that don't override the default implementation, e.g. with this simple DelegatingWrite:
I see two distinct possibilites to resolve this: 1) Treat incomplete s not ending on a codepoint boundary as a bug and fix that in the stdlib. Also clarify in the docs that indivual calls must be passed complete UTF-8 sequences if a Windows terminal is attached. 2) In the vain of "Be liberal in what you accept" handle incomplete UTF-8 passed in via calls appropriately, as long as the sequence is completed properly in the next call(s).
Hm, so this is ultimately a bug in the buffer uses? It attempts to write 1024 bytes but only 1023 bytes can written in the first OS call. It then has a leftover byte, which I guess it tries to write by itself thus causing this error?
The logic which errors if incomplete UTF-8 is passed in at index 0 is in the std lib at . That is where the error message comes from. As far as I can see the stdio buffer implementation (in stable, it is in , apparently currently being revamped) can not know of the requirement that only complete UTF-8 may be written to the underlying Windows terminal so I think that it should be encapsulated in by just accepting and buffering incomplete UTF-8 when necessary.
I mean, a generic buffer can attempt to avoid small writes (say, less than 16 bytes) by copying those left over bytes to the front of the buffer and waiting for either another to refill the buffer or a to empty it. But I see what you mean. Introducing a small buffer to windows/stdio would fix the problem.

return ret; } <del> // As the console is meant for presenting text, we assume bytes of `data` come from a string // and are encoded as UTF-8, which needs to be encoded as UTF-16. </del> <ins> if incomplete_utf8.len > 0 { assert!( incomplete_utf8.len < 4, "Unexpected number of bytes for incomplete UTF-8 codepoint." ); if data[0] >> 6 != 0b10 { incomplete_utf8.len = 0; // not a continuation byte - reject return Err(io::Error::new_const( io::ErrorKind::InvalidData, &"Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); } incomplete_utf8.bytes[incomplete_utf8.len as usize] = data[0]; incomplete_utf8.len += 1; let char_width = utf8_char_width(incomplete_utf8.bytes[0]); if (incomplete_utf8.len as usize) < char_width { // more bytes needed return Ok(1); } let s = str::from_utf8(&incomplete_utf8.bytes[0..incomplete_utf8.len as usize]); incomplete_utf8.len = 0; match s { Ok(s) => { assert_eq!(char_width, s.len()); let written = write_valid_utf8_to_console(handle, s)?; assert_eq!(written, s.len()); // guaranteed by write_valid_utf8_to_console() for single codepoint writes return Ok(1); } Err(_) => { return Err(io::Error::new_const( io::ErrorKind::InvalidData, &"Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); } } } // As the console is meant for presenting text, we assume bytes of `data` are encoded as UTF-8, // which needs to be encoded as UTF-16. </ins> // // If the data is not valid UTF-8 we write out as many bytes as are valid. <del> // Only when there are no valid bytes (which will happen on the next call), return an error. </del> <ins> // If the first byte is invalid it is either first byte of a multi-byte sequence but the // provided byte slice is too short or it is the first byte of an invalide multi-byte sequence. </ins> let len = cmp::min(data.len(), MAX_BUFFER_SIZE / 2); let utf8 = match str::from_utf8(&data[..len]) { Ok(s) => s, Err(ref e) if e.valid_up_to() == 0 => { <del> return Err(io::Error::new_const( io::ErrorKind::InvalidData, &"Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); </del> <ins> let first_byte_char_width = utf8_char_width(data[0]); if first_byte_char_width > 1 && data.len() < first_byte_char_width { incomplete_utf8.bytes[0] = data[0]; incomplete_utf8.len = 1; return Ok(1); } else { return Err(io::Error::new_const( io::ErrorKind::InvalidData, &"Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); } </ins> } Err(e) => str::from_utf8(&data[..e.valid_up_to()]).unwrap(), }; <ins> write_valid_utf8_to_console(handle, utf8) } fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usize> { </ins> let mut utf16 = [0u16; MAX_BUFFER_SIZE / 2]; let mut len_utf16 = 0; for (chr, dest) in utf8.encode_utf16().zip(utf16.iter_mut()) {


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: Program does not panic. Instead, this happened: Program panics with the error . <!-- 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</detailsTo clarify: This problem occurs with all trait implementations that don't override the default implementation, e.g. with this simple DelegatingWrite:
I see two distinct possibilites to resolve this: 1) Treat incomplete s not ending on a codepoint boundary as a bug and fix that in the stdlib. Also clarify in the docs that indivual calls must be passed complete UTF-8 sequences if a Windows terminal is attached. 2) In the vain of "Be liberal in what you accept" handle incomplete UTF-8 passed in via calls appropriately, as long as the sequence is completed properly in the next call(s).
Hm, so this is ultimately a bug in the buffer uses? It attempts to write 1024 bytes but only 1023 bytes can written in the first OS call. It then has a leftover byte, which I guess it tries to write by itself thus causing this error?
The logic which errors if incomplete UTF-8 is passed in at index 0 is in the std lib at . That is where the error message comes from. As far as I can see the stdio buffer implementation (in stable, it is in , apparently currently being revamped) can not know of the requirement that only complete UTF-8 may be written to the underlying Windows terminal so I think that it should be encapsulated in by just accepting and buffering incomplete UTF-8 when necessary.
I mean, a generic buffer can attempt to avoid small writes (say, less than 16 bytes) by copying those left over bytes to the front of the buffer and waiting for either another to refill the buffer or a to empty it. But I see what you mean. Introducing a small buffer to windows/stdio would fix the problem.

Ok(written) } <ins> impl IncompleteUtf8 { pub const fn new() -> IncompleteUtf8 { IncompleteUtf8 { bytes: [0; 4], len: 0 } } } </ins> impl Stdout { pub const fn new() -> Stdout { <del> Stdout </del> <ins> Stdout { incomplete_utf8: IncompleteUtf8::new() } </ins> } } impl io::Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { <del> write(c::STD_OUTPUT_HANDLE, buf) </del> <ins> write(c::STD_OUTPUT_HANDLE, buf, &mut self.incomplete_utf8) </ins> } fn flush(&mut self) -> io::Result<()> {


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: Program does not panic. Instead, this happened: Program panics with the error . <!-- 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</detailsTo clarify: This problem occurs with all trait implementations that don't override the default implementation, e.g. with this simple DelegatingWrite:
I see two distinct possibilites to resolve this: 1) Treat incomplete s not ending on a codepoint boundary as a bug and fix that in the stdlib. Also clarify in the docs that indivual calls must be passed complete UTF-8 sequences if a Windows terminal is attached. 2) In the vain of "Be liberal in what you accept" handle incomplete UTF-8 passed in via calls appropriately, as long as the sequence is completed properly in the next call(s).
Hm, so this is ultimately a bug in the buffer uses? It attempts to write 1024 bytes but only 1023 bytes can written in the first OS call. It then has a leftover byte, which I guess it tries to write by itself thus causing this error?
The logic which errors if incomplete UTF-8 is passed in at index 0 is in the std lib at . That is where the error message comes from. As far as I can see the stdio buffer implementation (in stable, it is in , apparently currently being revamped) can not know of the requirement that only complete UTF-8 may be written to the underlying Windows terminal so I think that it should be encapsulated in by just accepting and buffering incomplete UTF-8 when necessary.
I mean, a generic buffer can attempt to avoid small writes (say, less than 16 bytes) by copying those left over bytes to the front of the buffer and waiting for either another to refill the buffer or a to empty it. But I see what you mean. Introducing a small buffer to windows/stdio would fix the problem.

impl Stderr { pub const fn new() -> Stderr { <del> Stderr </del> <ins> Stderr { incomplete_utf8: IncompleteUtf8::new() } </ins> } } impl io::Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { <del> write(c::STD_ERROR_HANDLE, buf) </del> <ins> write(c::STD_ERROR_HANDLE, buf, &mut self.incomplete_utf8) </ins> } fn flush(&mut self) -> io::Result<()> {


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --If glob reexport reexports module and there is already module , the documentation duplicates. Current behaviour: ! ( module is duplicated, though both module links point to as expected) The expected behaviour: module is only shown once. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
claim

let mut inserted = FxHashSet::default(); items.extend(doc.foreigns.iter().map(|(item, renamed)| { let item = clean_maybe_renamed_foreign_item(cx, item, *renamed); <del> if let Some(name) = item.name { </del> <ins> if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) { </ins> inserted.insert((item.type_(), name)); } item })); <del> items.extend(doc.mods.iter().map(|x| { inserted.insert((ItemType::Module, x.name)); clean_doc_module(x, cx) </del> <ins> items.extend(doc.mods.iter().filter_map(|x| { if !inserted.insert((ItemType::Module, x.name)) { return None; } let item = clean_doc_module(x, cx); if item.attrs.lists(sym::doc).has_word(sym::hidden) { // Hidden modules are stripped at a later stage. // If a hidden module has the same name as a visible one, we want // to keep both of them around. inserted.remove(&(ItemType::Module, x.name)); } Some(item) </ins> })); // Split up imports from all other items.


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --If glob reexport reexports module and there is already module , the documentation duplicates. Current behaviour: ! ( module is duplicated, though both module links point to as expected) The expected behaviour: module is only shown once. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
claim

} let v = clean_maybe_renamed_item(cx, item, *renamed); for item in &v { <del> if let Some(name) = item.name { </del> <ins> if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) { </ins> inserted.insert((item.type_(), name)); } }


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --If glob reexport reexports module and there is already module , the documentation duplicates. Current behaviour: ! ( module is duplicated, though both module links point to as expected) The expected behaviour: module is only shown once. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
claim

self.inside_public_path &= self.cx.tcx.visibility(def_id).is_public(); for &i in m.item_ids { let item = self.cx.tcx.hir().item(i); <ins> if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { continue; } </ins> self.visit_item(item, None, &mut om); } <ins> for &i in m.item_ids { let item = self.cx.tcx.hir().item(i); // To match the way import precedence works, visit glob imports last. // Later passes in rustdoc will de-duplicate by name and kind, so if glob- // imported items appear last, then they'll be the ones that get discarded. if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { self.visit_item(item, None, &mut om); } } </ins> self.inside_public_path = orig_inside_public_path; om }


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --If glob reexport reexports module and there is already module , the documentation duplicates. Current behaviour: ! ( module is duplicated, though both module links point to as expected) The expected behaviour: module is only shown once. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
claim

<ins> // https://github.com/rust-lang/rust/pull/83872#issuecomment-820101008 #![crate_name="foo"] mod sub4 { /// 0 pub const X: usize = 0; pub mod inner { pub use super::*; /// 1 pub const X: usize = 1; } } #[doc(inline)] pub use sub4::inner::*; // @has 'foo/index.html' // @has - '//div[@class="item-right docblock-short"]' '1' // @!has - '//div[@class="item-right docblock-short"]' '0' fn main() { assert_eq!(X, 1); } </ins>


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --If glob reexport reexports module and there is already module , the documentation duplicates. Current behaviour: ! ( module is duplicated, though both module links point to as expected) The expected behaviour: module is only shown once. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
claim

<ins> // @has 'glob_shadowing/index.html' // @count - '//div[@class="item-left module-item"]' 6 // @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe' // @has - '//div[@class="item-right docblock-short"]' 'sub2::describe' // @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe2' // @!has - '//div[@class="item-right docblock-short"]' 'sub1::prelude' // @has - '//div[@class="item-right docblock-short"]' 'mod::prelude' // @has - '//div[@class="item-right docblock-short"]' 'sub1::Foo (struct)' // @has - '//div[@class="item-right docblock-short"]' 'mod::Foo (function)' // @has - '//div[@class="item-right docblock-short"]' 'sub4::inner::X' // @has 'glob_shadowing/fn.describe.html' // @has - '//div[@class="docblock"]' 'sub2::describe' mod sub1 { // this should be shadowed by sub2::describe /// sub1::describe pub fn describe() -> &'static str { "sub1::describe" } // this should be shadowed by mod::prelude /// sub1::prelude pub mod prelude { } // this should *not* be shadowed, because sub1::Foo and mod::Foo are in different namespaces /// sub1::Foo (struct) pub struct Foo; // this should be shadowed, // because both sub1::describe2 and sub3::describe2 are from glob reexport /// sub1::describe2 pub fn describe2() -> &'static str { "sub1::describe2" } } mod sub2 { /// sub2::describe pub fn describe() -> &'static str { "sub2::describe" } } mod sub3 { // this should be shadowed // because both sub1::describe2 and sub3::describe2 are from glob reexport /// sub3::describe2 pub fn describe2() -> &'static str { "sub3::describe2" } } mod sub4 { // this should be shadowed by sub4::inner::X /// sub4::X pub const X: usize = 0; pub mod inner { pub use super::*; /// sub4::inner::X pub const X: usize = 1; } } /// mod::Foo (function) pub fn Foo() {} #[doc(inline)] pub use sub2::describe; #[doc(inline)] pub use sub1::*; #[doc(inline)] pub use sub3::*; #[doc(inline)] pub use sub4::inner::*; /// mod::prelude pub mod prelude {} </ins>


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --If glob reexport reexports module and there is already module , the documentation duplicates. Current behaviour: ! ( module is duplicated, though both module links point to as expected) The expected behaviour: module is only shown once. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
claim

<ins> #![crate_name = "foo"] pub mod sub { pub struct Item; pub mod prelude { pub use super::Item; } } #[doc(inline)] pub use sub::*; // @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1 // @count foo/prelude/index.html '//div[@class="item-row"]' 0 pub mod prelude {} </ins>


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --If glob reexport reexports module and there is already module , the documentation duplicates. Current behaviour: ! ( module is duplicated, though both module links point to as expected) The expected behaviour: module is only shown once. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
claim

<ins> #![crate_name = "foo"] pub mod sub { pub struct Item; pub mod prelude { pub use super::Item; } } // @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1 // @count foo/prelude/index.html '//div[@class="item-row"]' 0 pub mod prelude {} #[doc(inline)] pub use sub::*; </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ assembly-output: emit-asm //@ compile-flags:-Copt-level=3 //@ only-x86_64 #![crate_type = "lib"] #[no_mangle] type T = u8; type T1 = (T, T, T, T, T, T, T, T); type T2 = [T; 8]; #[no_mangle] // CHECK-LABEL: foo1a // CHECK: cmp // CHECK-NEXT: set // CHECK-NEXT: ret pub fn foo1a(a: T1, b: T1) -> bool { a == b } #[no_mangle] // CHECK-LABEL: foo1b // CHECK: mov // CHECK-NEXT: cmp // CHECK-NEXT: set // CHECK-NEXT: ret pub fn foo1b(a: &T1, b: &T1) -> bool { a == b } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ compile-flags: -O //@ min-llvm-version: 17 #![crate_type = "lib"] #[no_mangle] // CHECK-LABEL: @foo // CHECK: getelementptr inbounds // CHECK-NEXT: load i64 // CHECK-NEXT: icmp eq i64 // CHECK-NEXT: br i1 #[no_mangle] pub fn foo(input: &mut &[u64]) -> Option<u64> { let (first, rest) = input.split_first()?; *input = rest; Some(*first) } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ compile-flags: -O // XXX: The x86-64 assembly get optimized correclty. But llvm-ir output is not until llvm 18? //@ min-llvm-version: 18 #![crate_type = "lib"] pub enum K{ A(Box<[i32]>), B(Box<[u8]>), C(Box<[String]>), D(Box<[u16]>), } #[no_mangle] // CHECK-LABEL: @get_len // CHECK: getelementptr inbounds // CHECK-NEXT: load // CHECK-NEXT: ret i64 // CHECK-NOT: switch pub fn get_len(arg: &K)->usize{ match arg { K::A(ref lst)=>lst.len(), K::B(ref lst)=>lst.len(), K::C(ref lst)=>lst.len(), K::D(ref lst)=>lst.len(), } } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ compile-flags: -O // This regress since Rust version 1.72. //@ min-llvm-version: 18.1.4 #![crate_type = "lib"] use std::convert::TryInto; const N: usize = 24; #[no_mangle] // CHECK-LABEL: @example // CHECK-NOT: unwrap_failed pub fn example(a: Vec<u8>) -> u8 { if a.len() != 32 { return 0; } let a: [u8; 32] = a.try_into().unwrap(); a[15] + a[N] } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ compile-flags: -O //@ min-llvm-version: 17 #![crate_type = "lib"] // CHECK-LABEL: @write_u8_variant_a // CHECK: getelementptr // CHECK-NEXT: icmp ugt #[no_mangle] pub fn write_u8_variant_a( bytes: &mut [u8], buf: u8, offset: usize, ) -> Option<&mut [u8]> { let buf = buf.to_le_bytes(); bytes .get_mut(offset..).and_then(|bytes| bytes.get_mut(..buf.len())) } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> // in Rust 1.73, -O and opt-level=3 optimizes differently //@ compile-flags: -C opt-level=3 //@ min-llvm-version: 17 #![crate_type = "lib"] use std::cmp::max; #[no_mangle] // CHECK-LABEL: @foo // CHECK-NOT: slice_start_index_len_fail // CHECK-NOT: unreachable pub fn foo(v: &mut Vec<u8>, size: usize)-> Option<&mut [u8]> { if v.len() > max(1, size) { let start = v.len() - size; Some(&mut v[start..]) } else { None } } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ compile-flags: -O //@ min-llvm-version: 18 #![crate_type = "lib"] // CHECK-LABEL: @div2 // CHECK: ashr i32 %a, 1 // CHECK-NEXT: ret i32 #[no_mangle] pub fn div2(a: i32) -> i32 { a.div_euclid(2) } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ compile-flags: -O #![crate_type = "lib"] const N: usize = 3; pub type T = u8; #[no_mangle] // CHECK-LABEL: @split_mutiple // CHECK-NOT: unreachable pub fn split_mutiple(slice: &[T]) -> (&[T], &[T]) { let len = slice.len() / N; slice.split_at(len * N) } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ compile-flags: -O //@ min-llvm-version: 17 #![crate_type = "lib"] #[no_mangle] // CHECK-LABEL: @foo // CHECK: {{.*}}: // CHECK: ret // CHECK-NOT: unreachable pub fn foo(arr: &mut [u32]) { for i in 0..arr.len() { for j in 0..i { assert!(j < arr.len()); } } } </ins>


Question:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

<ins> //@ compile-flags: -O //@ min-llvm-version: 18 #![crate_type = "lib"] use std::ptr::NonNull; // CHECK-LABEL: @slice_ptr_len_1 // CHECK: {{.*}}: // CHECK-NEXT: ret i64 %ptr.1 #[no_mangle] pub fn slice_ptr_len_1(ptr: *const [u8]) -> usize { let ptr = ptr.cast_mut(); if let Some(ptr) = NonNull::new(ptr) { ptr.len() } else { // We know ptr is null, so we know ptr.wrapping_byte_add(1) is not null. NonNull::new(ptr.wrapping_byte_add(1)).unwrap().len() } } </ins>


Question:
I tried this code: I expected to see this happen: successful test suite run Instead, this happened: debuginfo test failure for pretty-std-, saying that an expecting output from the debugger was not found. The specific line it seemed be this one: <details<summaryClick to see transcript that includes the full stdout/stderr output as reported by + </summary</details
Incidentally, when I tried to run the test by hand (which admittedly I might have messed up in some way), I saw this: <details<summaryClick to see some details about my attempt to run on a binary.</summary</summary</detailsIt seems pretty suspicious that lldb was reporting for the hashset and hashmap in these cases, when the unit 8test expects both their sizes to be 4. (But that also doesn't actually seem to be the behavior that x.py is observing, so that might be user error, or a separate bug entirely.)
I'm not sure if you've seen , but the lldb tests only run on macOS on CI. It looks like you are maybe using linux, so this is exercising untested code. In particular, pretty-std-collections is disabled on macOS, so it is not tested anywhere. It's not too surprising that it may have bitrotted. I'm also curious, are you using lldb installed on your system? Is it the same version of LLVM that rustc was built with?
Yeah I knew the debugger test suite i only enabled in certain contexts, but I couldn't remember the details. My runs of are using the wrapper from 1.50 stable. Of course that's just a wrapper over what's in my PATH ( in this case), right? lldb version 11.0.0 in this case. I should probably see if things change if I set in my . (In any case, I'd say it remains a suboptimal developer experience to have x.py test fail in this manner.)
was removed from rustbuild a long while back, so this shouldn't have any impact. Agreed, I ran into a similar problem (). As long as the test is disabled in CI, it'll probably keep breaking unfortunately. I'm pretty certain I tested locally, and it worked, so somehow it broke again. Maybe has some insight?
I can bisect, thanks for the link !
I checked the latest changes briefly and it looks like broke LLDB pretty-printing on Rust 1.51. Note that should be used only on the newest versions of . I'll open a PR to fix this soon.
Thanks that was quick! And please don't feel obligated to investigate when I ping. It was just a wild guess if you might know what was up.
No problem, please feel free to mention me in case of any debugger pretty-printers problems! I'm working on the debugging support in IntelliJ Rust and I'm interested in fixing issues like this ASAP.
I investigated the problem with a clear mind and found out that LLDB pretty-printer was updated improperly in (although GDB pretty-printer is OK). Please check the new PR. It would be so great to have LLDB pretty-printers tests on CI. In IntelliJ Rust, we on Linux. We Python package from CLion distribution but I suppose the system package can be linked and used instead (see ).

def update(self): # type: () -> None table = self.table() <del> capacity = table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1 ctrl = table.GetChildMemberWithName("ctrl").GetChildAtIndex(0) </del> <ins> inner_table = table.GetChildMemberWithName("table") </ins> <del> self.size = table.GetChildMemberWithName("items").GetValueAsUnsigned() </del> <ins> capacity = inner_table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1 ctrl = inner_table.GetChildMemberWithName("ctrl").GetChildAtIndex(0) self.size = inner_table.GetChildMemberWithName("items").GetValueAsUnsigned() </ins> self.pair_type = table.type.template_args[0] if self.pair_type.IsTypedefType(): self.pair_type = self.pair_type.GetTypedefedType() self.pair_type_size = self.pair_type.GetByteSize() <del> self.new_layout = not table.GetChildMemberWithName("data").IsValid() </del> <ins> self.new_layout = not inner_table.GetChildMemberWithName("data").IsValid() </ins> if self.new_layout: self.data_ptr = ctrl.Cast(self.pair_type.GetPointerType()) else: <del> self.data_ptr = table.GetChildMemberWithName("data").GetChildAtIndex(0) </del> <ins> self.data_ptr = inner_table.GetChildMemberWithName("data").GetChildAtIndex(0) </ins> u8_type = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar) u8_type_size = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar).GetByteSize()


Question:
I tried this code: I expected to see this happen: successful test suite run Instead, this happened: debuginfo test failure for pretty-std-, saying that an expecting output from the debugger was not found. The specific line it seemed be this one: <details<summaryClick to see transcript that includes the full stdout/stderr output as reported by + </summary</details
Incidentally, when I tried to run the test by hand (which admittedly I might have messed up in some way), I saw this: <details<summaryClick to see some details about my attempt to run on a binary.</summary</summary</detailsIt seems pretty suspicious that lldb was reporting for the hashset and hashmap in these cases, when the unit 8test expects both their sizes to be 4. (But that also doesn't actually seem to be the behavior that x.py is observing, so that might be user error, or a separate bug entirely.)
I'm not sure if you've seen , but the lldb tests only run on macOS on CI. It looks like you are maybe using linux, so this is exercising untested code. In particular, pretty-std-collections is disabled on macOS, so it is not tested anywhere. It's not too surprising that it may have bitrotted. I'm also curious, are you using lldb installed on your system? Is it the same version of LLVM that rustc was built with?
Yeah I knew the debugger test suite i only enabled in certain contexts, but I couldn't remember the details. My runs of are using the wrapper from 1.50 stable. Of course that's just a wrapper over what's in my PATH ( in this case), right? lldb version 11.0.0 in this case. I should probably see if things change if I set in my . (In any case, I'd say it remains a suboptimal developer experience to have x.py test fail in this manner.)
was removed from rustbuild a long while back, so this shouldn't have any impact. Agreed, I ran into a similar problem (). As long as the test is disabled in CI, it'll probably keep breaking unfortunately. I'm pretty certain I tested locally, and it worked, so somehow it broke again. Maybe has some insight?
I can bisect, thanks for the link !
I checked the latest changes briefly and it looks like broke LLDB pretty-printing on Rust 1.51. Note that should be used only on the newest versions of . I'll open a PR to fix this soon.
Thanks that was quick! And please don't feel obligated to investigate when I ping. It was just a wild guess if you might know what was up.
No problem, please feel free to mention me in case of any debugger pretty-printers problems! I'm working on the debugging support in IntelliJ Rust and I'm interested in fixing issues like this ASAP.
I investigated the problem with a clear mind and found out that LLDB pretty-printer was updated improperly in (although GDB pretty-printer is OK). Please check the new PR. It would be so great to have LLDB pretty-printers tests on CI. In IntelliJ Rust, we on Linux. We Python package from CLion distribution but I suppose the system package can be linked and used instead (see ).

# HashSet wraps either std HashMap or hashbrown::HashSet, which both # wrap hashbrown::HashMap, so either way we "unwrap" twice. hashbrown_hashmap = self.valobj.GetChildAtIndex(0).GetChildAtIndex(0) <del> return hashbrown_hashmap.GetChildMemberWithName("table").GetChildMemberWithName("table") </del> <ins> return hashbrown_hashmap.GetChildMemberWithName("table") </ins> def has_children(self): # type: () -> bool


Question:
The states: Here, "its buffer may simply be reused" is simply meant to refer to the behavior of the underlying allocator. But I have seen people with low-level experience be misled by this into thinking that the implementation of itself has its own global allocation cache. They then thought this cache was responsible for excess memory usage in their programs. I'm not sure what the best way to clarify this would be. Part of the reason the current wording can be misleading is that "reused by another " suggests a mechanism specific to . On the other hand, it would also help to just explicitly mention the allocator. Here is a possible version that addresses both points, but it's more wordy than the current version: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I guess this also includes in-place iteration?
In-place iteration is a fancy case of type-conversion. Simpler examples are conversions to , and which also keep the allocation.
Maybe it would be more clear to say "may be reused by another allocation"? That doesn't imply it has to be a Vec that reuses the memory.
label +A-collections +C-enhancement +T-libs
claim

/// scratch space that it may use however it wants. It will generally just do /// whatever is most efficient or otherwise easy to implement. Do not rely on /// removed data to be erased for security purposes. Even if you drop a `Vec`, its <del> /// buffer may simply be reused by another `Vec`. Even if you zero a `Vec`'s memory </del> <ins> /// buffer may simply be reused by another allocation. Even if you zero a `Vec`'s memory </ins> /// first, that might not actually happen because the optimizer does not consider /// this a side-effect that must be preserved. There is one case which we will /// not break, however: using `unsafe` code to write to the excess capacity,


Question:
fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.

val } <ins> fn emit_s390x_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, list: OperandRef<'tcx, &'ll Value>, target_ty: Ty<'tcx>, ) -> &'ll Value { // Implementation of the s390x ELF ABI calling convention for va_args see // https://github.com/IBM/s390x-abi (chapter 1.2.4) let va_list_addr = list.immediate(); let va_list_layout = list.deref(bx.cx).layout; let va_list_ty = va_list_layout.llvm_type(bx); let layout = bx.cx.layout_of(target_ty); let in_reg = bx.append_sibling_block("va_arg.in_reg"); let in_mem = bx.append_sibling_block("va_arg.in_mem"); let end = bx.append_sibling_block("va_arg.end"); // FIXME: vector ABI not yet supported. let target_ty_size = bx.cx.size_of(target_ty).bytes(); let indirect: bool = target_ty_size > 8 || !target_ty_size.is_power_of_two(); let unpadded_size = if indirect { 8 } else { target_ty_size }; let padded_size = 8; let padding = padded_size - unpadded_size; let gpr_type = indirect || !layout.is_single_fp_element(bx.cx); let (max_regs, reg_count_field, reg_save_index, reg_padding) = if gpr_type { (5, 0, 2, padding) } else { (4, 1, 16, 0) }; // Check whether the value was passed in a register or in memory. let reg_count = bx.struct_gep( va_list_ty, va_list_addr, va_list_layout.llvm_field_index(bx.cx, reg_count_field), ); let reg_count_v = bx.load(bx.type_i64(), reg_count, Align::from_bytes(8).unwrap()); let use_regs = bx.icmp(IntPredicate::IntULT, reg_count_v, bx.const_u64(max_regs)); bx.cond_br(use_regs, in_reg, in_mem); // Emit code to load the value if it was passed in a register. bx.switch_to_block(in_reg); // Work out the address of the value in the register save area. let reg_ptr = bx.struct_gep(va_list_ty, va_list_addr, va_list_layout.llvm_field_index(bx.cx, 3)); let reg_ptr_v = bx.load(bx.type_i8p(), reg_ptr, bx.tcx().data_layout.pointer_align.abi); let scaled_reg_count = bx.mul(reg_count_v, bx.const_u64(8)); let reg_off = bx.add(scaled_reg_count, bx.const_u64(reg_save_index * 8 + reg_padding)); let reg_addr = bx.gep(bx.type_i8(), reg_ptr_v, &[reg_off]); // Update the register count. let new_reg_count_v = bx.add(reg_count_v, bx.const_u64(1)); bx.store(new_reg_count_v, reg_count, Align::from_bytes(8).unwrap()); bx.br(end); // Emit code to load the value if it was passed in memory. bx.switch_to_block(in_mem); // Work out the address of the value in the argument overflow area. let arg_ptr = bx.struct_gep(va_list_ty, va_list_addr, va_list_layout.llvm_field_index(bx.cx, 2)); let arg_ptr_v = bx.load(bx.type_i8p(), arg_ptr, bx.tcx().data_layout.pointer_align.abi); let arg_off = bx.const_u64(padding); let mem_addr = bx.gep(bx.type_i8(), arg_ptr_v, &[arg_off]); // Update the argument overflow area pointer. let arg_size = bx.cx().const_u64(padded_size); let new_arg_ptr_v = bx.inbounds_gep(bx.type_i8(), arg_ptr_v, &[arg_size]); bx.store(new_arg_ptr_v, arg_ptr, bx.tcx().data_layout.pointer_align.abi); bx.br(end); // Return the appropriate result. bx.switch_to_block(end); let val_addr = bx.phi(bx.type_i8p(), &[reg_addr, mem_addr], &[in_reg, in_mem]); let val_type = layout.llvm_type(bx); let val_addr = if indirect { let ptr_type = bx.cx.type_ptr_to(val_type); let ptr_addr = bx.bitcast(val_addr, bx.cx.type_ptr_to(ptr_type)); bx.load(ptr_type, ptr_addr, bx.tcx().data_layout.pointer_align.abi) } else { bx.bitcast(val_addr, bx.cx.type_ptr_to(val_type)) }; bx.load(val_type, val_addr, layout.align.abi) } </ins> pub(super) fn emit_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, addr: OperandRef<'tcx, &'ll Value>,


Question:
fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.

emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), true) } "aarch64" => emit_aapcs_va_arg(bx, addr, target_ty), <ins> "s390x" => emit_s390x_va_arg(bx, addr, target_ty), </ins> // Windows x86_64 "x86_64" if target.is_like_windows => { let target_ty_size = bx.cx.size_of(target_ty).bytes();


Question:
fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.

/// Basic implementation of a `va_list`. // The name is WIP, using `VaListImpl` for now. #[cfg(any( <del> all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")), </del> <ins> all( not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "s390x"), not(target_arch = "x86_64") ), </ins> all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), target_family = "wasm", target_arch = "asmjs",


Question:
fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.

_marker: PhantomData<&'f mut &'f c_void>, } <ins> /// s390x ABI implementation of a `va_list`. #[cfg(target_arch = "s390x")] #[repr(C)] #[derive(Debug)] #[unstable( feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on  all supported platforms", issue = "44930" )] #[lang = "va_list"] pub struct VaListImpl<'f> { gpr: i64, fpr: i64, overflow_arg_area: *mut c_void, reg_save_area: *mut c_void, _marker: PhantomData<&'f mut &'f c_void>, } </ins> /// x86_64 ABI implementation of a `va_list`. #[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))] #[repr(C)]


Question:
fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.

all( not(target_arch = "aarch64"), not(target_arch = "powerpc"), <ins> not(target_arch = "s390x"), </ins> not(target_arch = "x86_64") ), all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),


Question:
fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.

inner: VaListImpl<'f>, #[cfg(all( <del> any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"), </del> <ins> any( target_arch = "aarch64", target_arch = "powerpc", target_arch = "s390x", target_arch = "x86_64" ), </ins> any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))), not(target_family = "wasm"), not(target_arch = "asmjs"),


Question:
fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.

} #[cfg(any( <del> all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")), </del> <ins> all( not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "s390x"), not(target_arch = "x86_64") ), </ins> all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), target_family = "wasm", target_arch = "asmjs",


Question:
fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.

} #[cfg(all( <del> any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"), </del> <ins> any( target_arch = "aarch64", target_arch = "powerpc", target_arch = "s390x", target_arch = "x86_64" ), </ins> any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))), not(target_family = "wasm"), not(target_arch = "asmjs"),


Question:
EDIT(camelid): This issue is now being used to track a different, but related, bug. The discussion starting is current. <!-- 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. --- Clone . <!-- 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<summary<strongBacktrace</strong</summary<p</p</details
this is probably related to somehow. I don't plan to investigate any of the proximate issues until the underlying problem is fixed. Feel free to take a look yourself if this is blocking your work, but it won't be easy.
Oh, I guess this could also be a missed case from That should be easier to fix.
If you can come up with an MCVE it would be easier to tell which of the two issues it is.
Not exactly an MCVE, but I think I'm able to reproduce this with only a handful of files The line does change slightly though: (Same rustc version output as above). Hope this helps :). Best, Mautamu
I think the issue is that the crate is first used in a dependency, so it isn't loaded in Maybe a fix is to recursively traverse the docs of re-exports? That sounds kind of expensive, but the only other option (besides fixing ) is to revert and re-open
An easy workaround is to link to somewhere in the crate re-exporting the docs, even something like this would work:
Hmm, this setup didn't reproduce the issue, not sure why:
Maybe the proc macro is related somehow?
Regression in searched nightlies: from nightly-2021-01-01 to nightly-2021-04-24 regressed nightly: nightly-2021-04-04 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </detailsThat's , good guess,
This regression now slipped into beta 1.53.0.
came up with a slightly smaller reproduction, the proc macro wasn't related:
We've also run into this recently with a rather trivial crate
This is likely to hit stable, as no beta-accepted patch appears available at this time.
Is there an easy way to help bisect to figure out which PR to revert, or otherwise help along this issue? It’d be somewhat sad for our five-method create to not have docs even on stable.
you can use the workaround I mentioned at the top: is the PR to revert; I'm not wholly opposed to doing so but it means reintroducing other regressions. See .
This now occurs on stable and should likely be tagged , I assume.
A note to others who stumble upon this, the workaround in works great; to figure out which crate(s) you need to list, run: Look for the last log message before the panic — in my case, that was: Adding fixed the problem.
should give you a lot less logging and still show the right crate.
Further minimized from and turned into a rustdoc test form:
thanks for the reduction, that helped a lot. The problem is that rustdoc is considering each line on its own, when it should be considering the whole documentation for the item at once: When there's a reference link, rustdoc will see the link text instead of the link target: The fix is to use in instead of visiting each attribute one by one.
I experienced this same issue today on 1.56 stable despite the fix. The log followed the same pattern as above when run with . Removing this dependency fixed the problem:
can you post a link to the code that caused the ICE?
cc
reports the same issue in an open source codebase:
Also seeing this in another project in 1.56 stable. Would put together a reproducer but there already is one.
If you could minimize the crash that would be helpful, the one at the top was already fixed by
I've reduced it to Still seems a bit large but having trouble getting it any smaller. This reproducer involves I suspect that is the root cause in this case, not sure if that tracks with the other reports.
how can I build that package? running gives me even though I have gcc installed.
The dependency is macOS only. GitHub runners can do it. There is probably a way to shrink the dependency enough to build on some other platform, can look into it a bit more
Updated to ICE on windows, which I suspect is enough for linux as well. May require or
Hmm, so something strange is going on here - I example a little more, down to four local crates: If has the contents of , then the issue reproduces correctly, but if it's anything smaller, then documents fine. At first I suspected the crate hash was different or something, but cargo is passing different hashes even when and are identical, so that's not it.
FWIW you can work around the ICE with this diff:
Really interesting workaround! Those ought to be the same due to , maybe there’s some interaction there?
see
MCVE:

use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_resolve as resolve; <ins> use rustc_resolve::Namespace::TypeNS; </ins> use rustc_session::config::{self, CrateType, ErrorOutputType}; use rustc_session::lint; use rustc_session::DiagnosticOutput; use rustc_session::Session; <ins> use rustc_span::def_id::CRATE_DEF_INDEX; </ins> use rustc_span::source_map; use rustc_span::symbol::sym; <del> use rustc_span::Span; </del> <ins> use rustc_span::{Span, DUMMY_SP}; </ins> use std::cell::RefCell; use std::lazy::SyncLazy;


Question:
EDIT(camelid): This issue is now being used to track a different, but related, bug. The discussion starting is current. <!-- 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. --- Clone . <!-- 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<summary<strongBacktrace</strong</summary<p</p</details
this is probably related to somehow. I don't plan to investigate any of the proximate issues until the underlying problem is fixed. Feel free to take a look yourself if this is blocking your work, but it won't be easy.
Oh, I guess this could also be a missed case from That should be easier to fix.
If you can come up with an MCVE it would be easier to tell which of the two issues it is.
Not exactly an MCVE, but I think I'm able to reproduce this with only a handful of files The line does change slightly though: (Same rustc version output as above). Hope this helps :). Best, Mautamu
I think the issue is that the crate is first used in a dependency, so it isn't loaded in Maybe a fix is to recursively traverse the docs of re-exports? That sounds kind of expensive, but the only other option (besides fixing ) is to revert and re-open
An easy workaround is to link to somewhere in the crate re-exporting the docs, even something like this would work:
Hmm, this setup didn't reproduce the issue, not sure why:
Maybe the proc macro is related somehow?
Regression in searched nightlies: from nightly-2021-01-01 to nightly-2021-04-24 regressed nightly: nightly-2021-04-04 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </detailsThat's , good guess,
This regression now slipped into beta 1.53.0.
came up with a slightly smaller reproduction, the proc macro wasn't related:
We've also run into this recently with a rather trivial crate
This is likely to hit stable, as no beta-accepted patch appears available at this time.
Is there an easy way to help bisect to figure out which PR to revert, or otherwise help along this issue? It’d be somewhat sad for our five-method create to not have docs even on stable.
you can use the workaround I mentioned at the top: is the PR to revert; I'm not wholly opposed to doing so but it means reintroducing other regressions. See .
This now occurs on stable and should likely be tagged , I assume.
A note to others who stumble upon this, the workaround in works great; to figure out which crate(s) you need to list, run: Look for the last log message before the panic — in my case, that was: Adding fixed the problem.
should give you a lot less logging and still show the right crate.
Further minimized from and turned into a rustdoc test form:
thanks for the reduction, that helped a lot. The problem is that rustdoc is considering each line on its own, when it should be considering the whole documentation for the item at once: When there's a reference link, rustdoc will see the link text instead of the link target: The fix is to use in instead of visiting each attribute one by one.
I experienced this same issue today on 1.56 stable despite the fix. The log followed the same pattern as above when run with . Removing this dependency fixed the problem:
can you post a link to the code that caused the ICE?
cc
reports the same issue in an open source codebase:
Also seeing this in another project in 1.56 stable. Would put together a reproducer but there already is one.
If you could minimize the crash that would be helpful, the one at the top was already fixed by
I've reduced it to Still seems a bit large but having trouble getting it any smaller. This reproducer involves I suspect that is the root cause in this case, not sure if that tracks with the other reports.
how can I build that package? running gives me even though I have gcc installed.
The dependency is macOS only. GitHub runners can do it. There is probably a way to shrink the dependency enough to build on some other platform, can look into it a bit more
Updated to ICE on windows, which I suspect is enough for linux as well. May require or
Hmm, so something strange is going on here - I example a little more, down to four local crates: If has the contents of , then the issue reproduces correctly, but if it's anything smaller, then documents fine. At first I suspected the crate hash was different or something, but cargo is passing different hashes even when and are identical, so that's not it.
FWIW you can work around the ICE with this diff:
Really interesting workaround! Those ought to be the same due to , maybe there’s some interaction there?
see
MCVE:

} crate fn create_resolver<'a>( <ins> externs: config::Externs, </ins> queries: &Queries<'a>, sess: &Session, ) -> Rc<RefCell<interface::BoxedResolver>> { let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek(); let resolver = resolver.clone(); <del> crate::passes::collect_intra_doc_links::load_intra_link_crates(resolver, krate) </del> <ins> let resolver = crate::passes::collect_intra_doc_links::load_intra_link_crates(resolver, krate); // FIXME: somehow rustdoc is still missing crates even though we loaded all // the known necessary crates. Load them all unconditionally until we find a way to fix this. // DO NOT REMOVE THIS without first testing on the reproducer in // https://github.com/jyn514/objr/commit/edcee7b8124abf0e4c63873e8422ff81beb11ebb let extern_names: Vec<String> = externs .iter() .filter(|(_, entry)| entry.add_prelude) .map(|(name, _)| name) .cloned() .collect(); resolver.borrow_mut().access(|resolver| { sess.time("load_extern_crates", || { for extern_name in &extern_names { debug!("loading extern crate {}", extern_name); if let Err(()) = resolver .resolve_str_path_error( DUMMY_SP, extern_name, TypeNS, LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(), ) { warn!("unable to resolve external crate {} (do you have an unused `--extern` crate?)", extern_name) } } }); }); resolver </ins> } crate fn run_global_ctxt(


Question:
EDIT(camelid): This issue is now being used to track a different, but related, bug. The discussion starting is current. <!-- 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. --- Clone . <!-- 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<summary<strongBacktrace</strong</summary<p</p</details
this is probably related to somehow. I don't plan to investigate any of the proximate issues until the underlying problem is fixed. Feel free to take a look yourself if this is blocking your work, but it won't be easy.
Oh, I guess this could also be a missed case from That should be easier to fix.
If you can come up with an MCVE it would be easier to tell which of the two issues it is.
Not exactly an MCVE, but I think I'm able to reproduce this with only a handful of files The line does change slightly though: (Same rustc version output as above). Hope this helps :). Best, Mautamu
I think the issue is that the crate is first used in a dependency, so it isn't loaded in Maybe a fix is to recursively traverse the docs of re-exports? That sounds kind of expensive, but the only other option (besides fixing ) is to revert and re-open
An easy workaround is to link to somewhere in the crate re-exporting the docs, even something like this would work:
Hmm, this setup didn't reproduce the issue, not sure why:
Maybe the proc macro is related somehow?
Regression in searched nightlies: from nightly-2021-01-01 to nightly-2021-04-24 regressed nightly: nightly-2021-04-04 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </detailsThat's , good guess,
This regression now slipped into beta 1.53.0.
came up with a slightly smaller reproduction, the proc macro wasn't related:
We've also run into this recently with a rather trivial crate
This is likely to hit stable, as no beta-accepted patch appears available at this time.
Is there an easy way to help bisect to figure out which PR to revert, or otherwise help along this issue? It’d be somewhat sad for our five-method create to not have docs even on stable.
you can use the workaround I mentioned at the top: is the PR to revert; I'm not wholly opposed to doing so but it means reintroducing other regressions. See .
This now occurs on stable and should likely be tagged , I assume.
A note to others who stumble upon this, the workaround in works great; to figure out which crate(s) you need to list, run: Look for the last log message before the panic — in my case, that was: Adding fixed the problem.
should give you a lot less logging and still show the right crate.
Further minimized from and turned into a rustdoc test form:
thanks for the reduction, that helped a lot. The problem is that rustdoc is considering each line on its own, when it should be considering the whole documentation for the item at once: When there's a reference link, rustdoc will see the link text instead of the link target: The fix is to use in instead of visiting each attribute one by one.
I experienced this same issue today on 1.56 stable despite the fix. The log followed the same pattern as above when run with . Removing this dependency fixed the problem:
can you post a link to the code that caused the ICE?
cc
reports the same issue in an open source codebase:
Also seeing this in another project in 1.56 stable. Would put together a reproducer but there already is one.
If you could minimize the crash that would be helpful, the one at the top was already fixed by
I've reduced it to Still seems a bit large but having trouble getting it any smaller. This reproducer involves I suspect that is the root cause in this case, not sure if that tracks with the other reports.
how can I build that package? running gives me even though I have gcc installed.
The dependency is macOS only. GitHub runners can do it. There is probably a way to shrink the dependency enough to build on some other platform, can look into it a bit more
Updated to ICE on windows, which I suspect is enough for linux as well. May require or
Hmm, so something strange is going on here - I example a little more, down to four local crates: If has the contents of , then the issue reproduces correctly, but if it's anything smaller, then documents fine. At first I suspected the crate hash was different or something, but cargo is passing different hashes even when and are identical, so that's not it.
FWIW you can work around the ICE with this diff:
Really interesting workaround! Those ought to be the same due to , maybe there’s some interaction there?
see
MCVE:

let default_passes = options.default_passes; let output_format = options.output_format; // FIXME: fix this clone (especially render_options) <ins> let externs = options.externs.clone(); </ins> let manual_passes = options.manual_passes.clone(); let render_options = options.render_options.clone(); let scrape_examples_options = options.scrape_examples_options.clone();


Question:
EDIT(camelid): This issue is now being used to track a different, but related, bug. The discussion starting is current. <!-- 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. --- Clone . <!-- 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<summary<strongBacktrace</strong</summary<p</p</details
this is probably related to somehow. I don't plan to investigate any of the proximate issues until the underlying problem is fixed. Feel free to take a look yourself if this is blocking your work, but it won't be easy.
Oh, I guess this could also be a missed case from That should be easier to fix.
If you can come up with an MCVE it would be easier to tell which of the two issues it is.
Not exactly an MCVE, but I think I'm able to reproduce this with only a handful of files The line does change slightly though: (Same rustc version output as above). Hope this helps :). Best, Mautamu
I think the issue is that the crate is first used in a dependency, so it isn't loaded in Maybe a fix is to recursively traverse the docs of re-exports? That sounds kind of expensive, but the only other option (besides fixing ) is to revert and re-open
An easy workaround is to link to somewhere in the crate re-exporting the docs, even something like this would work:
Hmm, this setup didn't reproduce the issue, not sure why:
Maybe the proc macro is related somehow?
Regression in searched nightlies: from nightly-2021-01-01 to nightly-2021-04-24 regressed nightly: nightly-2021-04-04 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </detailsThat's , good guess,
This regression now slipped into beta 1.53.0.
came up with a slightly smaller reproduction, the proc macro wasn't related:
We've also run into this recently with a rather trivial crate
This is likely to hit stable, as no beta-accepted patch appears available at this time.
Is there an easy way to help bisect to figure out which PR to revert, or otherwise help along this issue? It’d be somewhat sad for our five-method create to not have docs even on stable.
you can use the workaround I mentioned at the top: is the PR to revert; I'm not wholly opposed to doing so but it means reintroducing other regressions. See .
This now occurs on stable and should likely be tagged , I assume.
A note to others who stumble upon this, the workaround in works great; to figure out which crate(s) you need to list, run: Look for the last log message before the panic — in my case, that was: Adding fixed the problem.
should give you a lot less logging and still show the right crate.
Further minimized from and turned into a rustdoc test form:
thanks for the reduction, that helped a lot. The problem is that rustdoc is considering each line on its own, when it should be considering the whole documentation for the item at once: When there's a reference link, rustdoc will see the link text instead of the link target: The fix is to use in instead of visiting each attribute one by one.
I experienced this same issue today on 1.56 stable despite the fix. The log followed the same pattern as above when run with . Removing this dependency fixed the problem:
can you post a link to the code that caused the ICE?
cc
reports the same issue in an open source codebase:
Also seeing this in another project in 1.56 stable. Would put together a reproducer but there already is one.
If you could minimize the crash that would be helpful, the one at the top was already fixed by
I've reduced it to Still seems a bit large but having trouble getting it any smaller. This reproducer involves I suspect that is the root cause in this case, not sure if that tracks with the other reports.
how can I build that package? running gives me even though I have gcc installed.
The dependency is macOS only. GitHub runners can do it. There is probably a way to shrink the dependency enough to build on some other platform, can look into it a bit more
Updated to ICE on windows, which I suspect is enough for linux as well. May require or
Hmm, so something strange is going on here - I example a little more, down to four local crates: If has the contents of , then the issue reproduces correctly, but if it's anything smaller, then documents fine. At first I suspected the crate hash was different or something, but cargo is passing different hashes even when and are identical, so that's not it.
FWIW you can work around the ICE with this diff:
Really interesting workaround! Those ought to be the same due to , maybe there’s some interaction there?
see
MCVE:

// We need to hold on to the complete resolver, so we cause everything to be // cloned for the analysis passes to use. Suboptimal, but necessary in the // current architecture. <del> let resolver = core::create_resolver(queries, sess); </del> <ins> let resolver = core::create_resolver(externs, queries, sess); </ins> if sess.has_errors() { sess.fatal("Compilation failed, aborting rustdoc");


Question:
EDIT(camelid): This issue is now being used to track a different, but related, bug. The discussion starting is current. <!-- 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. --- Clone . <!-- 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<summary<strongBacktrace</strong</summary<p</p</details
this is probably related to somehow. I don't plan to investigate any of the proximate issues until the underlying problem is fixed. Feel free to take a look yourself if this is blocking your work, but it won't be easy.
Oh, I guess this could also be a missed case from That should be easier to fix.
If you can come up with an MCVE it would be easier to tell which of the two issues it is.
Not exactly an MCVE, but I think I'm able to reproduce this with only a handful of files The line does change slightly though: (Same rustc version output as above). Hope this helps :). Best, Mautamu
I think the issue is that the crate is first used in a dependency, so it isn't loaded in Maybe a fix is to recursively traverse the docs of re-exports? That sounds kind of expensive, but the only other option (besides fixing ) is to revert and re-open
An easy workaround is to link to somewhere in the crate re-exporting the docs, even something like this would work:
Hmm, this setup didn't reproduce the issue, not sure why:
Maybe the proc macro is related somehow?
Regression in searched nightlies: from nightly-2021-01-01 to nightly-2021-04-24 regressed nightly: nightly-2021-04-04 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </detailsThat's , good guess,
This regression now slipped into beta 1.53.0.
came up with a slightly smaller reproduction, the proc macro wasn't related:
We've also run into this recently with a rather trivial crate
This is likely to hit stable, as no beta-accepted patch appears available at this time.
Is there an easy way to help bisect to figure out which PR to revert, or otherwise help along this issue? It’d be somewhat sad for our five-method create to not have docs even on stable.
you can use the workaround I mentioned at the top: is the PR to revert; I'm not wholly opposed to doing so but it means reintroducing other regressions. See .
This now occurs on stable and should likely be tagged , I assume.
A note to others who stumble upon this, the workaround in works great; to figure out which crate(s) you need to list, run: Look for the last log message before the panic — in my case, that was: Adding fixed the problem.
should give you a lot less logging and still show the right crate.
Further minimized from and turned into a rustdoc test form:
thanks for the reduction, that helped a lot. The problem is that rustdoc is considering each line on its own, when it should be considering the whole documentation for the item at once: When there's a reference link, rustdoc will see the link text instead of the link target: The fix is to use in instead of visiting each attribute one by one.
I experienced this same issue today on 1.56 stable despite the fix. The log followed the same pattern as above when run with . Removing this dependency fixed the problem:
can you post a link to the code that caused the ICE?
cc
reports the same issue in an open source codebase:
Also seeing this in another project in 1.56 stable. Would put together a reproducer but there already is one.
If you could minimize the crash that would be helpful, the one at the top was already fixed by
I've reduced it to Still seems a bit large but having trouble getting it any smaller. This reproducer involves I suspect that is the root cause in this case, not sure if that tracks with the other reports.
how can I build that package? running gives me even though I have gcc installed.
The dependency is macOS only. GitHub runners can do it. There is probably a way to shrink the dependency enough to build on some other platform, can look into it a bit more
Updated to ICE on windows, which I suspect is enough for linux as well. May require or
Hmm, so something strange is going on here - I example a little more, down to four local crates: If has the contents of , then the issue reproduces correctly, but if it's anything smaller, then documents fine. At first I suspected the crate hash was different or something, but cargo is passing different hashes even when and are identical, so that's not it.
FWIW you can work around the ICE with this diff:
Really interesting workaround! Those ought to be the same due to , maybe there’s some interaction there?
see
MCVE:

<ins> use ast::visit; </ins> use rustc_ast as ast; use rustc_hir::def::Namespace::TypeNS; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};


Question:
EDIT(camelid): This issue is now being used to track a different, but related, bug. The discussion starting is current. <!-- 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. --- Clone . <!-- 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<summary<strongBacktrace</strong</summary<p</p</details
this is probably related to somehow. I don't plan to investigate any of the proximate issues until the underlying problem is fixed. Feel free to take a look yourself if this is blocking your work, but it won't be easy.
Oh, I guess this could also be a missed case from That should be easier to fix.
If you can come up with an MCVE it would be easier to tell which of the two issues it is.
Not exactly an MCVE, but I think I'm able to reproduce this with only a handful of files The line does change slightly though: (Same rustc version output as above). Hope this helps :). Best, Mautamu
I think the issue is that the crate is first used in a dependency, so it isn't loaded in Maybe a fix is to recursively traverse the docs of re-exports? That sounds kind of expensive, but the only other option (besides fixing ) is to revert and re-open
An easy workaround is to link to somewhere in the crate re-exporting the docs, even something like this would work:
Hmm, this setup didn't reproduce the issue, not sure why:
Maybe the proc macro is related somehow?
Regression in searched nightlies: from nightly-2021-01-01 to nightly-2021-04-24 regressed nightly: nightly-2021-04-04 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </detailsThat's , good guess,
This regression now slipped into beta 1.53.0.
came up with a slightly smaller reproduction, the proc macro wasn't related:
We've also run into this recently with a rather trivial crate
This is likely to hit stable, as no beta-accepted patch appears available at this time.
Is there an easy way to help bisect to figure out which PR to revert, or otherwise help along this issue? It’d be somewhat sad for our five-method create to not have docs even on stable.
you can use the workaround I mentioned at the top: is the PR to revert; I'm not wholly opposed to doing so but it means reintroducing other regressions. See .
This now occurs on stable and should likely be tagged , I assume.
A note to others who stumble upon this, the workaround in works great; to figure out which crate(s) you need to list, run: Look for the last log message before the panic — in my case, that was: Adding fixed the problem.
should give you a lot less logging and still show the right crate.
Further minimized from and turned into a rustdoc test form:
thanks for the reduction, that helped a lot. The problem is that rustdoc is considering each line on its own, when it should be considering the whole documentation for the item at once: When there's a reference link, rustdoc will see the link text instead of the link target: The fix is to use in instead of visiting each attribute one by one.
I experienced this same issue today on 1.56 stable despite the fix. The log followed the same pattern as above when run with . Removing this dependency fixed the problem:
can you post a link to the code that caused the ICE?
cc
reports the same issue in an open source codebase:
Also seeing this in another project in 1.56 stable. Would put together a reproducer but there already is one.
If you could minimize the crash that would be helpful, the one at the top was already fixed by
I've reduced it to Still seems a bit large but having trouble getting it any smaller. This reproducer involves I suspect that is the root cause in this case, not sure if that tracks with the other reports.
how can I build that package? running gives me even though I have gcc installed.
The dependency is macOS only. GitHub runners can do it. There is probably a way to shrink the dependency enough to build on some other platform, can look into it a bit more
Updated to ICE on windows, which I suspect is enough for linux as well. May require or
Hmm, so something strange is going on here - I example a little more, down to four local crates: If has the contents of , then the issue reproduces correctly, but if it's anything smaller, then documents fine. At first I suspected the crate hash was different or something, but cargo is passing different hashes even when and are identical, so that's not it.
FWIW you can work around the ICE with this diff:
Really interesting workaround! Those ought to be the same due to , maybe there’s some interaction there?
see
MCVE:

let mut loader = IntraLinkCrateLoader { current_mod: CRATE_DEF_ID, resolver }; // `walk_crate` doesn't visit the crate itself for some reason. loader.load_links_in_attrs(&krate.attrs, krate.span); <del> ast::visit::walk_crate(&mut loader, krate); </del> <ins> visit::walk_crate(&mut loader, krate); </ins> loader.resolver }