Skip to content

Commit 9b322a6

Browse files
committed
Treat cross-crate unboxed closure def IDs consistently
Always translate the ID into the local crate ID space since presently the only way to encounter an unboxed closure type from another crate is to inline once of its functions. This may need to change if abstract return types are added. Closes #18543
1 parent 28f70d3 commit 9b322a6

File tree

3 files changed

+40
-31
lines changed

3 files changed

+40
-31
lines changed

src/librustc/metadata/tydecode.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ pub enum DefIdSource {
5656

5757
// Identifies a region parameter (`fn foo<'X>() { ... }`).
5858
RegionParameter,
59+
60+
// Identifies an unboxed closure
61+
UnboxedClosureSource
5962
}
6063
pub type conv_did<'a> =
6164
|source: DefIdSource, ast::DefId|: 'a -> ast::DefId;
@@ -465,7 +468,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
465468
}
466469
'k' => {
467470
assert_eq!(next(st), '[');
468-
let did = parse_def(st, NominalType, |x,y| conv(x,y));
471+
let did = parse_def(st, UnboxedClosureSource, |x,y| conv(x,y));
469472
let region = parse_region(st, |x,y| conv(x,y));
470473
let substs = parse_substs(st, |x,y| conv(x,y));
471474
assert_eq!(next(st), ']');

src/librustc/middle/astencode.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use metadata::encoder as e;
2121
use middle::region;
2222
use metadata::tydecode;
2323
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
24-
use metadata::tydecode::{RegionParameter};
24+
use metadata::tydecode::{RegionParameter, UnboxedClosureSource};
2525
use metadata::tyencode;
2626
use middle::mem_categorization::Typer;
2727
use middle::subst;
@@ -1801,13 +1801,17 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> {
18011801
* case. We translate them with `tr_def_id()` which will map
18021802
* the crate numbers back to the original source crate.
18031803
*
1804+
* Unboxed closures are cloned along with the function being
1805+
* inlined, and all side tables use interned node IDs, so we
1806+
* translate their def IDs accordingly.
1807+
*
18041808
* It'd be really nice to refactor the type repr to not include
18051809
* def-ids so that all these distinctions were unnecessary.
18061810
*/
18071811

18081812
let r = match source {
18091813
NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did),
1810-
TypeParameter => dcx.tr_intern_def_id(did)
1814+
TypeParameter | UnboxedClosureSource => dcx.tr_intern_def_id(did)
18111815
};
18121816
debug!("convert_def_id(source={}, did={})={}", source, did, r);
18131817
return r;

src/librustc/middle/ty.rs

+30-28
Original file line numberDiff line numberDiff line change
@@ -4632,35 +4632,37 @@ pub struct UnboxedClosureUpvar {
46324632
// Returns a list of `UnboxedClosureUpvar`s for each upvar.
46334633
pub fn unboxed_closure_upvars(tcx: &ctxt, closure_id: ast::DefId, substs: &Substs)
46344634
-> Vec<UnboxedClosureUpvar> {
4635-
if closure_id.krate == ast::LOCAL_CRATE {
4636-
let capture_mode = tcx.capture_modes.borrow().get_copy(&closure_id.node);
4637-
match tcx.freevars.borrow().find(&closure_id.node) {
4638-
None => vec![],
4639-
Some(ref freevars) => {
4640-
freevars.iter().map(|freevar| {
4641-
let freevar_def_id = freevar.def.def_id();
4642-
let freevar_ty = node_id_to_type(tcx, freevar_def_id.node);
4643-
let mut freevar_ty = freevar_ty.subst(tcx, substs);
4644-
if capture_mode == ast::CaptureByRef {
4645-
let borrow = tcx.upvar_borrow_map.borrow().get_copy(&ty::UpvarId {
4646-
var_id: freevar_def_id.node,
4647-
closure_expr_id: closure_id.node
4648-
});
4649-
freevar_ty = mk_rptr(tcx, borrow.region, ty::mt {
4650-
ty: freevar_ty,
4651-
mutbl: borrow.kind.to_mutbl_lossy()
4652-
});
4653-
}
4654-
UnboxedClosureUpvar {
4655-
def: freevar.def,
4656-
span: freevar.span,
4657-
ty: freevar_ty
4658-
}
4659-
}).collect()
4660-
}
4635+
// Presently an unboxed closure type cannot "escape" out of a
4636+
// function, so we will only encounter ones that originated in the
4637+
// local crate or were inlined into it along with some function.
4638+
// This may change if abstract return types of some sort are
4639+
// implemented.
4640+
assert!(closure_id.krate == ast::LOCAL_CRATE);
4641+
let capture_mode = tcx.capture_modes.borrow().get_copy(&closure_id.node);
4642+
match tcx.freevars.borrow().find(&closure_id.node) {
4643+
None => vec![],
4644+
Some(ref freevars) => {
4645+
freevars.iter().map(|freevar| {
4646+
let freevar_def_id = freevar.def.def_id();
4647+
let freevar_ty = node_id_to_type(tcx, freevar_def_id.node);
4648+
let mut freevar_ty = freevar_ty.subst(tcx, substs);
4649+
if capture_mode == ast::CaptureByRef {
4650+
let borrow = tcx.upvar_borrow_map.borrow().get_copy(&ty::UpvarId {
4651+
var_id: freevar_def_id.node,
4652+
closure_expr_id: closure_id.node
4653+
});
4654+
freevar_ty = mk_rptr(tcx, borrow.region, ty::mt {
4655+
ty: freevar_ty,
4656+
mutbl: borrow.kind.to_mutbl_lossy()
4657+
});
4658+
}
4659+
UnboxedClosureUpvar {
4660+
def: freevar.def,
4661+
span: freevar.span,
4662+
ty: freevar_ty
4663+
}
4664+
}).collect()
46614665
}
4662-
} else {
4663-
tcx.sess.bug("unimplemented cross-crate closure upvars")
46644666
}
46654667
}
46664668

0 commit comments

Comments
 (0)