Impl Blocks
An impl block associates methods and functions with a struct type.
impl_block = "impl" IDENT "{" { method_def } "}" ;
method_def = "fn" IDENT "(" [ method_params ] ")" [ "->" type ] block ;
method_params = method_param { "," method_param } [ "," ] ;
method_param = "self" | ( IDENT ":" type ) ;
Methods
A method is a function defined inside an impl block that takes self as its first parameter.
The self parameter represents the receiver value and has the type of the impl block's target struct.
struct Point { x: i32, y: i32 }
impl Point {
fn get_x(self) -> i32 {
self.x
}
}
fn main() -> i32 {
let p = Point { x: 42, y: 10 };
p.get_x() // Returns 42
}
Method Calls
Methods are called using dot notation: receiver.method(args).
A method call receiver.method(args) is desugared to a function call with the receiver as the first argument.
Methods may have additional parameters after self.
struct Point { x: i32, y: i32 }
impl Point {
fn add(self, dx: i32, dy: i32) -> Point {
Point { x: self.x + dx, y: self.y + dy }
}
}
fn main() -> i32 {
let p = Point { x: 10, y: 20 };
let p2 = p.add(32, 0);
p2.x // Returns 42
}
Method Chaining
When a method returns the same struct type, method calls may be chained.
struct Counter { value: i32 }
impl Counter {
fn inc(self) -> Counter {
Counter { value: self.value + 1 }
}
}
fn main() -> i32 {
let c = Counter { value: 39 };
c.inc().inc().inc().value // Returns 42
}
Associated Functions
A function in an impl block that does not take self as its first parameter is an associated function.
Associated functions are called using path notation: Type::function(args).
struct Point { x: i32, y: i32 }
impl Point {
fn origin() -> Point {
Point { x: 0, y: 0 }
}
}
fn main() -> i32 {
let p = Point::origin();
p.x // Returns 0
}
Multiple Impl Blocks
Multiple impl blocks for the same struct type are allowed.
Method names MUST be unique across all impl blocks for a given struct type.
struct Point { x: i32, y: i32 }
impl Point {
fn get_x(self) -> i32 { self.x }
}
impl Point {
fn get_y(self) -> i32 { self.y }
}
fn main() -> i32 {
let p = Point { x: 42, y: 10 };
p.get_x() // Returns 42
}
Impl Block Ordering
An impl block may appear before or after the struct definition it implements. Forward references are resolved during semantic analysis.
Error Conditions
An impl block for an undefined struct type is a compile-time error.
Calling a method on a non-struct type is a compile-time error.
Calling an undefined method is a compile-time error.
Calling an associated function with method call syntax (receiver.function()) is a compile-time error.
Calling a method with associated function syntax (Type::method()) is a compile-time error.