Skip to content

Conversation

thenewwazoo
Copy link

@thenewwazoo thenewwazoo commented Aug 13, 2025

PR content

This commit makes a small number of updates necessary to adopt the stable toolchain:

  • Sets the stable toolchain as the default by config. Invoking nightly will require using +nightly-2025-07-20 per Update to nightly-2025-07-20 #2169.
  • Removes references to nightly requirements in the FAQ, and adds a note about enabling stack size checking being the only thing that requires nightly.
  • Removes code that passes the -Z flag to cargo to enable nightly features.
  • Updates #[naked] and asm! usage to stable convention, which is #[unsafe(naked)] and naked_asm!. Any affected assembly sections are expected to diverge (which was previously handled by options(noreturn)) or end with a trap (in the case of _start).
  • Replaces used(linker) with used, which is equivalent.
  • Adds a code path in the dist build task to build endoscope if the task being built has a name drv_lpc55_swd, upon which it depends. This is because artifact dependencies are not stable, but lcp55-swd depends on having the endoscope binary available to its build script.
  • Gates stack size emission and check behind a rustc_version channel check. Passing +nightly-2025-07-20 to cargo (when invoking xtask) will enable the check.

Fixes #1927

Open questions

  • This PR implicitly declares a MSRV of 1.89.0, but no MSRV policy, which requires the input of the maintainers.
  • Excepting the FAQ, the preferred nightly version is not actually encoded anywhere. You just have to kind of already know that 2025-07-20 is the blessed nightly version.
  • I have not run this on production hardware.
  • Checking task stack sizes is something that should be done in CI, but that requires tooling changes.

This commit makes a small number of updates necessary to adopt the
stable toolchain:
* Sets the stable toolchain as the default by config. Invoking nightly
  will require using `+nightly-2025-07-20` per oxidecomputer#2169.
* Removes references to nightly requirements in the FAQ, and adds a note
  about enabling stack size checking being the only thing that requires
  nightly.
* Removes code that passes the `-Z` flag to cargo to enable nightly
  features.
* Updates `#[naked]` and `asm!` usage to stable convention, which is
  `#[unsafe(naked)]` and `naked_asm!`. Any affected assembly sections
  are expected to diverge (which was previously handled by
  `options(noreturn)`) or end with a trap (in the case of `_start`).
* Replaces `used(linker)` with `used`, which is [equivalent].
* Adds a code path in the `dist` build task to build endoscope if the
  task being built has a name `drv_lpc55_swd`, upon which it depends.
  This is because [artifact dependencies] are not stable, but `lcp55-swd`
  depends on having the endoscope binary available to its build script.
* Gates stack size emission and check behind a `rustc_version` channel
  check. Passing `+nightly-2025-07-20` to `cargo` (when invoking xtask)
  will enable the check.

[equivalent]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/attrs/data_structures/enum.UsedBy.html
[artifact dependencies]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#artifact-dependencies
Comment on lines +505 to +521
if version_meta().unwrap().channel == Channel::Nightly {
// Check stack sizes and resolve task slots in our linked files
let mut possible_stack_overflow = vec![];
for task_name in cfg.toml.tasks.keys() {
if tasks_to_build.contains(task_name.as_str()) {
if task_can_overflow(&cfg.toml, task_name, verbose)? {
possible_stack_overflow.push(task_name);
}

resolve_task_slots(&cfg, task_name, image_name)?;
resolve_task_slots(&cfg, task_name, image_name)?;
}
}
if !possible_stack_overflow.is_empty() {
bail!(
"tasks may overflow: {possible_stack_overflow:?}; \
see logs above"
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooooh this is really a deal breaker right now I think :/

We really need the stack size checking feature as stackoverflows are one of the biggest hubris pain points

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's okay - the work is done, and going from "here is a list of nightly features we use" to "here is the one thing we use nightly for" is an improvement. and my goal was to knock out an easy task to familiarise myself with hubris, so: mission accomplished.

lmk if I should carve this change out slash refactor this PR as getting 90% there, or if there's more internal discussion to be had.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confess I haven't looked too closely at the mechanism or how it is implemented in practice, but I wonder if we need it in production? Or could we make it part of a CI pipeline with RUSTC_BOOTSTRAP=1?

Copy link
Author

@thenewwazoo thenewwazoo Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two aspects to the stack size check vis-a-vis compilation:

The first aspect is the tricker one. Right now, my current design expects cargo to be invoked with +nightly-... at the topmost level (i.e. cargo +nightly-... xtask ...) in order to implicitly select the nightly compiler. The rustc façade will take a toolchain spec, so the toolchain selection could potentially be pushed into the dist task by conditionally adding a +nightly-... argument to rustc. The BuildConfig used to locate rustc appears to support using a façade, though its default construction specifies the sysroot, which I think implies deeper plumbing would be necessary. The net result of this would be a stable compiler building a dist build task which invokes a nightly compiler to compile firmware tasks.

The second aspect is easier. If we shouldn't expect to find stack size info, just eat the error and move on.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this a bit more, the stack checking is not something that ends up in the production image, if that makes sense. You could use nightly to build a binary, emitting stack size info as a side-effect, and then throw that binary away in favor of a stable-toolchain-built binary, assuming all else is equal (... a big assumption, maybe).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that was kind of what I was going for with my earlier comment about only doing the stack checks with in CI, and not production. I apologize for being terribly vague there, however.

But a two-step process, where one builds a binary with the stack size data via setting RUSTC_BOOTSTRAP=1 and setting the magic -Z flag in RUSTFLAGS, and then building another binary without setting RUSTC_BOOTSTRAP, was what I meant.

I presume we can use the same compiler binary for both invocations, and that we don't need an actual nightly compiler binary for either, as long as we set RUSTC_BOOTSTRAP=1 for the case where we need the stack data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

We're still on the nightly toolchain and that's annoying

3 participants