Skip to content

Commit 6d7c66e

Browse files
committed
Introduce a "liberated fn sigs" map so that we have easy access to this
information when constructing MIR.
1 parent fffe075 commit 6d7c66e

File tree

4 files changed

+53
-24
lines changed

4 files changed

+53
-24
lines changed

src/librustc/middle/ty/context.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ pub struct Tables<'tcx> {
121121
/// Records the type of each closure. The def ID is the ID of the
122122
/// expression defining the closure.
123123
pub closure_kinds: DefIdMap<ty::ClosureKind>,
124+
125+
/// For each fn, records the "liberated" types of its arguments
126+
/// and return type. Liberated means that all bound regions
127+
/// (including late-bound regions) are replaced with free
128+
/// equivalents. This table is not used in trans (since regions
129+
/// are erased there) and hence is not serialized to metadata.
130+
pub liberated_fn_sigs: NodeMap<ty::FnSig<'tcx>>,
124131
}
125132

126133
impl<'tcx> Tables<'tcx> {
@@ -133,6 +140,7 @@ impl<'tcx> Tables<'tcx> {
133140
upvar_capture_map: FnvHashMap(),
134141
closure_tys: DefIdMap(),
135142
closure_kinds: DefIdMap(),
143+
liberated_fn_sigs: NodeMap(),
136144
}
137145
}
138146

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,6 @@ pub struct Inherited<'a, 'tcx: 'a> {
164164

165165
tables: &'a RefCell<ty::Tables<'tcx>>,
166166

167-
// A mapping from each fn's id to its signature, with all bound
168-
// regions replaced with free ones. Unlike the other tables, this
169-
// one is never copied into the tcx: it is only used by regionck.
170-
fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
171-
172167
// When we process a call like `c()` where `c` is a closure type,
173168
// we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
174169
// `FnOnce` closure. In that case, we defer full resolution of the
@@ -314,7 +309,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
314309
infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
315310
locals: RefCell::new(NodeMap()),
316311
tables: tables,
317-
fn_sig_map: RefCell::new(NodeMap()),
318312
deferred_call_resolutions: RefCell::new(DefIdMap()),
319313
deferred_cast_checks: RefCell::new(Vec::new()),
320314
}
@@ -620,22 +614,13 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
620614
ccx: ccx
621615
};
622616

623-
// Remember return type so that regionck can access it later.
624-
let mut fn_sig_tys: Vec<Ty> =
625-
arg_tys.iter()
626-
.cloned()
627-
.collect();
628-
629617
if let ty::FnConverging(ret_ty) = ret_ty {
630618
fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
631-
fn_sig_tys.push(ret_ty); // FIXME(#25759) just take implied bounds from the arguments
632619
}
633620

634-
debug!("fn-sig-map: fn_id={} fn_sig_tys={:?}",
635-
fn_id,
636-
fn_sig_tys);
621+
debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
637622

638-
inherited.fn_sig_map.borrow_mut().insert(fn_id, fn_sig_tys);
623+
inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
639624

640625
{
641626
let mut visit = GatherLocalsVisitor { fcx: &fcx, };

src/librustc_typeck/check/regionck.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,19 +284,32 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
284284
// When we enter a function, we can derive
285285
debug!("visit_fn_body(id={})", id);
286286

287-
let fn_sig_map = self.fcx.inh.fn_sig_map.borrow();
288-
let fn_sig = match fn_sig_map.get(&id) {
289-
Some(f) => f,
290-
None => {
291-
self.tcx().sess.bug(
292-
&format!("No fn-sig entry for id={}", id));
287+
let fn_sig = {
288+
let fn_sig_map = &self.infcx().tables.borrow().liberated_fn_sigs;
289+
match fn_sig_map.get(&id) {
290+
Some(f) => f.clone(),
291+
None => {
292+
self.tcx().sess.bug(
293+
&format!("No fn-sig entry for id={}", id));
294+
}
293295
}
294296
};
295297

296298
let old_region_bounds_pairs_len = self.region_bound_pairs.len();
297299

300+
// Collect the types from which we create inferred bounds.
301+
// For the return type, if diverging, substitute `bool` just
302+
// because it will have no effect.
303+
//
304+
// FIXME(#25759) return types should not be implied bounds
305+
let fn_sig_tys: Vec<_> =
306+
fn_sig.inputs.iter()
307+
.cloned()
308+
.chain(Some(fn_sig.output.unwrap_or(self.tcx().types.bool)))
309+
.collect();
310+
298311
let old_body_id = self.set_body_id(body.id);
299-
self.relate_free_regions(&fn_sig[..], body.id, span);
312+
self.relate_free_regions(&fn_sig_tys[..], body.id, span);
300313
link_fn_args(self,
301314
self.tcx().region_maps.node_extent(body.id),
302315
&fn_decl.inputs[..]);

src/librustc_typeck/check/writeback.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &hir::Expr) {
4343
wbcx.visit_expr(e);
4444
wbcx.visit_upvar_borrow_map();
4545
wbcx.visit_closures();
46+
wbcx.visit_liberated_fn_sigs();
4647
}
4748

4849
pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
@@ -63,6 +64,7 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
6364
}
6465
wbcx.visit_upvar_borrow_map();
6566
wbcx.visit_closures();
67+
wbcx.visit_liberated_fn_sigs();
6668
}
6769

6870
///////////////////////////////////////////////////////////////////////////
@@ -361,6 +363,13 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
361363
}
362364
}
363365

366+
fn visit_liberated_fn_sigs(&self) {
367+
for (&node_id, fn_sig) in self.fcx.inh.tables.borrow().liberated_fn_sigs.iter() {
368+
let fn_sig = self.resolve(fn_sig, ResolvingFnSig(node_id));
369+
self.tcx().tables.borrow_mut().liberated_fn_sigs.insert(node_id, fn_sig.clone());
370+
}
371+
}
372+
364373
fn resolve<T:TypeFoldable<'tcx>>(&self, t: &T, reason: ResolveReason) -> T {
365374
t.fold_with(&mut Resolver::new(self.fcx, reason))
366375
}
@@ -376,6 +385,7 @@ enum ResolveReason {
376385
ResolvingPattern(Span),
377386
ResolvingUpvar(ty::UpvarId),
378387
ResolvingClosure(DefId),
388+
ResolvingFnSig(ast::NodeId),
379389
}
380390

381391
impl ResolveReason {
@@ -387,6 +397,9 @@ impl ResolveReason {
387397
ResolvingUpvar(upvar_id) => {
388398
tcx.expr_span(upvar_id.closure_expr_id)
389399
}
400+
ResolvingFnSig(id) => {
401+
tcx.map.span(id)
402+
}
390403
ResolvingClosure(did) => {
391404
if let Some(node_id) = tcx.map.as_local_node_id(did) {
392405
tcx.expr_span(node_id)
@@ -463,6 +476,16 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
463476
span_err!(self.tcx.sess, span, E0196,
464477
"cannot determine a type for this closure")
465478
}
479+
480+
ResolvingFnSig(id) => {
481+
// any failures here should also fail when
482+
// resolving the patterns, closure types, or
483+
// something else.
484+
let span = self.reason.span(self.tcx);
485+
self.tcx.sess.delay_span_bug(
486+
span,
487+
&format!("cannot resolve some aspect of fn sig for {:?}", id));
488+
}
466489
}
467490
}
468491
}

0 commit comments

Comments
 (0)