Skip to content

Commit

Permalink
fix: Don't use public items via paths that include private modules (#316
Browse files Browse the repository at this point in the history
)
  • Loading branch information
LukeMathWalker authored Jun 22, 2024
1 parent 3007f1b commit 38426f2
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#[doc(inline)]
pub use api::engine;
#[doc(inline)]
pub use api::Surreal;

mod api {
pub struct Surreal<T>(T);

pub mod engine {
pub struct Any;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//! Do NOT edit this code.
//! It was automatically generated by Pavex.
//! All manual edits will be lost next time the code is generated.
extern crate alloc;
struct ServerState {
router: pavex_matchit::Router<u32>,
application_state: ApplicationState,
}
pub struct ApplicationState {
s0: dep::Surreal<dep::engine::Any>,
}
pub async fn build_application_state() -> crate::ApplicationState {
let v0 = app::constructor();
crate::ApplicationState { s0: v0 }
}
pub fn run(
server_builder: pavex::server::Server,
application_state: ApplicationState,
) -> pavex::server::ServerHandle {
let server_state = std::sync::Arc::new(ServerState {
router: build_router(),
application_state,
});
server_builder.serve(route_request, server_state)
}
fn build_router() -> pavex_matchit::Router<u32> {
let mut router = pavex_matchit::Router::new();
router.insert("/", 0u32).unwrap();
router
}
async fn route_request(
request: http::Request<hyper::body::Incoming>,
_connection_info: Option<pavex::connection::ConnectionInfo>,
server_state: std::sync::Arc<ServerState>,
) -> pavex::response::Response {
let (request_head, request_body) = request.into_parts();
#[allow(unused)]
let request_body = pavex::request::body::RawIncomingBody::from(request_body);
let request_head: pavex::request::RequestHead = request_head.into();
let matched_route = match server_state.router.at(&request_head.target.path()) {
Ok(m) => m,
Err(_) => {
let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter(
vec![],
)
.into();
return route_1::entrypoint(&allowed_methods).await;
}
};
let route_id = matched_route.value;
#[allow(unused)]
let url_params: pavex::request::path::RawPathParams<'_, '_> = matched_route
.params
.into();
match route_id {
0u32 => {
match &request_head.method {
&pavex::http::Method::GET => {
route_0::entrypoint(&server_state.application_state.s0).await
}
_ => {
let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([
pavex::http::Method::GET,
])
.into();
route_1::entrypoint(&allowed_methods).await
}
}
}
i => unreachable!("Unknown route id: {}", i),
}
}
pub mod route_0 {
pub async fn entrypoint<'a>(
s_0: &'a dep::Surreal<dep::engine::Any>,
) -> pavex::response::Response {
let response = wrapping_0(s_0).await;
response
}
async fn stage_1<'a>(
s_0: &'a dep::Surreal<dep::engine::Any>,
) -> pavex::response::Response {
let response = handler(s_0).await;
response
}
async fn wrapping_0(
v0: &dep::Surreal<dep::engine::Any>,
) -> pavex::response::Response {
let v1 = crate::route_0::Next0 {
s_0: v0,
next: stage_1,
};
let v2 = pavex::middleware::Next::new(v1);
let v3 = pavex::middleware::wrap_noop(v2).await;
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v3)
}
async fn handler(v0: &dep::Surreal<dep::engine::Any>) -> pavex::response::Response {
let v1 = app::handler(v0);
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v1)
}
struct Next0<'a, T>
where
T: std::future::Future<Output = pavex::response::Response>,
{
s_0: &'a dep::Surreal<dep::engine::Any>,
next: fn(&'a dep::Surreal<dep::engine::Any>) -> T,
}
impl<'a, T> std::future::IntoFuture for Next0<'a, T>
where
T: std::future::Future<Output = pavex::response::Response>,
{
type Output = pavex::response::Response;
type IntoFuture = T;
fn into_future(self) -> Self::IntoFuture {
(self.next)(self.s_0)
}
}
}
pub mod route_1 {
pub async fn entrypoint<'a>(
s_0: &'a pavex::router::AllowedMethods,
) -> pavex::response::Response {
let response = wrapping_0(s_0).await;
response
}
async fn stage_1<'a>(
s_0: &'a pavex::router::AllowedMethods,
) -> pavex::response::Response {
let response = handler(s_0).await;
response
}
async fn wrapping_0(
v0: &pavex::router::AllowedMethods,
) -> pavex::response::Response {
let v1 = crate::route_1::Next0 {
s_0: v0,
next: stage_1,
};
let v2 = pavex::middleware::Next::new(v1);
let v3 = pavex::middleware::wrap_noop(v2).await;
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v3)
}
async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::response::Response {
let v1 = pavex::router::default_fallback(v0).await;
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v1)
}
struct Next0<'a, T>
where
T: std::future::Future<Output = pavex::response::Response>,
{
s_0: &'a pavex::router::AllowedMethods,
next: fn(&'a pavex::router::AllowedMethods) -> T,
}
impl<'a, T> std::future::IntoFuture for Next0<'a, T>
where
T: std::future::Future<Output = pavex::response::Response>,
{
type Output = pavex::response::Response;
type IntoFuture = T;
fn into_future(self) -> Self::IntoFuture {
(self.next)(self.s_0)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
digraph "GET / - 0" {
0 [ label = "pavex::middleware::wrap_noop(pavex::middleware::Next<crate::route_0::Next0<'a>>) -> pavex::response::Response"]
1 [ label = "pavex::middleware::Next::new(crate::route_0::Next0<'a>) -> pavex::middleware::Next<crate::route_0::Next0<'a>>"]
2 [ label = "crate::route_0::Next0(&'a dep::Surreal<dep::engine::Any>) -> crate::route_0::Next0<'a>"]
4 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
5 [ label = "&dep::Surreal<dep::engine::Any>"]
1 -> 0 [ ]
2 -> 1 [ ]
0 -> 4 [ ]
5 -> 2 [ ]
}

digraph "GET / - 1" {
0 [ label = "app::handler(&dep::Surreal<dep::engine::Any>) -> pavex::response::Response"]
2 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
3 [ label = "&dep::Surreal<dep::engine::Any>"]
0 -> 2 [ ]
3 -> 0 [ ]
}

digraph "* / - 0" {
0 [ label = "pavex::middleware::wrap_noop(pavex::middleware::Next<crate::route_1::Next0<'a>>) -> pavex::response::Response"]
1 [ label = "pavex::middleware::Next::new(crate::route_1::Next0<'a>) -> pavex::middleware::Next<crate::route_1::Next0<'a>>"]
2 [ label = "crate::route_1::Next0(&'a pavex::router::AllowedMethods) -> crate::route_1::Next0<'a>"]
4 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
5 [ label = "&pavex::router::AllowedMethods"]
1 -> 0 [ ]
2 -> 1 [ ]
0 -> 4 [ ]
5 -> 2 [ ]
}

digraph "* / - 1" {
0 [ label = "pavex::router::default_fallback(&pavex::router::AllowedMethods) -> pavex::response::Response"]
2 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
3 [ label = "&pavex::router::AllowedMethods"]
0 -> 2 [ ]
3 -> 0 [ ]
}

digraph app_state {
0 [ label = "crate::ApplicationState(dep::Surreal<dep::engine::Any>) -> crate::ApplicationState"]
1 [ label = "app::constructor() -> dep::Surreal<dep::engine::Any>"]
1 -> 0 [ ]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use pavex::blueprint::{router::GET, Blueprint};
use pavex::f;
use pavex::response::Response;

pub type RemoteAlias = dep::Surreal<dep::engine::Any>;

pub fn constructor() -> RemoteAlias {
todo!()
}

pub fn handler(_a: &RemoteAlias) -> Response {
todo!()
}

pub fn blueprint() -> Blueprint {
let mut bp = Blueprint::new();
bp.singleton(f!(crate::constructor));
bp.route(GET, "/", f!(crate::handler));
bp
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
description = "Reproduction of a reported bug"

[expectations]
codegen = "pass"

[ephemeral_dependencies]
dep = { path = "dep.rs" }
1 change: 1 addition & 0 deletions libs/pavexc/src/compiler/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl App {
) else {
return Err(diagnostics);
};

let framework_item_db = FrameworkItemDb::new(&package_graph, &krate_collection);
let mut component_db = ComponentDb::build(
user_component_db,
Expand Down
9 changes: 8 additions & 1 deletion libs/pavexc/src/rustdoc/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,7 @@ impl Crate {
&mut id2private_import_paths,
&mut re_exports,
&krate.root,
true,
)?;

import_path2id.reserve(id2public_import_paths.len());
Expand Down Expand Up @@ -870,6 +871,7 @@ fn index_local_types<'a>(
private_path_index: &mut HashMap<rustdoc_types::Id, BTreeSet<Vec<String>>>,
re_exports: &mut HashMap<Vec<String>, (Vec<String>, u32)>,
current_item_id: &rustdoc_types::Id,
is_public: bool,
) -> Result<(), anyhow::Error> {
// TODO: the way we handle `current_path` is extremely wasteful,
// we can likely reuse the same buffer throughout.
Expand All @@ -890,6 +892,8 @@ fn index_local_types<'a>(
Some(i) => i,
};

let is_public = is_public && current_item.visibility == Visibility::Public;

match &current_item.inner {
ItemEnum::Module(m) => {
let current_path_segment = current_item
Expand All @@ -906,6 +910,7 @@ fn index_local_types<'a>(
private_path_index,
re_exports,
item_id,
is_public,
)?;
}
}
Expand Down Expand Up @@ -949,6 +954,7 @@ fn index_local_types<'a>(
private_path_index,
re_exports,
re_exported_item_id,
is_public,
)?;
}
} else {
Expand All @@ -960,6 +966,7 @@ fn index_local_types<'a>(
private_path_index,
re_exports,
imported_id,
is_public,
)?;
}
}
Expand All @@ -977,7 +984,7 @@ fn index_local_types<'a>(
current_path.push(name);
let path = current_path.into_iter().map(|s| s.to_string()).collect();

let index = if current_item.visibility == Visibility::Public {
let index = if is_public {
public_path_index
} else {
private_path_index
Expand Down

0 comments on commit 38426f2

Please sign in to comment.