Reputation: 2774
From what I know: In C language, the "type" of a variable is bound during compile time and the value of that variable is bound during run time.
For example, in int a = 10;
, the type int
is bound to the variable a
during compile time and the actual value 10
is bound (or assigned) to it during run time.
But in Rust, we have let a = 2;
. Here, when does the type (say i32
from any of the integer types in Rust) get bound to a
?
I am building a front-end Rust compiler and am currently writing the parser phase. At this point, what type should I assign to these variables?
Upvotes: 1
Views: 999
Reputation: 65692
Type binding is performed at compile time. This is necessary so that the compiler can emit the proper machine instructions (for example, an x86_64
processor doesn't multiply two i32
s the same way it multiplies two i64
s).
Many dynamically-typed languages, such as Python or Lua, will carry type information along with the values (not the variables) and dispatch operations at runtime based on the type of each operand. On the other hand, statically-typed languages, such as C or Rust, usually discard most of the type information; it's not necessary because the machine instructions required to perform the operation were emitted directly in the executable (which makes the statically-typed program faster than the comparable dynamically-typed program).
We can demonstrate that type binding is done at compile time by having the compiler tell us about type errors (this is known as type checking). Here's an example:
fn squared(x: f64) -> f64 {
x * x
}
fn main() {
let a = 2i32;
println!("{}", squared(a));
}
Compiling this gives the following output:
error[E0308]: mismatched types
--> src/main.rs:7:28
|
7 | println!("{}", squared(a));
| ^ expected f64, found i32
The Rust compiler can infer the type of many variables based on usage (similar to how auto
works in C++). When it can't, it'll give an error. For example:
fn main() {
let a;
}
gives this output:
error[E0282]: type annotations needed
--> src/main.rs:2:9
|
2 | let a;
| ^
| |
| cannot infer type for `_`
| consider giving `a` a type
When the compiler encounters errors, it stops and doesn't produce a runnable executable. Since we don't have an executable form of our program, there is no "run time", so the above happens at compile time.
Upvotes: 5