Change:
Notably, this does not occur with a trait like: This smells like a bug to me, unless a language change introduced special treatment of with regard to lifetimes.
An interesting quirk is that if you replace with just , it compiles fine with the impl.
cc
are you saying this used to work? Just curious what the original was.
(Also it seems difficult if not impossible to satisfy the combination of and ..... well I guess of static would, but I don't know if we can deduce that.
Yes, this used to work. This bug is affecting
It looks like this may have been introduced in . Prior to this, checking for bounds in was done via , which creates a throw-away inference context before calling into trait selection. It now goes through the ; the impl of for uses its own inference context. This causes region constraints introduced during trait selection for to stick around, resulting in a seemingly inappropriate transitive constraint between the free region within the closure body and at the call site of .
hmm good catch, sorry I let this slip through last week :( I'll try to pay it some attention now. The current code does not seem entirely wrong to me, though. I have to think this through a bit.

Discussion:
} pub fn node_is_reachable(&self, id: ast::NodeId) -> bool { <del> self.graph.depth_traverse(self.entry).any(|node| node.id() == id) </del> <ins> self.graph.depth_traverse(self.entry) .any(|idx| self.graph.node_data(idx).id() == id) </ins> } }

// Dorky hack to cause `dump_constraints` to only get called // if debug mode is enabled: <del> debug!("----() End constraint listing {:?}---", self.dump_constraints()); </del> <ins> debug!("----() End constraint listing (subject={}) {:?}---", subject, self.dump_constraints(subject)); </ins> graphviz::maybe_print_constraints_for(self, subject); <ins> let graph = self.construct_graph(); self.expand_givens(&graph); </ins> self.expansion(free_regions, &mut var_data); self.contraction(free_regions, &mut var_data); let values = self.extract_values_and_collect_conflicts(free_regions, <del> &var_data[..], </del> <ins> &var_data, &graph, </ins> errors); self.collect_concrete_region_errors(free_regions, &values, errors); values

}).collect() } <del> fn dump_constraints(&self) { debug!("----() Start constraint listing ()----"); </del> <ins> fn dump_constraints(&self, subject: ast::NodeId) { debug!("----() Start constraint listing (subject={}) ()----", subject); </ins> for (idx, (constraint, _)) in self.constraints.borrow().iter().enumerate() { debug!("Constraint {} => {}", idx, constraint.repr(self.tcx)); } } <ins> 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)); } } } } </ins> 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], <ins> graph: &RegionGraph, </ins> errors: &mut Vec<RegionResolutionError<'tcx>>) -> Vec<VarValue> {

// overlapping locations. let mut dup_vec: Vec<_> = repeat(u32::MAX).take(self.num_vars() as usize).collect(); <del> let mut opt_graph = None; </del> 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. =) */ <del> if opt_graph.is_none() { opt_graph = Some(self.construct_graph()); } let graph = opt_graph.as_ref().unwrap(); </del> let node_vid = RegionVid { index: idx as u32 }; match var_data[idx].classification { Expanding => {

} impl<'g, N:Debug, E:Debug> Iterator for DepthFirstTraversal<'g, N, E> { <del> type Item = &'g N; </del> <ins> type Item = NodeIndex; </ins> <del> fn next(&mut self) -> Option<&'g N> { </del> <ins> fn next(&mut self) -> Option<NodeIndex> { </ins> while let Some(idx) = self.stack.pop() { if !self.visited.insert(idx.node_id()) { continue;

} } <del> return Some(self.graph.node_data(idx)); </del> <ins> return Some(idx); </ins> } return None;

// return slot alloca. This can cause errors related to clean-up due to // the clobbering of the existing value in the return slot. fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bool { <del> for n in cfg.graph.depth_traverse(cfg.entry) { </del> <ins> for index in cfg.graph.depth_traverse(cfg.entry) { let n = cfg.graph.node_data(index); </ins> match tcx.map.find(n.id()) { Some(ast_map::NodeExpr(ex)) => { if let ast::ExprRet(Some(ref ret_expr)) = ex.node {

<ins> // 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() { } </ins>