We can implement the traits in core::ops
to define the behavior of operators for our types. The traits themselves are annotated with #[lang =...]
attributes so the compiler knows which traits and operators belong together.
For example, the Add
implementation for primitive types looks like this (macro manually expanded and simplified from here):
impl Add for i32 {
type Output = i32;
fn add(self, other: i32) -> i32 {
self + other
}
}
To my surprise, the implementation uses the +
operator internally, which presumably calls self.add(other)
, resulting in an infinite recursion. Obviously, things do not happen like this because expressions like 3 + 4
(assuming no constant folding) work perfectly fine.
Now consider this naive implementation of the Add
trait:
use std::ops::Add;
struct Foo;
impl Add for Foo {
type Output = Foo;
fn add(self, other: Foo) -> Foo {
self + other
}
}
fn main() {
let two_foo = Foo + Foo;
}
The compiler warns that function cannot return without recurring
and running this program in Debug mode properly stops with fatal runtime error: stack overflow
.
How does the compiler know how to add two numbers without falling into a recursive loophole?
How does the compiler know to add two numbers without falling into a recursive loophole?
Because the compiler is the compiler, and the compiler knows it doesn't need an Add
implementation to add two numbers. If it's doing constant folding, it just adds them. If it's generating code, it tells LLVM to add them at runtime.
Those Add
implementations aren't there to tell the compiler how to add numbers, they're to implement Add
for numbers so that user code can add numbers via the Add
trait just like any user-defined type. If those implementations didn't exist, then you wouldn't be able to add numbers in generic methods, because they wouldn't implement Add
.
To put it another way: Add
is what the compiler uses when it doesn't otherwise know how to add things. But it already knows how to add numbers, so it doesn't need them. They're provided for consistency with other types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With