auto merge of #18371 : nikomatsakis/rust/issue-18262, r=pcwalton

Teach variance checker about the lifetime bounds that appear in trait object types.

[breaking-change] This patch fixes a hole in the type system which resulted in lifetime parameters that were only used in trait objects not being checked. It's hard to characterize precisely the changes that might be needed to fix target code.

cc #18262 (this fixes the test case by @jakub- but I am not sure if this is the same issue that @alexcrichton was reporting)

r? @pnkfelix 

Fixes #18205
This commit is contained in:
bors 2014-11-01 01:41:45 +00:00
commit 1442235d3f
3 changed files with 32 additions and 2 deletions

View file

@ -778,7 +778,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
variance);
}
ty::ty_trait(box ty::TyTrait { def_id, ref substs, .. }) => {
ty::ty_trait(box ty::TyTrait { def_id, ref substs, bounds }) => {
let trait_def = ty::lookup_trait_def(self.tcx(), def_id);
let generics = &trait_def.generics;
@ -796,6 +796,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
assert!(generics.types.is_empty_in(subst::FnSpace));
assert!(generics.regions.is_empty_in(subst::FnSpace));
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
let contra = self.contravariant(variance);
self.add_constraints_from_region(bounds.region_bound, contra);
self.add_constraints_from_substs(
def_id,
generics.types.get_slice(subst::TypeSpace),

View file

@ -0,0 +1,26 @@
// 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.
// Checks that regions which appear in a trait object type are
// observed by the variance inference algorithm (and hence
// `TOption` is contavariant w/r/t `'a` and not bivariant).
//
// Issue #18262.
use std::mem;
trait T { fn foo(); }
#[rustc_variance]
struct TOption<'a> { //~ ERROR regions=[[-];[];[]]
v: Option<Box<T + 'a>>,
}
fn main() { }

View file

@ -17,7 +17,7 @@ struct Parser<'a, I, O> {
}
impl<'a, I, O: 'a> Parser<'a, I, O> {
fn compose<K: 'a>(mut self, mut rhs: Parser<O, K>) -> Parser<'a, I, K> {
fn compose<K: 'a>(mut self, mut rhs: Parser<'a, O, K>) -> Parser<'a, I, K> {
Parser {
parse: box move |&mut: x: I| {
match self.parse.call_mut((x,)) {