parent
ab579883f2
commit
369adaf515
@ -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::<Vec<Ty<'tcx>>>();
|
||||
let inputs =
|
||||
data.inputs.iter()
|
||||
.map(|a_t| ast_ty_arg_to_ty(this, &binding_rscope, decl_generics,
|
||||
0, ®ion_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()));
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
60
src/test/compile-fail/object-lifetime-default-ambiguous.rs
Normal file
60
src/test/compile-fail/object-lifetime-default-ambiguous.rs
Normal file
@ -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() {
|
||||
}
|
89
src/test/compile-fail/object-lifetime-default-elision.rs
Normal file
89
src/test/compile-fail/object-lifetime-default-elision.rs
Normal file
@ -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() {
|
||||
}
|
@ -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() {
|
||||
}
|
44
src/test/compile-fail/object-lifetime-default-mybox.rs
Normal file
44
src/test/compile-fail/object-lifetime-default-mybox.rs
Normal file
@ -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() {
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
24
src/test/compile-fail/region-object-lifetime-2.rs
Normal file
24
src/test/compile-fail/region-object-lifetime-2.rs
Normal file
@ -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() {}
|
||||
|
28
src/test/compile-fail/region-object-lifetime-3.rs
Normal file
28
src/test/compile-fail/region-object-lifetime-3.rs
Normal file
@ -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
|
||||
|
26
src/test/compile-fail/region-object-lifetime-4.rs
Normal file
26
src/test/compile-fail/region-object-lifetime-4.rs
Normal file
@ -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() {}
|
||||
|
25
src/test/compile-fail/region-object-lifetime-5.rs
Normal file
25
src/test/compile-fail/region-object-lifetime-5.rs
Normal file
@ -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() {}
|
||||
|
@ -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> {
|
||||
|
@ -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() {}
|
23
src/test/compile-fail/regions-close-object-into-object-2.rs
Normal file
23
src/test/compile-fail/regions-close-object-into-object-2.rs
Normal file
@ -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() { }
|
25
src/test/compile-fail/regions-close-object-into-object-3.rs
Normal file
25
src/test/compile-fail/regions-close-object-into-object-3.rs
Normal file
@ -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() {}
|
||||
|
24
src/test/compile-fail/regions-close-object-into-object-4.rs
Normal file
24
src/test/compile-fail/regions-close-object-into-object-4.rs
Normal file
@ -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() {}
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
@ -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() { }
|
||||
|
@ -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() { }
|
||||
|
@ -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() {}
|
||||
|
||||
|
47
src/test/run-pass/object-lifetime-default-from-ref-struct.rs
Normal file
47
src/test/run-pass/object-lifetime-default-from-ref-struct.rs
Normal file
@ -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() {
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user