about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-01 01:41:45 +0000
committerbors <bors@rust-lang.org>2014-11-01 01:41:45 +0000
commit1442235d3feab4c5ca3f55e2b3345583f640a17e (patch)
tree1883c6ac50cc96daf4bd3efca9c29d355f91c55d
parent88b6e93d35c34e143ba060a617e71c8af10fa15e (diff)
parent9a5e7ba4c7eefb2f40389966c562fbadcc778625 (diff)
downloadrust-1442235d3feab4c5ca3f55e2b3345583f640a17e.tar.gz
rust-1442235d3feab4c5ca3f55e2b3345583f640a17e.zip
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 
-rw-r--r--src/librustc/middle/typeck/variance.rs6
-rw-r--r--src/test/compile-fail/variance-trait-object-bound.rs26
-rw-r--r--src/test/run-pass/issue-16668.rs2
3 files changed, 32 insertions, 2 deletions
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index 5e62a8e9451..9a90381854a 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -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),
diff --git a/src/test/compile-fail/variance-trait-object-bound.rs b/src/test/compile-fail/variance-trait-object-bound.rs
new file mode 100644
index 00000000000..c61f2ff79c0
--- /dev/null
+++ b/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() { }
diff --git a/src/test/run-pass/issue-16668.rs b/src/test/run-pass/issue-16668.rs
index b66fb4306d0..92f8030a0dc 100644
--- a/src/test/run-pass/issue-16668.rs
+++ b/src/test/run-pass/issue-16668.rs
@@ -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,)) {