Make generator interior types deterministic
This commit is contained in:
parent
6eab1ca9dd
commit
eff2884e5f
1 changed files with 15 additions and 27 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue