Module rustc_hir_typeck::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 tests/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
- Coerce 🔒
- 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 variousreturn
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. - identity 🔒Do not require any adjustments, i.e. coerce
x -> x
. - simple 🔒
- success 🔒This always returns
Ok(...)
.
Type Aliases
- The type of a
CoerceMany
that is storing up the expressions into a buffer. We use this incheck/mod.rs
for things likebreak
.