# Mojo nightly

> Source: <https://mojolang.org/releases/nightly/>
> Published: 2026-08-13 22:17:00+00:00

# Mojo nightly

This version is still a work in progress.

### Highlights

- Code that performs many implicit conversions, most visibly large collection literals, compiles faster: the compiler no longer runs parameter inference on constructors that cannot be used for an implicit conversion in the first place. Files that are mostly data, such as the standard library's Unicode lookup tables, compile about 1.3x faster.

### Language changes

-
Renamed the

`@parameter`

decorator on parametric closures to`@__parameter`

. The deprecated`@parameter if`

/`@parameter for`

forms are unchanged; prefer`comptime if`

/`comptime for`

for compile-time control flow. -
The module & package system:

-
Directories may now have "namespace" semantics; a single directory name may resolve across distinct locations on disk which share that name.

```
# .# ├── one# │   └── foo# │       └── bar.mojo# └── two#     └── foo#         └── baz.mojo## Compiles with -Ione -Itwoimport foo.barimport foo.baz
```

-
Importing functions with the same name from different modules, combining them into one overload set, is now an error, following a period of deprecation.

-
Intra-package accesses without explicit

`import`

s are now an error, following a period of deprecation.

-

### Library changes

-
`StringDict`

now conforms to`Writable`

when its value type is`Writable`

, matching the existing behavior of`Dict`

. This lets you`print()`

a`StringDict`

or convert it to a`String`

. -
The

`chars`

argument of`strip()`

,`lstrip()`

and`rstrip()`

on`StringSpan`

,`String`

and`StringLiteral`

is now an`ImmStringSpan`

, so a mutable string is accepted as`chars`

, including the string being stripped (`s.strip(s)`

). -
`StringDict.__getitem__()`

now accepts a`StringSpan`

, so you can index a`StringDict`

with a borrowed string view without first allocating a`String`

just to perform the lookup. -
Renamed the variadic type-list parameter on

`Tuple`

and`VariadicPack`

to`Ts`

, standardizing the naming convention used across the standard library. The old name,`element_types`

, remains as a deprecated alias. -
Added experimental

`DType.float6_e2m3fn`

and`DType.float6_e3m2fn`

, the two 6-bit encodings from the[Open Compute microscaling specification](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf). Both are finite-only, so neither has an inf nor a NaN encoding.These are experimental storage formats for packed weights rather than general-purpose numeric types, and standard library support is deliberately partial. As with the existing

`DType.float4_e2m1fn`

, they are excluded from`is_numeric()`

, arithmetic is not implemented, and converting to or from another floating-point type is unsupported on every target, so values cannot be printed either. -
`Array`

now conforms to`Defaultable`

when its type`T`

is also`Defaultable`

. -
Deprecated

`is_trivially_movable()`

,`is_trivially_copyable()`

, and`is_trivially_deletable()`

in`std.memory`

in favor of`IsTriviallyMovable[T]`

,`IsTriviallyCopyable[T]`

, and`IsTriviallyDeinitable[T]`

in`std.traits`

. The replacements are`comptime`

predicates rather than functions, so drop the call parens at use sites, for example`IsTriviallyCopyable[T]`

instead of`is_trivially_copyable[T]()`

. -
Renamed

`UnsafeMaybeUninit`

to`MaybeUninit`

. It conforms to`Movable`

,`Copyable`

/`ImplicitlyCopyable`

, and`Deinitable`

only when the contained type's own move, copy, or implicit deinitializer is trivial, since moving, copying, or destroying a`MaybeUninit`

only touches its raw bits, never the contained value's own lifecycle methods. Gating conformance this way turns what would otherwise be silent memory-safety bugs into compile-time errors. -
`Atomic`

is now parameterized on a value type`T`

instead of a`DType`

. Update call sites from`Atomic[DType.float32]`

to`Atomic[Float32]`

. The atomic operations (`load()`

,`store()`

,`fetch_add()`

,`compare_exchange()`

, and so on) still only support`Scalar`

types. -
Added

`Pointer[T].unsafe_write(def() -> T)`

, which initializes the pointee with the value returned by a closure, constructing it directly in place rather than moving an already-constructed value there. Unlike`unsafe_write(var T)`

, this does not require the pointee type to be`Movable`

. -
`Pointer.mut_cast`

is now deprecated. Developers should prefer using explicit mutabilites at the callsite via`MutPointer`

or`ImmPointer`

. If mut casting is needed (it should try to be avoided) - you can use`unsafe_mut_cast`

. -
The following APIs have been migrated to unified closures:

`sort`

,`debug_assert`

,`Span.apply`

. -
Uncaught exceptions now print to

`stderr`

, not`stdout`

.

### Tooling changes

`mojo doc`

now reports the condition of a conditional trait conformance, and the generated API docs show it alongside the trait. Previously the condition was dropped, making a conditional conformance indistinguishable from an unconditional one. Also fixed rendering of some`where`

clauses.

### Removed

This release completes the removal of APIs deprecated during the v1.0 cycle.

-
Removed the temporary

`InlineArray`

alias for`Array`

, including its re-exports from`std.collections`

and the prelude. Use`Array`

directly. -
Removed the

`std.gpu.profiler`

module and its`ProfileBlock`

context manager. It timed host wall-clock, not GPU work, and reported the elapsed time with the operands reversed. Time a block of host code withdirectly, and use a GPU profiler such as Nsight Systems or`perf_counter_ns()`

`rocprof`

for device timings. -
Removed

`memcmp`

and its`std.memory`

re-export. Use`unsafe_memcmp`

instead. -
Removed the

`validate`

parameter from, which now always validates. Passing`b64decode()`

`validate=False`

did not skip any work on valid input; it only turned characters outside the base64 alphabet into silently corrupt output bytes. Drop`[validate=True]`

from existing calls; calls that relied on the default now raise instead of returning garbage. -
Removed the origin aliases left over from the

`Immut`

to`Imm`

and`External`

to`Untracked`

renames. Use the surviving spelling in each case:`ImmOrigin`

for`ImmutOrigin`

,`ImmUnsafeAnyOrigin`

for`ImmutUnsafeAnyOrigin`

,`ImmStaticOrigin`

for`StaticConstantOrigin`

,`UntrackedOrigin`

for`ExternalOrigin`

,`MutUntrackedOrigin`

for`MutExternalOrigin`

, and`ImmUntrackedOrigin`

for both`ImmutUntrackedOrigin`

and`ImmutExternalOrigin`

. -
Removed the pre-unification pointer aliases

`MutUnsafePointer`

,`ImmUnsafePointer`

,`ImmutUnsafePointer`

,`ImmutOpaquePointer`

,`ImmutPointer`

, and`OptionalUnsafePointer`

. Use`MutPointer`

,`ImmPointer`

,`ImmOpaquePointer`

, and`OptionalPointer`

instead.`UnsafePointer`

itself remains available, but is deprecated in favor of`Pointer`

. -
Removed the raw memory functions superseded by their

`unsafe_`

-prefixed spellings:`memcpy`

,`memset`

,`memset_zero`

,`uninit_move_n`

,`uninit_copy_n`

, and`destroy_n`

. Use`unsafe_memcpy`

,`unsafe_memset`

,`unsafe_memset_zero`

,`unsafe_uninit_move_n`

,`unsafe_uninit_copy_n`

, and`unsafe_destroy_n`

instead. -
Removed the

`size`

aliases left from the`size`

to`length`

rename:`SIMD.size`

,`Array.size`

,`TypeList.size`

, and the`SIMDSize`

alias for`SIMDLength`

. Use`length`

and`SIMDLength`

. -
Removed the

`as_immutable()`

and`get_immutable()`

methods on`Pointer`

,`Span`

, and`StringSpan`

. Use`as_imm()`

. -
Removed the

`ImmutSpan`

alias. Use`ImmSpan`

. -
Removed

`String.as_string_slice()`

. Construct a`StringSpan`

from the string instead:`StringSpan(my_string)`

. -
Removed the

`ImplicitlyDestructible`

and`ImplicitlyDeletable`

aliases. Use`Deinitable`

. -
Removed the deprecated ownership-transfer methods:

`List.steal_data()`

and`OwnedPointer.steal_data()`

are now`unsafe_take_allocation()`

,`OwnedPointer.take()`

is`into_inner()`

, and`Variant.take()`

and`Variant.unsafe_take()`

are`unwrap()`

and`unsafe_unwrap()`

. -
Removed the

`Pointer`

methods superseded by their`unsafe_`

-prefixed spellings:`as_noalias_ptr()`

,`destroy_pointee()`

,`destroy_pointee_with()`

,`init_pointee_move()`

,`init_pointee_copy()`

, and`init_pointee_move_from()`

. Use`unsafe_as_noalias()`

,`unsafe_deinit_pointee()`

,`unsafe_deinit_pointee_with()`

,`unsafe_write()`

, and`unsafe_write_move_from()`

. The`Pointer.type`

alias for`Pointer.T`

is gone as well. -
Removed the

`ConditionalType`

type function and the`std.utils.type_functions`

module. Use the ternary expression`T if cond else U`

. -
Removed

`trait_downcast()`

. Constrain on the trait instead, with`conforms_to(type_of(src), Trait)`

in a`where`

clause or a`comptime assert`

. -
Removed the parametric

`benchmark.run[func]()`

overloads. Pass the function as an argument to`run(f)`

instead, which accepts a unified closure. -
Removed

`AnyCoroutine`

,`Coroutine`

and`RaisingCoroutine`

from the prelude, and made the module that defines them private. Mojo's async support is unfinished, and these types being globally visible led people to build on an API that carries no stability guarantees.`async def`

is unaffected: the compiler still synthesizes these types for you, so they continue to appear in inferred types and diagnostics. There is no supported way to name them directly. -
Removed the async task API from the public

`std.runtime.asyncrt`

module, which is now private.`initialize_runtime()`

and`parallelism_level()`

are unaffected and have moved up to the`std.runtime`

package, so import them from`std.runtime`

instead of`std.runtime.asyncrt`

. -
Removed support for

`.mojopkg`

files after a period of deprecation. Use`.mojoc`

files instead.

### Fixed

-
`mojo build --emit asm`

and`--emit llvm`

now always write the offload kernel files next to the host output file. Building a kernel that an earlier build had already compiled could write them into the earlier build's output directory, or skip them with no diagnostic. -
Parametric

`raises`

now accepts any primary expression as the thrown type in a function signature, matching the syntax positions where types otherwise appear. This most notably fixes`raises Self.SomeAssocType`

on trait and struct methods, which would previously fail with an error. The parenthesized workaround (`raises (Self.DriveErrorType)`

) is no longer required. -
An integer

`range()`

with a step of zero is now always empty. It previously used to be an infinite loop - iterating forever at runtime, and hanging the compiler at comptime. -
Fixed

`ceildiv()`

returning`0`

for unsigned operands near the type's maximum value. The unsigned code path computed`numerator + denominator - 1`

, which overflows and wraps for large operands; it now derives the ceiling from the floor division and remainder instead. -
`Counter.most_common(n)`

now returns all elements when`n`

exceeds the number of unique elements, matching Python, instead of aborting. -
`os.path.join()`

now inserts separators based on the accumulated path rather than the first argument, so`join("/", "a", "b")`

returns`/a/b`

(previously`/ab`

) and`join("a", "b/", "c")`

returns`a/b/c`

(previously`a/b//c`

). -
`base64.b64decode()`

now raises an error when the input length is not divisible by 4 instead of reading past the end of the input (or aborting when asserts are enabled). -
On macOS,

`os.stat()`

and`os.lstat()`

no longer return a negative`st_mode`

for regular files. The underlying`mode_t`

and`nlink_t`

C type aliases were declared as signed 16-bit integers, but macOS defines them as unsigned, so any mode with the`S_IFREG`

bit set (every regular file) sign-extended into a negative`Int`

. -
`PythonObject`

no longer leaks a CPython reference per positional argument when calling a Python object, nor when setting an item, attribute, or set literal element.
