cairo-lang-semantic 2.20.0

Cairo semantic model.
Documentation
//! > different S3 and @S3 derefs.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > function_code
fn foo() {
    let s1 = S1 { a: 1, b: 2 };
    let s2 = S2 { inner: s1, c: 5 };
    let s3 = S3 { inner: s2 };

    (@s3).a;
    s3.c;
}

//! > function_name
foo

//! > module_code
#[derive(Drop, Copy)]
struct S1 {
    a: usize,
    b: felt252,
}

#[derive(Drop, Copy)]
struct S2 {
    inner: S1,
    c: usize,
}

#[derive(Drop)]
struct S3 {
    inner: S2,
}


impl S2Deref of core::ops::Deref<S2> {
    type Target = S1;
    fn deref(self: S2) -> S1 {
        self.inner
    }
}

impl S3Deref of core::ops::Deref<S3> {
    type Target = S2;
    fn deref(self: S3) -> S2 {
        self.inner
    }
}

impl S3SnapDeref of core::ops::Deref<@S3> {
    type Target = S1;
    fn deref(self: @S3) -> S1 {
        *self.inner.inner
    }
}

//! > expected_diagnostics

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

//! > Test method call through deref.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > function_code
fn foo() {
    let s1 = S1 { a: 1, b: 2 };
    let s2 = S2 { inner: s1, c: 5 };

    s2.foo();
}

//! > function_name
foo

//! > module_code
#[derive(Drop, Copy)]
struct S1 {
    a: usize,
    b: felt252,
}

#[derive(Drop, Copy)]
struct S2 {
    inner: S1,
    c: usize,
}

impl S2Deref of core::ops::Deref<S2> {
    type Target = S1;
    fn deref(self: S2) -> S1 {
        self.inner
    }
}

#[generate_trait]
impl MyImpl of MyTrait {
    fn foo(self: @S1) {}
}

//! > expected_diagnostics

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

//! > Test method call through box.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > function_code
fn foo() {
    let a = BoxTrait::new(@array![1_u32]);
    let _ = a.len();
}

//! > function_name
foo

//! > expected_diagnostics

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

//! > Calling deref on a box.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > function_code
fn foo() {
    let mut a = BoxTrait::new(@array![1_u32]);
    let _ = (*a);
}

//! > function_name
foo

//! > expected_diagnostics

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

//! > Calling deref on DerefMut.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > function_code
fn foo() {
    let mut a = S1 { inner: 1 };
    let _ = (*a);
}

//! > function_name
foo

//! > module_code
struct S1 {
    inner: usize,
}

impl S1DerefMut of core::ops::DerefMut<S1> {
    type Target = usize;
    fn deref_mut(ref self: S1) -> Self::Target {
        self.inner
    }
}

//! > expected_diagnostics

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

//! > Calling deref on DerefMut with non mutable variable.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > function_code
fn foo() {
    let a = S1 { inner: 1 };
    let _ = (*a);
}

//! > function_name
foo

//! > module_code
struct S1 {
    inner: usize,
}

impl S1DerefMut of core::ops::DerefMut<S1> {
    type Target = usize;
    fn deref_mut(ref self: S1) -> Self::Target {
        self.inner
    }
}

//! > expected_diagnostics
error[E2135]: Type `test::S1` cannot be dereferenced
 --> lib.cairo:13:14
    let _ = (*a);
             ^

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

//! > Final deref return values should decide the number of snapshots - single snapshot.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > function_code
fn foo(a: Box<@A>) -> @usize {
    a.b
}

//! > function_name
foo

//! > module_code
struct A {
    a: usize,
    b: usize,
}

//! > expected_diagnostics

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

//! > Final deref return values should decide the number of snapshots - multiple snapshots.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)

//! > function_code
fn foo(a: Box<@@@A>) -> @@@usize {
    a.b
}

//! > function_name
foo

//! > module_code
struct A {
    a: usize,
    b: usize,
}

//! > expected_diagnostics

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

//! > Deref impl missing its associated type reports the trait-item mismatch instead of an ICE.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > function_code
fn foo() {
    let b = MyBox {};
    b.get();
}

//! > function_name
foo

//! > module_code
#[derive(Drop)]
struct Inner {}

#[derive(Drop)]
struct MyBox {}

// `type Target` is missing: resolving a method through the deref chain used to ICE.
impl MyDeref of core::ops::Deref<MyBox> {
    fn deref(self: MyBox) -> Inner {
        Inner {}
    }
}

//! > expected_diagnostics
error[E0004]: Not all trait items are implemented. Missing: 'Target'.
 --> lib.cairo:8:6
impl MyDeref of core::ops::Deref<MyBox> {
     ^^^^^^^

error[E0002]: Method `get` could not be called on type `test::MyBox`.
Candidate `core::array::ArrayTrait::get` inference failed with: Type mismatch: `test::MyBox` and `@core::array::Array::<?0>`.
Candidate `core::array::SpanTrait::get` inference failed with: Type mismatch: `test::MyBox` and `core::array::Span::<?0>`.
Candidate `core::dict::Felt252DictTrait::get` inference failed with: Type mismatch: `test::MyBox` and `core::dict::Felt252Dict::<?0>`.
 --> lib.cairo:15:7
    b.get();
      ^^^