Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- 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 not an RPITIT bug, for the record.

<ins> // edition:2015 // check-pass // issue: 114664 fn ice() -> impl AsRef<Fn(&())> { //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! Foo } struct Foo; impl AsRef<dyn Fn(&())> for Foo { fn as_ref(&self) -> &(dyn for<'a> Fn(&'a ()) + 'static) { todo!() } } pub fn main() {} </ins>


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- 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 not an RPITIT bug, for the record.

<ins> warning: trait objects without an explicit `dyn` are deprecated --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 | LL | fn ice() -> impl AsRef<Fn(&())> { |                        ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | fn ice() -> impl AsRef<dyn Fn(&())> { |                        +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 | LL | fn ice() -> impl AsRef<Fn(&())> { |                        ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> help: use `dyn` | LL | fn ice() -> impl AsRef<dyn Fn(&())> { |                        +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 | LL | fn ice() -> impl AsRef<Fn(&())> { |                        ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> help: use `dyn` | LL | fn ice() -> impl AsRef<dyn Fn(&())> { |                        +++ warning: 3 warnings emitted </ins>


Question:
Bug originally found by , which I've then reduced. I tried this code: I expected to see this happen: Instead, this happened: code compiles successfully and onwards modify labels: +I-unsound +regression-from-stable-to-stable -regression-untriaged This does not occur if the implied-lifetime-bounds array is in closure parameter position; so it looks like a bug w.r.t. not properly checking the closure output type implied bounds?does not help (as of )
Bisected to nightly-2022-08-10: <- looks maybe interesting
you beat me by one minute :) cc for being possible cause of this unsoundness?
WG-prioritization assigning priority (). label -I-prioritize +P-high +T-compiler -needs-triage
Oh, neat it did turn out to be a new soundness bug instead of a dupe of . Thanks for figuring out this was a regression,
for we have a terminator calling , i.e. a function which returns . This does not include the implied bounds. Checking that is WF requires proving which succeeds without checking the usable implied bounds of the trait-ref. edit: there's a bit more to this than I thought
This soundness bug is effectively only reproducible via the traits because the impls for it are builtin and so a little screwy. An attempt to write an explicit impl for the builtin impls would require an explicit bound that holds which is not present on the builtin impl. There is an assumption that all it takes for an assoc type to be wf is the where clauses on it and the impl hold, and that all arguments in the traitref are wf. The builtin impls violate this by not having the required implied bound on the impl so we end up with being able to be proven wf without proving the implied bounds. When calling we check that the fn sig of is wf which is . Before we would check the normalized signature is wf so the return type would be which would cause us to prove . Now that we check the unnormalized_ signature is wf we end up never seeing the normalized form with the which introduces the implied bound. It is generally an invariant of the type system that holding should imply also holds. The fact that can be well formed but is not, is concerning. In an ideal world proving the traits would require also proving all the implied bounds hold but right now that is not possible afaik. A simple fix (albeit hacky until we make implied bounds desugared to actual bounds) would be to make us also check not just .

return; } }; <del> let (sig, map) = tcx.instantiate_bound_regions(sig, |br| { </del> <ins> let (unnormalized_sig, map) = tcx.instantiate_bound_regions(sig, |br| { </ins> use crate::renumber::RegionCtxt; let region_ctxt_fn = || {


Question:
Bug originally found by , which I've then reduced. I tried this code: I expected to see this happen: Instead, this happened: code compiles successfully and onwards modify labels: +I-unsound +regression-from-stable-to-stable -regression-untriaged This does not occur if the implied-lifetime-bounds array is in closure parameter position; so it looks like a bug w.r.t. not properly checking the closure output type implied bounds?does not help (as of )
Bisected to nightly-2022-08-10: <- looks maybe interesting
you beat me by one minute :) cc for being possible cause of this unsoundness?
WG-prioritization assigning priority (). label -I-prioritize +P-high +T-compiler -needs-triage
Oh, neat it did turn out to be a new soundness bug instead of a dupe of . Thanks for figuring out this was a regression,
for we have a terminator calling , i.e. a function which returns . This does not include the implied bounds. Checking that is WF requires proving which succeeds without checking the usable implied bounds of the trait-ref. edit: there's a bit more to this than I thought
This soundness bug is effectively only reproducible via the traits because the impls for it are builtin and so a little screwy. An attempt to write an explicit impl for the builtin impls would require an explicit bound that holds which is not present on the builtin impl. There is an assumption that all it takes for an assoc type to be wf is the where clauses on it and the impl hold, and that all arguments in the traitref are wf. The builtin impls violate this by not having the required implied bound on the impl so we end up with being able to be proven wf without proving the implied bounds. When calling we check that the fn sig of is wf which is . Before we would check the normalized signature is wf so the return type would be which would cause us to prove . Now that we check the unnormalized_ signature is wf we end up never seeing the normalized form with the which introduces the implied bound. It is generally an invariant of the type system that holding should imply also holds. The fact that can be well formed but is not, is concerning. In an ideal world proving the traits would require also proving all the implied bounds hold but right now that is not possible afaik. A simple fix (albeit hacky until we make implied bounds desugared to actual bounds) would be to make us also check not just .

region_ctxt_fn, ) }); <del> debug!(?sig); </del> <ins> debug!(?unnormalized_sig); </ins> // IMPORTANT: We have to prove well formed for the function signature before // we normalize it, as otherwise types like `<&'a &'b () as Trait>::Assoc` // get normalized away, causing us to ignore the `'b: 'a` bound used by the function.


Question:
Bug originally found by , which I've then reduced. I tried this code: I expected to see this happen: Instead, this happened: code compiles successfully and onwards modify labels: +I-unsound +regression-from-stable-to-stable -regression-untriaged This does not occur if the implied-lifetime-bounds array is in closure parameter position; so it looks like a bug w.r.t. not properly checking the closure output type implied bounds?does not help (as of )
Bisected to nightly-2022-08-10: <- looks maybe interesting
you beat me by one minute :) cc for being possible cause of this unsoundness?
WG-prioritization assigning priority (). label -I-prioritize +P-high +T-compiler -needs-triage
Oh, neat it did turn out to be a new soundness bug instead of a dupe of . Thanks for figuring out this was a regression,
for we have a terminator calling , i.e. a function which returns . This does not include the implied bounds. Checking that is WF requires proving which succeeds without checking the usable implied bounds of the trait-ref. edit: there's a bit more to this than I thought
This soundness bug is effectively only reproducible via the traits because the impls for it are builtin and so a little screwy. An attempt to write an explicit impl for the builtin impls would require an explicit bound that holds which is not present on the builtin impl. There is an assumption that all it takes for an assoc type to be wf is the where clauses on it and the impl hold, and that all arguments in the traitref are wf. The builtin impls violate this by not having the required implied bound on the impl so we end up with being able to be proven wf without proving the implied bounds. When calling we check that the fn sig of is wf which is . Before we would check the normalized signature is wf so the return type would be which would cause us to prove . Now that we check the unnormalized_ signature is wf we end up never seeing the normalized form with the which introduces the implied bound. It is generally an invariant of the type system that holding should imply also holds. The fact that can be well formed but is not, is concerning. In an ideal world proving the traits would require also proving all the implied bounds hold but right now that is not possible afaik. A simple fix (albeit hacky until we make implied bounds desugared to actual bounds) would be to make us also check not just .

// // See #91068 for an example. self.prove_predicates( <del> sig.inputs_and_output.iter().map(|ty| { </del> <ins> unnormalized_sig.inputs_and_output.iter().map(|ty| { </ins> ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed( ty.into(), )))


Question:
Bug originally found by , which I've then reduced. I tried this code: I expected to see this happen: Instead, this happened: code compiles successfully and onwards modify labels: +I-unsound +regression-from-stable-to-stable -regression-untriaged This does not occur if the implied-lifetime-bounds array is in closure parameter position; so it looks like a bug w.r.t. not properly checking the closure output type implied bounds?does not help (as of )
Bisected to nightly-2022-08-10: <- looks maybe interesting
you beat me by one minute :) cc for being possible cause of this unsoundness?
WG-prioritization assigning priority (). label -I-prioritize +P-high +T-compiler -needs-triage
Oh, neat it did turn out to be a new soundness bug instead of a dupe of . Thanks for figuring out this was a regression,
for we have a terminator calling , i.e. a function which returns . This does not include the implied bounds. Checking that is WF requires proving which succeeds without checking the usable implied bounds of the trait-ref. edit: there's a bit more to this than I thought
This soundness bug is effectively only reproducible via the traits because the impls for it are builtin and so a little screwy. An attempt to write an explicit impl for the builtin impls would require an explicit bound that holds which is not present on the builtin impl. There is an assumption that all it takes for an assoc type to be wf is the where clauses on it and the impl hold, and that all arguments in the traitref are wf. The builtin impls violate this by not having the required implied bound on the impl so we end up with being able to be proven wf without proving the implied bounds. When calling we check that the fn sig of is wf which is . Before we would check the normalized signature is wf so the return type would be which would cause us to prove . Now that we check the unnormalized_ signature is wf we end up never seeing the normalized form with the which introduces the implied bound. It is generally an invariant of the type system that holding should imply also holds. The fact that can be well formed but is not, is concerning. In an ideal world proving the traits would require also proving all the implied bounds hold but right now that is not possible afaik. A simple fix (albeit hacky until we make implied bounds desugared to actual bounds) would be to make us also check not just .

term_location.to_locations(), ConstraintCategory::Boring, ); <del> let sig = self.normalize(sig, term_location); </del> <ins> let sig = self.normalize(unnormalized_sig, term_location); // HACK(#114936): `WF(sig)` does not imply `WF(normalized(sig))` // with built-in `Fn` implementations, since the impl may not be // well-formed itself. if sig != unnormalized_sig { self.prove_predicates( sig.inputs_and_output.iter().map(|ty| { ty::Binder::dummy(ty::PredicateKind::Clause( ty::ClauseKind::WellFormed(ty.into()), )) }), term_location.to_locations(), ConstraintCategory::Boring, ); } </ins> self.check_call_dest(body, term, &sig, *destination, *target, term_location); // The ordinary liveness rules will ensure that all


Question:
Bug originally found by , which I've then reduced. I tried this code: I expected to see this happen: Instead, this happened: code compiles successfully and onwards modify labels: +I-unsound +regression-from-stable-to-stable -regression-untriaged This does not occur if the implied-lifetime-bounds array is in closure parameter position; so it looks like a bug w.r.t. not properly checking the closure output type implied bounds?does not help (as of )
Bisected to nightly-2022-08-10: <- looks maybe interesting
you beat me by one minute :) cc for being possible cause of this unsoundness?
WG-prioritization assigning priority (). label -I-prioritize +P-high +T-compiler -needs-triage
Oh, neat it did turn out to be a new soundness bug instead of a dupe of . Thanks for figuring out this was a regression,
for we have a terminator calling , i.e. a function which returns . This does not include the implied bounds. Checking that is WF requires proving which succeeds without checking the usable implied bounds of the trait-ref. edit: there's a bit more to this than I thought
This soundness bug is effectively only reproducible via the traits because the impls for it are builtin and so a little screwy. An attempt to write an explicit impl for the builtin impls would require an explicit bound that holds which is not present on the builtin impl. There is an assumption that all it takes for an assoc type to be wf is the where clauses on it and the impl hold, and that all arguments in the traitref are wf. The builtin impls violate this by not having the required implied bound on the impl so we end up with being able to be proven wf without proving the implied bounds. When calling we check that the fn sig of is wf which is . Before we would check the normalized signature is wf so the return type would be which would cause us to prove . Now that we check the unnormalized_ signature is wf we end up never seeing the normalized form with the which introduces the implied bound. It is generally an invariant of the type system that holding should imply also holds. The fact that can be well formed but is not, is concerning. In an ideal world proving the traits would require also proving all the implied bounds hold but right now that is not possible afaik. A simple fix (albeit hacky until we make implied bounds desugared to actual bounds) would be to make us also check not just .

<ins> // <https://github.com/rust-lang/rust/issues/114936> fn whoops( s: String, f: impl for<'s> FnOnce(&'s str) -> (&'static str, [&'static &'s (); 0]), ) -> &'static str { f(&s).0 //~^ ERROR `s` does not live long enough } // <https://github.com/rust-lang/rust/issues/118876> fn extend<T>(input: &T) -> &'static T { struct Bounded<'a, 'b: 'static, T>(&'a T, [&'b (); 0]); let n: Box<dyn FnOnce(&T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, [])); n(input).0 //~^ ERROR borrowed data escapes outside of function } // <https://github.com/rust-lang/rust/issues/118876> fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T { struct Bounded<'a, 'b: 'static, T>(&'a mut T, [&'b (); 0]); let mut n: Box<dyn FnMut(&mut T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, [])); n(input).0 //~^ ERROR borrowed data escapes outside of function } fn main() {} </ins>


Question:
Bug originally found by , which I've then reduced. I tried this code: I expected to see this happen: Instead, this happened: code compiles successfully and onwards modify labels: +I-unsound +regression-from-stable-to-stable -regression-untriaged This does not occur if the implied-lifetime-bounds array is in closure parameter position; so it looks like a bug w.r.t. not properly checking the closure output type implied bounds?does not help (as of )
Bisected to nightly-2022-08-10: <- looks maybe interesting
you beat me by one minute :) cc for being possible cause of this unsoundness?
WG-prioritization assigning priority (). label -I-prioritize +P-high +T-compiler -needs-triage
Oh, neat it did turn out to be a new soundness bug instead of a dupe of . Thanks for figuring out this was a regression,
for we have a terminator calling , i.e. a function which returns . This does not include the implied bounds. Checking that is WF requires proving which succeeds without checking the usable implied bounds of the trait-ref. edit: there's a bit more to this than I thought
This soundness bug is effectively only reproducible via the traits because the impls for it are builtin and so a little screwy. An attempt to write an explicit impl for the builtin impls would require an explicit bound that holds which is not present on the builtin impl. There is an assumption that all it takes for an assoc type to be wf is the where clauses on it and the impl hold, and that all arguments in the traitref are wf. The builtin impls violate this by not having the required implied bound on the impl so we end up with being able to be proven wf without proving the implied bounds. When calling we check that the fn sig of is wf which is . Before we would check the normalized signature is wf so the return type would be which would cause us to prove . Now that we check the unnormalized_ signature is wf we end up never seeing the normalized form with the which introduces the implied bound. It is generally an invariant of the type system that holding should imply also holds. The fact that can be well formed but is not, is concerning. In an ideal world proving the traits would require also proving all the implied bounds hold but right now that is not possible afaik. A simple fix (albeit hacky until we make implied bounds desugared to actual bounds) would be to make us also check not just .

<ins> error[E0597]: `s` does not live long enough --> $DIR/check-normalized-sig-for-wf.rs:7:7 | LL |     s: String, |     - binding `s` declared here ... LL |     f(&s).0 |     --^^- |     | | |     | borrowed value does not live long enough |     argument requires that `s` is borrowed for `'static` LL | LL | } | - `s` dropped here while still borrowed error[E0521]: borrowed data escapes outside of function --> $DIR/check-normalized-sig-for-wf.rs:15:5 | LL | fn extend<T>(input: &T) -> &'static T { |              -----  - let's call the lifetime of this reference `'1` |              | |              `input` is a reference that is only valid in the function body ... LL |     n(input).0 |     ^^^^^^^^ |     | |     `input` escapes the function body here |     argument requires that `'1` must outlive `'static` error[E0521]: borrowed data escapes outside of function --> $DIR/check-normalized-sig-for-wf.rs:23:5 | LL | fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T { |               --     ----- `input` is a reference that is only valid in the function body |               | |               lifetime `'a` defined here ... LL |     n(input).0 |     ^^^^^^^^ |     | |     `input` escapes the function body here |     argument requires that `'a` must outlive `'static` error: aborting due to 3 previous errors Some errors have detailed explanations: E0521, E0597. For more information about an error, try `rustc --explain E0521`. </ins>


Question:
<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --Nearly 50% performance regression between versions 1.71 and 1.72 when copying small byte arrays with platform (Macbook Pro M1). Used to track down the regression to I tried this code: I expected to see this happen: to run about 6,200,000 ns/iter like version 1.71 Instead, this happened: 9,159,412 ns/iter <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --It most recently worked on: 1.71 More specifically nightly-2023-06-06-aarch64-apple-darwin 72 nightly-2023-06-07-aarch64-apple-darwin <!-- Provide the version you are using that has the regression. --: Searched nightlies: from nightly-2023-06-06 to nightly-2023-06-07 regressed nightly: nightly-2023-06-07 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.7</summaryHost triple: x86_64-apple-darwin Reproduce with: </details modify labels: +regression-from-stable-to-stable -regression-untriaged
Here's a demo for :
Oof, that's massively worse. But even with a nice size (), it's still a small regression: We should probably revert , or limit it to very small arrays (<= 8 bytes / 1 usize? )
The original motivation of that PR is for arrays larger than that, so I'm not so sure. If I strip this down to just the pointer write it's not as bad, but it's quite clear that the problem is just x86-isel: Is that even good instruction selection?
Hmm, curiously looking at just the part of the push logic that copies the value, the assembly is entirely reasonable: then in the context of a "real" push, it somehow still blows up:
Here's a small tweak to try to fix this for 1.73:
I've opened to track the suboptimal codegen mentioned in Once a new nightly is out, please give it a shot and reopen if you're still seeing the regression.
On Ubuntu VM running on Ryzen 5950X this is far worse: 4x regression.
Things look much better with . Thanks for the quick fix!
Thanks for confirming! I'll see if it can make 1.73.

// Vectors, even for non-power-of-two sizes, have the same layout as // arrays but don't count as aggregate types <ins> // While LLVM theoretically supports non-power-of-two sizes, and they // often work fine, sometimes x86-isel deals with them horribly // (see #115212) so for now only use power-of-two ones. </ins> if let FieldsShape::Array { count, .. } = self.layout.fields() <ins> && count.is_power_of_two() </ins> && let element = self.field(cx, 0) && element.ty.is_integral() {


Question:
<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --Nearly 50% performance regression between versions 1.71 and 1.72 when copying small byte arrays with platform (Macbook Pro M1). Used to track down the regression to I tried this code: I expected to see this happen: to run about 6,200,000 ns/iter like version 1.71 Instead, this happened: 9,159,412 ns/iter <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --It most recently worked on: 1.71 More specifically nightly-2023-06-06-aarch64-apple-darwin 72 nightly-2023-06-07-aarch64-apple-darwin <!-- Provide the version you are using that has the regression. --: Searched nightlies: from nightly-2023-06-06 to nightly-2023-06-07 regressed nightly: nightly-2023-06-07 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.7</summaryHost triple: x86_64-apple-darwin Reproduce with: </details modify labels: +regression-from-stable-to-stable -regression-untriaged
Here's a demo for :
Oof, that's massively worse. But even with a nice size (), it's still a small regression: We should probably revert , or limit it to very small arrays (<= 8 bytes / 1 usize? )
The original motivation of that PR is for arrays larger than that, so I'm not so sure. If I strip this down to just the pointer write it's not as bad, but it's quite clear that the problem is just x86-isel: Is that even good instruction selection?
Hmm, curiously looking at just the part of the push logic that copies the value, the assembly is entirely reasonable: then in the context of a "real" push, it somehow still blows up:
Here's a small tweak to try to fix this for 1.73:
I've opened to track the suboptimal codegen mentioned in Once a new nightly is out, please give it a shot and reopen if you're still seeing the regression.
On Ubuntu VM running on Ryzen 5950X this is far worse: 4x regression.
Things look much better with . Thanks for the quick fix!
Thanks for confirming! I'll see if it can make 1.73.

} #[no_mangle] <del> // CHECK-LABEL: @replace_short_array( pub fn replace_short_array(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] { </del> <ins> // CHECK-LABEL: @replace_short_array_3( pub fn replace_short_array_3(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] { </ins> // CHECK-NOT: alloca <del> // CHECK: %[[R:.+]] = load <3 x i32>, ptr %r, align 4 // CHECK: store <3 x i32> %[[R]], ptr %result // CHECK: %[[V:.+]] = load <3 x i32>, ptr %v, align 4 // CHECK: store <3 x i32> %[[V]], ptr %r </del> <ins> // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %result, ptr align 4 %r, i64 12, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %r, ptr align 4 %v, i64 12, i1 false) std::mem::replace(r, v) } #[no_mangle] // CHECK-LABEL: @replace_short_array_4( pub fn replace_short_array_4(r: &mut [u32; 4], v: [u32; 4]) -> [u32; 4] { // CHECK-NOT: alloca // CHECK: %[[R:.+]] = load <4 x i32>, ptr %r, align 4 // CHECK: store <4 x i32> %[[R]], ptr %result // CHECK: %[[V:.+]] = load <4 x i32>, ptr %v, align 4 // CHECK: store <4 x i32> %[[V]], ptr %r </ins> std::mem::replace(r, v) }


Question:
<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --Nearly 50% performance regression between versions 1.71 and 1.72 when copying small byte arrays with platform (Macbook Pro M1). Used to track down the regression to I tried this code: I expected to see this happen: to run about 6,200,000 ns/iter like version 1.71 Instead, this happened: 9,159,412 ns/iter <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --It most recently worked on: 1.71 More specifically nightly-2023-06-06-aarch64-apple-darwin 72 nightly-2023-06-07-aarch64-apple-darwin <!-- Provide the version you are using that has the regression. --: Searched nightlies: from nightly-2023-06-06 to nightly-2023-06-07 regressed nightly: nightly-2023-06-07 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.7</summaryHost triple: x86_64-apple-darwin Reproduce with: </details modify labels: +regression-from-stable-to-stable -regression-untriaged
Here's a demo for :
Oof, that's massively worse. But even with a nice size (), it's still a small regression: We should probably revert , or limit it to very small arrays (<= 8 bytes / 1 usize? )
The original motivation of that PR is for arrays larger than that, so I'm not so sure. If I strip this down to just the pointer write it's not as bad, but it's quite clear that the problem is just x86-isel: Is that even good instruction selection?
Hmm, curiously looking at just the part of the push logic that copies the value, the assembly is entirely reasonable: then in the context of a "real" push, it somehow still blows up:
Here's a small tweak to try to fix this for 1.73:
I've opened to track the suboptimal codegen mentioned in Once a new nightly is out, please give it a shot and reopen if you're still seeing the regression.
On Ubuntu VM running on Ryzen 5950X this is far worse: 4x regression.
Things look much better with . Thanks for the quick fix!
Thanks for confirming! I'll see if it can make 1.73.

// CHECK-LABEL: @swap_rgb48_manually( #[no_mangle] pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) { <del> // CHECK-NOT: alloca // CHECK: %[[TEMP0:.+]] = load <3 x i16>, ptr %x, align 2 // CHECK: %[[TEMP1:.+]] = load <3 x i16>, ptr %y, align 2 // CHECK: store <3 x i16> %[[TEMP1]], ptr %x, align 2 // CHECK: store <3 x i16> %[[TEMP0]], ptr %y, align 2 </del> <ins> // FIXME: See #115212 for why this has an alloca again // CHECK: alloca [3 x i16], align 2 // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) </ins> let temp = *x; *x = *y;


Question:
<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --Nearly 50% performance regression between versions 1.71 and 1.72 when copying small byte arrays with platform (Macbook Pro M1). Used to track down the regression to I tried this code: I expected to see this happen: to run about 6,200,000 ns/iter like version 1.71 Instead, this happened: 9,159,412 ns/iter <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --It most recently worked on: 1.71 More specifically nightly-2023-06-06-aarch64-apple-darwin 72 nightly-2023-06-07-aarch64-apple-darwin <!-- Provide the version you are using that has the regression. --: Searched nightlies: from nightly-2023-06-06 to nightly-2023-06-07 regressed nightly: nightly-2023-06-07 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.7</summaryHost triple: x86_64-apple-darwin Reproduce with: </details modify labels: +regression-from-stable-to-stable -regression-untriaged
Here's a demo for :
Oof, that's massively worse. But even with a nice size (), it's still a small regression: We should probably revert , or limit it to very small arrays (<= 8 bytes / 1 usize? )
The original motivation of that PR is for arrays larger than that, so I'm not so sure. If I strip this down to just the pointer write it's not as bad, but it's quite clear that the problem is just x86-isel: Is that even good instruction selection?
Hmm, curiously looking at just the part of the push logic that copies the value, the assembly is entirely reasonable: then in the context of a "real" push, it somehow still blows up:
Here's a small tweak to try to fix this for 1.73:
I've opened to track the suboptimal codegen mentioned in Once a new nightly is out, please give it a shot and reopen if you're still seeing the regression.
On Ubuntu VM running on Ryzen 5950X this is far worse: 4x regression.
Things look much better with . Thanks for the quick fix!
Thanks for confirming! I'll see if it can make 1.73.

// CHECK-LABEL: @swap_rgb48 #[no_mangle] pub fn swap_rgb48(x: &mut RGB48, y: &mut RGB48) { <ins> // FIXME: See #115212 for why this has an alloca again // CHECK: alloca [3 x i16], align 2 // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) swap(x, y) } type RGBA64 = [u16; 4]; // CHECK-LABEL: @swap_rgba64 #[no_mangle] pub fn swap_rgba64(x: &mut RGBA64, y: &mut RGBA64) { </ins> // CHECK-NOT: alloca <del> // CHECK: load <3 x i16> // CHECK: load <3 x i16> // CHECK: store <3 x i16> // CHECK: store <3 x i16> </del> <ins> // CHECK-DAG: %[[XVAL:.+]] = load <4 x i16>, ptr %x, align 2 // CHECK-DAG: %[[YVAL:.+]] = load <4 x i16>, ptr %y, align 2 // CHECK-DAG: store <4 x i16> %[[YVAL]], ptr %x, align 2 // CHECK-DAG: store <4 x i16> %[[XVAL]], ptr %y, align 2 </ins> swap(x, y) }


Question:
I tried this code: I expected it to compile successfully. Instead, this happened: It most recently worked on 1.72 Regressed in cc Originally reported in cc modify labels: +regression-from-stable-to-beta -regression-untriaged
WG-prioritization assigning priority (). label -I-prioritize +P-high

// needs drop. let adt_has_dtor = |adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant); <del> let res = drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false).next().is_some(); </del> <ins> let res = drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false) .filter(filter_array_elements(tcx, query.param_env)) .next() .is_some(); </ins> debug!("needs_drop_raw({:?}) = {:?}", query, res); res } <ins> /// HACK: in order to not mistakenly assume that `[PhantomData<T>; N]` requires drop glue /// we check the element type for drop glue. The correct fix would be looking at the /// entirety of the code around `needs_drop_components` and this file and come up with /// logic that is easier to follow while not repeating any checks that may thus diverge. fn filter_array_elements<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> impl Fn(&Result<Ty<'tcx>, AlwaysRequiresDrop>) -> bool { move |ty| match ty { Ok(ty) => match *ty.kind() { ty::Array(elem, _) => tcx.needs_drop_raw(param_env.and(elem)), _ => true, }, Err(AlwaysRequiresDrop) => true, } } </ins> fn has_significant_drop_raw<'tcx>( tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,


Question:
I tried this code: I expected it to compile successfully. Instead, this happened: It most recently worked on 1.72 Regressed in cc Originally reported in cc modify labels: +regression-from-stable-to-beta -regression-untriaged
WG-prioritization assigning priority (). label -I-prioritize +P-high

adt_consider_insignificant_dtor(tcx), true, ) <ins> .filter(filter_array_elements(tcx, query.param_env)) </ins> .next() .is_some(); debug!("has_significant_drop_raw({:?}) = {:?}", query, res);


Question:
I tried this code: I expected it to compile successfully. Instead, this happened: It most recently worked on 1.72 Regressed in cc Originally reported in cc modify labels: +regression-from-stable-to-beta -regression-untriaged
WG-prioritization assigning priority (). label -I-prioritize +P-high

<ins> // build-pass pub const fn f<T, const N: usize>(_: [std::mem::MaybeUninit<T>; N]) {} pub struct Blubb<T>(*const T); pub const fn g<T, const N: usize>(_: [Blubb<T>; N]) {} pub struct Blorb<const N: usize>([String; N]); pub const fn h(_: Blorb<0>) {} pub struct Wrap(Blorb<0>); pub const fn i(_: Wrap) {} fn main() {} </ins>


Question:
I tried this code: I expected to see this happen: The lint is allowed. Instead, this happened: The lint still triggers. (Applying to the entire module works). (I'm assuming that this is unintentional, thus reporting as a "bug". If this behavior is intentional, consider this a feature request to change it). Latest playground nightly:
The problem here is that the lint is associated with the private item, not the item which names it in its bounds:
cc

}; let vis = self.tcx.local_visibility(local_def_id); <del> let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); </del> let span = self.tcx.def_span(self.item_def_id.to_def_id()); let vis_span = self.tcx.def_span(def_id); if self.in_assoc_ty && !vis.is_at_least(self.required_visibility, self.tcx) { let vis_descr = match vis { ty::Visibility::Public => "public", ty::Visibility::Restricted(vis_def_id) => { <del> if vis_def_id == self.tcx.parent_module(hir_id).to_local_def_id() { </del> <ins> if vis_def_id == self.tcx.parent_module_from_def_id(local_def_id).to_local_def_id() { </ins> "private" } else if vis_def_id.is_top_level_module() { "crate-private"


Question:
I tried this code: I expected to see this happen: The lint is allowed. Instead, this happened: The lint still triggers. (Applying to the entire module works). (I'm assuming that this is unintentional, thus reporting as a "bug". If this behavior is intentional, consider this a feature request to change it). Latest playground nightly:
The problem here is that the lint is associated with the private item, not the item which names it in its bounds:
cc

}; self.tcx.emit_spanned_lint( lint, <del> hir_id, </del> <ins> self.tcx.hir().local_def_id_to_hir_id(self.item_def_id), </ins> span, PrivateInterfacesOrBoundsLint { item_span: span,


Question:
I tried this code: I expected to see this happen: The lint is allowed. Instead, this happened: The lint still triggers. (Applying to the entire module works). (I'm assuming that this is unintentional, thus reporting as a "bug". If this behavior is intentional, consider this a feature request to change it). Latest playground nightly:
The problem here is that the lint is associated with the private item, not the item which names it in its bounds:
cc

<ins> // check-pass // compile-flags: --crate-type=lib #[allow(private_bounds)] pub trait Foo: FooImpl {} trait FooImpl {} </ins>


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- 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. --: <details<summary<strongError output</strong</summary<p</p</details<!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Regression in nightly-2022-09-05 commit[0] 2022-09-03: Auto merge of - cjgillot:old-no-lt, r=estebank commit[1] 2022-09-04: Auto merge of - matthiaskrgr:rollup-9n0257m, r=matthiaskrgr commit[2] 2022-09-04: Auto merge of - nikic:update-llvm-7, r=cuviper commit[3] 2022-09-04: Auto merge of - jswrenn:transmute, r=oli-obk commit[4] 2022-09-04: Auto merge of - klensy:bump-deps-08-22, r=Dylan-DPC commit[5] 2022-09-04: Auto merge of - compiler-errors:head-span-for-enclosing-scope, r=oli-obk commit[6] 2022-09-04: Auto merge of - matthiaskrgr:rollup-uj24yb5, r=matthiaskrgr commit[7] 2022-09-04: Auto merge of - asquared31415:vec-zero-opts, r=thomcc
Minimal: This has nothing to do with the transmutability feature. Also, it's fixed by , since the above desugars to:
WG-prioritization assigning priority (). label -I-prioritize +P-medium -needs-triage
This is but needs a test. To whoever does it, please commit the example I minimized and not the other one, since we don't need to make the test depend on the transmutability feature.

<ins> // Test for issues/115517 which is fixed by pull/115486 // This should not ice trait Test<const C: usize> {} trait Elide<T> { fn call(); } pub fn test() where (): Test<{ 1 + (<() as Elide(&())>::call) }>, //~^ ERROR cannot capture late-bound lifetime in constant { } fn main() {} </ins>


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- 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. --: <details<summary<strongError output</strong</summary<p</p</details<!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Regression in nightly-2022-09-05 commit[0] 2022-09-03: Auto merge of - cjgillot:old-no-lt, r=estebank commit[1] 2022-09-04: Auto merge of - matthiaskrgr:rollup-9n0257m, r=matthiaskrgr commit[2] 2022-09-04: Auto merge of - nikic:update-llvm-7, r=cuviper commit[3] 2022-09-04: Auto merge of - jswrenn:transmute, r=oli-obk commit[4] 2022-09-04: Auto merge of - klensy:bump-deps-08-22, r=Dylan-DPC commit[5] 2022-09-04: Auto merge of - compiler-errors:head-span-for-enclosing-scope, r=oli-obk commit[6] 2022-09-04: Auto merge of - matthiaskrgr:rollup-uj24yb5, r=matthiaskrgr commit[7] 2022-09-04: Auto merge of - asquared31415:vec-zero-opts, r=thomcc
Minimal: This has nothing to do with the transmutability feature. Also, it's fixed by , since the above desugars to:
WG-prioritization assigning priority (). label -I-prioritize +P-medium -needs-triage
This is but needs a test. To whoever does it, please commit the example I minimized and not the other one, since we don't need to make the test depend on the transmutability feature.

<ins> error: cannot capture late-bound lifetime in constant --> $DIR/escaping_bound_vars.rs:11:35 | LL |     (): Test<{ 1 + (<() as Elide(&())>::call) }>, |                                  -^ |                                  | |                                  lifetime defined here error: aborting due to previous error </ins>


Question:
() never finishes building the crate (0.11.3) when building with optimizations. Regression is exactly in the LLVM 17 upgrade: <details<summaryBacktrace</summary<p</p</details modify labels: +regression-from-stable-to-nightly -regression-untriaged
WG-prioritization assigning priority (). is it clear by looking at he stacktrace what kind of code is involved that causes the issue? I'm thinking if a smaller reproducible can help. label -I-prioritize +P-high
Can reproduce also with (to skip installing the asm dependency)
Problematic IR: Based on output, it looks like we go into an infinite loop unswitching loop.
Here is a test case for :
I've filed This appears to be related to the new invariant condition injection.

<del> Subproject commit 42263494d29febc26d3c1ebdaa7b63677573ec47 </del> <ins> Subproject commit d404cba4e39df595710869988ded7cbe1104b52f </ins>


Question:
The documentation of the macro currently does not mention at all that it also accepts optional format arguments, for example: Other macros like at least have the following sentence under "Panics": So maybe it would be good to do the following? [ ] Update the "Panics" section to be similar to [ ] Extend / adjust example to also show usage of custom message <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Any ? I mostly drew from the docs for , and I also took the liberty of cleaning up some of the formatting/typography.
Thanks! To me this looks good, but I don't know what the maintainers think.

/// The difference between `unimplemented!` and [`todo!`] is that while `todo!` /// conveys an intent of implementing the functionality later and the message is "not yet /// implemented", `unimplemented!` makes no such claims. Its message is "not implemented". <del> /// Also some IDEs will mark `todo!`s. </del> <ins> /// /// Also, some IDEs will mark `todo!`s. </ins> /// /// # Panics ///


Question:
The documentation of the macro currently does not mention at all that it also accepts optional format arguments, for example: Other macros like at least have the following sentence under "Panics": So maybe it would be good to do the following? [ ] Update the "Panics" section to be similar to [ ] Extend / adjust example to also show usage of custom message <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Any ? I mostly drew from the docs for , and I also took the liberty of cleaning up some of the formatting/typography.
Thanks! To me this looks good, but I don't know what the maintainers think.

/// The difference between [`unimplemented!`] and `todo!` is that while `todo!` conveys /// an intent of implementing the functionality later and the message is "not yet /// implemented", `unimplemented!` makes no such claims. Its message is "not implemented". <del> /// Also some IDEs will mark `todo!`s. </del> <ins> /// /// Also, some IDEs will mark `todo!`s. </ins> /// /// # Panics /// <del> /// This will always [`panic!`]. </del> <ins> /// This will always [`panic!`] because `todo!` is just a shorthand for `panic!` with a /// fixed, specific message. /// /// Like `panic!`, this macro has a second form for displaying custom values. </ins> /// /// # Examples ///


Question:
The documentation of the macro currently does not mention at all that it also accepts optional format arguments, for example: Other macros like at least have the following sentence under "Panics": So maybe it would be good to do the following? [ ] Update the "Panics" section to be similar to [ ] Extend / adjust example to also show usage of custom message <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Any ? I mostly drew from the docs for , and I also took the liberty of cleaning up some of the formatting/typography.
Thanks! To me this looks good, but I don't know what the maintainers think.

/// /// ``` /// trait Foo { <del> ///     fn bar(&self); </del> <ins> ///     fn bar(&self) -> u8; </ins> ///     fn baz(&self); <ins> ///     fn qux(&self) -> Result<u64, ()>; </ins> /// } /// ``` /// /// We want to implement `Foo` on one of our types, but we also want to work on /// just `bar()` first. In order for our code to compile, we need to implement <del> /// `baz()`, so we can use `todo!`: </del> <ins> /// `baz()` and `qux()`, so we can use `todo!`: </ins> /// /// ``` /// # trait Foo { <del> /// #     fn bar(&self); </del> <ins> /// #     fn bar(&self) -> u8; </ins> /// #     fn baz(&self); <ins> /// #     fn qux(&self) -> Result<u64, ()>; </ins> /// # } /// struct MyStruct; /// /// impl Foo for MyStruct { <del> ///     fn bar(&self) { ///         // implementation goes here </del> <ins> ///     fn bar(&self) -> u8 { ///         1 + 1 </ins> ///     } /// ///     fn baz(&self) { <del> ///         // let's not worry about implementing baz() for now </del> <ins> ///         // Let's not worry about implementing baz() for now </ins> ///         todo!(); ///     } <ins> /// ///     fn qux(&self) -> Result<u64, ()> { ///         // We can add a message to todo! to display our omission. ///         // This will display: ///         // "thread 'main' panicked at 'not yet implemented: MyStruct is not yet quxable'". ///         todo!("MyStruct is not yet quxable"); ///     } </ins> /// } /// /// fn main() { ///     let s = MyStruct; ///     s.bar(); /// <del> ///     // we aren't even using baz(), so this is fine. </del> <ins> ///     // We aren't even using baz() or qux(), so this is fine. </ins> /// } /// ``` #[macro_export]


Question:
When working on Miri I noticed "portable-atomics" gets rebuilt every time I switch between a check-build and actutally running tests. This boils down to being different between the two invocations: in check builds it contains but in test builds it does not. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Cc
HEAD: ! Seems working fine here.
I'll have to try if I can till reproduce. But note that I mentioned "test build" above, so this would be vs .
Yeah I can still reproduce the problems with those invocations. (It's not the latest master but recent enough: .) Sorry for not giving the exact commands in the issue description.
I missed the tests part, sorry. I just reproduce it too. I will be working on it by the coming week. claim

cargo.arg("--all-targets"); } <del> // Enable internal lints for clippy and rustdoc // NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]` // See https://github.com/rust-lang/rust/pull/80573#issuecomment-754010776 cargo.rustflag("-Zunstable-options"); </del> let _guard = builder.msg_check(&concat!(stringify!($name), " artifacts").to_lowercase(), target); run_cargo( builder,


Question:
When working on Miri I noticed "portable-atomics" gets rebuilt every time I switch between a check-build and actutally running tests. This boils down to being different between the two invocations: in check builds it contains but in test builds it does not. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Cc
HEAD: ! Seems working fine here.
I'll have to try if I can till reproduce. But note that I mentioned "test build" above, so this would be vs .
Yeah I can still reproduce the problems with those invocations. (It's not the latest master but recent enough: .) Sorry for not giving the exact commands in the issue description.
I missed the tests part, sorry. I just reproduce it too. I will be working on it by the coming week. claim

if !features.is_empty() { cargo.arg("--features").arg(&features.join(", ")); } <ins> // Enable internal lints for clippy and rustdoc // NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]` // See https://github.com/rust-lang/rust/pull/80573#issuecomment-754010776 // // NOTE: We unconditionally set this here to avoid recompiling tools between `x check $tool` // and `x test $tool` executions. // See https://github.com/rust-lang/rust/issues/116538 cargo.rustflag("-Zunstable-options"); </ins> cargo }


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

loan_issued_at: Location, ) { let sccs = self.regioncx.constraint_sccs(); <ins> let universal_regions = self.regioncx.universal_regions(); </ins> let issuing_region_scc = sccs.scc(issuing_region); // We first handle the cases where the loan doesn't go out of scope, depending on the issuing // region's successors. for scc in sccs.depth_first_search(issuing_region_scc) { <del> // 1. Via member constraints </del> <ins> // 1. Via applied member constraints </ins> // // The issuing region can flow into the choice regions, and they are either: // - placeholders or free regions themselves, // - or also transitively outlive a free region. // <del> // That is to say, if there are member constraints here, the loan escapes the function // and cannot go out of scope. We can early return. if self.regioncx.scc_has_member_constraints(scc) { return; </del> <ins> // That is to say, if there are applied member constraints here, the loan escapes the // function and cannot go out of scope. We could early return here. // // For additional insurance via fuzzing and crater, we verify that the constraint's min // choice indeed escapes the function. In the future, we could e.g. turn this check into // a debug assert and early return as an optimization. for constraint in self.regioncx.applied_member_constraints(scc) { if universal_regions.is_universal_region(constraint.min_choice) { return; } </ins> } // 2. Via regions that are live at all points: placeholders and free regions.


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

let mut polonius_prec = PoloniusOutOfScopePrecomputer::new(body, regioncx); for (loan_idx, loan_data) in borrow_set.iter_enumerated() { let issuing_region = loan_data.region; <del> let issued_location = loan_data.reserve_location; </del> <ins> let loan_issued_at = loan_data.reserve_location; </ins> polonius_prec.precompute_loans_out_of_scope( loan_idx, issuing_region, <del> issued_location, </del> <ins> loan_issued_at, </ins> ); }


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

self.scc_universes[scc] } <del> /// Once region solving has completed, this function will return /// the member constraints that were applied to the value of a given /// region `r`. See `AppliedMemberConstraint`. pub(crate) fn applied_member_constraints(&self, r: RegionVid) -> &[AppliedMemberConstraint] { let scc = self.constraint_sccs.scc(r); </del> <ins> /// Once region solving has completed, this function will return the member constraints that /// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`. pub(crate) fn applied_member_constraints( &self, scc: ConstraintSccIndex, ) -> &[AppliedMemberConstraint] { </ins> binary_search_util::binary_search_slice( &self.member_constraints_applied, |applied| applied.member_region_scc,


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

// Member constraints can also give rise to `'r: 'x` edges that // were not part of the graph initially, so watch out for those. // (But they are extremely rare; this loop is very cold.) <del> for constraint in self.applied_member_constraints(r) { </del> <ins> for constraint in self.applied_member_constraints(self.constraint_sccs.scc(r)) { </ins> let p_c = &self.member_constraints[constraint.member_constraint_index]; let constraint = OutlivesConstraint { sup: r,


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

self.constraint_sccs.as_ref() } <del> /// Returns whether the given SCC has any member constraints. pub(crate) fn scc_has_member_constraints(&self, scc: ConstraintSccIndex) -> bool { self.member_constraints.indices(scc).next().is_some() } </del> /// Returns whether the given SCC is live at all points: whether the representative is a /// placeholder or a free region. pub(crate) fn scc_is_live_at_all_points(&self, scc: ConstraintSccIndex) -> bool {


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy, /// or future prototype. <del> #[derive(Clone, Copy, PartialEq, Hash, Debug)] </del> <ins> #[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] </ins> pub enum Polonius { /// The default value: disabled. <ins> #[default] </ins> Off, /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

Next, } <del> impl Default for Polonius { fn default() -> Self { Polonius::Off } } </del> impl Polonius { /// Returns whether the legacy version of polonius is enabled pub fn is_legacy_enabled(&self) -> bool {


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

<ins> error[E0046]: not all trait items implemented, missing: `call` --> $DIR/location-insensitive-scopes-issue-116657.rs:18:1 | LL |     fn call(x: Self) -> Self::Output; |     --------------------------------- `call` from trait ... LL | impl<T: PlusOne> Callable for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `call` in implementation error: unconstrained opaque type --> $DIR/location-insensitive-scopes-issue-116657.rs:22:19 | LL |     type Output = impl PlusOne; |                   ^^^^^^^^^^^^ | = note: `Output` must be used in combination with a concrete type within the same impl error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds --> $DIR/location-insensitive-scopes-issue-116657.rs:28:5 | LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne { |         --                     ------------ opaque type defined here |         | |         hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here LL |     <&mut i32 as Callable>::call(y) |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound | LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a { |                                             ++++ error: aborting due to 3 previous errors Some errors have detailed explanations: E0046, E0700. For more information about an error, try `rustc --explain E0046`. </ins>


Question:
File: reduced: original: Version information Command: Program output:
cc
Some notes dump: the original test fuzzed into this MCVE is . NLLs and do compute the same scopes on that original difference in scopes here is on a somewhat ambiguous case in the current implementation: the loan ultimately flows into via member constraints, not a regular outlives constraint. NLL still computes a scope for it, doesn't since it considers the loan to escape the we ignored the member constraint here and computed the scope anyways, it would result in the same results as NLLs and not trigger the assert. A handful of other tests would then fail of SCC member constraints difference between this test and these other 4 seems to me to be about applied member constraints. That is, in this test the member constraint is likely not applied, so maybe the loan should only be considered to escape via these. We had discussed this very subject before, but thought the distinction didn't matter for the purpose of computing scopes -- maybe we were wrong in these edge cases. That should be a correct fix and should work on these 5 tests. So I'll look into that next.

<ins> // This is a non-regression test for issue #116657, where NLL and `-Zpolonius=next` computed // different loan scopes when a member constraint was not ultimately applied. // revisions: nll polonius // [polonius] compile-flags: -Zpolonius=next #![feature(impl_trait_in_assoc_type)] trait Callable { type Output; fn call(x: Self) -> Self::Output; } trait PlusOne {} impl<'a> PlusOne for &'a mut i32 {} impl<T: PlusOne> Callable for T { //[nll]~^ ERROR not all trait items implemented //[polonius]~^^ ERROR not all trait items implemented type Output = impl PlusOne; //[nll]~^ ERROR unconstrained opaque type //[polonius]~^^ ERROR unconstrained opaque type } fn test<'a>(y: &'a mut i32) -> impl PlusOne { <&mut i32 as Callable>::call(y) //[nll]~^ ERROR hidden type for `impl PlusOne` captures lifetime //[polonius]~^^ ERROR hidden type for `impl PlusOne` captures lifetime } fn main() {} </ins>


Question:
File: auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Regression in nightly-2021-04-12 finding bors merge commits found 9 bors merge commits in the specified range commit[0] 2021-04-10: Auto merge of - Aaron1011:new-preexp-tests, r=petrochenkov commit[1] 2021-04-10: Auto merge of - Aaron1011:derive-invoc-order, r=petrochenkov commit[2] 2021-04-11: Auto merge of - RalfJung:liballoc-miri, r=Manishearth commit[3] 2021-04-11: Auto merge of - nagisa:nixos-patching-fix, r=Mark-Simulacrum commit[4] 2021-04-11: Auto merge of - JohnTitor:issue-, r=estebank commit[5] 2021-04-11: Auto merge of - Aaron1011:feature/final-preexp-tts, r=petrochenkov commit[6] 2021-04-11: Auto merge of - LingMan:patch-1, r=nagisa commit[7] 2021-04-11: Auto merge of - tweksteen:androidsetmessage, r=m-ou-se commit[8] 2021-04-11: Auto merge of - hyd-dev:uwtable, r=nagisa
claim
Reduced reproduction:
claim

// Parse the arguments, starting out with `self` being allowed... let (mut params, _) = self.parse_paren_comma_seq(|p| { p.recover_diff_marker(); <ins> let snapshot = p.create_snapshot_for_diagnostic(); </ins> let param = p.parse_param_general(req_name, first_param).or_else(|mut e| { e.emit(); let lo = p.prev_token.span; <ins> p.restore_snapshot(snapshot); </ins> // Skip every token until next possible arg or end. p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(Delimiter::Parenthesis)]); // Create a placeholder argument for proper arg count (issue #34264).


Question:
File: auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Regression in nightly-2021-04-12 finding bors merge commits found 9 bors merge commits in the specified range commit[0] 2021-04-10: Auto merge of - Aaron1011:new-preexp-tests, r=petrochenkov commit[1] 2021-04-10: Auto merge of - Aaron1011:derive-invoc-order, r=petrochenkov commit[2] 2021-04-11: Auto merge of - RalfJung:liballoc-miri, r=Manishearth commit[3] 2021-04-11: Auto merge of - nagisa:nixos-patching-fix, r=Mark-Simulacrum commit[4] 2021-04-11: Auto merge of - JohnTitor:issue-, r=estebank commit[5] 2021-04-11: Auto merge of - Aaron1011:feature/final-preexp-tts, r=petrochenkov commit[6] 2021-04-11: Auto merge of - LingMan:patch-1, r=nagisa commit[7] 2021-04-11: Auto merge of - tweksteen:androidsetmessage, r=m-ou-se commit[8] 2021-04-11: Auto merge of - hyd-dev:uwtable, r=nagisa
claim
Reduced reproduction:
claim

<ins> #[derive(Debug)] struct Foo { #[cfg(all())] field: fn(($),), //~ ERROR expected pattern, found `$` //~^ ERROR expected pattern, found `$` } fn main() {} </ins>


Question:
File: auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Regression in nightly-2021-04-12 finding bors merge commits found 9 bors merge commits in the specified range commit[0] 2021-04-10: Auto merge of - Aaron1011:new-preexp-tests, r=petrochenkov commit[1] 2021-04-10: Auto merge of - Aaron1011:derive-invoc-order, r=petrochenkov commit[2] 2021-04-11: Auto merge of - RalfJung:liballoc-miri, r=Manishearth commit[3] 2021-04-11: Auto merge of - nagisa:nixos-patching-fix, r=Mark-Simulacrum commit[4] 2021-04-11: Auto merge of - JohnTitor:issue-, r=estebank commit[5] 2021-04-11: Auto merge of - Aaron1011:feature/final-preexp-tts, r=petrochenkov commit[6] 2021-04-11: Auto merge of - LingMan:patch-1, r=nagisa commit[7] 2021-04-11: Auto merge of - tweksteen:androidsetmessage, r=m-ou-se commit[8] 2021-04-11: Auto merge of - hyd-dev:uwtable, r=nagisa
claim
Reduced reproduction:
claim

<ins> error: expected pattern, found `$` --> $DIR/issue-116781.rs:4:16 | LL |     field: fn(($),), |                ^ expected pattern error: expected pattern, found `$` --> $DIR/issue-116781.rs:4:16 | LL |     field: fn(($),), |                ^ expected pattern | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors </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. --We have this code in our project on commit from line 44 and beyond: I expected to see this happen: running the doctest with the following command should work (note that we modify the release profile to have lto = "fat" enabled): Instead, this happened: the program crashes, compiling the same code in a separate example and the same cargo configuration results in an executable that works. Turning LTO off also makes a doctest that compiles properly, indicating LTO is at fault or part of the problem when combined with doctests. It has been happening randomly for doctests on a lot of Rust versions but we could not identify what the issue was, looks like enabling LTO creates a miscompile where a value that is provably 0 (as it's never modified by the code) is asserted to be != 0 and crashes the program, sometimes different things error out, it looks like the program is reading at the wrong location on the stack. The value being asserted != 0 is in Unfortunately we are not able to minify this issue at the moment as it's not happening reliably across doctests. <!-- 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. --: Unfortunately on nightly (used to recover the doctest binaries via RUSTDOCFLAGS="-Z unstable-options --persist-doctests doctestbins") only exhibits the crash for the parallel version of an encryption algorithm used with rayon (on current stable we can also get the crash with a serial algorithm but we don't seem to be able to recover the doctest binary). The archive contains the for the code compiled as an example (running fine) and the code compiled as a doctest exhibiting the miscompilation, if needed I can provide the binaries, but I would understand if nobody would want to run a binary coming from a bug report. Here is a snippet of a backtrace with two threads erroring on two different issues (while there is no problem having the same code compiled as an example). <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</detailsWe have also seen some flaky doctests on x8664 and could not narrow down the issue, we have turned off LTO for all of our doctests for now and we will monitor how things evolve, the reason for the suspicion of an issue on x86 as well is that M1 builds have been running with LTO off for months and have never exhibited the flaky doctest we saw on x8664, though given the compiled code in that case is significantly different (intrinsics usage being one factor) we can't yet be sure a similar issue is happening on x8664. Cheers
have you run the tests with miri to make sure that no UB is happening?
Hello not yet, I guess it's the occasion to use it, I'll report back
Should I try it on the example reproducing the doctest or is there a way to run it on doctests ?
I forgot whether Miri runs doctests. But you can just extract the doctest into a binary and run that.
Hello no undefined behavior found by MIRI, it seems rayon does not terminate its threads so MIRI detects that but the doctest taken out as an example is UB free (I adapted our crypto parameters to be very small but still trigger the crashing doctest). Cheers
adding I-unsound as this looks like a miscompilation. The next step would be to minimize the issue and create a smaller reproducer.
agreed, for now it's a bit hard as we used to hit that a bit randomly until we identified it seemed linked to doctests + LTO, we will try to find a way to minify it, in the meantime the assembly in the original report should already contain the miscompiled code (though I understand it's likely way too big for a reasonable analysis) Cheers
FWIW, a pattern I've seen a few times with doctests + fat lto is that doctests are unoptimized, so you get optimized IR from LTO fed into the backend with disabled optimization. This can expose bugs in FastISel that we don't otherwise hit. The key to reproducing it outside doc tests may be to use an lto=fat opt-level=0 configuration.
Thanks will give it a shot, I'm surprised doctest don't honor opitmization/configuration from the Cargo profile though any reason for this? If the various parts are not supposed to have mismatched opt levels then yes I can see how some hypothesis done would break at the junction of the optimized code and unoptimized one
For the doctest as an example binary with the lto=fat opt-level=0 configuration I cannot get it to crash
setting the opt-level=0 in release allows the doctest to pass as well, so a mixing of LTO and non 0 opt level seems to trigger the issue for the doctest, trying to minimize the repro case
setting opt-level=1 in release with LTO=fat crashes the doc test
Hello again, some news, I have a state where I'm able to trigger the crash at will with a single line being uncommented. the repro branch is here MIRI is still OK on the doctest taken as an example. The interesting part is in here, the line below will cause the doctest to crash when not commented, i.e. that function call has the issue, when commented out and inlining the function (i.e. the rest of the doctest below) the execution goes well. I will attach the dump of the assembly for both. nokfunctioncall.S has both the call to the function and the inlined version okfunctioninlined.S only has the inlined version run MIRI Run doctest
still feels like the wrong part of the stack gets read in the function where a value should be a 0 and something else is read from who knows where edit: will try to minify some more
With some logging from the inlined non bugged version Edit: the "MIRI run done" was a check for the MIRI example, I share the code between both, both runs here are normal runs from the function call bugged version looks like the first iteration of a loop is fine but then the data gets corrupted here the native modulus 2^64 is encoded as 0 in a u128, so the 2^64 are valid, but the is random data and seems to be changing from run to run
looks similar in spirit to with the sensitivity to opt levels, though I'm not familiar with the mir opt level
Hello, minified the example to an iterator call returning corrupted data when a specific feature (on which the code does not depend) is enabled. Disabling said feature makes the code run properly, changing the iterator to be an immutable iter does not cause the issue () The iterator in question is a wrapping lending iterator that is defined in , immutable variant is here Available here Run the doctest and crash it : Run the doctest and does not crash : Tried to take the code out to a different repo, it did not repro Let me know if there is something more I can do, but here I can't seem to minify it anymore than that at the moment
I can reproduce the crash on aarch64-linux after also enabling the seeder_unix feature. I'm not sure how to debug though -- it doesn't seem like rustdoc has any support for that at all? does nothing and neither does . How do you even get the executable it generates? Passing to rustdoc does fix the issue, so this looks like another "passing O3 IR to O0 backend" issue.
I do the following (notice RUSTDOCFLAGS) : then and copy the only executable found in there Yes I agree with the O3 thing, I just don't quite get why rustdoc does not use the configuration from the cargo profile provided in the command line Edit: I'm guessing it's not an easy problem and there may be a reason for this
should there be a rustdoc specific bug report somewhere ? I have to say I posted here mainly because I found an old issue that looked similar
Thanks, using worked! I've used this LLVM patch () to identify as the miscompiled function. This is the extracted IR: Yes, I think that would be a good idea. I think this is probably a cargo bug, as doesn't get passed to .
Thanks a lot and great that you could find the faulty function! Alright then you advise opening an issue on to let them know of the opt level not being forwarded ?
Upstream issue: Yeah. It might be intentional, but it seems suspicious to forward but not .
WG-prioritization assigning priority (). label -I-prioritize +P-high

<del> Subproject commit febc39711a7c91560eb0f0980916ae23c343b99d </del> <ins> Subproject commit fef3d7b14ede45d051dc688aae0bb8c8b02a0566 </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'called on a value'', 'thread 'rustc' panicked at 'called on a value'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details
cc
Oh I see, nested or-patterns are usually flattened except not here because of the bindings! Fix incoming, thanks again

let specialized = pat.specialize(pcx, &ctor); for (subpat, column) in specialized.iter().zip(&mut specialized_columns) { if subpat.is_or_pat() { <del> column.patterns.extend(subpat.iter_fields()) </del> <ins> column.patterns.extend(subpat.flatten_or_pat()) </ins> } else { column.patterns.push(subpat) }


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'called on a value'', 'thread 'rustc' panicked at 'called on a value'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details
cc
Oh I see, nested or-patterns are usually flattened except not here because of the bindings! Fix incoming, thanks again

((0, 0) | (1, 0),) => {} _ => {} } <ins> // This one caused ICE https://github.com/rust-lang/rust/issues/117378 match (0u8, 0) { (x @ 0 | x @ (1 | 2), _) => {} (3.., _) => {} } </ins> }


Question:
This is a common typo I make when hoisting an inconditional let binding into the let chain to merge two let-chains that could be one. The parser only needs to do look-ahead 1 and 2 to detect the case and recover. No response No response <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim

self.error_on_extra_if(&cond)?; // Parse block, which will always fail, but we can add a nice note to the error self.parse_block().map_err(|mut err| { <del> err.span_note( cond_span, "the `if` expression is missing a block after this condition", ); </del> <ins> if self.prev_token == token::Semi && self.token == token::AndAnd && let maybe_let = self.look_ahead(1, |t| t.clone()) && maybe_let.is_keyword(kw::Let) { err.span_suggestion( self.prev_token.span, "consider removing this semicolon to parse the `let` as part of the same chain", "", Applicability::MachineApplicable, ).span_note( self.token.span.to(maybe_let.span), "you likely meant to continue parsing the let-chain starting here", ); } else { err.span_note( cond_span, "the `if` expression is missing a block after this condition", ); } </ins> err })? }


Question:
This is a common typo I make when hoisting an inconditional let binding into the let chain to merge two let-chains that could be one. The parser only needs to do look-ahead 1 and 2 to detect the case and recover. No response No response <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim

<ins> // Issue #117720 #![feature(let_chains)] fn main() { if let () = () && let () = (); //~ERROR && let () = () { } } fn foo() { if let () = () && () == (); //~ERROR && 1 < 0 { } } fn bar() { if let () = () && () == (); //~ERROR && let () = () { } } </ins>


Question:
This is a common typo I make when hoisting an inconditional let binding into the let chain to merge two let-chains that could be one. The parser only needs to do look-ahead 1 and 2 to detect the case and recover. No response No response <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim

<ins> error: expected `{`, found `;` --> $DIR/semi-in-let-chain.rs:7:23 | LL |         && let () = (); |                       ^ expected `{` | note: you likely meant to continue parsing the let-chain starting here --> $DIR/semi-in-let-chain.rs:8:9 | LL |         && let () = () |         ^^^^^^ help: consider removing this semicolon to parse the `let` as part of the same chain | LL -         && let () = (); LL +         && let () = () | error: expected `{`, found `;` --> $DIR/semi-in-let-chain.rs:15:20 | LL |         && () == (); |                    ^ expected `{` | note: the `if` expression is missing a block after this condition --> $DIR/semi-in-let-chain.rs:14:8 | LL |       if let () = () |  ________^ LL | |         && () == (); | |___________________^ error: expected `{`, found `;` --> $DIR/semi-in-let-chain.rs:23:20 | LL |         && () == (); |                    ^ expected `{` | note: you likely meant to continue parsing the let-chain starting here --> $DIR/semi-in-let-chain.rs:24:9 | LL |         && let () = () |         ^^^^^^ help: consider removing this semicolon to parse the `let` as part of the same chain | LL -         && () == (); LL +         && () == () | error: aborting due to 3 previous errors </ins>


Question:
An iterator returns None if it is empty, but Peekable's isempty is defined like this: This needs to be changed to use isnone(). In fact, the code from testpeekableis_empty() fails. It looks like this escaped detection because of a missing "#[test]"
Whoops! Feel free to submit a pull request fixing it. :)

/// Check whether peekable iterator is empty or not. #[inline] pub fn is_empty(&mut self) -> bool { <del> self.peek().is_some() </del> <ins> self.peek().is_none() </ins> } }


Question:
An iterator returns None if it is empty, but Peekable's isempty is defined like this: This needs to be changed to use isnone(). In fact, the code from testpeekableis_empty() fails. It looks like this escaped detection because of a missing "#[test]"
Whoops! Feel free to submit a pull request fixing it. :)

assert_eq!(ys, [5, 4, 3, 2, 1]); } <ins> #[test] </ins> fn test_peekable_is_empty() { let a = [1]; let mut it = a.iter().peekable();


Question:
Hi there! I encountered a weird situation when writing a device driver using . Despite getting correct temperature readings in byte form from my thermocouple converter, all readings were incorrect after casting them to floats and applying some fundamental transformations. After much confusion, I tried using instead and found it worked perfectly! However, I knew the transformations should be correct either way: I tested this exact setup and formula using Linux and the crate. That led me to test those transformations on a few different machines. Please take a look at the results below to gain better insight. Arduino Device Other machines for all below MacBook Pro M1 on macOS and Asahi Linux () Linux () macOS () Ryzen desktop machine running Linux () Milk-V Duo () I can do more if you'd like! If there's any additional context I can give, or checking to be done, please let me know, and I'll happily look into it! Also, I did check the crate to see if it was working properly! I assume that since the and ufmt_float'd are the same, it must be an issue with itself. Please see and of the original test to get more info. Thank you for taking a look at my problem!
trying to figure out if this is a regression. I see that you tested on , does it also reproduce on other versions of the rust compiler? Did you try using a stable compiler (if usable for your project)?
AVR doesn't support 64-bit floats in Rust (operations on them should end up being linker errors, though ): The fundamental issue is that AVR intrinsics (e.g. operations for i32 or f32) require a special calling convention that hasn't been yet exposed from LLVM, preventing Rust's compiler-builtins from chiming in with its own implementation. Some intrinsics (such as those for i32, u32, f32 etc.) get implemented by linking the resulting AVR binaries with (that's why working with AVR requires avr-gcc), but GCC doesn't provide implementations for f64. tl;dr f64 is not supported, but (probably) should throw a linker error instead of trying to link with compiler-builtin's implementation (because that implementation uses a different calling convention than the LLVM's codegen expects) Edit: GCC does seem to contain proper impls nowadays (, actually) - maybe LLVM gets the calling convention wrong? I'll take a look over the weekend.
Alright, got it! -- fix at: (note that merging that merge request in compiler-builtins doesn't yet solve the issue here, because then I'll need to prepare another merge request bumping compiler-builtins inside rustc - all should be ready within a few days) As for the cause - since AVRs don't have a native support for floating-point operations, those must be implemented in software; usually implementations for things like that end up in a crate called compiler-builtins (linked above), which implements them in Rust using simple bitwise operations and whatnot. There's a difference, though, between the ABI as expected by LLVM and the code that's present inside compiler-builtins - for "bigger" types (like i64, i128, f32 etc.), AVR requires a special calling convention (which defines things like "which register should contain which value") that is not yet supported by compiler-builtins (and not so easy to expose there). So instead, we pull hand-written functions ("intrinsics") from GCC's standard library (which is why avr-gcc is required as the linker) - those functions use the correct registers -- but the linking order is that stuff from compiler-builtins gets linked before GCC's, that's why those invalid intrinsics have to be commented out in compiler-builtins (so that the avr-gcc can provide its own, correct definitions). This is exactly the same case as we used to have .
Woah, thanks for the fix! Sorry for not updating this issue for a bit - my wired internet hasn't been working, so I haven't had access to my Linux machine to test this functionality. Thank you for taking the time to get it working (and explain it to me)!

[[package]] name = "compiler_builtins" <del> version = "0.1.103" </del> <ins> version = "0.1.104" </ins> source = "registry+https://github.com/rust-lang/crates.io-index" <del> checksum = "a3b73c3443a5fd2438d7ba4853c64e4c8efc2404a9e28a9234cc2d5eebc6c242" </del> <ins> checksum = "99c3f9035afc33f4358773239573f7d121099856753e1bbd2a6a5207098fc741" </ins> dependencies = [ "cc", "rustc-std-workspace-core",


Question:
Hi there! I encountered a weird situation when writing a device driver using . Despite getting correct temperature readings in byte form from my thermocouple converter, all readings were incorrect after casting them to floats and applying some fundamental transformations. After much confusion, I tried using instead and found it worked perfectly! However, I knew the transformations should be correct either way: I tested this exact setup and formula using Linux and the crate. That led me to test those transformations on a few different machines. Please take a look at the results below to gain better insight. Arduino Device Other machines for all below MacBook Pro M1 on macOS and Asahi Linux () Linux () macOS () Ryzen desktop machine running Linux () Milk-V Duo () I can do more if you'd like! If there's any additional context I can give, or checking to be done, please let me know, and I'll happily look into it! Also, I did check the crate to see if it was working properly! I assume that since the and ufmt_float'd are the same, it must be an issue with itself. Please see and of the original test to get more info. Thank you for taking a look at my problem!
trying to figure out if this is a regression. I see that you tested on , does it also reproduce on other versions of the rust compiler? Did you try using a stable compiler (if usable for your project)?
AVR doesn't support 64-bit floats in Rust (operations on them should end up being linker errors, though ): The fundamental issue is that AVR intrinsics (e.g. operations for i32 or f32) require a special calling convention that hasn't been yet exposed from LLVM, preventing Rust's compiler-builtins from chiming in with its own implementation. Some intrinsics (such as those for i32, u32, f32 etc.) get implemented by linking the resulting AVR binaries with (that's why working with AVR requires avr-gcc), but GCC doesn't provide implementations for f64. tl;dr f64 is not supported, but (probably) should throw a linker error instead of trying to link with compiler-builtin's implementation (because that implementation uses a different calling convention than the LLVM's codegen expects) Edit: GCC does seem to contain proper impls nowadays (, actually) - maybe LLVM gets the calling convention wrong? I'll take a look over the weekend.
Alright, got it! -- fix at: (note that merging that merge request in compiler-builtins doesn't yet solve the issue here, because then I'll need to prepare another merge request bumping compiler-builtins inside rustc - all should be ready within a few days) As for the cause - since AVRs don't have a native support for floating-point operations, those must be implemented in software; usually implementations for things like that end up in a crate called compiler-builtins (linked above), which implements them in Rust using simple bitwise operations and whatnot. There's a difference, though, between the ABI as expected by LLVM and the code that's present inside compiler-builtins - for "bigger" types (like i64, i128, f32 etc.), AVR requires a special calling convention (which defines things like "which register should contain which value") that is not yet supported by compiler-builtins (and not so easy to expose there). So instead, we pull hand-written functions ("intrinsics") from GCC's standard library (which is why avr-gcc is required as the linker) - those functions use the correct registers -- but the linking order is that stuff from compiler-builtins gets linked before GCC's, that's why those invalid intrinsics have to be commented out in compiler-builtins (so that the avr-gcc can provide its own, correct definitions). This is exactly the same case as we used to have .
Woah, thanks for the fix! Sorry for not updating this issue for a bit - my wired internet hasn't been working, so I haven't had access to my Linux machine to test this functionality. Thank you for taking the time to get it working (and explain it to me)!

panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } libc = { version = "0.2.150", default-features = false, features = ['rustc-dep-of-std'], public = true } <del> compiler_builtins = { version = "0.1.103" } </del> <ins> compiler_builtins = { version = "0.1.104" } </ins> profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } hashbrown = { version = "0.14", default-features = false, features = ['rustc-dep-of-std'] }