diff options
| author | bors <bors@rust-lang.org> | 2015-07-18 11:02:58 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-07-18 11:02:58 +0000 |
| commit | a27fed7cbd9d5e2a2f025c226dd48bb0c4bbbb20 (patch) | |
| tree | 6c6640a9e220530affb4994c149c1c07ce7df822 /src | |
| parent | e0e18598198a4a370547d3ec65bc21219df81371 (diff) | |
| parent | d088db99a7c67bebb00c2d66bfaf9cb64298fba2 (diff) | |
| download | rust-a27fed7cbd9d5e2a2f025c226dd48bb0c4bbbb20.tar.gz rust-a27fed7cbd9d5e2a2f025c226dd48bb0c4bbbb20.zip | |
Auto merge of #27096 - apasel422:issue-26217, r=nikomatsakis
closes #26217 r? @nikomatsakis
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/middle/traits/fulfill.rs | 32 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-26217.rs | 16 | ||||
| -rw-r--r-- | src/test/run-pass/hrtb-type-outlives.rs (renamed from src/test/compile-fail/hrtb-type-outlives.rs) | 4 |
3 files changed, 40 insertions, 12 deletions
diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 08cb3e57015..44fc6b6b8ab 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -413,17 +413,33 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, } ty::Predicate::TypeOutlives(ref binder) => { - // For now, we just check that there are no higher-ranked - // regions. If there are, we will call this obligation an - // error. Eventually we should be able to support some - // cases here, I imagine (e.g., `for<'a> int : 'a`). + // Check if there are higher-ranked regions. match selcx.tcx().no_late_bound_regions(binder) { + // If there are, inspect the underlying type further. None => { - errors.push( - FulfillmentError::new( - obligation.clone(), - CodeSelectionError(Unimplemented))) + // Convert from `Binder<OutlivesPredicate<Ty, Region>>` to `Binder<Ty>`. + let binder = binder.map_bound_ref(|pred| pred.0); + + // Check if the type has any bound regions. + match selcx.tcx().no_late_bound_regions(&binder) { + // 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`. + None => { + errors.push( + FulfillmentError::new( + obligation.clone(), + CodeSelectionError(Unimplemented))) + } + // Otherwise, we have something of the form + // `for<'a> T: 'a where 'a not in T`, which we can treat as `T: 'static`. + Some(t_a) => { + register_region_obligation(t_a, ty::ReStatic, + obligation.cause.clone(), + region_obligations); + } + } } + // If there aren't, register the obligation. Some(ty::OutlivesPredicate(t_a, r_b)) => { register_region_obligation(t_a, r_b, obligation.cause.clone(), diff --git a/src/test/compile-fail/issue-26217.rs b/src/test/compile-fail/issue-26217.rs new file mode 100644 index 00000000000..06a8fe52588 --- /dev/null +++ b/src/test/compile-fail/issue-26217.rs @@ -0,0 +1,16 @@ +// Copyright 2015 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. + +fn foo<T>() where for<'a> T: 'a {} + +fn main<'a>() { + foo::<&'a i32>(); + //~^ ERROR the type `&'a i32` does not fulfill the required lifetime +} diff --git a/src/test/compile-fail/hrtb-type-outlives.rs b/src/test/run-pass/hrtb-type-outlives.rs index 7bb74d6b03a..083f042fec2 100644 --- a/src/test/compile-fail/hrtb-type-outlives.rs +++ b/src/test/run-pass/hrtb-type-outlives.rs @@ -34,10 +34,7 @@ impl<'a,X> Foo<&'a isize> for SomeStruct<X> } fn one() { - // In fact there is no good reason for this to be an error, but - // whatever, I'm mostly concerned it doesn't ICE right now: want_foo::<SomeStruct<usize>>(); - //~^ ERROR requirement `for<'a> usize : 'a` is not satisfied } /////////////////////////////////////////////////////////////////////////// @@ -53,7 +50,6 @@ impl<'a,X:'a> Foo<&'a isize> for AnotherStruct<X> fn two() { want_foo::<AnotherStruct<usize>>(); - //~^ ERROR requirement `for<'a> usize : 'a` is not satisfied } fn main() { } |
