Rust 1.99.0
- Add allow-by-default
raw_borrows_via_referenceslint that checks for references that decay immediately into raw borrows - Extend
unconditional_paniclint to function calls that panic when the chunks/windows size is zero - Stabilize C-variadic function definitions
- Stabilize the ability to use
#[unsafe(naked)]functions to define C-variadic functions (#![feature(c_variadic_naked_functions)]). - Trait methods are now resolved on an adjusted never type (producing a FCW)
- Coerce from inference variables to trait objects if the inference variable is related via subtyping to a type that is known to be
Sized - Stabilize
#[my_macro] mod foo;. This allows outlined modules (mod foo;) anywhere in the body of a custom attribute or derive macro. - Fix the
overflowing_literalslint with repeated negation. For instance, it will now no longer lint on--128_i8, which is already detected by thearithmetic_overflowlint. - Add POSIX symbols to the
invalid_runtime_symbol_definitionsandsuspicious_runtime_symbol_definitionslints - Lint unused
#[path]attributes on inline modules - Enable
unreachable_cfg_select_predicateslint as part ofunusedlint group - Stabilize passing 128-bit integers via vector registers with
asm!on x86 - Explicitly document that some allocations are allowed to grow in-place (but none are allowed to shrink)
- We now guarantee that the contents of an
UnsafeCellcan be accessed without going throughget - Account for globally enabled target features in
global_asm! - Warn if an invalid
docattribute is used on a macro invocation
- Convert
-Ctarget-cpuinto a target-modifier for AVR, AMDGCN and NVPTX - Enable
static_position_independent_executableson all gnu targets - When providing a suggestion about a missing method, rustc now prefers an exactly matching name from a doc alias attribute over a similarity search from other method names. If your new users sometimes expect a method under a different name, adding a doc alias will now help them find it via rustc suggestions, in addition to helping them find it via rustdoc search: When suggesting method names, prefer exact doc aliases over similar names
Refer to Rust's platform support page for more information on Rust's tiered platform support.
- Iteration on
RangeInclusive(a..=branges) is now optimized better in some circumstances. As a side effect of this, the behavior ofRangeInclusivevalues that has already been exhausted (as an iterator) has changed. For example, the return values ofstart()andend()on such ranges may return different values, and using such ranges as slice indexes may have different behavior. These behaviors were not guaranteed to be stable, so these changes are considered to not be breaking changes. - Relax
transmute_copyto accept?Sizedtypes - Update
transmute_copyto use a non-unwinding panic - Don't escape U+FF9E and U+FF9F in
escape_debug_ext - Re-export
core::fmt::NumBufferinalloc(andstd)
IntoIteratorforBox<[T; N]>IntoIteratorfor&Box<[T; N]>IntoIteratorfor&mut Box<[T; N]>VecDeque::retain_backcore::ffi::VaListBox::into_non_nullBox::from_non_nullVec::into_partsVec::from_partscore::mem::size_of_val_rawcore::mem::align_of_val_rawcore::alloc::Layout::for_value_rawString::from_utf8_lossy_ownedstring::FromUtf8Error::into_utf8_lossyFusedIterator for StepBy<I>std::fs::set_timesstd::fs::set_times_nofollow
- Add a new built-in profile
debug. This is a preparation for transitioning thedevprofile away from debugging to give a saner default for faster development iterations. Currently there is no difference betweendevanddebugprofiles. docs #17214 - Workspace members on edition 2024 or later can now override an inherited workspace dependency's
default-featuresfield. For example,serde = { workspace = true, default-features = false }now turns off default features even when the workspace definition enables them. On earlier editions,default-features = falseis ignored with a warning. (RFC 3945) #17126
See also the full Cargo changelog
- Add new
unused_footnote_definitionrustdoc lint - Smarter filtering of trait impls yields performance improvements of 20% on average and up to 40% on some real-world crates. (1, 2, 3, 4, 5)
- Fully deprecate the legacy integral modules. For example,
std::i32::MAXshould be accessed viai32::MAXinstead. - Upgrade
no_mangle_generic_itemsinto hard error - The
Pin::new_uncheckedhas had its safety invariants changed slightly - Do not promote references to extern statics
- Ensure that the inferred types of
letpatterns typecheck - hermit/fs: Return
unsupported()instead offrom_raw_os_error(22) - Fixed a bug where
#[repr(simd)]was accidentally allowed on macro invocations on stable Rust - Abort const-eval when there are generics in the type of the value being produced
- Attributes not applying to anything are now an error in code blocks in doc comments
Box::leak: tell people to avoid unleaking- PowerPC inline ASM: Fix scalar floats being in the wrong vector lane on little endian
- Do not take
doc(cfg())into account when filtering doctests - Infer anonymous lifetimes in the types of associated consts as
'static - Macros that expand to a semicolon now produce a warning lint (
semicolon_in_expressions_from_non_local_macros) even when the macro comes from another crate. Previously, such warnings only appeared for macros from the same crate, to avoid showing warnings that can't be fixed locally; however, this masked problems, as integration tests from the crate providing the macro get compiled as a separate crate, so tests often wouldn't reveal this issue. If you encounter a lint like this, please make sure to report it to the crate providing the macro so they can fix it; don't just silence it in your own crate. - In Cargo, incremental compilation is now disabled by default when running in CI. CI is detected via the
CIenvironment variable. #17220
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.
Rust 1.98.0
- Allow shortening lifetime of
&mutwhen unsize-coercing, even in an invariant position. For example, you can now coerce aCell<&'long mut i32>to aCell<&'short mut dyn Send>. Such shortenings were already previously allowed when coercing a&mutto a&, or coercing a&to a&. - Add deny-by-default
invalid_runtime_symbol_definitionslint and warn-by-defaultsuspicious_runtime_symbol_definitionslint- The lints currently specifically targets
coreruntime symbols likememcmp,memset,strlen, ... and is planned to be expanded in the next few releases.
- The lints currently specifically targets
- Add warn-by-default
c_void_returnslint to checkcore::ffi::c_voidas a return type
- Add
powerpc64-unknown-linux-gnuelfv2as Tier 3 - Add
aarch64-unknown-linux-pauthtestas Tier 3 target - Promote
thumbv7a-none-eabito Tier 2 - Promote
thumbv7a-none-eabihfto Tier 2 - Promote
thumbv7r-none-eabito Tier 2 - Promote
thumbv7r-none-eabihfto Tier 2 - Promote
thumbv8r-none-eabihfto Tier 2
Refer to Rust's platform support page for more information on Rust's tiered platform support.
- Change
Location<'_>lifetime to'staticinPanic[Hook]Info - Document panic in
RangeInclusive::from(legacy::RangeInclusive) - Document that
ManuallyDrop'sBoxinteraction has been fixed - Stabilize LoongArch CRC Intrinsics
- The
derivemacro is available at{core,std}::derive. This was previously unintentionally stabilized in 1.96, but is now explicitly accepted as a stabilized API.- Please note that the MSRV for
{core,std}::derivewill be 1.96, and not 1.98.
- Please note that the MSRV for
str::substr_range[T]::subslice_rangecore::fmt::NumBuffer<{integer}>::format_intoSend/Sync for std::process::CommandArgs{fN}::algebraic_add{fN}::algebraic_sub{fN}::algebraic_mul{fN}::algebraic_div{fN}::algebraic_remNonZero<{integer}>::from_str_radixString::from_utf16leString::from_utf16le_lossyString::from_utf16beString::from_utf16be_lossy[T]::strip_circumfixstr::strip_circumfixAtomic<T>::from_mutAtomic<T>::get_mut_sliceAtomic<T>::from_mut_slicestd::range::legacy
- If fully elided, lifetime bounds of trait object types may now resolve differently or even get rejected in very specific niche scenarios
- Error in more cases of ambiguous imports
- Switch the destructors implementation for thread locals on Windows to use Fiber Local Storage (FLS)
- Convert some cases of the
ambiguous_glob_importslint into a hard error - Where-bounds of the form
Type = TypeandType == Typeare no longer syntactically allowed - Ensure Send/Sync is not implemented for std::env::Vars{,Os}
- Fix that in some attributes, arguments were not properly rejected
repr(transparent)is now more strict about which fields have "trivial" layout and hence can be ignored:repr(C)types, types with private fields, and#[non_exhaustive]types are no longer considered "trivial"- Correctly check whether types have equal size in
transmute()when somereprattributes are involved. - More characters are escaped when printing strings and chars
- Implement fast path for
derive(PartialOrd)when derivingOrdThis can break crates in practice where a type's PartialOrd and Ord impls were inconsistent with each other. - Add temporary scope to
assert_eqandassert_ne - Closed a hole in the pattern matching structural equality check, preventing cases where a match of a constant would be allowed, despite disagreeing with a manually written
PartialEqimplementation, when aderive(PartialEq)implementation for that type also exists. - On Emscripten the WASM exception handling ABI is now unconditionally used The
-Zemscripten-wasm-eh=falseflag to switch back to JS exceptions has been removed. - The UNSAFE_CODE lint is now consistently emitted for all unsafe attributes
- Solaris: remove
File::lockimplementation, it has the wrong semantics (return "unsupported" instead) - Windows-gnu targets now specify baseline tools versions
- rustfmt now discovers module files that are defined in
cfg_select!This may cause more code to be formatted which was previously ignored.
Rust 1.97.1
- rustc: Fix miscompilation in LLVM optimization This backports an LLVM submodule bump to include the LLVM-side fix and a revert of the rustc change that is one known trigger for the bug. The rustc side revert should not be strictly necessary but is done out of abundance of caution.
Rust 1.97.0
- Consider
Result<T, Uninhabited>andControlFlow<Uninhabited, T>to be equivalent toTfor must use lint - Add allow-by-default
dead_code_pub_in_binarylint for unused pub items in binary crates - Stabilize the
div32,lam-bh,lamcas,ld-seq-saandscqtarget features - Stabilize
cfg(target_has_atomic_primitive_alignment) - Allow trailing
selfin imports in more cases
Refer to Rust's platform support page for more information on Rust's tiered platform support.
Default for RepeatNCopy for ffi::FromBytesUntilNulErrorSend for std::fs::Fileon UEFI<{integer}>::isolate_highest_one<{integer}>::isolate_lowest_one<{integer}>::highest_one<{integer}>::lowest_one<{integer}>::bit_widthNonZero<{integer}>::isolate_highest_oneNonZero<{integer}>::isolate_lowest_oneNonZero<{integer}>::highest_oneNonZero<{integer}>::lowest_oneNonZero<{integer}>::bit_width
These previously stable APIs are now stable in const contexts:
- Stabilize
build.warningsconfig. This controls how lint warnings from local packages are treated. Useful for enforcing a warning-free build in CI, replacing-Dwarnings. docs - Stabilize
resolver.lockfile-pathconfig. This allows specifying the path to the lockfile to use when resolving dependencies. Useful when working with read-only source directories. docs - cargo-clean: Error when
--target-dirdoesn't look like a Cargo target directory. This prevents accidental deletion of non-target directories. - Add
-mshorthand for--manifest-path - Remove
curldependency fromcrates-iocrate
- Emit a future-compatibility warning when relying on
f32: From<{float}>to constrain{float} - Rust will use the v0 symbol mangling scheme by default. This may cause some tools (such as debuggers or profilers, especially with old versions) to fail to demangle symbols emitted by Rust. It may also cause the formatting of text in backtraces to change.
- Prevent deref coercions in
pin!, in order to prevent unsoundness. The most likely case where this might impact users is: writingpin!(x)wherexhas type&mut Twill now always correctly produce a value of typePin<&mut &mut T>, instead of sometimes allowing a coercion that produces a value of typePin<&mut T>. This coercion was previously incorrectly allowed since Rust 1.88.0. - Deprecate
std::charconstants and functions - Warn on linker output by default
- Remove hidden
f64methods which have been deprecated since 1.0 - report the
varargs_without_patternlint in deps - Forbid passing generic arguments to module path segments even if the module reexports a generic enum variant
- Error on invalid macho
link_sectionspecifier - The encoding of certain
enums have changed. This is not a breaking change, as it only applies toenums without layout guarantees, but is noted here as we've seen people impacted from having made assumptions about the layout algorithm. - Error on
#[export_name = "..."]where the name is empty - Syntactically reject tuple index shorthands in struct patterns
- validate
#[link_name = "..."]&#[link(name = "...")]parameters - On Windows, after calling
shutdownon a socket to shut down the write side, attempting to write to the socket will now produce aBrokenPipeerror rather thanOther. MapWSAESHUTDOWNtoio::ErrorKind::BrokenPipe
Rust 1.96.0
- Allow passing
exprmetavariable tocfg - Always coerce never types in tuple expressions
- Avoid incorrect inference guidance of function arguments in rare cases
- Support s390x vector registers in inline assembly
- Allow using constants of type
ManuallyDropas patterns (fixing a regression introduced in 1.94.0)
- Enable link relaxation feature for LoongArch Linux targets
- Update
riscv64gc-unknown-fuchsiabaseline to RVA22 + vector
- Support iterating over ranges of
NonZerointegers - refactor 'valid for read/write' definition: exclude null; add that as an exception on individual methods instead
- Fix SGX delayed host lookup via ToSocketAddr
assert_matches!debug_assert_matches!From<T> for AssertUnwindSafe<T>From<T> for LazyCell<T, F>From<T> for LazyLock<T, F>core::range::RangeToInclusivecore::range::RangeToInclusiveItercore::range::RangeFromcore::range::RangeFromItercore::range::Rangecore::range::RangeIter
- Allow a dependency to specify both a git repository and an alternate registry. Just like with crates.io, the git repository will be used locally, but the registry version will be used when published.
- Added
target.'cfg(..)'.rustdocflagssupport in configuration. - Fixed CVE-2026-5222 and CVE-2026-5223.
- Deprecation notes are now rendered like any other documentation. Previously they used the css
white-space: pre-wrap;property and stripped any<p>elements from the rendered html, however this caused issues and unintuitive behavior. The new behavior should be more predictable, however some multi-line deprecation notes will now be rendered as as single lines. If this is undesirable, you can use the standard markdown method of forcing a linebreak, which is two spaces followed by a newline ("\n"). - Don't emit rustdoc
missing_doc_code_exampleslint on impl items - Seperate methods and associated functions in sidebar
- Fix layout of
#[repr(Int)]enums in some edge cases involving fields of uninhabited zero-sized types - Prevent unsize-coercing into
Pin<Foo>whereFoodoesn't implementDeref. Some such coercions were previously allowed, but produce a type with no useful public API. - rustc: Stop passing
--allow-undefinedon wasm targets - Gate the accidentally stabilized
#![reexport_test_harness_main]attribute - Error on return-position-impl-trait-in-traits whose types are too private
- Report the
uninhabited_staticlint in dependencies and make it deny-by-default - Distributed builds now contain non-split debuginfo for windows-gnu This appears to improve the quality of backtraces. This change has no effect on the defaults for the output of rustc/cargo on these targets.
- Check const generic arguments are correctly typed in more positions
- Remove
-Csoft-float - Importing structs with
::{self [as name]}, e.g.,struct S {}; use S::{self as Other};, is now no longer permitted because{self}imports require a module parent. - For
export_name,link_name, andlink_sectionattributes, if multiple of the same attribute is present, the first one now takes precedence. - Update the minimum external LLVM to 21
- On
avrtargets, C'sdoubletype is 32-bit by default, so changec_doubletof32onavrtargets to match. This is a breaking change, but necessary to makec_doublematch C's double.
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.
Rust 1.95.0
- Stabilize
if letguards on match arms irrefutable_let_patternslint no longer lints on let chains- Support importing path-segment keywords with renaming
- Stabilize inline assembly for PowerPC and PowerPC64
- const-eval: be more consistent in the behavior of padding during typed copies
- Const blocks are no longer evaluated to determine if expressions involving fallible operations can implicitly be constant-promoted.. Expressions whose ability to implicitly be promoted would depend on the result of a const block are no longer implicitly promoted.
- Make operational semantics of pattern matching independent of crate and module
- Stabilize
--remap-path-scopefor controlling the scoping of how paths get remapped in the resulting binary - Apply patches for CVE-2026-6042 and CVE-2026-40200 to vendored musl
- Promote
powerpc64-unknown-linux-muslto Tier 2 with host tools - Promote
aarch64-apple-tvosto Tier 2 - Promote
aarch64-apple-tvos-simto Tier 2 - Promote
aarch64-apple-watchosto Tier 2 - Promote
aarch64-apple-watchos-simto Tier 2 - Promote
aarch64-apple-visionosto Tier 2 - Promote
aarch64-apple-visionos-simto Tier 2
Refer to Rust's platform support page for more information on Rust's tiered platform support.
thread::scope: document how join interacts with TLS destructors- Speed up
str::containson aarch64 targets withneontarget feature enabled by default
MaybeUninit<[T; N]>: From<[MaybeUninit<T>; N]>MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>; N]>MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>]>MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>; N]>MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>]>[MaybeUninit<T>; N]: From<MaybeUninit<[T; N]>>Cell<[T; N]>: AsRef<[Cell<T>; N]>Cell<[T; N]>: AsRef<[Cell<T>]>Cell<[T]>: AsRef<[Cell<T>]>bool: TryFrom<{integer}>AtomicPtr::updateAtomicPtr::try_updateAtomicBool::updateAtomicBool::try_updateAtomicIn::updateAtomicIn::try_updateAtomicUn::updateAtomicUn::try_updatecfg_select!mod core::rangecore::range::RangeInclusivecore::range::RangeInclusiveItercore::hint::cold_path<*const T>::as_ref_unchecked<*mut T>::as_ref_unchecked<*mut T>::as_mut_uncheckedVec::push_mutVec::insert_mutVecDeque::push_front_mutVecDeque::push_back_mutVecDeque::insert_mutLinkedList::push_front_mutLinkedList::push_back_mutLayout::dangling_ptrLayout::repeatLayout::repeat_packedLayout::extend_packed
These previously stable APIs are now stable in const contexts:
- Array coercions may now result in less inference constraints than before
- Importing
$cratewithout renaming, i.e.use $crate::{self};, is now no longer permitted due to stricter error checking forselfimports. - const-eval: be more consistent in the behavior of padding during typed copies. In very rare cases, this may cause compilation errors due to bytes from parts of a pointer ending up in the padding bytes of a
constorstatic. - A future-incompatibility warning lint
ambiguous_glob_imported_traitsis now reported when using an ambiguously glob imported trait - Check lifetime bounds of types mentioning only type parameters
- Report more visibility-related ambiguous import errors
- Deprecate
Eq::assert_receiver_is_total_eqand emit future compatibility warnings on manual impls - powerpc64: Use the ELF ABI version set in target spec instead of guessing (fixes the ELF ABI used by the OpenBSD target)
- Matching on a
#[non_exhaustive]enum now reads the discriminant, even if the enum has only one variant. This can cause closures to capture values that they previously wouldn't. mut refandmut ref mutpatterns, part of the unstable Match Ergonomics 2024 RFC, were accidentally allowed on stable within struct pattern field shorthand. These patterns are now correctly feature-gated as unstable in this position.- Add future-compatibility warning for derive helper attributes which conflict with built-in attributes
- JSON target specs have been destabilized and now require
-Z unstable-optionsto use. Previously, they could not be used without the standard library, which has no stable build mechanism. In preparation for thebuild-stdproject adding that support, JSON target specs are being proactively gated to ensure they remain unstable even ifbuild-stdis stabilized. Cargo now includes the-Z json-target-specCLI flag to automatically pass-Z unstable-optionsto the compiler when needed. See #150151, #151534, and rust-lang/cargo#16557. - The arguments of
#[feature]attributes on invalid targets are now checked
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.
Rust 1.94.1
- Fix
std::thread::spawnon wasm32-wasip1-threads - Remove new methods added to
std::os::windows::fs::OpenOptionsExtThe new methods were unstable, but the trait itself is not sealed and so cannot be extended with non-default methods. - Clippy: fix ICE in
match_same_arms - Cargo: update tar to 0.4.45 This resolves CVE-2026-33055 and CVE-2026-33056. Users of crates.io are not affected. See blog for more details.