auto merge of #17760 : bkoropoff/rust/issue-17737, r=eddyb

This is a quick fix.  In the long term, the `TyVisitor` interface should be expanded to better represent closure types.

Closes issue #17737
This commit is contained in:
bors 2014-10-04 17:47:06 +00:00
commit e434aa1cf7
2 changed files with 60 additions and 18 deletions

View File

@ -127,6 +127,22 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
self.visit(name, []);
}
fn visit_closure_ty(&mut self, fty: &ty::ClosureTy, is_unboxed: bool) {
let pureval = ast_fn_style_constant(fty.fn_style);
let sigilval = match fty.store {
ty::UniqTraitStore => 2u,
ty::RegionTraitStore(..) => 4u,
};
let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
let extra = vec!(self.c_uint(pureval),
self.c_uint(sigilval),
self.c_uint(fty.sig.inputs.len()),
self.c_uint(retval));
self.visit("enter_fn", extra.as_slice());
self.visit_sig(retval, &fty.sig, is_unboxed);
self.visit("leave_fn", extra.as_slice());
}
// Entrypoint
pub fn visit_ty(&mut self, t: ty::t) {
let bcx = self.bcx;
@ -247,20 +263,8 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
// FIXME (#2594): fetch constants out of intrinsic
// FIXME (#4809): visitor should break out bare fns from other fns
ty::ty_closure(ref fty) => {
let pureval = ast_fn_style_constant(fty.fn_style);
let sigilval = match fty.store {
ty::UniqTraitStore => 2u,
ty::RegionTraitStore(..) => 4u,
};
let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
let extra = vec!(self.c_uint(pureval),
self.c_uint(sigilval),
self.c_uint(fty.sig.inputs.len()),
self.c_uint(retval));
self.visit("enter_fn", extra.as_slice());
self.visit_sig(retval, &fty.sig);
self.visit("leave_fn", extra.as_slice());
ty::ty_closure(box ref fty) => {
self.visit_closure_ty(fty, false);
}
// FIXME (#2594): fetch constants out of intrinsic:: for the
@ -274,7 +278,7 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
self.c_uint(fty.sig.inputs.len()),
self.c_uint(retval));
self.visit("enter_fn", extra.as_slice());
self.visit_sig(retval, &fty.sig);
self.visit_sig(retval, &fty.sig, false);
self.visit("leave_fn", extra.as_slice());
}
@ -388,7 +392,11 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
// Miscellaneous extra types
ty::ty_infer(_) => self.leaf("infer"),
ty::ty_err => self.leaf("err"),
ty::ty_unboxed_closure(..) => self.leaf("err"),
ty::ty_unboxed_closure(ref def_id, _) => {
let closure_map = tcx.unboxed_closures.borrow();
let fty = &closure_map.find(def_id).unwrap().closure_type;
self.visit_closure_ty(fty, true);
}
ty::ty_param(ref p) => {
let extra = vec!(self.c_uint(p.idx));
self.visit("param", extra.as_slice())
@ -396,8 +404,18 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
}
}
pub fn visit_sig(&mut self, retval: uint, sig: &ty::FnSig) {
for (i, arg) in sig.inputs.iter().enumerate() {
pub fn visit_sig(&mut self, retval: uint, sig: &ty::FnSig, is_unboxed: bool) {
let args = if is_unboxed {
match ty::get(sig.inputs[0]).sty {
ty::ty_tup(ref contents) => contents.iter(),
ty::ty_nil => [].iter(),
_ => unreachable!()
}
} else {
sig.inputs.iter()
};
for (i, arg) in args.enumerate() {
let modeval = 5u; // "by copy"
let extra = vec!(self.c_uint(i),
self.c_uint(modeval),

View File

@ -0,0 +1,24 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(unboxed_closures)]
// Test generating type visitor glue for unboxed closures
extern crate debug;
fn main() {
let expected = "fn(); fn(uint, uint) -> uint; fn() -> !";
let result = format!("{:?}; {:?}; {:?}",
|:| {},
|&: x: uint, y: uint| { x + y },
|&mut:| -> ! { fail!() });
assert_eq!(expected, result.as_slice());
}