Change:
} } <del> ty::Predicate::TypeOutlives(..) | ty::Predicate::RegionOutlives(..) => { // we do not consider region relationships when // evaluating trait matches Ok(EvaluatedToOk) </del> <ins> ty::Predicate::TypeOutlives(ref binder) => { assert!(!binder.has_escaping_regions()); // Check if the type has higher-ranked regions. if binder.skip_binder().0.has_escaping_regions() { // If so, this obligation is an error (for now). Eventually we should be // able to support additional cases here, like `for<'a> &'a str: 'a`. // NOTE: this hack is implemented in both trait fulfillment and // evaluation. If you fix it in one place, make sure you fix it // in the other. // We don't want to allow this sort of reasoning in intercrate // mode, for backwards-compatibility reasons. if self.intercrate.is_some() { Ok(EvaluatedToAmbig) } else { Ok(EvaluatedToErr) } } else { // If the type has no late bound regions, then if we assign all // the inference variables in it to be 'static, then the type // will be 'static itself. // // Therefore, `staticize(T): 'a` holds for any `'a`, so this // obligation is fulfilled. Because evaluation works with // staticized types (yes I know this is involved with #21974), // we are 100% OK here. Ok(EvaluatedToOk) } } ty::Predicate::RegionOutlives(ref binder) => { let ty::OutlivesPredicate(r_a, r_b) = binder.skip_binder(); if r_a == r_b { // for<'a> 'a: 'a. OK Ok(EvaluatedToOk) } else if **r_a == ty::ReStatic { // 'static: 'x always holds. // // This special case is handled somewhat inconsistently - if we // have an inference variable that is supposed to be equal to // `'static`, then we don't allow it to be equated to an LBR, // but if we have a literal `'static`, then we *do*. // // This is actually consistent with how our region inference works. // // It would appear that this sort of inconsistency would // cause "instability" problems with evaluation caching. However, // evaluation caching is only for trait predicates, and when // trait predicates create nested obligations, they contain // inference variables for all the regions in the trait - the // only way this codepath can be reached from trait predicate // evaluation is when the user typed an explicit `where 'static: 'a` // lifetime bound (in which case we want to return EvaluatedToOk). // // If we ever want to handle inference variables that might be // equatable with ReStatic, we need to make sure we are not confused by // technically-allowed-by-RFC-447-but-probably-should-not-be // impls such as // ```Rust // impl<'a, 's, T> X<'s> for T where T: Debug + 'a, 'a: 's // ``` Ok(EvaluatedToOk) } else if r_a.is_late_bound() || r_b.is_late_bound() { // There is no current way to prove `for<'a> 'a: 'x` // unless `'a = 'x`, because there are no bounds involving // lifetimes. // It might be possible to prove `for<'a> 'x: 'a` by forcing `'x` // to be `'static`. However, this is not currently done by type // inference unless `'x` is literally ReStatic. See the comment // above. // We don't want to allow this sort of reasoning in intercrate // mode, for backwards-compatibility reasons. if self.intercrate.is_some() { Ok(EvaluatedToAmbig) } else { Ok(EvaluatedToErr) } } else { // Relating 2 inference variable regions. These will // always hold if our query is "staticized". Ok(EvaluatedToOk) } </ins> } ty::Predicate::ObjectSafe(trait_def_id) => {

Discussion:
This is a regression between rustc 1.20.0 and 1.21.0. 20 correctly rejects this code with the following error.
Tagging P-high because this very much affects Serde.
Same issue using Serde traits: (One possible) output:
Even better, :
Perhaps we can bisect this regression? (e.g., with )
Bisected to correct behavior in nightly-2017-07-07 -- rustc 1.20.0-nightly ( 2017-07-06), incorrect behavior in nightly-2017-07-08 -- rustc 1.20.0-nightly ( 2017-07-07). That range is Looks like
visited for triage. Assigning to
thanks, very helpful!
I think the bug is here: In particular, I think the condition is not strong enough. doesn't consider region annotations, so we probably need to not use this logic if there are any regions. But I'm wondering if the whole concept is flawed. I'm a bit fearful of regions being introduced through associated type normalization.
I have a fix.
Of course, any approach that relies on any lifetimes in the affected trait-ref is fatally flawed - here's an example where the trait ref is the region-free .
I'm not really sure what your example is meant to illustrate. That said, running that on my branch gives an error: This seems like the error I would expect, more or less. We try to use the impl to prove that but we fail to do so (because of the side condition that it adds).
BTW, the check looks like it happened because I used there, and an explicit check when he changed in to note be made true by late-bound regions.
visited for triage. bug seems to be being dealt with, assuming that PR is eventually deemed as passing muster...
Yes, I think that the "no late-bound regions" check was basically a workaround for this same problem; I removed it in the PR since I think it has a "more correct" fix.