From 22ba66fb8ab3ef2d3cc81931060229c99132e1de Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Wed, 23 Jul 2025 09:06:31 -0500 Subject: [PATCH] Document type coercions --- .../noir/concepts/data_types/coercions.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 docs/docs/noir/concepts/data_types/coercions.md diff --git a/docs/docs/noir/concepts/data_types/coercions.md b/docs/docs/noir/concepts/data_types/coercions.md new file mode 100644 index 00000000000..99db92fccc1 --- /dev/null +++ b/docs/docs/noir/concepts/data_types/coercions.md @@ -0,0 +1,55 @@ +--- +title: Type Coercions +description: + Noir's various type coercions +keywords: + [ + noir, + types, + coercions, + casts, + ] +sidebar_position: 11 +--- + +When one type is required in Noir code but a different type is given, the compiler will typically issue +a type error. There are a few cases however where the compiler will instead automatically perform a +type coercion. These are typically limited to a few type pairs where converting from one to the other +will not sacrifice performance or correctness. Currently, Noir will will try to perform the following +type coercions: + +| Actual Type | Expected Type | +| ------------- | --------------------------- | +| `[T; N]` | `[T]` | +| `fn(..) -> R` | `unconstrained fn(..) -> R` | +| `str` | `CtString` | +| `&mut T` | `&T` | + +Note that: +- Conversions are only from the actual type to the expected type, never the other way around. +- Conversions are only performed on the outermost type, they're never performed within a nested type. +- `CtString` is a compile-time only type, so this conversion is only valid in [comptime code](../../concepts/comptime.md). +- `&T` requires the experimental `-Zownership` flag to be enabled. + +Examples: +```noir +fn requires_slice(_slice: [Field]) {} +comptime fn requires_ct_string(_s: CtString) {} + +fn main() { + let array: [Field; 4] = [1, 2, 3, 4]; + + // Ok - array is converted to a slice + requires_slice(array); + // equivalent to: + requires_slice(array.as_slice()); + + // coerce a constrained function to an unconstrained one: + let f: unconstrained fn([Field]) = requires_slice; + + comptime { + // Passing a str<6> where a CtString is expected + requires_ct_string("hello!") + } +} +```