Nightly: v0.26.2
This version is still a work in progress.
✨ Highlights
Language enhancements
-
Mojo now supports specifying default value for inferred parameter, it make it easier to create a partially bound type like
struct Pointer[mut = False, // o: Origin[mut]] : pass # Default to immutable pointer comptime ImmPointer = Pointer[_] # Explicitly set to mutable pointer comptime mutPointer = Pointer[mut = True, _] # Inferred mutability from `SomeOrigin()` comptime InferredPointer = Pointer[SomeOrigin()] # Parametric mutability pointer. comptime ParametricPointer = Pointer[...] -
Mojo now supports a standalone
assertstatement, similar to Python'sassert. It checks a condition at runtime and aborts the program if the condition is false:assert x > 0, "x must be positive" assert len(items) != 0The condition must be a
Boolexpression and the optional message can be anyWritableexpression (StringLiteral,String,Int, etc.). Under the hood,assertdesugars to a call todebug_assert, so it respects the existing-D ASSERTflag: assertions are active when compiled with-D ASSERT=alland are no-ops otherwise. -
Mojo now enforces a more explicit parameter bindings rules:
-
[]is mandatory to make type more concrete:struct SomeStruct[a : Int = 1]: pass # SS1 is a parametric type comptime SS1 = SomeStruct # SS2 a concrete type alias of `SomeStruct[1] comptime SS2 = SomeStruct[] -
When
[]is used, it must produce a concrete type unless_/...is used to unbind a specific/multiple missing parameters.struct SomeStruct[a : Int, b: Int, c: Int = 2]: pass # Error: can not infer `b`, since `[]` must produce a concrete type, without `_`/`...`` comptime SS1 = SomeStruct[1] # This is a concrete type alias of `SomeStruct[1, 1, 2]` comptime SS2 = SomeStruct[1, 1] # Using `...` defers binding of b and c, and produces `SomeStruct[1, ?, ?]` (preserving possible defaults) comptime SS3 = SomeStruct[1, ...] # Even SS3 unbinds `c`, Mojo keeps track of the fact that there is a default value for c: # This install b (using 1) and c (using default value), and produce `SomeStruct[1, 1, 2]` comptime SS4 = SS3[1] # This installs the default and is identical to `SomeStruct[1, ?, 2]` comptime SS5 = SomeStruct[1, _] # This unbind the default explicitly and is identical to `SomeStruct[1, ?, ?]` comptime SS6 = SomeStruct[1, _, _] # The following two are equivalent: comptime SS7 = SomeStruct comptime SS8 = SomeStruct[...]
-
-
Mojo now supports t-strings (template strings) for building structured string templates with interpolated expressions. T-strings use the
t"..."prefix and produce aTStringvalue that captures both the static format string and any runtime arguments, rather than immediately producing aString:fn main(): var x = 10 var y = 20 print(t"{x} + {y} = {x + y}") # prints: 10 + 20 = 30Use
{{and}}to include literal braces in the output:print(t"Use {{braces}} like this") # prints: Use {braces} like this -
Mojo now supports
comptime ifandcomptime foras the preferred syntax for compile-time conditional and loop constructs, replacing the legacy@parameter ifand@parameter fordecorator forms:# Old syntax (still accepted, deprecated in a future release) @parameter if some_condition: ... @parameter for i in range(10): ... # New syntax comptime if some_condition: ... comptime for i in range(10): ...Both syntaxes are accepted in this release. The
@parameterforms will be deprecated soon, and the parser will generate a warning and a fixit suggestion to migrate to the new syntax. -
@register_passable("trivial")is now deprecated, conform toTrivialRegisterPassabletrait instead. The decorator will be removed after next release. -
@register_passableis now deprecated, conform toRegisterPassabletrait instead. The decorator will be removed after next release. -
Mojo now supports more flexible default arguments and parameters, which can mismatch on declared type when their types are parametric. This allows inferring parameters from these when they are used as a default value, for example:
fn take_string_slice[o: ImmOrigin](str: StringSlice[o] = ""): ... fn use_it(): take_string_slice() # Ok, defaults to empty string, inferring "o". # Explicit calls also work of course. take_string_slice(StaticString("hello")) # Default value is checked for validity at the call site. fn defaultArgumentBadType2[T: AnyType](a: T = 1.0): pass fn callDefaultArgumentBadType2(): # Ok! defaultArgumentBadType2[Float64]() # error: value passed to 'a' cannot be converted from 'FloatLiteral[1]' to 'Int' defaultArgumentBadType2[Int]() -
Mojo now supports the
@align(N)decorator to specify minimum alignment for structs, similar to C++'salignasand Rust's#[repr(align(N))]. The valueNmust be a positive power of 2 and specifies the minimum alignment in bytes. The actual alignment will bemax(N, natural_alignment)- you cannot use@alignto reduce alignment below the struct's natural alignment. For example,@align(1)on a struct containing anInt(8-byte aligned) will emit a warning and the struct will remain 8-byte aligned.from sys import align_of @align(64) struct CacheAligned: var data: Int fn main(): print(align_of[CacheAligned]()) # Prints 64Both stack and heap allocations respect
@align.The alignment value can also be a struct parameter, enabling generic aligned types:
@align(Self.alignment) struct AlignedBuffer[alignment: Int]: var data: Int fn main(): print(align_of[AlignedBuffer[64]]()) # Prints 64 print(align_of[AlignedBuffer[128]]()) # Prints 128 -
Mojo now allows move constructors to take their "take" argument as either
deinitorvar.deinitshould be generally preferred, butvarcan be useful in unusual cases where you want C++-like behavior where the destructor still runs on the value after the move constructor is done with it.fn __init__(out self, *, var take: Self): self.data = munge(take.data) # take.__del__() runs here. -
deffunctions now allows araisesspecifier, and support typed errors.defwill soon require an exception specifier to throw, so we strongly recommend changingdeffunctions to have an explicitraiseskeyword. To help with migration, the Mojo compiler now produces a warning fordeffunctions that lack araisesspecifier.# Older behavior def foo(): # implicitly raises Error. def bar() raises: # was invalid # Current behavior def bar(): # Still implicitly raises Error (not recommended; warns) def bar() raises: # Explicit raises Error (recommended) # Near future behavior def bar(): # Does not raise. def bar() raises: # Explicit raises Error (required)
Language changes
-
**_and*_are no longer supported in parameter binding lists. Use a more concise...to unbind any unspecified parameter explicitly. -
As part of "init unification", the
__moveinit__and__copyinit__methods are now renamed tofn __init__(out self, *, take: Self)andfn __init__(out self, *, copy: Self)respectively. Mojo now accepts these names for initializers, but also supports the legacy__moveinit__and__copyinit__names as well (for now). However, the argument name for these legacy methods must now be namedtakeandcopyrespectively. Please move to the more modern__init__names when possible. -
As part of init unification, the
__moveinit__is_trivialand__copyinit__is_trivialmembers ofMovableandCopyablehave been renamed to__move_ctor_is_trivialand__copy_ctor_is_trivialrespectively. -
Homogenous variadic parameters are now passed with the
VariadicParamListtype (formerly known asVariadicList) and arguments are now passed consistently passed withVariadicList(formerlyVariadicListMem) instead of trivial types being passed directly. -
Slice literals in subscripts has changed to be more similar to collection literals. They now pass an empty tuple as a required
__slice_literal__keyword argument to disambiguate slices. If you have defined your own range types, please add a__slice_literal__: () = ()argument to their constructors. -
traitdeclarations no longer automatically inherit fromImplicitlyDestructible.structdeclarations are not changed, and continue to inherit fromImplicitlyDestructible.Previously, the
@explicit_destroyannotation was required to opt-out ofImplicitlyDestructibleconformance. Now, if a trait's usage depends on implicit destructibility, it must opt-in explicitly:# Before trait Foo: ... # After: trait Foo(ImplicitlyDestructible): ...Conversely, if a trait wanted to support non-implicitly-destructible types, it no longer needs to be annotated with
@explicit_destroy:# Before @explicit_destroy trait Foo: ... # After trait Foo: ...Making
structcontinue to inherit fromImplicitlyDestructibleand nottraitis intended to balance usability and familiarity in the common case, with the need to foster broad Mojo ecosystem support for explicitly destroyed types.It's not a problem if the majority of
structtypes areImplicitlyDestructiblein practice. However, if many ecosystem libraries are written with unnecessaryImplicitlyDestructiblebounds, that would hamper the usability of any individualstructtype that opts-in to being explicitly destroyed.Libraries with generic algorithms and types should be written to accommodate linear types. Making
ImplicitlyDestructibleopt-in for traits encourages a default stance of support, with specific types and functions only opting-in to the narrowerImplicitlyDestructiblerequirement if they truly need it.The majority of generic algorithms that take their inputs by reference should not be affected.
-
Unstable
__comptime_assertsyntax is now finalized ascomptime assert. A deprecation warning is emitted with a fixit for the old syntax. -
comptime assertno longer errors on always false conditions. The assertion will only trigger if its parent scope is concretized. -
A statically False
comptime assertnow ends a scope. Any code following it in the same scope is now a warning, and can be removed. -
Re-exported symbols from a package's
__init__.mojoare no longer shadowed by a submodule of the same name. For example, ifpkg/foo.mojodefinesfn fooandpkg/__init__.mojodoesfrom .foo import foo, thenfrom pkg import fooandfrom pkg import *now correctly resolve to the function rather than the module. -
is_compile_time()has been renamed tois_run_in_comptime_interpreter()to provide a mechanism for supporting different code execution path in comptime interpreter from runtime generated code. The check should be used as condition for runtimeif. Compiler now warns if it is used as condition forcomptime if.
Library changes
-
StaticTuplenow supports comparison operators.__eq__/__ne__are available whenelement_type: Equatable, and__lt__/__le__/__gt__/__ge__are available whenelement_type: Comparable. All use lexicographic ordering with compile-time unrolled loops. -
Dictnow uses real conditional conformances forWritable. TheDicttype only conforms toWritablewhen both its key and value types do, enforced at compile time viawhereclauses. -
Standard library types now use conditional conformances, replacing previous
_constrained_conforms_tochecks:Dict:WritableInlineArray:WritableList:Equatable,WritableOptional:WritableSet:WritableTuple:WritableVariant:Writable
-
lane_group_sum(),lane_group_max(), andlane_group_min()instd.gpu.primitives.warpnow always broadcast the reduction result to all participating lanes, using optimized hardware-specific paths (AMD DPP, Blackwell redux, or butterfly shuffle pattern). The previouslane_group_sum_and_broadcast(),lane_group_max_and_broadcast()functions are deprecated — use the short names instead. -
Boolno longer conforms to theIndexertrait. Previously,Boolcould be used to index into collections (e.g.,nums[True]), which is not desirable behavior for a strongly-typed language. UseInt(my_bool)to explicitly convert aBoolto an index. -
The
StringableandRepresentabletraits are now deprecated. UseWritableinstead to make your types formattable as strings.Writableprovides a default implementation, so in many cases simply addingWritableconformance is enough without manually implementingwrite_to()orwrite_repr_to(), however, you can manually implement these to get custom output. -
The
env_get_bool(),env_get_int(),env_get_string(), andenv_get_dtype()functions in thesys.param_envmodule have been renamed toget_defined_bool(),get_defined_int(),get_defined_string(), andget_defined_dtype()in the newsys.definesmodule. The new names better reflect that these functions read compile-time defines (set via-D), not runtime environment variables. Theis_defined()function has also moved tosys.defineswithout renaming. The old names insys.param_envare deprecated but still available. -
TString.write_to()now uses a compact encoding for format strings. The format string is flattened at compile time into NUL-terminated literal segments, producing considerably smaller static data and faster runtime than the previous struct-based precompiled entries. -
Set.pop()now usesDict.popitem()directly, avoiding a redundant rehash. Order changes from FIFO to LIFO, matching Python's unorderedset.pop(). -
Set.__gt__()andSet.__lt__()now use an O(1)len()check plus a singleissubset()traversal instead of two full traversals. -
Added
uninit_move_n(),uninit_copy_n(), anddestroy_n()functions to thememorymodule for efficient bulk memory operations. These functions handle moving, copying, and destroying multiple values in contiguous memory, with automatic optimization for trivial types usingmemcpy. They encapsulate the common pattern of checking__move_ctor_is_trivial,__copy_ctor_is_trivial, or__del__is_trivialand selecting the appropriate implementation. TheListcollection now uses these functions internally for improved code clarity and maintainability. -
Dictinternals have been replaced with a Swiss Table implementation using SIMD group probing for lookups. This improves lookup, insertion, and deletion performance — especially when looking up keys not in the dict — while increasing the load factor from 2/3 to 7/8 for better memory efficiency. Thepower_of_two_initial_capacitykeyword argument has been renamed tocapacityand now accepts any positive integer (it is rounded up to the next power of two internally, minimum 16). -
Dictnow performs in-place tombstone rehashing when the table is full of tombstones but the live element count is low. This prevents unnecessary capacity doubling after repeated insert/delete cycles. -
Implicit conversions from
InttoSIMDare now deprecated, and will be removed in a future version of Mojo. This includes deprecating converions fromIntto specificSIMDscalar types likeInt8orFloat32.Note: The experimental
mojo build --experimental-fixitcommand may be useful in assiting with migrating your code to reflect this change.Code currently relying on implicit conversions, e.g.:
fn foo(arg: Int) -> Float32: return argshould be changed to use an explicit conversion:
fn foo(arg: Int) -> Float32: return Float32(arg)Occasionally, when an implicit conversion was happening from a scalar
Intto a widerSIMDvalue, the compiler will suggest a change to make the conversion explicit that is somewhat verbose, performing both the type conversion and the "splat" in a single step:var bits: SIMD[DType.uint8, 16] = ... - var y = bits >> (j * 4) + var y = bits >> SIMD[DType.uint8, 16](j * 4)a simpler change is to make the type conversion explicit, and let the "splat" continue to happen implicitly (which will remain supported):
var bits: SIMD[DType.uint8, 16] = ... - var y = bits >> (j * 4) + var y = bits >> UInt8(j * 4)A similar overly verbose suggestion can be emitted relating to
LayoutTensor.element_type, where the compiler may suggest a change of the form:- tensor[i] = i * l + tensor[i] = LayoutTensor[DType.uint32, Layout(IntTuple(-1)), stack].element_type(i * l)where a simpler change is sufficient:
- tensor[i] = i * l + tensor[i] = UInt32(i * l) # Note: If the tensors `dtype` is not statically known, this works as well: + tensor[i] = Scalar[tensor.dtype](i * l) -
The
builtin.mathmodule has been merged intomath. The traitsAbsable,DivModable,Powable,Roundableand functionsabs(),divmod(),max(),min(),pow(),round()are now part of themathmodule and continue to be available in the prelude. Code that explicitly imported frombuiltin.mathshould update to import frommathinstead. -
The
ffimodule is now a top-level module in the standard library, rather than being nested undersys. This improves discoverability of FFI functionality. Update your imports fromfrom sys.ffi import ...tofrom ffi import .... -
Added
UnsafeUnion[*Ts], a C-style untagged union type for FFI interoperability. UnlikeVariant,UnsafeUniondoes not track which type is stored (no discriminant), making it suitable for interfacing with C unions and low-level type punning. The memory layout exactly matches C unions (size is max of elements, alignment is max of elements).All element types must have trivial copy, move, and destroy operations, matching C union semantics where types don't have constructors or destructors.
Construction is explicit (no implicit conversion) to emphasize the unsafe nature of this type. All accessor methods are prefixed with
unsafe_to make it clear that these operations are unsafe.from ffi import UnsafeUnion # Define a union that can hold Int32 or Float32 comptime IntOrFloat = UnsafeUnion[Int32, Float32] var u = IntOrFloat(Int32(42)) print(u.unsafe_get[Int32]()) # => 42 print(u) # => UnsafeUnion[Int32, Float32](size=4, align=4) # Type punning (reinterpreting bits) var u2 = IntOrFloat(Float32(1.0)) print(u2.unsafe_get[Int32]()) # => 1065353216 (IEEE 754 bits) -
The
itertoolsmodule now includes three new iterator combinators:cycle(iterable): Creates an iterator that cycles through elements indefinitelytake_while[predicate](iterable): Yields elements while the predicate returns Truedrop_while[predicate](iterable): Drops elements while the predicate returns True, then yields the rest
-
Math functions in
std.math(exp,exp2,log2,erf,tanh,sin,cos,tan,acos,asin,atan,atan2,acosh,asinh,atanh,cosh,sinh,expm1,log10,log1p,logb,cbrt,erfc,j0,j1,y0,y1) now usewhere dtype.is_floating_point()clauses on their signatures instead of__comptime_assertchecks in their bodies. This provides better compile-time error messages at the call site. Callers using these functions with genericdtypeparameters may need to add evidence proving (either awhereclause or__comptime_assert) that their type is floating point. -
Many kernels in
nnhave been migrated to useTileTensor. We will have more documentation onTileTensorand its uses over the coming weeks. -
InlineArraynow requires explicitly using literals for construction. E.g.var a: InlineArray[UInt8, 4] = [1, 2, 3, 4] # instead of InlineArray[UInt8, 4](1, 2, 3, 4) -
The following types now conform to
Writableand have custom implementations ofwrite_toandwrite_repr_to.TupleVariantOptional
-
The
stdlibis beginning to remove support for theStringableandRepresentabletraits in favor of the unifiedWritabletrait. Most stdlib types have had their conformance toStringableandRepresentableremoved and the associated__str__()and__repr__()methods have been deprecated. -
The
testingmodule now providesassert_equalandassert_not_equaloverloads forTuple, enabling direct tuple-to-tuple comparisons in tests instead of element-by-element assertions. Element types must conform toEquatable & Writable. -
The
__reversed__()method onString,StringSlice, andStringLiteralhas been deprecated in favor of the newcodepoints_reversed()method. The new method name makes it explicit that iteration is over Unicode codepoints in reverse order, maintaining consistency with the existingcodepoints()andcodepoint_slices()methods. The deprecated__reversed__()methods will continue to work but will emit deprecation warnings. -
The
Originstruct now takes the underlying MLIR origin as a parameter instead of storing it. This follows the design ofIntLiteraland related types, and fixes some memory safety problems. -
The
StringSliceconstructor fromStringnow propagates mutability. If you have a mutable reference to aString,StringSlice(str)returns a mutableStringSlice. TheString.as_string_slice()method is now deprecated in favor of theStringSlice(str)constructor, andString.as_string_slice_mut()has been removed. -
String.ljust,String.rjust, andString.centerhave been renamed toString.ascii_ljust,String.ascii_rjust, andString.ascii_center. Likewise for their mequivalents onStringSliceandStaticString -
String.resizewill now panic if the new length would truncate a codepoint. Previously it would result in a string with invalid UTF-8. -
String.resizewill now panic iffill_byteis >=128. Previously it would create invalid UTF-8. -
Subscripting into
StringandStringSlicewill now panic if the index falls in the middle of a UTF-8 encoded code-point. Previously they would return invalid UTF-8. This panic is unconditional. Use.as_bytes()[...]if you really want the previous behavior. -
StringSlice[byte=]subscripting now returns aStringSliceinstead of aString, This is consistent with range-based subscripting. -
Subscripting
StringandStringSliceby byte position will now return an entire Unicode codepoint. Previously it would return a single byte, and produce invalid UTF-8 if the index fell on the starting byte of a multi-byte codepoint. -
The following types now correctly implement
write_repr_toList,Set
-
assert_equalandassert_not_equalnow work with types implementingWritable. -
All traits and structs with
@register_passable("trivial")decorator are now extendingTrivialRegisterPassabletrait. The decorator is removed from them. -
String,StringSlice, andStringLiteral's.format()method now require their arguments to beWritable. -
Formatting compile-time format strings (
StringLiterals) no longer allocates memory! It usesglobal_constantto store what would be heap allocated parsed formatting data. -
Int.__truediv__now performs truncating integer division, returningIntinstead of the previously deprecatedFloat64. Use explicitFloat64casts for floating-point division. -
Documentation for
SIMD.__round__now clarifies the pre-existing behavior that ties are rounded to the nearest even, not away from zero. -
A new
utils/type_functionsmodule was added for holding type functions. Type functions arecomptimedeclarations that produce a type from compile-time parameter inputs. Unlike regularfnfunctions which accept and return runtime values, type functions operate entirely at compile time -- they takecomptimeparameters and evaluate to a type, with no runtime component.ConditionalType- A type function that conditionally selects between two types based on a compile-time boolean condition. It is the type-level equivalent of the ternary conditional expressionThen if If else Else.
-
reflection/traitshas been added, providing compile-time meta functions (AllWritable,AllMovable,AllCopyable,AllImplicitlyCopyable,AllDefaultable,AllEquatable) that evaluate toTrueif all types in a variadic type list conform to the corresponding trait. -
UnsafeMaybeUninithas been renamed as such, and it's methods have had their names updated to reflect theinitname. It also now exposes azeroed()method to get zeroed out uninitialized memory. It also no longer callsabort()when being copied or moved, allowing for more practical uses. -
Added the
UnsafeNicheableandUnsafeSingleNicheabletraits tostd.utils. These traits allow types to expose known-invalid bit patterns ("niches") that can be used by containers likeOptionalandVariantto avoid storing a separate tag, so thatsize_of[Optional[T]]() == size_of[T]().UnsafeSingleNicheableis a simplified subtrait for the common case where a type has exactly one niche value.VariantandOptionalnow automatically take advantage of this: when the variant types qualify, the discriminant tag is elided entirely, reducing the size of the variant. For example,size_of[Optional[T]]() == size_of[T]()for anyTthat implementsUnsafeNicheable.Variantalso only works withMovabletypes in the interim instead ofAnyTypedue to some compiler limitations.
-
Span[T]is no longer restricted toCopyabletypes. It now works withT: AnyType. There are a few restrictions including iteration requiringT: Copyable. -
Int.write_paddednow accounts for a negative sign when calculating the width, resulting in a consistent width regardless of sign:Int(1).write_padded(s, 4) # writes " 1" Int(-1).write_padded(s, 4) # writes " -1" -
SIMDnow has awrite_paddedmethod for integralDTypes, matching the behaviour ofInt.write_padded. The padding is added elementwise. UnlikeSIMDregular printing, there are no spaces added between elements by default:Int32(1).write_padded(s, 4) # writes " 1" Int32(-1).write_padded(s, 4) # writes " -1" # "[ 1, -1, 0,1234]" SIMD[DType.int32, 4](1,-1,0,1234).write_padded(s, 4) # "[255,255]" SIMD[DType.uint8, 2](255).write_padded(s, 1) -
SIMD's safe division operators (__floordiv__,__mod__,__divmod__) now return safe results in an elementwise fashion. They previously returned a zero result if any element of the divisor was zero:comptime Int32x2 = SIMD[DType.int32, 2] var a = Int32x2(99, 99) var b = Int32x2(4, 0) # Now returns [24, 0] # Previously returned [0, 0] print(a.__floordiv__(b)) -
Changed
CompilationTarget.unsupported_target_error()to returnNever, and removed it'sresulttype parameter. -
Remove
DType.get_dtype[T]()andDType.is_scalar[T](). These were low-level operations for extracting theDTypeof aSIMDin generic code. There are better alternatives available in Mojo today using reflection capabilities.
Tooling changes
-
The Mojo compiler now accepts conjoined
-Doptions in addition to the non-conjoined form as before. Now, both-Dfooand-D fooare accepted. -
mojo buildnow supports several--print-*options for discovering target configuration and supported architectures:--print-effective-target: Shows the resolved target configuration after processing all command-line flags.--print-supported-targets: Lists all available LLVM target architectures.--print-supported-cpus: Lists valid CPU names for a given target triple (requires--target-triple).--print-supported-accelerators: Lists all supported GPU and accelerator architectures (NVIDIA, AMD, Apple Metal).
-
mojo formatnow only formats Mojo files (.mojo,.🔥) by default when run on a directory. Previously it would also format Python files, which conflicted with Python-specific formatters in pre-commit hooks. Users who want to format Python files can usemblackdirectly. -
mojo formatnow supports--print-cache-dir(hidden, use--help-hiddento see it) to display the path to the formatter cache directory. -
mojo build --emit=asmnow also emits GPU kernel assembly files alongside the host.soutput. For NVIDIA targets, PTX is written as<out>_<kernelfn>.ptx; for Apple Metal targets, LLVM IR is written as<out>_<kernelfn>.ll; for AMD targets,.amdgcnfiles are written. Multiple kernels generated from the same function are disambiguated with a numeric suffix (e.g.<out>_<kernelfn>_1.ptx).
❌ Removed
-
The
ownedkeyword has been removed. Usevarfor parameters ordeinitfor__moveinit__/__del__arguments as appropriate. -
Dict.EMPTYandDict.REMOVEDcomptime aliases have been removed. These were internal implementation details of the old hash table design. -
The
@nonmaterializabledecorator has been renamed to@__nonmaterializable. This decorator should not be used outside the standard library, and might be removed in a future release.
🛠️ Fixed
-
Fixed a bug where Mojo incorrectly passed or returned structs in
externC function calls. The compiler now applies platform ABI coercion (System V AMD64 on x86-64, AAPCS on ARM64) when lowering external calls, decomposing structs into the register types the C ABI requires — matching the behavior of Clang and Rust. This resolves silent wrong-answer bugs when calling C functions that take or return struct types. -
Issue #5845: Functions raising custom type with conversion fails when returning StringSlice
-
Issue #5722:
__del__incorrectly runs when__init__raises before all fields are initialized. -
Issue #5875: Storing
SIMD[DType.bool, N]with width > 1 to a pointer and reading back element-wise now returns correct values. -
StringSlice.find: Fixed integer overflow bug in SIMD string search that caused searches to fail when searching for strings longer thansimd_width_of[DType.bool]()and haystacks larger than UInt16.MAX. -
LinkedList.reverse(): Fixed missingprevpointer updates, which caused__reversed__()to produce wrong results after reversing. -
Mojo would previously consider types Movable if they had a
__moveinit__method, even if they didn't conform toMovable. Movability is now tied to the conformance which implies the method.
Was this page helpful?
Thank you! We'll create more content like this.
Thank you for helping us improve!