Repository: graphql-rust/juniper (language: rust)

Issue:
Nullable Fields For Input Objects Should  Accept Null As A Value. 
As suggested in [3.18](http://facebook.github.io/graphql/#sec-Types.Non-Null)  nullable types can both accept null and are optional. Furthermore, the table found in [Input Object](http://facebook.github.io/graphql/#sec-Input-Objects) section also says this as well. 

For example, I have the mutation:
 
```
mutation {
  createRma(rmaInput:{
          id: "test123"
	  status: false
	  companyName: null
  })
}
```

Represented in rust like so: 

```rust
graphql_input_object!(
     pub struct RmaInput {
         id: String,
         status: bool,
         company_name: Option<String>
    }
);
```

I get an error message that says "Unexpected \\"null\\""

While understand that having this field added is somewhat wasted typing, but it would be nice to explicitly state that is should be null. 


Discussion / hints:

Fix patch:
diff --git a/src/parser/value.rs b/src/parser/value.rs
index e7aa912a0..cda1607db 100644
--- a/src/parser/value.rs
+++ b/src/parser/value.rs
@@ -24,7 +24,7 @@ pub fn parse_value_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> Parse
         Spanning { item: Token::Name("false"), .. } =>
             Ok(parser.next().map(|_| InputValue::boolean(false))),
         Spanning { item: Token::Name("null"), .. } =>
-            Err(parser.next().map(ParseError::UnexpectedToken)),
+            Ok(parser.next().map(|_| InputValue::null())),
         Spanning { item: Token::Name(name), .. } =>
             Ok(parser.next().map(|_| InputValue::enum_value(name.to_owned()))),
         _ => Err(parser.next().map(ParseError::UnexpectedToken)),
diff --git a/src/types/utilities.rs b/src/types/utilities.rs
index d2b16dabd..c957d5a4f 100644
--- a/src/types/utilities.rs
+++ b/src/types/utilities.rs
@@ -21,7 +21,7 @@ pub fn is_valid_literal_value(schema: &SchemaType, arg_type: &TypeType, arg_valu
         }
         TypeType::Concrete(t) => {
             match *arg_value {
-                ref v @ InputValue::Null |
+                InputValue::Null => true,
                 ref v @ InputValue::Int(_) |
                 ref v @ InputValue::Float(_) |
                 ref v @ InputValue::String(_) |
diff --git a/src/validation/multi_visitor.rs b/src/validation/multi_visitor.rs
index bda0e43c0..f0e3de8d9 100644
--- a/src/validation/multi_visitor.rs
+++ b/src/validation/multi_visitor.rs
@@ -95,6 +95,13 @@ impl<'a> Visitor<'a> for MultiVisitor<'a> {
         self.visit_all(|v| v.exit_inline_fragment(ctx, f));
     }
 
+    fn enter_null_value(&mut self, ctx: &mut ValidatorContext<'a>, n: Spanning<()>) {
+        self.visit_all(|v| v.enter_null_value(ctx, n.clone()));
+    }
+    fn exit_null_value(&mut self, ctx: &mut ValidatorContext<'a>, n: Spanning<()>) {
+        self.visit_all(|v| v.exit_null_value(ctx, n.clone()));
+    }
+
     fn enter_int_value(&mut self, ctx: &mut ValidatorContext<'a>, i: Spanning<i64>) {
         self.visit_all(|v| v.enter_int_value(ctx, i.clone()));
     }
diff --git a/src/validation/rules/arguments_of_correct_type.rs b/src/validation/rules/arguments_of_correct_type.rs
index 1cffe4459..510f593f7 100644
--- a/src/validation/rules/arguments_of_correct_type.rs
+++ b/src/validation/rules/arguments_of_correct_type.rs
@@ -64,6 +64,33 @@ mod tests {
     use parser::SourcePosition;
     use validation::{RuleError, expect_passes_rule, expect_fails_rule};
 
+    #[test]
+    fn good_null_value() {
+        expect_passes_rule(factory, r#"
+            {
+              complicatedArgs {
+                intArgField(intArg: null)
+              }
+            }
+        "#);
+    }
+
+    #[test]
+    fn null_into_int() {
+        expect_fails_rule(factory, r#"
+            {
+              complicatedArgs {
+                nonNullIntArgField(nonNullIntArg: null)
+              }
+            }
+        "#,
+            &[
+                RuleError::new(&error_message("nonNullIntArg", "Int!"), &[
+                    SourcePosition::new(97, 3, 50),
+                ])
+            ]);
+    }
+
     #[test]
     fn good_int_value() {
         expect_passes_rule(factory, r#"
diff --git a/src/validation/traits.rs b/src/validation/traits.rs
index aaec53c43..8b97ff8ee 100644
--- a/src/validation/traits.rs
+++ b/src/validation/traits.rs
@@ -36,6 +36,9 @@ pub trait Visitor<'a> {
     fn enter_inline_fragment(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<InlineFragment>) {}
     fn exit_inline_fragment(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<InlineFragment>) {}
 
+    fn enter_null_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<()>) {}
+    fn exit_null_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<()>) {}
+
     fn enter_int_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<i64>) {}
     fn exit_int_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<i64>) {}
 
diff --git a/src/validation/visitor.rs b/src/validation/visitor.rs
index 7076a3315..856be7a3b 100644
--- a/src/validation/visitor.rs
+++ b/src/validation/visitor.rs
@@ -226,7 +226,7 @@ fn enter_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'
     let end = &input_value.end;
 
     match input_value.item {
-        Null => panic!("null values can't appear in the AST"),
+        Null => v.enter_null_value(ctx, Spanning::start_end(start, end, ())),
         Int(ref i) => v.enter_int_value(ctx, Spanning::start_end(start, end, *i)),
         Float(ref f) => v.enter_float_value(ctx, Spanning::start_end(start, end, *f)),
         String(ref s) => v.enter_string_value(ctx, Spanning::start_end(start, end, s)),
@@ -245,7 +245,7 @@ fn exit_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a
     let end = &input_value.end;
 
     match input_value.item {
-        Null => panic!("null values can't appear in the AST"),
+        Null => v.exit_null_value(ctx, Spanning::start_end(start, end, ())),
         Int(ref i) => v.exit_int_value(ctx, Spanning::start_end(start, end, *i)),
         Float(ref f) => v.exit_float_value(ctx, Spanning::start_end(start, end, *f)),
         String(ref s) => v.exit_string_value(ctx, Spanning::start_end(start, end, s)),


Test patch:
diff --git a/src/executor_tests/variables.rs b/src/executor_tests/variables.rs
index 2ba53b10a..a1baab7ce 100644
--- a/src/executor_tests/variables.rs
+++ b/src/executor_tests/variables.rs
@@ -338,6 +338,17 @@ fn allow_nullable_inputs_to_be_omitted_in_variable() {
         });
 }
 
+#[test]
+fn allow_nullable_inputs_to_be_explicitly_null() {
+    run_query(
+        r#"{ fieldWithNullableStringInput(input: null) }"#,
+        |result| {
+            assert_eq!(
+                result.get("fieldWithNullableStringInput"),
+                Some(&Value::string(r#"None"#)));
+        });
+}
+
 #[test]
 fn allow_nullable_inputs_to_be_set_to_null_in_variable() {
     run_variable_query(