about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-02-12 09:37:52 -0500
committerNiko Matsakis <niko@alum.mit.edu>2015-02-16 10:55:37 -0500
commit369adaf5150877c124de99a1b9a94f7b522aade6 (patch)
tree6a8524bd83db4dc3e2f082a63556e4d715d0fe27
parentab579883f27e511d6325f7b20dbc147ad0ecef6f (diff)
downloadrust-369adaf5150877c124de99a1b9a94f7b522aade6.tar.gz
rust-369adaf5150877c124de99a1b9a94f7b522aade6.zip
Implement the rules for RFC 599, and add various tests.
Fixes #22211.
-rw-r--r--src/librustc_typeck/astconv.rs71
-rw-r--r--src/test/compile-fail/issue-11374.rs4
-rw-r--r--src/test/compile-fail/issue-5216.rs8
-rw-r--r--src/test/compile-fail/object-lifetime-default-ambiguous.rs60
-rw-r--r--src/test/compile-fail/object-lifetime-default-elision.rs89
-rw-r--r--src/test/compile-fail/object-lifetime-default-from-box-error.rs45
-rw-r--r--src/test/compile-fail/object-lifetime-default-mybox.rs44
-rw-r--r--src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs2
-rw-r--r--src/test/compile-fail/region-object-lifetime-1.rs29
-rw-r--r--src/test/compile-fail/region-object-lifetime-2.rs24
-rw-r--r--src/test/compile-fail/region-object-lifetime-3.rs28
-rw-r--r--src/test/compile-fail/region-object-lifetime-4.rs26
-rw-r--r--src/test/compile-fail/region-object-lifetime-5.rs25
-rw-r--r--src/test/compile-fail/region-object-lifetime-in-coercion.rs4
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-1.rs (renamed from src/test/compile-fail/regions-close-object-into-object.rs)15
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-2.rs23
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-3.rs25
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-4.rs24
-rw-r--r--src/test/compile-fail/seq-args.rs2
-rw-r--r--src/test/compile-fail/structure-constructor-type-mismatch.rs1
-rw-r--r--src/test/compile-fail/trait-bounds-cant-coerce.rs2
-rw-r--r--src/test/compile-fail/trait-bounds-sugar.rs3
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs1
-rw-r--r--src/test/run-pass/object-lifetime-default-from-ref-struct.rs47
26 files changed, 542 insertions, 68 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index d4252a92695..dd814962c71 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -438,23 +438,25 @@ fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>,
 {
     let regions: Vec<_> =
         data.lifetimes.iter()
-        .map(|l| ast_region_to_region(this.tcx(), l))
-        .collect();
+                      .map(|l| ast_region_to_region(this.tcx(), l))
+                      .collect();
 
     let region_substs =
         create_region_substs(this, rscope, span, decl_generics, regions);
 
     let types: Vec<_> =
         data.types.iter()
-        .map(|t| ast_ty_to_ty(this, rscope, &**t))
-        .collect();
+                  .enumerate()
+                  .map(|(i,t)| ast_ty_arg_to_ty(this, rscope, decl_generics,
+                                                i, &region_substs, t))
+                  .collect();
 
     let assoc_bindings: Vec<_> =
         data.bindings.iter()
-        .map(|b| ConvertedBinding { item_name: b.ident.name,
-                                    ty: ast_ty_to_ty(this, rscope, &*b.ty),
-                                    span: b.span })
-        .collect();
+                     .map(|b| ConvertedBinding { item_name: b.ident.name,
+                                                 ty: ast_ty_to_ty(this, rscope, &*b.ty),
+                                                 span: b.span })
+                     .collect();
 
     (region_substs, types, assoc_bindings)
 }
@@ -525,9 +527,11 @@ fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>,
         create_region_substs(this, rscope, span, decl_generics, Vec::new());
 
     let binding_rscope = BindingRscope::new();
-    let inputs = data.inputs.iter()
-                            .map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
-                            .collect::<Vec<Ty<'tcx>>>();
+    let inputs =
+        data.inputs.iter()
+                   .map(|a_t| ast_ty_arg_to_ty(this, &binding_rscope, decl_generics,
+                                               0, &region_substs, a_t))
+                   .collect::<Vec<Ty<'tcx>>>();
 
     let input_params: Vec<_> = repeat(String::new()).take(inputs.len()).collect();
     let (implied_output_region,
@@ -655,7 +659,7 @@ fn ast_path_to_trait_ref<'a,'tcx>(
 
     let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
         ast::AngleBracketedParameters(ref data) => {
-            // For now, require that parenthetical5D notation be used
+            // For now, require that parenthetical notation be used
             // only with `Fn()` etc.
             if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
                 span_err!(this.tcx().sess, path.span, E0215,
@@ -1070,10 +1074,45 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
                              qpath.item_path.identifier.name);
 }
 
-// Parses the programmer's textual representation of a type into our
-// internal notion of a type.
-pub fn ast_ty_to_ty<'tcx>(
-        this: &AstConv<'tcx>, rscope: &RegionScope, ast_ty: &ast::Ty) -> Ty<'tcx>
+/// Convert a type supplied as value for a type argument from AST into our
+/// our internal representation. This is the same as `ast_ty_to_ty` but that
+/// it applies the object lifetime default.
+///
+/// # Parameters
+///
+/// * `this`, `rscope`: the surrounding context
+/// * `decl_generics`: the generics of the struct/enum/trait declaration being
+///   referenced
+/// * `index`: the index of the type parameter being instantiated from the list
+///   (we assume it is in the `TypeSpace`)
+/// * `region_substs`: a partial substitution consisting of
+///   only the region type parameters being supplied to this type.
+/// * `ast_ty`: the ast representation of the type being supplied
+pub fn ast_ty_arg_to_ty<'tcx>(this: &AstConv<'tcx>,
+                              rscope: &RegionScope,
+                              decl_generics: &ty::Generics<'tcx>,
+                              index: usize,
+                              region_substs: &Substs<'tcx>,
+                              ast_ty: &ast::Ty)
+                              -> Ty<'tcx>
+{
+    let tcx = this.tcx();
+
+    if let Some(def) = decl_generics.types.opt_get(TypeSpace, index) {
+        let object_lifetime_default = def.object_lifetime_default.subst(tcx, region_substs);
+        let rscope1 = &ObjectLifetimeDefaultRscope::new(rscope, object_lifetime_default);
+        ast_ty_to_ty(this, rscope1, ast_ty)
+    } else {
+        ast_ty_to_ty(this, rscope, ast_ty)
+    }
+}
+
+/// Parses the programmer's textual representation of a type into our
+/// internal notion of a type.
+pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
+                          rscope: &RegionScope,
+                          ast_ty: &ast::Ty)
+                          -> Ty<'tcx>
 {
     debug!("ast_ty_to_ty(ast_ty={})",
            ast_ty.repr(this.tcx()));
diff --git a/src/test/compile-fail/issue-11374.rs b/src/test/compile-fail/issue-11374.rs
index 6dbea33d7d5..09d7293a3d0 100644
--- a/src/test/compile-fail/issue-11374.rs
+++ b/src/test/compile-fail/issue-11374.rs
@@ -12,7 +12,7 @@ use std::old_io;
 use std::vec;
 
 pub struct Container<'a> {
-    reader: &'a mut Reader //~ ERROR explicit lifetime bound required
+    reader: &'a mut Reader
 }
 
 impl<'a> Container<'a> {
@@ -33,5 +33,5 @@ pub fn for_stdin<'a>() -> Container<'a> {
 fn main() {
     let mut c = for_stdin();
     let mut v = Vec::new();
-    c.read_to(v);
+    c.read_to(v); //~ ERROR mismatched types
 }
diff --git a/src/test/compile-fail/issue-5216.rs b/src/test/compile-fail/issue-5216.rs
index fef414ce978..81424577d49 100644
--- a/src/test/compile-fail/issue-5216.rs
+++ b/src/test/compile-fail/issue-5216.rs
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 fn f() { }
-struct S(Box<FnMut()>); //~ ERROR explicit lifetime bound required
-pub static C: S = S(f);
+struct S(Box<FnMut()>);
+pub static C: S = S(f); //~ ERROR mismatched types
 
 
 fn g() { }
-type T = Box<FnMut()>;  //~ ERROR explicit lifetime bound required
-pub static D: T = g;
+type T = Box<FnMut()>;
+pub static D: T = g; //~ ERROR mismatched types
 
 fn main() {}
diff --git a/src/test/compile-fail/object-lifetime-default-ambiguous.rs b/src/test/compile-fail/object-lifetime-default-ambiguous.rs
new file mode 100644
index 00000000000..c899232b733
--- /dev/null
+++ b/src/test/compile-fail/object-lifetime-default-ambiguous.rs
@@ -0,0 +1,60 @@
+// Copyright 2015 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 if a struct declares multiple region bounds for a given
+// type parameter, an explicit lifetime bound is required on object
+// lifetimes within.
+
+#![allow(dead_code)]
+
+trait Test {
+    fn foo(&self) { }
+}
+
+struct Ref0<T:?Sized> {
+    r: *mut T
+}
+
+struct Ref1<'a,T:'a+?Sized> {
+    r: &'a T
+}
+
+struct Ref2<'a,'b:'a,T:'a+'b+?Sized> {
+    r: &'a &'b T
+}
+
+fn a<'a,'b>(t: Ref2<'a,'b,Test>) {
+    //~^ ERROR lifetime bound for this object type cannot be deduced from context
+}
+
+fn b(t: Ref2<Test>) {
+    //~^ ERROR lifetime bound for this object type cannot be deduced from context
+}
+
+fn c(t: Ref2<&Test>) {
+    // In this case, the &'a overrides.
+}
+
+fn d(t: Ref2<Ref1<Test>>) {
+    // In this case, the lifetime parameter from the Ref1 overrides.
+}
+
+fn e(t: Ref2<Ref0<Test>>) {
+    //~^ ERROR lifetime bound for this object type cannot be deduced from context
+    //
+    // In this case, Ref0 just inherits.
+}
+
+fn f(t: &Ref2<Test>) {
+    //~^ ERROR lifetime bound for this object type cannot be deduced from context
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/object-lifetime-default-elision.rs b/src/test/compile-fail/object-lifetime-default-elision.rs
new file mode 100644
index 00000000000..0077d10e6ca
--- /dev/null
+++ b/src/test/compile-fail/object-lifetime-default-elision.rs
@@ -0,0 +1,89 @@
+// Copyright 2015 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 various cases where the old rules under lifetime elision
+// yield slightly different results than the new rules.
+
+#![allow(dead_code)]
+
+trait SomeTrait {
+    fn dummy(&self) { }
+}
+
+struct SomeStruct<'a> {
+    r: Box<SomeTrait+'a>
+}
+
+fn deref<T>(ss: &T) -> T {
+    // produces the type of a deref without worrying about whether a
+    // move out would actually be legal
+    loop { }
+}
+
+fn load0<'a>(ss: &'a Box<SomeTrait>) -> Box<SomeTrait> {
+    // Under old rules, the fully elaborated types of input/output were:
+    //
+    // for<'a,'b> fn(&'a Box<SomeTrait+'b>) -> Box<SomeTrait+'a>
+    //
+    // Under new rules the result is:
+    //
+    // for<'a> fn(&'a Box<SomeTrait+'a>) -> Box<SomeTrait+'static>
+    //
+    // Therefore, we get a type error attempting to return `deref(ss)`
+    // since `SomeTrait+'a <: SomeTrait+'static` does not hold.
+
+    deref(ss)
+        //~^ ERROR cannot infer
+}
+
+fn load1(ss: &SomeTrait) -> &SomeTrait {
+    // Under old rules, the fully elaborated types of input/output were:
+    //
+    // for<'a,'b> fn(&'a (SomeTrait+'b)) -> &'a (SomeTrait+'a)
+    //
+    // Under new rules the result is:
+    //
+    // for<'a> fn(&'a (SomeTrait+'a)) -> &'a (SomeTrait+'a)
+    //
+    // In both cases, returning `ss` is legal.
+
+    ss
+}
+
+fn load2<'a>(ss: &'a SomeTrait) -> &SomeTrait {
+    // Same as `load1` but with an explicit name thrown in for fun.
+
+    ss
+}
+
+fn load3<'a,'b>(ss: &'a SomeTrait) -> &'b SomeTrait {
+    // Under old rules, the fully elaborated types of input/output were:
+    //
+    // for<'a,'b,'c>fn(&'a (SomeTrait+'c)) -> &'b (SomeTrait+'a)
+    //
+    // Based on the input/output types, the compiler could infer that
+    //     'c : 'a
+    //     'b : 'a
+    // must hold, and therefore it permitted `&'a (Sometrait+'c)` to be
+    // coerced to `&'b (SomeTrait+'a)`.
+    //
+    // Under the newer defaults, though, we get:
+    //
+    // for<'a,'b> fn(&'a (SomeTrait+'a)) -> &'b (SomeTrait+'b)
+    //
+    // which fails to type check.
+
+    ss
+        //~^ ERROR cannot infer
+        //~| ERROR mismatched types
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/object-lifetime-default-from-box-error.rs b/src/test/compile-fail/object-lifetime-default-from-box-error.rs
new file mode 100644
index 00000000000..70752cbfda1
--- /dev/null
+++ b/src/test/compile-fail/object-lifetime-default-from-box-error.rs
@@ -0,0 +1,45 @@
+// Copyright 2015 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 various cases where the defaults should lead to errors being
+// reported.
+
+#![allow(dead_code)]
+
+trait SomeTrait {
+    fn dummy(&self) { }
+}
+
+struct SomeStruct<'a> {
+    r: Box<SomeTrait+'a>
+}
+
+fn load(ss: &mut SomeStruct) -> Box<SomeTrait> {
+    // `Box<SomeTrait>` defaults to a `'static` bound, so this return
+    // is illegal.
+
+    ss.r //~ ERROR mismatched types
+}
+
+fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) {
+    // No error: b is bounded by 'static which outlives the
+    // (anonymous) lifetime on the struct.
+
+    ss.r = b;
+}
+
+fn store1<'b>(ss: &mut SomeStruct, b: Box<SomeTrait+'b>) {
+    // Here we override the lifetimes explicitly, and so naturally we get an error.
+
+    ss.r = b; //~ ERROR mismatched types
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/object-lifetime-default-mybox.rs b/src/test/compile-fail/object-lifetime-default-mybox.rs
new file mode 100644
index 00000000000..c107c8d131d
--- /dev/null
+++ b/src/test/compile-fail/object-lifetime-default-mybox.rs
@@ -0,0 +1,44 @@
+// Copyright 2015 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 a "pass-through" object-lifetime-default that produces errors.
+
+#![allow(dead_code)]
+
+trait SomeTrait {
+    fn dummy(&self) { }
+}
+
+struct MyBox<T:?Sized> {
+    r: Box<T>
+}
+
+fn deref<T>(ss: &T) -> T {
+    // produces the type of a deref without worrying about whether a
+    // move out would actually be legal
+    loop { }
+}
+
+fn load0(ss: &MyBox<SomeTrait>) -> MyBox<SomeTrait> {
+    deref(ss) //~ ERROR cannot infer
+}
+
+fn load1<'a,'b>(a: &'a MyBox<SomeTrait>,
+                b: &'b MyBox<SomeTrait>)
+                -> &'b MyBox<SomeTrait>
+{
+    a
+      //~^ ERROR cannot infer
+      //~| ERROR mismatched types
+      //~| ERROR mismatched types
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs b/src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs
index 6b3c92e0028..b8cbbdbe9ec 100644
--- a/src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs
+++ b/src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs
@@ -25,7 +25,7 @@ struct Foo<'a,'b,'c> {
     c: Box<Is<'a>>,
     d: Box<IsSend>,
     e: Box<Is<'a>+Send>, // we can derive two bounds, but one is 'static, so ok
-    f: Box<SomeTrait>, //~ ERROR explicit lifetime bound required
+    f: Box<SomeTrait>,   // OK, defaults to 'static due to RFC 599.
     g: Box<SomeTrait+'a>,
 
     z: Box<Is<'a>+'b+'c>, //~ ERROR only a single explicit lifetime bound is permitted
diff --git a/src/test/compile-fail/region-object-lifetime-1.rs b/src/test/compile-fail/region-object-lifetime-1.rs
index 4758ce71fff..bb37d55fb08 100644
--- a/src/test/compile-fail/region-object-lifetime-1.rs
+++ b/src/test/compile-fail/region-object-lifetime-1.rs
@@ -11,6 +11,8 @@
 // Various tests related to testing how region inference works
 // with respect to the object receivers.
 
+#![allow(warnings)]
+
 trait Foo {
     fn borrowed<'a>(&'a self) -> &'a ();
 }
@@ -21,29 +23,6 @@ fn borrowed_receiver_same_lifetime<'a>(x: &'a Foo) -> &'a () {
     x.borrowed()
 }
 
-// Borrowed receiver but two distinct lifetimes, we get an error.
-fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a Foo) -> &'b () {
-    x.borrowed() //~ ERROR cannot infer
-}
-
-// Borrowed receiver with two distinct lifetimes, but we know that
-// 'b:'a, hence &'a () is permitted.
-fn borrowed_receiver_related_lifetimes<'a,'b>(x: &'a (Foo+'b)) -> &'a () {
-    x.borrowed()
-}
-
-// Here we have two distinct lifetimes, but we try to return a pointer
-// with the longer lifetime when (from the signature) we only know
-// that it lives as long as the shorter lifetime. Therefore, error.
-fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (Foo+'b)) -> &'b () {
-    x.borrowed() //~ ERROR cannot infer
-}
-
-// Here, the object is bounded by an anonymous lifetime and returned
-// as `&'static`, so you get an error.
-fn owned_receiver(x: Box<Foo>) -> &'static () {
-    x.borrowed() //~ ERROR cannot infer
-}
-
-fn main() {}
+#[rustc_error]
+fn main() {} //~ ERROR compilation successful
 
diff --git a/src/test/compile-fail/region-object-lifetime-2.rs b/src/test/compile-fail/region-object-lifetime-2.rs
new file mode 100644
index 00000000000..f9bf4e257b3
--- /dev/null
+++ b/src/test/compile-fail/region-object-lifetime-2.rs
@@ -0,0 +1,24 @@
+// Copyright 2012-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.
+
+// Various tests related to testing how region inference works
+// with respect to the object receivers.
+
+trait Foo {
+    fn borrowed<'a>(&'a self) -> &'a ();
+}
+
+// Borrowed receiver but two distinct lifetimes, we get an error.
+fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a Foo) -> &'b () {
+    x.borrowed() //~ ERROR cannot infer
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/region-object-lifetime-3.rs b/src/test/compile-fail/region-object-lifetime-3.rs
new file mode 100644
index 00000000000..7f00334f67e
--- /dev/null
+++ b/src/test/compile-fail/region-object-lifetime-3.rs
@@ -0,0 +1,28 @@
+// Copyright 2012-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.
+
+// Various tests related to testing how region inference works
+// with respect to the object receivers.
+
+#![allow(warnings)]
+
+trait Foo {
+    fn borrowed<'a>(&'a self) -> &'a ();
+}
+
+// Borrowed receiver with two distinct lifetimes, but we know that
+// 'b:'a, hence &'a () is permitted.
+fn borrowed_receiver_related_lifetimes<'a,'b>(x: &'a (Foo+'b)) -> &'a () {
+    x.borrowed()
+}
+
+#[rustc_error]
+fn main() {} //~ ERROR compilation successful
+
diff --git a/src/test/compile-fail/region-object-lifetime-4.rs b/src/test/compile-fail/region-object-lifetime-4.rs
new file mode 100644
index 00000000000..fe0ff8dc3fe
--- /dev/null
+++ b/src/test/compile-fail/region-object-lifetime-4.rs
@@ -0,0 +1,26 @@
+// Copyright 2012-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.
+
+// Various tests related to testing how region inference works
+// with respect to the object receivers.
+
+trait Foo {
+    fn borrowed<'a>(&'a self) -> &'a ();
+}
+
+// Here we have two distinct lifetimes, but we try to return a pointer
+// with the longer lifetime when (from the signature) we only know
+// that it lives as long as the shorter lifetime. Therefore, error.
+fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (Foo+'b)) -> &'b () {
+    x.borrowed() //~ ERROR cannot infer
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/region-object-lifetime-5.rs b/src/test/compile-fail/region-object-lifetime-5.rs
new file mode 100644
index 00000000000..f07f753d825
--- /dev/null
+++ b/src/test/compile-fail/region-object-lifetime-5.rs
@@ -0,0 +1,25 @@
+// Copyright 2012-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.
+
+// Various tests related to testing how region inference works
+// with respect to the object receivers.
+
+trait Foo {
+    fn borrowed<'a>(&'a self) -> &'a ();
+}
+
+// Here, the object is bounded by an anonymous lifetime and returned
+// as `&'static`, so you get an error.
+fn owned_receiver(x: Box<Foo>) -> &'static () {
+    x.borrowed() //~ ERROR `*x` does not live long enough
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/region-object-lifetime-in-coercion.rs b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
index e4521873a61..cf1e516901c 100644
--- a/src/test/compile-fail/region-object-lifetime-in-coercion.rs
+++ b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
@@ -26,7 +26,9 @@ fn b(v: &[u8]) -> Box<Foo + 'static> {
 }
 
 fn c(v: &[u8]) -> Box<Foo> {
-    box v // OK thanks to lifetime elision
+    // same as previous case due to RFC 599
+
+    box v //~ ERROR declared lifetime bound not satisfied
 }
 
 fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
diff --git a/src/test/compile-fail/regions-close-object-into-object.rs b/src/test/compile-fail/regions-close-object-into-object-1.rs
index 675f86b58f4..7a0e3cf4611 100644
--- a/src/test/compile-fail/regions-close-object-into-object.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-1.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![feature(box_syntax)]
+#![allow(warnings)]
 
 trait A<T> {}
 struct B<'a, T>(&'a (A<T>+'a));
@@ -17,19 +18,7 @@ trait X {}
 impl<'a, T> X for B<'a, T> {}
 
 fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
-    box B(&*v) as Box<X>
-}
-
-fn g<'a, T: 'static>(v: Box<A<T>>) -> Box<X+'static> {
-    box B(&*v) as Box<X> //~ ERROR cannot infer
-}
-
-fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
-    box B(&*v) as Box<X>
-}
-
-fn i<'a, T, U>(v: Box<A<U>>) -> Box<X+'static> {
-    box B(&*v) as Box<X> //~ ERROR cannot infer
+    box B(&*v) as Box<X> //~ ERROR `*v` does not live long enough
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/regions-close-object-into-object-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs
new file mode 100644
index 00000000000..7861fb95fef
--- /dev/null
+++ b/src/test/compile-fail/regions-close-object-into-object-2.rs
@@ -0,0 +1,23 @@
+// 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.
+
+#![feature(box_syntax)]
+
+trait A<T> {}
+struct B<'a, T>(&'a (A<T>+'a));
+
+trait X {}
+impl<'a, T> X for B<'a, T> {}
+
+fn g<'a, T: 'static>(v: Box<A<T>+'a>) -> Box<X+'static> {
+    box B(&*v) as Box<X> //~ ERROR cannot infer
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/regions-close-object-into-object-3.rs b/src/test/compile-fail/regions-close-object-into-object-3.rs
new file mode 100644
index 00000000000..31354de2a27
--- /dev/null
+++ b/src/test/compile-fail/regions-close-object-into-object-3.rs
@@ -0,0 +1,25 @@
+// 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.
+
+#![feature(box_syntax)]
+#![allow(warnings)]
+
+trait A<T> {}
+struct B<'a, T>(&'a (A<T>+'a));
+
+trait X {}
+impl<'a, T> X for B<'a, T> {}
+
+fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
+    box B(&*v) as Box<X> //~ ERROR `*v` does not live long enough
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/regions-close-object-into-object-4.rs b/src/test/compile-fail/regions-close-object-into-object-4.rs
new file mode 100644
index 00000000000..c60975f97e1
--- /dev/null
+++ b/src/test/compile-fail/regions-close-object-into-object-4.rs
@@ -0,0 +1,24 @@
+// 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.
+
+#![feature(box_syntax)]
+
+trait A<T> {}
+struct B<'a, T>(&'a (A<T>+'a));
+
+trait X {}
+impl<'a, T> X for B<'a, T> {}
+
+fn i<'a, T, U>(v: Box<A<U>+'a>) -> Box<X+'static> {
+    box B(&*v) as Box<X> //~ ERROR cannot infer
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/seq-args.rs b/src/test/compile-fail/seq-args.rs
index b4929eacf3d..44b049d6561 100644
--- a/src/test/compile-fail/seq-args.rs
+++ b/src/test/compile-fail/seq-args.rs
@@ -14,7 +14,7 @@ trait seq { }
 impl<T> seq<T> for Vec<T> { //~ ERROR wrong number of type arguments
     /* ... */
 }
-impl seq<bool> for u32 {
+impl seq<bool> for u32 { //~ ERROR wrong number of type arguments
    /* Treat the integer as a sequence of bits */
 }
 
diff --git a/src/test/compile-fail/structure-constructor-type-mismatch.rs b/src/test/compile-fail/structure-constructor-type-mismatch.rs
index a82c05c72c3..c276228b18e 100644
--- a/src/test/compile-fail/structure-constructor-type-mismatch.rs
+++ b/src/test/compile-fail/structure-constructor-type-mismatch.rs
@@ -57,6 +57,7 @@ fn main() {
 
     let pt3 = PointF::<i32> {
         //~^ ERROR wrong number of type arguments
+        //~| ERROR structure constructor specifies a structure of type
         x: 9i32,
         y: 10i32,
     };
diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs
index 79174552ae0..89e89cf8246 100644
--- a/src/test/compile-fail/trait-bounds-cant-coerce.rs
+++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs
@@ -22,7 +22,7 @@ fn c(x: Box<Foo+Sync+Send>) {
 fn d(x: Box<Foo>) {
     a(x); //~  ERROR mismatched types
           //~| expected `Box<Foo + Send>`
-          //~| found `Box<Foo>`
+          //~| found `Box<Foo + 'static>`
           //~| expected bounds `Send`
           //~| found no bounds
 }
diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs
index 4da496621d1..3d264e681a3 100644
--- a/src/test/compile-fail/trait-bounds-sugar.rs
+++ b/src/test/compile-fail/trait-bounds-sugar.rs
@@ -24,8 +24,7 @@ fn c(x: Box<Foo+Sync>) {
 }
 
 fn d(x: &'static (Foo+Sync)) {
-    b(x); //~ ERROR cannot infer
-    //~^ ERROR mismatched types
+    b(x);
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
index dcfcb7d4772..9f0682df3fe 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
@@ -12,7 +12,9 @@
 
 trait Three<A,B,C> { fn dummy(&self) -> (A,B,C); }
 
-fn foo(_: &Three()) //~ ERROR wrong number of type arguments
+fn foo(_: &Three())
+//~^ ERROR wrong number of type arguments
+//~| ERROR no associated type `Output`
 {}
 
 fn main() { }
diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
index a8ac62444aa..40635cf3ddd 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
@@ -12,7 +12,9 @@
 
 trait Zero { fn dummy(&self); }
 
-fn foo(_: Zero()) //~ ERROR wrong number of type arguments
+fn foo(_: Zero())
+    //~^ ERROR wrong number of type arguments
+    //~| ERROR no associated type `Output` defined in `Zero`
 {}
 
 fn main() { }
diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
index e63f510b890..5810ffcf21a 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
@@ -14,6 +14,7 @@ trait Trait {}
 
 fn f<F:Trait(isize) -> isize>(x: F) {}
 //~^ ERROR wrong number of type arguments: expected 0, found 1
+//~| ERROR no associated type `Output`
 
 fn main() {}
 
diff --git a/src/test/run-pass/object-lifetime-default-from-ref-struct.rs b/src/test/run-pass/object-lifetime-default-from-ref-struct.rs
new file mode 100644
index 00000000000..24da9603679
--- /dev/null
+++ b/src/test/run-pass/object-lifetime-default-from-ref-struct.rs
@@ -0,0 +1,47 @@
+// Copyright 2015 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 the lifetime of the enclosing `&` is used for the object
+// lifetime bound.
+
+#![allow(dead_code)]
+
+trait Test {
+    fn foo(&self) { }
+}
+
+struct Ref<'a,T:'a+?Sized> {
+    r: &'a T
+}
+
+struct SomeStruct<'a> {
+    t: Ref<'a,Test>,
+    u: Ref<'a,Test+'a>,
+}
+
+fn a<'a>(t: Ref<'a,Test>, mut ss: SomeStruct<'a>) {
+    ss.t = t;
+}
+
+fn b<'a>(t: Ref<'a,Test>, mut ss: SomeStruct<'a>) {
+    ss.u = t;
+}
+
+fn c<'a>(t: Ref<'a,Test+'a>, mut ss: SomeStruct<'a>) {
+    ss.t = t;
+}
+
+fn d<'a>(t: Ref<'a,Test+'a>, mut ss: SomeStruct<'a>) {
+    ss.u = t;
+}
+
+
+fn main() {
+}