From a950e545992e9d4927ad45186ec037179bf9117d Mon Sep 17 00:00:00 2001 From: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com> Date: Thu, 8 Jun 2023 21:01:27 +0100 Subject: [PATCH] Fix bug related to generic arguments defined in a foreign crate wrt the typedef definition. --- libs/pavex/src/compiler/resolvers.rs | 2 +- .../expectations/app.rs | 103 ++++++++++++++++++ .../expectations/diagnostics.dot | 8 ++ .../lib.rs | 40 +++++++ .../test_config.toml | 11 ++ .../test_config.toml | 2 +- 6 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/expectations/app.rs create mode 100644 libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/expectations/diagnostics.dot create mode 100644 libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/lib.rs create mode 100644 libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/test_config.toml diff --git a/libs/pavex/src/compiler/resolvers.rs b/libs/pavex/src/compiler/resolvers.rs index 111d35f4c..81c8f6e13 100644 --- a/libs/pavex/src/compiler/resolvers.rs +++ b/libs/pavex/src/compiler/resolvers.rs @@ -56,7 +56,7 @@ pub(crate) fn resolve_type( if let GenericArg::Type(provided_arg) = provided_arg { resolve_type( provided_arg, - &global_type_id.package_id, + &used_by_package_id, krate_collection, &generic_bindings, )? diff --git a/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/expectations/app.rs b/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/expectations/app.rs new file mode 100644 index 000000000..00f8737c5 --- /dev/null +++ b/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/expectations/app.rs @@ -0,0 +1,103 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +#[allow(unused_imports)] +use std as alloc; +struct ServerState { + router: pavex_runtime::routing::Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +pub struct ApplicationState {} +pub async fn build_application_state() -> crate::ApplicationState { + crate::ApplicationState {} +} +pub async fn run( + server_builder: pavex_runtime::hyper::server::Builder< + pavex_runtime::hyper::server::conn::AddrIncoming, + >, + application_state: ApplicationState, +) -> Result<(), pavex_runtime::Error> { + let server_state = std::sync::Arc::new(ServerState { + router: build_router().map_err(pavex_runtime::Error::new)?, + application_state, + }); + let make_service = pavex_runtime::hyper::service::make_service_fn(move |_| { + let server_state = server_state.clone(); + async move { + Ok::< + _, + pavex_runtime::hyper::Error, + >( + pavex_runtime::hyper::service::service_fn(move |request| { + let server_state = server_state.clone(); + async move { + Ok::< + _, + pavex_runtime::hyper::Error, + >(route_request(request, server_state).await) + } + }), + ) + } + }); + server_builder.serve(make_service).await.map_err(pavex_runtime::Error::new) +} +fn build_router() -> Result< + pavex_runtime::routing::Router, + pavex_runtime::routing::InsertError, +> { + let mut router = pavex_runtime::routing::Router::new(); + router.insert("/home", 0u32)?; + Ok(router) +} +async fn route_request( + request: http::Request, + server_state: std::sync::Arc, +) -> pavex_runtime::response::Response { + #[allow(unused)] + let (request_head, request_body) = request.into_parts(); + let request_head: pavex_runtime::request::RequestHead = request_head.into(); + let matched_route = match server_state.router.at(&request_head.uri.path()) { + Ok(m) => m, + Err(_) => { + return pavex_runtime::response::Response::builder() + .status(pavex_runtime::http::StatusCode::NOT_FOUND) + .body(pavex_runtime::body::boxed(hyper::body::Body::empty())) + .unwrap(); + } + }; + let route_id = matched_route.value; + #[allow(unused)] + let url_params: pavex_runtime::extract::route::RawRouteParams<'_, '_> = matched_route + .params + .into(); + match route_id { + 0u32 => { + match &request_head.method { + &pavex_runtime::http::Method::GET => route_handler_0().await, + _ => { + pavex_runtime::response::Response::builder() + .status(pavex_runtime::http::StatusCode::METHOD_NOT_ALLOWED) + .header(pavex_runtime::http::header::ALLOW, "GET") + .body(pavex_runtime::body::boxed(hyper::body::Body::empty())) + .unwrap() + } + } + } + _ => { + pavex_runtime::response::Response::builder() + .status(pavex_runtime::http::StatusCode::NOT_FOUND) + .body(pavex_runtime::body::boxed(hyper::body::Body::empty())) + .unwrap() + } + } +} +pub async fn route_handler_0() -> http::Response< + http_body::combinators::BoxBody, +> { + let v0 = app::handler(); + as pavex_runtime::response::IntoResponse>::into_response(v0) +} \ No newline at end of file diff --git a/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/expectations/diagnostics.dot b/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/expectations/diagnostics.dot new file mode 100644 index 000000000..dd79c028d --- /dev/null +++ b/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/expectations/diagnostics.dot @@ -0,0 +1,8 @@ +digraph "GET /home" { + 0 [ label = "app::handler() -> http::Response"] + 1 [ label = " as pavex_runtime::response::IntoResponse>::into_response(http::Response) -> http::Response>"] + 0 -> 1 [ ] +} +digraph app_state { + 0 [ label = "crate::ApplicationState() -> crate::ApplicationState"] +} \ No newline at end of file diff --git a/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/lib.rs b/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/lib.rs new file mode 100644 index 000000000..565af934f --- /dev/null +++ b/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/lib.rs @@ -0,0 +1,40 @@ +use pavex_builder::{f, router::GET, Blueprint}; +use pavex_runtime::response::IntoResponse; +use pavex_runtime::response::Response; + +pub fn blueprint() -> Blueprint { + let mut bp = Blueprint::new(); + bp.route(GET, "/home", f!(crate::handler)); + bp +} + +// A locally-definited type +pub struct BodyType { + pub name: String, + pub age: u8, +} + +impl http_body::Body for BodyType { + type Data = bytes::Bytes; + type Error = pavex_runtime::Error; + + fn poll_data( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll>> { + todo!() + } + + fn poll_trailers( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll, Self::Error>> { + todo!() + } +} + +// The `Response` type comes from `pavex_runtime` but the body +// type is defined in this crate. +pub fn handler() -> Response { + todo!() +} diff --git a/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/test_config.toml b/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/test_config.toml new file mode 100644 index 000000000..031551b4b --- /dev/null +++ b/libs/pavex_cli/tests/ui_tests/reflection/generic_parameters_can_come_from_another_crate/test_config.toml @@ -0,0 +1,11 @@ +description = """ +Pavex handles types whose generic parameter are not defined in the same crate +that defines the base type +""" + +[expectations] +codegen = "pass" + +[dependencies] +http-body = "0.4" +bytes = "1" \ No newline at end of file diff --git a/libs/pavex_cli/tests/ui_tests/reflection/local_glob_reexports_are_supported/test_config.toml b/libs/pavex_cli/tests/ui_tests/reflection/local_glob_reexports_are_supported/test_config.toml index 48241e359..077ca6c62 100644 --- a/libs/pavex_cli/tests/ui_tests/reflection/local_glob_reexports_are_supported/test_config.toml +++ b/libs/pavex_cli/tests/ui_tests/reflection/local_glob_reexports_are_supported/test_config.toml @@ -1,4 +1,4 @@ -description = "pavex is abled to handle glob re-exports from local modules" +description = "Pavex is able to handle glob re-exports from local modules" [expectations] codegen = "pass"