Module rustc_typeck::check::coercion [−][src]
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 infering 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
CoerceMany encapsulates the pattern you should use when you have
many expressions that are all getting coerced to a common
type. This arises, for example, when you have a match (the result
of each arm is coerced to a common type). It also arises in less
obvious places, such as when you have many break foo
expressions
that target the same loop, or the various return
expressions in
a function.
Enums
Traits
Something that can be converted into an expression to which we can apply a coercion.
Functions
Coercing a mutable reference to an immutable works, while
coercing &T
to &mut T
should be forbidden.
Do not require any adjustments, i.e. coerce x -> x
.
This always returns Ok(...)
.
Type Definitions
The type of a CoerceMany
that is storing up the expressions into
a buffer. We use this in check/mod.rs
for things like break
.