From d8a9c9a2774bd08019ee23d1ca57babb7f4acbff Mon Sep 17 00:00:00 2001 From: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:14:33 +0100 Subject: [PATCH] fix: Ensure that types from std::sync work as expected when used as inputs/outputs --- libs/pavexc/src/rustdoc/queries.rs | 29 ++++++- .../diagnostics.dot | 40 ++++++---- .../expectations/app.rs | 77 +++++++++++++------ .../expectations/diagnostics.dot | 40 ++++++---- .../arc_singletons_are_supported/src/lib.rs | 18 ++++- 5 files changed, 147 insertions(+), 57 deletions(-) diff --git a/libs/pavexc/src/rustdoc/queries.rs b/libs/pavexc/src/rustdoc/queries.rs index b4ab6893c..5be539e39 100644 --- a/libs/pavexc/src/rustdoc/queries.rs +++ b/libs/pavexc/src/rustdoc/queries.rs @@ -467,7 +467,7 @@ impl CrateCollection { // The item might come from a transitive dependency via a re-export // done by a direct dependency. // We don't have a bulletproof way of finding the re-exporter name, but we can - // try to infer it (e.g. via the `name` proeprty). + // try to infer it (e.g. via the `name` property). re_exporter_crate_name: Option<&str>, ) -> Result<(GlobalItemId, &[String]), anyhow::Error> { let (definition_package_id, path) = { @@ -988,6 +988,33 @@ fn index_local_types<'a>( } } else { navigation_history.insert(*imported_id); + + // We keep track of the source path in our indexes. + // This is useful, in particular, if we don't have + // access to the source module of the imported item. + // This can happen when working with `std`/`alloc`/`core` + // since the JSON output doesn't include private/doc-hidden + // items. + { + let mut normalized_source_path = vec![]; + let source_segments = i.source.split("::"); + for segment in source_segments { + if segment == "self" { + normalized_source_path + .extend(current_path.iter().map(|s| s.to_string())); + } else if segment == "crate" { + normalized_source_path.push(current_path[0].to_string()) + } else { + normalized_source_path.push(segment.to_string()); + } + } + // Assume it's private unless we find out otherwise later on + private_path_index + .entry(*imported_id) + .or_default() + .insert(normalized_source_path); + } + index_local_types( krate, package_id, diff --git a/libs/ui_tests/reflection/arc_singletons_are_supported/diagnostics.dot b/libs/ui_tests/reflection/arc_singletons_are_supported/diagnostics.dot index 52d6ac6ed..321653449 100644 --- a/libs/ui_tests/reflection/arc_singletons_are_supported/diagnostics.dot +++ b/libs/ui_tests/reflection/arc_singletons_are_supported/diagnostics.dot @@ -1,21 +1,29 @@ digraph "GET / - 0" { - 0 [ label = "3| pavex::middleware::wrap_noop(pavex::middleware::Next>) -> pavex::response::Response"] - 1 [ label = "2| pavex::middleware::Next::new(crate::route_0::Next0<'a>) -> pavex::middleware::Next>"] - 2 [ label = "1| crate::route_0::Next0(&'a alloc::sync::Arc) -> crate::route_0::Next0<'a>"] - 4 [ label = "4| ::into_response(pavex::response::Response) -> pavex::response::Response"] - 5 [ label = "0| &alloc::sync::Arc"] + 0 [ label = "5| pavex::middleware::wrap_noop(pavex::middleware::Next>) -> pavex::response::Response"] + 1 [ label = "4| pavex::middleware::Next::new(crate::route_0::Next0<'a, 'b, 'c>) -> pavex::middleware::Next>"] + 2 [ label = "3| crate::route_0::Next0(&'a alloc::sync::Arc>, &'b alloc::sync::Arc>, &'c alloc::sync::Arc) -> crate::route_0::Next0<'a, 'b, 'c>"] + 3 [ label = "1| &alloc::sync::Arc>"] + 4 [ label = "2| &alloc::sync::Arc"] + 6 [ label = "6| ::into_response(pavex::response::Response) -> pavex::response::Response"] + 7 [ label = "0| &alloc::sync::Arc>"] 1 -> 0 [ ] 2 -> 1 [ ] - 0 -> 4 [ ] - 5 -> 2 [ ] + 4 -> 2 [ ] + 3 -> 2 [ ] + 0 -> 6 [ ] + 7 -> 2 [ ] } digraph "GET / - 1" { - 0 [ label = "1| app_933292bd::handler(&alloc::sync::Arc) -> http::StatusCode"] - 2 [ label = "2| ::into_response(http::StatusCode) -> pavex::response::Response"] - 3 [ label = "0| &alloc::sync::Arc"] - 0 -> 2 [ ] - 3 -> 0 [ ] + 0 [ label = "3| app_933292bd::handler(&alloc::sync::Arc, &alloc::sync::Arc>, &alloc::sync::Arc>) -> http::StatusCode"] + 1 [ label = "1| &alloc::sync::Arc>"] + 2 [ label = "2| &alloc::sync::Arc>"] + 4 [ label = "4| ::into_response(http::StatusCode) -> pavex::response::Response"] + 5 [ label = "0| &alloc::sync::Arc"] + 2 -> 0 [ ] + 1 -> 0 [ ] + 0 -> 4 [ ] + 5 -> 0 [ ] } digraph "* / - 0" { @@ -39,7 +47,11 @@ digraph "* / - 1" { } digraph app_state { - 0 [ label = "1| crate::ApplicationState(alloc::sync::Arc) -> crate::ApplicationState"] - 1 [ label = "0| app_933292bd::constructor() -> alloc::sync::Arc"] + 0 [ label = "3| crate::ApplicationState(alloc::sync::Arc>, alloc::sync::Arc, alloc::sync::Arc>) -> crate::ApplicationState"] + 1 [ label = "2| app_933292bd::arc_rwlock() -> alloc::sync::Arc>"] + 2 [ label = "1| app_933292bd::arc() -> alloc::sync::Arc"] + 3 [ label = "0| app_933292bd::arc_mutex() -> alloc::sync::Arc>"] + 3 -> 0 [ ] + 2 -> 0 [ ] 1 -> 0 [ ] } diff --git a/libs/ui_tests/reflection/arc_singletons_are_supported/expectations/app.rs b/libs/ui_tests/reflection/arc_singletons_are_supported/expectations/app.rs index 99900fc13..2f26ddc57 100644 --- a/libs/ui_tests/reflection/arc_singletons_are_supported/expectations/app.rs +++ b/libs/ui_tests/reflection/arc_singletons_are_supported/expectations/app.rs @@ -7,11 +7,19 @@ struct ServerState { application_state: ApplicationState, } pub struct ApplicationState { - s0: alloc::sync::Arc, + s0: alloc::sync::Arc>, + s1: alloc::sync::Arc, + s2: alloc::sync::Arc>, } pub async fn build_application_state() -> crate::ApplicationState { - let v0 = app::constructor(); - crate::ApplicationState { s0: v0 } + let v0 = app::arc_mutex(); + let v1 = app::arc(); + let v2 = app::arc_rwlock(); + crate::ApplicationState { + s0: v2, + s1: v1, + s2: v0, + } } pub fn run( server_builder: pavex::server::Server, @@ -56,7 +64,12 @@ async fn route_request( 0u32 => { match &request_head.method { &pavex::http::Method::GET => { - route_0::entrypoint(&server_state.application_state.s0).await + route_0::entrypoint( + &server_state.application_state.s0, + &server_state.application_state.s1, + &server_state.application_state.s2, + ) + .await } _ => { let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ @@ -71,50 +84,66 @@ async fn route_request( } } pub mod route_0 { - pub async fn entrypoint<'a>( - s_0: &'a alloc::sync::Arc, + pub async fn entrypoint<'a, 'b, 'c>( + s_0: &'a alloc::sync::Arc>, + s_1: &'b alloc::sync::Arc, + s_2: &'c alloc::sync::Arc>, ) -> pavex::response::Response { - let response = wrapping_0(s_0).await; + let response = wrapping_0(s_0, s_1, s_2).await; response } - async fn stage_1<'a>( - s_0: &'a alloc::sync::Arc, + async fn stage_1<'a, 'b, 'c>( + s_0: &'a alloc::sync::Arc>, + s_1: &'b alloc::sync::Arc>, + s_2: &'c alloc::sync::Arc, ) -> pavex::response::Response { - let response = handler(s_0).await; + let response = handler(s_0, s_1, s_2).await; response } async fn wrapping_0( - v0: &alloc::sync::Arc, + v0: &alloc::sync::Arc>, + v1: &alloc::sync::Arc, + v2: &alloc::sync::Arc>, ) -> pavex::response::Response { - let v1 = crate::route_0::Next0 { - s_0: v0, + let v3 = crate::route_0::Next0 { + s_0: v2, + s_1: v0, + s_2: v1, next: stage_1, }; - let v2 = pavex::middleware::Next::new(v1); - let v3 = pavex::middleware::wrap_noop(v2).await; - ::into_response(v3) + let v4 = pavex::middleware::Next::new(v3); + let v5 = pavex::middleware::wrap_noop(v4).await; + ::into_response(v5) } async fn handler( - v0: &alloc::sync::Arc, + v0: &alloc::sync::Arc>, + v1: &alloc::sync::Arc>, + v2: &alloc::sync::Arc, ) -> pavex::response::Response { - let v1 = app::handler(v0); - ::into_response(v1) + let v3 = app::handler(v2, v0, v1); + ::into_response(v3) } - struct Next0<'a, T> + struct Next0<'a, 'b, 'c, T> where T: std::future::Future, { - s_0: &'a alloc::sync::Arc, - next: fn(&'a alloc::sync::Arc) -> T, + s_0: &'a alloc::sync::Arc>, + s_1: &'b alloc::sync::Arc>, + s_2: &'c alloc::sync::Arc, + next: fn( + &'a alloc::sync::Arc>, + &'b alloc::sync::Arc>, + &'c alloc::sync::Arc, + ) -> T, } - impl<'a, T> std::future::IntoFuture for Next0<'a, T> + impl<'a, 'b, 'c, T> std::future::IntoFuture for Next0<'a, 'b, 'c, T> where T: std::future::Future, { type Output = pavex::response::Response; type IntoFuture = T; fn into_future(self) -> Self::IntoFuture { - (self.next)(self.s_0) + (self.next)(self.s_0, self.s_1, self.s_2) } } } diff --git a/libs/ui_tests/reflection/arc_singletons_are_supported/expectations/diagnostics.dot b/libs/ui_tests/reflection/arc_singletons_are_supported/expectations/diagnostics.dot index fec1bc9b2..f76ffb131 100644 --- a/libs/ui_tests/reflection/arc_singletons_are_supported/expectations/diagnostics.dot +++ b/libs/ui_tests/reflection/arc_singletons_are_supported/expectations/diagnostics.dot @@ -1,21 +1,29 @@ digraph "GET / - 0" { - 0 [ label = "3| pavex::middleware::wrap_noop(pavex::middleware::Next>) -> pavex::response::Response"] - 1 [ label = "2| pavex::middleware::Next::new(crate::route_0::Next0<'a>) -> pavex::middleware::Next>"] - 2 [ label = "1| crate::route_0::Next0(&'a alloc::sync::Arc) -> crate::route_0::Next0<'a>"] - 4 [ label = "4| ::into_response(pavex::response::Response) -> pavex::response::Response"] - 5 [ label = "0| &alloc::sync::Arc"] + 0 [ label = "5| pavex::middleware::wrap_noop(pavex::middleware::Next>) -> pavex::response::Response"] + 1 [ label = "4| pavex::middleware::Next::new(crate::route_0::Next0<'a, 'b, 'c>) -> pavex::middleware::Next>"] + 2 [ label = "3| crate::route_0::Next0(&'a alloc::sync::Arc>, &'b alloc::sync::Arc>, &'c alloc::sync::Arc) -> crate::route_0::Next0<'a, 'b, 'c>"] + 3 [ label = "1| &alloc::sync::Arc>"] + 4 [ label = "2| &alloc::sync::Arc"] + 6 [ label = "6| ::into_response(pavex::response::Response) -> pavex::response::Response"] + 7 [ label = "0| &alloc::sync::Arc>"] 1 -> 0 [ ] 2 -> 1 [ ] - 0 -> 4 [ ] - 5 -> 2 [ ] + 4 -> 2 [ ] + 3 -> 2 [ ] + 0 -> 6 [ ] + 7 -> 2 [ ] } digraph "GET / - 1" { - 0 [ label = "1| app::handler(&alloc::sync::Arc) -> http::StatusCode"] - 2 [ label = "2| ::into_response(http::StatusCode) -> pavex::response::Response"] - 3 [ label = "0| &alloc::sync::Arc"] - 0 -> 2 [ ] - 3 -> 0 [ ] + 0 [ label = "3| app::handler(&alloc::sync::Arc, &alloc::sync::Arc>, &alloc::sync::Arc>) -> http::StatusCode"] + 1 [ label = "1| &alloc::sync::Arc>"] + 2 [ label = "2| &alloc::sync::Arc>"] + 4 [ label = "4| ::into_response(http::StatusCode) -> pavex::response::Response"] + 5 [ label = "0| &alloc::sync::Arc"] + 2 -> 0 [ ] + 1 -> 0 [ ] + 0 -> 4 [ ] + 5 -> 0 [ ] } digraph "* / - 0" { @@ -39,7 +47,11 @@ digraph "* / - 1" { } digraph app_state { - 0 [ label = "1| crate::ApplicationState(alloc::sync::Arc) -> crate::ApplicationState"] - 1 [ label = "0| app::constructor() -> alloc::sync::Arc"] + 0 [ label = "3| crate::ApplicationState(alloc::sync::Arc>, alloc::sync::Arc, alloc::sync::Arc>) -> crate::ApplicationState"] + 1 [ label = "2| app::arc_rwlock() -> alloc::sync::Arc>"] + 2 [ label = "1| app::arc() -> alloc::sync::Arc"] + 3 [ label = "0| app::arc_mutex() -> alloc::sync::Arc>"] + 3 -> 0 [ ] + 2 -> 0 [ ] 1 -> 0 [ ] } \ No newline at end of file diff --git a/libs/ui_tests/reflection/arc_singletons_are_supported/src/lib.rs b/libs/ui_tests/reflection/arc_singletons_are_supported/src/lib.rs index 98b1f674e..ded3aed94 100644 --- a/libs/ui_tests/reflection/arc_singletons_are_supported/src/lib.rs +++ b/libs/ui_tests/reflection/arc_singletons_are_supported/src/lib.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::sync::{Arc, Mutex, RwLock}; use pavex::blueprint::{router::GET, Blueprint}; use pavex::f; @@ -6,17 +6,27 @@ use pavex::http::StatusCode; pub struct Custom; -pub fn constructor() -> Arc { +pub fn arc() -> Arc { Arc::new(Custom) } -pub fn handler(_s: &Arc) -> StatusCode { +pub fn arc_mutex() -> Arc> { + Arc::new(Mutex::new(Custom)) +} + +pub fn arc_rwlock() -> Arc> { + Arc::new(RwLock::new(Custom)) +} + +pub fn handler(_s: &Arc, _t: &Arc>, _u: &Arc>) -> StatusCode { todo!() } pub fn blueprint() -> Blueprint { let mut bp = Blueprint::new(); - bp.singleton(f!(crate::constructor)); + bp.singleton(f!(crate::arc)); + bp.singleton(f!(crate::arc_mutex)); + bp.singleton(f!(crate::arc_rwlock)); bp.route(GET, "/", f!(crate::handler)); bp }