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.

Re-exports

use check::FnCtxt;
use check::Needs;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::infer::Coercion;
use rustc::infer::InferResult;
use rustc::infer::InferOk;
use rustc::infer::type_variable::TypeVariableOrigin;
use rustc::traits;
use rustc::traits::ObligationCause;
use rustc::traits::ObligationCauseCode;
use rustc::ty::adjustment::Adjustment;
use rustc::ty::adjustment::Adjust;
use rustc::ty::adjustment::AllowTwoPhase;
use rustc::ty::adjustment::AutoBorrow;
use rustc::ty::adjustment::AutoBorrowMutability;
use rustc::ty;
use rustc::ty::TypeAndMut;
use rustc::ty::Ty;
use rustc::ty::ClosureSubsts;
use rustc::ty::fold::TypeFoldable;
use rustc::ty::error::TypeError;
use rustc::ty::relate::RelateResult;
use errors::DiagnosticBuilder;
use syntax::feature_gate;
use syntax::ptr::P;
use syntax::ptr::P;
use syntax_pos;
use std::collections::VecDeque;
use std::ops::Deref;

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 break foo expressions that target the same loop, or the various return expressions in a function.

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 CoerceMany that is storing up the expressions into a buffer. We use this in check/mod.rs for things like break.