IMPORTANT: To view this page as Markdown, append `.md` to the URL (e.g. /docs/manual/basics.md). For the complete Mojo documentation index, see llms.txt.
Skip to main content
Version: Nightly
For the complete Mojo documentation index, see llms.txt. Markdown versions of all pages are available by appending .md to any URL (e.g. /docs/manual/basics.md).

Reflected

struct Reflected[T: AnyType]

A compile-time reflection handle type for a Mojo type.

Reflected[T] exposes compile-time introspection of T through static methods. It has no runtime fields — T lives entirely in the compile-time parameter — and is not constructible. Spell access as reflect[T].method() (preferred) or Reflected[T].method().

Member shape — when to use @staticmethod vs a comptime alias:

  • A member that returns a type (e.g. Reflected[FieldT]) is a comptime member alias and is spelled without (). This keeps it composable in type position: reflect[T].field_type["x"].T reads as a type. field_type[name] is the only such member today.
  • A member that returns a value (an Int, StaticString, InlineArray, a TypeList, a typed ref, etc.) is an @staticmethod and is spelled with () — e.g. reflect[T].field_count(), reflect[T].field_names(), reflect[T].field_index["x"](). The () at the call site signals "evaluate this comptime expression to a value." field_types returns a TypeList value (not a type) and so is a static method.

When adding a new member: pick a comptime alias if the result will be used in type position, @staticmethod if it will be assigned to a comptime variable or compared at the call site.

For best performance, assign the result of static methods that return type-level values (such as field_names, field_types, field_count) to comptime variables so the work happens at compile time.

Example:

struct Point:
var x: Int
var y: Float64

def main():
comptime if reflect[Point].is_struct():
comptime names = reflect[Point].field_names()
comptime for i in range(reflect[Point].field_count()):
print(names[i])

Parameters

  • T (AnyType): The type being introspected. The wrapped type is exposed via this parameter, so reflect[T].T is T.

Implemented traits

AnyType, ImplicitlyDestructible

comptime members

field_type

comptime field_type[name: StringLiteral[value]] = Reflected[#kgen.struct_field_type_by_name<:trait<@std::@builtin::@anytype::@AnyType> T, #kgen.param.decl.ref<"name.value`1"> : !kgen.string>]

A reflection handle type for the named field's type.

The result is Reflected[FieldT], so reflect[T].field_type["x"].T can be used in type position and .name(), .field_count(), etc. compose directly without an additional ().

Note: T must be a concrete type, not a generic type parameter, when looking up by name.

Example:

struct Point:
var x: Int
var y: Float64

def main():
comptime y_type = reflect[Point].field_type["y"]
var v: y_type.T = 3.14 # y_type.T is Float64

Parameters

Methods

is_struct

static is_struct() -> Bool

Returns True if T is a Mojo struct type, False otherwise.

This distinguishes Mojo struct types from MLIR primitive types (such as __mlir_type.index or __mlir_type.i64). The other reflection methods produce a compile error on non-struct types, so is_struct is useful as a comptime if guard when iterating over field types that may contain MLIR primitives.

Example:

def process_type[T: AnyType]():
comptime if reflect[T].is_struct():
print("struct with", reflect[T].field_count(), "fields")
else:
print("non-struct:", reflect[T].name())

Returns:

Bool: True if T is a Mojo struct type, False if it is an MLIR type.

name

static name[*, qualified_builtins: Bool = False]() -> StaticString

Returns the struct name of T.

Example:

struct Point:
var x: Int
var y: Float64

def main():
print(reflect[Point].name()) # "Point" (or module-qualified if defined)

Parameters:

  • qualified_builtins (Bool): Whether to print fully qualified builtin type names (e.g. std.builtin.int.Int) or shorten them (e.g. Int).

Returns:

StaticString: Type name.

base_name

static base_name() -> StaticString

Returns the name of the base type of a parameterized type.

For parameterized types like List[Int], this returns "List". For non-parameterized types, it returns the type's simple name.

Unlike name, this method strips type parameters and returns only the unqualified base type name.

Example:

from std.collections import List, Dict

def main():
print(reflect[List[Int]].base_name()) # "List"
print(reflect[Dict[String, Int]].base_name()) # "Dict"
print(reflect[Int].base_name()) # "Int"

Returns:

StaticString: The unqualified name of the base type as a StaticString.

field_count

static field_count() -> Int

Returns the number of fields in struct T.

Constraints:

T must be a struct type.

Returns:

Int: The number of fields in the struct.

field_types

static field_types() -> TypeList[#kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>]

Returns the types of all fields in struct T as a TypeList.

For nested structs this returns the struct type itself, not its flattened fields.

Example:

struct Point:
var x: Int
var y: Float64

def main():
comptime types = reflect[Point].field_types()
comptime for i in range(reflect[Point].field_count()):
print(reflect[types[i]].name())

Constraints:

T must be a struct type.

Returns:

TypeList[#kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>]: A TypeList with one entry per field in the struct.

field_names

static field_names() -> InlineArray[StringSlice[StaticConstantOrigin], TypeList[#kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>].size]

Returns the names of all fields in struct T.

Constraints:

T must be a struct type.

Returns:

InlineArray[StringSlice[StaticConstantOrigin], TypeList[#kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>].size]: An InlineArray of StaticString, one entry per field.

field_index

static field_index[name: StringLiteral[name.value]]() -> Int

Returns the index of the field with the given name in struct T.

Note: T must be a concrete type, not a generic type parameter, when looking up by name.

Parameters:

Returns:

Int: The zero-based index of the field.

field_ref

static field_ref[idx: Int](ref s: T) -> ref[s_is_mut] #kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>[idx]

Returns a reference to the field at the given index in s.

Returns a reference rather than a copy, so this works with non-copyable field types and supports mutation through the result.

Example:

@fieldwise_init
struct Container:
var id: Int
var name: String

def main():
var c = Container(id=1, name="test")
reflect[Container].field_ref[0](c) = 42 # mutates c.id

Constraints:

T must be a struct type. idx must be in range [0, field_count()).

Parameters:

  • idx (Int): The zero-based index of the field.

Args:

  • s (T): The struct value to access.

Returns:

ref[s_is_mut] #kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>[idx]: A reference to the field at the specified index, with the same mutability as s.

field_offset

static field_offset[*, name: StringLiteral[name.value], target: __mlir_type.`!kgen.target` = _current_target()]() -> Int

Returns the byte offset of the named field within struct T.

Accounts for alignment padding between fields. Computed using the target's data layout.

Example:

struct Point:
var x: Int # offset 0
var y: Float64 # offset 8

def main():
comptime x_off = reflect[Point].field_offset[name="x"]() # 0
comptime y_off = reflect[Point].field_offset[name="y"]() # 8

Constraints:

T must be a struct type with a field of the given name.

Parameters:

  • name (StringLiteral[name.value]): The name of the field.
  • target (__mlir_type.`!kgen.target`): The target architecture (defaults to the current target).

Returns:

Int: The byte offset of the field from the start of the struct.

static field_offset[*, index: Int, target: __mlir_type.`!kgen.target` = _current_target()]() -> Int

Returns the byte offset of the field at the given index.

Accounts for alignment padding between fields. Computed using the target's data layout.

Constraints:

T must be a struct type. index must be in range [0, field_count()).

Parameters:

  • index (Int): The zero-based index of the field.
  • target (__mlir_type.`!kgen.target`): The target architecture (defaults to the current target).

Returns:

Int: The byte offset of the field from the start of the struct.