Repository: graphql-rust/juniper (language: rust)

Issue:
Panic when spreading untyped union fragment
**Describe the bug**
Updated my project from `0.15.3` to `0.15.5` and started observing the following sort of panic when spreading an untyped union fragment. Note that the specified concrete type is actually the union type.
`panicked at 'Concrete type <UnionType> is not handled by instance resolvers on GraphQL union <UnionType>`

**To Reproduce**
Example schema:

```graphql
union Character = Human | Droid
type Droid {
  id: ID!
  sensorColor: String!
}
type Human {
  id: ID!
  eyeColor: String!
}

type Query {
  mainCharacter: Character!
}
```

with the following query:

```graphql
query Query {
  mainCharacter {
    ...CharacterFragment
  }
}

fragment CharacterFragment on Character {
  __typename
  ... on Human {
    id
    eyeColor
  }
  ... on Droid {
    id
    sensorColor
  }
}
```

**Expected behavior**
No panic. And some result like:
```json
{
  "mainCharacter": { "__typename": "Droid", "id": 1, "sensorColor": "red" }
}
```


**Additional context**
I have an incoming PR that seems to fix this issue while still passing the tests for #922. Looks like it should be as simple as using the `concrete_type_name` when invoking `instance.resolve_into_type_async`. 



Discussion / hints:

Fix patch:
diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md
index 990099bb6..a95a471b4 100644
--- a/juniper/CHANGELOG.md
+++ b/juniper/CHANGELOG.md
@@ -1,6 +1,6 @@
 # master
 
-- No changes yet
+- Fix panic on spreading untyped union fragments ([#945](https://github.com/graphql-rust/juniper/issues/945))
 
 # [[0.15.6] 2021-06-07](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.6)
 
diff --git a/juniper/src/types/async_await.rs b/juniper/src/types/async_await.rs
index 4fd16aad7..ca253c1a5 100644
--- a/juniper/src/types/async_await.rs
+++ b/juniper/src/types/async_await.rs
@@ -313,7 +313,7 @@ where
                     let sub_result = instance
                         .resolve_into_type_async(
                             info,
-                            fragment.type_condition.item,
+                            &concrete_type_name,
                             Some(&fragment.selection_set[..]),
                             &sub_exec,
                         )
diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs
index 911b561aa..2102925ab 100644
--- a/juniper/src/types/base.rs
+++ b/juniper/src/types/base.rs
@@ -521,7 +521,7 @@ where
                 {
                     let sub_result = instance.resolve_into_type(
                         info,
-                        fragment.type_condition.item,
+                        &concrete_type_name,
                         Some(&fragment.selection_set[..]),
                         &sub_exec,
                     );
diff --git a/juniper_rocket_async/src/lib.rs b/juniper_rocket_async/src/lib.rs
index ee5573dd4..4d2ab9b1e 100644
--- a/juniper_rocket_async/src/lib.rs
+++ b/juniper_rocket_async/src/lib.rs
@@ -322,7 +322,10 @@ where
 {
     type Error = String;
 
-    async fn from_data(req: &'r Request<'_>, data: Data) -> data::Outcome<Self, Self::Error> {
+    async fn from_data(
+        req: &'r Request<'_>,
+        data: Data<'r>,
+    ) -> data::Outcome<'r, Self, Self::Error> {
         use rocket::tokio::io::AsyncReadExt as _;
 
         let content_type = req


Test patch:
diff --git a/integration_tests/juniper_tests/src/issue_945.rs b/integration_tests/juniper_tests/src/issue_945.rs
new file mode 100644
index 000000000..763fcd69a
--- /dev/null
+++ b/integration_tests/juniper_tests/src/issue_945.rs
@@ -0,0 +1,95 @@
+use juniper::*;
+
+struct Query;
+
+#[graphql_object]
+impl Query {
+    fn artoo() -> Character {
+        Character::Droid(Droid {
+            id: 1,
+            name: "R2-D2".to_owned(),
+            sensor_color: "red".to_owned(),
+        })
+    }
+}
+
+#[derive(GraphQLUnion)]
+enum Character {
+    Droid(Droid),
+    #[allow(dead_code)]
+    Human(Human),
+}
+
+#[derive(GraphQLObject)]
+struct Human {
+    pub id: i32,
+    pub name: String,
+    pub eye_color: String,
+}
+
+#[derive(GraphQLObject)]
+struct Droid {
+    pub id: i32,
+    pub name: String,
+    pub sensor_color: String,
+}
+
+type Schema = RootNode<'static, Query, EmptyMutation<()>, EmptySubscription<()>>;
+
+#[tokio::test]
+async fn test_fragment_on_interface() {
+    let query = r#"
+        query Query {
+            artoo {
+                ...CharacterFragment
+            }
+        }
+
+        fragment CharacterFragment on Character {
+            __typename
+            ... on Human {
+                id
+                eyeColor
+            }
+            ... on Droid {
+                id
+                sensorColor
+            }
+        }
+    "#;
+
+    let (res, errors) = execute(
+        query,
+        None,
+        &Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()),
+        &Variables::new(),
+        &(),
+    )
+    .await
+    .unwrap();
+
+    assert_eq!(errors.len(), 0);
+    assert_eq!(
+        res,
+        graphql_value!({
+            "artoo": {"__typename": "Droid", "id": 1, "sensorColor": "red"}
+        }),
+    );
+
+    let (res, errors) = execute_sync(
+        query,
+        None,
+        &Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()),
+        &Variables::new(),
+        &(),
+    )
+    .unwrap();
+
+    assert_eq!(errors.len(), 0);
+    assert_eq!(
+        res,
+        graphql_value!({
+            "artoo": {"__typename": "Droid", "id": 1, "sensorColor": "red"}
+        }),
+    );
+}
diff --git a/integration_tests/juniper_tests/src/lib.rs b/integration_tests/juniper_tests/src/lib.rs
index 0da4dad4d..5592c1464 100644
--- a/integration_tests/juniper_tests/src/lib.rs
+++ b/integration_tests/juniper_tests/src/lib.rs
@@ -25,4 +25,6 @@ mod issue_922;
 #[cfg(test)]
 mod issue_925;
 #[cfg(test)]
+mod issue_945;
+#[cfg(test)]
 mod pre_parse;