1
Fork 0

librustc_typeck: use unboxed closures

This commit is contained in:
Jorge Aparicio 2014-12-09 16:04:19 -05:00
parent 888f24969f
commit 521a6e62b1
5 changed files with 72 additions and 61 deletions

View file

@ -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) {

View file

@ -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));

View file

@ -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.

View file

@ -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,

View file

@ -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);