jiebi/CodeConvo huggingface dataset:
Change:
A while ago we merged the first backend pr to enable automatic differentiation in Rust: This was good enough to add and enable the config in and run . We would now like to improve the integration to also successfully run (to use Rust in our autodiff compiler explorer). and I looked into it for a while and while it seems like a simple linker issue, we didn't fully understood where it comes from and what's the best way to fix it. This commit has a few more changes (not yet upstreamed) that might help for understanding how enzyme is used We also have documentation here: Back to the issue. We first build Enzyme (a git submodule) and then try to link it. To copy Jed's observations: The code to add is in inside fn cargo. Note that linking works correctly when building normal crates. Also, I find it odd that this one line of code yields so many repeat arguments (as in, Is there a better way to link Enzyme? Should we prefer to elide Enzyme linking when it isn't needed or be more explicit with paths so it is always found? A potentially related linking error only happens under MacOS: Related Zulip issue: https://rust- Tracking:
It's not just about dist builds; this happens on any build that triggers tool builds (e.g., running would fail too). This happens because enzyme linking flags are set in the general-purpose cargo function and used in every build even when they aren't needed. changes this so that the flags are set only for the rustc build as they aren't required for other builds.
Thank you for the quick fix!

Discussion:
// killed, rather than having an error bubble up and cause a panic. cargo.rustflag("-Zon-broken-pipe=kill"); <ins> if builder.config.llvm_enzyme { cargo.rustflag("-l").rustflag("Enzyme-19"); } </ins> // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary // and may just be a time sink. if compiler.stage != 0 {

rustflags.arg(sysroot_str); } <del> // https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/.E2.9C.94.20link.20new.20library.20into.20stage1.2Frustc if self.config.llvm_enzyme { rustflags.arg("-l"); rustflags.arg("Enzyme-19"); } </del> let use_new_symbol_mangling = match self.config.rust_new_symbol_mangling { Some(setting) => { // If an explicit setting is given, use that
Change:
On this test failed, then passed, then failed. That PR modified rustccodegenllvm, so maybe it's a problem with the PR, but... On the test failed as well. And LLVM update should have no impact on the llvm-19 job, so this is an unrelated failure. <details</detailsTest:
Also failed in and
We should remove this test and reopen the issue, especially if it's true that nobody understands why the codegen improved:
"Nobody understands" as in "nobody bothered to run a bisect". This test has been consistently passing with our own LLVM 19 builds, so it's pretty weird that it fails with Ubuntu's.
is it possible that a commit was merged in the past... uhh... 5 months that fixed a behavior that affects this? I think that Ubuntu's LLVM 19 may actually be a snapshot from April.
That would certainly be bad -- where did you find that it is from April? It looks like Ubuntu 24.10 has the final release since yesterday: I can't find a history on their website though. Possibly just regenerating the docker image will fix this issue.
The log from has: So the docker image should currently have rc4, which is close to what our fork currently uses.
ah, I misunderstood something, then. I was looking at their "llvm-toolchain-snapshot" and trying to figure out its relationships to their other llvm repos and which branch would be in use: and I was having trouble finding the version string in the log, too. it seems it isn't always printed?
I've tried running this test in a loop in the x86_64-gnu-llvm-19 docker container and it never failed :( So no idea what's going on here.
Yes, I tried similar antics right before I put up the PR to remove it. I actually probably would have left it if I could have reproduced a failure, because then I'd have any hope of it actually being solved by anything except magic.

Discussion:
<del> //@ compile-flags: -O // This regress since Rust version 1.72. //@ min-llvm-version: 18.1.4 #![crate_type = "lib"] use std::convert::TryInto; const N: usize = 24; // CHECK-LABEL: @example // CHECK-NOT: unwrap_failed #[no_mangle] pub fn example(a: Vec<u8>) -> u8 { if a.len() != 32 { return 0; } let a: [u8; 32] = a.try_into().unwrap(); a[15] + a[N] } </del>
Change:
<!-- [31mICE[0m: Rustc '-Zvalidate-mir -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in Item(DefId(0:7 ~ a[e8bd]::hello)) (after pass CheckPackedRef) at bb3[6]:'', 'thread 'rustc' panicked at 'broken MIR in Item(DefId(0:7 ~ a[e8bd]::hello)) (after pass CheckPackedRef) at bb3[6]:'' 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<!-- query stack: [mirbuilt] building MIR for [hasffiunwindcalls] checking if contains FFI-unwind calls --
another one from rust #![feature(typealiasimpltrait)] fn rpit() -impl Sized {} pub type Tait = impl Sized; pub fn foo() -Box<dyn std::future::Future<Output = Tait{ Box::new(async { let out: Tait = rpit(); _out }) } ``
another one that is a bit smaller than the original example:

Discussion:
&self, pred: impl Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>, ) -> bool { <ins> let pred: ty::Predicate<'tcx> = pred.upcast(self.tcx); // We sometimes have to use `defining_opaque_types` for predicates // to succeed here and figuring out how exactly that should work // is annoying. It is harmless enough to just not validate anything // in that case. We still check this after analysis as all opaque // types have been revealed at this point. if pred.has_opaque_types() { return true; } </ins> let infcx = self.tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new(

<del> //@ known-bug: #130921 //@ compile-flags: -Zvalidate-mir -Copt-level=0 --crate-type lib pub fn hello() -> [impl Sized; 2] { if false { let x = hello(); let _: &[i32] = &x; } todo!() } </del>

<ins> //@ check-pass //@ compile-flags: -Zvalidate-mir fn hello() -> &'static [impl Sized; 0] { if false { let x = hello(); let _: &[i32] = x; } &[] } fn main() {} </ins>
Change:
After I noticed that whenever I modify tests (on Windows), stage 1 cargo gets unnecessary rebuilt which also triggers rebuilds for other tools like stage 0 rustdoc. I'm pretty sure something in my implementation is wrong w.r.t. to properly caching, but I didn't invest time in figuring out why yet, hence opening this bug to track it. The build sequence is something like stage 0 std -stage 1 rustc -stage 1 std -stage 1 tool cargo -stage 0 compiletest / run-make-support / rustdoc. Example repro steps: Run -make sure stage 1 cargo is already built. Modify a test. Observe that stage 1 cargo gets rebuilt even though I didn't modify it.
EDIT: oh, is it because in run-make-support or rustdoc we use or something that is a different staged cargo compared to the one we built with stage 1 rustc...
Actually unassigning because I don't know how to cleanly fix this just yet. EDIT: opened thread https://rust-
Running twice is enough to reproduce cargo rebuild issue. Probably some rustflags invalidating the build cache.
Reopening because we need to revert in favor of a different approach.

Discussion:
cargo.rustdocflag("-Zcrate-attr=warn(rust_2018_idioms)"); <del> // If the rustc output is piped to e.g. `head -n1` we want the process to be // killed, rather than having an error bubble up and cause a panic. cargo.rustflag("-Zon-broken-pipe=kill"); </del> if builder.config.llvm_enzyme { cargo.rustflag("-l").rustflag("Enzyme-19"); }

cargo.arg("--features").arg(features.join(", ")); } <ins> // Warning: be very careful with RUSTFLAGS or command-line options, as conditionally applied // RUSTFLAGS or cli flags can lead to hard-to-diagnose rebuilds due to flag differences, causing // previous tool build artifacts to get invalidated. </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

// See https://github.com/rust-lang/rust/issues/116538 cargo.rustflag("-Zunstable-options"); <del> // `-Zon-broken-pipe=kill` breaks cargo tests if !path.ends_with("cargo") { // If the output is piped to e.g. `head -n1` we want the process to be killed, // rather than having an error bubble up and cause a panic. cargo.rustflag("-Zon-broken-pipe=kill"); } </del> cargo }
Change:
! Compare e..g , where the button correctly produces in the clipboard, with , where it currently gives me instead! I would guess, this is a change that came with the redesign in , though I haven’t checked to confirm that. This only happen with modules; things like structs, macros, type synonyms… als seem to work correctly. cc label +T-rustdoc +T-rustdoc-frontend +A-rustdoc-ui <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Most pages have the title - but modules don't have this, so the title of the page is just appended to . claim

Discussion:
return; } but.onclick = () => { <del> const path = []; onEachLazy(document.querySelectorAll(".rustdoc-breadcrumbs a"), a => { path.push(a.textContent); }); path.push(document.querySelector("title").textContent.split(" ")[0]); </del> <ins> // Most page titles are '<Item> in <path::to::module> - Rust', except // modules (which don't have the first part) and keywords/primitives // (which don't have a module path) const title = document.querySelector("title").textContent.replace(" - Rust", ""); const [item, module] = title.split(" in "); const path = [item]; if (module !== undefined) { path.unshift(module); } </ins> copyContentToClipboard(path.join("::")); copyButtonAnimation(but);
Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: always panic Instead, this happened: only -Zmir-opt-level=2 panic For mir-opt-level 0, 1 and 3, they all normally return <!-- 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. --: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
equals , so I think the panic case is incorrect?
Yeah, I think so.
Looks like it's JumpThreading that incorrectly removes the condition
I managed to create an example without panic, just wrong value
Most likely
ha, I found the bug. We're optimizing incorrectly in the jump threading code. Right now it's only written to handle bool correctly. I'll put up a fix claim

Discussion:
} // Transfer the conditions on the copy rhs, after inversing polarity. Rvalue::UnaryOp(UnOp::Not, Operand::Move(place) | Operand::Copy(place)) => { <ins> if !place.ty(self.body, self.tcx).ty.is_bool() { // Constructing the conditions by inverting the polarity // of equality is only correct for bools. That is to say, // `!a == b` is not `a != b` for integers greater than 1 bit. return; } </ins> let Some(conditions) = state.try_get_idx(lhs, &self.map) else { return }; let Some(place) = self.map.find(place.as_ref()) else { return }; <ins> // FIXME: I think This could be generalized to not bool if we // actually perform a logical not on the condition's value. </ins> let conds = conditions.map(self.arena, Condition::inv); state.insert_value_idx(place, conds, &self.map); }

<ins> - // MIR for `bitwise_not` before JumpThreading + // MIR for `bitwise_not` after JumpThreading fn bitwise_not() -> i32 { let mut _0: i32; let mut _1: i32; let mut _2: bool; let mut _3: i32; let mut _4: i32; scope 1 { debug a => _1; } bb0: { StorageLive(_1); _1 = const 0_i32; _1 = const 1_i32; StorageLive(_2); StorageLive(_3); StorageLive(_4); _4 = copy _1; _3 = Not(move _4); StorageDead(_4); _2 = Eq(move _3, const 0_i32); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { StorageDead(_3); _0 = const 1_i32; goto -> bb3; } bb2: { StorageDead(_3); _0 = const 0_i32; goto -> bb3; } bb3: { StorageDead(_2); StorageDead(_1); return; } } </ins>

if x == 0.0 { 0 } else { 1 } } <ins> pub fn bitwise_not() -> i32 { // CHECK-LABEL: fn bitwise_not( // CHECK: switchInt( // Test for #131195, which was optimizing `!a == b` into `a != b`. let mut a: i32 = 0; a = 1; if !a == 0 { 1 } else { 0 } } </ins> fn main() { // CHECK-LABEL: fn main( too_complex(Ok(0));

// EMIT_MIR jump_threading.assume.JumpThreading.diff // EMIT_MIR jump_threading.aggregate_copy.JumpThreading.diff // EMIT_MIR jump_threading.floats.JumpThreading.diff <ins> // EMIT_MIR jump_threading.bitwise_not.JumpThreading.diff </ins>
Change:
Using , running causes bootstrap to rebuild all of std before running the tests, even when the build cache ought to be warm from a previous . Needless to say, this is not very fun when actually trying to run one or more mir-opt tests.
cc
I will note that does seem to avoid the rebuild when re-running the tests.
Is there some way for CI to error on spurious rebuilds? I don't know what that would look like but this has happened in a few different places for different reasons so it'd be nice if there were some way to catch it early.
Usually the spurious rebuilds happen if you try to run the same command, twice. I don't think that's very tractable for CI, but am happy to be proven wrong. Maybe we can try to devise some kind of mechanism in bootstrap to make some invalidations impossible, but I don't know how such a mechanism would work in general.
One mechanism for that would be to keep the rustflags logic in a single sealed module, so they can't be set externally from the individual build steps, which means they can't invalidate the build cache. Next to that approach we can add test coverage to rustflags logic.
I opened a short-term immediate fix in , but the long term solution to prevent resurrgence of -induced invalidation is a proper prevention mechanism as described above.
Also this one actually builds same stage std twice for host if host == target (i.e. not cross-compile) because std was 'd twice with differing . The double std build was the dead giveaway that fortunately makes it very easy to tell what the rebuild was caused by.

Discussion:
builder.ensure(TestHelpers { target: compiler.host }); // ensure that `libproc_macro` is available on the host. <del> builder.ensure(compile::Std::new(compiler, compiler.host)); </del> <ins> if suite == "mir-opt" { builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, compiler.host)); } else { builder.ensure(compile::Std::new(compiler, compiler.host)); } </ins> // As well as the target if suite != "mir-opt" {
Change:
I tried : I expected to see this happen: nothing Instead, this happened: rustfmt reorders and incorrectly...
cc I imagine this blocks stabilization.
Ah, I definitely forgot to reorder these bounds after we settled the ordering.

Discussion:
ast::GenericBound::Trait(ref poly_trait_ref) => { let snippet = context.snippet(self.span()); let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); <del> let ast::TraitBoundModifiers { constness, asyncness, polarity, } = poly_trait_ref.modifiers; let mut constness = constness.as_str().to_string(); if !constness.is_empty() { constness.push(' '); } let mut asyncness = asyncness.as_str().to_string(); if !asyncness.is_empty() { asyncness.push(' '); } let polarity = polarity.as_str(); let shape = shape .offset_left(constness.len() + polarity.len()) .max_width_error(shape.width, self.span())?; </del> poly_trait_ref .rewrite_result(context, shape) <del> .map(|s| format!("{constness}{asyncness}{polarity}{s}")) </del> .map(|s| if has_paren { format!("({})", s) } else { s }) } ast::GenericBound::Use(ref args, span) => {

} fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { <del> if let Some(lifetime_str) = rewrite_bound_params(context, shape, &self.bound_generic_params) </del> <ins> let (binder, shape) = if let Some(lifetime_str) = rewrite_bound_params(context, shape, &self.bound_generic_params) </ins> { // 6 is "for<> ".len() let extra_offset = lifetime_str.len() + 6; let shape = shape .offset_left(extra_offset) .max_width_error(shape.width, self.span)?; <del> let path_str = self.trait_ref.rewrite_result(context, shape)?; Ok(format!("for<{lifetime_str}> {path_str}")) </del> <ins> (format!("for<{lifetime_str}> "), shape) </ins> } else { <del> self.trait_ref.rewrite_result(context, shape) </del> <ins> (String::new(), shape) }; let ast::TraitBoundModifiers { constness, asyncness, polarity, } = self.modifiers; let mut constness = constness.as_str().to_string(); if !constness.is_empty() { constness.push(' '); </ins> } <ins> let mut asyncness = asyncness.as_str().to_string(); if !asyncness.is_empty() { asyncness.push(' '); } let polarity = polarity.as_str(); let shape = shape .offset_left(constness.len() + polarity.len()) .max_width_error(shape.width, self.span)?; let path_str = self.trait_ref.rewrite_result(context, shape)?; Ok(format!( "{binder}{constness}{asyncness}{polarity}{path_str}" )) </ins> } }

// rustfmt-edition: 2018 fn foo() -> impl async Fn() {} <ins> fn bar() -> impl for<'a> async Fn(&'a ()) {} </ins>
Change:
<!-- [31mICE[0m: 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<!-- query stack: [resolverforlowering_raw] getting the resolver for lowering --
mvce
bisects to cc ^^'

Discussion:
} mis.iter().fold(true, |res, mi| { <del> let mut mi = mi.meta_item().unwrap().clone(); </del> <ins> let Some(mut mi) = mi.meta_item().cloned() else { dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: mi.span(), }); return false; }; </ins> if let [seg, ..] = &mut mi.path.segments[..] { seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name)); }

//~^ ERROR invalid predicate `target_pointer` fn three() {} <ins> #[cfg(target(true))] //~^ ERROR `cfg` predicate key must be an identifier fn four() {} </ins> fn main() {}

LL | #[cfg(target(os = "linux", pointer(width = "64")))] |                            ^^^^^^^^^^^^^^^^^^^^^ <del> error: aborting due to 3 previous errors </del> <ins> error: `cfg` predicate key must be an identifier --> $DIR/cfg-target-compact-errors.rs:17:14 | LL | #[cfg(target(true))] |              ^^^^ error: aborting due to 4 previous errors </ins> Some errors have detailed explanations: E0537, E0565. For more information about an error, try `rustc --explain E0537`.
Change:
Their continued existence in the tutorial is causing confusion over what the status of this feature is. Let all the world know that managed pointers are relegated to the dustbin of history!
It's unclear to me if the tutorial is being rewritten from scratch by Mozilla. There's not much motivation for anyone to work on it if it's just going to be thrown out.
That may be true, but if a good samaritan wanted to do just enough work to delete mentions of them from the current tutorial, it would not be unappreciated.
Hi, I am the one who asked about this initially. I have started to work on it now.
At this point I do think it's worthwhile to keep maintaining the tutorial. Even if it doesn't survive as the tutorial, it does contain a lot of information that will end up disseminated elsewhere.
Not maintaining the tutorial leads to a growing collection of inaccurate or wrong information. Removing it could give newcomers a better first-time experience of Rust.

Discussion:
# struct Point { x: f64, y: f64 } # enum Shape { Rectangle(Point, Point) } # impl Shape { fn area(&self) -> int { 0 } } <del> let start = @Point { x: 10.0, y: 20.0 }; </del> <ins> let start = ~Point { x: 10.0, y: 20.0 }; </ins> let end = ~Point { x: (*start).x + 100.0, y: (*start).y + 100.0 }; let rect = &Rectangle(*start, *end); let area = (*rect).area();

# struct Point { x: f64, y: f64 } # enum Shape { Rectangle(Point, Point) } # impl Shape { fn area(&self) -> int { 0 } } <del> let start = @Point { x: 10.0, y: 20.0 }; </del> <ins> let start = ~Point { x: 10.0, y: 20.0 }; </ins> let end = ~Point { x: start.x + 100.0, y: start.y + 100.0 }; let rect = &Rectangle(*start, *end); let area = rect.area();

~~~ # struct Point { x: f64, y: f64 } <del> let point = &@~Point { x: 10.0, y: 20.0 }; </del> <ins> let point = &~Point { x: 10.0, y: 20.0 }; </ins> println!("{:f}", point.x); ~~~

// As with typical function arguments, owned pointers // are automatically converted to references <del> (@s).draw_reference(); </del> (~s).draw_reference(); // Unlike typical function arguments, the self value will

(& &s).draw_reference(); // ... and dereferenced and borrowed <del> (&@~s).draw_reference(); </del> <ins> (&~s).draw_reference(); </ins> ~~~ Implementations may also define standalone (sometimes called "static")

only be referred to via one of the pointer types. Other pointer types work as well. Casts to traits may only be done with compatible pointers so, <del> for example, an `@Circle` may not be cast to an `~Drawable`. </del> <ins> for example, an `&Circle` may not be cast to an `~Drawable`. </ins> ~~~ # type Circle = int; type Rectangle = int;

# impl Circle for CircleStruct { fn radius(&self) -> f64 { (self.area() / PI).sqrt() } } # impl Shape for CircleStruct { fn area(&self) -> f64 { PI * square(self.radius) } } <del> let concrete = @CircleStruct{center:Point{x:3.0,y:4.0},radius:5.0}; let mycircle: @Circle = concrete as @Circle; </del> <ins> let concrete = ~CircleStruct{center:Point{x:3.0,y:4.0},radius:5.0}; let mycircle: ~Circle = concrete as ~Circle; </ins> let nonsense = mycircle.radius() * mycircle.area(); ~~~
Change:
We should be publishing a "default" local- file on rust- (or, at minimum, our github repo for now). When you run cargo for the first time it should fetch this if it hasn't got a local- file, and there should be a "cargo init" command or something that re-fetches this default.
handles this.
Looks like it doesn't auto-fetch yet.

Discussion:
ret; } <ins> let lib = c.libdir; let bin = c.bindir; </ins> let target = c.opts.free[2u]; // FIXME: needs stronger pattern matching <ins> // FIXME: needs to uninstall from a specified location in a cache instead // of looking for it (binaries can be uninstalled by name only) </ins> if is_uuid(target) { <del> for os::list_dir(c.libdir).each { |file| </del> <ins> for os::list_dir(lib).each { |file| </ins> alt str::find_str(file, "-" + target + "-") { some(idx) { <del> let full = path::normalize(path::connect(c.libdir, file)); </del> <ins> let full = path::normalize(path::connect(lib, file)); </ins> if os::remove_file(full) { info("uninstalled: '" + full + "'"); } else {

error("can't find package with uuid: " + target); } else { <del> for os::list_dir(c.libdir).each { |file| </del> <ins> for os::list_dir(lib).each { |file| </ins> alt str::find_str(file, "lib" + target + "-") { some(idx) { <del> let full = path::normalize(path::connect(c.libdir, file)); </del> <ins> let full = path::normalize(path::connect(lib, file)); if os::remove_file(full) { info("uninstalled: '" + full + "'"); } else { error("could not uninstall: '" + full + "'"); } ret; } none { cont; } } } for os::list_dir(bin).each { |file| alt str::find_str(file, target) { some(idx) { let full = path::normalize(path::connect(bin, file)); </ins> if os::remove_file(full) { info("uninstalled: '" + full + "'"); } else {