This PR contains the following updates: | Package | Update | Change | |---|---|---| | [rust](https://redirect.github.com/rust-lang/rust) | minor | `1.80.1` -> `1.81.0` | --- ### Release Notes <details> <summary>rust-lang/rust (rust)</summary> ### [`v1.81.0`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1810-2024-09-05) [Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.80.1...1.81.0) \========================== <a id="1.81.0-Language"></a> ## Language - [Abort on uncaught panics in `extern "C"` functions.](https://redirect.github.com/rust-lang/rust/pull/116088/) - [Fix ambiguous cases of multiple `&` in elided self lifetimes.](https://redirect.github.com/rust-lang/rust/pull/117967/) - [Stabilize `#[expect]` for lints (RFC 2383),](https://redirect.github.com/rust-lang/rust/pull/120924/) like `#[allow]` with a warning if the lint is *not* fulfilled. - [Change method resolution to constrain hidden types instead of rejecting method candidates.](https://redirect.github.com/rust-lang/rust/pull/123962/) - [Bump `elided_lifetimes_in_associated_constant` to deny.](https://redirect.github.com/rust-lang/rust/pull/124211/) - [`offset_from`: always allow pointers to point to the same address.](https://redirect.github.com/rust-lang/rust/pull/124921/) - [Allow constraining opaque types during subtyping in the trait system.](https://redirect.github.com/rust-lang/rust/pull/125447/) - [Allow constraining opaque types during various unsizing casts.](https://redirect.github.com/rust-lang/rust/pull/125610/) - [Deny keyword lifetimes pre-expansion.](https://redirect.github.com/rust-lang/rust/pull/126762/) <a id="1.81.0-Compiler"></a> ## Compiler - [Make casts of pointers to trait objects stricter.](https://redirect.github.com/rust-lang/rust/pull/120248/) - [Check alias args for well-formedness even if they have escaping bound vars.](https://redirect.github.com/rust-lang/rust/pull/123737/) - [Deprecate no-op codegen option `-Cinline-threshold=...`.](https://redirect.github.com/rust-lang/rust/pull/124712/) - [Re-implement a type-size based limit.](https://redirect.github.com/rust-lang/rust/pull/125507/) - [Properly account for alignment in `transmute` size checks.](https://redirect.github.com/rust-lang/rust/pull/125740/) - [Remove the `box_pointers` lint.](https://redirect.github.com/rust-lang/rust/pull/126018/) - [Ensure the interpreter checks bool/char for validity when they are used in a cast.](https://redirect.github.com/rust-lang/rust/pull/126265/) - [Improve coverage instrumentation for functions containing nested items.](https://redirect.github.com/rust-lang/rust/pull/127199/) - Target changes: - [Add Tier 3 `no_std` Xtensa targets:](https://redirect.github.com/rust-lang/rust/pull/125141/) `xtensa-esp32-none-elf`, `xtensa-esp32s2-none-elf`, `xtensa-esp32s3-none-elf` - [Add Tier 3 `std` Xtensa targets:](https://redirect.github.com/rust-lang/rust/pull/126380/) `xtensa-esp32-espidf`, `xtensa-esp32s2-espidf`, `xtensa-esp32s3-espidf` - [Add Tier 3 i686 Redox OS target:](https://redirect.github.com/rust-lang/rust/pull/126192/) `i686-unknown-redox` - [Promote `arm64ec-pc-windows-msvc` to Tier 2.](https://redirect.github.com/rust-lang/rust/pull/126039/) - [Promote `wasm32-wasip2` to Tier 2.](https://redirect.github.com/rust-lang/rust/pull/126967/) - [Promote `loongarch64-unknown-linux-musl` to Tier 2 with host tools.](https://redirect.github.com/rust-lang/rust/pull/126298/) - [Enable full tools and profiler for LoongArch Linux targets.](https://redirect.github.com/rust-lang/rust/pull/127078/) - [Unconditionally warn on usage of `wasm32-wasi`.](https://redirect.github.com/rust-lang/rust/pull/126662/) (see compatibility note below) - Refer to Rust's \[platform support page]\[platform-support-doc] for more information on Rust's tiered platform support. <a id="1.81.0-Libraries"></a> ## Libraries - [Split core's `PanicInfo` and std's `PanicInfo`.](https://redirect.github.com/rust-lang/rust/pull/115974/) (see compatibility note below) - [Generalize `{Rc,Arc}::make_mut()` to unsized types.](https://redirect.github.com/rust-lang/rust/pull/116113/) - [Replace sort implementations with stable `driftsort` and unstable `ipnsort`.](https://redirect.github.com/rust-lang/rust/pull/124032/) All `slice::sort*` and `slice::select_nth*` methods are expected to see significant performance improvements. See the [research project](https://redirect.github.com/Voultapher/sort-research-rs) for more details. - [Document behavior of `create_dir_all` with respect to empty paths.](https://redirect.github.com/rust-lang/rust/pull/125112/) - [Fix interleaved output in the default panic hook when multiple threads panic simultaneously.](https://redirect.github.com/rust-lang/rust/pull/127397/) <a id="1.81.0-Stabilized-APIs"></a> ## Stabilized APIs - [`core::error`](https://doc.rust-lang.org/stable/core/error/index.html) - [`hint::assert_unchecked`](https://doc.rust-lang.org/stable/core/hint/fn.assert_unchecked.html) - [`fs::exists`](https://doc.rust-lang.org/stable/std/fs/fn.exists.html) - [`AtomicBool::fetch_not`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicBool.html#method.fetch_not) - [`Duration::abs_diff`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.abs_diff) - [`IoSlice::advance`](https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.advance) - [`IoSlice::advance_slices`](https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.advance_slices) - [`IoSliceMut::advance`](https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.advance) - [`IoSliceMut::advance_slices`](https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.advance_slices) - [`PanicHookInfo`](https://doc.rust-lang.org/stable/std/panic/struct.PanicHookInfo.html) - [`PanicInfo::message`](https://doc.rust-lang.org/stable/core/panic/struct.PanicInfo.html#method.message) - [`PanicMessage`](https://doc.rust-lang.org/stable/core/panic/struct.PanicMessage.html) These APIs are now stable in const contexts: - [`char::from_u32_unchecked`](https://doc.rust-lang.org/stable/core/char/fn.from_u32\_unchecked.html) (function) - [`char::from_u32_unchecked`](https://doc.rust-lang.org/stable/core/primitive.char.html#method.from_u32\_unchecked) (method) - [`CStr::count_bytes`](https://doc.rust-lang.org/stable/core/ffi/c_str/struct.CStr.html#method.count_bytes) - [`CStr::from_ptr`](https://doc.rust-lang.org/stable/core/ffi/c_str/struct.CStr.html#method.from_ptr) <a id="1.81.0-Cargo"></a> ## Cargo - [Generated `.cargo_vcs_info.json` is always included, even when `--allow-dirty` is passed.](https://redirect.github.com/rust-lang/cargo/pull/13960/) - [Disallow `package.license-file` and `package.readme` pointing to non-existent files during packaging.](https://redirect.github.com/rust-lang/cargo/pull/13921/) - [Disallow passing `--release`/`--debug` flag along with the `--profile` flag.](https://redirect.github.com/rust-lang/cargo/pull/13971/) - [Remove `lib.plugin` key support in `Cargo.toml`. Rust plugin support has been deprecated for four years and was removed in 1.75.0.](https://redirect.github.com/rust-lang/cargo/pull/13902/) <a id="1.81.0-Compatibility-Notes"></a> ## Compatibility Notes - Usage of the `wasm32-wasi` target will now issue a compiler warning and request users switch to the `wasm32-wasip1` target instead. Both targets are the same, `wasm32-wasi` is only being renamed, and this [change to the WASI target](https://blog.rust-lang.org/2024/04/09/updates-to-rusts-wasi-targets.html) is being done to enable removing `wasm32-wasi` in January 2025. - We have renamed `std::panic::PanicInfo` to `std::panic::PanicHookInfo`. The old name will continue to work as an alias, but will result in a deprecation warning starting in Rust 1.82.0. `core::panic::PanicInfo` will remain unchanged, however, as this is now a *different type*. The reason is that these types have different roles: `std::panic::PanicHookInfo` is the argument to the [panic hook](https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html) in std context (where panics can have an arbitrary payload), while `core::panic::PanicInfo` is the argument to the [`#[panic_handler]`](https://doc.rust-lang.org/nomicon/panic-handler.html) in no_std context (where panics always carry a formatted *message*). Separating these types allows us to add more useful methods to these types, such as `std::panic::PanicHookInfo::payload_as_str()` and `core::panic::PanicInfo::message()`. - The new sort implementations may panic if a type's implementation of [`Ord`](https://doc.rust-lang.org/std/cmp/trait.Ord.html) (or the given comparison function) does not implement a [total order](https://en.wikipedia.org/wiki/Total_order) as the trait requires. `Ord`'s supertraits (`PartialOrd`, `Eq`, and `PartialEq`) must also be consistent. The previous implementations would not "notice" any problem, but the new implementations have a good chance of detecting inconsistencies, throwing a panic rather than returning knowingly unsorted data. <a id="1.81.0-Internal-Changes"></a> ## Internal Changes These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - [Add a Rust-for Linux `auto` CI job to check kernel builds.](https://redirect.github.com/rust-lang/rust/pull/125209/) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC41OS4yIiwidXBkYXRlZEluVmVyIjoiMzguNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> |
||
|---|---|---|
| .. | ||
| examples | ||
| src | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| README.md | ||
Oxc transformer
We mostly model Oxc's transforms on Babel's implementations.
First iteration of a transform will usually be as straight a port from Babel as possible. We may then iterate from there to gain better performance.
We import Babel's transformer tests, and aim to pass them all.
All transforms are implementations of the Traverse trait.
Composing transforms
We aim to run all transforms together in a single AST visitation pass.
This will be the most performant method, though it causes some complexity, especially due to interactions between different transforms acting on the same code. It is unclear at present if this methodology will be viable, but it is our initial aim, and we will only fall back to multiple passes if single-pass proves unworkable.
Style guide for implementing transforms
Transforms are complex. Please try to make the code as clear and easy to follow as possible.
NB: Not all the "rules" in this style guide are currently followed in transforms we've written so far. We will update those transforms to follow this guide when we have time. But all new transforms should follow this style guide closely.
Structure
Each transform should be in its own file.
Some transforms just delegate work to sub-transforms. e.g. React transform delegates to the ReactJsx
and ReactDisplayName transforms.
Comments
For a maintainable and understandable codebase, please go big on code comments. The more, the merrier!
Top of file
Each transform should include a comment at top of file including:
- High level explanation of what transform does.
- One "before / after" example.
- Link to Babel plugin.
- Note of any ways in which our implementation diverges from Babel's, and why.
Methods
If it's a complicated transform with multiple visitors which interact with each other, add comments explaining how the pieces fit together.
Code snippets
AstBuilder calls are often very verbose. Preface each chunk of AstBuilder calls with a short comment
showing what this code produces. e.g.:
// `let Foo;`
let declarations = {
let ident = BindingIdentifier::new(SPAN, "Foo");
let pattern_kind = self.ast.binding_pattern_identifier(ident);
let binding = self.ast.binding_pattern(pattern_kind, None, false);
let decl = self.ast.variable_declarator(SPAN, VariableDeclarationKind::Let, binding, None, false);
self.ast.new_vec_single(decl)
};
let var_decl = Declaration::VariableDeclaration(self.ast.variable_declaration(
SPAN,
kind,
declarations,
Modifiers::empty(),
));
Where we can improve on Babel
Babel has less of an emphasis on performance than Oxc has. For this reason Babel's implementations are often not as efficient as they could be.
In some cases, we could do better, but we are unable to at present because a more efficient implementation would result in cosmetic differences between Oxc's output and Babel's (e.g. different variable names) which causes Babel's tests to fail when run on Oxc's output.
In future we may find a way to work around this problem.
So where we feel Babel's implementation is inefficient, but we have to follow it at present to pass their
tests, make a // TODO(improve-on-babel): Babel's impl is inefficient because X, we could do better by Y
comment, so we can return to it later.
Clear "entry points"
"Entry points" are where the visitor calls into the transform.
- Entry points of transform should be implemented as
impl Traverse for MyTransform. - Those methods have to be called
enter_*andexit_*. - Parent transform will only interface with child transform via these entry points.
- Only other method exposed externally should be
new. That should be at top of the file. - Entry points go directly below
newmethod definition. - Internal methods implemented lower down in an
impl MyTransformblock. - Internal methods named descriptively -
add_id_to_functionnottransform_function.
i.e. File is laid out so logic flows from top of file to bottom.
e.g.:
struct FunctionRenamer {
prefix: String,
}
// Initialization
impl FunctionRenamer {
pub fn new(prefix: String) -> Self {
Self { prefix }
}
}
// Entry points
impl<'a> Traverse<'a> for FunctionRenamer {
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
match stmt {
Statement::FunctionDeclaration(func) => {
self.rename_function(func, ctx);
}
Statement::ExportDefaultDeclaration(decl) => {
if let ExportDefaultDeclarationKind::FunctionDeclaration(func) = &mut decl.declaration {
self.rename_function(func, ctx);
}
}
}
}
}
// Internal methods
impl FunctionRenamer {
/// Rename the function
// This function's name describes what it does, not just `transform_function`
fn rename_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
// Do stuff
}
}
Encapsulate logic
All logic for each transform should live in that specific file, with no "leaking" into the parent
transform. Each transform is only called into via the standard enter_*/exit_* entry points.
Only exception is that parent can check if child transform is enabled or not.
Bad! Don't do this.
Here some of logic from child transform is "leaked" into the parent:
// src/do_stuff/mod.rs
impl<'a> Traverse<'a> for ParentTransform {
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
if self.child_is_enabled {
match expr {
Expression::JSXElement(e) => {
self.child.enter_jsx_element(e, ctx);
}
Expression::JSXFragment(e) => {
self.child.enter_jsx_fragment(e, ctx);
}
_ => {}
}
}
}
}
// src/do_stuff/child.rs
impl<'a> Traverse<'a> for ChildTransform {
fn enter_jsx_element(&mut self, elem: &mut JSXElement<'a>, ctx: &mut TraverseCtx<'a>) {
// Do stuff
}
fn enter_jsx_fragment(&mut self, elem: &mut JSXFragment<'a>, ctx: &mut TraverseCtx<'a>) {
// Do stuff
}
}
Good!
All the child transform's logic is encapsulated in ChildTransform:
// src/do_stuff/mod.rs
impl<'a> Traverse<'a> for ParentTransform {
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
if self.child_is_enabled {
self.child.enter_expression(expr, ctx);
}
}
}
// src/do_stuff/child.rs
impl<'a> Traverse<'a> for ChildTransform {
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
match expr {
Expression::JSXElement(e) => {
self.do_stuff_to_jsx_element(e, ctx);
}
Expression::JSXFragment(e) => {
self.do_stuff_to_jsx_fragment(e, ctx);
}
_ => {}
}
}
}
impl ChildTransform {
fn do_stuff_to_jsx_element(&mut self, elem: &mut JSXElement<'a>, ctx: &mut TraverseCtx<'a>) {
// Do stuff
}
fn do_stuff_to_jsx_fragment(&mut self, elem: &mut JSXFragment<'a>, ctx: &mut TraverseCtx<'a>) {
// Do stuff
}
}