Use fully qualified paths in generated code (#1195)

If user code has a type alias (or custom type) called `Result` or
`Option` etc, this would be used instead of the intended standard
library types causing surprising compile errors from generated code.

Using the fully qualified path allows the generated code to be isolated
from user types.

Includes two basic regression tests covering `Result` and `Send`.

Fixes #1194
This commit is contained in:
Peter Holloway 2023-10-06 19:59:00 +01:00 committed by GitHub
parent 9849736582
commit 801820a3b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 150 additions and 118 deletions

View file

@ -102,12 +102,12 @@ impl Directive {
impl ToTokens for Directive {
fn to_tokens(&self, into: &mut TokenStream) {
let reason = self
.reason
.as_ref()
.map_or_else(|| quote! { None }, |text| quote! { Some(#text) });
let reason = self.reason.as_ref().map_or_else(
|| quote! { ::core::option::Option::None },
|text| quote! { ::core::option::Option::Some(#text) },
);
quote! {
.deprecated(::std::option::Option::#reason)
.deprecated(#reason)
}
.to_tokens(into);
}

View file

@ -335,13 +335,13 @@ impl OnMethod {
::juniper::IntoFieldError::<#scalar>::into_field_error(e)
.map_message(|m| format!(#err_text, m))
})
}, Ok))
}, ::core::result::Result::Ok))
};
if for_async {
quote! {
match #arg {
Ok(v) => v,
Err(e) => return Box::pin(async { Err(e) }),
::core::result::Result::Ok(v) => v,
::core::result::Result::Err(e) => return ::std::boxed::Box::pin(async { ::core::result::Result::Err(e) }),
}
}
} else {

View file

@ -227,7 +227,7 @@ impl Definition {
ty_name: &str,
) -> TokenStream {
quote! {
return Err(::juniper::FieldError::from(::std::format!(
return ::core::result::Result::Err(::juniper::FieldError::from(::std::format!(
"Field `{}` not found on type `{}`",
field,
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
@ -354,18 +354,18 @@ impl Definition {
async move {
let ex = executor.as_executor();
match res2 {
Ok(Some((ctx, r))) => {
::core::result::Result::Ok(::core::option::Option::Some((ctx, r))) => {
let sub = ex.replaced_context(ctx);
sub.resolve_with_ctx_async(&(), &r)
.await
.map_err(|e| ex.new_error(e))
}
Ok(None) => Ok(::juniper::Value::null()),
Err(e) => Err(ex.new_error(e)),
::core::result::Result::Ok(::core::option::Option::None) => ::core::result::Result::Ok(::juniper::Value::null()),
::core::result::Result::Err(e) => ::core::result::Result::Err(ex.new_error(e)),
}
}
});
Ok(::juniper::Value::Scalar::<
::core::result::Result::Ok(::juniper::Value::Scalar::<
::juniper::ValuesStream::<#scalar>
>(::juniper::futures::StreamExt::boxed(stream)))
})

View file

@ -13,8 +13,8 @@ pub(crate) fn sync_resolving_code() -> TokenStream {
quote! {
::juniper::IntoResolvable::into_resolvable(res, executor.context())
.and_then(|res| match res {
Some((ctx, r)) => executor.replaced_context(ctx).resolve_with_ctx(info, &r),
None => Ok(::juniper::Value::null()),
::core::option::Option::Some((ctx, r)) => executor.replaced_context(ctx).resolve_with_ctx(info, &r),
::core::option::Option::None => ::core::result::Result::Ok(::juniper::Value::null()),
})
}
}
@ -34,13 +34,13 @@ pub(crate) fn async_resolving_code(ty: Option<&syn::Type>) -> TokenStream {
let ty = ty.map(|t| quote! { : #t });
quote! {
Box::pin(::juniper::futures::FutureExt::then(fut, move |res #ty| async move {
::std::boxed::Box::pin(::juniper::futures::FutureExt::then(fut, move |res #ty| async move {
match ::juniper::IntoResolvable::into_resolvable(res, executor.context())? {
Some((ctx, r)) => {
::core::option::Option::Some((ctx, r)) => {
let subexec = executor.replaced_context(ctx);
subexec.resolve_with_ctx_async(info, &r).await
},
None => Ok(::juniper::Value::null()),
::core::option::Option::None => ::core::result::Result::Ok(::juniper::Value::null()),
}
}))
}

View file

@ -450,8 +450,8 @@ impl Definition {
for #ident #ty_generics
#where_clause
{
fn name(_ : &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_ : &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::core::option::Option::Some(#name)
}
fn meta<'r>(
@ -489,13 +489,13 @@ impl Definition {
let name = &v.name;
quote! {
Self::#ident => Ok(::juniper::Value::scalar(String::from(#name))),
Self::#ident => ::core::result::Result::Ok(::juniper::Value::scalar(::std::string::String::from(#name))),
}
});
let ignored = self.has_ignored_variants.then(|| {
quote! {
_ => Err(::juniper::FieldError::<#scalar>::from(
_ => ::core::result::Result::Err(::juniper::FieldError::<#scalar>::from(
"Cannot resolve ignored enum variant",
)),
}
@ -509,14 +509,14 @@ impl Definition {
type Context = #context;
type TypeInfo = ();
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> ::core::option::Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
fn resolve(
&self,
_: &(),
_: Option<&[::juniper::Selection<#scalar>]>,
_: ::core::option::Option<&[::juniper::Selection<#scalar>]>,
_: &::juniper::Executor<Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
match self {
@ -549,11 +549,11 @@ impl Definition {
fn resolve_async<'__a>(
&'__a self,
info: &'__a Self::TypeInfo,
selection_set: Option<&'__a [::juniper::Selection<#scalar>]>,
selection_set: ::core::option::Option<&'__a [::juniper::Selection<#scalar>]>,
executor: &'__a ::juniper::Executor<Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'__a, ::juniper::ExecutionResult<#scalar>> {
let v = ::juniper::GraphQLValue::resolve(self, info, selection_set, executor);
Box::pin(::juniper::futures::future::ready(v))
::std::boxed::Box::pin(::juniper::futures::future::ready(v))
}
}
}
@ -577,7 +577,7 @@ impl Definition {
let name = &v.name;
quote! {
Some(#name) => Ok(Self::#ident),
::core::option::Option::Some(#name) => ::core::result::Result::Ok(Self::#ident),
}
});
@ -588,10 +588,10 @@ impl Definition {
{
type Error = ::std::string::String;
fn from_input_value(v: &::juniper::InputValue<#scalar>) -> Result<Self, Self::Error> {
fn from_input_value(v: &::juniper::InputValue<#scalar>) -> ::core::result::Result<Self, Self::Error> {
match v.as_enum_value().or_else(|| v.as_string_value()) {
#( #variants )*
_ => Err(::std::format!("Unknown enum value: {}", v)),
_ => ::core::result::Result::Err(::std::format!("Unknown enum value: {}", v)),
}
}
}
@ -617,14 +617,14 @@ impl Definition {
quote! {
#ident::#var_ident => ::juniper::InputValue::<#scalar>::scalar(
String::from(#name),
::std::string::String::from(#name),
),
}
});
let ignored = self.has_ignored_variants.then(|| {
quote! {
_ => panic!("Cannot resolve ignored enum variant"),
_ => ::core::panic!("Cannot resolve ignored enum variant"),
}
});
@ -730,13 +730,13 @@ impl Definition {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });
if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}

View file

@ -479,8 +479,8 @@ impl Definition {
for #ident #ty_generics
#where_clause
{
fn name(_: &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_: &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::core::option::Option::Some(#name)
}
fn meta<'r>(
@ -524,7 +524,7 @@ impl Definition {
type Context = #context;
type TypeInfo = ();
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> ::core::option::Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
}
@ -594,11 +594,11 @@ impl Definition {
quote! {
match obj.get(#name) {
Some(v) => {
::core::option::Option::Some(v) => {
::juniper::FromInputValue::<#scalar>::from_input_value(v)
.map_err(::juniper::IntoFieldError::into_field_error)?
}
None => { #fallback }
::core::option::Option::None => { #fallback }
}
}
};
@ -616,14 +616,14 @@ impl Definition {
fn from_input_value(
value: &::juniper::InputValue<#scalar>,
) -> Result<Self, Self::Error> {
) -> ::core::result::Result<Self, Self::Error> {
let obj = value
.to_object_value()
.ok_or_else(|| ::juniper::FieldError::<#scalar>::from(
::std::format!("Expected input object, found: {}", value))
)?;
Ok(#ident {
::core::result::Result::Ok(#ident {
#( #fields )*
})
}
@ -763,13 +763,13 @@ impl Definition {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });
if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}

View file

@ -460,7 +460,7 @@ impl Definition {
syn::GenericParam::Const(_) => return None,
};
Some(quote! {
::std::marker::PhantomData<::std::sync::atomic::AtomicPtr<Box<#ty>>>
::core::marker::PhantomData<::std::sync::atomic::AtomicPtr<std::boxed::Box<#ty>>>
})
});
quote! { __Phantom(#(#phantom_params),*) }
@ -487,7 +487,7 @@ impl Definition {
quote! {
#[automatically_derived]
#[derive(Clone, Copy, Debug)]
#[derive(::std::clone::Clone, ::core::marker::Copy, ::std::fmt::Debug)]
#[doc = #enum_doc]
#vis enum #enum_ident #enum_gens {
#( #[doc(hidden)] #variants_idents(#variant_gens_pars), )*
@ -523,12 +523,12 @@ impl Definition {
quote! {{
const SUPPRESS_DEAD_CODE: () = {
let none = Option::<#ident #const_gens>::None;
let none = ::core::option::Option::<#ident #const_gens>::None;
match none {
Some(unreachable) => {
::core::option::Option::Some(unreachable) => {
#( let _ = unreachable.#fields; )*
}
None => {}
::core::option::Option::None => {}
}
};
let _ = SUPPRESS_DEAD_CODE;
@ -715,8 +715,8 @@ impl Definition {
for #ty #ty_generics
#where_clause
{
fn name(_ : &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_ : &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::std::option::Option::Some(#name)
}
fn meta<'r>(
@ -784,14 +784,14 @@ impl Definition {
type Context = #context;
type TypeInfo = ();
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> std::option::Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
fn resolve_field(
&self,
info: &Self::TypeInfo,
field: &str,
field: &::core::primitive::str,
args: &::juniper::Arguments<'_, #scalar>,
executor: &::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
@ -805,15 +805,15 @@ impl Definition {
&self,
context: &Self::Context,
info: &Self::TypeInfo,
) -> String {
) -> ::std::string::String {
#downcast_check
}
fn resolve_into_type(
&self,
info: &Self::TypeInfo,
type_name: &str,
_: Option<&[::juniper::Selection<'_, #scalar>]>,
type_name: &::core::primitive::str,
_: ::core::option::Option<&[::juniper::Selection<'_, #scalar>]>,
executor: &::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
#downcast
@ -862,21 +862,21 @@ impl Definition {
fn resolve_field_async<'b>(
&'b self,
info: &'b Self::TypeInfo,
field: &'b str,
field: &'b ::core::primitive::str,
args: &'b ::juniper::Arguments<'_, #scalar>,
executor: &'b ::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'b, ::juniper::ExecutionResult<#scalar>> {
match field {
#( #fields_resolvers )*
_ => Box::pin(async move { #no_field_err }),
_ => ::std::boxed::Box::pin(async move { #no_field_err }),
}
}
fn resolve_into_type_async<'b>(
&'b self,
info: &'b Self::TypeInfo,
type_name: &str,
_: Option<&'b [::juniper::Selection<'b, #scalar>]>,
type_name: &::core::primitive::str,
_: ::core::option::Option<&'b [::juniper::Selection<'b, #scalar>]>,
executor: &'b ::juniper::Executor<'b, 'b, Self::Context, #scalar>
) -> ::juniper::BoxFuture<'b, ::juniper::ExecutionResult<#scalar>> {
#downcast
@ -1360,13 +1360,13 @@ impl Definition {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });
if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}

View file

@ -310,13 +310,13 @@ impl<Operation: ?Sized + 'static> Definition<Operation> {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });
if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}
@ -457,8 +457,8 @@ impl<Operation: ?Sized + 'static> Definition<Operation> {
#[automatically_derived]
impl #impl_generics ::juniper::GraphQLType<#scalar> for #ty #where_clause
{
fn name(_ : &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_ : &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::core::option::Option::Some(#name)
}
fn meta<'r>(
@ -783,14 +783,14 @@ impl Definition<Query> {
type Context = #context;
type TypeInfo = ();
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> ::core::option::Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
fn resolve_field(
&self,
info: &Self::TypeInfo,
field: &str,
field: &::core::primitive::str,
args: &::juniper::Arguments<'_, #scalar>,
executor: &::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
@ -804,7 +804,7 @@ impl Definition<Query> {
&self,
_: &Self::Context,
_: &Self::TypeInfo,
) -> String {
) -> ::std::string::String {
#name.into()
}
}
@ -847,13 +847,13 @@ impl Definition<Query> {
fn resolve_field_async<'b>(
&'b self,
info: &'b Self::TypeInfo,
field: &'b str,
field: &'b ::core::primitive::str,
args: &'b ::juniper::Arguments<'_, #scalar>,
executor: &'b ::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'b, ::juniper::ExecutionResult<#scalar>> {
match field {
#( #fields_resolvers )*
_ => Box::pin(async move { #no_field_err }),
_ => ::std::boxed::Box::pin(async move { #no_field_err }),
}
}
}

View file

@ -375,8 +375,8 @@ impl Definition {
impl #impl_gens ::juniper::GraphQLType<#scalar> for #ty
#where_clause
{
fn name(_: &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_: &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::core::option::Option::Some(#name)
}
fn meta<'r>(
@ -416,14 +416,14 @@ impl Definition {
type Context = ();
type TypeInfo = ();
fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> {
fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> ::core::option::Option<&'i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
fn resolve(
&self,
info: &(),
selection: Option<&[::juniper::Selection<'_, #scalar>]>,
selection: ::core::option::Option<&[::juniper::Selection<'_, #scalar>]>,
executor: &::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
#resolve
@ -451,12 +451,12 @@ impl Definition {
fn resolve_async<'b>(
&'b self,
info: &'b Self::TypeInfo,
selection_set: Option<&'b [::juniper::Selection<'_, #scalar>]>,
selection_set: ::core::option::Option<&'b [::juniper::Selection<'_, #scalar>]>,
executor: &'b ::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'b, ::juniper::ExecutionResult<#scalar>> {
use ::juniper::futures::future;
let v = ::juniper::GraphQLValue::resolve(self, info, selection_set, executor);
Box::pin(future::ready(v))
::std::boxed::Box::pin(future::ready(v))
}
}
}
@ -507,7 +507,7 @@ impl Definition {
{
type Error = ::juniper::executor::FieldError<#scalar>;
fn from_input_value(input: &::juniper::InputValue<#scalar>) -> Result<Self, Self::Error> {
fn from_input_value(input: &::juniper::InputValue<#scalar>) -> ::core::result::Result<Self, Self::Error> {
#from_input_value
.map_err(::juniper::executor::IntoFieldError::<#scalar>::into_field_error)
}
@ -646,13 +646,13 @@ impl Definition {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });
if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}
@ -720,7 +720,7 @@ impl Methods {
to_output: Some(to_output),
..
} => {
quote! { Ok(#to_output(self)) }
quote! { ::core::result::Result::Ok(#to_output(self)) }
}
Self::Delegated { field, .. } => {
quote! {

View file

@ -49,18 +49,18 @@ impl Definition<Subscription> {
type Context = #context;
type TypeInfo = ();
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> ::core::option::Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
fn resolve_field(
&self,
_: &Self::TypeInfo,
_: &str,
_: &::core::primitive::str,
_: &::juniper::Arguments<'_, #scalar>,
_: &::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
Err(::juniper::FieldError::from(
::core::result::Result::Err(::juniper::FieldError::from(
"Called `resolve_field` on subscription object",
))
}
@ -69,7 +69,7 @@ impl Definition<Subscription> {
&self,
_: &Self::Context,
_: &Self::TypeInfo,
) -> String {
) -> ::std::string::String {
#name.into()
}
}
@ -94,7 +94,7 @@ impl Definition<Subscription> {
.as_mut()
.unwrap()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
let ty = &self.ty;
let ty_name = ty.to_token_stream().to_string();
@ -116,7 +116,7 @@ impl Definition<Subscription> {
>(
&'s self,
info: &'i Self::TypeInfo,
field: &'fi str,
field: &'fi ::core::primitive::str,
args: ::juniper::Arguments<'args, #scalar>,
executor: &'ref_e ::juniper::Executor<'ref_e, 'e, Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'f, std::result::Result<
@ -134,7 +134,7 @@ impl Definition<Subscription> {
{
match field {
#( #fields_resolvers )*
_ => Box::pin(async move { #no_field_err }),
_ => ::std::boxed::Box::pin(async move { #no_field_err }),
}
}
}

View file

@ -151,7 +151,7 @@ fn parse_variant_from_enum_variant(
}
} else {
parse_quote! {
match self { #enum_ident::#var_ident(ref v) => Some(v), _ => None, }
match self { #enum_ident::#var_ident(ref v) => ::core::option::Option::Some(v), _ => ::core::option::Option::None, }
}
};

View file

@ -338,7 +338,8 @@ impl Definition {
let mut ty_full = quote! { #ty #ty_generics };
if self.is_trait_object {
ty_full = quote! { dyn #ty_full + '__obj + Send + Sync };
ty_full =
quote! { dyn #ty_full + '__obj + ::core::marker::Send + ::core::marker::Sync };
}
let mut generics = self.generics.clone();
@ -382,13 +383,13 @@ impl Definition {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });
if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}
@ -472,8 +473,8 @@ impl Definition {
#[automatically_derived]
impl #impl_generics ::juniper::GraphQLType<#scalar> for #ty_full #where_clause
{
fn name(_ : &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_ : &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::core::option::Option::Some(#name)
}
fn meta<'r>(
@ -524,7 +525,7 @@ impl Definition {
type Context = #context;
type TypeInfo = ();
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
@ -532,7 +533,7 @@ impl Definition {
&self,
context: &Self::Context,
info: &Self::TypeInfo,
) -> String {
) -> ::std::string::String {
#( #match_variant_names )*
::std::panic!(
"GraphQL union `{}` cannot be resolved into any of its \
@ -544,13 +545,13 @@ impl Definition {
fn resolve_into_type(
&self,
info: &Self::TypeInfo,
type_name: &str,
_: Option<&[::juniper::Selection<'_, #scalar>]>,
type_name: &::core::primitive::str,
_: ::core::option::Option<&[::juniper::Selection<'_, #scalar>]>,
executor: &::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
let context = executor.context();
#( #variant_resolvers )*
return Err(::juniper::FieldError::from(::std::format!(
return ::core::result::Result::Err(::juniper::FieldError::from(::std::format!(
"Concrete type `{}` is not handled by instance \
resolvers on GraphQL union `{}`",
type_name, #name,
@ -586,8 +587,8 @@ impl Definition {
fn resolve_into_type_async<'b>(
&'b self,
info: &'b Self::TypeInfo,
type_name: &str,
_: Option<&'b [::juniper::Selection<'b, #scalar>]>,
type_name: &::core::primitive::str,
_: ::core::option::Option<&'b [::juniper::Selection<'b, #scalar>]>,
executor: &'b ::juniper::Executor<'b, 'b, Self::Context, #scalar>
) -> ::juniper::BoxFuture<'b, ::juniper::ExecutionResult<#scalar>> {
let context = executor.context();
@ -735,13 +736,13 @@ impl VariantDefinition {
quote! {
match <#ty as ::juniper::GraphQLType<#scalar>>::name(info) {
Some(name) => {
::core::option::Option::Some(name) => {
if type_name == name {
let fut = ::juniper::futures::future::ready({ #expr });
return #resolving_code;
}
}
None => return ::juniper::macros::helper::err_unnamed_type_fut(#ty_name),
::core::option::Option::None => return ::juniper::macros::helper::err_unnamed_type_fut(#ty_name),
}
}
}

View file

@ -250,46 +250,46 @@ impl Definition {
let methods = [
(
Method::AsInt,
quote! { fn as_int(&self) -> Option<i32> },
quote! { i32::from(*v) },
quote! { fn as_int(&self) -> ::core::option::Option<::core::primitive::i32> },
quote! { ::core::primitive::i32::from(*v) },
),
(
Method::AsFloat,
quote! { fn as_float(&self) -> Option<f64> },
quote! { f64::from(*v) },
quote! { fn as_float(&self) -> ::core::option::Option<::core::primitive::f64> },
quote! { ::core::primitive::f64::from(*v) },
),
(
Method::AsStr,
quote! { fn as_str(&self) -> Option<&str> },
quote! { fn as_str(&self) -> ::core::option::Option<&::core::primitive::str> },
quote! { ::std::convert::AsRef::as_ref(v) },
),
(
Method::AsString,
quote! { fn as_string(&self) -> Option<String> },
quote! { fn as_string(&self) -> ::core::option::Option<::std::string::String> },
quote! { ::std::string::ToString::to_string(v) },
),
(
Method::IntoString,
quote! { fn into_string(self) -> Option<String> },
quote! { fn into_string(self) -> ::core::option::Option<::std::string::String> },
quote! { ::std::string::String::from(v) },
),
(
Method::AsBool,
quote! { fn as_bool(&self) -> Option<bool> },
quote! { bool::from(*v) },
quote! { fn as_bool(&self) -> ::core::option::Option<::core::primitive::bool> },
quote! { ::core::primitive::bool::from(*v) },
),
];
let methods = methods.iter().map(|(m, sig, def)| {
let arms = self.methods.get(m).into_iter().flatten().map(|v| {
let arm = v.match_arm();
let call = v.expr.as_ref().map_or(def.clone(), |f| quote! { #f(v) });
quote! { #arm => Some(#call), }
quote! { #arm => ::core::option::Option::Some(#call), }
});
quote! {
#sig {
match self {
#(#arms)*
_ => None,
_ => ::core::option::Option::None,
}
}
}
@ -341,28 +341,28 @@ impl Definition {
}
#[automatically_derived]
impl #impl_gen ::std::convert::From<#ty_ident #ty_gen> for Option<#var_ty>
impl #impl_gen ::std::convert::From<#ty_ident #ty_gen> for ::core::option::Option<#var_ty>
#where_clause
{
fn from(ty: #ty_ident #ty_gen) -> Self {
if let #ty_ident::#var_ident #var_field = ty {
Some(v)
::core::option::Option::Some(v)
} else {
None
::core::option::Option::None
}
}
}
#[automatically_derived]
impl #lf_impl_gen ::std::convert::From<&'___a #ty_ident #ty_gen> for
Option<&'___a #var_ty>
::core::option::Option<&'___a #var_ty>
#where_clause
{
fn from(ty: &'___a #ty_ident #ty_gen) -> Self {
if let #ty_ident::#var_ident #var_field = ty {
Some(v)
::core::option::Option::Some(v)
} else {
None
::core::option::Option::None
}
}
}

View file

@ -0,0 +1,12 @@
// Local types overriding the stdlib Result should not affect generated code
type Result<T> = std::result::Result<T, ()>;
#[derive(juniper::GraphQLInputObject)]
#[graphql(name = "UserInformation")]
pub struct Update {
pub email: Option<String>,
pub username: Option<String>,
}
pub fn main() {}

View file

@ -0,0 +1,12 @@
// Local types overriding the stdlib Send should not affect generated code
trait Send {}
#[derive(juniper::GraphQLInputObject)]
#[graphql(name = "UserInformation")]
pub struct Update {
pub email: Option<String>,
pub username: Option<String>,
}
pub fn main() {}

View file

@ -7,3 +7,10 @@ fn test_failing_compilation() {
let t = trybuild::TestCases::new();
t.compile_fail("fail/**/*.rs");
}
#[rustversion::nightly]
#[test]
fn test_passing_compilation() {
let t = trybuild::TestCases::new();
t.pass("pass/**/*.rs");
}