From ba1ed85b3c3dd77fbae7baf6bc4e693321a94083 Mon Sep 17 00:00:00 2001
From: tyranron <tyranron@gmail.com>
Date: Tue, 19 Apr 2022 16:33:10 +0300
Subject: [PATCH] Relax object safety requirement for `GraphQLValue` and
 `GraphQLValueAsync` traits

---
 juniper/CHANGELOG.md                      |  2 ++
 juniper/src/lib.rs                        |  9 ++---
 juniper/src/macros/helper/mod.rs          | 31 +-----------------
 juniper/src/types/async_await.rs          |  8 -----
 juniper/src/types/base.rs                 |  8 -----
 juniper_codegen/src/graphql_object/mod.rs | 40 -----------------------
 6 files changed, 6 insertions(+), 92 deletions(-)

diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md
index 149b7e15..f280e865 100644
--- a/juniper/CHANGELOG.md
+++ b/juniper/CHANGELOG.md
@@ -59,6 +59,7 @@ All user visible changes to `juniper` crate will be documented in this file. Thi
 ### Changed
 
 - Made `GraphQLRequest` fields public. ([#750])
+- Relaxed [object safety] requirement for `GraphQLValue` and `GraphQLValueAsync` traits. ([rev])
 
 ## Fixed
 
@@ -109,5 +110,6 @@ See [old CHANGELOG](/../../blob/juniper-v0.15.9/juniper/CHANGELOG.md).
 [Cargo feature]: https://doc.rust-lang.org/cargo/reference/features.html
 [graphql-scalars.dev]: https://graphql-scalars.dev
 [October 2021]: https://spec.graphql.org/October2021
+[object safety]: https://doc.rust-lang.org/reference/items/traits.html#object-safety
 [orphan rules]: https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
 [Semantic Versioning 2.0.0]: https://semver.org
diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs
index d864cd10..0373175e 100644
--- a/juniper/src/lib.rs
+++ b/juniper/src/lib.rs
@@ -71,18 +71,15 @@ pub use crate::{
         LookAheadSelection, LookAheadValue, OwnedExecutor, Registry, ValuesStream, Variables,
     },
     introspection::IntrospectionFormat,
-    macros::helper::{
-        subscription::{ExtractTypeFromStream, IntoFieldResult},
-        AsDynGraphQLValue,
-    },
+    macros::helper::subscription::{ExtractTypeFromStream, IntoFieldResult},
     parser::{ParseError, ScalarToken, Spanning},
     schema::{
         meta,
         model::{RootNode, SchemaType},
     },
     types::{
-        async_await::{DynGraphQLValueAsync, GraphQLTypeAsync, GraphQLValueAsync},
-        base::{Arguments, DynGraphQLValue, GraphQLType, GraphQLValue, TypeKind},
+        async_await::{GraphQLTypeAsync, GraphQLValueAsync},
+        base::{Arguments, GraphQLType, GraphQLValue, TypeKind},
         marker::{self, GraphQLInterface, GraphQLObject, GraphQLUnion},
         nullable::Nullable,
         scalars::{EmptyMutation, EmptySubscription, ID},
diff --git a/juniper/src/macros/helper/mod.rs b/juniper/src/macros/helper/mod.rs
index 0f81018d..f6565e03 100644
--- a/juniper/src/macros/helper/mod.rs
+++ b/juniper/src/macros/helper/mod.rs
@@ -6,36 +6,7 @@ use std::fmt;
 
 use futures::future::{self, BoxFuture};
 
-use crate::{DefaultScalarValue, DynGraphQLValue, DynGraphQLValueAsync, FieldError, ScalarValue};
-
-/// Conversion of a [`GraphQLValue`] to its [trait object][1].
-///
-/// [`GraphQLValue`]: crate::GraphQLValue
-/// [1]: https://doc.rust-lang.org/reference/types/trait-object.html
-pub trait AsDynGraphQLValue<S: ScalarValue = DefaultScalarValue> {
-    /// Context type of this [`GraphQLValue`].
-    ///
-    /// [`GraphQLValue`]: crate::GraphQLValue
-    type Context;
-
-    /// Schema information type of this [`GraphQLValue`].
-    ///
-    /// [`GraphQLValue`]: crate::GraphQLValue
-    type TypeInfo;
-
-    /// Converts this value to a [`DynGraphQLValue`] [trait object][1].
-    ///
-    /// [1]: https://doc.rust-lang.org/reference/types/trait-object.html
-    fn as_dyn_graphql_value(&self) -> &DynGraphQLValue<S, Self::Context, Self::TypeInfo>;
-
-    /// Converts this value to a [`DynGraphQLValueAsync`] [trait object][1].
-    ///
-    /// [1]: https://doc.rust-lang.org/reference/types/trait-object.html
-    fn as_dyn_graphql_value_async(&self)
-        -> &DynGraphQLValueAsync<S, Self::Context, Self::TypeInfo>;
-}
-
-crate::sa::assert_obj_safe!(AsDynGraphQLValue<Context = (), TypeInfo = ()>);
+use crate::FieldError;
 
 /// This trait is used by [`graphql_scalar!`] macro to retrieve [`Error`] type
 /// from a [`Result`].
diff --git a/juniper/src/types/async_await.rs b/juniper/src/types/async_await.rs
index fdc4a037..e3273275 100644
--- a/juniper/src/types/async_await.rs
+++ b/juniper/src/types/async_await.rs
@@ -111,14 +111,6 @@ where
     }
 }
 
-crate::sa::assert_obj_safe!(GraphQLValueAsync<Context = (), TypeInfo = ()>);
-
-/// Helper alias for naming [trait objects][1] of [`GraphQLValueAsync`].
-///
-/// [1]: https://doc.rust-lang.org/reference/types/trait-object.html
-pub type DynGraphQLValueAsync<S, C, TI> =
-    dyn GraphQLValueAsync<S, Context = C, TypeInfo = TI> + Send + 'static;
-
 /// Extension of [`GraphQLType`] trait with asynchronous queries/mutations resolvers.
 ///
 /// It's automatically implemented for [`GraphQLValueAsync`] and [`GraphQLType`] implementers, so
diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs
index 175be929..d5c9e394 100644
--- a/juniper/src/types/base.rs
+++ b/juniper/src/types/base.rs
@@ -294,14 +294,6 @@ where
     }
 }
 
-crate::sa::assert_obj_safe!(GraphQLValue<Context = (), TypeInfo = ()>);
-
-/// Helper alias for naming [trait objects][1] of [`GraphQLValue`].
-///
-/// [1]: https://doc.rust-lang.org/reference/types/trait-object.html
-pub type DynGraphQLValue<S, C, TI> =
-    dyn GraphQLValue<S, Context = C, TypeInfo = TI> + Send + Sync + 'static;
-
 /// Primary trait used to expose Rust types in a GraphQL schema.
 ///
 /// All of the convenience macros ultimately expand into an implementation of
diff --git a/juniper_codegen/src/graphql_object/mod.rs b/juniper_codegen/src/graphql_object/mod.rs
index 49459737..e29a0425 100644
--- a/juniper_codegen/src/graphql_object/mod.rs
+++ b/juniper_codegen/src/graphql_object/mod.rs
@@ -500,7 +500,6 @@ impl ToTokens for Definition<Query> {
         self.impl_graphql_type_tokens().to_tokens(into);
         self.impl_graphql_value_tokens().to_tokens(into);
         self.impl_graphql_value_async_tokens().to_tokens(into);
-        self.impl_as_dyn_graphql_value_tokens().to_tokens(into);
         self.impl_reflection_traits_tokens().to_tokens(into);
         self.impl_field_meta_tokens().to_tokens(into);
         self.impl_field_tokens().to_tokens(into);
@@ -868,43 +867,4 @@ impl Definition<Query> {
             }
         }
     }
-
-    /// Returns generated code implementing [`AsDynGraphQLValue`] trait for this
-    /// [GraphQL object][1].
-    ///
-    /// [`AsDynGraphQLValue`]: juniper::AsDynGraphQLValue
-    /// [1]: https://spec.graphql.org/June2018/#sec-Objects
-    #[must_use]
-    fn impl_as_dyn_graphql_value_tokens(&self) -> Option<TokenStream> {
-        if self.interfaces.is_empty() {
-            return None;
-        }
-
-        let scalar = &self.scalar;
-
-        let (impl_generics, where_clause) = self.impl_generics(true);
-        let ty = &self.ty;
-
-        Some(quote! {
-            #[allow(non_snake_case)]
-            #[automatically_derived]
-            impl#impl_generics ::juniper::AsDynGraphQLValue<#scalar> for #ty #where_clause
-            {
-                type Context = <Self as ::juniper::GraphQLValue<#scalar>>::Context;
-                type TypeInfo = <Self as ::juniper::GraphQLValue<#scalar>>::TypeInfo;
-
-                fn as_dyn_graphql_value(
-                    &self,
-                ) -> &::juniper::DynGraphQLValue<#scalar, Self::Context, Self::TypeInfo> {
-                    self
-                }
-
-                fn as_dyn_graphql_value_async(
-                    &self,
-                ) -> &::juniper::DynGraphQLValueAsync<#scalar, Self::Context, Self::TypeInfo> {
-                    self
-                }
-            }
-        })
-    }
 }