Implement in-band lifetime bindings

This commit is contained in:
Taylor Cramer 2017-11-16 22:59:45 -08:00 committed by Niko Matsakis
parent 1dc0b573e7
commit 91b7920c09
33 changed files with 1026 additions and 136 deletions

View file

@ -0,0 +1,26 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
fn foo(x: fn(&'a u32)) {}
fn bar(x: &Fn(&'a u32)) {}
fn baz(x: fn(&'a u32), y: &'a u32) {}
struct Foo<'a> { x: &'a u32 }
impl Foo<'a> {
fn bar(&self, x: fn(&'a u32)) {}
}
fn main() {}

View file

@ -0,0 +1,26 @@
error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders
--> $DIR/E0687.rs:14:15
|
14 | fn foo(x: fn(&'a u32)) {}
| ^^ in-band lifetime definition
error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders
--> $DIR/E0687.rs:16:16
|
16 | fn bar(x: &Fn(&'a u32)) {}
| ^^ in-band lifetime definition
error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders
--> $DIR/E0687.rs:18:15
|
18 | fn baz(x: fn(&'a u32), y: &'a u32) {}
| ^^ in-band lifetime definition
error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders
--> $DIR/E0687.rs:23:26
|
23 | fn bar(&self, x: fn(&'a u32)) {}
| ^^ in-band lifetime definition
error: aborting due to 4 previous errors

View file

@ -0,0 +1,18 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes, universal_impl_trait)]
fn bar<F>(x: &F) where F: Fn(&'a u32) {}
fn baz(x: &impl Fn(&'a u32)) {}
fn main() {}

View file

@ -0,0 +1,14 @@
error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders
--> $DIR/E0687_where.rs:14:31
|
14 | fn bar<F>(x: &F) where F: Fn(&'a u32) {}
| ^^ in-band lifetime definition
error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders
--> $DIR/E0687_where.rs:16:21
|
16 | fn baz(x: &impl Fn(&'a u32)) {}
| ^^ in-band lifetime definition
error: aborting due to 2 previous errors

View file

@ -0,0 +1,26 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
fn foo<'a>(x: &'a u32, y: &'b u32) {}
struct Foo<'a> { x: &'a u32 }
impl Foo<'a> {
fn bar<'b>(x: &'a u32, y: &'b u32, z: &'c u32) {}
}
impl<'b> Foo<'a> {
fn baz() {}
}
fn main() {}

View file

@ -0,0 +1,26 @@
error[E0688]: cannot mix in-band and explicit lifetime definitions
--> $DIR/E0688.rs:14:28
|
14 | fn foo<'a>(x: &'a u32, y: &'b u32) {}
| -- ^^ in-band lifetime definition here
| |
| explicit lifetime definition here
error[E0688]: cannot mix in-band and explicit lifetime definitions
--> $DIR/E0688.rs:19:44
|
19 | fn bar<'b>(x: &'a u32, y: &'b u32, z: &'c u32) {}
| -- ^^ in-band lifetime definition here
| |
| explicit lifetime definition here
error[E0688]: cannot mix in-band and explicit lifetime definitions
--> $DIR/E0688.rs:22:14
|
22 | impl<'b> Foo<'a> {
| -- ^^ in-band lifetime definition here
| |
| explicit lifetime definition here
error: aborting due to 3 previous errors

View file

@ -0,0 +1,18 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
fn foo(x: &'a u32, y: &u32) -> &'a u32 { y }
fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y }
fn main() {}

View file

@ -0,0 +1,18 @@
error[E0621]: explicit lifetime required in the type of `y`
--> $DIR/mismatched.rs:14:42
|
14 | fn foo(x: &'a u32, y: &u32) -> &'a u32 { y }
| - ^ lifetime `'a` required
| |
| consider changing the type of `y` to `&'a u32`
error[E0623]: lifetime mismatch
--> $DIR/mismatched.rs:16:46
|
16 | fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y }
| ------- ------- ^ ...but data from `y` is returned here
| |
| this parameter and the return type are declared with different lifetimes...
error: aborting due to 2 previous errors

View file

@ -0,0 +1,20 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
trait Get {
fn baz(&self, x: &'a u32, y: &u32) -> &'a u32 {
y
}
}
fn main() {}

View file

@ -0,0 +1,10 @@
error[E0621]: explicit lifetime required in the type of `y`
--> $DIR/mismatched_trait.rs:16:9
|
15 | fn baz(&self, x: &'a u32, y: &u32) -> &'a u32 {
| - consider changing the type of `y` to `&'a u32`
16 | y
| ^ lifetime `'a` required
error: aborting due to previous error

View file

@ -0,0 +1,24 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
trait Get {
fn foo(&self, x: &'a u32, y: &u32) -> &'a u32;
}
impl Get for i32 {
fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
x
}
}
fn main() {}

View file

@ -0,0 +1,39 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements
--> $DIR/mismatched_trait_impl.rs:19:5
|
19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
20 | | x
21 | | }
| |_____^
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 19:5...
--> $DIR/mismatched_trait_impl.rs:19:5
|
19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
20 | | x
21 | | }
| |_____^
note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32)
--> $DIR/mismatched_trait_impl.rs:19:5
|
19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
20 | | x
21 | | }
| |_____^
note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 19:5...
--> $DIR/mismatched_trait_impl.rs:19:5
|
19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
20 | | x
21 | | }
| |_____^
note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32)
--> $DIR/mismatched_trait_impl.rs:19:5
|
19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
20 | | x
21 | | }
| |_____^
error: aborting due to previous error

View file

@ -0,0 +1,21 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
fn foo(x: &'a u32) -> &'a u32 { x }
fn main() {
let mut p = 3;
let r = foo(&p);
p += 1;
println!("{}", r);
}

View file

@ -0,0 +1,10 @@
error[E0506]: cannot assign to `p` because it is borrowed
--> $DIR/mut_while_borrow.rs:19:5
|
18 | let r = foo(&p);
| - borrow of `p` occurs here
19 | p += 1;
| ^^^^^^ assignment to borrowed `p` occurs here
error: aborting due to previous error

View file

@ -0,0 +1,22 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
struct Foo {
x: &'test u32,
}
enum Bar {
Baz(&'test u32),
}
fn main() {}

View file

@ -0,0 +1,14 @@
error[E0261]: use of undeclared lifetime name `'test`
--> $DIR/no_in_band_in_struct.rs:15:9
|
15 | x: &'test u32,
| ^^^^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'test`
--> $DIR/no_in_band_in_struct.rs:19:10
|
19 | Baz(&'test u32),
| ^^^^^ undeclared lifetime
error: aborting due to 2 previous errors

View file

@ -0,0 +1,23 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
fn foo(x: &u32) {
let y: &'test u32 = x;
}
fn foo2(x: &u32) {}
fn bar() {
let y: fn(&'test u32) = foo2;
}
fn main() {}

View file

@ -0,0 +1,14 @@
error[E0261]: use of undeclared lifetime name `'test`
--> $DIR/no_introducing_in_band_in_locals.rs:15:13
|
15 | let y: &'test u32 = x;
| ^^^^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'test`
--> $DIR/no_introducing_in_band_in_locals.rs:20:16
|
20 | let y: fn(&'test u32) = foo2;
| ^^^^^ undeclared lifetime
error: aborting due to 2 previous errors

View file

@ -0,0 +1,21 @@
// Copyright 2017 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.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
struct Foo<T>(T);
impl Foo<&'s u8> {
fn bar<'s>(&self, x: &'s u8) {}
fn baz(x: for<'s> fn(&'s u32)) {}
}
fn main() {}

View file

@ -0,0 +1,19 @@
error[E0496]: lifetime name `'s` shadows a lifetime name that is already in scope
--> $DIR/shadow.rs:17:12
|
16 | impl Foo<&'s u8> {
| -- first declared here
17 | fn bar<'s>(&self, x: &'s u8) {}
| ^^ lifetime 's already in scope
error[E0496]: lifetime name `'s` shadows a lifetime name that is already in scope
--> $DIR/shadow.rs:18:19
|
16 | impl Foo<&'s u8> {
| -- first declared here
17 | fn bar<'s>(&self, x: &'s u8) {}
18 | fn baz(x: for<'s> fn(&'s u32)) {}
| ^^ lifetime 's already in scope
error: aborting due to 2 previous errors