//! > Test method
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() -> Option<felt252> {
let x = None;
let _ = x.is_some();
x
}
//! > function_name
foo
//! > module_code
trait AnotherTrait {
fn is_some(self: felt252) -> bool;
}
impl OtherImpl of AnotherTrait {
fn is_some(self: felt252) -> bool {
true
}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Test method failures
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() -> Option<felt252> {
let x = None;
x.is_foo();
x.is_bla();
let y = Some(true);
y.is_bar();
y.SomeOtherPrefix::is_bar();
x
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {
fn is_bla(self: Option<T>) -> bool;
fn is_bar(self: Option<T>) -> bool;
}
impl MyTraitImpl<T> of MyTrait<T> {
fn is_bla(self: Option<T>) -> bool {
match self {
Some(_) => true,
None => false,
}
}
fn is_bar(self: Option<T>) -> bool {
true
}
}
impl AnotherMyTraitImpl<T> of MyTrait<felt252> {
fn is_bla(self: Option<felt252>) -> bool {
match self {
Some(_) => true,
None => false,
}
}
fn is_bar(self: Option<felt252>) -> bool {
true
}
}
trait AnotherTrait {
fn is_bar(self: Option<bool>) -> bool;
}
impl AnotherTraitImpl of AnotherTrait {
fn is_bar(self: Option<bool>) -> bool {
false
}
}
//! > expected_diagnostics
error[E0002]: Method `is_foo` not found on type `core::option::Option::<?0>`. Did you import the correct trait and impl?
--> lib.cairo:37:7
x.is_foo();
^^^^^^
error[E2046]: Ambiguous method call. More than one applicable trait function with a suitable self type was found: MyTrait::is_bar and AnotherTrait::is_bar. Consider adding type annotations or explicitly refer to the impl function.
--> lib.cairo:40:7
y.is_bar();
^^^^^^
error[E2085]: Invalid member expression.
--> lib.cairo:41:7
y.SomeOtherPrefix::is_bar();
^^^^^^^^^^^^^^^^^^^^^^^^^
error[E2313]: Candidate impl test::AnotherMyTraitImpl::<?0> has an unused generic parameter.
--> lib.cairo:38:7
x.is_bla();
^^^^^^
//! > ==========================================================================
//! > Test calling a method of a trait from the generic arguments.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
bar(3_u8);
}
//! > function_name
foo
//! > module_code
fn bar<T, impl CallableImpl: callable::CallableTrait<T>>(x: T) {
x.call();
}
mod callable {
trait CallableTrait<T> {
fn call(self: T);
}
impl U8Callable of CallableTrait<u8> {
fn call(self: u8) {}
}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Calling a method of a trait from a generic argument, after an unresolved generic argument.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
bar(3_u8);
}
//! > function_name
foo
//! > module_code
fn bar<T, +unknown, +callable::CallableTrait<T>>(x: T) {
x.call();
}
mod callable {
trait CallableTrait<T> {
fn call(self: T);
}
impl U8Callable of CallableTrait<u8> {
fn call(self: u8) {}
}
}
//! > expected_diagnostics
error[E0006]: Trait not found.
--> lib.cairo:1:12
fn bar<T, +unknown, +callable::CallableTrait<T>>(x: T) {
^^^^^^^
//! > ==========================================================================
//! > Test calling a method of a trait from an impl in the module.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
bar(3_u8);
}
//! > function_name
foo
//! > module_code
fn bar(x: u8) {
x.call();
}
mod callable {
trait CallableTrait<T> {
fn call(self: T);
}
}
impl U8Callable of callable::CallableTrait<u8> {
fn call(self: u8) {}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Test calling a method of a trait from an impl in the module that is not the relevant impl.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
bar(3_u8);
}
//! > function_name
foo
//! > module_code
fn bar(x: u8) {
x.call();
}
mod callable {
trait CallableTrait<T> {
fn call(self: T);
}
impl U8Callable of CallableTrait<u8> {
fn call(self: u8) {}
}
}
impl U16Callable of callable::CallableTrait<u16> {
fn call(self: u16) {}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Test calling a method of a trait from an impl alias in the module.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
bar(3_u8);
}
//! > function_name
foo
//! > module_code
impl X = callable::U8Callable;
fn bar(x: u8) {
x.call();
}
mod callable {
trait CallableTrait<T> {
fn call(self: T);
}
impl U8Callable of CallableTrait<u8> {
fn call(self: u8) {}
}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Test calling a trait method from an impl alias in the module that is not the relevant impl.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
bar(3_u8);
}
//! > function_name
foo
//! > module_code
impl X = callable::U16Callable;
fn bar(x: u8) {
x.call();
}
mod callable {
trait CallableTrait<T> {
fn call(self: T);
}
impl U8Callable of CallableTrait<u8> {
fn call(self: u8) {}
}
impl U16Callable of CallableTrait<u16> {
fn call(self: u16) {}
}
}
//! > expected_diagnostics
//! > ==========================================================================
//! > No impls found for method on a concrete self.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
3_u16.bar();
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {
fn bar(self: T);
}
//! > expected_diagnostics
error[E0002]: Method `bar` could not be called on type `core::integer::u16`.
Candidate `test::MyTrait::bar` inference failed with: Trait has no implementation in context: test::MyTrait::<core::integer::u16>.
--> lib.cairo:5:11
3_u16.bar();
^^^
//! > ==========================================================================
//! > No impls found for method on a type-var self.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
(3_u16 + 3_u16).bar();
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {
fn bar(self: T);
}
//! > expected_diagnostics
error[E0002]: Method `bar` could not be called on type `core::integer::u16`.
Candidate `test::MyTrait::bar` inference failed with: Trait has no implementation in context: test::MyTrait::<core::integer::u16>.
--> lib.cairo:5:21
(3_u16 + 3_u16).bar();
^^^
//! > ==========================================================================
//! > Wrong num of arguments.
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
0.bar(1);
0.bar(1, 2, 3);
}
//! > function_name
foo
//! > module_code
trait MyTrait<T> {
fn bar(self: T, a: felt252, b: felt252);
}
impl MyImpl of MyTrait<felt252> {
fn bar(self: felt252, a: felt252, b: felt252) {}
}
//! > expected_diagnostics
error[E2030]: Wrong number of arguments. Expected 3, found: 2
--> lib.cairo:8:7
0.bar(1);
^^^^^^
error[E2030]: Wrong number of arguments. Expected 3, found: 4
--> lib.cairo:9:7
0.bar(1, 2, 3);
^^^^^^^^^^^^
//! > ==========================================================================
//! > method with impl type
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
let channel = PoseidonChannel {};
channel.draw_felt();
}
//! > function_name
foo
//! > module_code
trait ChannelTrait {
type Channel;
fn draw_felt(ref self: Self::Channel) -> felt252;
}
struct PoseidonChannel {}
impl PoseidonChannelImpl of ChannelTrait {
type Channel = PoseidonChannel;
fn draw_felt(ref self: PoseidonChannel) -> felt252 {
5
}
}
//! > expected_diagnostics
error[E0002]: Method `draw_felt` could not be called on type `test::PoseidonChannel`.
Candidate `test::ChannelTrait::draw_felt` inference failed with: Type mismatch: `test::PoseidonChannel` and `test::ChannelTrait::Channel`.
--> lib.cairo:18:13
channel.draw_felt();
^^^^^^^^^
//! > ==========================================================================
//! > Test ref self on expression receiver (not a variable)
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: false)
//! > function_code
fn foo() {
// ref self method called on expression (not a variable) should work
let _ = make_counter().increment();
let _ = make_counter().increment().increment();
}
//! > function_name
foo
//! > module_code
#[derive(Drop)]
struct Counter {
value: u32,
}
trait CounterTrait {
fn increment(ref self: Counter) -> Counter;
}
impl CounterImpl of CounterTrait {
fn increment(ref self: Counter) -> Counter {
self.value += 1;
self
}
}
fn make_counter() -> Counter {
Counter { value: 0 }
}
//! > expected_diagnostics
//! > ==========================================================================
//! > Test ref self on expression receiver - regular ref arg still requires variable
//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)
//! > function_code
fn foo() {
// ref self on expression works
let _ = make_counter().increment();
// but regular ref arg (not self) still requires a variable
bar(make_counter());
}
//! > function_name
foo
//! > module_code
#[derive(Drop)]
struct Counter {
value: u32,
}
trait CounterTrait {
fn increment(ref self: Counter) -> Counter;
}
impl CounterImpl of CounterTrait {
fn increment(ref self: Counter) -> Counter {
self.value += 1;
self
}
}
fn make_counter() -> Counter {
Counter { value: 0 }
}
fn bar(ref x: Counter) {}
//! > expected_diagnostics
error[E2079]: ref argument must be a variable.
--> lib.cairo:26:9
bar(make_counter());
^^^^^^^^^^^^^^