From 5caea1f90802f123e6ecfdb76f42db54f7cb0a4b Mon Sep 17 00:00:00 2001
From: Magnus Hallin <mhallin@fastmail.com>
Date: Sun, 16 Oct 2016 16:02:40 +0200
Subject: [PATCH] Make FieldResults in field resolvers optional :D

---
 README.md                           |   2 +-
 src/executor.rs                     |  28 ++++++
 src/executor_tests/introspection.rs |  19 ++--
 src/lib.rs                          |  32 ++++---
 src/macros/enums.rs                 |   6 ++
 src/macros/field.rs                 |   2 +-
 src/macros/interface.rs             |  27 +++---
 src/macros/object.rs                |  77 +++++++--------
 src/macros/scalar.rs                |   6 ++
 src/macros/tests/args.rs            |  31 +++---
 src/macros/tests/enums.rs           |  13 ++-
 src/macros/tests/field.rs           |  17 ++--
 src/macros/tests/input_object.rs    |   5 +-
 src/macros/tests/object.rs          |  50 +++++-----
 src/macros/tests/scalar.rs          |   9 +-
 src/schema/schema.rs                | 144 ++++++++++++++--------------
 src/tests/schema.rs                 |  69 +++++++------
 src/types/containers.rs             |  20 +++-
 src/types/pointers.rs               |  14 ++-
 src/types/scalars.rs                |  15 ++-
 20 files changed, 328 insertions(+), 258 deletions(-)

diff --git a/README.md b/README.md
index 385deeae..ad45ff9d 100644
--- a/README.md
+++ b/README.md
@@ -132,7 +132,7 @@ as well.
     * [X] `graphql_input_object!` helper completely missing
     * [X] Add support for deprecating things
     * [X] Custom enum values and descriptions
-    * [ ] Improved syntax for fields that can't fail resolution - make
+    * [X] Improved syntax for fields that can't fail resolution - make
       `FieldResult<T>` optional maybe?
 * [ ] Investigate asynchronous execution - implementing it is not necessary, but
   at least look at what API changes will be needed for us to hook into
diff --git a/src/executor.rs b/src/executor.rs
index 2c0c4c98..ddb6ed50 100644
--- a/src/executor.rs
+++ b/src/executor.rs
@@ -61,6 +61,23 @@ pub type FieldResult<T> = Result<T, String>;
 /// The result of resolving an unspecified field
 pub type ExecutionResult = Result<Value, String>;
 
+/// Convert a value into a successful field result
+///
+/// Used by the helper macros to support both returning a naked value
+/// *and* a `FieldResult` from a field.
+pub trait IntoFieldResult<T>: Sized {
+    /// Wrap `self` in a `Result`
+    ///
+    /// The implementation of this should always be `Ok(self)`.
+    fn into(self) -> FieldResult<T>;
+}
+
+impl<T> IntoFieldResult<T> for FieldResult<T> {
+    fn into(self) -> FieldResult<T> {
+        self
+    }
+}
+
 impl<'a, CtxT> Executor<'a, CtxT> {
     /// Resolve a single arbitrary value into an `ExecutionResult`
     pub fn resolve<T: GraphQLType<CtxT>>(&mut self, value: &T) -> ExecutionResult {
@@ -293,6 +310,17 @@ impl<CtxT> Registry<CtxT> {
         }
     }
 
+    #[doc(hidden)]
+    pub fn field_convert<T: IntoFieldResult<I>, I>(&mut self, name: &str) -> Field where I: GraphQLType<CtxT> {
+        Field {
+            name: name.to_owned(),
+            description: None,
+            arguments: None,
+            field_type: self.get_type::<I>(),
+            deprecation_reason: None,
+        }
+    }
+
     #[doc(hidden)]
     pub fn field_inside_result<T>(&mut self, name: &str, _: FieldResult<T>) -> Field where T: GraphQLType<CtxT> {
         Field {
diff --git a/src/executor_tests/introspection.rs b/src/executor_tests/introspection.rs
index 70058a7a..1d0ad324 100644
--- a/src/executor_tests/introspection.rs
+++ b/src/executor_tests/introspection.rs
@@ -1,6 +1,5 @@
 use std::collections::HashMap;
 
-use executor::FieldResult;
 use value::Value;
 use schema::model::RootNode;
 
@@ -32,9 +31,9 @@ graphql_enum!(Sample as "SampleEnum" {
 
 graphql_interface!(Interface: () as "SampleInterface" |&self| {
     description: "A sample interface"
-    
-    field sample_enum() -> FieldResult<Sample> as "A sample field in the interface" {
-        Ok(Sample::One)
+
+    field sample_enum() -> Sample as "A sample field in the interface" {
+        Sample::One
     }
 
     instance_resolvers: |&_| [
@@ -47,15 +46,15 @@ graphql_object!(Root: () as "Root" |&self| {
 
     interfaces: [Interface]
 
-    field sample_enum() -> FieldResult<Sample> {
-        Ok(Sample::One)
+    field sample_enum() -> Sample {
+        Sample::One
     }
 
     field sample_scalar(
-        first: i64 as "The first number", 
+        first: i64 as "The first number",
         second = 123: i64 as "The second number"
-    ) -> FieldResult<Scalar> as "A sample scalar field on the object" {
-        Ok(Scalar(first + second))
+    ) -> Scalar as "A sample scalar field on the object" {
+        Scalar(first + second)
     }
 });
 
@@ -121,7 +120,7 @@ fn enum_introspection() {
 
     assert_eq!(type_info.get("name"), Some(&Value::string("SampleEnum")));
     assert_eq!(type_info.get("kind"), Some(&Value::string("ENUM")));
-    assert_eq!(type_info.get("description"), Some(&Value::null())); 
+    assert_eq!(type_info.get("description"), Some(&Value::null()));
     assert_eq!(type_info.get("interfaces"), Some(&Value::null()));
     assert_eq!(type_info.get("possibleTypes"), Some(&Value::null()));
     assert_eq!(type_info.get("inputFields"), Some(&Value::null()));
diff --git a/src/lib.rs b/src/lib.rs
index 4db4caeaf..3397114d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -28,8 +28,8 @@ existing object types as GraphQL objects:
 
 ```rust
 #[macro_use] extern crate juniper;
-use juniper::FieldResult;
 # use std::collections::HashMap;
+use juniper::FieldResult;
 
 struct User { id: String, name: String, friend_ids: Vec<String>  }
 struct QueryRoot;
@@ -42,15 +42,19 @@ struct Database { users: HashMap<String, User> }
 graphql_object!(User: Database as "User" |&self| {
 
     // Expose a simple field as a GraphQL string.
+    field id() -> &String {
+        &self.id
+    }
+
+    field name() -> &String {
+        &self.name
+    }
+
     // FieldResult<T> is an alias for Result<T, String> - simply return
     // a string from this method and it will be correctly inserted into
     // the execution response.
-    field id() -> FieldResult<&String> {
-        Ok(&self.id)
-    }
-
-    field name() -> FieldResult<&String> {
-        Ok(&self.name)
+    field secret() -> FieldResult<&String> {
+        Err("Can't touch this".to_owned())
     }
 
     // Field accessors can optionally take an "executor" as their first
@@ -59,10 +63,10 @@ graphql_object!(User: Database as "User" |&self| {
     //
     // In this example, the context is used to convert the friend_ids array
     // into actual User objects.
-    field friends(&mut executor) -> FieldResult<Vec<&User>> {
-        Ok(self.friend_ids.iter()
+    field friends(&mut executor) -> Vec<&User> {
+        self.friend_ids.iter()
             .filter_map(|id| executor.context().users.get(id))
-            .collect())
+            .collect()
     }
 });
 
@@ -71,8 +75,8 @@ graphql_object!(User: Database as "User" |&self| {
 graphql_object!(QueryRoot: Database as "Query" |&self| {
 
     // Arguments work just like they do on functions.
-    field user(&mut executor, id: String) -> FieldResult<Option<&User>> {
-        Ok(executor.context().users.get(&id))
+    field user(&mut executor, id: String) -> Option<&User> {
+        executor.context().users.get(&id)
     }
 });
 
@@ -197,13 +201,13 @@ use rustc_serialize::json::{ToJson, Json};
 
 use parser::{parse_document_source, ParseError, Spanning, SourcePosition};
 use validation::{RuleError, ValidatorContext, visit_all_rules};
+use executor::execute_validated_query;
 
 pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection};
 pub use value::Value;
 pub use types::base::{Arguments, GraphQLType, TypeKind};
 pub use executor::{
-    Executor, Registry, ExecutionResult, ExecutionError, FieldResult,
-    execute_validated_query,
+    Executor, Registry, ExecutionResult, ExecutionError, FieldResult, IntoFieldResult,
 };
 pub use types::scalars::ID;
 pub use schema::model::RootNode;
diff --git a/src/macros/enums.rs b/src/macros/enums.rs
index 77f8fbba..e758bff8 100644
--- a/src/macros/enums.rs
+++ b/src/macros/enums.rs
@@ -110,6 +110,12 @@ macro_rules! graphql_enum {
                 }
             }
         }
+
+        impl $crate::IntoFieldResult<$name> for $name {
+            fn into(self) -> $crate::FieldResult<$name> {
+                Ok(self)
+            }
+        }
     };
 
     // No more items to parse
diff --git a/src/macros/field.rs b/src/macros/field.rs
index 8ba74b65..d983096d 100644
--- a/src/macros/field.rs
+++ b/src/macros/field.rs
@@ -77,7 +77,7 @@ macro_rules! __graphql__build_field_matches {
                     $body
                 };
 
-                return result.and_then(|r| $executorvar.resolve(&r))
+                return ($crate::IntoFieldResult::into(result)).and_then(|r| $executorvar.resolve(&r))
             }
         )*
         panic!("Field {} not found on type {}", $fieldvar, $outname);
diff --git a/src/macros/interface.rs b/src/macros/interface.rs
index 74f619aa..5f1f839d 100644
--- a/src/macros/interface.rs
+++ b/src/macros/interface.rs
@@ -38,7 +38,6 @@ shared context to implement downcasts.
 
 ```rust
 # #[macro_use] extern crate juniper;
-# use juniper::FieldResult;
 # use std::collections::HashMap;
 struct Human { id: String }
 struct Droid { id: String }
@@ -60,16 +59,16 @@ impl Character for Droid {
 }
 
 graphql_object!(Human: Database as "Human" |&self| {
-    field id() -> FieldResult<&str> { Ok(&self.id) }
+    field id() -> &str { &self.id }
 });
 
 graphql_object!(Droid: Database as "Droid" |&self| {
-    field id() -> FieldResult<&str> { Ok(&self.id) }
+    field id() -> &str { &self.id }
 });
 
 // You can introduce lifetimes or generic parameters by < > before the name.
 graphql_interface!(<'a> &'a Character: Database as "Character" |&self| {
-    field id() -> FieldResult<&str> { Ok(self.id()) }
+    field id() -> &str { self.id() }
 
     instance_resolvers: |&context| [
         context.humans.get(self.id()),
@@ -97,9 +96,8 @@ macro_rules! graphql_interface {
         $acc.push(__graphql__args!(
             @apply_args,
             $reg,
-            $reg.field_inside_result(
-                &$crate::to_snake_case(stringify!($name)),
-                Err("dummy".to_owned()) as $t)
+            $reg.field_convert::<$t, _>(
+                &$crate::to_snake_case(stringify!($name)))
                 .description($desc)
                 .deprecated($reason),
             $args));
@@ -116,9 +114,8 @@ macro_rules! graphql_interface {
         $acc.push(__graphql__args!(
             @apply_args,
             $reg,
-            $reg.field_inside_result(
-                &$crate::to_snake_case(stringify!($name)),
-                Err("dummy".to_owned()) as $t)
+            $reg.field_convert::<$t, _>(
+                &$crate::to_snake_case(stringify!($name)))
                 .deprecated($reason),
             $args));
 
@@ -134,9 +131,8 @@ macro_rules! graphql_interface {
         $acc.push(__graphql__args!(
             @apply_args,
             $reg,
-            $reg.field_inside_result(
-                &$crate::to_snake_case(stringify!($name)),
-                Err("dummy".to_owned()) as $t)
+            $reg.field_convert::<$t, _>(
+                &$crate::to_snake_case(stringify!($name)))
                 .description($desc),
             $args));
 
@@ -152,9 +148,8 @@ macro_rules! graphql_interface {
         $acc.push(__graphql__args!(
             @apply_args,
             $reg,
-            $reg.field_inside_result(
-                &$crate::to_snake_case(stringify!($name)),
-                Err("dummy".to_owned()) as $t),
+            $reg.field_convert::<$t, _>(
+                &$crate::to_snake_case(stringify!($name))),
             $args));
 
         graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*);
diff --git a/src/macros/object.rs b/src/macros/object.rs
index 77d9e62e..8d6df382 100644
--- a/src/macros/object.rs
+++ b/src/macros/object.rs
@@ -11,23 +11,22 @@ The simplest case exposes fields on a struct:
 
 ```rust
 # #[macro_use] extern crate juniper;
-# use juniper::FieldResult;
 struct User { id: String, name: String, group_ids: Vec<String> }
 
 graphql_object!(User: () as "User" |&self| {
-    field id() -> FieldResult<&String> {
-        Ok(&self.id)
+    field id() -> &String {
+        &self.id
     }
 
-    field name() -> FieldResult<&String> {
-        Ok(&self.name)
+    field name() -> &String {
+        &self.name
     }
 
     // Field and argument names will be converted from snake case to camel case,
     // as is the common naming convention in GraphQL. The following field would
     // be named "memberOfGroup", and the argument "groupId".
-    field member_of_group(group_id: String) -> FieldResult<bool> {
-        Ok(self.group_ids.iter().any(|gid| gid == &group_id))
+    field member_of_group(group_id: String) -> bool {
+        self.group_ids.iter().any(|gid| gid == &group_id)
     }
 });
 
@@ -41,24 +40,23 @@ arguments:
 
 ```rust
 # #[macro_use] extern crate juniper;
-# use juniper::FieldResult;
 struct User { id: String, name: String, group_ids: Vec<String> }
 
 graphql_object!(User: () as "User" |&self| {
     description: "A user in the database"
 
-    field id() -> FieldResult<&String> as "The user's unique identifier" {
-        Ok(&self.id)
+    field id() -> &String as "The user's unique identifier" {
+        &self.id
     }
 
-    field name() -> FieldResult<&String> as "The user's name" {
-        Ok(&self.name)
+    field name() -> &String as "The user's name" {
+        &self.name
     }
 
     field member_of_group(
         group_id: String as "The group id you want to test membership against"
-    ) -> FieldResult<bool> as "Test if a user is member of a group" {
-        Ok(self.group_ids.iter().any(|gid| gid == &group_id))
+    ) -> bool as "Test if a user is member of a group" {
+        self.group_ids.iter().any(|gid| gid == &group_id)
     }
 });
 
@@ -72,26 +70,16 @@ generic parameters:
 
 ```rust
 # #[macro_use] extern crate juniper;
-# use juniper::FieldResult;
 trait SomeTrait { fn id(&self) -> &str; }
 
 graphql_object!(<'a> &'a SomeTrait: () as "SomeTrait" |&self| {
-    field id() -> FieldResult<&str> { Ok(self.id()) }
+    field id() -> &str { self.id() }
 });
 
 struct GenericType<T> { items: Vec<T> }
 
 graphql_object!(<T> GenericType<T>: () as "GenericType" |&self| {
-    field count() -> FieldResult<i64> { Ok(self.items.len() as i64) }
-});
-
-struct SelfContained { name: String }
-
-// If the type does not require access to a specific context, you can make it
-// generic on the context type. This statically ensures that the fields only
-// can access what's available from the type itself.
-graphql_object!(<Context> SelfContained: Context as "SelfContained" |&self| {
-    field name() -> FieldResult<&String> { Ok(&self.name) }
+    field count() -> i64 { self.items.len() as i64 }
 });
 
 # fn main() { }
@@ -103,7 +91,6 @@ You can use the `interfaces` item to implement interfaces:
 
 ```rust
 # #[macro_use] extern crate juniper;
-# use juniper::FieldResult;
 trait Interface {
     fn id(&self) -> &str;
     fn as_implementor(&self) -> Option<Implementor>;
@@ -111,7 +98,7 @@ trait Interface {
 struct Implementor { id: String }
 
 graphql_interface!(<'a> &'a Interface: () as "Interface" |&self| {
-    field id() -> FieldResult<&str> { Ok(self.id()) }
+    field id() -> &str { self.id() }
 
     instance_resolvers: |&context| [
         self.as_implementor(),
@@ -119,7 +106,7 @@ graphql_interface!(<'a> &'a Interface: () as "Interface" |&self| {
 });
 
 graphql_object!(Implementor: () as "Implementor" |&self| {
-    field id() -> FieldResult<&str> { Ok(&self.id) }
+    field id() -> &str { &self.id }
 
     interfaces: [&Interface]
 });
@@ -194,8 +181,10 @@ need to have any connection, only what's exposed in the schema matters.
 ### Fields
 
 ```text
-field name(args...) -> FieldResult<Type> { }
-field name(args...) -> FieldResult<Type> as "Field description" { }
+field name(args...) -> Type { }
+field name(args...) -> Type as "Field description" { }
+field deprecated "Reason" name(args...) -> Type { }
+field deprecated "Reason" name(args...) -> Type as "Field description" { }
 ```
 
 Defines a field on the object. The name is converted to camel case, e.g.
@@ -248,9 +237,8 @@ macro_rules! graphql_object {
         $acc.push(__graphql__args!(
             @apply_args,
             $reg,
-            $reg.field_inside_result(
-                &$crate::to_snake_case(stringify!($name)),
-                Err("dummy".to_owned()) as $t)
+            $reg.field_convert::<$t, _>(
+                &$crate::to_snake_case(stringify!($name)))
                 .description($desc)
                 .deprecated($reason),
             $args));
@@ -267,9 +255,8 @@ macro_rules! graphql_object {
         $acc.push(__graphql__args!(
             @apply_args,
             $reg,
-            $reg.field_inside_result(
-                &$crate::to_snake_case(stringify!($name)),
-                Err("dummy".to_owned()) as $t)
+            $reg.field_convert::<$t, _>(
+                &$crate::to_snake_case(stringify!($name)))
                 .deprecated($reason),
             $args));
 
@@ -285,9 +272,8 @@ macro_rules! graphql_object {
         $acc.push(__graphql__args!(
             @apply_args,
             $reg,
-            $reg.field_inside_result(
-                &$crate::to_snake_case(stringify!($name)),
-                Err("dummy".to_owned()) as $t)
+            $reg.field_convert::<$t, _>(
+                &$crate::to_snake_case(stringify!($name)))
                 .description($desc),
             $args));
 
@@ -303,9 +289,8 @@ macro_rules! graphql_object {
         $acc.push(__graphql__args!(
             @apply_args,
             $reg,
-            $reg.field_inside_result(
-                &$crate::to_snake_case(stringify!($name)),
-                Err("dummy".to_owned()) as $t),
+            $reg.field_convert::<$t, _>(
+                &$crate::to_snake_case(stringify!($name))),
             $args));
 
         graphql_object!(@gather_object_meta, $reg, $acc, $descr, $ifaces, $( $rest )*);
@@ -407,6 +392,12 @@ macro_rules! graphql_object {
                     $($items)*);
             }
         });
+
+        impl<$($lifetime)*> $crate::IntoFieldResult<$name> for $name {
+            fn into(self) -> $crate::FieldResult<$name> {
+                Ok(self)
+            }
+        }
     };
 
     (
diff --git a/src/macros/scalar.rs b/src/macros/scalar.rs
index a28e17cc..3948b9fd 100644
--- a/src/macros/scalar.rs
+++ b/src/macros/scalar.rs
@@ -92,6 +92,12 @@ macro_rules! graphql_scalar {
                 $fiv_body
             }
         }
+
+        impl $crate::IntoFieldResult<$name> for $name {
+            fn into(self) -> $crate::FieldResult<$name> {
+                Ok(self)
+            }
+        }
     };
 
     // No more items to parse
diff --git a/src/macros/tests/args.rs b/src/macros/tests/args.rs
index 54741a95..12396943 100644
--- a/src/macros/tests/args.rs
+++ b/src/macros/tests/args.rs
@@ -1,6 +1,5 @@
 use std::collections::HashMap;
 
-use executor::FieldResult;
 use value::Value;
 use schema::model::RootNode;
 
@@ -20,49 +19,49 @@ Syntax to validate:
 */
 
 graphql_object!(Root: () as "Root" |&self| {
-    field simple() -> FieldResult<i64> { Ok(0) }
-    field exec_arg(&mut executor) -> FieldResult<i64> { Ok(0) }
-    field exec_arg_and_more(&mut executor, arg: i64) -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
+    field exec_arg(&mut executor) -> i64 { 0 }
+    field exec_arg_and_more(&mut executor, arg: i64) -> i64 { 0 }
 
-    field single_arg(arg: i64) -> FieldResult<i64> { Ok(0) }
+    field single_arg(arg: i64) -> i64 { 0 }
     field multi_args(
         arg1: i64,
         arg2: i64
-    ) -> FieldResult<i64> { Ok(0) }
+    ) -> i64 { 0 }
     field multi_args_trailing_comma(
         arg1: i64,
         arg2: i64,
-    ) -> FieldResult<i64> { Ok(0) }
+    ) -> i64 { 0 }
 
-    field single_arg_descr(arg: i64 as "The arg") -> FieldResult<i64> { Ok(0) }
+    field single_arg_descr(arg: i64 as "The arg") -> i64 { 0 }
     field multi_args_descr(
         arg1: i64 as "The first arg",
         arg2: i64 as "The second arg"
-    ) -> FieldResult<i64> { Ok(0) }
+    ) -> i64 { 0 }
     field multi_args_descr_trailing_comma(
         arg1: i64 as "The first arg",
         arg2: i64 as "The second arg",
-    ) -> FieldResult<i64> { Ok(0) }
+    ) -> i64 { 0 }
 
-    field arg_with_default(arg = 123: i64) -> FieldResult<i64> { Ok(0) }
+    field arg_with_default(arg = 123: i64) -> i64 { 0 }
     field multi_args_with_default(
         arg1 = 123: i64,
         arg2 = 456: i64
-    ) -> FieldResult<i64> { Ok(0) }
+    ) -> i64 { 0 }
     field multi_args_with_default_trailing_comma(
         arg1 = 123: i64,
         arg2 = 456: i64,
-    ) -> FieldResult<i64> { Ok(0) }
+    ) -> i64 { 0 }
 
-    field arg_with_default_descr(arg = 123: i64 as "The arg") -> FieldResult<i64> { Ok(0) }
+    field arg_with_default_descr(arg = 123: i64 as "The arg") -> i64 { 0 }
     field multi_args_with_default_descr(
         arg1 = 123: i64 as "The first arg",
         arg2 = 456: i64 as "The second arg"
-    ) -> FieldResult<i64> { Ok(0) }
+    ) -> i64 { 0 }
     field multi_args_with_default_trailing_comma_descr(
         arg1 = 123: i64 as "The first arg",
         arg2 = 456: i64 as "The second arg",
-    ) -> FieldResult<i64> { Ok(0) }
+    ) -> i64 { 0 }
 });
 
 fn run_args_info_query<F>(field_name: &str, f: F)
diff --git a/src/macros/tests/enums.rs b/src/macros/tests/enums.rs
index 5b667dc5..0782e62d 100644
--- a/src/macros/tests/enums.rs
+++ b/src/macros/tests/enums.rs
@@ -1,6 +1,5 @@
 use std::collections::HashMap;
 
-use executor::FieldResult;
 use value::Value;
 use schema::model::RootNode;
 
@@ -59,12 +58,12 @@ graphql_enum!(EnumDeprecation {
 });
 
 graphql_object!(Root: () as "Root" |&self| {
-    field default_name() -> FieldResult<DefaultName> { Ok(DefaultName::Foo) }
-    field named() -> FieldResult<Named> { Ok(Named::Foo) }
-    field no_trailing_comma() -> FieldResult<NoTrailingComma> { Ok(NoTrailingComma::Foo) }
-    field enum_description() -> FieldResult<EnumDescription> { Ok(EnumDescription::Foo) }
-    field enum_value_description() -> FieldResult<EnumValueDescription> { Ok(EnumValueDescription::Foo) }
-    field enum_deprecation() -> FieldResult<EnumDeprecation> { Ok(EnumDeprecation::Foo) }
+    field default_name() -> DefaultName { DefaultName::Foo }
+    field named() -> Named { Named::Foo }
+    field no_trailing_comma() -> NoTrailingComma { NoTrailingComma::Foo }
+    field enum_description() -> EnumDescription { EnumDescription::Foo }
+    field enum_value_description() -> EnumValueDescription { EnumValueDescription::Foo }
+    field enum_deprecation() -> EnumDeprecation { EnumDeprecation::Foo }
 });
 
 fn run_type_info_query<F>(doc: &str, f: F) where F: Fn((&HashMap<String, Value>, &Vec<Value>)) -> () {
diff --git a/src/macros/tests/field.rs b/src/macros/tests/field.rs
index 72575bb2..c004bccc 100644
--- a/src/macros/tests/field.rs
+++ b/src/macros/tests/field.rs
@@ -1,6 +1,5 @@
 use std::collections::HashMap;
 
-use executor::FieldResult;
 use value::Value;
 use ast::InputValue;
 use schema::model::RootNode;
@@ -19,29 +18,29 @@ Syntax to validate:
 */
 
 graphql_object!(Root: () as "Root" |&self| {
-    field simple() -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
 
-    field description() -> FieldResult<i64> as "Field description" { Ok(0) }
+    field description() -> i64 as "Field description" { 0 }
 
     field deprecated "Deprecation reason"
-        deprecated() -> FieldResult<i64> { Ok(0) }
+        deprecated() -> i64 { 0 }
 
     field deprecated "Deprecation reason"
-        deprecated_descr() -> FieldResult<i64> as "Field description" { Ok(0) }
+        deprecated_descr() -> i64 as "Field description" { 0 }
 
     interfaces: [Interface]
 });
 
 graphql_interface!(Interface: () as "Interface" |&self| {
-    field simple() -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
 
-    field description() -> FieldResult<i64> as "Field description" { Ok(0) }
+    field description() -> i64 as "Field description" { 0 }
 
     field deprecated "Deprecation reason"
-        deprecated() -> FieldResult<i64> { Ok(0) }
+        deprecated() -> i64 { 0 }
 
     field deprecated "Deprecation reason"
-        deprecated_descr() -> FieldResult<i64> as "Field description" { Ok(0) }
+        deprecated_descr() -> i64 as "Field description" { 0 }
 
     instance_resolvers: |&_| [
         Some(Root {}),
diff --git a/src/macros/tests/input_object.rs b/src/macros/tests/input_object.rs
index 86ab5573..0e8d1605 100644
--- a/src/macros/tests/input_object.rs
+++ b/src/macros/tests/input_object.rs
@@ -1,7 +1,6 @@
 use std::collections::HashMap;
 
 use ast::{InputValue, FromInputValue};
-use executor::FieldResult;
 use value::Value;
 use schema::model::RootNode;
 
@@ -57,8 +56,8 @@ graphql_object!(Root: () as "Root" |&self| {
         a4: Named,
         a5: Description,
         a6: FieldDescription
-    ) -> FieldResult<i64> {
-        Ok(0)
+    ) -> i64 {
+        0
     }
 });
 
diff --git a/src/macros/tests/object.rs b/src/macros/tests/object.rs
index 36157273..cfcecccb 100644
--- a/src/macros/tests/object.rs
+++ b/src/macros/tests/object.rs
@@ -1,7 +1,7 @@
 use std::collections::HashMap;
+use std::marker::PhantomData;
 
 use ast::InputValue;
-use executor::FieldResult;
 use value::Value;
 use schema::model::RootNode;
 
@@ -20,8 +20,11 @@ struct Interface;
 
 struct DefaultName;
 
-struct WithLifetime;
-struct WithGenerics;
+#[allow(dead_code)]
+struct WithLifetime<'a> { data: PhantomData<&'a i64> }
+
+#[allow(dead_code)]
+struct WithGenerics<T> { data: T }
 
 struct DescriptionFirst;
 struct FieldsFirst;
@@ -33,20 +36,21 @@ struct CommasOnMeta;
 struct Root;
 
 graphql_object!(DefaultName: () |&self| {
-    field simple() -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
 });
 
 
-graphql_object!(<'a> &'a WithLifetime: () as "WithLifetime" |&self| {
-    field simple() -> FieldResult<i64> { Ok(0) }
+graphql_object!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| {
+    field simple() -> i64 { 0 }
 });
 
-graphql_object!(<CtxT> WithGenerics: CtxT as "WithGenerics" |&self| {
-    field simple() -> FieldResult<i64> { Ok(0) }
+graphql_object!(<T> WithGenerics<T>: () as "WithGenerics" |&self| {
+    field simple() -> i64 { 0 }
 });
 
+
 graphql_interface!(Interface: () as "Interface" |&self| {
-    field simple() -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
 
     instance_resolvers: |_| [
         Some(DescriptionFirst {}),
@@ -56,13 +60,13 @@ graphql_interface!(Interface: () as "Interface" |&self| {
 graphql_object!(DescriptionFirst: () as "DescriptionFirst" |&self| {
     description: "A description"
 
-    field simple() -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
 
     interfaces: [Interface]
 });
 
 graphql_object!(FieldsFirst: () as "FieldsFirst" |&self| {
-    field simple() -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
 
     description: "A description"
 
@@ -72,7 +76,7 @@ graphql_object!(FieldsFirst: () as "FieldsFirst" |&self| {
 graphql_object!(InterfacesFirst: () as "InterfacesFirst" |&self| {
     interfaces: [Interface]
 
-    field simple() -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
 
     description: "A description"
 });
@@ -80,7 +84,7 @@ graphql_object!(InterfacesFirst: () as "InterfacesFirst" |&self| {
 graphql_object!(CommasWithTrailing: () as "CommasWithTrailing" |&self| {
     interfaces: [Interface],
 
-    field simple() -> FieldResult<i64> { Ok(0) },
+    field simple() -> i64 { 0 },
 
     description: "A description",
 });
@@ -90,21 +94,21 @@ graphql_object!(CommasOnMeta: () as "CommasOnMeta" |&self| {
     interfaces: [Interface],
     description: "A description",
 
-    field simple() -> FieldResult<i64> { Ok(0) }
+    field simple() -> i64 { 0 }
 });
 
-graphql_object!(Root: () as "Root" |&self| {
-    field default_name() -> FieldResult<DefaultName> { Ok(DefaultName {}) }
+graphql_object!(<'a> Root: () as "Root" |&self| {
+    field default_name() -> DefaultName { DefaultName {} }
 
-    field with_lifetime() -> FieldResult<&WithLifetime> { Err("Nope".to_owned()) }
-    field with_generics() -> FieldResult<WithGenerics> { Ok(WithGenerics {}) }
+    field with_lifetime() -> WithLifetime<'a> { WithLifetime { data: PhantomData } }
+    field with_generics() -> WithGenerics<i64> { WithGenerics { data: 123 } }
 
-    field description_first() -> FieldResult<DescriptionFirst> { Ok(DescriptionFirst {}) }
-    field fields_first() -> FieldResult<FieldsFirst> { Ok(FieldsFirst {}) }
-    field interfaces_first() -> FieldResult<InterfacesFirst> { Ok(InterfacesFirst {}) }
+    field description_first() -> DescriptionFirst { DescriptionFirst {} }
+    field fields_first() -> FieldsFirst { FieldsFirst {} }
+    field interfaces_first() -> InterfacesFirst { InterfacesFirst {} }
 
-    field commas_with_trailing() -> FieldResult<CommasWithTrailing> { Ok(CommasWithTrailing {}) }
-    field commas_on_meta() -> FieldResult<CommasOnMeta> { Ok(CommasOnMeta {}) }
+    field commas_with_trailing() -> CommasWithTrailing { CommasWithTrailing {} }
+    field commas_on_meta() -> CommasOnMeta { CommasOnMeta {} }
 });
 
 
diff --git a/src/macros/tests/scalar.rs b/src/macros/tests/scalar.rs
index 8a33522e..bc1fb2ef 100644
--- a/src/macros/tests/scalar.rs
+++ b/src/macros/tests/scalar.rs
@@ -1,6 +1,5 @@
 use std::collections::HashMap;
 
-use executor::FieldResult;
 use value::Value;
 use schema::model::RootNode;
 
@@ -63,10 +62,10 @@ graphql_scalar!(ScalarDescription {
 });
 
 graphql_object!(Root: () as "Root" |&self| {
-    field default_name() -> FieldResult<DefaultName> { Ok(DefaultName(0)) }
-    field other_order() -> FieldResult<OtherOrder> { Ok(OtherOrder(0)) }
-    field named() -> FieldResult<Named> { Ok(Named(0)) }
-    field scalar_description() -> FieldResult<ScalarDescription> { Ok(ScalarDescription(0)) }
+    field default_name() -> DefaultName { DefaultName(0) }
+    field other_order() -> OtherOrder { OtherOrder(0) }
+    field named() -> Named { Named(0) }
+    field scalar_description() -> ScalarDescription { ScalarDescription(0) }
 });
 
 fn run_type_info_query<F>(doc: &str, f: F) where F: Fn(&HashMap<String, Value>) -> () {
diff --git a/src/schema/schema.rs b/src/schema/schema.rs
index 34fca9ca..28588a59 100644
--- a/src/schema/schema.rs
+++ b/src/schema/schema.rs
@@ -1,7 +1,7 @@
 use rustc_serialize::json::ToJson;
 
 use types::base::{GraphQLType, Arguments, TypeKind};
-use executor::{Executor, Registry, FieldResult, ExecutionResult};
+use executor::{Executor, Registry, ExecutionResult};
 
 use schema::meta::{MetaType, ObjectMeta, EnumMeta, InputObjectMeta, UnionMeta, InterfaceMeta,
                    Field, Argument, EnumValue};
@@ -32,48 +32,48 @@ impl<CtxT, QueryT, MutationT> GraphQLType<CtxT> for RootNode<CtxT, QueryT, Mutat
 }
 
 graphql_object!(SchemaType: SchemaType as "__Schema" |&self| {
-    field types() -> FieldResult<Vec<TypeType>> {
-        Ok(self.type_list())
+    field types() -> Vec<TypeType> {
+        self.type_list()
     }
 
-    field query_type() -> FieldResult<TypeType> {
-        Ok(self.query_type())
+    field query_type() -> TypeType {
+        self.query_type()
     }
 
-    field mutation_type() -> FieldResult<Option<TypeType>> {
-        Ok(self.mutation_type())
+    field mutation_type() -> Option<TypeType> {
+        self.mutation_type()
     }
 
-    field directives() -> FieldResult<Vec<&DirectiveType>> {
-        Ok(self.directive_list())
+    field directives() -> Vec<&DirectiveType> {
+        self.directive_list()
     }
 });
 
 graphql_object!(<'a> TypeType<'a>: SchemaType as "__Type" |&self| {
-    field name() -> FieldResult<Option<&str>> {
-        Ok(match *self {
+    field name() -> Option<&str> {
+        match *self {
             TypeType::Concrete(t) => t.name(),
             _ => None,
-        })
+        }
     }
 
-    field description() -> FieldResult<Option<&String>> {
-        Ok(match *self {
+    field description() -> Option<&String> {
+        match *self {
             TypeType::Concrete(t) => t.description(),
             _ => None,
-        })
+        }
     }
 
-    field kind() -> FieldResult<TypeKind> {
-        Ok(match *self {
+    field kind() -> TypeKind {
+        match *self {
             TypeType::Concrete(t) => t.type_kind(),
             TypeType::List(_) => TypeKind::List,
             TypeType::NonNull(_) => TypeKind::NonNull,
-        })
+        }
     }
 
-    field fields(include_deprecated = false: bool) -> FieldResult<Option<Vec<&Field>>> {
-        Ok(match *self {
+    field fields(include_deprecated = false: bool) -> Option<Vec<&Field>> {
+        match *self {
             TypeType::Concrete(&MetaType::Interface(InterfaceMeta { ref fields, .. })) |
             TypeType::Concrete(&MetaType::Object(ObjectMeta { ref fields, .. })) =>
                 Some(fields
@@ -81,26 +81,26 @@ graphql_object!(<'a> TypeType<'a>: SchemaType as "__Type" |&self| {
                     .filter(|f| include_deprecated || f.deprecation_reason.is_none())
                     .collect()),
             _ => None,
-        })
+        }
     }
 
-    field of_type() -> FieldResult<Option<&TypeType>> {
-        Ok(match *self {
+    field of_type() -> Option<&TypeType> {
+        match *self {
             TypeType::Concrete(_) => None,
             TypeType::List(ref l) | TypeType::NonNull(ref l) => Some(l),
-        })
+        }
     }
 
-    field input_fields() -> FieldResult<Option<&Vec<Argument>>> {
-        Ok(match *self {
+    field input_fields() -> Option<&Vec<Argument>> {
+        match *self {
             TypeType::Concrete(&MetaType::InputObject(InputObjectMeta { ref input_fields, .. })) =>
                 Some(input_fields),
             _ => None,
-        })
+        }
     }
 
-    field interfaces(&mut executor) -> FieldResult<Option<Vec<TypeType>>> {
-        Ok(match *self {
+    field interfaces(&mut executor) -> Option<Vec<TypeType>> {
+        match *self {
             TypeType::Concrete(&MetaType::Object(ObjectMeta { ref interface_names, .. })) => {
                 let schema = executor.context();
                 Some(interface_names
@@ -109,12 +109,12 @@ graphql_object!(<'a> TypeType<'a>: SchemaType as "__Type" |&self| {
                     .collect())
             }
             _ => None,
-        })
+        }
     }
 
-    field possible_types(&mut executor) -> FieldResult<Option<Vec<TypeType>>> {
+    field possible_types(&mut executor) -> Option<Vec<TypeType>> {
         let schema = executor.context();
-        Ok(match *self {
+        match *self {
             TypeType::Concrete(&MetaType::Union(UnionMeta { ref of_type_names, .. })) => {
                 Some(of_type_names
                     .iter()
@@ -134,80 +134,80 @@ graphql_object!(<'a> TypeType<'a>: SchemaType as "__Type" |&self| {
                     .collect())
             }
             _ => None,
-        })
+        }
     }
 
-    field enum_values(include_deprecated = false: bool) -> FieldResult<Option<Vec<&EnumValue>>> {
-        Ok(match *self {
+    field enum_values(include_deprecated = false: bool) -> Option<Vec<&EnumValue>> {
+        match *self {
             TypeType::Concrete(&MetaType::Enum(EnumMeta { ref values, .. })) =>
                 Some(values
                     .iter()
                     .filter(|f| include_deprecated || f.deprecation_reason.is_none())
                     .collect()),
             _ => None,
-        })
+        }
     }
 });
 
 graphql_object!(Field: SchemaType as "__Field" |&self| {
-    field name() -> FieldResult<&String> {
-        Ok(&self.name)
+    field name() -> &String {
+        &self.name
     }
 
-    field description() -> FieldResult<&Option<String>> {
-        Ok(&self.description)
+    field description() -> &Option<String> {
+        &self.description
     }
 
-    field args() -> FieldResult<Vec<&Argument>> {
-        Ok(self.arguments.as_ref().map_or_else(|| Vec::new(), |v| v.iter().collect()))
+    field args() -> Vec<&Argument> {
+        self.arguments.as_ref().map_or_else(|| Vec::new(), |v| v.iter().collect())
     }
 
-    field type(&mut executor) -> FieldResult<TypeType> {
-        Ok(executor.context().make_type(&self.field_type))
+    field type(&mut executor) -> TypeType {
+        executor.context().make_type(&self.field_type)
     }
 
-    field is_deprecated() -> FieldResult<bool> {
-        Ok(self.deprecation_reason.is_some())
+    field is_deprecated() -> bool {
+        self.deprecation_reason.is_some()
     }
 
-    field deprecation_reason() -> FieldResult<&Option<String>> {
-        Ok(&self.deprecation_reason)
+    field deprecation_reason() -> &Option<String> {
+        &self.deprecation_reason
     }
 });
 
 graphql_object!(Argument: SchemaType as "__InputValue" |&self| {
-    field name() -> FieldResult<&String> {
-        Ok(&self.name)
+    field name() -> &String {
+        &self.name
     }
 
-    field description() -> FieldResult<&Option<String>> {
-        Ok(&self.description)
+    field description() -> &Option<String> {
+        &self.description
     }
 
-    field type(&mut executor) -> FieldResult<TypeType> {
-        Ok(executor.context().make_type(&self.arg_type))
+    field type(&mut executor) -> TypeType {
+        executor.context().make_type(&self.arg_type)
     }
 
-    field default_value() -> FieldResult<Option<String>> {
-        Ok(self.default_value.as_ref().map(|v| v.to_json().to_string()))
+    field default_value() -> Option<String> {
+        self.default_value.as_ref().map(|v| v.to_json().to_string())
     }
 });
 
 graphql_object!(EnumValue: SchemaType as "__EnumValue" |&self| {
-    field name() -> FieldResult<&String> {
-        Ok(&self.name)
+    field name() -> &String {
+        &self.name
     }
 
-    field description() -> FieldResult<&Option<String>> {
-        Ok(&self.description)
+    field description() -> &Option<String> {
+        &self.description
     }
 
-    field is_deprecated() -> FieldResult<bool> {
-        Ok(self.deprecation_reason.is_some())
+    field is_deprecated() -> bool {
+        self.deprecation_reason.is_some()
     }
 
-    field deprecation_reason() -> FieldResult<&Option<String>> {
-        Ok(&self.deprecation_reason)
+    field deprecation_reason() -> &Option<String> {
+        &self.deprecation_reason
     }
 });
 
@@ -224,20 +224,20 @@ graphql_enum!(TypeKind as "__TypeKind" {
 
 
 graphql_object!(DirectiveType: SchemaType as "__Directive" |&self| {
-    field name() -> FieldResult<&String> {
-        Ok(&self.name)
+    field name() -> &String {
+        &self.name
     }
 
-    field description() -> FieldResult<&Option<String>> {
-        Ok(&self.description)
+    field description() -> &Option<String> {
+        &self.description
     }
 
-    field locations() -> FieldResult<&Vec<DirectiveLocation>> {
-        Ok(&self.locations)
+    field locations() -> &Vec<DirectiveLocation> {
+        &self.locations
     }
 
-    field args() -> FieldResult<&Vec<Argument>> {
-        Ok(&self.arguments)
+    field args() -> &Vec<Argument> {
+        &self.arguments
     }
 });
 
diff --git a/src/tests/schema.rs b/src/tests/schema.rs
index 210c19e2..cde33b12 100644
--- a/src/tests/schema.rs
+++ b/src/tests/schema.rs
@@ -1,4 +1,3 @@
-use executor::FieldResult;
 use tests::model::{Character, Human, Droid, Database, Episode};
 
 graphql_enum!(Episode {
@@ -10,21 +9,21 @@ graphql_enum!(Episode {
 graphql_interface!(<'a> &'a Character: Database as "Character" |&self| {
     description: "A character in the Star Wars Trilogy"
 
-    field id() -> FieldResult<&str> as "The id of the character" {
-        Ok(self.id())
+    field id() -> &str as "The id of the character" {
+        self.id()
     }
 
-    field name() -> FieldResult<Option<&str>> as "The name of the character" {
-        Ok(Some(self.name()))
+    field name() -> Option<&str> as "The name of the character" {
+        Some(self.name())
     }
 
-    field friends(&mut executor) -> FieldResult<Vec<&Character>>
+    field friends(&mut executor) -> Vec<&Character>
     as "The friends of the character" {
-        Ok(executor.context().get_friends(self.as_character()))
+        executor.context().get_friends(self.as_character())
     }
 
-    field appears_in() -> FieldResult<&[Episode]> as "Which movies they appear in" {
-        Ok(self.appears_in())
+    field appears_in() -> &[Episode] as "Which movies they appear in" {
+        self.appears_in()
     }
 
     instance_resolvers: |&context| [
@@ -38,25 +37,25 @@ graphql_object!(<'a> &'a Human: Database as "Human" |&self| {
 
     interfaces: [&Character]
 
-    field id() -> FieldResult<&str> as "The id of the human"{
-        Ok(self.id())
+    field id() -> &str as "The id of the human"{
+        self.id()
     }
 
-    field name() -> FieldResult<Option<&str>> as "The name of the human" {
-        Ok(Some(self.name()))
+    field name() -> Option<&str> as "The name of the human" {
+        Some(self.name())
     }
 
-    field friends(&mut executor) -> FieldResult<Vec<&Character>>
+    field friends(&mut executor) -> Vec<&Character>
     as "The friends of the human" {
-        Ok(executor.context().get_friends(self.as_character()))
+        executor.context().get_friends(self.as_character())
     }
 
-    field appears_in() -> FieldResult<&[Episode]> as "Which movies they appear in" {
-        Ok(self.appears_in())
+    field appears_in() -> &[Episode] as "Which movies they appear in" {
+        self.appears_in()
     }
 
-    field home_planet() -> FieldResult<&Option<String>> as "The home planet of the human" {
-        Ok(self.home_planet())
+    field home_planet() -> &Option<String> as "The home planet of the human" {
+        self.home_planet()
     }
 });
 
@@ -65,25 +64,25 @@ graphql_object!(<'a> &'a Droid: Database as "Droid" |&self| {
 
     interfaces: [&Character]
 
-    field id() -> FieldResult<&str> as "The id of the droid" {
-        Ok(self.id())
+    field id() -> &str as "The id of the droid" {
+        self.id()
     }
 
-    field name() -> FieldResult<Option<&str>> as "The name of the droid" {
-        Ok(Some(self.name()))
+    field name() -> Option<&str> as "The name of the droid" {
+        Some(self.name())
     }
 
-    field friends(&mut executor) -> FieldResult<Vec<&Character>>
+    field friends(&mut executor) -> Vec<&Character>
     as "The friends of the droid" {
-        Ok(executor.context().get_friends(self.as_character()))
+        executor.context().get_friends(self.as_character())
     }
 
-    field appears_in() -> FieldResult<&[Episode]> as "Which movies they appear in" {
-        Ok(self.appears_in())
+    field appears_in() -> &[Episode] as "Which movies they appear in" {
+        self.appears_in()
     }
 
-    field primary_function() -> FieldResult<&Option<String>> as "The primary function of the droid" {
-        Ok(self.primary_function())
+    field primary_function() -> &Option<String> as "The primary function of the droid" {
+        self.primary_function()
     }
 });
 
@@ -93,21 +92,21 @@ graphql_object!(Database: Database as "Query" |&self| {
 
     field human(
         id: String as "id of the human"
-    ) -> FieldResult<Option<&Human>> {
-        Ok(self.get_human(&id))
+    ) -> Option<&Human> {
+        self.get_human(&id)
     }
 
     field droid(
         id: String as "id of the droid"
-    ) -> FieldResult<Option<&Droid>> {
-        Ok(self.get_droid(&id))
+    ) -> Option<&Droid> {
+        self.get_droid(&id)
     }
 
     field hero(
         episode: Option<Episode> as
         "If omitted, returns the hero of the whole saga. If provided, returns \
         the hero of that particular episode"
-    ) -> FieldResult<Option<&Character>> {
-        Ok(Some(self.get_hero(episode).as_character()))
+    ) -> Option<&Character> {
+        Some(self.get_hero(episode).as_character())
     }
 });
diff --git a/src/types/containers.rs b/src/types/containers.rs
index 744d06e8..11501524 100644
--- a/src/types/containers.rs
+++ b/src/types/containers.rs
@@ -2,7 +2,7 @@ use ast::{InputValue, ToInputValue, FromInputValue, Selection};
 use value::Value;
 use schema::meta::MetaType;
 
-use executor::{Executor, Registry};
+use executor::{Executor, Registry, IntoFieldResult, FieldResult};
 use types::base::{GraphQLType};
 
 impl<T, CtxT> GraphQLType<CtxT> for Option<T> where T: GraphQLType<CtxT> {
@@ -43,6 +43,12 @@ impl<T> ToInputValue for Option<T> where T: ToInputValue {
     }
 }
 
+impl<T> IntoFieldResult<Option<T>> for Option<T> {
+    fn into(self) -> FieldResult<Option<T>> {
+        Ok(self)
+    }
+}
+
 
 impl<T, CtxT> GraphQLType<CtxT> for Vec<T> where T: GraphQLType<CtxT> {
     fn name() -> Option<&'static str> {
@@ -84,6 +90,12 @@ impl<T> ToInputValue for Vec<T> where T: ToInputValue {
     }
 }
 
+impl<T> IntoFieldResult<Vec<T>> for Vec<T> {
+    fn into(self) -> FieldResult<Vec<T>> {
+        Ok(self)
+    }
+}
+
 
 impl<'a, T, CtxT> GraphQLType<CtxT> for &'a [T] where T: GraphQLType<CtxT> {
     fn name() -> Option<&'static str> {
@@ -106,3 +118,9 @@ impl<'a, T> ToInputValue for &'a [T] where T: ToInputValue {
         InputValue::list(self.iter().map(|v| v.to()).collect())
     }
 }
+
+impl<'a, T> IntoFieldResult<&'a [T]> for &'a [T] {
+    fn into(self) -> FieldResult<&'a [T]> {
+        Ok(self)
+    }
+}
diff --git a/src/types/pointers.rs b/src/types/pointers.rs
index 6882d5ca..01a7e5dc 100644
--- a/src/types/pointers.rs
+++ b/src/types/pointers.rs
@@ -2,7 +2,7 @@ use ast::{Selection, InputValue, ToInputValue, FromInputValue};
 use value::Value;
 
 use schema::meta::MetaType;
-use executor::{Executor, Registry, ExecutionResult};
+use executor::{Executor, Registry, ExecutionResult, IntoFieldResult, FieldResult};
 use types::base::{Arguments, GraphQLType};
 
 impl<T, CtxT> GraphQLType<CtxT> for Box<T> where T: GraphQLType<CtxT> {
@@ -43,6 +43,12 @@ impl<T> ToInputValue for Box<T> where T: ToInputValue {
     }
 }
 
+impl<T> IntoFieldResult<Box<T>> for Box<T> {
+    fn into(self) -> FieldResult<Box<T>> {
+        Ok(self)
+    }
+}
+
 impl<'a, T, CtxT> GraphQLType<CtxT> for &'a T where T: GraphQLType<CtxT> {
     fn name() -> Option<&'static str> {
         T::name()
@@ -71,3 +77,9 @@ impl<'a, T> ToInputValue for &'a T where T: ToInputValue {
         (**self).to()
     }
 }
+
+impl<'a, T> IntoFieldResult<&'a T> for &'a T {
+    fn into(self) -> FieldResult<&'a T> {
+        Ok(self)
+    }
+}
diff --git a/src/types/scalars.rs b/src/types/scalars.rs
index ba1a2d6e..f4b7eb9d 100644
--- a/src/types/scalars.rs
+++ b/src/types/scalars.rs
@@ -3,7 +3,7 @@ use value::Value;
 
 use schema::meta::MetaType;
 
-use executor::{Executor, Registry};
+use executor::{Executor, Registry, FieldResult, IntoFieldResult};
 use types::base::GraphQLType;
 
 /// An ID as defined by the GraphQL specification
@@ -60,6 +60,13 @@ impl<'a> ToInputValue for &'a str {
     }
 }
 
+impl<'a> IntoFieldResult<&'a str> for &'a str {
+    fn into(self) -> FieldResult<&'a str> {
+        Ok(self)
+    }
+}
+
+
 
 graphql_scalar!(bool as "Boolean" {
     resolve(&self) -> Value {
@@ -119,3 +126,9 @@ impl FromInputValue for () {
         None
     }
 }
+
+impl IntoFieldResult<()> for () {
+    fn into(self) -> FieldResult<()> {
+        Ok(self)
+    }
+}