Description
When I changed a signature of a function from returning a struct that implementing some trait Responder
to impl Responder
, the compiler panicked. The panic stack trace is at the end of the post.
Code that works:
[package]
name = "rustc-crash"
version = "0.1.0"
[dependencies]
rocket = "0.3"
rocket_codegen = "0.3"
#![feature(plugin, custom_derive, conservative_impl_trait)]
#![plugin(rocket_codegen)]
extern crate rocket;
use rocket::State;
use rocket::response::Responder;
struct SomeState;
/// This is OK
#[get("/one")]
fn test_one() -> &'static str {
"Hello world"
}
/// This panics
#[get("/")]
fn test_two(state: State<SomeState>) -> &'static str{
"Hello world"
}
fn main() {
rocket::ignite()
.mount(
"/",
routes![test_one, test_two],
)
.manage(SomeState)
.launch();
}
Code that panics:
#![feature(plugin, custom_derive, conservative_impl_trait)]
#![plugin(rocket_codegen)]
extern crate rocket;
use rocket::State;
use rocket::response::Responder;
struct SomeState;
/// This is OK
#[get("/one")]
fn test_one<'r>() -> impl Responder<'r> {
"Hello world"
}
/// This panics
#[get("/")]
fn test_two(state: State<SomeState>) -> impl Responder {
"Hello world"
}
fn main() {
rocket::ignite()
.mount(
"/",
routes![test_one, test_two],
)
.manage(SomeState)
.launch();
}
More information
Rocket.rs routes are any functions that returns something that implements the Responder
trait. The codegen plugin will wire the routes up via wrapper functions.
Consider the snippet of cargo expand
for the code above:
#[allow(unreachable_code)]
fn rocket_route_fn_test_one<'_b>(
__req: &'_b ::rocket::Request,
__data: ::rocket::Data,
) -> ::rocket::handler::Outcome<'_b> {
let responder = test_one();
::rocket::handler::Outcome::from(__req, responder)
}
/// Rocket code generated static route information structure.
#[allow(non_upper_case_globals)]
#[rocket_route_info]
pub static static_rocket_route_info_for_test_one: ::rocket::StaticRouteInfo =
::rocket::StaticRouteInfo {
method: ::rocket::http::Method::Get,
path: "/one",
handler: rocket_route_fn_test_one,
format: None,
rank: None,
};
/// This is OK
#[rocket_route(static_rocket_route_info_for_test_one)]
fn test_one<'r>() -> impl Responder<'r> {
"Hello world"
}
I suspect this might be because of the generated line ::rocket::handler::Outcome::from(__req, responder)
, which has this signature.
Apologies that I don't know any more of rustc's internals to offer any more information.
EDIT:
If I change the signature to fn test_two<'r>(state: State<'r, SomeState>) -> impl Responder<'r>
, the code will compile.
This might be a duplicate of #39872. Please feel free to close this if they are the same.
Meta
rustc --version --verbose
:
rustc 1.20.0-nightly (ae98ebf 2017-07-20)
binary: rustc
commit-hash: ae98ebf
commit-date: 2017-07-20
host: x86_64-unknown-linux-gnu
release: 1.20.0-nightly
LLVM version: 4.0
Backtrace:
$ RUST_BACKTRACE=1 cargo test
Compiling rustc-crash v0.1.0 (file:///home/yongwen/work/scratch/rustc-crash)
error: internal compiler error: /checkout/src/librustc/infer/region_inference/mod.rs:706: cannot relate bound region: ReLateBound(DebruijnIndex { depth: 2 }, BrAnon(0)) <= '_#26r
--> src/main.rs:17:1
|
17 | #[get("/")]
| ^^^^^^^^^^^
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.20.0-nightly (ae98ebfcb 2017-07-20) running on x86_64-unknown-linux-gnu
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'Box<Any>', /checkout/src/librustc_errors/lib.rs:437:8
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at /checkout/src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at /checkout/src/libstd/sys_common/backtrace.rs:60
at /checkout/src/libstd/panicking.rs:380
3: std::panicking::default_hook
at /checkout/src/libstd/panicking.rs:390
4: std::panicking::rust_panic_with_hook
at /checkout/src/libstd/panicking.rs:611
5: std::panicking::begin_panic_new
6: rustc_errors::Handler::span_bug
7: rustc::session::opt_span_bug_fmt::{{closure}}
8: rustc::session::opt_span_bug_fmt
9: rustc::session::span_bug_fmt
10: rustc::infer::region_inference::RegionVarBindings::make_subregion
11: rustc::infer::region_inference::RegionVarBindings::make_eqregion
12: rustc::ty::relate::relate_substs::{{closure}}
13: <<core::result::Result<V, E> as core::iter::traits::FromIterator<core::result::Result<A, E>>>::from_iter::Adapter<Iter, E> as core::iter::iterator::Iterator>::next
14: <core::result::Result<V, E> as core::iter::traits::FromIterator<core::result::Result<A, E>>>::from_iter
15: <core::result::Result<T, E> as rustc::ty::context::InternIteratorElement<T, R>>::intern_with
16: rustc::infer::at::At::sub_exp
17: rustc::traits::select::SelectionContext::match_projection
18: rustc::traits::select::SelectionContext::match_projection_obligation_against_definition_bounds
19: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
20: rustc::dep_graph::graph::DepGraph::with_anon_task
21: rustc::traits::select::SelectionContext::candidate_from_obligation
22: rustc::traits::select::SelectionContext::select
23: <rustc::traits::fulfill::FulfillProcessor<'a, 'b, 'gcx, 'tcx> as rustc_data_structures::obligation_forest::ObligationProcessor>::process_obligation
24: rustc::traits::fulfill::FulfillmentContext::select
25: rustc::traits::fulfill::FulfillmentContext::select_where_possible
26: rustc_typeck::check::FnCtxt::select_obligations_where_possible
27: rustc_typeck::check::FnCtxt::check_argument_types
28: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::confirm_builtin_call
29: rustc_typeck::check::FnCtxt::check_expr_kind
30: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_lvalue_pref
31: rustc_typeck::check::FnCtxt::check_block_with_expected::{{closure}}
32: rustc_typeck::check::FnCtxt::check_block_with_expected
33: rustc_typeck::check::FnCtxt::check_expr_kind
34: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_lvalue_pref
35: rustc_typeck::check::FnCtxt::check_return_expr
36: rustc_typeck::check::check_fn
37: rustc_typeck::check::typeck_tables_of::{{closure}}
38: rustc_typeck::check::typeck_tables_of
39: rustc::dep_graph::graph::DepGraph::with_task
40: rustc::ty::maps::<impl rustc::ty::maps::queries::typeck_tables_of<'tcx>>::try_get
41: rustc::ty::maps::TyCtxtAt::typeck_tables_of
42: rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::typeck_tables_of
43: rustc_typeck::check::typeck_item_bodies
44: rustc::dep_graph::graph::DepGraph::with_task
45: rustc::ty::maps::<impl rustc::ty::maps::queries::typeck_item_bodies<'tcx>>::try_get
46: rustc::ty::maps::TyCtxtAt::typeck_item_bodies
47: rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::typeck_item_bodies
48: rustc_typeck::check_crate
49: rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}
50: rustc_driver::driver::phase_3_run_analysis_passes
51: rustc_driver::driver::compile_input
52: rustc_driver::run_compiler
error: Could not compile `rustc-crash`.
To learn more, run the command again with --verbose.