From 801820a3b67389ee567f0c540a4d6a8a3b8d9fbc Mon Sep 17 00:00:00 2001
From: Peter Holloway <holloway.p.r@gmail.com>
Date: Fri, 6 Oct 2023 19:59:00 +0100
Subject: [PATCH] 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
---
 juniper_codegen/src/common/deprecation.rs     | 10 +++---
 juniper_codegen/src/common/field/arg.rs       |  6 ++--
 juniper_codegen/src/common/field/mod.rs       | 10 +++---
 juniper_codegen/src/common/gen.rs             | 10 +++---
 juniper_codegen/src/graphql_enum/mod.rs       | 30 ++++++++--------
 .../src/graphql_input_object/mod.rs           | 18 +++++-----
 juniper_codegen/src/graphql_interface/mod.rs  | 36 +++++++++----------
 juniper_codegen/src/graphql_object/mod.rs     | 18 +++++-----
 juniper_codegen/src/graphql_scalar/mod.rs     | 20 +++++------
 .../src/graphql_subscription/mod.rs           | 14 ++++----
 juniper_codegen/src/graphql_union/derive.rs   |  2 +-
 juniper_codegen/src/graphql_union/mod.rs      | 29 +++++++--------
 juniper_codegen/src/scalar_value/mod.rs       | 34 +++++++++---------
 tests/codegen/pass/local_results.rs           | 12 +++++++
 tests/codegen/pass/local_send.rs              | 12 +++++++
 tests/codegen/src/lib.rs                      |  7 ++++
 16 files changed, 150 insertions(+), 118 deletions(-)
 create mode 100644 tests/codegen/pass/local_results.rs
 create mode 100644 tests/codegen/pass/local_send.rs

diff --git a/juniper_codegen/src/common/deprecation.rs b/juniper_codegen/src/common/deprecation.rs
index 9efd6ef0..51eed825 100644
--- a/juniper_codegen/src/common/deprecation.rs
+++ b/juniper_codegen/src/common/deprecation.rs
@@ -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);
     }
diff --git a/juniper_codegen/src/common/field/arg.rs b/juniper_codegen/src/common/field/arg.rs
index afbe53ed..b425eb19 100644
--- a/juniper_codegen/src/common/field/arg.rs
+++ b/juniper_codegen/src/common/field/arg.rs
@@ -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 {
diff --git a/juniper_codegen/src/common/field/mod.rs b/juniper_codegen/src/common/field/mod.rs
index 8e8cd297..dedcd1bc 100644
--- a/juniper_codegen/src/common/field/mod.rs
+++ b/juniper_codegen/src/common/field/mod.rs
@@ -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)))
                 })
diff --git a/juniper_codegen/src/common/gen.rs b/juniper_codegen/src/common/gen.rs
index a0b5e731..d4080772 100644
--- a/juniper_codegen/src/common/gen.rs
+++ b/juniper_codegen/src/common/gen.rs
@@ -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()),
             }
         }))
     }
diff --git a/juniper_codegen/src/graphql_enum/mod.rs b/juniper_codegen/src/graphql_enum/mod.rs
index c14356f6..d6f30c10 100644
--- a/juniper_codegen/src/graphql_enum/mod.rs
+++ b/juniper_codegen/src/graphql_enum/mod.rs
@@ -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 });
             }
         }
 
diff --git a/juniper_codegen/src/graphql_input_object/mod.rs b/juniper_codegen/src/graphql_input_object/mod.rs
index 93c21d6f..9d3c3ad2 100644
--- a/juniper_codegen/src/graphql_input_object/mod.rs
+++ b/juniper_codegen/src/graphql_input_object/mod.rs
@@ -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 });
             }
         }
 
diff --git a/juniper_codegen/src/graphql_interface/mod.rs b/juniper_codegen/src/graphql_interface/mod.rs
index afb856e1..9a1ec21c 100644
--- a/juniper_codegen/src/graphql_interface/mod.rs
+++ b/juniper_codegen/src/graphql_interface/mod.rs
@@ -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 });
             }
         }
 
diff --git a/juniper_codegen/src/graphql_object/mod.rs b/juniper_codegen/src/graphql_object/mod.rs
index facc7300..8d772561 100644
--- a/juniper_codegen/src/graphql_object/mod.rs
+++ b/juniper_codegen/src/graphql_object/mod.rs
@@ -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 }),
                     }
                 }
             }
diff --git a/juniper_codegen/src/graphql_scalar/mod.rs b/juniper_codegen/src/graphql_scalar/mod.rs
index 2280d9c2..ae4d5377 100644
--- a/juniper_codegen/src/graphql_scalar/mod.rs
+++ b/juniper_codegen/src/graphql_scalar/mod.rs
@@ -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! {
diff --git a/juniper_codegen/src/graphql_subscription/mod.rs b/juniper_codegen/src/graphql_subscription/mod.rs
index c8d2fb42..37b99d86 100644
--- a/juniper_codegen/src/graphql_subscription/mod.rs
+++ b/juniper_codegen/src/graphql_subscription/mod.rs
@@ -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 }),
                     }
                 }
             }
diff --git a/juniper_codegen/src/graphql_union/derive.rs b/juniper_codegen/src/graphql_union/derive.rs
index a10be60c..c4bbaf6d 100644
--- a/juniper_codegen/src/graphql_union/derive.rs
+++ b/juniper_codegen/src/graphql_union/derive.rs
@@ -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, }
         }
     };
 
diff --git a/juniper_codegen/src/graphql_union/mod.rs b/juniper_codegen/src/graphql_union/mod.rs
index fa585b00..4ff361c8 100644
--- a/juniper_codegen/src/graphql_union/mod.rs
+++ b/juniper_codegen/src/graphql_union/mod.rs
@@ -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),
             }
         }
     }
diff --git a/juniper_codegen/src/scalar_value/mod.rs b/juniper_codegen/src/scalar_value/mod.rs
index e0a0d78b..97294df9 100644
--- a/juniper_codegen/src/scalar_value/mod.rs
+++ b/juniper_codegen/src/scalar_value/mod.rs
@@ -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
                             }
                         }
                     }
diff --git a/tests/codegen/pass/local_results.rs b/tests/codegen/pass/local_results.rs
new file mode 100644
index 00000000..ab3026ec
--- /dev/null
+++ b/tests/codegen/pass/local_results.rs
@@ -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() {}
diff --git a/tests/codegen/pass/local_send.rs b/tests/codegen/pass/local_send.rs
new file mode 100644
index 00000000..2d07b2d0
--- /dev/null
+++ b/tests/codegen/pass/local_send.rs
@@ -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() {}
diff --git a/tests/codegen/src/lib.rs b/tests/codegen/src/lib.rs
index abdcf203..f497321a 100644
--- a/tests/codegen/src/lib.rs
+++ b/tests/codegen/src/lib.rs
@@ -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");
+}