about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-10-16 18:58:07 -0400
committerNiko Matsakis <niko@alum.mit.edu>2014-10-16 18:58:42 -0400
commit7876cf9ca915724d1888043a9cbfedd45009e5f2 (patch)
tree7233c6d98467305ec886950f8b07110b24cdd2d4
parent4a382d7c4743775e9ee87735ed606b0a673d8ed5 (diff)
downloadrust-7876cf9ca915724d1888043a9cbfedd45009e5f2.tar.gz
rust-7876cf9ca915724d1888043a9cbfedd45009e5f2.zip
Check object lifetime bounds in coercions, not just trait bounds. Fixes #18055.
-rw-r--r--src/librustc/middle/typeck/check/mod.rs7
-rw-r--r--src/test/compile-fail/region-object-lifetime-in-coercion.rs35
2 files changed, 42 insertions, 0 deletions
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index ed663cb85a2..94f73031a42 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1681,10 +1681,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.register_unsize_obligations(span, &**u)
             }
             ty::UnsizeVtable(ref ty_trait, self_ty) => {
+                // If the type is `Foo+'a`, ensures that the type
+                // being cast to `Foo+'a` implements `Foo`:
                 vtable2::register_object_cast_obligations(self,
                                                           span,
                                                           ty_trait,
                                                           self_ty);
+
+                // If the type is `Foo+'a`, ensures that the type
+                // being cast to `Foo+'a` outlives `'a`:
+                let origin = infer::RelateObjectBound(span);
+                self.register_region_obligation(origin, self_ty, ty_trait.bounds.region_bound);
             }
         }
     }
diff --git a/src/test/compile-fail/region-object-lifetime-in-coercion.rs b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
new file mode 100644
index 00000000000..6791b7c5870
--- /dev/null
+++ b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
@@ -0,0 +1,35 @@
+// 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.
+
+// Test that attempts to implicitly coerce a value into an
+// object respect the lifetime bound on the object type.
+
+fn a(v: &[u8]) -> Box<Clone + 'static> {
+    let x: Box<Clone + 'static> = box v; //~ ERROR does not outlive
+    x
+}
+
+fn b(v: &[u8]) -> Box<Clone + 'static> {
+    box v //~ ERROR does not outlive
+}
+
+fn c(v: &[u8]) -> Box<Clone> {
+    box v // OK thanks to lifetime elision
+}
+
+fn d<'a,'b>(v: &'a [u8]) -> Box<Clone+'b> {
+    box v //~ ERROR does not outlive
+}
+
+fn e<'a:'b,'b>(v: &'a [u8]) -> Box<Clone+'b> {
+    box v // OK, thanks to 'a:'b
+}
+
+fn main() { }