jiebi/CodeConvo huggingface dataset:
Code change:
Adding the follow method as part of a benchmark to which exercises results in the following assembly (extracted with objdump): The ghidra decompile for the same function (comments are mine): Note the useless loop. The number of loop iterations (or rather the pointer increments) is needed to calculate the new length of the output . LLVM already manages to hoist but then it fails to eliminate the now-useless loop. The issue does not occur if one uses instead, which always results in length == 0. I tried several variations of the loop (e.g. replacing with a simple ) but it generally results in the same or worse assembly. Note: The assembly looks somewhat different if I but the decrementing loop without side-effect is still there. I assume the differences are due to LTO or some other compiler settings. Tested on commit 2020-11-21 22:46 modify labels: +I-slow
It looks like this can be solved with more ~dakka~ passes. On godbolt it can be made loop-free by adding And branchless with Using as starting point requires the same passes to be to achieve these results, i.e. it does not provide a better baseline. I failed to reproduce this improvement locally but that might be due to argument escaping issues when attempting to put the space-separated list into
Surprisingly targeting a current CPU results in only one extra pass needed to achieve the loop-free result:
Inserting one loop deletion pass directly into also results in the branchless version without having to change target-cpu or adding additional other passes. So I assume that the other passes are only needed due to the way that works.
It looks like that this removed on nightly now. On nightly: On stable:
That's only true for types because I implemented a specialization for that purpose. The suboptimal assembly still exists for types not implementing Copy, e.g. newtypes. I'll update my initial post.
Something that was is that this case also fails for - i.e. with the specialization - is when the wrapper type is
Seems to work in the other direction weirdly is optimised away, whilst is not
Is there a case here that still doesn't optimize? It looks like all the existing godbolt links do.
Looks good, I'll update the existing codegen test.

Related discussion:
text: // ignore-debug: the debug assertions get in the way // compile-flags: -O -Z merge-functions=disabled <ins> // min-llvm-version: 16 </ins> #![crate_type = "lib"] // Ensure that trivial casts of vec elements are O(1) pub struct Wrapper<T>(T); <ins> // previously repr(C) caused the optimization to fail </ins> #[repr(C)] pub struct Foo { a: u64,
Code change:
Adding the follow method as part of a benchmark to which exercises results in the following assembly (extracted with objdump): The ghidra decompile for the same function (comments are mine): Note the useless loop. The number of loop iterations (or rather the pointer increments) is needed to calculate the new length of the output . LLVM already manages to hoist but then it fails to eliminate the now-useless loop. The issue does not occur if one uses instead, which always results in length == 0. I tried several variations of the loop (e.g. replacing with a simple ) but it generally results in the same or worse assembly. Note: The assembly looks somewhat different if I but the decrementing loop without side-effect is still there. I assume the differences are due to LTO or some other compiler settings. Tested on commit 2020-11-21 22:46 modify labels: +I-slow
It looks like this can be solved with more ~dakka~ passes. On godbolt it can be made loop-free by adding And branchless with Using as starting point requires the same passes to be to achieve these results, i.e. it does not provide a better baseline. I failed to reproduce this improvement locally but that might be due to argument escaping issues when attempting to put the space-separated list into
Surprisingly targeting a current CPU results in only one extra pass needed to achieve the loop-free result:
Inserting one loop deletion pass directly into also results in the branchless version without having to change target-cpu or adding additional other passes. So I assume that the other passes are only needed due to the way that works.
It looks like that this removed on nightly now. On nightly: On stable:
That's only true for types because I implemented a specialization for that purpose. The suboptimal assembly still exists for types not implementing Copy, e.g. newtypes. I'll update my initial post.
Something that was is that this case also fails for - i.e. with the specialization - is when the wrapper type is
Seems to work in the other direction weirdly is optimised away, whilst is not
Is there a case here that still doesn't optimize? It looks like all the existing godbolt links do.
Looks good, I'll update the existing codegen test.

Related discussion:
text: d: u64, } <del> // Going from an aggregate struct to another type currently requires Copy to // enable the TrustedRandomAccess specialization. Without it optimizations do not yet // reliably recognize the loops as noop for repr(C) or non-Copy structs. </del> <ins> // implementing Copy exercises the TrustedRandomAccess specialization inside the in-place // specialization </ins> #[derive(Copy, Clone)] pub struct Bar { a: u64,
Code change:
Adding the follow method as part of a benchmark to which exercises results in the following assembly (extracted with objdump): The ghidra decompile for the same function (comments are mine): Note the useless loop. The number of loop iterations (or rather the pointer increments) is needed to calculate the new length of the output . LLVM already manages to hoist but then it fails to eliminate the now-useless loop. The issue does not occur if one uses instead, which always results in length == 0. I tried several variations of the loop (e.g. replacing with a simple ) but it generally results in the same or worse assembly. Note: The assembly looks somewhat different if I but the decrementing loop without side-effect is still there. I assume the differences are due to LTO or some other compiler settings. Tested on commit 2020-11-21 22:46 modify labels: +I-slow
It looks like this can be solved with more ~dakka~ passes. On godbolt it can be made loop-free by adding And branchless with Using as starting point requires the same passes to be to achieve these results, i.e. it does not provide a better baseline. I failed to reproduce this improvement locally but that might be due to argument escaping issues when attempting to put the space-separated list into
Surprisingly targeting a current CPU results in only one extra pass needed to achieve the loop-free result:
Inserting one loop deletion pass directly into also results in the branchless version without having to change target-cpu or adding additional other passes. So I assume that the other passes are only needed due to the way that works.
It looks like that this removed on nightly now. On nightly: On stable:
That's only true for types because I implemented a specialization for that purpose. The suboptimal assembly still exists for types not implementing Copy, e.g. newtypes. I'll update my initial post.
Something that was is that this case also fails for - i.e. with the specialization - is when the wrapper type is
Seems to work in the other direction weirdly is optimised away, whilst is not
Is there a case here that still doesn't optimize? It looks like all the existing godbolt links do.
Looks good, I'll update the existing codegen test.

Related discussion:
text: d: u64, } <ins> // this exercises the try-fold codepath pub struct Baz { a: u64, b: u64, c: u64, d: u64, } </ins> // CHECK-LABEL: @vec_iterator_cast_primitive #[no_mangle] pub fn vec_iterator_cast_primitive(vec: Vec<i8>) -> Vec<u8> {
Code change:
<!-- 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<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
It doesn't fixed in rustc 1.52.0-nightly ( 2021-02-14) link to playground : <details<summary<strongBacktrace</strong</summary<p</p</details
i dont think the fix was merged by then. it works in 1.52.0-nightly 2021-02-16 :)

Related discussion:
text: ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(), ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(), ty::Array(t, n) => { <ins> if t.is_simple_ty() { return format!("array `{}`", self).into(); } </ins> let n = tcx.lift(n).unwrap(); <del> match n.try_eval_usize(tcx, ty::ParamEnv::empty()) { _ if t.is_simple_ty() => format!("array `{}`", self).into(), Some(n) => format!("array of {} element{}", n, pluralize!(n)).into(), None => "array".into(), </del> <ins> if let ty::ConstKind::Value(v) = n.val { if let Some(n) = v.try_to_machine_usize(tcx) { return format!("array of {} element{}", n, pluralize!(n)).into(); } </ins> } <ins> "array".into() </ins> } ty::Slice(ty) if ty.is_simple_ty() => format!("slice `{}`", self).into(), ty::Slice(_) => "slice".into(),
Code change:
<!-- 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<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
It doesn't fixed in rustc 1.52.0-nightly ( 2021-02-14) link to playground : <details<summary<strongBacktrace</strong</summary<p</p</details
i dont think the fix was merged by then. it works in 1.52.0-nightly 2021-02-16 :)

Related discussion:
text: tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { <del> // see comment in const_eval_raw_provider for what we're doing here </del> <ins> // see comment in eval_to_allocation_raw_provider for what we're doing here </ins> if key.param_env.reveal() == Reveal::All { let mut key = key; key.param_env = key.param_env.with_user_facing();
Code change:
<!-- 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<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
It doesn't fixed in rustc 1.52.0-nightly ( 2021-02-14) link to playground : <details<summary<strongBacktrace</strong</summary<p</p</details
i dont think the fix was merged by then. it works in 1.52.0-nightly 2021-02-16 :)

Related discussion:
text: <ins> #![feature(const_generics, const_evaluatable_checked)] #![allow(incomplete_features)] // This test is a minimized reproduction for #79518 where // during error handling for the type mismatch we would try // to evaluate std::mem::size_of::<Self::Assoc> causing an ICE trait Foo { type Assoc: PartialEq; const AssocInstance: Self::Assoc; fn foo() where [(); std::mem::size_of::<Self::Assoc>()]: , { Self::AssocInstance == [(); std::mem::size_of::<Self::Assoc>()]; //~^ Error: mismatched types } } fn main() {} </ins>
Code change:
<!-- 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<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
It doesn't fixed in rustc 1.52.0-nightly ( 2021-02-14) link to playground : <details<summary<strongBacktrace</strong</summary<p</p</details
i dont think the fix was merged by then. it works in 1.52.0-nightly 2021-02-16 :)

Related discussion:
text: <ins> error[E0308]: mismatched types --> $DIR/issue-79518-default_trait_method_normalization.rs:16:32 | LL |         Self::AssocInstance == [(); std::mem::size_of::<Self::Assoc>()]; |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found array `[(); _]` | = note: expected associated type `<Self as Foo>::Assoc` found array `[(); _]` = help: consider constraining the associated type `<Self as Foo>::Assoc` to `[(); _]` or calling a method that returns `<Self as Foo>::Assoc` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>
Code change:
I tried this code: This should give a suggestion to reorder the keywords to , something like: Right now it gives this error, which is not very helpful: Tested on 1.48.0 and 1.50.0-nightly (2020-12-03 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Releasing assignment as I'm not really sure how to fix this at the moment. release-assignment
This could be handled directly in the parser code which generates the above diagnostic.
claim

Related discussion:
text: *self = snapshot; Err(err) } <ins> /// Get the diagnostics for the cases where `move async` is found. /// /// `move_async_span` starts at the 'm' of the move keyword and ends with the 'c' of the async keyword pub(super) fn incorrect_move_async_order_found( &self, move_async_span: Span, ) -> DiagnosticBuilder<'a> { let mut err = self.struct_span_err(move_async_span, "the order of `move` and `async` is incorrect"); err.span_suggestion_verbose( move_async_span, "try switching the order", "async move".to_owned(), Applicability::MaybeIncorrect, ); err } </ins> }
Code change:
I tried this code: This should give a suggestion to reorder the keywords to , something like: Right now it gives this error, which is not very helpful: Tested on 1.48.0 and 1.50.0-nightly (2020-12-03 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Releasing assignment as I'm not really sure how to fix this at the moment. release-assignment
This could be handled directly in the parser code which generates the above diagnostic.
claim

Related discussion:
text: self.sess.gated_spans.gate(sym::async_closure, span); } <del> let capture_clause = self.parse_capture_clause(); </del> <ins> let capture_clause = self.parse_capture_clause()?; </ins> let decl = self.parse_fn_block_decl()?; let decl_hi = self.prev_token.span; let body = match decl.output {
Code change:
I tried this code: This should give a suggestion to reorder the keywords to , something like: Right now it gives this error, which is not very helpful: Tested on 1.48.0 and 1.50.0-nightly (2020-12-03 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Releasing assignment as I'm not really sure how to fix this at the moment. release-assignment
This could be handled directly in the parser code which generates the above diagnostic.
claim

Related discussion:
text: } /// Parses an optional `move` prefix to a closure-like construct. <del> fn parse_capture_clause(&mut self) -> CaptureBy { if self.eat_keyword(kw::Move) { CaptureBy::Value } else { CaptureBy::Ref } </del> <ins> fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> { if self.eat_keyword(kw::Move) { // Check for `move async` and recover if self.check_keyword(kw::Async) { let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo); Err(self.incorrect_move_async_order_found(move_async_span)) } else { Ok(CaptureBy::Value) } } else { Ok(CaptureBy::Ref) } </ins> } /// Parses the `|arg, arg|` header of a closure.
Code change:
I tried this code: This should give a suggestion to reorder the keywords to , something like: Right now it gives this error, which is not very helpful: Tested on 1.48.0 and 1.50.0-nightly (2020-12-03 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Releasing assignment as I'm not really sure how to fix this at the moment. release-assignment
This could be handled directly in the parser code which generates the above diagnostic.
claim

Related discussion:
text: fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> { let lo = self.token.span; self.expect_keyword(kw::Async)?; <del> let capture_clause = self.parse_capture_clause(); </del> <ins> let capture_clause = self.parse_capture_clause()?; </ins> let (iattrs, body) = self.parse_inner_attrs_and_block()?; attrs.extend(iattrs); let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body);
Code change:
I tried this code: This should give a suggestion to reorder the keywords to , something like: Right now it gives this error, which is not very helpful: Tested on 1.48.0 and 1.50.0-nightly (2020-12-03 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Releasing assignment as I'm not really sure how to fix this at the moment. release-assignment
This could be handled directly in the parser code which generates the above diagnostic.
claim

Related discussion:
text: <ins> // run-rustfix // edition:2018 // Regression test for issue 79694 fn main() { let _ = async move { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect } </ins>
Code change:
I tried this code: This should give a suggestion to reorder the keywords to , something like: Right now it gives this error, which is not very helpful: Tested on 1.48.0 and 1.50.0-nightly (2020-12-03 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Releasing assignment as I'm not really sure how to fix this at the moment. release-assignment
This could be handled directly in the parser code which generates the above diagnostic.
claim

Related discussion:
text: <ins> // run-rustfix // edition:2018 // Regression test for issue 79694 fn main() { let _ = move async { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect } </ins>
Code change:
I tried this code: This should give a suggestion to reorder the keywords to , something like: Right now it gives this error, which is not very helpful: Tested on 1.48.0 and 1.50.0-nightly (2020-12-03 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Releasing assignment as I'm not really sure how to fix this at the moment. release-assignment
This could be handled directly in the parser code which generates the above diagnostic.
claim

Related discussion:
text: <ins> error: the order of `move` and `async` is incorrect --> $DIR/incorrect-move-async-order-issue-79694.rs:7:13 | LL |     let _ = move async { }; |             ^^^^^^^^^^ | help: try switching the order | LL |     let _ = async move { }; |             ^^^^^^^^^^ error: aborting due to previous error </ins>
Code change:
(Edit: Actually, being an inherent fn doesn't matter. It happens with top-level fns too.) This prints the diagnostic: The suggestion in the last line is not valid syntax (). It also emits malformed syntax if the first parameter is a or parameter. The diagnostic becomes well-formed if any of the following is done: The first parameter is changed to instead ofThe fn is not an async fn. In either case, the diagnostic correctly says: Happens on both nightly: ... and stable:
This should hopefully be a fairly straightforward patch to the diagnostics code that generates the suggestion.

Related discussion:
text: let pred = trait_ref.without_const().to_predicate(tcx).to_string(); let pred = pred.replace(&impl_trait_str, &type_param_name); let mut sugg = vec![ <ins> // Find the last of the generic parameters contained within the span of // the generics </ins> match generics .params .iter() <del> .filter(|p| match p.kind { hir::GenericParamKind::Type { synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), .. } => false, _ => true, }) .last() </del> <ins> .map(|p| p.bounds_span().unwrap_or(p.span)) .filter(|&span| generics.span.contains(span) && span.desugaring_kind().is_none()) .max_by_key(|span| span.hi()) </ins> { // `fn foo(t: impl Trait)` //        ^ suggest `<T: Trait>` here None => (generics.span, format!("<{}>", type_param)), // `fn foo<A>(t: impl Trait)` //        ^^^ suggest `<A, T: Trait>` here <del> Some(param) => ( param.bounds_span().unwrap_or(param.span).shrink_to_hi(), format!(", {}", type_param), ), </del> <ins> Some(span) => (span.shrink_to_hi(), format!(", {}", type_param)), </ins> }, // `fn foo(t: impl Trait)` //                       ^ suggest `where <T as Trait>::A: Bound`
Code change:
(Edit: Actually, being an inherent fn doesn't matter. It happens with top-level fns too.) This prints the diagnostic: The suggestion in the last line is not valid syntax (). It also emits malformed syntax if the first parameter is a or parameter. The diagnostic becomes well-formed if any of the following is done: The first parameter is changed to instead ofThe fn is not an async fn. In either case, the diagnostic correctly says: Happens on both nightly: ... and stable:
This should hopefully be a fairly straightforward patch to the diagnostics code that generates the suggestion.

Related discussion:
text: } } <ins> #[rustfmt::skip] fn baw<>(constraints: impl Iterator) { for constraint in constraints { qux(constraint); //~^ ERROR `<impl Iterator as Iterator>::Item` doesn't implement `Debug` } } </ins> fn qux(_: impl std::fmt::Debug) {} fn main() {}