1
Fork 0

Make generator interior types deterministic

This commit is contained in:
John Kåre Alsaker 2017-08-14 07:23:35 +02:00
parent 6eab1ca9dd
commit eff2884e5f

View file

@ -18,13 +18,14 @@ use syntax::ast::NodeId;
use syntax::codemap::Span; use syntax::codemap::Span;
use std::rc::Rc; use std::rc::Rc;
use super::FnCtxt; use super::FnCtxt;
use util::nodemap::FxHashSet;
use util::nodemap::FxHashMap; use util::nodemap::FxHashMap;
struct InteriorVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { struct InteriorVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
cache: FxHashMap<NodeId, Option<Span>>, cache: FxHashMap<NodeId, Option<Span>>,
types: FxHashSet<Ty<'tcx>>,
// FIXME: Use an ordered hash map here
types: Vec<Ty<'tcx>>,
region_maps: Rc<RegionMaps>, region_maps: Rc<RegionMaps>,
} }
@ -37,26 +38,19 @@ impl<'a, 'gcx, 'tcx> InteriorVisitor<'a, 'gcx, 'tcx> {
}).unwrap_or(true); }).unwrap_or(true);
if live_across_yield { if live_across_yield {
let ty = self.fcx.resolve_type_vars_if_possible(&ty);
if log_enabled!(log::LogLevel::Debug) { if log_enabled!(log::LogLevel::Debug) {
if let Some(s) = scope { let span = scope.map(|s| s.span(&self.fcx.tcx.hir).unwrap_or(DUMMY_SP));
let span = s.span(&self.fcx.tcx.hir).unwrap_or(DUMMY_SP); debug!("type in expr = {:?}, scope = {:?}, type = {:?}, span = {:?}",
debug!("type in generator with scope = {:?}, type = {:?}, span = {:?}", expr, scope, ty, span);
scope, }
self.fcx.resolve_type_vars_if_possible(&ty),
span); if !self.types.contains(&ty) {
} else { self.types.push(ty);
debug!("type in generator WITHOUT scope, type = {:?}",
self.fcx.resolve_type_vars_if_possible(&ty));
}
if let Some(e) = expr {
debug!("type from expression: {:?}, span={:?}", e, e.span);
}
} }
self.types.insert(ty);
} else { } else {
if let Some(e) = expr { debug!("no type in expr = {:?}, span = {:?}", expr, expr.map(|e| e.span));
debug!("NO type from expression: {:?}, span = {:?}", e, e.span);
}
} }
} }
} }
@ -68,19 +62,13 @@ pub fn resolve_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
let body = fcx.tcx.hir.body(body_id); let body = fcx.tcx.hir.body(body_id);
let mut visitor = InteriorVisitor { let mut visitor = InteriorVisitor {
fcx, fcx,
types: FxHashSet(), types: Vec::new(),
cache: FxHashMap(), cache: FxHashMap(),
region_maps: fcx.tcx.region_maps(def_id), region_maps: fcx.tcx.region_maps(def_id),
}; };
intravisit::walk_body(&mut visitor, body); intravisit::walk_body(&mut visitor, body);
// Deduplicate types let tuple = fcx.tcx.intern_tup(&visitor.types, false);
let set: FxHashSet<_> = visitor.types.into_iter()
.map(|t| fcx.resolve_type_vars_if_possible(&t))
.collect();
let types: Vec<_> = set.into_iter().collect();
let tuple = fcx.tcx.intern_tup(&types, false);
debug!("Types in generator {:?}, span = {:?}", tuple, body.value.span); debug!("Types in generator {:?}, span = {:?}", tuple, body.value.span);