@nonmaterializable
You can add the @nonmaterializable
decorator on a struct to declare that the
type can exist only in the parameter domain (it can be used for metaprogramming
only, and not as a runtime type). And, if an instance of this type does
transition into the runtime domain, this decorator declares what type it
becomes there.
To use it, declare your type with @nonmaterializable(TargetType)
, where
TargetType
is the type that the object should convert to if it becomes a
runtime value (you must declare the TargetType
). For example, if a struct is
marked as @nonmaterializable(Foo)
, then anywhere that it goes from a
parameter value to a runtime value, it automatically converts into the Foo
type.
For example, the following ParamStruct
type can be used in the parameter
domain, but the runtime_struct
instance of it is converted to a
RuntimeStruct
when it's materialized as a runtime value:
@fieldwise_init
@register_passable("trivial")
struct RuntimeStruct:
var value: Int
@implicit
fn __init__(out self, nms: ParamStruct):
self.value = nms.param_value
@nonmaterializable(RuntimeStruct)
@register_passable("trivial")
struct ParamStruct[param_value: Int]:
fn __init__(out self):
pass
fn __add__(
self, rhs: ParamStruct
) -> ParamStruct[self.param_value + rhs.param_value]:
return ParamStruct[self.param_value + rhs.param_value]()
def main():
alias still_param_struct = ParamStruct[1]() + ParamStruct[2]()
print(still_param_struct.param_value)
# When materializing to a run-time variable, it is automatically converted,
# even without a type annotation.
var runtime_struct = still_param_struct
print(runtime_struct.value)
@fieldwise_init
@register_passable("trivial")
struct RuntimeStruct:
var value: Int
@implicit
fn __init__(out self, nms: ParamStruct):
self.value = nms.param_value
@nonmaterializable(RuntimeStruct)
@register_passable("trivial")
struct ParamStruct[param_value: Int]:
fn __init__(out self):
pass
fn __add__(
self, rhs: ParamStruct
) -> ParamStruct[self.param_value + rhs.param_value]:
return ParamStruct[self.param_value + rhs.param_value]()
def main():
alias still_param_struct = ParamStruct[1]() + ParamStruct[2]()
print(still_param_struct.param_value)
# When materializing to a run-time variable, it is automatically converted,
# even without a type annotation.
var runtime_struct = still_param_struct
print(runtime_struct.value)
The materialized struct must have an @implicit
conversion constructor that
takes an instance of the non-materializable struct as input (as shown in the
code example).
Also, since the non-materializable type only exists in the parameter domain, all of its methods must be able to run in the parameter domain.
Was this page helpful?
Thank you! We'll create more content like this.
Thank you for helping us improve!