Module rustc_typeck::check::coercion
source · Expand description
Type Coercion
Under certain circumstances we will coerce from one type to another, for example by auto-borrowing. This occurs in situations where the compiler has a firm ‘expected type’ that was supplied from the user, and where the actual type is similar to that expected type in purpose but not in representation (so actual subtyping is inappropriate).
Reborrowing
Note that if we are expecting a reference, we will reborrow
even if the argument provided was already a reference. This is
useful for freezing mut things (that is, when the expected type is &T
but you have &mut T) and also for avoiding the linearity
of mut things (when the expected is &mut T and you have &mut T). See
the various src/test/ui/coerce/*.rs
tests for
examples of where this is useful.
Subtle note
When inferring the generic arguments of functions, the argument order is relevant, which can lead to the following edge case:
fn foo<T>(a: T, b: T) {
// ...
}
foo(&7i32, &mut 7i32);
// This compiles, as we first infer `T` to be `&i32`,
// and then coerce `&mut 7i32` to `&7i32`.
foo(&mut 7i32, &7i32);
// This does not compile, as we first infer `T` to be `&mut i32`
// and are then unable to coerce `&7i32` to `&mut i32`.
Structs
break foo
expressions
that target the same loop, or the various return
expressions in
a function.Enums
Traits
Functions
&T
to &mut T
should be forbidden.x -> x
.Ok(...)
.Type Definitions
CoerceMany
that is storing up the expressions into
a buffer. We use this in check/mod.rs
for things like break
.