Skip to content

Commit e434aa1

Browse files
committed
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
2 parents 20f4c45 + 404db68 commit e434aa1

File tree

2 files changed

+60
-18
lines changed

2 files changed

+60
-18
lines changed

Diff for: src/librustc/middle/trans/reflect.rs

+36-18
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,22 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
127127
self.visit(name, []);
128128
}
129129

130+
fn visit_closure_ty(&mut self, fty: &ty::ClosureTy, is_unboxed: bool) {
131+
let pureval = ast_fn_style_constant(fty.fn_style);
132+
let sigilval = match fty.store {
133+
ty::UniqTraitStore => 2u,
134+
ty::RegionTraitStore(..) => 4u,
135+
};
136+
let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
137+
let extra = vec!(self.c_uint(pureval),
138+
self.c_uint(sigilval),
139+
self.c_uint(fty.sig.inputs.len()),
140+
self.c_uint(retval));
141+
self.visit("enter_fn", extra.as_slice());
142+
self.visit_sig(retval, &fty.sig, is_unboxed);
143+
self.visit("leave_fn", extra.as_slice());
144+
}
145+
130146
// Entrypoint
131147
pub fn visit_ty(&mut self, t: ty::t) {
132148
let bcx = self.bcx;
@@ -247,20 +263,8 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
247263

248264
// FIXME (#2594): fetch constants out of intrinsic
249265
// FIXME (#4809): visitor should break out bare fns from other fns
250-
ty::ty_closure(ref fty) => {
251-
let pureval = ast_fn_style_constant(fty.fn_style);
252-
let sigilval = match fty.store {
253-
ty::UniqTraitStore => 2u,
254-
ty::RegionTraitStore(..) => 4u,
255-
};
256-
let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
257-
let extra = vec!(self.c_uint(pureval),
258-
self.c_uint(sigilval),
259-
self.c_uint(fty.sig.inputs.len()),
260-
self.c_uint(retval));
261-
self.visit("enter_fn", extra.as_slice());
262-
self.visit_sig(retval, &fty.sig);
263-
self.visit("leave_fn", extra.as_slice());
266+
ty::ty_closure(box ref fty) => {
267+
self.visit_closure_ty(fty, false);
264268
}
265269

266270
// FIXME (#2594): fetch constants out of intrinsic:: for the
@@ -274,7 +278,7 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
274278
self.c_uint(fty.sig.inputs.len()),
275279
self.c_uint(retval));
276280
self.visit("enter_fn", extra.as_slice());
277-
self.visit_sig(retval, &fty.sig);
281+
self.visit_sig(retval, &fty.sig, false);
278282
self.visit("leave_fn", extra.as_slice());
279283
}
280284

@@ -388,16 +392,30 @@ impl<'a, 'blk, 'tcx> Reflector<'a, 'blk, 'tcx> {
388392
// Miscellaneous extra types
389393
ty::ty_infer(_) => self.leaf("infer"),
390394
ty::ty_err => self.leaf("err"),
391-
ty::ty_unboxed_closure(..) => self.leaf("err"),
395+
ty::ty_unboxed_closure(ref def_id, _) => {
396+
let closure_map = tcx.unboxed_closures.borrow();
397+
let fty = &closure_map.find(def_id).unwrap().closure_type;
398+
self.visit_closure_ty(fty, true);
399+
}
392400
ty::ty_param(ref p) => {
393401
let extra = vec!(self.c_uint(p.idx));
394402
self.visit("param", extra.as_slice())
395403
}
396404
}
397405
}
398406

399-
pub fn visit_sig(&mut self, retval: uint, sig: &ty::FnSig) {
400-
for (i, arg) in sig.inputs.iter().enumerate() {
407+
pub fn visit_sig(&mut self, retval: uint, sig: &ty::FnSig, is_unboxed: bool) {
408+
let args = if is_unboxed {
409+
match ty::get(sig.inputs[0]).sty {
410+
ty::ty_tup(ref contents) => contents.iter(),
411+
ty::ty_nil => [].iter(),
412+
_ => unreachable!()
413+
}
414+
} else {
415+
sig.inputs.iter()
416+
};
417+
418+
for (i, arg) in args.enumerate() {
401419
let modeval = 5u; // "by copy"
402420
let extra = vec!(self.c_uint(i),
403421
self.c_uint(modeval),

Diff for: src/test/run-pass/issue-17737.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(unboxed_closures)]
12+
13+
// Test generating type visitor glue for unboxed closures
14+
15+
extern crate debug;
16+
17+
fn main() {
18+
let expected = "fn(); fn(uint, uint) -> uint; fn() -> !";
19+
let result = format!("{:?}; {:?}; {:?}",
20+
|:| {},
21+
|&: x: uint, y: uint| { x + y },
22+
|&mut:| -> ! { fail!() });
23+
assert_eq!(expected, result.as_slice());
24+
}

0 commit comments

Comments
 (0)