From 369adaf5150877c124de99a1b9a94f7b522aade6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 09:37:52 -0500 Subject: [PATCH] Implement the rules for RFC 599, and add various tests. Fixes #22211. --- src/librustc_typeck/astconv.rs | 71 +++++++++++---- src/test/compile-fail/issue-11374.rs | 4 +- src/test/compile-fail/issue-5216.rs | 8 +- .../object-lifetime-default-ambiguous.rs | 60 +++++++++++++ .../object-lifetime-default-elision.rs | 89 +++++++++++++++++++ .../object-lifetime-default-from-box-error.rs | 45 ++++++++++ .../object-lifetime-default-mybox.rs | 44 +++++++++ ...n-bounds-on-objects-and-type-parameters.rs | 2 +- .../compile-fail/region-object-lifetime-1.rs | 29 +----- .../compile-fail/region-object-lifetime-2.rs | 24 +++++ .../compile-fail/region-object-lifetime-3.rs | 28 ++++++ .../compile-fail/region-object-lifetime-4.rs | 26 ++++++ .../compile-fail/region-object-lifetime-5.rs | 25 ++++++ .../region-object-lifetime-in-coercion.rs | 4 +- ... => regions-close-object-into-object-1.rs} | 15 +--- .../regions-close-object-into-object-2.rs | 23 +++++ .../regions-close-object-into-object-3.rs | 25 ++++++ .../regions-close-object-into-object-4.rs | 24 +++++ src/test/compile-fail/seq-args.rs | 2 +- .../structure-constructor-type-mismatch.rs | 1 + .../compile-fail/trait-bounds-cant-coerce.rs | 2 +- src/test/compile-fail/trait-bounds-sugar.rs | 3 +- ...r-wrong-number-number-type-parameters-3.rs | 4 +- ...gar-wrong-number-number-type-parameters.rs | 4 +- .../unboxed-closure-sugar-wrong-trait.rs | 1 + ...object-lifetime-default-from-ref-struct.rs | 47 ++++++++++ 26 files changed, 542 insertions(+), 68 deletions(-) create mode 100644 src/test/compile-fail/object-lifetime-default-ambiguous.rs create mode 100644 src/test/compile-fail/object-lifetime-default-elision.rs create mode 100644 src/test/compile-fail/object-lifetime-default-from-box-error.rs create mode 100644 src/test/compile-fail/object-lifetime-default-mybox.rs create mode 100644 src/test/compile-fail/region-object-lifetime-2.rs create mode 100644 src/test/compile-fail/region-object-lifetime-3.rs create mode 100644 src/test/compile-fail/region-object-lifetime-4.rs create mode 100644 src/test/compile-fail/region-object-lifetime-5.rs rename src/test/compile-fail/{regions-close-object-into-object.rs => regions-close-object-into-object-1.rs} (67%) create mode 100644 src/test/compile-fail/regions-close-object-into-object-2.rs create mode 100644 src/test/compile-fail/regions-close-object-into-object-3.rs create mode 100644 src/test/compile-fail/regions-close-object-into-object-4.rs create mode 100644 src/test/run-pass/object-lifetime-default-from-ref-struct.rs 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, ®ion_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::>>(); + let inputs = + data.inputs.iter() + .map(|a_t| ast_ty_arg_to_ty(this, &binding_rscope, decl_generics, + 0, ®ion_substs, a_t)) + .collect::>>(); 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); //~ ERROR explicit lifetime bound required -pub static C: S = S(f); +struct S(Box); +pub static C: S = S(f); //~ ERROR mismatched types fn g() { } -type T = Box; //~ ERROR explicit lifetime bound required -pub static D: T = g; +type T = Box; +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 or the MIT license +// , 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 { + 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) { + //~^ 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>) { + // In this case, the lifetime parameter from the Ref1 overrides. +} + +fn e(t: Ref2>) { + //~^ ERROR lifetime bound for this object type cannot be deduced from context + // + // In this case, Ref0 just inherits. +} + +fn f(t: &Ref2) { + //~^ 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 or the MIT license +// , 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 +} + +fn deref(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) -> Box { + // Under old rules, the fully elaborated types of input/output were: + // + // for<'a,'b> fn(&'a Box) -> Box + // + // Under new rules the result is: + // + // for<'a> fn(&'a Box) -> Box + // + // 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 or the MIT license +// , 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 +} + +fn load(ss: &mut SomeStruct) -> Box { + // `Box` defaults to a `'static` bound, so this return + // is illegal. + + ss.r //~ ERROR mismatched types +} + +fn store(ss: &mut SomeStruct, b: Box) { + // 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) { + // 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 or the MIT license +// , 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 { + r: Box +} + +fn deref(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) -> MyBox { + deref(ss) //~ ERROR cannot infer +} + +fn load1<'a,'b>(a: &'a MyBox, + b: &'b MyBox) + -> &'b MyBox +{ + 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>, d: Box, e: Box+Send>, // we can derive two bounds, but one is 'static, so ok - f: Box, //~ ERROR explicit lifetime bound required + f: Box, // OK, defaults to 'static due to RFC 599. g: Box, z: Box+'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) -> &'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 or the MIT license +// , 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 or the MIT license +// , 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 or the MIT license +// , 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 or the MIT license +// , 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) -> &'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 { } fn c(v: &[u8]) -> Box { - 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 { 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 similarity index 67% rename from src/test/compile-fail/regions-close-object-into-object.rs rename to 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 {} struct B<'a, T>(&'a (A+'a)); @@ -17,19 +18,7 @@ trait X {} impl<'a, T> X for B<'a, T> {} fn f<'a, T, U>(v: Box+'static>) -> Box { - box B(&*v) as Box -} - -fn g<'a, T: 'static>(v: Box>) -> Box { - box B(&*v) as Box //~ ERROR cannot infer -} - -fn h<'a, T, U>(v: Box+'static>) -> Box { - box B(&*v) as Box -} - -fn i<'a, T, U>(v: Box>) -> Box { - box B(&*v) as Box //~ ERROR cannot infer + box B(&*v) as Box //~ 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(box_syntax)] + +trait A {} +struct B<'a, T>(&'a (A+'a)); + +trait X {} +impl<'a, T> X for B<'a, T> {} + +fn g<'a, T: 'static>(v: Box+'a>) -> Box { + box B(&*v) as Box //~ 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(box_syntax)] +#![allow(warnings)] + +trait A {} +struct B<'a, T>(&'a (A+'a)); + +trait X {} +impl<'a, T> X for B<'a, T> {} + +fn h<'a, T, U>(v: Box+'static>) -> Box { + box B(&*v) as Box //~ 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(box_syntax)] + +trait A {} +struct B<'a, T>(&'a (A+'a)); + +trait X {} +impl<'a, T> X for B<'a, T> {} + +fn i<'a, T, U>(v: Box+'a>) -> Box { + box B(&*v) as Box //~ 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 seq for Vec { //~ ERROR wrong number of type arguments /* ... */ } -impl seq for u32 { +impl seq 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:: { //~^ 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) { fn d(x: Box) { a(x); //~ ERROR mismatched types //~| expected `Box` - //~| found `Box` + //~| found `Box` //~| 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) { } 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 { 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 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 or the MIT license +// , 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() { +}