Skip to content

Commit

Permalink
Ensure our impl lookup optimization accounts for optional edges. (#682
Browse files Browse the repository at this point in the history
)
  • Loading branch information
obi1kenobi committed Dec 20, 2024
1 parent 5682ce3 commit 92ea66c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/adapter/optimizations/impl_lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ pub(crate) fn resolve_owner_impl<'a, V: AsVertex<Vertex<'a>> + 'a>(
_ => unreachable!("unexpected edge name: {edge_name}"),
};

// Check if the `method` edge is used next at the destination.
// Check if the `method` edge is used in a mandatory fashion at the destination.
if let Some(method_vertex_info) = resolve_info
.destination()
.first_edge("method")
.first_mandatory_edge("method")
.as_ref()
.map(|e| e.destination())
{
Expand Down
59 changes: 59 additions & 0 deletions src/adapter/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3917,3 +3917,62 @@ fn item_lookup_by_path_optimization() {
expected_results.sort_unstable();
similar_asserts::assert_eq!(expected_results, results);
}

#[test]
fn impl_lookup_by_method_name_optimization() {
// Any test crate that has `impl` blocks without methods would work for this test.
get_test_data!(data, associated_consts);
let adapter = RustdocAdapter::new(&data, None);
let adapter = Arc::new(&adapter);

let query = r#"
{
Crate {
item {
... on ImplOwner {
name @output
# Since this edge is optional, this query matches:
# - types with inherent impls containing the named method
# - types that *do not have* any methods in their inherent impls.
#
# Failure to account for either of these cases means we have a bug in
# the "item lookup by importable path" optimization code path.
inherent_impl {
method @optional {
method: name @output @filter(op: "=", value: ["$name"])
}
}
}
}
}
}
"#;

let variables = btreemap! {
"name" => "non_existent",
};

let schema =
Schema::parse(include_str!("../rustdoc_schema.graphql")).expect("schema failed to parse");

#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, serde::Deserialize)]
struct Output {
name: String,
method: Option<String>,
}

let mut results: Vec<_> =
trustfall::execute_query(&schema, adapter.clone(), query, variables.clone())
.expect("failed to run query")
.map(|row| row.try_into_struct().expect("shape mismatch"))
.collect();
results.sort_unstable();

let mut expected_results = vec![Output {
name: "Counter".into(),
method: None,
}];
expected_results.sort_unstable();
similar_asserts::assert_eq!(expected_results, results);
}

0 comments on commit 92ea66c

Please sign in to comment.