diff --git a/examples/server.rs b/examples/server.rs
index ec8d6c4a..e4ef3cbe 100644
--- a/examples/server.rs
+++ b/examples/server.rs
@@ -9,7 +9,7 @@ use std::env;
 use mount::Mount;
 use logger::Logger;
 use iron::prelude::*;
-use juniper::FieldResult;
+use juniper::EmptyMutation;
 use juniper::iron_handlers::{GraphQLHandler, GraphiQLHandler};
 use juniper::tests::model::Database;
 
@@ -20,7 +20,11 @@ fn context_factory(_: &mut Request) -> Database {
 fn main() {
     let mut mount = Mount::new();
 
-    let graphql_endpoint = GraphQLHandler::new(context_factory, Database::new(), ());
+    let graphql_endpoint = GraphQLHandler::new(
+        context_factory,
+        Database::new(),
+        EmptyMutation::<Database>::new(),
+    );
     let graphiql_endpoint = GraphiQLHandler::new("/graphql");
 
     mount.mount("/", graphiql_endpoint);
diff --git a/src/executor.rs b/src/executor.rs
index ae277917..4dceee46 100644
--- a/src/executor.rs
+++ b/src/executor.rs
@@ -1,5 +1,4 @@
 use std::collections::HashMap;
-use std::marker::PhantomData;
 use std::sync::RwLock;
 
 use ::GraphQLError;
@@ -20,10 +19,9 @@ use types::base::GraphQLType;
 /// The registry gathers metadata for all types in a schema. It provides
 /// convenience methods to convert types implementing the `GraphQLType` trait
 /// into `Type` instances and automatically registers them.
-pub struct Registry<CtxT> {
+pub struct Registry {
     /// Currently registered types
     pub types: HashMap<String, MetaType>,
-    phantom: PhantomData<CtxT>,
 }
 
 #[derive(Clone)]
@@ -80,9 +78,46 @@ impl<T> IntoFieldResult<T> for FieldResult<T> {
     }
 }
 
+/// Conversion trait for context types
+///
+/// This is currently only used for converting arbitrary contexts into
+/// the empty tuple, but will in the future be used to support general
+/// context conversion for larger schemas.
+pub trait FromContext<T> {
+    /// Perform the conversion
+    fn from_context(value: &T) -> &Self;
+}
+
+/// Marker trait for types that can act as context objects for GraphQL types.
+pub trait Context { }
+
+static NULL_CONTEXT: () = ();
+
+impl<T> FromContext<T> for () {
+    fn from_context(_: &T) -> &Self {
+        &NULL_CONTEXT
+    }
+}
+
+impl<T> FromContext<T> for T where T: Context {
+    fn from_context(value: &T) -> &Self {
+        value
+    }
+}
+
 impl<'a, CtxT> Executor<'a, CtxT> {
+    /// Resolve a single arbitrary value, mapping the context to a new type
+    pub fn resolve_with_ctx<NewCtxT, T: GraphQLType<Context=NewCtxT>>(
+        &self, value: &T
+    ) -> ExecutionResult
+        where NewCtxT: FromContext<CtxT>,
+    {
+        self.replaced_context(<NewCtxT as FromContext<CtxT>>::from_context(&self.context))
+            .resolve(value)
+    }
+
     /// Resolve a single arbitrary value into an `ExecutionResult`
-    pub fn resolve<T: GraphQLType<CtxT>>(&self, value: &T) -> ExecutionResult {
+    pub fn resolve<T: GraphQLType<Context=CtxT>>(&self, value: &T) -> ExecutionResult {
         Ok(value.resolve(
             match self.current_selection_set {
                 Some(ref sel) => Some(sel.clone()),
@@ -94,7 +129,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
     /// Resolve a single arbitrary value into a return value
     ///
     /// If the field fails to resolve, `null` will be returned.
-    pub fn resolve_into_value<T: GraphQLType<CtxT>>(&self, value: &T) -> Value {
+    pub fn resolve_into_value<T: GraphQLType<Context=CtxT>>(&self, value: &T) -> Value {
         match self.resolve(value) {
             Ok(v) => v,
             Err(e) => {
@@ -230,13 +265,13 @@ impl ExecutionError {
 pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
     document: Document,
     operation_name: Option<&str>,
-    root_node: &RootNode<CtxT, QueryT, MutationT>,
+    root_node: &RootNode<QueryT, MutationT>,
     variables: &HashMap<String, InputValue>,
     context: &CtxT
 )
     -> Result<(Value, Vec<ExecutionError>), GraphQLError<'a>>
-    where QueryT: GraphQLType<CtxT>,
-          MutationT: GraphQLType<CtxT>
+    where QueryT: GraphQLType<Context=CtxT>,
+          MutationT: GraphQLType<Context=CtxT>
 {
     let mut fragments = vec![];
     let mut operation = None;
@@ -290,12 +325,11 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
     Ok((value, errors))
 }
 
-impl<CtxT> Registry<CtxT> {
+impl Registry {
     /// Construct a new registry
-    pub fn new(types: HashMap<String, MetaType>) -> Registry<CtxT> {
+    pub fn new(types: HashMap<String, MetaType>) -> Registry {
         Registry {
             types: types,
-            phantom: PhantomData,
         }
     }
 
@@ -303,7 +337,7 @@ impl<CtxT> Registry<CtxT> {
     ///
     /// If the registry hasn't seen a type with this name before, it will
     /// construct its metadata and store it.
-    pub fn get_type<T>(&mut self) -> Type where T: GraphQLType<CtxT> {
+    pub fn get_type<T>(&mut self) -> Type where T: GraphQLType {
         if let Some(name) = T::name() {
             if !self.types.contains_key(name) {
                 self.insert_placeholder(name, Type::NonNullNamed(name.to_owned()));
@@ -318,7 +352,7 @@ impl<CtxT> Registry<CtxT> {
     }
 
     /// Create a field with the provided name
-    pub fn field<T>(&mut self, name: &str) -> Field where T: GraphQLType<CtxT> {
+    pub fn field<T>(&mut self, name: &str) -> Field where T: GraphQLType {
         Field {
             name: name.to_owned(),
             description: None,
@@ -329,7 +363,7 @@ impl<CtxT> Registry<CtxT> {
     }
 
     #[doc(hidden)]
-    pub fn field_convert<T: IntoFieldResult<I>, I>(&mut self, name: &str) -> Field where I: GraphQLType<CtxT> {
+    pub fn field_convert<T: IntoFieldResult<I>, I>(&mut self, name: &str) -> Field where I: GraphQLType {
         Field {
             name: name.to_owned(),
             description: None,
@@ -340,7 +374,7 @@ impl<CtxT> Registry<CtxT> {
     }
 
     #[doc(hidden)]
-    pub fn field_inside_result<T>(&mut self, name: &str, _: FieldResult<T>) -> Field where T: GraphQLType<CtxT> {
+    pub fn field_inside_result<T>(&mut self, name: &str, _: FieldResult<T>) -> Field where T: GraphQLType {
         Field {
             name: name.to_owned(),
             description: None,
@@ -351,7 +385,7 @@ impl<CtxT> Registry<CtxT> {
     }
 
     /// Create an argument with the provided name
-    pub fn arg<T>(&mut self, name: &str) -> Argument where T: GraphQLType<CtxT> + FromInputValue {
+    pub fn arg<T>(&mut self, name: &str) -> Argument where T: GraphQLType + FromInputValue {
         Argument::new(name, self.get_type::<T>())
     }
 
@@ -365,7 +399,7 @@ impl<CtxT> Registry<CtxT> {
         value: &T,
     )
         -> Argument
-        where T: GraphQLType<CtxT> + ToInputValue + FromInputValue
+        where T: GraphQLType + ToInputValue + FromInputValue
     {
         Argument::new(name, self.get_type::<Option<T>>())
             .default_value(value.to())
@@ -384,20 +418,20 @@ impl<CtxT> Registry<CtxT> {
     /// This expects the type to implement `FromInputValue`.
     pub fn build_scalar_type<T>(&mut self)
         -> ScalarMeta
-        where T: FromInputValue + GraphQLType<CtxT>
+        where T: FromInputValue + GraphQLType
     {
         let name = T::name().expect("Scalar types must be named. Implement name()");
         ScalarMeta::new::<T>(name)
     }
 
     /// Create a list meta type
-    pub fn build_list_type<T: GraphQLType<CtxT>>(&mut self) -> ListMeta {
+    pub fn build_list_type<T: GraphQLType>(&mut self) -> ListMeta {
         let of_type = self.get_type::<T>();
         ListMeta::new(of_type)
     }
 
     /// Create a nullable meta type
-    pub fn build_nullable_type<T: GraphQLType<CtxT>>(&mut self) -> NullableMeta {
+    pub fn build_nullable_type<T: GraphQLType>(&mut self) -> NullableMeta {
         let of_type = self.get_type::<T>();
         NullableMeta::new(of_type)
     }
@@ -408,7 +442,7 @@ impl<CtxT> Registry<CtxT> {
     /// function that needs to be called with the list of fields on the object.
     pub fn build_object_type<T>(&mut self)
         -> Box<Fn(&[Field]) -> ObjectMeta>
-        where T: GraphQLType<CtxT>
+        where T: GraphQLType
     {
         let name = T::name().expect("Object types must be named. Implement name()");
         let typename_field = self.field::<String>("__typename");
@@ -423,7 +457,7 @@ impl<CtxT> Registry<CtxT> {
     /// Create an enum meta type
     pub fn build_enum_type<T>(&mut self)
         -> Box<Fn(&[EnumValue]) -> EnumMeta>
-        where T: FromInputValue + GraphQLType<CtxT>
+        where T: FromInputValue + GraphQLType
     {
         let name = T::name().expect("Enum types must be named. Implement name()");
 
@@ -433,7 +467,7 @@ impl<CtxT> Registry<CtxT> {
     /// Create an interface meta type builder
     pub fn build_interface_type<T>(&mut self)
         -> Box<Fn(&[Field]) -> InterfaceMeta>
-        where T: GraphQLType<CtxT>
+        where T: GraphQLType
     {
         let name = T::name().expect("Interface types must be named. Implement name()");
         let typename_field = self.field::<String>("__typename");
@@ -448,7 +482,7 @@ impl<CtxT> Registry<CtxT> {
     /// Create a union meta type builder
     pub fn build_union_type<T>(&mut self)
         -> Box<Fn(&[Type]) -> UnionMeta>
-        where T: GraphQLType<CtxT>
+        where T: GraphQLType
     {
         let name = T::name().expect("Union types must be named. Implement name()");
 
@@ -458,7 +492,7 @@ impl<CtxT> Registry<CtxT> {
     /// Create an input object meta type builder
     pub fn build_input_object_type<T>(&mut self)
         -> Box<Fn(&[Argument]) -> InputObjectMeta>
-        where T: FromInputValue + GraphQLType<CtxT>
+        where T: FromInputValue + GraphQLType
     {
         let name = T::name().expect("Input object types must be named. Implement name()");
 
diff --git a/src/executor_tests/directives.rs b/src/executor_tests/directives.rs
index e3acaf08..b681dd01 100644
--- a/src/executor_tests/directives.rs
+++ b/src/executor_tests/directives.rs
@@ -3,6 +3,7 @@ use std::collections::HashMap;
 use value::Value;
 use ast::InputValue;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 struct TestType;
 
@@ -19,7 +20,7 @@ graphql_object!(TestType: () |&self| {
 fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
     where F: Fn(&HashMap<String, Value>) -> ()
 {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(query, None, &schema, &vars, &())
         .expect("Execution failed");
diff --git a/src/executor_tests/enums.rs b/src/executor_tests/enums.rs
index effca654..bfec7ba2 100644
--- a/src/executor_tests/enums.rs
+++ b/src/executor_tests/enums.rs
@@ -6,6 +6,7 @@ use schema::model::RootNode;
 use ::GraphQLError::ValidationError;
 use validation::RuleError;
 use parser::SourcePosition;
+use types::scalars::EmptyMutation;
 
 #[derive(Debug)]
 enum Color { Red, Green, Blue }
@@ -30,7 +31,7 @@ graphql_object!(TestType: () |&self| {
 fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
     where F: Fn(&HashMap<String, Value>) -> ()
 {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(query, None, &schema, &vars, &())
         .expect("Execution failed");
@@ -74,7 +75,7 @@ fn serializes_as_output() {
 
 #[test]
 fn does_not_accept_string_literals() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"{ toString(color: "RED") }"#;
     let vars = vec![
@@ -107,7 +108,7 @@ fn accepts_strings_in_variables() {
 
 #[test]
 fn does_not_accept_incorrect_enum_name_in_variables() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($color: Color!) { toString(color: $color) }"#;
     let vars = vec![
@@ -127,7 +128,7 @@ fn does_not_accept_incorrect_enum_name_in_variables() {
 
 #[test]
 fn does_not_accept_incorrect_type_in_variables() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($color: Color!) { toString(color: $color) }"#;
     let vars = vec![
diff --git a/src/executor_tests/executor.rs b/src/executor_tests/executor.rs
index bf725156..b389dc92 100644
--- a/src/executor_tests/executor.rs
+++ b/src/executor_tests/executor.rs
@@ -2,6 +2,7 @@ mod field_execution {
     use value::Value;
     use ast::InputValue;
     use schema::model::RootNode;
+    use types::scalars::EmptyMutation;
 
     struct DataType;
     struct DeepDataType;
@@ -33,7 +34,7 @@ mod field_execution {
 
     #[test]
     fn test() {
-        let schema = RootNode::new(DataType, ());
+        let schema = RootNode::new(DataType, EmptyMutation::<()>::new());
         let doc = r"
           query Example($size: Int) {
             a,
@@ -109,6 +110,7 @@ mod field_execution {
 mod merge_parallel_fragments {
     use value::Value;
     use schema::model::RootNode;
+    use types::scalars::EmptyMutation;
 
     struct Type;
 
@@ -121,7 +123,7 @@ mod merge_parallel_fragments {
 
     #[test]
     fn test() {
-        let schema = RootNode::new(Type, ());
+        let schema = RootNode::new(Type, EmptyMutation::<()>::new());
         let doc = r"
           { a, ...FragOne, ...FragTwo }
           fragment FragOne on Type {
@@ -162,6 +164,7 @@ mod merge_parallel_fragments {
 
 mod threads_context_correctly {
     use value::Value;
+    use types::scalars::EmptyMutation;
     use schema::model::RootNode;
 
     struct Schema;
@@ -172,7 +175,7 @@ mod threads_context_correctly {
 
     #[test]
     fn test() {
-        let schema = RootNode::new(Schema, ());
+        let schema = RootNode::new(Schema, EmptyMutation::<String>::new());
         let doc = r"{ a }";
 
         let vars = vec![].into_iter().collect();
@@ -197,6 +200,7 @@ mod nulls_out_errors {
     use schema::model::RootNode;
     use executor::{ExecutionError, FieldResult};
     use parser::SourcePosition;
+    use types::scalars::EmptyMutation;
 
     struct Schema;
 
@@ -207,7 +211,7 @@ mod nulls_out_errors {
 
     #[test]
     fn test() {
-        let schema = RootNode::new(Schema, ());
+        let schema = RootNode::new(Schema, EmptyMutation::<()>::new());
         let doc = r"{ sync, syncError }";
 
         let vars = vec![].into_iter().collect();
@@ -239,6 +243,7 @@ mod nulls_out_errors {
 mod named_operations {
     use value::Value;
     use schema::model::RootNode;
+    use types::scalars::EmptyMutation;
     use ::GraphQLError;
 
     struct Schema;
@@ -249,7 +254,7 @@ mod named_operations {
 
     #[test]
     fn uses_inline_operation_if_no_name_provided() {
-        let schema = RootNode::new(Schema, ());
+        let schema = RootNode::new(Schema, EmptyMutation::<()>::new());
         let doc = r"{ a }";
 
         let vars = vec![].into_iter().collect();
@@ -268,7 +273,7 @@ mod named_operations {
 
     #[test]
     fn uses_only_named_operation() {
-        let schema = RootNode::new(Schema, ());
+        let schema = RootNode::new(Schema, EmptyMutation::<()>::new());
         let doc = r"query Example { a }";
 
         let vars = vec![].into_iter().collect();
@@ -287,7 +292,7 @@ mod named_operations {
 
     #[test]
     fn uses_named_operation_if_name_provided() {
-        let schema = RootNode::new(Schema, ());
+        let schema = RootNode::new(Schema, EmptyMutation::<()>::new());
         let doc = r"query Example { first: a } query OtherExample { second: a }";
 
         let vars = vec![].into_iter().collect();
@@ -306,7 +311,7 @@ mod named_operations {
 
     #[test]
     fn error_if_multiple_operations_provided_but_no_name() {
-        let schema = RootNode::new(Schema, ());
+        let schema = RootNode::new(Schema, EmptyMutation::<()>::new());
         let doc = r"query Example { first: a } query OtherExample { second: a }";
 
         let vars = vec![].into_iter().collect();
@@ -319,7 +324,7 @@ mod named_operations {
 
     #[test]
     fn error_if_unknown_operation_name_provided() {
-        let schema = RootNode::new(Schema, ());
+        let schema = RootNode::new(Schema, EmptyMutation::<()>::new());
         let doc = r"query Example { first: a } query OtherExample { second: a }";
 
         let vars = vec![].into_iter().collect();
diff --git a/src/executor_tests/interfaces_unions.rs b/src/executor_tests/interfaces_unions.rs
index b840787d..b3dd252c 100644
--- a/src/executor_tests/interfaces_unions.rs
+++ b/src/executor_tests/interfaces_unions.rs
@@ -1,6 +1,7 @@
 mod interface {
     use value::Value;
     use schema::model::RootNode;
+    use types::scalars::EmptyMutation;
 
     trait Pet {
         fn name(&self) -> &str;
@@ -71,7 +72,7 @@ mod interface {
                     Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
                 ],
             },
-            ());
+            EmptyMutation::<()>::new());
         let doc = r"
           {
             pets {
@@ -118,6 +119,7 @@ mod interface {
 mod union {
     use value::Value;
     use schema::model::RootNode;
+    use types::scalars::EmptyMutation;
 
     trait Pet {
         fn as_dog(&self) -> Option<&Dog> { None }
@@ -178,7 +180,7 @@ mod union {
                     Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
                 ],
             },
-            ());
+            EmptyMutation::<()>::new());
         let doc = r"
           {
             pets {
diff --git a/src/executor_tests/introspection.rs b/src/executor_tests/introspection.rs
index e9cdc672..03b725e3 100644
--- a/src/executor_tests/introspection.rs
+++ b/src/executor_tests/introspection.rs
@@ -2,6 +2,7 @@ use std::collections::HashMap;
 
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 enum Sample {
     One,
@@ -67,7 +68,7 @@ fn test_execution() {
         second: sampleScalar(first: 10 second: 20)
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
@@ -104,7 +105,7 @@ fn enum_introspection() {
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
@@ -182,7 +183,7 @@ fn interface_introspection() {
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
@@ -283,7 +284,7 @@ fn object_introspection() {
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
@@ -395,7 +396,7 @@ fn scalar_introspection() {
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
diff --git a/src/executor_tests/variables.rs b/src/executor_tests/variables.rs
index 76a930c7..0d2c78a7 100644
--- a/src/executor_tests/variables.rs
+++ b/src/executor_tests/variables.rs
@@ -6,6 +6,7 @@ use schema::model::RootNode;
 use ::GraphQLError::ValidationError;
 use validation::RuleError;
 use parser::SourcePosition;
+use types::scalars::EmptyMutation;
 
 #[derive(Debug)]
 struct TestComplexScalar;
@@ -88,7 +89,7 @@ graphql_object!(TestType: () |&self| {
 fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
     where F: Fn(&HashMap<String, Value>) -> ()
 {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(query, None, &schema, &vars, &())
         .expect("Execution failed");
@@ -196,7 +197,7 @@ fn variable_runs_from_input_value_on_scalar() {
 
 #[test]
 fn variable_error_on_nested_non_null() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#;
     let vars = vec![
@@ -220,7 +221,7 @@ fn variable_error_on_nested_non_null() {
 
 #[test]
 fn variable_error_on_incorrect_type() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#;
     let vars = vec![
@@ -240,7 +241,7 @@ fn variable_error_on_incorrect_type() {
 
 #[test]
 fn variable_error_on_omit_non_null() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#;
     let vars = vec![
@@ -263,7 +264,7 @@ fn variable_error_on_omit_non_null() {
 
 #[test]
 fn variable_multiple_errors_with_nesting() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: TestNestedInputObject) { fieldWithNestedObjectInput(input: $input) }"#;
     let vars = vec![
@@ -291,7 +292,7 @@ fn variable_multiple_errors_with_nesting() {
 
 #[test]
 fn variable_error_on_additional_field() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#;
     let vars = vec![
@@ -377,7 +378,7 @@ fn allow_nullable_inputs_to_be_set_to_value_directly() {
 
 #[test]
 fn does_not_allow_non_nullable_input_to_be_omitted_in_variable() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($value: String!) { fieldWithNonNullableStringInput(input: $value) }"#;
     let vars = vec![
@@ -396,7 +397,7 @@ fn does_not_allow_non_nullable_input_to_be_omitted_in_variable() {
 
 #[test]
 fn does_not_allow_non_nullable_input_to_be_set_to_null_in_variable() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($value: String!) { fieldWithNonNullableStringInput(input: $value) }"#;
     let vars = vec![
@@ -489,7 +490,7 @@ fn allow_lists_to_contain_null() {
 
 #[test]
 fn does_not_allow_non_null_lists_to_be_null() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: [String]!) { nnList(input: $input) }"#;
     let vars = vec![
@@ -572,7 +573,7 @@ fn allow_lists_of_non_null_to_contain_values() {
 
 #[test]
 fn does_not_allow_lists_of_non_null_to_contain_null() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: [String!]) { listNn(input: $input) }"#;
     let vars = vec![
@@ -596,7 +597,7 @@ fn does_not_allow_lists_of_non_null_to_contain_null() {
 
 #[test]
 fn does_not_allow_non_null_lists_of_non_null_to_contain_null() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: [String!]!) { nnListNn(input: $input) }"#;
     let vars = vec![
@@ -620,7 +621,7 @@ fn does_not_allow_non_null_lists_of_non_null_to_contain_null() {
 
 #[test]
 fn does_not_allow_non_null_lists_of_non_null_to_be_null() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: [String!]!) { nnListNn(input: $input) }"#;
     let vars = vec![
@@ -656,7 +657,7 @@ fn allow_non_null_lists_of_non_null_to_contain_values() {
 
 #[test]
 fn does_not_allow_invalid_types_to_be_used_as_values() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: TestType!) { fieldWithObjectInput(input: $input) }"#;
     let vars = vec![
@@ -679,7 +680,7 @@ fn does_not_allow_invalid_types_to_be_used_as_values() {
 
 #[test]
 fn does_not_allow_unknown_types_to_be_used_as_values() {
-    let schema = RootNode::new(TestType, ());
+    let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
 
     let query = r#"query q($input: UnknownType!) { fieldWithObjectInput(input: $input) }"#;
     let vars = vec![
diff --git a/src/integrations/iron_handlers.rs b/src/integrations/iron_handlers.rs
index 91c12bc5..339c75f9 100644
--- a/src/integrations/iron_handlers.rs
+++ b/src/integrations/iron_handlers.rs
@@ -25,11 +25,11 @@ use ::{InputValue, GraphQLType, RootNode, execute};
 pub struct GraphQLHandler<CtxFactory, Query, Mutation, CtxT>
     where CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
           CtxT: 'static,
-          Query: GraphQLType<CtxT> + Send + Sync + 'static,
-          Mutation: GraphQLType<CtxT> + Send + Sync + 'static,
+          Query: GraphQLType<Context=CtxT> + Send + Sync + 'static,
+          Mutation: GraphQLType<Context=CtxT> + Send + Sync + 'static,
 {
     context_factory: CtxFactory,
-    root_node: RootNode<CtxT, Query, Mutation>,
+    root_node: RootNode<Query, Mutation>,
 }
 
 /// Handler that renders GraphiQL - a graphical query editor interface
@@ -41,8 +41,8 @@ impl<CtxFactory, Query, Mutation, CtxT>
     GraphQLHandler<CtxFactory, Query, Mutation, CtxT>
     where CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
           CtxT: 'static,
-          Query: GraphQLType<CtxT> + Send + Sync + 'static,
-          Mutation: GraphQLType<CtxT> + Send + Sync + 'static,
+          Query: GraphQLType<Context=CtxT> + Send + Sync + 'static,
+          Mutation: GraphQLType<Context=CtxT> + Send + Sync + 'static,
 {
     /// Build a new GraphQL handler
     ///
@@ -150,8 +150,8 @@ impl<CtxFactory, Query, Mutation, CtxT>
     for GraphQLHandler<CtxFactory, Query, Mutation, CtxT>
     where CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
           CtxT: 'static,
-          Query: GraphQLType<CtxT> + Send + Sync + 'static,
-          Mutation: GraphQLType<CtxT> + Send + Sync + 'static,
+          Query: GraphQLType<Context=CtxT> + Send + Sync + 'static,
+          Mutation: GraphQLType<Context=CtxT> + Send + Sync + 'static,
 {
     fn handle(&self, req: &mut Request) -> IronResult<Response> {
         match req.method {
@@ -248,6 +248,7 @@ mod tests {
     use iron::{Handler, Headers};
 
     use ::tests::model::Database;
+    use types::scalars::EmptyMutation;
 
     use super::GraphQLHandler;
 
@@ -259,7 +260,7 @@ mod tests {
         Box::new(GraphQLHandler::new(
             context_factory,
             Database::new(),
-            (),
+            EmptyMutation::<Database>::new(),
         ))
     }
 
diff --git a/src/lib.rs b/src/lib.rs
index 99fbcb6b..95df6f55 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -33,14 +33,18 @@ existing object types as GraphQL objects:
 ```rust
 #[macro_use] extern crate juniper;
 # use std::collections::HashMap;
-use juniper::FieldResult;
+use juniper::{Context, FieldResult};
 
 struct User { id: String, name: String, friend_ids: Vec<String>  }
 struct QueryRoot;
 struct Database { users: HashMap<String, User> }
 
+impl Context for Database {}
+
 // GraphQL objects can access a "context object" during execution. Use this
-// object to provide e.g. database access to the field accessors.
+// object to provide e.g. database access to the field accessors. This object
+// must implement the `Context` trait. If you don't need a context, use the
+// empty tuple `()` to indicate this.
 //
 // In this example, we use the Database struct as our context.
 graphql_object!(User: Database |&self| {
@@ -105,6 +109,7 @@ extern crate iron;
 
 use iron::prelude::*;
 use juniper::iron_handlers::GraphQLHandler;
+use juniper::{Context, EmptyMutation};
 
 # use juniper::FieldResult;
 #
@@ -150,11 +155,14 @@ fn context_factory(_: &mut Request) -> Database {
     }
 }
 
+impl Context for Database {}
+
 fn main() {
     // GraphQLHandler takes a context factory function, the root object,
     // and the mutation object. If we don't have any mutations to expose, we
     // can use the empty tuple () to indicate absence.
-    let graphql_endpoint = GraphQLHandler::new(context_factory, QueryRoot, ());
+    let graphql_endpoint = GraphQLHandler::new(
+        context_factory, QueryRoot, EmptyMutation::<Database>::new());
 
     // Start serving the schema at the root on port 8080.
     Iron::new(graphql_endpoint).http("localhost:8080").unwrap();
@@ -212,10 +220,11 @@ pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection};
 pub use value::Value;
 pub use types::base::{Arguments, GraphQLType, TypeKind};
 pub use executor::{
+    Context, FromContext,
     Executor, Registry, ExecutionResult, ExecutionError, FieldResult, IntoFieldResult,
 };
 pub use validation::RuleError;
-pub use types::scalars::ID;
+pub use types::scalars::{EmptyMutation, ID};
 pub use schema::model::RootNode;
 pub use result_ext::ResultExt;
 
@@ -238,13 +247,13 @@ pub enum GraphQLError<'a> {
 pub fn execute<'a, CtxT, QueryT, MutationT>(
     document_source: &'a str,
     operation_name: Option<&str>,
-    root_node: &RootNode<CtxT, QueryT, MutationT>,
+    root_node: &RootNode<QueryT, MutationT>,
     variables: &HashMap<String, InputValue>,
     context: &CtxT,
 )
     -> Result<(Value, Vec<ExecutionError>), GraphQLError<'a>>
-    where QueryT: GraphQLType<CtxT>,
-          MutationT: GraphQLType<CtxT>,
+    where QueryT: GraphQLType<Context=CtxT>,
+          MutationT: GraphQLType<Context=CtxT>,
 {
     let document = try!(parse_document_source(document_source));
 
diff --git a/src/macros/enums.rs b/src/macros/enums.rs
index 3e61c964..23424fdb 100644
--- a/src/macros/enums.rs
+++ b/src/macros/enums.rs
@@ -59,12 +59,14 @@ macro_rules! graphql_enum {
         ( $name:path, $outname:tt, $descr:tt ),
         [ $( ( $eval:tt, $ename:tt, $edescr:tt, $edepr:tt ) , )* ]
     ) => {
-        impl<CtxT> $crate::GraphQLType<CtxT> for $name {
+        impl $crate::GraphQLType for $name {
+            type Context = ();
+
             fn name() -> Option<&'static str> {
                 Some(graphql_enum!(@as_expr, $outname))
             }
 
-            fn meta(registry: &mut $crate::Registry<CtxT>) -> $crate::meta::MetaType {
+            fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
                 graphql_enum!(
                     @maybe_apply, $descr, description,
                     registry.build_enum_type::<$name>()(&[
@@ -81,7 +83,7 @@ macro_rules! graphql_enum {
                     .into_meta()
             }
 
-            fn resolve(&self, _: Option<Vec<$crate::Selection>>, _: &$crate::Executor<CtxT>) -> $crate::Value {
+            fn resolve(&self, _: Option<Vec<$crate::Selection>>, _: &$crate::Executor<Self::Context>) -> $crate::Value {
                 match self {
                     $(
                         &graphql_enum!(@as_pattern, $eval) =>
diff --git a/src/macros/field.rs b/src/macros/field.rs
index a03d6a12..64bff58d 100644
--- a/src/macros/field.rs
+++ b/src/macros/field.rs
@@ -77,7 +77,8 @@ macro_rules! __graphql__build_field_matches {
                     $body
                 })();
 
-                return ($crate::IntoFieldResult::into(result)).and_then(|r| $executorvar.resolve(&r))
+                return ($crate::IntoFieldResult::into(result)).and_then(
+                    |r| $executorvar.resolve_with_ctx(&r))
             }
         )*
         panic!("Field {} not found on type {}", $fieldvar, $outname);
diff --git a/src/macros/input_object.rs b/src/macros/input_object.rs
index 90b04077..7c76f2b2 100644
--- a/src/macros/input_object.rs
+++ b/src/macros/input_object.rs
@@ -148,12 +148,14 @@ macro_rules! graphql_input_object {
             }
         }
 
-        impl<CtxT> $crate::GraphQLType<CtxT> for $name {
+        impl $crate::GraphQLType for $name {
+            type Context = ();
+
             fn name() -> Option<&'static str> {
                 Some($outname)
             }
 
-            fn meta(registry: &mut $crate::Registry<CtxT>) -> $crate::meta::MetaType {
+            fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
                 graphql_input_object!(
                     @maybe_apply, $descr, description,
                     registry.build_input_object_type::<$name>()(
diff --git a/src/macros/interface.rs b/src/macros/interface.rs
index 01d27d42..41cb96a4 100644
--- a/src/macros/interface.rs
+++ b/src/macros/interface.rs
@@ -192,7 +192,7 @@ macro_rules! graphql_interface {
 
         $(
             if let Some(_) = $resolver as Option<$srctype> {
-                return (<$srctype as $crate::GraphQLType<$ctxttype>>::name()).unwrap().to_owned();
+                return (<$srctype as $crate::GraphQLType>::name()).unwrap().to_owned();
             }
         )*
 
@@ -208,7 +208,7 @@ macro_rules! graphql_interface {
         let $ctxtvar = &$execarg.context();
 
         $(
-            if $typenamearg == (<$srctype as $crate::GraphQLType<$ctxttype>>::name()).unwrap().to_owned() {
+            if $typenamearg == (<$srctype as $crate::GraphQLType>::name()).unwrap().to_owned() {
                 return $execarg.resolve(&$resolver);
             }
         )*
@@ -227,14 +227,16 @@ macro_rules! graphql_interface {
             $( $items:tt )*
         }
     ) => {
-        graphql_interface!(@as_item, impl<$($lifetime)*> $crate::GraphQLType<$ctxt> for $name {
+        graphql_interface!(@as_item, impl<$($lifetime)*> $crate::GraphQLType for $name {
+            type Context = $ctxt;
+
             fn name() -> Option<&'static str> {
                 Some($outname)
             }
 
             #[allow(unused_assignments)]
             #[allow(unused_mut)]
-            fn meta(registry: &mut $crate::Registry<$ctxt>) -> $crate::meta::MetaType {
+            fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
                 let mut fields = Vec::new();
                 let mut description = None;
                 graphql_interface!(@ gather_meta, (registry, fields, description), $($items)*);
@@ -249,14 +251,14 @@ macro_rules! graphql_interface {
 
             #[allow(unused_variables)]
             #[allow(unused_mut)]
-            fn resolve_field(&$mainself, field: &str, args: &$crate::Arguments, mut executor: &$crate::Executor<$ctxt>) -> $crate::ExecutionResult {
+            fn resolve_field(&$mainself, field: &str, args: &$crate::Arguments, mut executor: &$crate::Executor<Self::Context>) -> $crate::ExecutionResult {
                 __graphql__build_field_matches!(
                     ($outname, $mainself, field, args, executor),
                     (),
                     $($items)*);
             }
 
-            fn concrete_type_name(&$mainself, context: &$ctxt) -> String {
+            fn concrete_type_name(&$mainself, context: &Self::Context) -> String {
                 graphql_interface!(
                     @ concrete_type_name,
                     ($outname, context, $ctxt),
@@ -267,7 +269,7 @@ macro_rules! graphql_interface {
                 &$mainself,
                 type_name: &str,
                 _: Option<Vec<$crate::Selection>>,
-                executor: &$crate::Executor<$ctxt>,
+                executor: &$crate::Executor<Self::Context>,
             )
                 -> $crate::ExecutionResult
             {
diff --git a/src/macros/object.rs b/src/macros/object.rs
index 5330f0ed..fa440538 100644
--- a/src/macros/object.rs
+++ b/src/macros/object.rs
@@ -348,14 +348,16 @@ macro_rules! graphql_object {
         ( $($lifetime:tt)* );
         $name:ty; $ctxt:ty; $outname:expr; $mainself:ident; $($items:tt)*
     ) => {
-        graphql_object!(@as_item, impl<$($lifetime)*> $crate::GraphQLType<$ctxt> for $name {
+        graphql_object!(@as_item, impl<$($lifetime)*> $crate::GraphQLType for $name {
+            type Context = $ctxt;
+
             fn name() -> Option<&'static str> {
                 Some($outname)
             }
 
             #[allow(unused_assignments)]
             #[allow(unused_mut)]
-            fn meta(registry: &mut $crate::Registry<$ctxt>) -> $crate::meta::MetaType {
+            fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
                 let mut fields = Vec::new();
                 let mut description = None;
                 let mut interfaces: Option<Vec<$crate::Type>> = None;
@@ -382,7 +384,7 @@ macro_rules! graphql_object {
                 &$mainself,
                 field: &str,
                 args: &$crate::Arguments,
-                executor: &$crate::Executor<$ctxt>
+                executor: &$crate::Executor<Self::Context>
             )
                 -> $crate::ExecutionResult
             {
diff --git a/src/macros/scalar.rs b/src/macros/scalar.rs
index ad0d3253..269745e4 100644
--- a/src/macros/scalar.rs
+++ b/src/macros/scalar.rs
@@ -61,12 +61,14 @@ macro_rules! graphql_scalar {
             ( $fiv_arg:ident, $fiv_result:ty, $fiv_body:block )
         )
     ) => {
-        impl<CtxT> $crate::GraphQLType<CtxT> for $name {
+        impl $crate::GraphQLType for $name {
+            type Context = ();
+
             fn name() -> Option<&'static str> {
                 Some($outname)
             }
 
-            fn meta(registry: &mut $crate::Registry<CtxT>) -> $crate::meta::MetaType {
+            fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
                 graphql_scalar!(
                     @maybe_apply, $descr, description,
                     registry.build_scalar_type::<Self>())
@@ -76,7 +78,7 @@ macro_rules! graphql_scalar {
             fn resolve(
                 &$resolve_selfvar,
                 _: Option<Vec<$crate::Selection>>,
-                _: &$crate::Executor<CtxT>) -> $crate::Value {
+                _: &$crate::Executor<Self::Context>) -> $crate::Value {
                 $resolve_body
             }
         }
diff --git a/src/macros/tests/args.rs b/src/macros/tests/args.rs
index f677d43b..37d16eec 100644
--- a/src/macros/tests/args.rs
+++ b/src/macros/tests/args.rs
@@ -2,6 +2,7 @@ use std::collections::HashMap;
 
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 struct Root;
 
@@ -87,7 +88,7 @@ fn run_args_info_query<F>(field_name: &str, f: F)
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
diff --git a/src/macros/tests/enums.rs b/src/macros/tests/enums.rs
index 0576ecf9..db2bc686 100644
--- a/src/macros/tests/enums.rs
+++ b/src/macros/tests/enums.rs
@@ -2,6 +2,7 @@ use std::collections::HashMap;
 
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 
 enum DefaultName { Foo, Bar }
@@ -67,7 +68,7 @@ graphql_object!(Root: () |&self| {
 });
 
 fn run_type_info_query<F>(doc: &str, f: F) where F: Fn((&HashMap<String, Value>, &Vec<Value>)) -> () {
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
diff --git a/src/macros/tests/field.rs b/src/macros/tests/field.rs
index 16d6e8cd..2ac68c08 100644
--- a/src/macros/tests/field.rs
+++ b/src/macros/tests/field.rs
@@ -4,6 +4,7 @@ use value::Value;
 use ast::InputValue;
 use schema::model::RootNode;
 use executor::FieldResult;
+use types::scalars::EmptyMutation;
 
 struct Interface;
 struct Root;
@@ -71,7 +72,7 @@ fn run_field_info_query<F>(type_name: &str, field_name: &str, f: F)
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
     let vars = vec![
         ("typeName".to_owned(), InputValue::string(type_name)),
     ].into_iter().collect();
diff --git a/src/macros/tests/input_object.rs b/src/macros/tests/input_object.rs
index 28835e56..3999a201 100644
--- a/src/macros/tests/input_object.rs
+++ b/src/macros/tests/input_object.rs
@@ -3,6 +3,7 @@ use std::collections::HashMap;
 use ast::{InputValue, FromInputValue};
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 struct Root;
 
@@ -62,7 +63,7 @@ graphql_object!(Root: () |&self| {
 });
 
 fn run_type_info_query<F>(doc: &str, f: F) where F: Fn(&HashMap<String, Value>, &Vec<Value>) -> () {
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
diff --git a/src/macros/tests/interface.rs b/src/macros/tests/interface.rs
index 6afa25c8..b4c0e87d 100644
--- a/src/macros/tests/interface.rs
+++ b/src/macros/tests/interface.rs
@@ -4,6 +4,7 @@ use std::marker::PhantomData;
 use ast::InputValue;
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 /*
 
@@ -142,7 +143,7 @@ fn run_type_info_query<F>(type_name: &str, f: F)
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
     let vars = vec![
         ("typeName".to_owned(), InputValue::string(type_name)),
     ].into_iter().collect();
diff --git a/src/macros/tests/object.rs b/src/macros/tests/object.rs
index 63d8815d..c00d5df9 100644
--- a/src/macros/tests/object.rs
+++ b/src/macros/tests/object.rs
@@ -4,6 +4,7 @@ use std::marker::PhantomData;
 use ast::InputValue;
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 /*
 
@@ -130,7 +131,7 @@ fn run_type_info_query<F>(type_name: &str, f: F)
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
     let vars = vec![
         ("typeName".to_owned(), InputValue::string(type_name)),
     ].into_iter().collect();
diff --git a/src/macros/tests/scalar.rs b/src/macros/tests/scalar.rs
index 0cb832ca..c8744a22 100644
--- a/src/macros/tests/scalar.rs
+++ b/src/macros/tests/scalar.rs
@@ -2,6 +2,7 @@ use std::collections::HashMap;
 
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 struct DefaultName(i64);
 struct OtherOrder(i64);
@@ -69,7 +70,7 @@ graphql_object!(Root: () |&self| {
 });
 
 fn run_type_info_query<F>(doc: &str, f: F) where F: Fn(&HashMap<String, Value>) -> () {
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
 
     let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
         .expect("Execution failed");
diff --git a/src/macros/tests/union.rs b/src/macros/tests/union.rs
index 12d2c616..6bfd560b 100644
--- a/src/macros/tests/union.rs
+++ b/src/macros/tests/union.rs
@@ -4,6 +4,7 @@ use std::marker::PhantomData;
 use ast::InputValue;
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 
 /*
 
@@ -109,7 +110,7 @@ fn run_type_info_query<F>(type_name: &str, f: F)
         }
     }
     "#;
-    let schema = RootNode::new(Root {}, ());
+    let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
     let vars = vec![
         ("typeName".to_owned(), InputValue::string(type_name)),
     ].into_iter().collect();
diff --git a/src/macros/union.rs b/src/macros/union.rs
index 5a4dd0c6..0a78f26b 100644
--- a/src/macros/union.rs
+++ b/src/macros/union.rs
@@ -62,7 +62,7 @@ macro_rules! graphql_union {
 
         $(
             if let Some(_) = $resolver as Option<$srctype> {
-                return (<$srctype as $crate::GraphQLType<$ctxttype>>::name()).unwrap().to_owned();
+                return (<$srctype as $crate::GraphQLType>::name()).unwrap().to_owned();
             }
         )*
 
@@ -79,7 +79,7 @@ macro_rules! graphql_union {
         let $ctxtvar = &$execarg.context();
 
         $(
-            if $typenamearg == (<$srctype as $crate::GraphQLType<$ctxttype>>::name()).unwrap().to_owned() {
+            if $typenamearg == (<$srctype as $crate::GraphQLType>::name()).unwrap().to_owned() {
                 return $execarg.resolve(&$resolver);
             }
         )*
@@ -105,14 +105,16 @@ macro_rules! graphql_union {
             $( $items:tt )*
         }
     ) => {
-        graphql_union!(@as_item, impl<$($lifetime)*> $crate::GraphQLType<$ctxt> for $name {
+        graphql_union!(@as_item, impl<$($lifetime)*> $crate::GraphQLType for $name {
+            type Context = $ctxt;
+
             fn name() -> Option<&'static str> {
                 Some($outname)
             }
 
             #[allow(unused_assignments)]
             #[allow(unused_mut)]
-            fn meta(registry: &mut $crate::Registry<$ctxt>) -> $crate::meta::MetaType {
+            fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
                 let mut types;
                 let mut description = None;
                 graphql_union!(@ gather_meta, (registry, types, description), $($items)*);
@@ -125,7 +127,7 @@ macro_rules! graphql_union {
                 mt.into_meta()
             }
 
-            fn concrete_type_name(&$mainself, context: &$ctxt) -> String {
+            fn concrete_type_name(&$mainself, context: &Self::Context) -> String {
                 graphql_union!(
                     @ concrete_type_name,
                     ($outname, context, $ctxt),
@@ -136,7 +138,7 @@ macro_rules! graphql_union {
                 &$mainself,
                 type_name: &str,
                 _: Option<Vec<$crate::Selection>>,
-                executor: &$crate::Executor<$ctxt>,
+                executor: &$crate::Executor<Self::Context>,
             )
                 -> $crate::ExecutionResult
             {
diff --git a/src/schema/model.rs b/src/schema/model.rs
index 8836b638..870ac477 100644
--- a/src/schema/model.rs
+++ b/src/schema/model.rs
@@ -1,37 +1,24 @@
 use std::collections::HashMap;
-use std::marker::PhantomData;
 use std::fmt;
 
 use types::base::{GraphQLType};
-use executor::Registry;
+use executor::{Registry, Context};
 use ast::Type;
 use schema::meta::{MetaType, ObjectMeta, PlaceholderMeta, UnionMeta, InterfaceMeta, Argument};
 
 /// Root query node of a schema
 ///
-/// This brings the mutatino and query types together, and provides the
+/// This brings the mutation and query types together, and provides the
 /// predefined metadata fields.
-pub struct RootNode<InnerT, QueryT, MutationT=()> {
+pub struct RootNode<QueryT, MutationT> {
     #[doc(hidden)]
     pub query_type: QueryT,
     #[doc(hidden)]
     pub mutation_type: MutationT,
     #[doc(hidden)]
     pub schema: SchemaType,
-    phantom_wrapped: PhantomData<InnerT>,
 }
 
-// RootNode implements Send + Sync if both the mutation type and query
-// type implements them. SchemaType also needs to implement them.
-//
-// InnerT does _not_ need to implement Send + Sync because it does not
-// actually appear in the struct.
-unsafe impl<InnerT, QueryT, MutationT> Send for RootNode<InnerT, QueryT, MutationT>
-    where QueryT: Send, MutationT: Send, SchemaType: Send { }
-
-unsafe impl<InnerT, QueryT, MutationT> Sync for RootNode<InnerT, QueryT, MutationT>
-    where QueryT: Sync, MutationT: Sync, SchemaType: Sync { }
-
 /// Metadata for a schema
 pub struct SchemaType {
     types: HashMap<String, MetaType>,
@@ -40,6 +27,8 @@ pub struct SchemaType {
     directives: HashMap<String, DirectiveType>,
 }
 
+impl Context for SchemaType {}
+
 pub enum TypeType<'a> {
     Concrete(&'a MetaType),
     NonNull(Box<TypeType<'a>>),
@@ -63,82 +52,72 @@ pub enum DirectiveLocation {
     InlineFragment,
 }
 
-impl<InnerT, QueryT, MutationT> RootNode<InnerT, QueryT, MutationT>
-    where QueryT: GraphQLType<InnerT>,
-          MutationT: GraphQLType<InnerT>,
+impl<QueryT, MutationT> RootNode<QueryT, MutationT>
+    where QueryT: GraphQLType,
+          MutationT: GraphQLType,
 {
     /// Construct a new root node from query and mutation nodes
     ///
-    /// If the schema should not support mutations, you can pass in `()` to
-    /// remove the mutation type from the schema.
-    pub fn new(query_obj: QueryT, mutation_obj: MutationT) -> RootNode<InnerT, QueryT, MutationT> {
+    /// If the schema should not support mutations, use the
+    /// `new` constructor instead.
+    pub fn new(query_obj: QueryT, mutation_obj: MutationT) -> RootNode<QueryT, MutationT> {
         RootNode {
             query_type: query_obj,
             mutation_type: mutation_obj,
-            schema: SchemaType::new::<InnerT, QueryT, MutationT>(),
-            phantom_wrapped: PhantomData,
+            schema: SchemaType::new::<QueryT, MutationT>(),
         }
     }
 }
 
 impl SchemaType {
-    pub fn new<CtxT, QueryT, MutationT>() -> SchemaType
-        where QueryT: GraphQLType<CtxT>,
-              MutationT: GraphQLType<CtxT>,
+    pub fn new<QueryT, MutationT>() -> SchemaType
+        where QueryT: GraphQLType,
+              MutationT: GraphQLType,
     {
-        let mut types = HashMap::new();
         let mut directives = HashMap::new();
         let query_type_name: String;
         let mutation_type_name: String;
 
-        {
-            let mut registry = Registry::<CtxT>::new(types);
-            query_type_name = registry.get_type::<QueryT>().innermost_name().to_owned();
-            mutation_type_name = registry.get_type::<MutationT>().innermost_name().to_owned();
-            types = registry.types;
-        }
+        let mut registry = Registry::new(HashMap::new());
+        query_type_name = registry.get_type::<QueryT>().innermost_name().to_owned();
+        mutation_type_name = registry.get_type::<MutationT>().innermost_name().to_owned();
 
-        {
-            let mut registry = Registry::<SchemaType>::new(types);
-            registry.get_type::<SchemaType>();
-            directives.insert(
-                "skip".to_owned(),
-                DirectiveType::new_skip(&mut registry));
-            directives.insert(
-                "include".to_owned(),
-                DirectiveType::new_include(&mut registry));
+        registry.get_type::<SchemaType>();
+        directives.insert(
+            "skip".to_owned(),
+            DirectiveType::new_skip(&mut registry));
+        directives.insert(
+            "include".to_owned(),
+            DirectiveType::new_include(&mut registry));
 
-            let mut meta_fields = vec![
-                registry.field::<SchemaType>("__schema"),
-                registry.field::<TypeType>("__type")
-                    .argument(registry.arg::<String>("name")),
-            ];
+        let mut meta_fields = vec![
+            registry.field::<SchemaType>("__schema"),
+            registry.field::<TypeType>("__type")
+                .argument(registry.arg::<String>("name")),
+        ];
 
-            if let Some(root_type) = registry.types.get_mut(&query_type_name) {
-                if let &mut MetaType::Object(ObjectMeta { ref mut fields, .. }) = root_type {
-                    fields.append(&mut meta_fields);
-                }
-                else {
-                    panic!("Root type is not an object");
-                }
+        if let Some(root_type) = registry.types.get_mut(&query_type_name) {
+            if let &mut MetaType::Object(ObjectMeta { ref mut fields, .. }) = root_type {
+                fields.append(&mut meta_fields);
             }
             else {
-                panic!("Root type not found");
+                panic!("Root type is not an object");
             }
-
-            types = registry.types;
+        }
+        else {
+            panic!("Root type not found");
         }
 
-        for meta_type in types.values() {
+        for meta_type in registry.types.values() {
             if let MetaType::Placeholder(PlaceholderMeta { ref of_type }) = *meta_type {
                 panic!("Type {:?} is still a placeholder type", of_type);
             }
         }
 
         SchemaType {
-            types: types,
+            types: registry.types,
             query_type_name: query_type_name,
-            mutation_type_name: if &mutation_type_name != "__Unit" { Some(mutation_type_name) } else { None },
+            mutation_type_name: if &mutation_type_name != "__EmptyMutation" { Some(mutation_type_name) } else { None },
             directives: directives,
         }
     }
@@ -305,7 +284,7 @@ impl DirectiveType {
         }
     }
 
-    fn new_skip<CtxT>(registry: &mut Registry<CtxT>) -> DirectiveType {
+    fn new_skip(registry: &mut Registry) -> DirectiveType {
         Self::new(
             "skip",
             &[
@@ -318,7 +297,7 @@ impl DirectiveType {
             ])
     }
 
-    fn new_include<CtxT>(registry: &mut Registry<CtxT>) -> DirectiveType {
+    fn new_include(registry: &mut Registry) -> DirectiveType {
         Self::new(
             "include",
             &[
diff --git a/src/schema/schema.rs b/src/schema/schema.rs
index 9e3d580c..a7fca03e 100644
--- a/src/schema/schema.rs
+++ b/src/schema/schema.rs
@@ -7,15 +7,17 @@ use schema::meta::{MetaType, ObjectMeta, EnumMeta, InputObjectMeta, UnionMeta, I
                    Field, Argument, EnumValue};
 use schema::model::{RootNode, SchemaType, TypeType, DirectiveType, DirectiveLocation};
 
-impl<CtxT, QueryT, MutationT> GraphQLType<CtxT> for RootNode<CtxT, QueryT, MutationT>
-    where QueryT: GraphQLType<CtxT>,
-          MutationT: GraphQLType<CtxT>
+impl<CtxT, QueryT, MutationT> GraphQLType for RootNode<QueryT, MutationT>
+    where QueryT: GraphQLType<Context=CtxT>,
+          MutationT: GraphQLType<Context=CtxT>
 {
+    type Context = CtxT;
+
     fn name() -> Option<&'static str> {
         QueryT::name()
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         QueryT::meta(registry)
     }
 
diff --git a/src/tests/introspection_tests.rs b/src/tests/introspection_tests.rs
index 3ffa6326..97d7c587 100644
--- a/src/tests/introspection_tests.rs
+++ b/src/tests/introspection_tests.rs
@@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet};
 use value::Value;
 use schema::model::RootNode;
 use tests::model::Database;
+use types::scalars::EmptyMutation;
 
 #[test]
 fn test_query_type_name() {
@@ -15,7 +16,7 @@ fn test_query_type_name() {
           }
         }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -38,7 +39,7 @@ fn test_specific_type_name() {
           }
         }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -61,7 +62,7 @@ fn test_specific_object_type_name_and_kind() {
         }
         "#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -85,7 +86,7 @@ fn test_specific_interface_type_name_and_kind() {
         }
         "#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -109,7 +110,7 @@ fn test_documentation() {
         }
         "#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -135,7 +136,7 @@ fn test_possible_types() {
         }
         "#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     let result = ::execute(doc, None, &schema, &HashMap::new(), &database);
 
diff --git a/src/tests/query_tests.rs b/src/tests/query_tests.rs
index 3f128049..c9325efd 100644
--- a/src/tests/query_tests.rs
+++ b/src/tests/query_tests.rs
@@ -3,6 +3,7 @@ use std::collections::HashMap;
 use ast::InputValue;
 use value::Value;
 use schema::model::RootNode;
+use types::scalars::EmptyMutation;
 use tests::model::Database;
 
 #[test]
@@ -14,7 +15,7 @@ fn test_hero_name() {
             }
         }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -39,7 +40,7 @@ fn test_hero_name_and_friends() {
             }
         }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -80,7 +81,7 @@ fn test_hero_name_and_friends_and_friends_of_friends() {
             }
         }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -162,7 +163,7 @@ fn test_hero_name_and_friends_and_friends_of_friends() {
 fn test_query_name() {
     let doc = r#"{ human(id: "1000") { name } }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -178,7 +179,7 @@ fn test_query_name() {
 fn test_query_alias_single() {
     let doc = r#"{ luke: human(id: "1000") { name } }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -198,7 +199,7 @@ fn test_query_alias_multiple() {
             leia: human(id: "1003") { name }
         }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -226,7 +227,7 @@ fn test_query_alias_multiple_with_fragment() {
             homePlanet
         }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -247,7 +248,7 @@ fn test_query_alias_multiple_with_fragment() {
 fn test_query_name_variable() {
     let doc = r#"query FetchSomeIDQuery($someId: String!) { human(id: $someId) { name } }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     let vars = vec![
         ("someId".to_owned(), InputValue::string("1000")),
@@ -267,7 +268,7 @@ fn test_query_name_variable() {
 fn test_query_name_invalid_variable() {
     let doc = r#"query FetchSomeIDQuery($someId: String!) { human(id: $someId) { name } }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     let vars = vec![
         ("someId".to_owned(), InputValue::string("some invalid id")),
@@ -285,7 +286,7 @@ fn test_query_name_invalid_variable() {
 fn test_query_friends_names() {
     let doc = r#"{ human(id: "1000") { friends { name } } }"#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -325,7 +326,7 @@ fn test_query_inline_fragments_droid() {
         }
         "#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
@@ -350,7 +351,7 @@ fn test_query_inline_fragments_human() {
         }
         "#;
     let database = Database::new();
-    let schema = RootNode::new(&database, ());
+    let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
 
     assert_eq!(
         ::execute(doc, None, &schema, &HashMap::new(), &database),
diff --git a/src/tests/schema.rs b/src/tests/schema.rs
index e1182d68..0e36b721 100644
--- a/src/tests/schema.rs
+++ b/src/tests/schema.rs
@@ -1,4 +1,7 @@
 use tests::model::{Character, Human, Droid, Database, Episode};
+use executor::Context;
+
+impl Context for Database {}
 
 graphql_enum!(Episode {
     Episode::NewHope => "NEW_HOPE",
diff --git a/src/types/base.rs b/src/types/base.rs
index 3585b73e..d972a237 100644
--- a/src/types/base.rs
+++ b/src/types/base.rs
@@ -135,7 +135,7 @@ equivalent of the `User` object as shown in the example in the documentation
 root:
 
 ```rust
-use juniper::{GraphQLType, Registry, FieldResult,
+use juniper::{GraphQLType, Registry, FieldResult, Context,
               Arguments, Executor, ExecutionResult};
 use juniper::meta::MetaType;
 # use std::collections::HashMap;
@@ -143,15 +143,19 @@ use juniper::meta::MetaType;
 struct User { id: String, name: String, friend_ids: Vec<String>  }
 struct Database { users: HashMap<String, User> }
 
-impl GraphQLType<Database> for User {
+impl Context for Database {}
+
+impl GraphQLType for User {
+    type Context = Database;
+
     fn name() -> Option<&'static str> {
         Some("User")
     }
 
-    fn meta(registry: &mut Registry<Database>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         // First, we need to define all fields and their types on this type.
         //
-        // If need arguments, want to implement interfaces, or want to add
+        // If we need arguments, want to implement interfaces, or want to add
         // documentation strings, we can do it here.
         registry.build_object_type::<User>()(&[
                 registry.field::<&String>("id"),
@@ -171,12 +175,15 @@ impl GraphQLType<Database> for User {
     {
         // Next, we need to match the queried field name. All arms of this
         // match statement return `ExecutionResult`, which makes it hard to
-        // statically verify that the type you pass on to `executor.resolve`
+        // statically verify that the type you pass on to `executor.resolve*`
         // actually matches the one that you defined in `meta()` above.
         let database = executor.context();
         match field_name {
-            "id" => executor.resolve(&self.id),
-            "name" => executor.resolve(&self.name),
+            // Because scalars are defined with another `Context` associated
+            // type, you must use resolve_with_ctx here to make the executor
+            // perform automatic type conversion of its argument.
+            "id" => executor.resolve_with_ctx(&self.id),
+            "name" => executor.resolve_with_ctx(&self.name),
 
             // You pass a vector of User objects to `executor.resolve`, and it
             // will determine which fields of the sub-objects to actually
@@ -201,7 +208,14 @@ impl GraphQLType<Database> for User {
 ```
 
 */
-pub trait GraphQLType<CtxT>: Sized {
+pub trait GraphQLType: Sized {
+    /// The expected context type for this GraphQL type
+    ///
+    /// The context is threaded through query execution to all affected nodes,
+    /// and can be used to hold common data, e.g. database connections or
+    /// request session information.
+    type Context;
+
     /// The name of the GraphQL type to expose.
     ///
     /// This function will be called multiple times during schema construction.
@@ -210,7 +224,7 @@ pub trait GraphQLType<CtxT>: Sized {
     fn name() -> Option<&'static str>;
 
     /// The meta type representing this GraphQL type.
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType;
+    fn meta(registry: &mut Registry) -> MetaType;
 
     /// Resolve the value of a single field on this type.
     ///
@@ -221,7 +235,7 @@ pub trait GraphQLType<CtxT>: Sized {
     ///
     /// The default implementation panics.
     #[allow(unused_variables)]
-    fn resolve_field(&self, field_name: &str, arguments: &Arguments, executor: &Executor<CtxT>)
+    fn resolve_field(&self, field_name: &str, arguments: &Arguments, executor: &Executor<Self::Context>)
         -> ExecutionResult
     {
         panic!("resolve_field must be implemented by object types");
@@ -234,7 +248,7 @@ pub trait GraphQLType<CtxT>: Sized {
     ///
     /// The default implementation panics.
     #[allow(unused_variables)]
-    fn resolve_into_type(&self, type_name: &str, selection_set: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> ExecutionResult {
+    fn resolve_into_type(&self, type_name: &str, selection_set: Option<Vec<Selection>>, executor: &Executor<Self::Context>) -> ExecutionResult {
         if Self::name().unwrap() == type_name {
             Ok(self.resolve(selection_set, executor))
         } else {
@@ -246,7 +260,7 @@ pub trait GraphQLType<CtxT>: Sized {
     ///
     /// The default implementation panics.
     #[allow(unused_variables)]
-    fn concrete_type_name(&self, context: &CtxT) -> String {
+    fn concrete_type_name(&self, context: &Self::Context) -> String {
         panic!("concrete_type_name must be implemented by unions and interfaces");
     }
 
@@ -260,7 +274,7 @@ pub trait GraphQLType<CtxT>: Sized {
     /// The default implementation uses `resolve_field` to resolve all fields,
     /// including those through fragment expansion, for object types. For
     /// non-object types, this method panics.
-    fn resolve(&self, selection_set: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> Value {
+    fn resolve(&self, selection_set: Option<Vec<Selection>>, executor: &Executor<Self::Context>) -> Value {
         if let Some(selection_set) = selection_set {
             let mut result = HashMap::new();
             resolve_selection_set_into(self, selection_set, executor, &mut result);
@@ -277,7 +291,7 @@ fn resolve_selection_set_into<T, CtxT>(
     selection_set: Vec<Selection>,
     executor: &Executor<CtxT>,
     result: &mut HashMap<String, Value>)
-    where T: GraphQLType<CtxT>
+    where T: GraphQLType<Context=CtxT>
 {
     let meta_type = executor.schema()
         .concrete_type_by_name(T::name().expect("Resolving named type's selection set"))
diff --git a/src/types/containers.rs b/src/types/containers.rs
index 2fcb0d4e..86e8f14c 100644
--- a/src/types/containers.rs
+++ b/src/types/containers.rs
@@ -5,12 +5,14 @@ use schema::meta::MetaType;
 use executor::{Executor, Registry, IntoFieldResult, FieldResult};
 use types::base::{GraphQLType};
 
-impl<T, CtxT> GraphQLType<CtxT> for Option<T> where T: GraphQLType<CtxT> {
+impl<T, CtxT> GraphQLType for Option<T> where T: GraphQLType<Context=CtxT> {
+    type Context = CtxT;
+
     fn name() -> Option<&'static str> {
         None
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_nullable_type::<T>().into_meta()
     }
 
@@ -50,12 +52,14 @@ impl<T> IntoFieldResult<Option<T>> for Option<T> {
 }
 
 
-impl<T, CtxT> GraphQLType<CtxT> for Vec<T> where T: GraphQLType<CtxT> {
+impl<T, CtxT> GraphQLType for Vec<T> where T: GraphQLType<Context=CtxT> {
+    type Context = CtxT;
+
     fn name() -> Option<&'static str> {
         None
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_list_type::<T>().into_meta()
     }
 
@@ -102,12 +106,14 @@ impl<T> IntoFieldResult<Vec<T>> for Vec<T> {
 }
 
 
-impl<'a, T, CtxT> GraphQLType<CtxT> for &'a [T] where T: GraphQLType<CtxT> {
+impl<'a, T, CtxT> GraphQLType for &'a [T] where T: GraphQLType<Context=CtxT> {
+    type Context = CtxT;
+
     fn name() -> Option<&'static str> {
         None
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_list_type::<T>().into_meta()
     }
 
diff --git a/src/types/pointers.rs b/src/types/pointers.rs
index 7124945a..cf8d1b7d 100644
--- a/src/types/pointers.rs
+++ b/src/types/pointers.rs
@@ -5,12 +5,14 @@ use schema::meta::MetaType;
 use executor::{Executor, Registry, ExecutionResult, IntoFieldResult, FieldResult};
 use types::base::{Arguments, GraphQLType};
 
-impl<T, CtxT> GraphQLType<CtxT> for Box<T> where T: GraphQLType<CtxT> {
+impl<T, CtxT> GraphQLType for Box<T> where T: GraphQLType<Context=CtxT> {
+    type Context = CtxT;
+
     fn name() -> Option<&'static str> {
         T::name()
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         T::meta(registry)
     }
 
@@ -49,12 +51,14 @@ impl<T> IntoFieldResult<Box<T>> for Box<T> {
     }
 }
 
-impl<'a, T, CtxT> GraphQLType<CtxT> for &'a T where T: GraphQLType<CtxT> {
+impl<'a, T, CtxT> GraphQLType for &'a T where T: GraphQLType<Context=CtxT> {
+    type Context = CtxT;
+
     fn name() -> Option<&'static str> {
         T::name()
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         T::meta(registry)
     }
 
diff --git a/src/types/scalars.rs b/src/types/scalars.rs
index c7eac471..8d5f6499 100644
--- a/src/types/scalars.rs
+++ b/src/types/scalars.rs
@@ -1,3 +1,5 @@
+use std::marker::PhantomData;
+
 use ast::{InputValue, Selection, FromInputValue, ToInputValue};
 use value::Value;
 
@@ -40,16 +42,18 @@ graphql_scalar!(String as "String" {
 });
 
 
-impl<'a, CtxT> GraphQLType<CtxT> for &'a str {
+impl<'a> GraphQLType for &'a str {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("String")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_scalar_type::<String>().into_meta()
     }
 
-    fn resolve(&self, _: Option<Vec<Selection>>, _: &Executor<CtxT>) -> Value {
+    fn resolve(&self, _: Option<Vec<Selection>>, _: &Executor<Self::Context>) -> Value {
         Value::string(self)
     }
 }
@@ -111,12 +115,14 @@ graphql_scalar!(f64 as "Float" {
 });
 
 
-impl<CtxT> GraphQLType<CtxT> for () {
+impl GraphQLType for () {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("__Unit")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_scalar_type::<Self>().into_meta()
     }
 }
@@ -132,3 +138,39 @@ impl IntoFieldResult<()> for () {
         Ok(self)
     }
 }
+
+
+/// Utility type to define read-only schemas
+///
+/// If you instantiate `RootNode` with this as the mutation, no mutation will be
+/// generated for the schema.
+pub struct EmptyMutation<T> {
+    phantom: PhantomData<T>,
+}
+
+impl<T> EmptyMutation<T> {
+    /// Construct a new empty mutation
+    pub fn new() -> EmptyMutation<T> {
+        EmptyMutation {
+            phantom: PhantomData,
+        }
+    }
+}
+
+impl<T> GraphQLType for EmptyMutation<T> {
+    type Context = T;
+
+    fn name() -> Option<&'static str> {
+        Some("__EmptyMutation")
+    }
+
+    fn meta(registry: &mut Registry) -> MetaType {
+        registry.build_object_type::<Self>()(&[]).into_meta()
+    }
+}
+
+impl<T> IntoFieldResult<EmptyMutation<T>> for EmptyMutation<T> {
+    fn into(self) -> FieldResult<EmptyMutation<T>> {
+        Ok(self)
+    }
+}
diff --git a/src/validation/rules/overlapping_fields_can_be_merged.rs b/src/validation/rules/overlapping_fields_can_be_merged.rs
index 88000c49..2011279f 100644
--- a/src/validation/rules/overlapping_fields_can_be_merged.rs
+++ b/src/validation/rules/overlapping_fields_can_be_merged.rs
@@ -1164,12 +1164,14 @@ mod tests {
     struct Node;
     struct QueryRoot;
 
-    impl<CtxT> GraphQLType<CtxT> for SomeBox {
+    impl GraphQLType for SomeBox {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("SomeBox")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_interface_type::<Self>()(&[
                     registry.field::<Option<SomeBox>>("deepBox"),
                     registry.field::<Option<String>>("unrelatedField"),
@@ -1178,12 +1180,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for StringBox {
+    impl GraphQLType for StringBox {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("StringBox")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_object_type::<Self>()(&[
                     registry.field::<Option<String>>("scalar"),
                     registry.field::<Option<StringBox>>("deepBox"),
@@ -1199,12 +1203,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for IntBox {
+    impl GraphQLType for IntBox {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("IntBox")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_object_type::<Self>()(&[
                     registry.field::<Option<i64>>("scalar"),
                     registry.field::<Option<IntBox>>("deepBox"),
@@ -1220,12 +1226,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for NonNullStringBox1 {
+    impl GraphQLType for NonNullStringBox1 {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("NonNullStringBox1")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_interface_type::<Self>()(&[
                     registry.field::<String>("scalar"),
                 ])
@@ -1233,12 +1241,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for NonNullStringBox1Impl {
+    impl GraphQLType for NonNullStringBox1Impl {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("NonNullStringBox1Impl")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_object_type::<Self>()(&[
                     registry.field::<String>("scalar"),
                     registry.field::<Option<SomeBox>>("deepBox"),
@@ -1252,12 +1262,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for NonNullStringBox2 {
+    impl GraphQLType for NonNullStringBox2 {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("NonNullStringBox2")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_interface_type::<Self>()(&[
                     registry.field::<String>("scalar"),
                 ])
@@ -1265,12 +1277,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for NonNullStringBox2Impl {
+    impl GraphQLType for NonNullStringBox2Impl {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("NonNullStringBox2Impl")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_object_type::<Self>()(&[
                     registry.field::<String>("scalar"),
                     registry.field::<Option<SomeBox>>("deepBox"),
@@ -1284,12 +1298,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for Node {
+    impl GraphQLType for Node {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("Node")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_object_type::<Self>()(&[
                     registry.field::<Option<ID>>("id"),
                     registry.field::<Option<String>>("name"),
@@ -1298,12 +1314,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for Edge {
+    impl GraphQLType for Edge {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("Edge")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_object_type::<Self>()(&[
                     registry.field::<Option<Node>>("node"),
                 ])
@@ -1311,12 +1329,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for Connection {
+    impl GraphQLType for Connection {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("Connection")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.build_object_type::<Self>()(&[
                     registry.field::<Option<Vec<Option<Edge>>>>("edges"),
                 ])
@@ -1324,12 +1344,14 @@ mod tests {
         }
     }
 
-    impl<CtxT> GraphQLType<CtxT> for QueryRoot {
+    impl GraphQLType for QueryRoot {
+        type Context = ();
+
         fn name() -> Option<&'static str> {
             Some("QueryRoot")
         }
 
-        fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+        fn meta(registry: &mut Registry) -> MetaType {
             registry.get_type::<IntBox>();
             registry.get_type::<StringBox>();
             registry.get_type::<NonNullStringBox1Impl>();
diff --git a/src/validation/test_harness.rs b/src/validation/test_harness.rs
index 96277c17..40edc7e0 100644
--- a/src/validation/test_harness.rs
+++ b/src/validation/test_harness.rs
@@ -2,7 +2,7 @@ use parser::parse_document_source;
 use ast::{FromInputValue, InputValue};
 use types::base::GraphQLType;
 use executor::Registry;
-use types::scalars::ID;
+use types::scalars::{EmptyMutation, ID};
 use schema::model::{DirectiveType, DirectiveLocation, RootNode};
 use schema::meta::{EnumValue, MetaType};
 use validation::{Visitor, RuleError, ValidatorContext, MultiVisitor, visit};
@@ -51,12 +51,14 @@ struct ComplexInput {
     string_list_field: Option<Vec<Option<String>>>,
 }
 
-impl<CtxT> GraphQLType<CtxT> for Being {
+impl GraphQLType for Being {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("Being")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_interface_type::<Self>()(&[
                 registry.field::<Option<String>>("name")
                     .argument(registry.arg::<Option<bool>>("surname")),
@@ -65,12 +67,14 @@ impl<CtxT> GraphQLType<CtxT> for Being {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for Pet {
+impl GraphQLType for Pet {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("Pet")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_interface_type::<Self>()(&[
                 registry.field::<Option<String>>("name")
                     .argument(registry.arg::<Option<bool>>("surname")),
@@ -79,12 +83,14 @@ impl<CtxT> GraphQLType<CtxT> for Pet {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for Canine {
+impl GraphQLType for Canine {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("Canine")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_interface_type::<Self>()(&[
                 registry.field::<Option<String>>("name")
                     .argument(registry.arg::<Option<bool>>("surname")),
@@ -93,12 +99,14 @@ impl<CtxT> GraphQLType<CtxT> for Canine {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for DogCommand {
+impl GraphQLType for DogCommand {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("DogCommand")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_enum_type::<Self>()(&[
                 EnumValue::new("SIT"),
                 EnumValue::new("HEEL"),
@@ -119,12 +127,14 @@ impl FromInputValue for DogCommand {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for Dog {
+impl GraphQLType for Dog {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("Dog")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_object_type::<Self>()(&[
                 registry.field::<Option<String>>("name")
                     .argument(registry.arg::<Option<bool>>("surname")),
@@ -148,12 +158,14 @@ impl<CtxT> GraphQLType<CtxT> for Dog {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for FurColor {
+impl GraphQLType for FurColor {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("FurColor")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_enum_type::<Self>()(&[
                 EnumValue::new("BROWN"),
                 EnumValue::new("BLACK"),
@@ -176,12 +188,14 @@ impl FromInputValue for FurColor {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for Cat {
+impl GraphQLType for Cat {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("Cat")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_object_type::<Self>()(&[
                 registry.field::<Option<String>>("name")
                     .argument(registry.arg::<Option<bool>>("surname")),
@@ -198,12 +212,14 @@ impl<CtxT> GraphQLType<CtxT> for Cat {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for CatOrDog {
+impl GraphQLType for CatOrDog {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("CatOrDog")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_union_type::<Self>()(&[
                 registry.get_type::<Cat>(),
                 registry.get_type::<Dog>(),
@@ -212,12 +228,14 @@ impl<CtxT> GraphQLType<CtxT> for CatOrDog {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for Intelligent {
+impl GraphQLType for Intelligent {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("Intelligent")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_interface_type::<Self>()(&[
                 registry.field::<Option<i64>>("iq"),
             ])
@@ -225,12 +243,14 @@ impl<CtxT> GraphQLType<CtxT> for Intelligent {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for Human {
+impl GraphQLType for Human {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("Human")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_object_type::<Self>()(&[
                 registry.field::<Option<String>>("name")
                     .argument(registry.arg::<Option<bool>>("surname")),
@@ -246,12 +266,14 @@ impl<CtxT> GraphQLType<CtxT> for Human {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for Alien {
+impl GraphQLType for Alien {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("Alien")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_object_type::<Self>()(&[
                 registry.field::<Option<String>>("name")
                     .argument(registry.arg::<Option<bool>>("surname")),
@@ -266,12 +288,14 @@ impl<CtxT> GraphQLType<CtxT> for Alien {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for DogOrHuman {
+impl GraphQLType for DogOrHuman {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("DogOrHuman")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_union_type::<Self>()(&[
                 registry.get_type::<Dog>(),
                 registry.get_type::<Human>(),
@@ -280,12 +304,14 @@ impl<CtxT> GraphQLType<CtxT> for DogOrHuman {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for HumanOrAlien {
+impl GraphQLType for HumanOrAlien {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("HumanOrAlien")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_union_type::<Self>()(&[
                 registry.get_type::<Human>(),
                 registry.get_type::<Alien>(),
@@ -294,12 +320,14 @@ impl<CtxT> GraphQLType<CtxT> for HumanOrAlien {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for ComplexInput {
+impl GraphQLType for ComplexInput {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("ComplexInput")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_input_object_type::<Self>()(&[
                 registry.arg::<bool>("requiredField"),
                 registry.arg::<Option<i64>>("intField"),
@@ -331,12 +359,14 @@ impl FromInputValue for ComplexInput {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for ComplicatedArgs {
+impl GraphQLType for ComplicatedArgs {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("ComplicatedArgs")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_object_type::<Self>()(&[
                 registry.field::<Option<String>>("intArgField")
                     .argument(registry.arg::<Option<i64>>("intArg")),
@@ -372,12 +402,14 @@ impl<CtxT> GraphQLType<CtxT> for ComplicatedArgs {
     }
 }
 
-impl<CtxT> GraphQLType<CtxT> for QueryRoot {
+impl GraphQLType for QueryRoot {
+    type Context = ();
+
     fn name() -> Option<&'static str> {
         Some("QueryRoot")
     }
 
-    fn meta(registry: &mut Registry<CtxT>) -> MetaType {
+    fn meta(registry: &mut Registry) -> MetaType {
         registry.build_object_type::<Self>()(&[
                 registry.field::<Option<Human>>("human")
                     .argument(registry.arg::<Option<ID>>("id")),
@@ -396,11 +428,11 @@ impl<CtxT> GraphQLType<CtxT> for QueryRoot {
 
 pub fn validate<'a, R, V, F>(r: R, q: &str, factory: F)
     -> Vec<RuleError>
-    where R: GraphQLType<()>,
+    where R: GraphQLType,
           V: Visitor<'a> + 'a,
           F: Fn() -> V
 {
-    let mut root = RootNode::<(), R, ()>::new(r, ());
+    let mut root = RootNode::new(r, EmptyMutation::<()>::new());
 
     root.schema.add_directive(DirectiveType::new("onQuery", &[DirectiveLocation::Query], &[]));
     root.schema.add_directive(DirectiveType::new("onMutation", &[DirectiveLocation::Mutation], &[]));
@@ -429,7 +461,7 @@ pub fn expect_passes_rule<'a, V, F>(factory: F, q: &str)
 }
 
 pub fn expect_passes_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &str)
-    where R: GraphQLType<()>,
+    where R: GraphQLType,
           V: Visitor<'a> + 'a,
           F: Fn() -> V
 {
@@ -449,7 +481,7 @@ pub fn expect_fails_rule<'a, V, F>(factory: F, q: &str, expected_errors: &[RuleE
 }
 
 pub fn expect_fails_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &str, expected_errors: &[RuleError])
-    where R: GraphQLType<()>,
+    where R: GraphQLType,
           V: Visitor<'a> + 'a,
           F: Fn() -> V
 {