Address ICE related to impl trait

Original bug: https://github.com/rust-lang/rust/issues/43380

Fixes #33
This commit is contained in:
Yong Wen Chua 2018-02-14 13:37:48 +08:00
parent ff1deabf55
commit 39eb59e466
3 changed files with 26 additions and 11 deletions

View File

@ -11,16 +11,20 @@ use rocket::response::Responder;
use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors};
/// Using a borrowed Cors
/// Note that the `'r` lifetime annotation is not requred here because `State` borrows with lifetime
/// `'r` and so does `Responder`!
#[get("/")]
fn borrowed<'r>(options: State<'r, Cors>) -> impl Responder<'r> {
fn borrowed(options: State<Cors>) -> impl Responder {
options
.inner()
.respond_borrowed(|guard| guard.responder("Hello CORS"))
}
/// Using a `Response` instead of a `Responder`. You generally won't have to do this.
/// Note that the `'r` lifetime annotation is not requred here because `State` borrows with lifetime
/// `'r` and so does `Responder`!
#[get("/response")]
fn response<'r>(options: State<'r, Cors>) -> impl Responder<'r> {
fn response(options: State<Cors>) -> impl Responder {
let mut response = Response::new();
response.set_sized_body(Cursor::new("Hello CORS!"));
@ -30,6 +34,7 @@ fn response<'r>(options: State<'r, Cors>) -> impl Responder<'r> {
}
/// Create and use an ad-hoc Cors
/// Note that the `'r` lifetime is needed because the compiler cannot elide anything.
#[get("/owned")]
fn owned<'r>() -> impl Responder<'r> {
let options = cors_options();
@ -39,6 +44,7 @@ fn owned<'r>() -> impl Responder<'r> {
/// You need to define an OPTIONS route for preflight checks if you want to use `Cors` struct
/// that is not in Rocket's managed state.
/// These routes can just return the unit type `()`
/// Note that the `'r` lifetime is needed because the compiler cannot elide anything.
#[options("/owned")]
fn owned_options<'r>() -> impl Responder<'r> {
let options = cors_options();

View File

@ -250,7 +250,7 @@
//! In this case, you might as well use the `Guard` method above and place the `Cors` struct in
//! Rocket's [state](https://rocket.rs/guide/state/).
//! Alternatively, you can create a `Cors` struct directly in the route.
//! - Your routes will need to have a `'r` lifetime and return `impl Responder<'r>`.
//! - Your routes _might_ need to have a `'r` lifetime and return `impl Responder<'r>`. See below.
//! - Using the `Cors` struct, use either the
//! [`respond_owned`](struct.Cors.html#method.respond_owned) or
//! [`respond_borrowed`](struct.Cors.html#method.respond_borrowed) function and pass in a handler
@ -260,11 +260,20 @@
//! - You will have to manually define your own `OPTIONS` routes.
//!
//! ### Notes about route lifetime
//! It is unfortunate that you have to manually specify the `'r` lifetimes in your routes.
//! Leaving out the lifetime will result in a
//! [compiler panic](https://github.com/rust-lang/rust/issues/43380). Even if the panic is fixed,
//! it is not known if we can exclude the lifetime because lifetimes are _elided_ in Rust,
//! not inferred.
//! You might have to specify a `'r` lifetime in your routes and then return `impl Responder<'r>`.
//! If you are not sure what to do, you can try to leave the lifetime out and then add it in
//! when the compiler complains.
//!
//! Generally, you will need to manually annotate the lifetime for the following cases where
//! the compiler is unable to [elide](https://doc.rust-lang.org/beta/nomicon/lifetime-elision.html)
//! the lifetime:
//!
//! - Your function arguments do not borrow anything.
//! - Your function arguments borrow from more than one lifetime.
//! - Your function arguments borrow from a lifetime that is shorter than the `'r` lifetime
//! required.
//!
//! You can see examples when the lifetime annotation is required (or not) in `examples/manual.rs`.
//!
//! ### Owned example
//! This is the most likely scenario when you want to have manual CORS validation. You can use this

View File

@ -17,14 +17,14 @@ use rocket_cors::*;
/// Using a borrowed `Cors`
#[get("/")]
fn cors<'r>(options: State<'r, Cors>) -> impl Responder<'r> {
fn cors(options: State<Cors>) -> impl Responder {
options
.inner()
.respond_borrowed(|guard| guard.responder("Hello CORS"))
}
#[get("/panic")]
fn panicking_route<'r>(options: State<'r, Cors>) -> impl Responder<'r> {
fn panicking_route(options: State<Cors>) -> impl Responder {
options.inner().respond_borrowed(|_| -> () {
panic!("This route will panic");
})
@ -51,7 +51,7 @@ fn owned<'r>() -> impl Responder<'r> {
/// `Responder` with String
#[allow(unmounted_route)]
#[get("/")]
fn responder_string<'r>(options: State<'r, Cors>) -> impl Responder<'r> {
fn responder_string(options: State<Cors>) -> impl Responder {
options
.inner()
.respond_borrowed(|guard| guard.responder("Hello CORS".to_string()))