When does Rust infer type?

Given a Vec, type is infered when you put first element in it. But this case Im working on is also using trait objects. It's a GUI lib called Druid. I could have asked this question in Druid but I feel it falls under Rust specifically.
Given following code snippet

trait Data {}

pub trait Widget<T> {
    // some methods

struct MyData{}

pub struct MyWidget<T> {
    //contains a vec of child Widgets

impl Data for MyData{}

impl<T: Data> Widget<T> for MyWidget<T> {
    pub new() -> Self {

    pub fn with_child(mut self, child: impl Widget<T> + 'static) -> Self {
        //Adds child to vec. 

When I call below method, when and how does Rust infer type?

fn build_calc() -> impl Widget<MyData> <-- 1 {
    let parent_widget = MyWidget::new();
    let child_widget = MyWidget::new(); <-- 2
    parent_widget.with_child(child_widget) <-- 3

Does it infer at 1, 2 or 3? Can I have MyWidget<MyData1> with child as MyWidget<MyData2>? MyData1 and MyData2 are both Data.

Well it gets a bunch of information from various places:

  1. It knows that parent_widget is a Widget<T> for some T.
  2. It knows that child_widget is also a Widget<T> for some possibly different T.
  3. But since with_child requires that both inputs have the same type T, it knows that they must be the same T type.
  4. And since it must return a Widget<MyData>, and with_child returns a Widget<T>, it knows that T must be MyData.

It's based on the Hindley-Milner algorithm


That makes sense. I have followup question:
In my example the tree is very basic: one parent with one child. But it can be have many more parents and children. What we do is return the root widget.
So from your step 4, compiler can infer T as MyData only for root. So does compiler (with help of Hindley–Milner algorithm) figure out type for other widgets in tree? Looks to me it goes top-to-bottom.

Well it figured out that it had a bunch of equalities between types, so when it figured out what any of them was, it knew what every one of them is.

1 Like

Yeah. That is good way to put it.
Thank you.