Skip to content

Commit

Permalink
auto merge of #18371 : nikomatsakis/rust/issue-18262, r=pcwalton
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Nov 1, 2014
2 parents 88b6e93 + 9a5e7ba commit 1442235
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/librustc/middle/typeck/variance.rs
Expand Up @@ -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;

Expand All @@ -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),
Expand Down
26 changes: 26 additions & 0 deletions src/test/compile-fail/variance-trait-object-bound.rs
@@ -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() { }
2 changes: 1 addition & 1 deletion src/test/run-pass/issue-16668.rs
Expand Up @@ -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,)) {
Expand Down

0 comments on commit 1442235

Please sign in to comment.