From 7876cf9ca915724d1888043a9cbfedd45009e5f2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 16 Oct 2014 18:58:07 -0400 Subject: [PATCH] Check object lifetime bounds in coercions, not just trait bounds. Fixes #18055. --- src/librustc/middle/typeck/check/mod.rs | 7 ++++ .../region-object-lifetime-in-coercion.rs | 35 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/test/compile-fail/region-object-lifetime-in-coercion.rs diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index ed663cb85a2c4..94f73031a427e 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 0000000000000..6791b7c5870e0 --- /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 or the MIT license +// , 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 { + let x: Box = box v; //~ ERROR does not outlive + x +} + +fn b(v: &[u8]) -> Box { + box v //~ ERROR does not outlive +} + +fn c(v: &[u8]) -> Box { + box v // OK thanks to lifetime elision +} + +fn d<'a,'b>(v: &'a [u8]) -> Box { + box v //~ ERROR does not outlive +} + +fn e<'a:'b,'b>(v: &'a [u8]) -> Box { + box v // OK, thanks to 'a:'b +} + +fn main() { }