//! > Test return type inference
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() -> Option<felt252> {
Some(5)
}
//! > function_name
foo
//! > expected_diagnostics
//! > ==========================================================================
//! > Test array inference
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
let mut arr = array::array_new();
array::array_append(ref arr, 1);
}
//! > function_name
foo
//! > expected_diagnostics
//! > ==========================================================================
//! > Test cycles
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > comments
// TODO(spapini): Make better diagnostics.
//! > function_code
fn foo() {
MyTrait::foo();
}
//! > function_name
foo
//! > module_code
trait MyTrait {
fn foo();
}
impl MyImpl<+MyTrait> of MyTrait {
fn foo() {}
}
//! > expected_diagnostics
error[E2301]: Inference cycle detected
--> lib.cairo:9:14
MyTrait::foo();
^^^
//! > ==========================================================================
//! > Test undetermined system
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
let mut _arr = array::array_new();
}
//! > function_name
foo
//! > expected_diagnostics
error[E2314]: Type annotations needed. Failed to infer ?0.
--> lib.cairo:2:27
let mut _arr = array::array_new();
^^^^^^^^^
//! > ==========================================================================
//! > Test type mismatch
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
let mut _arr: felt252 = array::array_new::<felt252>();
}
//! > function_name
foo
//! > expected_diagnostics
error[E2041]: Unexpected argument type. Expected: "core::felt252", found: "core::array::Array::<core::felt252>".
--> lib.cairo:2:29
let mut _arr: felt252 = array::array_new::<felt252>();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! > ==========================================================================
//! > Test never type
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() -> felt252 {
panic(array::array_new())
}
//! > function_name
foo
//! > expected_diagnostics
//! > ==========================================================================
//! > Test anti never type
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() -> never {
5_felt252
}
//! > function_name
foo
//! > expected_diagnostics
error[E2042]: Unexpected return type. Expected: "core::never", found: "core::felt252".
--> lib.cairo:1:13
fn foo() -> never {
^^^^^
//! > ==========================================================================
//! > Test trait inference.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
MyTrait::foo(5);
MyTrait::foo(true);
MyTrait::foo(None);
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {
fn foo(x: T);
}
impl MyImpl1 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl2 of MyTrait<bool> {
fn foo(x: bool) {}
}
impl MyImpl3 of MyTrait<Option<felt252>> {
fn foo(x: Option<felt252>) {}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Test trait inference no impl failure.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
MyTrait::foo(true);
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {
fn foo(x: T);
}
impl MyImpl1 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl2 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl3 of MyTrait<Option<felt252>> {
fn foo(x: Option<felt252>) {}
}
impl MyImpl4 of MyTrait<Option<bool>> {
fn foo(x: Option<bool>) {}
}
//! > expected_diagnostics
error[E2311]: Trait has no implementation in context: test::MyTrait::<core::bool>.
--> lib.cairo:17:14
MyTrait::foo(true);
^^^
//! > ==========================================================================
//! > Test trait inference multiple impl failure.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
MyTrait::foo(5);
MyTrait::foo(Option::<felt252>::None);
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {
fn foo(x: T);
}
impl MyImpl1 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl2 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl3 of MyTrait<Option<felt252>> {
fn foo(x: Option<felt252>) {}
}
impl MyImpl4 of MyTrait<Option<bool>> {
fn foo(x: Option<bool>) {}
}
//! > expected_diagnostics
error[E2313]: Trait `test::MyTrait::<core::felt252>` has multiple implementations, in: `test::MyImpl1`, `test::MyImpl2`
--> lib.cairo:17:14
MyTrait::foo(5);
^^^
//! > ==========================================================================
//! > Test trait inference unresolved type for impl.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
MyTrait::foo(None);
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {
fn foo(x: T);
}
impl MyImpl1 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl2 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl3 of MyTrait<Option<felt252>> {
fn foo(x: Option<felt252>) {}
}
impl MyImpl4 of MyTrait<Option<bool>> {
fn foo(x: Option<bool>) {}
}
//! > expected_diagnostics
error[E2313]: Trait `test::MyTrait::<core::option::Option::<?0>>` has multiple implementations, in: `test::MyImpl3`, `test::MyImpl4`
--> lib.cairo:17:14
MyTrait::foo(None);
^^^
//! > ==========================================================================
//! > Test dot_expr inference.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo(my_box: Box<MyStruct>) -> felt252 {
box::unbox(my_box).a
}
//! > function_name
foo
//! > module_code
struct MyStruct {
a: felt252,
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Infer impl
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
bar(true);
}
//! > function_name
foo
//! > module_code
fn bar<impl Tr: MyTrait<bool>>(x: bool) {}
trait MyTrait<T> {
fn foo(x: T);
}
impl MyImpl1 of MyTrait<bool> {
fn foo(x: bool) {}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Infer impl after inferring type
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
bar(Some(5));
}
//! > function_name
foo
//! > module_code
fn bar<S, impl Tr: MyTrait<S>>(x: S) {}
trait MyTrait<T> {
fn foo(x: T);
}
impl MyImpl1 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl2 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl3 of MyTrait<Option<felt252>> {
fn foo(x: Option<felt252>) {}
}
impl MyImpl4 of MyTrait<Option<bool>> {
fn foo(x: Option<bool>) {}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Infer impl failure
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
bar(true);
}
//! > function_name
foo
//! > module_code
fn bar<S, impl Tr: MyTrait<S>>(x: S) {}
trait MyTrait<T> {
fn foo(x: T);
}
impl MyImpl1 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl2 of MyTrait<felt252> {
fn foo(x: felt252) {}
}
impl MyImpl3 of MyTrait<Option<felt252>> {
fn foo(x: Option<felt252>) {}
}
impl MyImpl4 of MyTrait<Option<bool>> {
fn foo(x: Option<bool>) {}
}
//! > expected_diagnostics
error[E2311]: Trait has no implementation in context: test::MyTrait::<core::bool>.
--> lib.cairo:19:5
bar(true);
^^^
//! > ==========================================================================
//! > Infer impl generic param from generic param.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
A::<felt252> {}.foo();
}
//! > function_name
foo
//! > module_code
struct A<T> {}
trait MyTrait<T> {
fn foo<impl TDrop: Drop<T>>(self: A<T>);
fn bar<impl TDrop: Drop<T>>(self: A<T>);
}
impl MyImpl<T> of MyTrait<T> {
fn foo<impl TDrop: Drop<T>>(self: A<T>) {
self.bar()
}
fn bar<impl TDrop: Drop<T>>(self: A<T>) {}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Complex clone inference.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
let _ = (@5).clone();
let _ = 5.clone();
}
//! > function_name
foo
//! > expected_diagnostics
//! > ==========================================================================
//! > infer generic impl in a function.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
clone_loop(5)
}
//! > function_name
foo
//! > module_code
fn clone_loop<T, impl TClone: Clone<T>>(x: T) {
clone_loop::<T>(x)
}
//! > expected_diagnostics
//! > ==========================================================================
//! > infer drop impl.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {}
//! > function_name
foo
//! > module_code
struct A {}
struct B {
a: A,
}
impl I<impl TI: Drop<A>> of Drop<B>;
//! > expected_diagnostics
//! > ==========================================================================
//! > equality from signature
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
assert_eq(1, 2 + 3, '4');
}
//! > function_name
foo
//! > module_code
#[inline]
fn assert_eq<T, impl TPartialEq: PartialEq<T>>(a: T, b: T, err_code: felt252) {
assert(a == b, err_code);
}
//! > expected_diagnostics
//! > ==========================================================================
//! > inference from struct pattern
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
let u256 { low: _, high: _ } = 123;
}
//! > function_name
foo
//! > expected_diagnostics
//! > ==========================================================================
//! > inference in impl generic params
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {}
//! > function_name
foo
//! > module_code
trait Bash<S> {
fn foo(state: S);
}
trait BashExTrait<S> {
fn bar(self: S);
}
impl BashEx<S, +Bash<S>> of BashExTrait<S> {
fn bar(self: S) {
Bash::<_>::foo(self);
}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Test no default type for string literals.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
let _x = "hello";
}
//! > function_name
foo
//! > expected_diagnostics
error[E2314]: Type annotations needed. Failed to infer ?0.
--> lib.cairo:2:14
let _x = "hello";
^^^^^^^
//! > ==========================================================================
//! > Test impl inference with an impl of a non-existing trait in context.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
// A NumericLiteral<felt252> should be inferred here.
let _x = 123;
}
//! > function_name
foo
//! > module_code
impl MyImpl of NonExistingTrait {}
//! > expected_diagnostics
error[E0006]: Trait not found.
--> lib.cairo:1:16
impl MyImpl of NonExistingTrait {}
^^^^^^^^^^^^^^^^
//! > ==========================================================================
//! > Test type inference not stopping on missing type.
//! > test_runner_name
test_function_diagnostics
//! > function_code
fn foo() {
let mut data_hash = 0;
data_hash = unknown_return_unknown();
}
//! > function_name
foo
//! > expected_diagnostics
error[E0006]: Function not found.
--> lib.cairo:3:17
data_hash = unknown_return_unknown();
^^^^^^^^^^^^^^^^^^^^^^
//! > ==========================================================================
//! > Test trait inference multiple impl failure with involved generic params.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
bar(0_u8);
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {}
impl MyIpls<T, +Drop<T>> of MyTrait<T> {}
// impl MyImpl<T, +Into<T, u8>> of TryInto<T, u8> {
// fn try_into(self: T) -> Option<u8> {
// Some(self.into())
// }
// }
fn bar<T, +Drop<T>, +MyTrait<T>>(a: T) -> T {
baz(a)
}
fn baz<T, +Drop<T>, +MyTrait<T>>(a: T) -> T {
a
}
//! > expected_diagnostics
error[E2313]: Trait `test::MyTrait::<T>` has multiple implementations, in: `+MyTrait<T>`, `test::MyIpls::<T, +Drop<T>>`
--> lib.cairo:12:5
baz(a)
^^^
//! > ==========================================================================
//! > Test inference failure because of unbalanced snapshot.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
let x = 5;
let y: u32 = 5;
takes_snapshots(x, y);
}
//! > function_name
foo
//! > module_code
fn takes_snapshots<T>(x: @T, y: @T) {}
//! > expected_diagnostics
error[E2041]: Unexpected argument type. Expected: "@?2", found: "core::integer::u32".
It is possible that the type inference failed because the types differ in the number of snapshots.
Consider adding or removing snapshots.
--> lib.cairo:5:24
takes_snapshots(x, y);
^
//! > ==========================================================================
//! > Returned type is not inferred.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() -> Option {
Some(5_u32)
}
//! > function_name
foo
//! > expected_diagnostics
error[E2314]: Type annotations needed. Failed to infer ?0.
--> lib.cairo:1:13
fn foo() -> Option {
^^^^^^
//! > ==========================================================================
//! > Use of an impl with and inferred and missing trait type.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
MyTrait::f();
}
//! > function_name
foo
//! > module_code
trait MyTrait {
type ty;
fn f() -> Self::ty;
}
impl MyImpl of MyTrait {
fn f() -> u32 {
5_u32
}
}
//! > expected_diagnostics
error[E0004]: Not all trait items are implemented. Missing: 'ty'.
--> lib.cairo:5:6
impl MyImpl of MyTrait {
^^^^^^