The type provider is a (arguably poorly named) data structure that stores not only the selected type for each
expression in the program, but also a bunch of other stuff (see declare_tp_fields). Why does it exist at all,
instead of just storing this info on Driver? Because there are some occasions where the typechecker wants to make
queries about the program, such as which possible types an expression could have. Making these queries requires
making changes to the values in the type provider, which we don’t want to do. So we have two kinds of type
providers, abstracted by the TypeProvider trait: real and mock. There is
only one real type provider, which stores the real answers. A mock type provider wraps the real type provider and
provides a safe sandbox to temporarily make modifications to, then throw away.