Skip to content

Commit 1069c0e

Browse files
committed
add a special case for literal 'static: 'a where-clauses
This makes evaluation more consistent with fulfillment.
1 parent 9d44e9e commit 1069c0e

File tree

2 files changed

+64
-15
lines changed

2 files changed

+64
-15
lines changed

src/librustc/traits/select.rs

+31-15
Original file line numberDiff line numberDiff line change
@@ -727,26 +727,42 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
727727
if r_a == r_b {
728728
// for<'a> 'a: 'a. OK
729729
Ok(EvaluatedToOk)
730+
} else if **r_a == ty::ReStatic {
731+
// 'static: 'x always holds.
732+
//
733+
// This special case is handled somewhat inconsistently - if we
734+
// have an inference variable that is supposed to be equal to
735+
// `'static`, then we don't allow it to be equated to an LBR,
736+
// but if we have a literal `'static`, then we *do*.
737+
//
738+
// This is actually consistent with how our region inference works.
739+
//
740+
// It would appear that this sort of inconsistency would
741+
// cause "instability" problems with evaluation caching. However,
742+
// evaluation caching is only for trait predicates, and when
743+
// trait predicates create nested obligations, they contain
744+
// inference variables for all the regions in the trait - the
745+
// only way this codepath can be reached from trait predicate
746+
// evaluation is when the user typed an explicit `where 'static: 'a`
747+
// lifetime bound (in which case we want to return EvaluatedToOk).
748+
//
749+
// If we ever want to handle inference variables that might be
750+
// equatable with ReStatic, we need to make sure we are not confused by
751+
// technically-allowed-by-RFC-447-but-probably-should-not-be
752+
// impls such as
753+
// ```Rust
754+
// impl<'a, 's, T> X<'s> for T where T: Debug + 'a, 'a: 's
755+
// ```
756+
Ok(EvaluatedToOk)
730757
} else if r_a.is_late_bound() || r_b.is_late_bound() {
731758
// There is no current way to prove `for<'a> 'a: 'x`
732759
// unless `'a = 'x`, because there are no bounds involving
733760
// lifetimes.
734761

735-
// It is possible to solve `for<'a> 'x: 'a` where `'x`
736-
// is a free region by forcing `'x = 'static`. However,
737-
// fulfillment does not *quite* do this ATM (it calls
738-
// `region_outlives_predicate`, which is OK if `'x` is
739-
// literally ReStatic, but is *not* OK if `'x` is any
740-
// sort of inference variable, even if it *is* equal
741-
// to `'static`).
742-
743-
// If we ever want to handle that sort of obligations,
744-
// we need to make sure we are not confused by
745-
// technically-allowed-by-RFC-447-but-probably-should-not-be
746-
// impls such as
747-
// ```Rust
748-
// impl<'a, 's, T> X<'s> for T where T: Debug + 's, 'a: 's
749-
// ```
762+
// It might be possible to prove `for<'a> 'x: 'a` by forcing `'x`
763+
// to be `'static`. However, this is not currently done by type
764+
// inference unless `'x` is literally ReStatic. See the comment
765+
// above.
750766

751767
// We don't want to allow this sort of reasoning in intercrate
752768
// mode, for backwards-compatibility reasons.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// run-pass
12+
13+
trait Foo<'a> {
14+
fn xyz(self);
15+
}
16+
impl<'a, T> Foo<'a> for T where 'static: 'a {
17+
fn xyz(self) {}
18+
}
19+
20+
trait Bar {
21+
fn uvw(self);
22+
}
23+
impl<T> Bar for T where for<'a> T: Foo<'a> {
24+
fn uvw(self) { self.xyz(); }
25+
}
26+
27+
fn foo<T>(t: T) where T: Bar {
28+
t.uvw();
29+
}
30+
31+
fn main() {
32+
foo(0);
33+
}

0 commit comments

Comments
 (0)