diff --git a/integration_tests/juniper_tests/src/issue_398.rs b/integration_tests/juniper_tests/src/issue_398.rs new file mode 100644 index 00000000..4171e2f0 --- /dev/null +++ b/integration_tests/juniper_tests/src/issue_398.rs @@ -0,0 +1,67 @@ +// Original author of this test is . +use juniper::*; + +struct Query; + +#[juniper::object] +impl Query { + fn users(executor: &Executor) -> Vec { + // This doesn't cause a panic + executor.look_ahead(); + + vec![User { + country: Country { id: 1 }, + }] + } +} + +struct User { + country: Country, +} + +#[juniper::object] +impl User { + fn country(&self, executor: &Executor) -> &Country { + // This panics! + executor.look_ahead(); + + &self.country + } +} + +struct Country { + id: i32, +} + +#[juniper::object] +impl Country { + fn id(&self) -> i32 { + self.id + } +} + +type Schema = juniper::RootNode<'static, Query, EmptyMutation<()>>; + +#[test] +fn it_works() { + let _ = juniper::execute( + r#" + query Query { + users { + ...userFields + } + } + + fragment userFields on User { + country { + id + } + } + "#, + None, + &Schema::new(Query, EmptyMutation::new()), + &Variables::new(), + &(), + ) + .unwrap(); +} diff --git a/integration_tests/juniper_tests/src/lib.rs b/integration_tests/juniper_tests/src/lib.rs index 33cfc350..62662744 100644 --- a/integration_tests/juniper_tests/src/lib.rs +++ b/integration_tests/juniper_tests/src/lib.rs @@ -4,3 +4,5 @@ mod codegen; mod custom_scalar; #[cfg(test)] mod issue_371; +#[cfg(test)] +mod issue_398; diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index 930fd38c..7a098b06 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -518,22 +518,23 @@ where }; self.parent_selection_set .map(|p| { - let p = p - .iter() - .find(|&x| { - match *x { - Selection::Field(ref field) => { - let field = &field.item; - // TODO: support excludes. - let name = field.name.item; - let alias = field.alias.as_ref().map(|a| a.item); - alias.unwrap_or(name) == field_name - } - _ => false, + let found_field = p.iter().find(|&x| { + match *x { + Selection::Field(ref field) => { + let field = &field.item; + // TODO: support excludes. + let name = field.name.item; + let alias = field.alias.as_ref().map(|a| a.item); + alias.unwrap_or(name) == field_name } - }) - .expect("lookahead to find the field"); - LookAheadSelection::build_from_selection(&p, self.variables, self.fragments) + _ => false, + } + }); + if let Some(p) = found_field { + LookAheadSelection::build_from_selection(&p, self.variables, self.fragments) + } else { + None + } }) .filter(|s| s.is_some()) .unwrap_or_else(|| {