librustc_typeck: use unboxed closures
This commit is contained in:
parent
888f24969f
commit
521a6e62b1
5 changed files with 72 additions and 61 deletions
|
@ -28,12 +28,14 @@ pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
|
|||
|sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) })
|
||||
}
|
||||
|
||||
pub fn suptype_with_fn<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
sp: Span,
|
||||
b_is_expected: bool,
|
||||
ty_a: Ty<'tcx>,
|
||||
ty_b: Ty<'tcx>,
|
||||
handle_err: |Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>|) {
|
||||
pub fn suptype_with_fn<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
sp: Span,
|
||||
b_is_expected: bool,
|
||||
ty_a: Ty<'tcx>,
|
||||
ty_b: Ty<'tcx>,
|
||||
handle_err: F) where
|
||||
F: FnOnce(Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>),
|
||||
{
|
||||
// n.b.: order of actual, expected is reversed
|
||||
match infer::mk_subty(fcx.infcx(), b_is_expected, infer::Misc(sp),
|
||||
ty_b, ty_a) {
|
||||
|
|
|
@ -286,11 +286,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_trait_ref<R>(&mut self,
|
||||
self_ty: Ty<'tcx>,
|
||||
closure: |&mut ConfirmContext<'a,'tcx>,
|
||||
Ty<'tcx>, &ty::TyTrait<'tcx>| -> R)
|
||||
-> R
|
||||
fn extract_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R where
|
||||
F: FnMut(&mut ConfirmContext<'a, 'tcx>, Ty<'tcx>, &ty::TyTrait<'tcx>) -> R,
|
||||
{
|
||||
// If we specified that this is an object method, then the
|
||||
// self-type ought to be something that can be dereferenced to
|
||||
|
@ -665,9 +662,11 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn wrap_autoref<'tcx>(mut deref: ty::AutoDerefRef<'tcx>,
|
||||
base_fn: |Option<Box<ty::AutoRef<'tcx>>>| -> ty::AutoRef<'tcx>)
|
||||
-> ty::AutoDerefRef<'tcx> {
|
||||
fn wrap_autoref<'tcx, F>(mut deref: ty::AutoDerefRef<'tcx>,
|
||||
base_fn: F)
|
||||
-> ty::AutoDerefRef<'tcx> where
|
||||
F: FnOnce(Option<Box<ty::AutoRef<'tcx>>>) -> ty::AutoRef<'tcx>,
|
||||
{
|
||||
let autoref = mem::replace(&mut deref.autoref, None);
|
||||
let autoref = autoref.map(|r| box r);
|
||||
deref.autoref = Some(base_fn(autoref));
|
||||
|
|
|
@ -710,10 +710,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
mutbl: m }))
|
||||
}
|
||||
|
||||
fn search_mutabilities(&mut self,
|
||||
mk_adjustment: |ast::Mutability| -> PickAdjustment,
|
||||
mk_autoref_ty: |ast::Mutability, ty::Region| -> Ty<'tcx>)
|
||||
-> Option<PickResult<'tcx>>
|
||||
fn search_mutabilities<F, G>(&mut self,
|
||||
mut mk_adjustment: F,
|
||||
mut mk_autoref_ty: G)
|
||||
-> Option<PickResult<'tcx>> where
|
||||
F: FnMut(ast::Mutability) -> PickAdjustment,
|
||||
G: FnMut(ast::Mutability, ty::Region) -> Ty<'tcx>,
|
||||
{
|
||||
// In general, during probing we erase regions. See
|
||||
// `impl_self_ty()` for an explanation.
|
||||
|
|
|
@ -1885,9 +1885,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.inh.item_substs.borrow()
|
||||
}
|
||||
|
||||
pub fn opt_node_ty_substs(&self,
|
||||
id: ast::NodeId,
|
||||
f: |&ty::ItemSubsts<'tcx>|) {
|
||||
pub fn opt_node_ty_substs<F>(&self,
|
||||
id: ast::NodeId,
|
||||
f: F) where
|
||||
F: FnOnce(&ty::ItemSubsts<'tcx>),
|
||||
{
|
||||
match self.inh.item_substs.borrow().get(&id) {
|
||||
Some(s) => { f(s) }
|
||||
None => { }
|
||||
|
@ -2027,12 +2029,14 @@ impl Copy for LvaluePreference {}
|
|||
///
|
||||
/// Note: this method does not modify the adjustments table. The caller is responsible for
|
||||
/// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
|
||||
pub fn autoderef<'a, 'tcx, T>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
|
||||
base_ty: Ty<'tcx>,
|
||||
expr_id: Option<ast::NodeId>,
|
||||
mut lvalue_pref: LvaluePreference,
|
||||
should_stop: |Ty<'tcx>, uint| -> Option<T>)
|
||||
-> (Ty<'tcx>, uint, Option<T>) {
|
||||
pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
|
||||
base_ty: Ty<'tcx>,
|
||||
expr_id: Option<ast::NodeId>,
|
||||
mut lvalue_pref: LvaluePreference,
|
||||
mut should_stop: F)
|
||||
-> (Ty<'tcx>, uint, Option<T>) where
|
||||
F: FnMut(Ty<'tcx>, uint) -> Option<T>,
|
||||
{
|
||||
let mut t = base_ty;
|
||||
for autoderefs in range(0, fcx.tcx().sess.recursion_limit.get()) {
|
||||
let resolved_t = structurally_resolved_type(fcx, sp, t);
|
||||
|
@ -2194,12 +2198,13 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn autoderef_for_index<'a, 'tcx, T>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
base_expr: &ast::Expr,
|
||||
base_ty: Ty<'tcx>,
|
||||
lvalue_pref: LvaluePreference,
|
||||
step: |Ty<'tcx>, ty::AutoDerefRef<'tcx>| -> Option<T>)
|
||||
-> Option<T>
|
||||
fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
base_expr: &ast::Expr,
|
||||
base_ty: Ty<'tcx>,
|
||||
lvalue_pref: LvaluePreference,
|
||||
mut step: F)
|
||||
-> Option<T> where
|
||||
F: FnMut(Ty<'tcx>, ty::AutoDerefRef<'tcx>) -> Option<T>,
|
||||
{
|
||||
// FIXME(#18741) -- this is almost but not quite the same as the
|
||||
// autoderef that normal method probing does. They could likely be
|
||||
|
@ -2938,11 +2943,12 @@ enum TupleArgumentsFlag {
|
|||
/// Note that inspecting a type's structure *directly* may expose the fact
|
||||
/// that there are actually multiple representations for `ty_err`, so avoid
|
||||
/// that when err needs to be handled differently.
|
||||
fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
expr: &ast::Expr,
|
||||
expected: Expectation<'tcx>,
|
||||
lvalue_pref: LvaluePreference,
|
||||
unifier: ||)
|
||||
fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
expr: &ast::Expr,
|
||||
expected: Expectation<'tcx>,
|
||||
lvalue_pref: LvaluePreference,
|
||||
unifier: F) where
|
||||
F: FnOnce(),
|
||||
{
|
||||
debug!(">> typechecking: expr={} expected={}",
|
||||
expr.repr(fcx.tcx()), expected.repr(fcx.tcx()));
|
||||
|
@ -3117,14 +3123,16 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
fcx.write_ty(id, if_ty);
|
||||
}
|
||||
|
||||
fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
op_ex: &ast::Expr,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
opname: ast::Name,
|
||||
trait_did: Option<ast::DefId>,
|
||||
lhs: &'a ast::Expr,
|
||||
rhs: Option<&P<ast::Expr>>,
|
||||
unbound_method: ||) -> Ty<'tcx> {
|
||||
fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
op_ex: &ast::Expr,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
opname: ast::Name,
|
||||
trait_did: Option<ast::DefId>,
|
||||
lhs: &'a ast::Expr,
|
||||
rhs: Option<&P<ast::Expr>>,
|
||||
unbound_method: F) -> Ty<'tcx> where
|
||||
F: FnOnce(),
|
||||
{
|
||||
let method = match trait_did {
|
||||
Some(trait_did) => {
|
||||
// We do eager coercions to make using operators
|
||||
|
@ -4376,19 +4384,17 @@ impl<'tcx> Expectation<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn map<'a>(self, fcx: &FnCtxt<'a, 'tcx>,
|
||||
unpack: |&ty::sty<'tcx>| -> Expectation<'tcx>)
|
||||
-> Expectation<'tcx> {
|
||||
fn map<'a, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Expectation<'tcx> where
|
||||
F: FnOnce(&ty::sty<'tcx>) -> Expectation<'tcx>
|
||||
{
|
||||
match self.resolve(fcx) {
|
||||
NoExpectation => NoExpectation,
|
||||
ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_to_option<'a, O>(self,
|
||||
fcx: &FnCtxt<'a, 'tcx>,
|
||||
unpack: |&ty::sty<'tcx>| -> Option<O>)
|
||||
-> Option<O>
|
||||
fn map_to_option<'a, O, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Option<O> where
|
||||
F: FnOnce(&ty::sty<'tcx>) -> Option<O>,
|
||||
{
|
||||
match self.resolve(fcx) {
|
||||
NoExpectation => None,
|
||||
|
|
|
@ -170,14 +170,16 @@ fn no_params<'tcx>(t: Ty<'tcx>) -> ty::Polytype<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn require_same_types<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
|
||||
t1_is_expected: bool,
|
||||
span: Span,
|
||||
t1: Ty<'tcx>,
|
||||
t2: Ty<'tcx>,
|
||||
msg: || -> String)
|
||||
-> bool {
|
||||
fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
|
||||
maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
|
||||
t1_is_expected: bool,
|
||||
span: Span,
|
||||
t1: Ty<'tcx>,
|
||||
t2: Ty<'tcx>,
|
||||
msg: M)
|
||||
-> bool where
|
||||
M: FnOnce() -> String,
|
||||
{
|
||||
let result = match maybe_infcx {
|
||||
None => {
|
||||
let infcx = infer::new_infer_ctxt(tcx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue