Skip to content

Commit c4b1500

Browse files
committed
Rollup merge of #22966 - nikomatsakis:closure-region-hierarchy, r=pnkfelix
Remove the synthetic \"region bound\" from closures and instead update how type-outlives works for closure types so that it ensures that all upvars outlive the region in question. This gives the same guarantees but without introducing artificial regions (and gives better error messages to boot). This is refactoring towards #3696. r? @pnkfelix
2 parents f608afe + 00fcf79 commit c4b1500

28 files changed

+93
-230
lines changed

Diff for: src/librustc/metadata/tydecode.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -555,11 +555,9 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
555555
'k' => {
556556
assert_eq!(next(st), '[');
557557
let did = parse_def_(st, ClosureSource, conv);
558-
let region = parse_region_(st, conv);
559558
let substs = parse_substs_(st, conv);
560559
assert_eq!(next(st), ']');
561-
return ty::mk_closure(st.tcx, did,
562-
st.tcx.mk_region(region), st.tcx.mk_substs(substs));
560+
return ty::mk_closure(st.tcx, did, st.tcx.mk_substs(substs));
563561
}
564562
'P' => {
565563
assert_eq!(next(st), '[');

Diff for: src/librustc/metadata/tyencode.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,8 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
139139
enc_substs(w, cx, substs);
140140
mywrite!(w, "]");
141141
}
142-
ty::ty_closure(def, region, substs) => {
142+
ty::ty_closure(def, substs) => {
143143
mywrite!(w, "k[{}|", (cx.ds)(def));
144-
enc_region(w, cx, *region);
145144
enc_substs(w, cx, substs);
146145
mywrite!(w, "]");
147146
}

Diff for: src/librustc/middle/fast_reject.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
7474
let def_id = tcx.lang_items.owned_box().unwrap();
7575
Some(StructSimplifiedType(def_id))
7676
}
77-
ty::ty_closure(def_id, _, _) => {
77+
ty::ty_closure(def_id, _) => {
7878
Some(ClosureSimplifiedType(def_id))
7979
}
8080
ty::ty_tup(ref tys) => {

Diff for: src/librustc/middle/infer/combine.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -503,15 +503,14 @@ pub fn super_tys<'tcx, C>(this: &C,
503503
Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs)))
504504
}
505505

506-
(&ty::ty_closure(a_id, a_region, a_substs),
507-
&ty::ty_closure(b_id, b_region, b_substs))
506+
(&ty::ty_closure(a_id, a_substs),
507+
&ty::ty_closure(b_id, b_substs))
508508
if a_id == b_id => {
509509
// All ty_closure types with the same id represent
510510
// the (anonymous) type of the same closure expression. So
511511
// all of their regions should be equated.
512-
let region = try!(this.equate().regions(*a_region, *b_region));
513512
let substs = try!(this.substs_variances(None, a_substs, b_substs));
514-
Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs)))
513+
Ok(ty::mk_closure(tcx, a_id, tcx.mk_substs(substs)))
515514
}
516515

517516
(&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {

Diff for: src/librustc/middle/liveness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
14961496
fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
14971497
let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
14981498
match fn_ty.sty {
1499-
ty::ty_closure(closure_def_id, _, substs) =>
1499+
ty::ty_closure(closure_def_id, substs) =>
15001500
self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
15011501
_ =>
15021502
ty::ty_fn_ret(fn_ty),

Diff for: src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
607607
def::DefUpvar(var_id, fn_node_id) => {
608608
let ty = try!(self.node_ty(fn_node_id));
609609
match ty.sty {
610-
ty::ty_closure(closure_id, _, _) => {
610+
ty::ty_closure(closure_id, _) => {
611611
match self.typer.closure_kind(closure_id) {
612612
Some(kind) => {
613613
self.cat_upvar(id, span, var_id, fn_node_id, kind)

Diff for: src/librustc/middle/region.rs

+2
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,10 @@ impl InnermostEnclosingExpr {
320320

321321
#[derive(Debug, Copy)]
322322
pub struct Context {
323+
/// the scope that contains any new variables declared
323324
var_parent: InnermostDeclaringBlock,
324325

326+
/// region parent of expressions etc
325327
parent: InnermostEnclosingExpr,
326328
}
327329

Diff for: src/librustc/middle/traits/project.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
154154
debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}",
155155
self_ty.sty);
156156
match self_ty.sty {
157-
ty::ty_closure(closure_def_id, _, substs) => {
157+
ty::ty_closure(closure_def_id, substs) => {
158158
let closure_typer = selcx.closure_typer();
159159
let closure_type = closure_typer.closure_type(closure_def_id, substs);
160160
let ty::Binder((_, ret_type)) =

Diff for: src/librustc/middle/traits/select.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
293293
// lifetimes can appear inside the self-type.
294294
let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
295295
let (closure_def_id, substs) = match self_ty.sty {
296-
ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
296+
ty::ty_closure(id, ref substs) => (id, substs.clone()),
297297
_ => { return; }
298298
};
299299
assert!(!substs.has_escaping_regions());
@@ -1054,7 +1054,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10541054

10551055
let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
10561056
let (closure_def_id, substs) = match self_ty.sty {
1057-
ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
1057+
ty::ty_closure(id, ref substs) => (id, substs.clone()),
10581058
ty::ty_infer(ty::TyVar(_)) => {
10591059
debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
10601060
candidates.ambiguous = true;
@@ -1533,7 +1533,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15331533
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
15341534
ty::ty_tup(ref tys) => Ok(If(tys.clone())),
15351535

1536-
ty::ty_closure(def_id, _, substs) => {
1536+
ty::ty_closure(def_id, substs) => {
15371537
// FIXME -- This case is tricky. In the case of by-ref
15381538
// closures particularly, we need the results of
15391539
// inference to decide how to reflect the type of each
@@ -1687,7 +1687,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16871687
Some(tys.clone())
16881688
}
16891689

1690-
ty::ty_closure(def_id, _, substs) => {
1690+
ty::ty_closure(def_id, substs) => {
16911691
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
16921692

16931693
match self.closure_typer.closure_upvars(def_id, substs) {

Diff for: src/librustc/middle/ty.rs

+9-15
Original file line numberDiff line numberDiff line change
@@ -1367,7 +1367,7 @@ pub enum sty<'tcx> {
13671367
ty_trait(Box<TyTrait<'tcx>>),
13681368
ty_struct(DefId, &'tcx Substs<'tcx>),
13691369

1370-
ty_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
1370+
ty_closure(DefId, &'tcx Substs<'tcx>),
13711371

13721372
ty_tup(Vec<Ty<'tcx>>),
13731373

@@ -2658,8 +2658,7 @@ impl FlagComputation {
26582658
}
26592659
}
26602660

2661-
&ty_closure(_, region, substs) => {
2662-
self.add_region(*region);
2661+
&ty_closure(_, substs) => {
26632662
self.add_substs(substs);
26642663
}
26652664

@@ -2927,10 +2926,9 @@ pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
29272926
mk_t(cx, ty_struct(struct_id, substs))
29282927
}
29292928

2930-
pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
2931-
region: &'tcx Region, substs: &'tcx Substs<'tcx>)
2929+
pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
29322930
-> Ty<'tcx> {
2933-
mk_t(cx, ty_closure(closure_id, region, substs))
2931+
mk_t(cx, ty_closure(closure_id, substs))
29342932
}
29352933

29362934
pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
@@ -3513,13 +3511,11 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
35133511
apply_lang_items(cx, did, res)
35143512
}
35153513

3516-
ty_closure(did, r, substs) => {
3514+
ty_closure(did, substs) => {
35173515
// FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
35183516
let param_env = ty::empty_parameter_environment(cx);
35193517
let upvars = closure_upvars(&param_env, did, substs).unwrap();
3520-
TypeContents::union(&upvars,
3521-
|f| tc_ty(cx, &f.ty, cache))
3522-
| borrowed_contents(*r, MutMutable)
3518+
TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
35233519
}
35243520

35253521
ty_tup(ref tys) => {
@@ -5175,7 +5171,7 @@ pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
51755171
Some(tt.principal_def_id()),
51765172
ty_struct(id, _) |
51775173
ty_enum(id, _) |
5178-
ty_closure(id, _, _) =>
5174+
ty_closure(id, _) =>
51795175
Some(id),
51805176
_ =>
51815177
None
@@ -6301,10 +6297,9 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
63016297
}
63026298
ty_infer(_) => unreachable!(),
63036299
ty_err => byte!(21),
6304-
ty_closure(d, r, _) => {
6300+
ty_closure(d, _) => {
63056301
byte!(22);
63066302
did(state, d);
6307-
region(state, *r);
63086303
}
63096304
ty_projection(ref data) => {
63106305
byte!(23);
@@ -6618,8 +6613,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
66186613
ty_struct(_, substs) => {
66196614
accum_substs(accumulator, substs);
66206615
}
6621-
ty_closure(_, region, substs) => {
6622-
accumulator.push(*region);
6616+
ty_closure(_, substs) => {
66236617
accum_substs(accumulator, substs);
66246618
}
66256619
ty_bool |

Diff for: src/librustc/middle/ty_fold.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -650,10 +650,9 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
650650
let substs = substs.fold_with(this);
651651
ty::ty_struct(did, this.tcx().mk_substs(substs))
652652
}
653-
ty::ty_closure(did, ref region, ref substs) => {
654-
let r = region.fold_with(this);
653+
ty::ty_closure(did, ref substs) => {
655654
let s = substs.fold_with(this);
656-
ty::ty_closure(did, this.tcx().mk_region(r), this.tcx().mk_substs(s))
655+
ty::ty_closure(did, this.tcx().mk_substs(s))
657656
}
658657
ty::ty_projection(ref data) => {
659658
ty::ty_projection(data.fold_with(this))

Diff for: src/librustc/middle/ty_walk.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl<'tcx> TypeWalker<'tcx> {
4545
}
4646
ty::ty_enum(_, ref substs) |
4747
ty::ty_struct(_, ref substs) |
48-
ty::ty_closure(_, _, ref substs) => {
48+
ty::ty_closure(_, ref substs) => {
4949
self.push_reversed(substs.types.as_slice());
5050
}
5151
ty::ty_tup(ref ts) => {

Diff for: src/librustc/util/ppaux.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
406406
data.item_name.user_string(cx))
407407
}
408408
ty_str => "str".to_string(),
409-
ty_closure(ref did, _, substs) => {
409+
ty_closure(ref did, substs) => {
410410
let closure_tys = cx.closure_tys.borrow();
411411
closure_tys.get(did).map(|closure_type| {
412412
closure_to_string(cx, &closure_type.subst(cx, substs))

Diff for: src/librustc_trans/trans/adt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
169169

170170
Univariant(mk_struct(cx, &ftys[..], packed, t), dtor)
171171
}
172-
ty::ty_closure(def_id, _, substs) => {
172+
ty::ty_closure(def_id, substs) => {
173173
let typer = NormalizingClosureTyper::new(cx.tcx());
174174
let upvars = typer.closure_upvars(def_id, substs).unwrap();
175175
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();

Diff for: src/librustc_trans/trans/base.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
291291
ty::ty_bare_fn(_, ref f) => {
292292
(&f.sig, f.abi, None)
293293
}
294-
ty::ty_closure(closure_did, _, substs) => {
294+
ty::ty_closure(closure_did, substs) => {
295295
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
296296
function_type = typer.closure_type(closure_did, substs);
297297
let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
@@ -685,7 +685,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
685685
}
686686
})
687687
}
688-
ty::ty_closure(def_id, _, substs) => {
688+
ty::ty_closure(def_id, substs) => {
689689
let repr = adt::represent_type(cx.ccx(), t);
690690
let typer = common::NormalizingClosureTyper::new(cx.tcx());
691691
let upvars = typer.closure_upvars(def_id, substs).unwrap();
@@ -2437,7 +2437,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
24372437
let function_type;
24382438
let (fn_sig, abi, env_ty) = match fn_ty.sty {
24392439
ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, None),
2440-
ty::ty_closure(closure_did, _, substs) => {
2440+
ty::ty_closure(closure_did, substs) => {
24412441
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
24422442
function_type = typer.closure_type(closure_did, substs);
24432443
let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
@@ -2454,7 +2454,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
24542454
// These have an odd calling convention, so we need to manually
24552455
// unpack the input ty's
24562456
let input_tys = match fn_ty.sty {
2457-
ty::ty_closure(_, _, _) => {
2457+
ty::ty_closure(..) => {
24582458
assert!(abi == RustCall);
24592459

24602460
match fn_sig.inputs[0].sty {

Diff for: src/librustc_trans/trans/closure.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
138138
// duplicate declarations
139139
let function_type = erase_regions(ccx.tcx(), &function_type);
140140
let params = match function_type.sty {
141-
ty::ty_closure(_, _, substs) => &substs.types,
141+
ty::ty_closure(_, substs) => &substs.types,
142142
_ => unreachable!()
143143
};
144144
let mono_id = MonoId {

Diff for: src/librustc_trans/trans/debuginfo.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ impl<'tcx> TypeMap<'tcx> {
472472
}
473473
}
474474
},
475-
ty::ty_closure(def_id, _, substs) => {
475+
ty::ty_closure(def_id, substs) => {
476476
let typer = NormalizingClosureTyper::new(cx.tcx());
477477
let closure_ty = typer.closure_type(def_id, substs);
478478
self.get_unique_type_id_of_closure_type(cx,
@@ -2983,7 +2983,7 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
29832983
ty::ty_bare_fn(_, ref barefnty) => {
29842984
subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
29852985
}
2986-
ty::ty_closure(def_id, _, substs) => {
2986+
ty::ty_closure(def_id, substs) => {
29872987
let typer = NormalizingClosureTyper::new(cx.tcx());
29882988
let sig = typer.closure_type(def_id, substs).sig;
29892989
subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)

Diff for: src/librustc_typeck/check/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
137137
return Some(CallStep::Builtin);
138138
}
139139

140-
ty::ty_closure(def_id, _, substs) => {
140+
ty::ty_closure(def_id, substs) => {
141141
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
142142

143143
// Check whether this is a call to a closure where we

Diff for: src/librustc_typeck/check/closure.rs

-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use astconv;
1616
use middle::region;
1717
use middle::subst;
1818
use middle::ty::{self, ToPolyTraitRef, Ty};
19-
use rscope::RegionScope;
2019
use syntax::abi;
2120
use syntax::ast;
2221
use syntax::ast_util;
@@ -61,17 +60,8 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
6160
abi::RustCall,
6261
expected_sig);
6362

64-
let region = match fcx.anon_regions(expr.span, 1) {
65-
Err(_) => {
66-
fcx.ccx.tcx.sess.span_bug(expr.span,
67-
"can't make anon regions here?!")
68-
}
69-
Ok(regions) => regions[0],
70-
};
71-
7263
let closure_type = ty::mk_closure(fcx.ccx.tcx,
7364
expr_def_id,
74-
fcx.ccx.tcx.mk_region(region),
7565
fcx.ccx.tcx.mk_substs(
7666
fcx.inh.param_env.free_substs.clone()));
7767

Diff for: src/librustc_typeck/check/implicator.rs

+11-23
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use util::ppaux::Repr;
2929
pub enum Implication<'tcx> {
3030
RegionSubRegion(Option<Ty<'tcx>>, ty::Region, ty::Region),
3131
RegionSubGeneric(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
32+
RegionSubClosure(Option<Ty<'tcx>>, ty::Region, ast::DefId, &'tcx Substs<'tcx>),
3233
Predicate(ast::DefId, ty::Predicate<'tcx>),
3334
}
3435

@@ -91,29 +92,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
9192
// No borrowed content reachable here.
9293
}
9394

94-
ty::ty_closure(_, region, _) => {
95-
// An "closure type" is basically
96-
// modeled here as equivalent to a struct like
97-
//
98-
// struct TheClosure<'b> {
99-
// ...
100-
// }
101-
//
102-
// where the `'b` is the lifetime bound of the
103-
// contents (i.e., all contents must outlive 'b).
104-
//
105-
// Even though closures are glorified structs
106-
// of upvars, we do not need to consider them as they
107-
// can't generate any new constraints. The
108-
// substitutions on the closure are equal to the free
109-
// substitutions of the enclosing parameter
110-
// environment. An upvar captured by value has the
111-
// same type as the original local variable which is
112-
// already checked for consistency. If the upvar is
113-
// captured by reference it must also outlive the
114-
// region bound on the closure, but this is explicitly
115-
// handled by logic in regionck.
116-
self.push_region_constraint_from_top(*region);
95+
ty::ty_closure(def_id, substs) => {
96+
let &(r_a, opt_ty) = self.stack.last().unwrap();
97+
self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs));
11798
}
11899

119100
ty::ty_trait(ref t) => {
@@ -448,6 +429,13 @@ impl<'tcx> Repr<'tcx> for Implication<'tcx> {
448429
p.repr(tcx))
449430
}
450431

432+
Implication::RegionSubClosure(_, ref a, ref b, ref c) => {
433+
format!("RegionSubClosure({}, {}, {})",
434+
a.repr(tcx),
435+
b.repr(tcx),
436+
c.repr(tcx))
437+
}
438+
451439
Implication::Predicate(ref def_id, ref p) => {
452440
format!("Predicate({}, {})",
453441
def_id.repr(tcx),

0 commit comments

Comments
 (0)