Skip to content

Commit

Permalink
Fix all errors except error_reporting and cfg construction
Browse files Browse the repository at this point in the history
  • Loading branch information
cramertj committed Apr 15, 2017
1 parent b95e875 commit 2eddfa7
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 43 deletions.
12 changes: 8 additions & 4 deletions src/librustc/infer/region_inference/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,11 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
add_node(n2);
}

tcx.region_maps().each_encl_scope(|sub, sup| {
add_node(Node::Region(ty::ReScope(*sub)));
add_node(Node::Region(ty::ReScope(*sup)));
tcx.with_each_region_map(|_fn_id, region_maps| {
region_maps.each_encl_scope(|sub, sup| {
add_node(Node::Region(ty::ReScope(*sub)));
add_node(Node::Region(ty::ReScope(*sup)));
});
});
}

Expand Down Expand Up @@ -245,7 +247,9 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
fn edges(&self) -> dot::Edges<Edge<'tcx>> {
debug!("constraint graph has {} edges", self.map.len());
let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup)));
self.tcx.with_each_region_map(|_fn_id, region_maps| {
region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup)));
});
debug!("region graph has {} edges", v.len());
Cow::Owned(v)
}
Expand Down
61 changes: 37 additions & 24 deletions src/librustc/infer/region_inference/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
fn lub_concrete_regions(&self,
free_regions: &FreeRegionMap,
a: &'tcx Region,
b: &'tcx Region)
b: &'tcx Region,
node_id: ast::NodeId)
-> &'tcx Region {
match (a, b) {
(&ReLateBound(..), _) |
Expand Down Expand Up @@ -938,7 +939,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// A "free" region can be interpreted as "some region
// at least as big as the block fr.scope_id". So, we can
// reasonably compare free regions and scopes:
let r_id = self.tcx.region_maps()
let r_id = self.tcx.region_maps(node_id)
.nearest_common_ancestor(fr.scope, s_id);

if r_id == fr.scope {
Expand All @@ -958,7 +959,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// subtype of the region corresponding to an inner
// block.
self.tcx.mk_region(ReScope(
self.tcx.region_maps().nearest_common_ancestor(a_id, b_id)))
self.tcx.region_maps(node_id).nearest_common_ancestor(a_id, b_id)))
}

(&ReFree(a_fr), &ReFree(b_fr)) => {
Expand Down Expand Up @@ -1011,9 +1012,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {

let graph = self.construct_graph();
self.expand_givens(&graph);
self.expansion(free_regions, &mut var_data);
self.collect_errors(free_regions, &mut var_data, errors);
self.collect_var_errors(free_regions, &var_data, &graph, errors);
self.expansion(free_regions, &mut var_data, subject);
self.collect_errors(free_regions, &mut var_data, errors, subject);
self.collect_var_errors(free_regions, &var_data, &graph, errors, subject);
var_data
}

Expand Down Expand Up @@ -1056,21 +1057,25 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
}

fn expansion(&self, free_regions: &FreeRegionMap, var_values: &mut [VarValue<'tcx>]) {
fn expansion(&self,
free_regions: &FreeRegionMap,
var_values: &mut [VarValue<'tcx>],
node_id: ast::NodeId)
{
self.iterate_until_fixed_point("Expansion", |constraint, origin| {
debug!("expansion: constraint={:?} origin={:?}",
constraint, origin);
match *constraint {
ConstrainRegSubVar(a_region, b_vid) => {
let b_data = &mut var_values[b_vid.index as usize];
self.expand_node(free_regions, a_region, b_vid, b_data)
self.expand_node(free_regions, a_region, b_vid, b_data, node_id)
}
ConstrainVarSubVar(a_vid, b_vid) => {
match var_values[a_vid.index as usize] {
ErrorValue => false,
Value(a_region) => {
let b_node = &mut var_values[b_vid.index as usize];
self.expand_node(free_regions, a_region, b_vid, b_node)
self.expand_node(free_regions, a_region, b_vid, b_node, node_id)
}
}
}
Expand All @@ -1088,7 +1093,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
free_regions: &FreeRegionMap,
a_region: &'tcx Region,
b_vid: RegionVid,
b_data: &mut VarValue<'tcx>)
b_data: &mut VarValue<'tcx>,
node_id: ast::NodeId)
-> bool {
debug!("expand_node({:?}, {:?} == {:?})",
a_region,
Expand All @@ -1108,7 +1114,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {

match *b_data {
Value(cur_region) => {
let lub = self.lub_concrete_regions(free_regions, a_region, cur_region);
let lub = self.lub_concrete_regions(free_regions, a_region, cur_region, node_id);
if lub == cur_region {
return false;
}
Expand All @@ -1134,7 +1140,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
fn collect_errors(&self,
free_regions: &FreeRegionMap,
var_data: &mut Vec<VarValue<'tcx>>,
errors: &mut Vec<RegionResolutionError<'tcx>>) {
errors: &mut Vec<RegionResolutionError<'tcx>>,
node_id: ast::NodeId) {
let constraints = self.constraints.borrow();
for (constraint, origin) in constraints.iter() {
debug!("collect_errors: constraint={:?} origin={:?}",
Expand All @@ -1146,7 +1153,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}

ConstrainRegSubReg(sub, sup) => {
if free_regions.is_subregion_of(self.tcx, sub, sup) {
if free_regions.is_subregion_of(self.tcx, sub, sup, node_id) {
continue;
}

Expand Down Expand Up @@ -1174,7 +1181,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// Do not report these errors immediately:
// instead, set the variable value to error and
// collect them later.
if !free_regions.is_subregion_of(self.tcx, a_region, b_region) {
if !free_regions.is_subregion_of(self.tcx, a_region, b_region, node_id) {
debug!("collect_errors: region error at {:?}: \
cannot verify that {:?}={:?} <= {:?}",
origin,
Expand All @@ -1190,7 +1197,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
for verify in self.verifys.borrow().iter() {
debug!("collect_errors: verify={:?}", verify);
let sub = normalize(self.tcx, var_data, verify.region);
if verify.bound.is_met(self.tcx, free_regions, var_data, sub) {
if verify.bound.is_met(self.tcx, free_regions, var_data, sub, node_id) {
continue;
}

Expand All @@ -1212,7 +1219,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
free_regions: &FreeRegionMap,
var_data: &[VarValue<'tcx>],
graph: &RegionGraph<'tcx>,
errors: &mut Vec<RegionResolutionError<'tcx>>) {
errors: &mut Vec<RegionResolutionError<'tcx>>,
node_id: ast::NodeId) {
debug!("collect_var_errors");

// This is the best way that I have found to suppress
Expand Down Expand Up @@ -1262,7 +1270,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
graph,
&mut dup_vec,
node_vid,
errors);
errors,
node_id);
}
}
}
Expand Down Expand Up @@ -1315,7 +1324,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
graph: &RegionGraph<'tcx>,
dup_vec: &mut [u32],
node_idx: RegionVid,
errors: &mut Vec<RegionResolutionError<'tcx>>) {
errors: &mut Vec<RegionResolutionError<'tcx>>,
node_id: ast::NodeId) {
// Errors in expanding nodes result from a lower-bound that is
// not contained by an upper-bound.
let (mut lower_bounds, lower_dup) = self.collect_concrete_regions(graph,
Expand Down Expand Up @@ -1347,7 +1357,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {

for lower_bound in &lower_bounds {
for upper_bound in &upper_bounds {
if !free_regions.is_subregion_of(self.tcx, lower_bound.region, upper_bound.region) {
if !free_regions.is_subregion_of(
self.tcx, lower_bound.region, upper_bound.region, node_id)
{
let origin = (*self.var_origins.borrow())[node_idx.index as usize].clone();
debug!("region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
sup: {:?}",
Expand Down Expand Up @@ -1594,26 +1606,27 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
free_regions: &FreeRegionMap,
var_values: &Vec<VarValue<'tcx>>,
min: &'tcx ty::Region)
min: &'tcx ty::Region,
node_id: ast::NodeId)
-> bool {
match self {
&VerifyBound::AnyRegion(ref rs) =>
rs.iter()
.map(|&r| normalize(tcx, var_values, r))
.any(|r| free_regions.is_subregion_of(tcx, min, r)),
.any(|r| free_regions.is_subregion_of(tcx, min, r, node_id)),

&VerifyBound::AllRegions(ref rs) =>
rs.iter()
.map(|&r| normalize(tcx, var_values, r))
.all(|r| free_regions.is_subregion_of(tcx, min, r)),
.all(|r| free_regions.is_subregion_of(tcx, min, r, node_id)),

&VerifyBound::AnyBound(ref bs) =>
bs.iter()
.any(|b| b.is_met(tcx, free_regions, var_values, min)),
.any(|b| b.is_met(tcx, free_regions, var_values, min, node_id)),

&VerifyBound::AllBounds(ref bs) =>
bs.iter()
.all(|b| b.is_met(tcx, free_regions, var_values, min)),
.all(|b| b.is_met(tcx, free_regions, var_values, min, node_id)),
}
}
}
11 changes: 8 additions & 3 deletions src/librustc/middle/free_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use ty::{self, TyCtxt, FreeRegion, Region};
use ty::wf::ImpliedBound;
use rustc_data_structures::transitive_relation::TransitiveRelation;
use syntax::ast::NodeId;

#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct FreeRegionMap {
Expand Down Expand Up @@ -124,10 +125,14 @@ impl FreeRegionMap {

/// Determines whether one region is a subregion of another. This is intended to run *after
/// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
///
/// `node_id` should be the id of a node in one of the regions, or of the function the regions
/// are in
pub fn is_subregion_of(&self,
tcx: TyCtxt,
sub_region: &ty::Region,
super_region: &ty::Region)
super_region: &ty::Region,
node_id: NodeId)
-> bool {
let result = sub_region == super_region || {
match (sub_region, super_region) {
Expand All @@ -136,10 +141,10 @@ impl FreeRegionMap {
true,

(&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) =>
tcx.region_maps().is_subscope_of(sub_scope, super_scope),
tcx.region_maps(node_id).is_subscope_of(sub_scope, super_scope),

(&ty::ReScope(sub_scope), &ty::ReFree(fr)) =>
tcx.region_maps().is_subscope_of(sub_scope, fr.scope) ||
tcx.region_maps(node_id).is_subscope_of(sub_scope, fr.scope) ||
self.is_static(fr),

(&ty::ReFree(sub_fr), &ty::ReFree(super_fr)) =>
Expand Down
22 changes: 14 additions & 8 deletions src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1269,23 +1269,29 @@ impl<'hir, 'a> Visitor<'hir> for RegionResolutionVisitor<'hir, 'a> {
}
}

pub fn resolve_crate<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {

struct CrateResolutionVisitor<'a, 'tcx: 'a>(TyCtxt<'a, 'tcx, 'tcx>);
pub fn resolve_crate<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, f: F)
where F: FnMut(DefId, Rc<RegionMaps>) -> ()
{
struct CrateResolutionVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F>(TyCtxt<'a, 'gcx, 'tcx>, F)
where F: FnMut(DefId, Rc<RegionMaps>) -> ();

impl<'a, 'hir: 'a> Visitor<'hir> for CrateResolutionVisitor<'a, 'hir> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
impl<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F> Visitor<'gcx> for
CrateResolutionVisitor<'a, 'gcx, 'tcx, F>
where F: FnMut(DefId, Rc<RegionMaps>) -> ()
{
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
NestedVisitorMap::OnlyBodies(&self.0.hir)
}
fn visit_fn(&mut self, _fk: FnKind<'hir>, _fd: &'hir FnDecl,
fn visit_fn(&mut self, _fk: FnKind<'tcx>, _fd: &'tcx FnDecl,
_b: hir::BodyId, _s: Span, fn_id: NodeId)
{
let fn_def_id = self.0.hir.local_def_id(fn_id);
ty::queries::region_resolve_fn::get(self.0, DUMMY_SP, fn_def_id);
(self.1)(fn_def_id, ty::queries::region_resolve_fn::get(self.0, DUMMY_SP, fn_def_id));
}
}

tcx.hir.krate().visit_all_item_likes(&mut CrateResolutionVisitor(tcx).as_deep_visitor());
tcx.hir.krate().visit_all_item_likes(
&mut CrateResolutionVisitor(tcx, f).as_deep_visitor());
}

fn region_resolve_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_id: DefId)
Expand Down
7 changes: 6 additions & 1 deletion src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use hir::map as hir_map;
use hir::map::DisambiguatedDefPathData;
use middle::free_region::FreeRegionMap;
use middle::lang_items;
use middle::region::RegionMaps;
use middle::region::{self, RegionMaps};
use middle::resolve_lifetime;
use middle::stability;
use mir::Mir;
Expand Down Expand Up @@ -679,6 +679,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
ty::queries::region_resolve_fn::get(self, DUMMY_SP, self.hir.local_def_id(outermost_fn_id))
}

pub fn with_each_region_map<F>(self, f: F) where F: FnMut(DefId, Rc<RegionMaps>) -> ()
{
region::resolve_crate(self, f);
}

/// Create a type context and call the closure with a `TyCtxt` reference
/// to the context. The closure enforces that the type context and any interned
/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
Expand Down
8 changes: 5 additions & 3 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use ich::StableHashingContext;
use middle::const_val::ConstVal;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::privacy::AccessLevels;
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
use middle::region::{CodeExtent, ROOT_CODE_EXTENT, DUMMY_CODE_EXTENT};
use middle::resolve_lifetime::ObjectLifetimeDefault;
use mir::Mir;
use traits;
Expand Down Expand Up @@ -2474,7 +2474,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

// for an empty parameter environment, there ARE no free
// regions, so it shouldn't matter what we use for the free id
let free_id_outlive = self.region_maps().node_extent(ast::DUMMY_NODE_ID);
let free_id_outlive = DUMMY_CODE_EXTENT;
ty::ParameterEnvironment {
free_substs: self.intern_substs(&[]),
caller_bounds: Vec::new(),
Expand Down Expand Up @@ -2556,8 +2556,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
is_sized_cache: RefCell::new(FxHashMap()),
};

let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
let cause = traits::ObligationCause::misc(span,
free_id_outlive.node_id(&self.region_maps()));
free_id_outlive.node_id(
&self.region_maps(node_id)));
traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
}

Expand Down

0 comments on commit 2eddfa7

Please sign in to comment.