parent
ab579883f2
commit
369adaf515
26 changed files with 542 additions and 68 deletions
|
@ -438,23 +438,25 @@ fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>,
|
||||||
{
|
{
|
||||||
let regions: Vec<_> =
|
let regions: Vec<_> =
|
||||||
data.lifetimes.iter()
|
data.lifetimes.iter()
|
||||||
.map(|l| ast_region_to_region(this.tcx(), l))
|
.map(|l| ast_region_to_region(this.tcx(), l))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let region_substs =
|
let region_substs =
|
||||||
create_region_substs(this, rscope, span, decl_generics, regions);
|
create_region_substs(this, rscope, span, decl_generics, regions);
|
||||||
|
|
||||||
let types: Vec<_> =
|
let types: Vec<_> =
|
||||||
data.types.iter()
|
data.types.iter()
|
||||||
.map(|t| ast_ty_to_ty(this, rscope, &**t))
|
.enumerate()
|
||||||
.collect();
|
.map(|(i,t)| ast_ty_arg_to_ty(this, rscope, decl_generics,
|
||||||
|
i, ®ion_substs, t))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let assoc_bindings: Vec<_> =
|
let assoc_bindings: Vec<_> =
|
||||||
data.bindings.iter()
|
data.bindings.iter()
|
||||||
.map(|b| ConvertedBinding { item_name: b.ident.name,
|
.map(|b| ConvertedBinding { item_name: b.ident.name,
|
||||||
ty: ast_ty_to_ty(this, rscope, &*b.ty),
|
ty: ast_ty_to_ty(this, rscope, &*b.ty),
|
||||||
span: b.span })
|
span: b.span })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
(region_substs, types, assoc_bindings)
|
(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());
|
create_region_substs(this, rscope, span, decl_generics, Vec::new());
|
||||||
|
|
||||||
let binding_rscope = BindingRscope::new();
|
let binding_rscope = BindingRscope::new();
|
||||||
let inputs = data.inputs.iter()
|
let inputs =
|
||||||
.map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
|
data.inputs.iter()
|
||||||
.collect::<Vec<Ty<'tcx>>>();
|
.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 input_params: Vec<_> = repeat(String::new()).take(inputs.len()).collect();
|
||||||
let (implied_output_region,
|
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 {
|
let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
|
||||||
ast::AngleBracketedParameters(ref data) => {
|
ast::AngleBracketedParameters(ref data) => {
|
||||||
// For now, require that parenthetical5D notation be used
|
// For now, require that parenthetical notation be used
|
||||||
// only with `Fn()` etc.
|
// only with `Fn()` etc.
|
||||||
if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
|
if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
|
||||||
span_err!(this.tcx().sess, path.span, E0215,
|
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);
|
qpath.item_path.identifier.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the programmer's textual representation of a type into our
|
/// Convert a type supplied as value for a type argument from AST into our
|
||||||
// internal notion of a type.
|
/// our internal representation. This is the same as `ast_ty_to_ty` but that
|
||||||
pub fn ast_ty_to_ty<'tcx>(
|
/// it applies the object lifetime default.
|
||||||
this: &AstConv<'tcx>, rscope: &RegionScope, ast_ty: &ast::Ty) -> Ty<'tcx>
|
///
|
||||||
|
/// # 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={})",
|
debug!("ast_ty_to_ty(ast_ty={})",
|
||||||
ast_ty.repr(this.tcx()));
|
ast_ty.repr(this.tcx()));
|
||||||
|
|
|
@ -12,7 +12,7 @@ use std::old_io;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
pub struct Container<'a> {
|
pub struct Container<'a> {
|
||||||
reader: &'a mut Reader //~ ERROR explicit lifetime bound required
|
reader: &'a mut Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Container<'a> {
|
impl<'a> Container<'a> {
|
||||||
|
@ -33,5 +33,5 @@ pub fn for_stdin<'a>() -> Container<'a> {
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut c = for_stdin();
|
let mut c = for_stdin();
|
||||||
let mut v = Vec::new();
|
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.
|
// except according to those terms.
|
||||||
|
|
||||||
fn f() { }
|
fn f() { }
|
||||||
struct S(Box<FnMut()>); //~ ERROR explicit lifetime bound required
|
struct S(Box<FnMut()>);
|
||||||
pub static C: S = S(f);
|
pub static C: S = S(f); //~ ERROR mismatched types
|
||||||
|
|
||||||
|
|
||||||
fn g() { }
|
fn g() { }
|
||||||
type T = Box<FnMut()>; //~ ERROR explicit lifetime bound required
|
type T = Box<FnMut()>;
|
||||||
pub static D: T = g;
|
pub static D: T = g; //~ ERROR mismatched types
|
||||||
|
|
||||||
fn main() {}
|
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>>,
|
c: Box<Is<'a>>,
|
||||||
d: Box<IsSend>,
|
d: Box<IsSend>,
|
||||||
e: Box<Is<'a>+Send>, // we can derive two bounds, but one is 'static, so ok
|
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>,
|
g: Box<SomeTrait+'a>,
|
||||||
|
|
||||||
z: Box<Is<'a>+'b+'c>, //~ ERROR only a single explicit lifetime bound is permitted
|
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
|
// Various tests related to testing how region inference works
|
||||||
// with respect to the object receivers.
|
// with respect to the object receivers.
|
||||||
|
|
||||||
|
#![allow(warnings)]
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
||||||
fn borrowed<'a>(&'a self) -> &'a ();
|
fn borrowed<'a>(&'a self) -> &'a ();
|
||||||
}
|
}
|
||||||
|
@ -21,29 +23,6 @@ fn borrowed_receiver_same_lifetime<'a>(x: &'a Foo) -> &'a () {
|
||||||
x.borrowed()
|
x.borrowed()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Borrowed receiver but two distinct lifetimes, we get an error.
|
#[rustc_error]
|
||||||
fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a Foo) -> &'b () {
|
fn main() {} //~ ERROR compilation successful
|
||||||
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() {}
|
|
||||||
|
|
||||||
|
|
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> {
|
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> {
|
fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
#![allow(warnings)]
|
||||||
|
|
||||||
trait A<T> {}
|
trait A<T> {}
|
||||||
struct B<'a, T>(&'a (A<T>+'a));
|
struct B<'a, T>(&'a (A<T>+'a));
|
||||||
|
@ -17,19 +18,7 @@ trait X {}
|
||||||
impl<'a, T> X for B<'a, T> {}
|
impl<'a, T> X for B<'a, T> {}
|
||||||
|
|
||||||
fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
|
fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
|
||||||
box B(&*v) as Box<X>
|
box B(&*v) as Box<X> //~ ERROR `*v` does not live long enough
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
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<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 */
|
/* Treat the integer as a sequence of bits */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ fn main() {
|
||||||
|
|
||||||
let pt3 = PointF::<i32> {
|
let pt3 = PointF::<i32> {
|
||||||
//~^ ERROR wrong number of type arguments
|
//~^ ERROR wrong number of type arguments
|
||||||
|
//~| ERROR structure constructor specifies a structure of type
|
||||||
x: 9i32,
|
x: 9i32,
|
||||||
y: 10i32,
|
y: 10i32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn c(x: Box<Foo+Sync+Send>) {
|
||||||
fn d(x: Box<Foo>) {
|
fn d(x: Box<Foo>) {
|
||||||
a(x); //~ ERROR mismatched types
|
a(x); //~ ERROR mismatched types
|
||||||
//~| expected `Box<Foo + Send>`
|
//~| expected `Box<Foo + Send>`
|
||||||
//~| found `Box<Foo>`
|
//~| found `Box<Foo + 'static>`
|
||||||
//~| expected bounds `Send`
|
//~| expected bounds `Send`
|
||||||
//~| found no bounds
|
//~| found no bounds
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,7 @@ fn c(x: Box<Foo+Sync>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn d(x: &'static (Foo+Sync)) {
|
fn d(x: &'static (Foo+Sync)) {
|
||||||
b(x); //~ ERROR cannot infer
|
b(x);
|
||||||
//~^ ERROR mismatched types
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
trait Three<A,B,C> { fn dummy(&self) -> (A,B,C); }
|
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() { }
|
fn main() { }
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
trait Zero { fn dummy(&self); }
|
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() { }
|
fn main() { }
|
||||||
|
|
|
@ -14,6 +14,7 @@ trait Trait {}
|
||||||
|
|
||||||
fn f<F:Trait(isize) -> isize>(x: F) {}
|
fn f<F:Trait(isize) -> isize>(x: F) {}
|
||||||
//~^ ERROR wrong number of type arguments: expected 0, found 1
|
//~^ ERROR wrong number of type arguments: expected 0, found 1
|
||||||
|
//~| ERROR no associated type `Output`
|
||||||
|
|
||||||
fn main() {}
|
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…
Add table
Add a link
Reference in a new issue