Hm, I thought that this would actually just work. This means that my understanding of Rust's compilation model is wrong. I would very grateful if someone could explain what is wrong with my mental model
Let's say I have two files/crates: container.rs and main.rs
// container.rs
use std::fmt::Display;
pub struct Container<T> {
pub t: T
}
impl<T> Container<T> {
pub fn print(&self)
where
T: Display
{
println!("{}", self.t);
}
}
pub mod impls {
use super::Container;
pub fn make_i32_container() -> Container<i32> {
Container { t: 92 }
}
}
//main.rs
extern crate container;
use container::Container;
fn main() {
let c: Container<i32> = Container { t: 92 };
c.print();
}
And I compile then using the following two commands:
$ rustc --crate-type lib container.rs
$ rustc main.rs --extern container=./libcontainer.rlib
I think that libcontainer.rlib
contains (optimized, if --release
is present) machine code or bit code for non-generic make_i32_container
function. If this is true, it must contain code for Container<i32>
instantiation as well.
Then, when we compile main.rs
, it seems to me that the compiler can see that we already have the necessary instantiation, and avoid specializing Container
for i32
the second time. Or are template instantiations per-crate, and then the duplicates get removed during linking, like with C++ inline?