cairo-lang-semantic 2.21.0

Cairo semantic model.
Documentation
//! > Test instantiation.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
struct MyStruct {}

#[phantom]
enum MyEnum {
    a: felt252,
}
fn foo() {
    MyStruct {};
    MyEnum::a(3);
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:9:5
    MyStruct {};
    ^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:10:5
    MyEnum::a(3);
    ^^^^^^^^^^^^

//! > ==========================================================================

//! > Attribute argument with modifier keyword.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > cairo_code
#[cfg(ref x)]
fn f() {}

//! > expected_diagnostics

//! > ==========================================================================

//! > Phantom enum inside a generic container in a function signature.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
enum Ph {
    A: felt252,
    B: (felt252, felt252),
}
fn foo(x: Option<Ph>) -> Option<Ph> {
    x
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:6:8
fn foo(x: Option<Ph>) -> Option<Ph> {
       ^^^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:6:26
fn foo(x: Option<Ph>) -> Option<Ph> {
                         ^^^^^^^^^^

//! > ==========================================================================

//! > Phantom struct inside a generic container in a function signature.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
struct Ph {
    a: felt252,
    b: felt252,
}
fn foo(x: Option<Ph>) -> Option<Ph> {
    x
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:6:8
fn foo(x: Option<Ph>) -> Option<Ph> {
       ^^^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:6:26
fn foo(x: Option<Ph>) -> Option<Ph> {
                         ^^^^^^^^^^

//! > ==========================================================================

//! > Phantom type reached through a non-phantom generic struct's member in a signature.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
struct Ph {
    a: felt252,
}

struct Wrapper<T> {
    value: T,
}
fn foo(x: Wrapper<Ph>) -> Wrapper<Ph> {
    x
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:9:8
fn foo(x: Wrapper<Ph>) -> Wrapper<Ph> {
       ^^^^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:9:27
fn foo(x: Wrapper<Ph>) -> Wrapper<Ph> {
                          ^^^^^^^^^^^

//! > ==========================================================================

//! > Phantom type behind a snapshot in a function signature.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
enum Ph {}
fn foo(x: @Ph) {}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:3:8
fn foo(x: @Ph) {}
       ^^^^^^

//! > ==========================================================================

//! > Phantom type as an implicit parameter.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
enum Ph {}
fn foo() implicits(Ph) {}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:3:20
fn foo() implicits(Ph) {}
                   ^^

//! > ==========================================================================

//! > Phantom type in a closure parameter.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
enum Ph {}
fn foo() {
    let _f = |_x: Option<Ph>| {};
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:4:15
    let _f = |_x: Option<Ph>| {};
              ^^^^^^^^^^^^^^

//! > ==========================================================================

//! > Array of a phantom type.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
enum Ph {
    A: felt252,
}
fn foo(x: Array<Ph>) -> Array<Ph> {
    x
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:5:8
fn foo(x: Array<Ph>) -> Array<Ph> {
       ^^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:5:25
fn foo(x: Array<Ph>) -> Array<Ph> {
                        ^^^^^^^^^

//! > ==========================================================================

//! > Array of an empty phantom struct is reported as phantom, not zero-sized.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
struct Ph {}
fn foo(x: Array<Ph>) -> Array<Ph> {
    x
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:3:8
fn foo(x: Array<Ph>) -> Array<Ph> {
       ^^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:3:25
fn foo(x: Array<Ph>) -> Array<Ph> {
                        ^^^^^^^^^

//! > ==========================================================================

//! > Array of a phantom type as a struct member.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
enum Ph {
    A: felt252,
}

struct S {
    x: Array<Ph>,
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:7:5
    x: Array<Ph>,
    ^^^^^^^^^^^^

//! > ==========================================================================

//! > Phantom type nested in an array inside a Span.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
enum Ph {
    A: felt252,
}
fn foo(x: Span<Ph>) -> Span<Ph> {
    x
}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:5:8
fn foo(x: Span<Ph>) -> Span<Ph> {
       ^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:5:24
fn foo(x: Span<Ph>) -> Span<Ph> {
                       ^^^^^^^^

//! > ==========================================================================

//! > Zero-sized type nested in an array inside a Span.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
fn foo(x: Span<()>) -> Span<()> {
    x
}

//! > expected_diagnostics
error[E2053]: Cannot have array of type "()" that is zero sized.
 --> lib.cairo:1:8
fn foo(x: Span<()>) -> Span<()> {
       ^^^^^^^^^^^

error[E2053]: Cannot have array of type "()" that is zero sized.
 --> lib.cairo:1:24
fn foo(x: Span<()>) -> Span<()> {
                       ^^^^^^^^

//! > ==========================================================================

//! > Phantom array reached through a cycle of array-recursive types.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > cairo_code
#[phantom]
enum Ph {
    A: felt252,
}

struct A {
    b: Array<B>,
}

struct B {
    a: Array<A>,
    bad: Array<Ph>,
}
fn foo(x: B, y: A) {}

//! > expected_diagnostics
error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:7:5
    b: Array<B>,
    ^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:11:5
    a: Array<A>,
    ^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:12:5
    bad: Array<Ph>,
    ^^^^^^^^^^^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:14:8
fn foo(x: B, y: A) {}
       ^^^^

error[E2019]: Phantom types cannot be instantiated.
 --> lib.cairo:14:14
fn foo(x: B, y: A) {}
             ^^^^

//! > ==========================================================================

//! > Type recursive through an array with no bad element is fine (cycle terminates).

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > cairo_code
struct A {
    a: Array<A>,
}
fn foo(x: A) {}

//! > expected_diagnostics