Module rustc_typeck::check::coercion [−][src]
🔬 This is a nightly-only experimental API. (rustc_private
)
this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via Cargo.toml
instead?
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/const things (that is, when the expected is &T
but you have &const T or &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/run-pass/coerce-reborrow-*.rs
tests for
examples of where this is useful.
Subtle note
When deciding what type coercions to consider, we do not attempt to
resolve any type variables we may encounter. This is because b
represents the expected type "as the user wrote it", meaning that if
the user defined a generic function like
fn foo(a: A, b: A) { ... }
and then we wrote foo(&1, @2)
, we will not auto-borrow
either argument. In older code we went to some lengths to
resolve the b
variable, which could mean that we'd
auto-borrow later arguments but not earlier ones, which
seems very confusing.
Subtler note
However, right now, if the user manually specifies the values for the type variables, as so:
foo::<&int>(@1, @2)
then we will auto-borrow, because we can't distinguish this from a
function that declared &int
. This is inconsistent but it's easiest
at the moment. The right thing to do, I think, is to consider the
unsubstituted type when deciding whether to auto-borrow, but the
substituted type when considering the bounds and so forth. But most
of our methods don't give access to the unsubstituted type, and
rightly so because they'd be error-prone. So maybe the thing to do is
to actually determine the kind of coercions that should occur
separately and pass them in. Or maybe it's ok as is. Anyway, it's
sort of a minor point so I've opted to leave it for later---after all
we may want to adjust precisely when coercions occur.
Structs
Coerce |
[ Experimental ]
|
CoerceMany |
[ Experimental ] 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 |
Enums
Expressions |
[ Experimental ]
|
Traits
AsCoercionSite |
[ Experimental ] Something that can be converted into an expression to which we can apply a coercion. |
Functions
coerce_mutbls |
[ Experimental ]
|
identity |
[ Experimental ]
|
simple |
[ Experimental ]
|
success |
[ Experimental ]
|
Type Definitions
CoerceResult |
[ Experimental ]
|
DynamicCoerceMany |
[ Experimental ] The type of a |
Existentials
[ Experimental ]
|