// Dorky hack to cause `dump_constraints` to only get called
// if debug mode is enabled:
- debug!("----() End constraint listing {:?}---", self.dump_constraints());
+ debug!("----() End constraint listing (subject={}) {:?}---",
+ subject, self.dump_constraints(subject));
graphviz::maybe_print_constraints_for(self, subject);
+ let graph = self.construct_graph();
+ self.expand_givens(&graph);
self.expansion(free_regions, &mut var_data);
self.contraction(free_regions, &mut var_data);
let values =
self.extract_values_and_collect_conflicts(free_regions,
- &var_data[..],
+ &var_data,
+ &graph,
errors);
self.collect_concrete_region_errors(free_regions, &values, errors);
values
}).collect()
}
- fn dump_constraints(&self) {
- debug!("----() Start constraint listing ()----");
+ fn dump_constraints(&self, subject: ast::NodeId) {
+ debug!("----() Start constraint listing (subject={}) ()----", subject);
for (idx, (constraint, _)) in self.constraints.borrow().iter().enumerate() {
debug!("Constraint {} => {}", idx, constraint.repr(self.tcx));
}
}
+ fn expand_givens(&self, graph: &RegionGraph) {
+ // Givens are a kind of horrible hack to account for
+ // constraints like 'c <= '0 that are known to hold due to
+ // closure signatures (see the comment above on the `givens`
+ // field). They should go away. But until they do, the role
+ // of this fn is to account for the transitive nature:
+ //
+ // Given 'c <= '0
+ // and '0 <= '1
+ // then 'c <= '1
+
+ let mut givens = self.givens.borrow_mut();
+ let seeds: Vec<_> = givens.iter().cloned().collect();
+ for (fr, vid) in seeds {
+ let seed_index = NodeIndex(vid.index as usize);
+ for succ_index in graph.depth_traverse(seed_index) {
+ let succ_index = succ_index.0 as u32;
+ if succ_index < self.num_vars() {
+ let succ_vid = RegionVid { index: succ_index };
+ givens.insert((fr, succ_vid));
+ }
+ }
+ }
+ }
+
fn expansion(&self, free_regions: &FreeRegionMap, var_data: &mut [VarData]) {
self.iterate_until_fixed_point("Expansion", |constraint| {
debug!("expansion: constraint={} origin={}",
&self,
free_regions: &FreeRegionMap,
var_data: &[VarData],
+ graph: &RegionGraph,
errors: &mut Vec<RegionResolutionError<'tcx>>)
-> Vec<VarValue>
{
// overlapping locations.
let mut dup_vec: Vec<_> = repeat(u32::MAX).take(self.num_vars() as usize).collect();
- let mut opt_graph = None;
-
for idx in 0..self.num_vars() as usize {
match var_data[idx].value {
Value(_) => {
starts to create problems we'll have to revisit
this portion of the code and think hard about it. =) */
- if opt_graph.is_none() {
- opt_graph = Some(self.construct_graph());
- }
- let graph = opt_graph.as_ref().unwrap();
-
let node_vid = RegionVid { index: idx as u32 };
match var_data[idx].classification {
Expanding => {
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for #24085. Errors were occuring in region
+// inference due to the requirement that `'a:b'`, which was getting
+// incorrectly translated in connection with the closure below.
+
+#[derive(Copy,Clone)]
+struct Path<'a:'b, 'b> {
+ x: &'a i32,
+ tail: Option<&'b Path<'a, 'b>>
+}
+
+#[allow(dead_code, unconditional_recursion)]
+fn foo<'a,'b,F>(p: Path<'a, 'b>, mut f: F)
+ where F: for<'c> FnMut(Path<'a, 'c>) {
+ foo(p, |x| f(x))
+}
+
+fn main() { }