diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md
index 68cc94c8f..4dc03f95d 100644
--- a/juniper/CHANGELOG.md
+++ b/juniper/CHANGELOG.md
@@ -53,6 +53,7 @@ All user visible changes to `juniper` crate will be documented in this file. Thi
 - Removed lifetime parameter from `ParseError`, `GraphlQLError`, `GraphQLBatchRequest` and `GraphQLRequest`. ([#1081], [#528])
 - Upgraded [GraphiQL] to 3.0.9 version (requires new [`graphql-transport-ws` GraphQL over WebSocket Protocol] integration on server, see `juniper_warp/examples/subscription.rs`). ([#1188], [#1193], [#1204])
 - Made `LookAheadMethods::children()` method to return slice instead of `Vec`. ([#1200])
+- Abstracted `Spanning::start` and `Spanning::end` fields into separate struct `Span`. ([#1207], [#1208])
 
 ### Added
 
@@ -131,6 +132,8 @@ All user visible changes to `juniper` crate will be documented in this file. Thi
 [#1199]: /../../pull/1199
 [#1200]: /../../pull/1200
 [#1204]: /../../pull/1204
+[#1207]: /../../pull/1207
+[#1208]: /../../pull/1208
 [ba1ed85b]: /../../commit/ba1ed85b3c3dd77fbae7baf6bc4e693321a94083
 [CVE-2022-31173]: /../../security/advisories/GHSA-4rx6-g5vg-5f3j
 
diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs
index fc39ef83f..d89ec1e2c 100644
--- a/juniper/src/executor/mod.rs
+++ b/juniper/src/executor/mod.rs
@@ -885,7 +885,7 @@ where
             schema: &root_node.schema,
             context,
             errors: &errors,
-            field_path: Arc::new(FieldPath::Root(operation.start)),
+            field_path: Arc::new(FieldPath::Root(operation.span.start)),
         };
 
         value = match operation.item.operation_type {
@@ -983,7 +983,7 @@ where
             schema: &root_node.schema,
             context,
             errors: &errors,
-            field_path: Arc::new(FieldPath::Root(operation.start)),
+            field_path: Arc::new(FieldPath::Root(operation.span.start)),
         };
 
         value = match operation.item.operation_type {
@@ -1129,7 +1129,7 @@ where
             schema: &root_node.schema,
             context,
             errors: &errors,
-            field_path: Arc::new(FieldPath::Root(operation.start)),
+            field_path: Arc::new(FieldPath::Root(operation.span.start)),
         };
 
         value = match operation.item.operation_type {
diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs
index 387799640..5080cffd0 100644
--- a/juniper/src/integrations/serde.rs
+++ b/juniper/src/integrations/serde.rs
@@ -252,8 +252,8 @@ impl Serialize for Spanning<ParseError> {
         map.serialize_value(&msg)?;
 
         let mut loc = IndexMap::new();
-        loc.insert("line".to_owned(), self.start.line() + 1);
-        loc.insert("column".to_owned(), self.start.column() + 1);
+        loc.insert("line".to_owned(), self.start().line() + 1);
+        loc.insert("column".to_owned(), self.start().column() + 1);
 
         let locations = vec![loc];
         map.serialize_key("locations")?;
diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs
index 43326eb39..43c286482 100644
--- a/juniper/src/lib.rs
+++ b/juniper/src/lib.rs
@@ -73,7 +73,7 @@ pub use crate::{
     },
     introspection::IntrospectionFormat,
     macros::helper::subscription::{ExtractTypeFromStream, IntoFieldResult},
-    parser::{ParseError, ScalarToken, Spanning},
+    parser::{ParseError, ScalarToken, Span, Spanning},
     schema::{
         meta,
         model::{RootNode, SchemaType},
diff --git a/juniper/src/parser/document.rs b/juniper/src/parser/document.rs
index cb2b308fb..4ace75abc 100644
--- a/juniper/src/parser/document.rs
+++ b/juniper/src/parser/document.rs
@@ -82,9 +82,8 @@ where
         let fields = fields.as_ref().map(|c| c as &[_]);
         let selection_set = parse_selection_set(parser, schema, fields)?;
 
-        Ok(Spanning::start_end(
-            &selection_set.start,
-            &selection_set.end,
+        Ok(Spanning::new(
+            selection_set.span,
             Operation {
                 operation_type: OperationType::Query,
                 name: None,
@@ -94,7 +93,7 @@ where
             },
         ))
     } else {
-        let start_pos = parser.peek().start;
+        let start_pos = parser.peek().span.start;
         let operation_type = parse_operation_type(parser)?;
         let op = match operation_type.item {
             OperationType::Query => Some(schema.concrete_query_type()),
@@ -114,7 +113,7 @@ where
 
         Ok(Spanning::start_end(
             &start_pos,
-            &selection_set.end,
+            &selection_set.span.end,
             Operation {
                 operation_type: operation_type.item,
                 name,
@@ -133,9 +132,7 @@ fn parse_fragment_definition<'a, 'b, S>(
 where
     S: ScalarValue,
 {
-    let Spanning {
-        start: start_pos, ..
-    } = parser.expect(&Token::Name("fragment"))?;
+    let start_pos = parser.expect(&Token::Name("fragment"))?.span.start;
     let name = match parser.expect_name() {
         Ok(n) => {
             if n.item == "on" {
@@ -160,7 +157,7 @@ where
 
     Ok(Spanning::start_end(
         &start_pos,
-        &selection_set.end,
+        &selection_set.span.end,
         Fragment {
             name,
             type_condition: type_cond,
@@ -222,10 +219,7 @@ fn parse_fragment<'a, 'b, S>(
 where
     S: ScalarValue,
 {
-    let Spanning {
-        start: ref start_pos,
-        ..
-    } = parser.expect(&Token::Ellipsis)?;
+    let start_pos = parser.expect(&Token::Ellipsis)?.span.start;
 
     match parser.peek().item {
         Token::Name("on") => {
@@ -240,8 +234,8 @@ where
             let selection_set = parse_selection_set(parser, schema, fields)?;
 
             Ok(Selection::InlineFragment(Spanning::start_end(
-                &start_pos.clone(),
-                &selection_set.end,
+                &start_pos,
+                &selection_set.span.end,
                 InlineFragment {
                     type_condition: Some(name),
                     directives: directives.map(|s| s.item),
@@ -253,8 +247,8 @@ where
             let selection_set = parse_selection_set(parser, schema, fields)?;
 
             Ok(Selection::InlineFragment(Spanning::start_end(
-                &start_pos.clone(),
-                &selection_set.end,
+                &start_pos,
+                &selection_set.span.end,
                 InlineFragment {
                     type_condition: None,
                     directives: None,
@@ -270,7 +264,7 @@ where
                 &start_pos.clone(),
                 &directives
                     .as_ref()
-                    .map_or(&frag_name.end, |s| &s.end)
+                    .map_or(&frag_name.span.end, |s| &s.span.end)
                     .clone(),
                 FragmentSpread {
                     name: frag_name,
@@ -283,8 +277,8 @@ where
             let selection_set = parse_selection_set(parser, schema, fields)?;
 
             Ok(Selection::InlineFragment(Spanning::start_end(
-                &start_pos.clone(),
-                &selection_set.end,
+                &start_pos,
+                &selection_set.span.end,
                 InlineFragment {
                     type_condition: None,
                     directives: directives.map(|s| s.item),
@@ -329,13 +323,13 @@ where
     let selection_set = parse_optional_selection_set(parser, schema, fields)?;
 
     Ok(Spanning::start_end(
-        &alias.as_ref().unwrap_or(&name).start.clone(),
+        &alias.as_ref().unwrap_or(&name).span.start,
         &selection_set
             .as_ref()
-            .map(|s| &s.end)
-            .or_else(|| directives.as_ref().map(|s| &s.end))
-            .or_else(|| arguments.as_ref().map(|s| &s.end))
-            .unwrap_or(&name.end)
+            .map(|s| &s.span.end)
+            .or_else(|| directives.as_ref().map(|s| &s.span.end))
+            .or_else(|| arguments.as_ref().map(|s| &s.span.end))
+            .unwrap_or(&name.span.end)
             .clone(),
         Field {
             alias,
@@ -389,8 +383,8 @@ where
     let value = parse_value_literal(parser, false, schema, tpe)?;
 
     Ok(Spanning::start_end(
-        &name.start.clone(),
-        &value.end.clone(),
+        &name.span.start,
+        &value.span.end.clone(),
         (name, value),
     ))
 }
@@ -437,9 +431,7 @@ fn parse_variable_definition<'a, 'b, S>(
 where
     S: ScalarValue,
 {
-    let Spanning {
-        start: start_pos, ..
-    } = parser.expect(&Token::Dollar)?;
+    let start_pos = parser.expect(&Token::Dollar)?.span.start;
     let var_name = parser.expect_name()?;
     parser.expect(&Token::Colon)?;
     let var_type = parse_type(parser)?;
@@ -457,10 +449,10 @@ where
         &start_pos,
         &default_value
             .as_ref()
-            .map_or(&var_type.end, |s| &s.end)
+            .map_or(&var_type.span.end, |s| &s.span.end)
             .clone(),
         (
-            Spanning::start_end(&start_pos, &var_name.end, var_name.item),
+            Spanning::start_end(&start_pos, &var_name.span.end, var_name.item),
             VariableDefinition {
                 var_type,
                 default_value,
@@ -496,9 +488,7 @@ fn parse_directive<'a, 'b, S>(
 where
     S: ScalarValue,
 {
-    let Spanning {
-        start: start_pos, ..
-    } = parser.expect(&Token::At)?;
+    let start_pos = parser.expect(&Token::At)?.span.start;
     let name = parser.expect_name()?;
 
     let directive = schema.directive_by_name(name.item);
@@ -511,20 +501,24 @@ where
 
     Ok(Spanning::start_end(
         &start_pos,
-        &arguments.as_ref().map_or(&name.end, |s| &s.end).clone(),
+        &arguments
+            .as_ref()
+            .map_or(&name.span.end, |s| &s.span.end)
+            .clone(),
         Directive { name, arguments },
     ))
 }
 
 pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult<Type<'a>> {
     let parsed_type = if let Some(Spanning {
-        start: start_pos, ..
+        span: ref start_span,
+        ..
     }) = parser.skip(&Token::BracketOpen)?
     {
         let inner_type = parse_type(parser)?;
-        let Spanning { end: end_pos, .. } = parser.expect(&Token::BracketClose)?;
+        let end_pos = parser.expect(&Token::BracketClose)?.span.end;
         Spanning::start_end(
-            &start_pos,
+            &start_span.start,
             &end_pos,
             Type::List(Box::new(inner_type.item), None),
         )
@@ -542,7 +536,7 @@ pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult<Type<'a>> {
 }
 
 fn wrap_non_null<'a>(parser: &mut Parser<'a>, inner: Spanning<Type<'a>>) -> ParseResult<Type<'a>> {
-    let Spanning { end: end_pos, .. } = parser.expect(&Token::ExclamationMark)?;
+    let end_pos = &parser.expect(&Token::ExclamationMark)?.span.end;
 
     let wrapped = match inner.item {
         Type::Named(name) => Type::NonNullNamed(name),
@@ -550,5 +544,5 @@ fn wrap_non_null<'a>(parser: &mut Parser<'a>, inner: Spanning<Type<'a>>) -> Pars
         t => t,
     };
 
-    Ok(Spanning::start_end(&inner.start, &end_pos, wrapped))
+    Ok(Spanning::start_end(&inner.span.start, end_pos, wrapped))
 }
diff --git a/juniper/src/parser/mod.rs b/juniper/src/parser/mod.rs
index f64225c2d..04d34901e 100644
--- a/juniper/src/parser/mod.rs
+++ b/juniper/src/parser/mod.rs
@@ -15,5 +15,5 @@ pub use self::document::parse_document_source;
 pub use self::{
     lexer::{Lexer, LexerError, ScalarToken, Token},
     parser::{OptionParseResult, ParseError, ParseResult, Parser, UnlocatedParseResult},
-    utils::{SourcePosition, Spanning},
+    utils::{SourcePosition, Span, Spanning},
 };
diff --git a/juniper/src/parser/parser.rs b/juniper/src/parser/parser.rs
index b0c270995..d053ec42f 100644
--- a/juniper/src/parser/parser.rs
+++ b/juniper/src/parser/parser.rs
@@ -97,9 +97,8 @@ impl<'a> Parser<'a> {
     #[doc(hidden)]
     pub fn next_token(&mut self) -> ParseResult<Token<'a>> {
         if self.tokens.len() == 1 {
-            Err(Spanning::start_end(
-                &self.peek().start,
-                &self.peek().end,
+            Err(Spanning::new(
+                self.peek().span,
                 ParseError::UnexpectedEndOfFile,
             ))
         } else {
@@ -125,7 +124,7 @@ impl<'a> Parser<'a> {
             Ok(Some(self.next_token()?))
         } else if self.peek().item == Token::EndOfFile {
             Err(Spanning::zero_width(
-                &self.peek().start,
+                &self.peek().span.start,
                 ParseError::UnexpectedEndOfFile,
             ))
         } else {
@@ -144,14 +143,12 @@ impl<'a> Parser<'a> {
         T: fmt::Debug,
         F: Fn(&mut Parser<'a>) -> ParseResult<T>,
     {
-        let Spanning {
-            start: start_pos, ..
-        } = self.expect(opening)?;
+        let start_pos = &self.expect(opening)?.span.start;
         let mut items = Vec::new();
 
         loop {
-            if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
-                return Ok(Spanning::start_end(&start_pos, &end_pos, items));
+            if let Some(Spanning { span, .. }) = self.skip(closing)? {
+                return Ok(Spanning::start_end(start_pos, &span.end, items));
             }
 
             items.push(parser(self)?);
@@ -169,16 +166,14 @@ impl<'a> Parser<'a> {
         T: fmt::Debug,
         F: Fn(&mut Parser<'a>) -> ParseResult<T>,
     {
-        let Spanning {
-            start: start_pos, ..
-        } = self.expect(opening)?;
+        let start_pos = &self.expect(opening)?.span.start;
         let mut items = Vec::new();
 
         loop {
             items.push(parser(self)?);
 
-            if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
-                return Ok(Spanning::start_end(&start_pos, &end_pos, items));
+            if let Some(end_spanning) = self.skip(closing)? {
+                return Ok(Spanning::start_end(start_pos, &end_spanning.end(), items));
             }
         }
     }
@@ -194,16 +189,14 @@ impl<'a> Parser<'a> {
         T: fmt::Debug,
         F: Fn(&mut Parser<'a>) -> UnlocatedParseResult<T>,
     {
-        let Spanning {
-            start: start_pos, ..
-        } = self.expect(opening)?;
+        let start_pos = &self.expect(opening)?.span.start;
         let mut items = Vec::new();
 
         loop {
             items.push(parser(self)?);
 
-            if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
-                return Ok(Spanning::start_end(&start_pos, &end_pos, items));
+            if let Some(end_spanning) = self.skip(closing)? {
+                return Ok(Spanning::start_end(start_pos, &end_spanning.end(), items));
             }
         }
     }
@@ -224,9 +217,8 @@ impl<'a> Parser<'a> {
             Spanning {
                 item: Token::EndOfFile,
                 ..
-            } => Err(Spanning::start_end(
-                &self.peek().start,
-                &self.peek().end,
+            } => Err(Spanning::new(
+                self.peek().span,
                 ParseError::UnexpectedEndOfFile,
             )),
             _ => Err(self.next_token()?.map(ParseError::unexpected_token)),
diff --git a/juniper/src/parser/tests/lexer.rs b/juniper/src/parser/tests/lexer.rs
index a1dc5b695..0eb62ae73 100644
--- a/juniper/src/parser/tests/lexer.rs
+++ b/juniper/src/parser/tests/lexer.rs
@@ -342,8 +342,8 @@ fn numbers() {
         expected: &str,
     ) {
         let parsed = tokenize_single(source);
-        assert_eq!(parsed.start, start);
-        assert_eq!(parsed.end, end);
+        assert_eq!(parsed.span.start, start);
+        assert_eq!(parsed.span.end, end);
 
         match parsed.item {
             Token::Scalar(ScalarToken::Float(actual)) => {
diff --git a/juniper/src/parser/utils.rs b/juniper/src/parser/utils.rs
index 645c30141..3ff0318d5 100644
--- a/juniper/src/parser/utils.rs
+++ b/juniper/src/parser/utils.rs
@@ -8,65 +8,90 @@ pub struct SourcePosition {
     col: usize,
 }
 
-/// Data structure used to wrap items with start and end markers in the input source
-///
-/// A "span" is a range of characters in the input source, starting at the
-/// character pointed by the `start` field and ending just before the `end`
-/// marker.
-#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
-pub struct Spanning<T> {
-    /// The wrapped item
-    pub item: T,
-
-    /// Start position of the item
+/// Range of characters in the input source, starting at the character pointed by the `start` field
+/// and ending just before the `end` marker.
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub struct Span {
+    /// Start position of this [`Span`].
     pub start: SourcePosition,
 
-    /// End position of the item
+    /// End position of this [`Span`].
     ///
-    /// This points to the first source position _after_ the wrapped item.
+    /// > __NOTE__: This points to the first source position __after__ this [`Span`].
     pub end: SourcePosition,
 }
 
-impl<T> Spanning<T> {
+impl Span {
     #[doc(hidden)]
-    pub fn zero_width(pos: &SourcePosition, item: T) -> Spanning<T> {
-        Spanning {
-            item,
-            start: *pos,
-            end: *pos,
+    #[inline]
+    pub fn zero_width(pos: SourcePosition) -> Self {
+        Self {
+            start: pos,
+            end: pos,
         }
     }
 
     #[doc(hidden)]
-    pub fn single_width(pos: &SourcePosition, item: T) -> Spanning<T> {
-        let mut end = *pos;
+    #[inline]
+    pub fn single_width(pos: SourcePosition) -> Self {
+        let mut end = pos;
         end.advance_col();
 
-        Spanning {
-            item,
-            start: *pos,
-            end,
-        }
+        Self { start: pos, end }
     }
 
     #[doc(hidden)]
-    pub fn start_end(start: &SourcePosition, end: &SourcePosition, item: T) -> Spanning<T> {
-        Spanning {
-            item,
-            start: *start,
-            end: *end,
+    #[inline]
+    pub fn unlocated() -> Self {
+        Self {
+            start: SourcePosition::new_origin(),
+            end: SourcePosition::new_origin(),
         }
     }
+}
+
+/// Data structure used to wrap items into a [`Span`].
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub struct Spanning<T> {
+    /// Wrapped item.
+    pub item: T,
+
+    /// [`Span`] of the wrapped item.
+    pub span: Span,
+}
+
+impl<T> Spanning<T> {
+    #[doc(hidden)]
+    pub fn new(span: Span, item: T) -> Self {
+        Self { item, span }
+    }
+
+    #[doc(hidden)]
+    pub fn zero_width(&pos: &SourcePosition, item: T) -> Spanning<T> {
+        Self::new(Span::zero_width(pos), item)
+    }
+
+    #[doc(hidden)]
+    pub fn single_width(&pos: &SourcePosition, item: T) -> Spanning<T> {
+        Self::new(Span::single_width(pos), item)
+    }
+
+    #[doc(hidden)]
+    pub fn start_end(&start: &SourcePosition, &end: &SourcePosition, item: T) -> Spanning<T> {
+        Self::new(Span { start, end }, item)
+    }
 
     #[doc(hidden)]
     #[allow(clippy::self_named_constructors)]
     pub fn spanning(v: Vec<Spanning<T>>) -> Option<Spanning<Vec<Spanning<T>>>> {
-        if let (Some(start), Some(end)) = (v.first().map(|s| s.start), v.last().map(|s| s.end)) {
-            Some(Spanning {
-                item: v,
-                start,
-                end,
-            })
+        if let (Some(start), Some(end)) = (v.first().map(|s| s.span), v.last().map(|s| s.span)) {
+            Some(Spanning::new(
+                Span {
+                    start: start.start,
+                    end: end.end,
+                },
+                v,
+            ))
         } else {
             None
         }
@@ -74,33 +99,38 @@ impl<T> Spanning<T> {
 
     #[doc(hidden)]
     pub fn unlocated(item: T) -> Spanning<T> {
-        Spanning {
-            item,
-            start: SourcePosition::new_origin(),
-            end: SourcePosition::new_origin(),
-        }
+        Self::new(Span::unlocated(), item)
+    }
+
+    /// Returns start position of the item.
+    #[inline]
+    pub fn start(&self) -> SourcePosition {
+        self.span.start
+    }
+
+    /// Returns end position of the item.
+    ///
+    /// > __NOTE__: This points to the first source position __after__ the item.
+    #[inline]
+    pub fn end(&self) -> SourcePosition {
+        self.span.end
     }
 
     /// Modify the contents of the spanned item.
     pub fn map<O, F: Fn(T) -> O>(self, f: F) -> Spanning<O> {
-        Spanning {
-            item: f(self.item),
-            start: self.start,
-            end: self.end,
-        }
+        Spanning::new(self.span, f(self.item))
     }
 
     /// Modifies the contents of the spanned item in case `f` returns [`Some`],
     /// or returns [`None`] otherwise.
     pub fn and_then<O, F: Fn(T) -> Option<O>>(self, f: F) -> Option<Spanning<O>> {
-        let (start, end) = (self.start, self.end);
-        f(self.item).map(|item| Spanning { item, start, end })
+        f(self.item).map(|item| Spanning::new(self.span, item))
     }
 }
 
 impl<T: fmt::Display> fmt::Display for Spanning<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}. At {}", self.item, self.start)
+        write!(f, "{}. At {}", self.item, self.span.start)
     }
 }
 
diff --git a/juniper/src/parser/value.rs b/juniper/src/parser/value.rs
index 21f4518f1..53a8103fe 100644
--- a/juniper/src/parser/value.rs
+++ b/juniper/src/parser/value.rs
@@ -1,7 +1,7 @@
 use crate::ast::InputValue;
 
 use crate::{
-    parser::{ParseError, ParseResult, Parser, ScalarToken, SourcePosition, Spanning, Token},
+    parser::{ParseError, ParseResult, Parser, ScalarToken, Spanning, Token},
     schema::{
         meta::{InputObjectMeta, MetaType},
         model::SchemaType,
@@ -9,6 +9,8 @@ use crate::{
     value::ScalarValue,
 };
 
+use super::utils::Span;
+
 pub fn parse_value_literal<'b, S>(
     parser: &mut Parser<'_>,
     is_const: bool,
@@ -56,13 +58,12 @@ where
         ) => {
             if let Spanning {
                 item: Token::Scalar(scalar),
-                start,
-                end,
+                span,
             } = parser.next_token()?
             {
                 (s.parse_fn)(scalar)
-                    .map(|s| Spanning::start_end(&start, &end, InputValue::Scalar(s)))
-                    .or_else(|_| parse_scalar_literal_by_infered_type(scalar, &start, &end, schema))
+                    .map(|s| Spanning::new(span, InputValue::Scalar(s)))
+                    .or_else(|_| parse_scalar_literal_by_infered_type(scalar, span, schema))
             } else {
                 unreachable!()
             }
@@ -76,11 +77,10 @@ where
         ) => {
             if let Spanning {
                 item: Token::Scalar(token),
-                start,
-                end,
+                span,
             } = parser.next_token()?
             {
-                parse_scalar_literal_by_infered_type(token, &start, &end, schema)
+                parse_scalar_literal_by_infered_type(token, span, schema)
             } else {
                 unreachable!()
             }
@@ -173,8 +173,8 @@ where
     let value = parse_value_literal(parser, is_const, schema, tpe)?;
 
     Ok(Spanning::start_end(
-        &key.start,
-        &value.end.clone(),
+        &key.span.start,
+        &value.span.end.clone(),
         (key.map(|s| s.to_owned()), value),
     ))
 }
@@ -183,26 +183,23 @@ fn parse_variable_literal<S>(parser: &mut Parser<'_>) -> ParseResult<InputValue<
 where
     S: ScalarValue,
 {
-    let Spanning {
-        start: start_pos, ..
-    } = parser.expect(&Token::Dollar)?;
+    let start_pos = &parser.expect(&Token::Dollar)?.span.start;
     let Spanning {
         item: name,
-        end: end_pos,
+        span: end_span,
         ..
     } = parser.expect_name()?;
 
     Ok(Spanning::start_end(
-        &start_pos,
-        &end_pos,
+        start_pos,
+        &end_span.end,
         InputValue::variable(name),
     ))
 }
 
 fn parse_scalar_literal_by_infered_type<'b, S>(
     token: ScalarToken<'_>,
-    start: &SourcePosition,
-    end: &SourcePosition,
+    span: Span,
     schema: &'b SchemaType<'b, S>,
 ) -> ParseResult<InputValue<S>>
 where
@@ -238,6 +235,6 @@ where
         }
     };
     result
-        .map(|s| Spanning::start_end(start, end, s))
-        .map_err(|e| Spanning::start_end(start, end, e))
+        .map(|s| Spanning::new(span, s))
+        .map_err(|e| Spanning::new(span, e))
 }
diff --git a/juniper/src/types/async_await.rs b/juniper/src/types/async_await.rs
index 28fa6e904..f0988cf3b 100644
--- a/juniper/src/types/async_await.rs
+++ b/juniper/src/types/async_await.rs
@@ -207,8 +207,7 @@ where
         match *selection {
             Selection::Field(Spanning {
                 item: ref f,
-                start: ref start_pos,
-                ..
+                ref span,
             }) => {
                 if is_excluded(&f.directives, executor.variables()) {
                     continue;
@@ -237,7 +236,7 @@ where
                 let sub_exec = executor.field_sub_executor(
                     response_name,
                     f.name.item,
-                    *start_pos,
+                    span.start,
                     f.selection_set.as_ref().map(|v| &v[..]),
                 );
                 let args = Arguments::new(
@@ -252,7 +251,7 @@ where
                     &meta_field.arguments,
                 );
 
-                let pos = *start_pos;
+                let pos = span.start;
                 let is_non_null = meta_field.field_type.is_non_null();
 
                 let response_name = response_name.to_string();
@@ -285,8 +284,7 @@ where
 
             Selection::FragmentSpread(Spanning {
                 item: ref spread,
-                start: ref start_pos,
-                ..
+                ref span,
             }) => {
                 if is_excluded(&spread.directives, executor.variables()) {
                     continue;
@@ -327,15 +325,14 @@ where
                             ));
                         }
                     } else if let Err(e) = sub_result {
-                        sub_exec.push_error_at(e, *start_pos);
+                        sub_exec.push_error_at(e, span.start);
                     }
                 }
             }
 
             Selection::InlineFragment(Spanning {
                 item: ref fragment,
-                start: ref start_pos,
-                ..
+                ref span,
             }) => {
                 if is_excluded(&fragment.directives, executor.variables()) {
                     continue;
@@ -372,7 +369,7 @@ where
                                 ));
                             }
                         } else if let Err(e) = sub_result {
-                            sub_exec.push_error_at(e, *start_pos);
+                            sub_exec.push_error_at(e, span.start);
                         }
                     }
                 } else {
diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs
index d1debc4b9..c99825091 100644
--- a/juniper/src/types/base.rs
+++ b/juniper/src/types/base.rs
@@ -431,8 +431,7 @@ where
         match *selection {
             Selection::Field(Spanning {
                 item: ref f,
-                start: ref start_pos,
-                ..
+                ref span,
             }) => {
                 if is_excluded(&f.directives, executor.variables()) {
                     continue;
@@ -461,7 +460,7 @@ where
                 let sub_exec = executor.field_sub_executor(
                     response_name,
                     f.name.item,
-                    *start_pos,
+                    span.start,
                     f.selection_set.as_ref().map(|v| &v[..]),
                 );
 
@@ -486,7 +485,7 @@ where
                     Ok(Value::Null) if meta_field.field_type.is_non_null() => return false,
                     Ok(v) => merge_key_into(result, response_name, v),
                     Err(e) => {
-                        sub_exec.push_error_at(e, *start_pos);
+                        sub_exec.push_error_at(e, span.start);
 
                         if meta_field.field_type.is_non_null() {
                             return false;
@@ -498,8 +497,7 @@ where
             }
             Selection::FragmentSpread(Spanning {
                 item: ref spread,
-                start: ref start_pos,
-                ..
+                span,
             }) => {
                 if is_excluded(&spread.directives, executor.variables()) {
                     continue;
@@ -533,14 +531,13 @@ where
                             merge_key_into(result, &k, v);
                         }
                     } else if let Err(e) = sub_result {
-                        sub_exec.push_error_at(e, *start_pos);
+                        sub_exec.push_error_at(e, span.start);
                     }
                 }
             }
             Selection::InlineFragment(Spanning {
                 item: ref fragment,
-                start: ref start_pos,
-                ..
+                ref span,
             }) => {
                 if is_excluded(&fragment.directives, executor.variables()) {
                     continue;
@@ -570,7 +567,7 @@ where
                                 merge_key_into(result, &k, v);
                             }
                         } else if let Err(e) = sub_result {
-                            sub_exec.push_error_at(e, *start_pos);
+                            sub_exec.push_error_at(e, span.start);
                         }
                     }
                 } else if !resolve_selection_set_into(
diff --git a/juniper/src/types/subscriptions.rs b/juniper/src/types/subscriptions.rs
index 63fa14e44..4b575c82a 100644
--- a/juniper/src/types/subscriptions.rs
+++ b/juniper/src/types/subscriptions.rs
@@ -283,8 +283,7 @@ where
         match selection {
             Selection::Field(Spanning {
                 item: ref f,
-                start: ref start_pos,
-                ..
+                ref span,
             }) => {
                 if is_excluded(&f.directives, executor.variables()) {
                     continue;
@@ -308,7 +307,7 @@ where
                 let sub_exec = executor.field_sub_executor(
                     response_name,
                     f.name.item,
-                    *start_pos,
+                    span.start,
                     f.selection_set.as_ref().map(|x| &x[..]),
                 );
 
@@ -336,7 +335,7 @@ where
                     }
                     Ok(v) => merge_key_into(&mut object, response_name, v),
                     Err(e) => {
-                        sub_exec.push_error_at(e, *start_pos);
+                        sub_exec.push_error_at(e, span.start);
 
                         if meta_field.field_type.is_non_null() {
                             return Value::Null;
@@ -349,8 +348,7 @@ where
 
             Selection::FragmentSpread(Spanning {
                 item: ref spread,
-                start: ref start_pos,
-                ..
+                ref span,
             }) => {
                 if is_excluded(&spread.directives, executor.variables()) {
                     continue;
@@ -382,14 +380,13 @@ where
                             _ => unreachable!(),
                         }
                     }
-                    Err(e) => sub_exec.push_error_at(e, *start_pos),
+                    Err(e) => sub_exec.push_error_at(e, span.start),
                 }
             }
 
             Selection::InlineFragment(Spanning {
                 item: ref fragment,
-                start: ref start_pos,
-                ..
+                ref span,
             }) => {
                 if is_excluded(&fragment.directives, executor.variables()) {
                     continue;
@@ -410,7 +407,7 @@ where
                             merge_key_into(&mut object, &k, v);
                         }
                     } else if let Err(e) = sub_result {
-                        sub_exec.push_error_at(e, *start_pos);
+                        sub_exec.push_error_at(e, span.start);
                     }
                 } else if let Some(type_name) = meta_type.name() {
                     let sub_result = instance
@@ -422,7 +419,7 @@ where
                             merge_key_into(&mut object, &k, v);
                         }
                     } else if let Err(e) = sub_result {
-                        sub_exec.push_error_at(e, *start_pos);
+                        sub_exec.push_error_at(e, span.start);
                     }
                 } else {
                     return Value::Null;
diff --git a/juniper/src/validation/input_value.rs b/juniper/src/validation/input_value.rs
index 432126f8c..1c906bbbe 100644
--- a/juniper/src/validation/input_value.rs
+++ b/juniper/src/validation/input_value.rs
@@ -58,12 +58,12 @@ fn validate_var_defs<S>(
                             r#"Variable "${}" of required type "{}" was not provided."#,
                             name.item, def.var_type.item,
                         ),
-                        &[name.start],
+                        &[name.span.start],
                     ));
                 } else if let Some(v) = values.get(name.item) {
                     errors.append(&mut unify_value(
                         name.item,
-                        &name.start,
+                        &name.span.start,
                         v,
                         &ct,
                         schema,
diff --git a/juniper/src/validation/rules/arguments_of_correct_type.rs b/juniper/src/validation/rules/arguments_of_correct_type.rs
index 85a8959f6..424b8027f 100644
--- a/juniper/src/validation/rules/arguments_of_correct_type.rs
+++ b/juniper/src/validation/rules/arguments_of_correct_type.rs
@@ -61,7 +61,7 @@ where
             if !is_valid_literal_value(ctx.schema, &meta_type, &arg_value.item) {
                 ctx.report_error(
                     &error_message(arg_name.item, &argument_meta.arg_type),
-                    &[arg_value.start],
+                    &[arg_value.span.start],
                 );
             }
         }
diff --git a/juniper/src/validation/rules/default_values_of_correct_type.rs b/juniper/src/validation/rules/default_values_of_correct_type.rs
index f3d254623..a1a648ffa 100644
--- a/juniper/src/validation/rules/default_values_of_correct_type.rs
+++ b/juniper/src/validation/rules/default_values_of_correct_type.rs
@@ -25,14 +25,13 @@ where
     ) {
         if let Some(Spanning {
             item: ref var_value,
-            ref start,
-            ..
+            ref span,
         }) = var_def.default_value
         {
             if var_def.var_type.item.is_non_null() {
                 ctx.report_error(
                     &non_null_error_message(var_name.item, &var_def.var_type.item),
-                    &[*start],
+                    &[span.start],
                 )
             } else {
                 let meta_type = ctx.schema.make_type(&var_def.var_type.item);
@@ -40,7 +39,7 @@ where
                 if !is_valid_literal_value(ctx.schema, &meta_type, var_value) {
                     ctx.report_error(
                         &type_error_message(var_name.item, &var_def.var_type.item),
-                        &[*start],
+                        &[span.start],
                     );
                 }
             }
diff --git a/juniper/src/validation/rules/fields_on_correct_type.rs b/juniper/src/validation/rules/fields_on_correct_type.rs
index b195df459..1e3f7e028 100644
--- a/juniper/src/validation/rules/fields_on_correct_type.rs
+++ b/juniper/src/validation/rules/fields_on_correct_type.rs
@@ -30,7 +30,7 @@ where
                         context.report_error(
                             "`__typename` may not be included as a root \
                              field in a subscription operation",
-                            &[field.item.name.start],
+                            &[field.item.name.span.start],
                         );
                     }
                 }
@@ -60,7 +60,7 @@ where
 
                     context.report_error(
                         &error_message(field_name.item, type_name),
-                        &[field_name.start],
+                        &[field_name.span.start],
                     );
                 }
             }
diff --git a/juniper/src/validation/rules/fragments_on_composite_types.rs b/juniper/src/validation/rules/fragments_on_composite_types.rs
index 927f46de8..c5e9b804f 100644
--- a/juniper/src/validation/rules/fragments_on_composite_types.rs
+++ b/juniper/src/validation/rules/fragments_on_composite_types.rs
@@ -28,7 +28,7 @@ where
 
                     context.report_error(
                         &error_message(Some(f.item.name.item), type_name),
-                        &[type_cond.start],
+                        &[type_cond.span.start],
                     );
                 }
             }
@@ -50,7 +50,7 @@ where
                     .next();
 
                 if let Some(name) = invalid_type_name {
-                    context.report_error(&error_message(None, name), &[type_cond.start]);
+                    context.report_error(&error_message(None, name), &[type_cond.span.start]);
                 }
             }
         }
diff --git a/juniper/src/validation/rules/known_argument_names.rs b/juniper/src/validation/rules/known_argument_names.rs
index 3239b514a..c8e11820f 100644
--- a/juniper/src/validation/rules/known_argument_names.rs
+++ b/juniper/src/validation/rules/known_argument_names.rs
@@ -84,7 +84,7 @@ where
                     }
                 };
 
-                ctx.report_error(&message, &[arg_name.start]);
+                ctx.report_error(&message, &[arg_name.span.start]);
             }
         }
     }
diff --git a/juniper/src/validation/rules/known_directives.rs b/juniper/src/validation/rules/known_directives.rs
index 9a2b9f5b1..47bc9fdcb 100644
--- a/juniper/src/validation/rules/known_directives.rs
+++ b/juniper/src/validation/rules/known_directives.rs
@@ -143,12 +143,15 @@ where
                 {
                     ctx.report_error(
                         &misplaced_error_message(directive_name, current_location),
-                        &[directive.start],
+                        &[directive.span.start],
                     );
                 }
             }
         } else {
-            ctx.report_error(&unknown_error_message(directive_name), &[directive.start]);
+            ctx.report_error(
+                &unknown_error_message(directive_name),
+                &[directive.span.start],
+            );
         }
     }
 }
diff --git a/juniper/src/validation/rules/known_fragment_names.rs b/juniper/src/validation/rules/known_fragment_names.rs
index ac4b7b193..0e4ebb102 100644
--- a/juniper/src/validation/rules/known_fragment_names.rs
+++ b/juniper/src/validation/rules/known_fragment_names.rs
@@ -22,7 +22,7 @@ where
     ) {
         let spread_name = &spread.item.name;
         if !context.is_known_fragment(spread_name.item) {
-            context.report_error(&error_message(spread_name.item), &[spread_name.start]);
+            context.report_error(&error_message(spread_name.item), &[spread_name.span.start]);
         }
     }
 }
diff --git a/juniper/src/validation/rules/known_type_names.rs b/juniper/src/validation/rules/known_type_names.rs
index 7f926b598..863147cfa 100644
--- a/juniper/src/validation/rules/known_type_names.rs
+++ b/juniper/src/validation/rules/known_type_names.rs
@@ -22,7 +22,7 @@ where
         fragment: &'a Spanning<InlineFragment<S>>,
     ) {
         if let Some(ref type_cond) = fragment.item.type_condition {
-            validate_type(ctx, type_cond.item, &type_cond.start);
+            validate_type(ctx, type_cond.item, &type_cond.span.start);
         }
     }
 
@@ -32,7 +32,7 @@ where
         fragment: &'a Spanning<Fragment<S>>,
     ) {
         let type_cond = &fragment.item.type_condition;
-        validate_type(ctx, type_cond.item, &type_cond.start);
+        validate_type(ctx, type_cond.item, &type_cond.span.start);
     }
 
     fn enter_variable_definition(
@@ -41,7 +41,7 @@ where
         (_, var_def): &'a (Spanning<&'a str>, VariableDefinition<S>),
     ) {
         let type_name = var_def.var_type.item.innermost_name();
-        validate_type(ctx, type_name, &var_def.var_type.start);
+        validate_type(ctx, type_name, &var_def.var_type.span.start);
     }
 }
 
diff --git a/juniper/src/validation/rules/lone_anonymous_operation.rs b/juniper/src/validation/rules/lone_anonymous_operation.rs
index cea1b234e..7b9af4120 100644
--- a/juniper/src/validation/rules/lone_anonymous_operation.rs
+++ b/juniper/src/validation/rules/lone_anonymous_operation.rs
@@ -37,7 +37,7 @@ where
     ) {
         if let Some(operation_count) = self.operation_count {
             if operation_count > 1 && op.item.name.is_none() {
-                ctx.report_error(error_message(), &[op.start]);
+                ctx.report_error(error_message(), &[op.span.start]);
             }
         }
     }
diff --git a/juniper/src/validation/rules/no_fragment_cycles.rs b/juniper/src/validation/rules/no_fragment_cycles.rs
index e32e1d53e..d4ba2d3f7 100644
--- a/juniper/src/validation/rules/no_fragment_cycles.rs
+++ b/juniper/src/validation/rules/no_fragment_cycles.rs
@@ -73,11 +73,7 @@ where
             self.spreads
                 .entry(current_fragment)
                 .or_default()
-                .push(Spanning::start_end(
-                    &spread.start,
-                    &spread.end,
-                    spread.item.name.item,
-                ));
+                .push(Spanning::new(spread.span, spread.item.name.item));
         }
     }
 }
@@ -131,7 +127,7 @@ impl<'a> CycleDetector<'a> {
                 };
 
                 self.errors
-                    .push(RuleError::new(&error_message(name), &[err_pos.start]));
+                    .push(RuleError::new(&error_message(name), &[err_pos.span.start]));
             } else {
                 let mut path = path.clone();
                 path.push(node);
diff --git a/juniper/src/validation/rules/no_undefined_variables.rs b/juniper/src/validation/rules/no_undefined_variables.rs
index 77368f5ed..6b697ec0b 100644
--- a/juniper/src/validation/rules/no_undefined_variables.rs
+++ b/juniper/src/validation/rules/no_undefined_variables.rs
@@ -99,7 +99,7 @@ where
                 unused
                     .into_iter()
                     .map(|var| {
-                        RuleError::new(&error_message(var.item, *op_name), &[var.start, *pos])
+                        RuleError::new(&error_message(var.item, *op_name), &[var.span.start, *pos])
                     })
                     .collect(),
             );
@@ -114,7 +114,7 @@ where
         let op_name = op.item.name.as_ref().map(|s| s.item);
         self.current_scope = Some(Scope::Operation(op_name));
         self.defined_variables
-            .insert(op_name, (op.start, HashSet::new()));
+            .insert(op_name, (op.span.start, HashSet::new()));
     }
 
     fn enter_fragment_definition(
@@ -164,7 +164,7 @@ where
                         .item
                         .referenced_variables()
                         .iter()
-                        .map(|&var_name| Spanning::start_end(&value.start, &value.end, var_name))
+                        .map(|&var_name| Spanning::new(value.span, var_name))
                         .collect(),
                 );
         }
diff --git a/juniper/src/validation/rules/no_unused_fragments.rs b/juniper/src/validation/rules/no_unused_fragments.rs
index 794869ad1..d728acb77 100644
--- a/juniper/src/validation/rules/no_unused_fragments.rs
+++ b/juniper/src/validation/rules/no_unused_fragments.rs
@@ -80,7 +80,7 @@ where
 
         for fragment in &self.defined_fragments {
             if !reachable.contains(&fragment.item) {
-                ctx.report_error(&error_message(fragment.item), &[fragment.start]);
+                ctx.report_error(&error_message(fragment.item), &[fragment.span.start]);
             }
         }
     }
@@ -101,7 +101,7 @@ where
     ) {
         self.current_scope = Some(Scope::Fragment(f.item.name.item));
         self.defined_fragments
-            .insert(Spanning::start_end(&f.start, &f.end, f.item.name.item));
+            .insert(Spanning::new(f.span, f.item.name.item));
     }
 
     fn enter_fragment_spread(
diff --git a/juniper/src/validation/rules/no_unused_variables.rs b/juniper/src/validation/rules/no_unused_variables.rs
index 98595dbdc..2fd1f078f 100644
--- a/juniper/src/validation/rules/no_unused_variables.rs
+++ b/juniper/src/validation/rules/no_unused_variables.rs
@@ -99,7 +99,9 @@ where
                 def_vars
                     .iter()
                     .filter(|var| !used.contains(var.item))
-                    .map(|var| RuleError::new(&error_message(var.item, *op_name), &[var.start]))
+                    .map(|var| {
+                        RuleError::new(&error_message(var.item, *op_name), &[var.span.start])
+                    })
                     .collect(),
             );
         }
diff --git a/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs b/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs
index c6c203c74..a41610d3f 100644
--- a/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs
+++ b/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs
@@ -406,8 +406,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
                             "{name1} and {name2} are different fields",
                         )),
                     ),
-                    vec![ast1.start],
-                    vec![ast2.start],
+                    vec![ast1.span.start],
+                    vec![ast2.span.start],
                 ));
             }
 
@@ -417,8 +417,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
                         response_name.into(),
                         ConflictReasonMessage::Message("they have differing arguments".into()),
                     ),
-                    vec![ast1.start],
-                    vec![ast2.start],
+                    vec![ast1.span.start],
+                    vec![ast2.span.start],
                 ));
             }
         }
@@ -435,8 +435,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
                             "they return conflicting types {t1} and {t2}",
                         )),
                     ),
-                    vec![ast1.start],
-                    vec![ast2.start],
+                    vec![ast1.span.start],
+                    vec![ast2.span.start],
                 ));
             }
         }
@@ -451,7 +451,12 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
                 ctx,
             );
 
-            return self.subfield_conflicts(&conflicts, response_name, &ast1.start, &ast2.start);
+            return self.subfield_conflicts(
+                &conflicts,
+                response_name,
+                &ast1.span.start,
+                &ast2.span.start,
+            );
         }
 
         None
diff --git a/juniper/src/validation/rules/possible_fragment_spreads.rs b/juniper/src/validation/rules/possible_fragment_spreads.rs
index c9e11f6f1..856b33ec0 100644
--- a/juniper/src/validation/rules/possible_fragment_spreads.rs
+++ b/juniper/src/validation/rules/possible_fragment_spreads.rs
@@ -70,7 +70,7 @@ where
                         parent_type.name().unwrap_or("<unknown>"),
                         frag_type.name().unwrap_or("<unknown>"),
                     ),
-                    &[frag.start],
+                    &[frag.span.start],
                 );
             }
         }
@@ -109,7 +109,7 @@ where
                         parent_type.name().unwrap_or("<unknown>"),
                         frag_type.name().unwrap_or("<unknown>"),
                     ),
-                    &[spread.start],
+                    &[spread.span.start],
                 );
             }
         }
diff --git a/juniper/src/validation/rules/provided_non_null_arguments.rs b/juniper/src/validation/rules/provided_non_null_arguments.rs
index 6c8d07a98..d326a5ed1 100644
--- a/juniper/src/validation/rules/provided_non_null_arguments.rs
+++ b/juniper/src/validation/rules/provided_non_null_arguments.rs
@@ -38,7 +38,7 @@ where
                 {
                     ctx.report_error(
                         &field_error_message(field_name, &meta_arg.name, &meta_arg.arg_type),
-                        &[field.start],
+                        &[field.span.start],
                     );
                 }
             }
@@ -72,7 +72,7 @@ where
                             &meta_arg.name,
                             &meta_arg.arg_type,
                         ),
-                        &[directive.start],
+                        &[directive.span.start],
                     );
                 }
             }
diff --git a/juniper/src/validation/rules/scalar_leafs.rs b/juniper/src/validation/rules/scalar_leafs.rs
index 00a92dade..d93d7a18e 100644
--- a/juniper/src/validation/rules/scalar_leafs.rs
+++ b/juniper/src/validation/rules/scalar_leafs.rs
@@ -26,11 +26,11 @@ where
             match (field_type.is_leaf(), &field.item.selection_set) {
                 (true, &Some(_)) => Some(RuleError::new(
                     &no_allowed_error_message(field_name, field_type_literal),
-                    &[field.start],
+                    &[field.span.start],
                 )),
                 (false, &None) => Some(RuleError::new(
                     &required_error_message(field_name, field_type_literal),
-                    &[field.start],
+                    &[field.span.start],
                 )),
                 _ => None,
             }
diff --git a/juniper/src/validation/rules/unique_argument_names.rs b/juniper/src/validation/rules/unique_argument_names.rs
index cbfe510cf..948278c89 100644
--- a/juniper/src/validation/rules/unique_argument_names.rs
+++ b/juniper/src/validation/rules/unique_argument_names.rs
@@ -36,10 +36,13 @@ where
     ) {
         match self.known_names.entry(arg_name.item) {
             Entry::Occupied(e) => {
-                ctx.report_error(&error_message(arg_name.item), &[*e.get(), arg_name.start]);
+                ctx.report_error(
+                    &error_message(arg_name.item),
+                    &[*e.get(), arg_name.span.start],
+                );
             }
             Entry::Vacant(e) => {
-                e.insert(arg_name.start);
+                e.insert(arg_name.span.start);
             }
         }
     }
diff --git a/juniper/src/validation/rules/unique_fragment_names.rs b/juniper/src/validation/rules/unique_fragment_names.rs
index f54e46d1e..260178ebe 100644
--- a/juniper/src/validation/rules/unique_fragment_names.rs
+++ b/juniper/src/validation/rules/unique_fragment_names.rs
@@ -30,11 +30,11 @@ where
             Entry::Occupied(e) => {
                 context.report_error(
                     &duplicate_message(f.item.name.item),
-                    &[*e.get(), f.item.name.start],
+                    &[*e.get(), f.item.name.span.start],
                 );
             }
             Entry::Vacant(e) => {
-                e.insert(f.item.name.start);
+                e.insert(f.item.name.span.start);
             }
         }
     }
diff --git a/juniper/src/validation/rules/unique_input_field_names.rs b/juniper/src/validation/rules/unique_input_field_names.rs
index 7e3b1d022..a95f1d11e 100644
--- a/juniper/src/validation/rules/unique_input_field_names.rs
+++ b/juniper/src/validation/rules/unique_input_field_names.rs
@@ -39,11 +39,11 @@ where
                 Entry::Occupied(e) => {
                     ctx.report_error(
                         &error_message(&field_name.item),
-                        &[*e.get(), field_name.start],
+                        &[*e.get(), field_name.span.start],
                     );
                 }
                 Entry::Vacant(e) => {
-                    e.insert(field_name.start);
+                    e.insert(field_name.span.start);
                 }
             }
         }
diff --git a/juniper/src/validation/rules/unique_operation_names.rs b/juniper/src/validation/rules/unique_operation_names.rs
index 8f6936963..fc6cf9cf7 100644
--- a/juniper/src/validation/rules/unique_operation_names.rs
+++ b/juniper/src/validation/rules/unique_operation_names.rs
@@ -29,10 +29,10 @@ where
         if let Some(ref op_name) = op.item.name {
             match self.names.entry(op_name.item) {
                 Entry::Occupied(e) => {
-                    ctx.report_error(&error_message(op_name.item), &[*e.get(), op.start]);
+                    ctx.report_error(&error_message(op_name.item), &[*e.get(), op.span.start]);
                 }
                 Entry::Vacant(e) => {
-                    e.insert(op.start);
+                    e.insert(op.span.start);
                 }
             }
         }
diff --git a/juniper/src/validation/rules/unique_variable_names.rs b/juniper/src/validation/rules/unique_variable_names.rs
index fa146122b..a1b02df10 100644
--- a/juniper/src/validation/rules/unique_variable_names.rs
+++ b/juniper/src/validation/rules/unique_variable_names.rs
@@ -36,10 +36,13 @@ where
     ) {
         match self.names.entry(var_name.item) {
             Entry::Occupied(e) => {
-                ctx.report_error(&error_message(var_name.item), &[*e.get(), var_name.start]);
+                ctx.report_error(
+                    &error_message(var_name.item),
+                    &[*e.get(), var_name.span.start],
+                );
             }
             Entry::Vacant(e) => {
-                e.insert(var_name.start);
+                e.insert(var_name.span.start);
             }
         }
     }
diff --git a/juniper/src/validation/rules/variables_are_input_types.rs b/juniper/src/validation/rules/variables_are_input_types.rs
index 1ba363fec..8c952570a 100644
--- a/juniper/src/validation/rules/variables_are_input_types.rs
+++ b/juniper/src/validation/rules/variables_are_input_types.rs
@@ -29,7 +29,7 @@ where
             if !var_type.is_input() {
                 ctx.report_error(
                     &error_message(var_name.item, &var_def.var_type.item),
-                    &[var_def.var_type.start],
+                    &[var_def.var_type.span.start],
                 );
             }
         }
diff --git a/juniper/src/validation/rules/variables_in_allowed_position.rs b/juniper/src/validation/rules/variables_in_allowed_position.rs
index 9a3db6fcf..7e69469c6 100644
--- a/juniper/src/validation/rules/variables_in_allowed_position.rs
+++ b/juniper/src/validation/rules/variables_in_allowed_position.rs
@@ -94,7 +94,7 @@ impl<'a, S: fmt::Debug> VariableInAllowedPosition<'a, S> {
                     if !ctx.schema.is_subtype(&expected_type, var_type) {
                         ctx.report_error(
                             &error_message(var_name.item, expected_type, var_type),
-                            &[var_def_name.start, var_name.start],
+                            &[var_def_name.span.start, var_name.span.start],
                         );
                     }
                 }
@@ -169,7 +169,7 @@ where
                 .entry(scope.clone())
                 .or_default()
                 .push((
-                    Spanning::start_end(&var_name.start, &var_name.end, var_name.item),
+                    Spanning::new(var_name.span, var_name.item),
                     input_type.clone(),
                 ));
         }
diff --git a/juniper/src/validation/visitor.rs b/juniper/src/validation/visitor.rs
index 488e65abb..4bff7c9b6 100644
--- a/juniper/src/validation/visitor.rs
+++ b/juniper/src/validation/visitor.rs
@@ -377,16 +377,15 @@ fn enter_input_value<'a, S, V>(
 {
     use crate::InputValue::*;
 
-    let start = &input_value.start;
-    let end = &input_value.end;
+    let span = input_value.span;
 
     match input_value.item {
-        Null => v.enter_null_value(ctx, Spanning::start_end(start, end, ())),
-        Scalar(ref s) => v.enter_scalar_value(ctx, Spanning::start_end(start, end, s)),
-        Enum(ref s) => v.enter_enum_value(ctx, Spanning::start_end(start, end, s)),
-        Variable(ref s) => v.enter_variable_value(ctx, Spanning::start_end(start, end, s)),
-        List(ref l) => v.enter_list_value(ctx, Spanning::start_end(start, end, l)),
-        Object(ref o) => v.enter_object_value(ctx, Spanning::start_end(start, end, o)),
+        Null => v.enter_null_value(ctx, Spanning::new(span, ())),
+        Scalar(ref s) => v.enter_scalar_value(ctx, Spanning::new(span, s)),
+        Enum(ref s) => v.enter_enum_value(ctx, Spanning::new(span, s)),
+        Variable(ref s) => v.enter_variable_value(ctx, Spanning::new(span, s)),
+        List(ref l) => v.enter_list_value(ctx, Spanning::new(span, l)),
+        Object(ref o) => v.enter_object_value(ctx, Spanning::new(span, o)),
     }
 }
 
@@ -400,15 +399,14 @@ fn exit_input_value<'a, S, V>(
 {
     use crate::InputValue::*;
 
-    let start = &input_value.start;
-    let end = &input_value.end;
+    let span = input_value.span;
 
     match input_value.item {
-        Null => v.exit_null_value(ctx, Spanning::start_end(start, end, ())),
-        Scalar(ref s) => v.exit_scalar_value(ctx, Spanning::start_end(start, end, s)),
-        Enum(ref s) => v.exit_enum_value(ctx, Spanning::start_end(start, end, s)),
-        Variable(ref s) => v.exit_variable_value(ctx, Spanning::start_end(start, end, s)),
-        List(ref l) => v.exit_list_value(ctx, Spanning::start_end(start, end, l)),
-        Object(ref o) => v.exit_object_value(ctx, Spanning::start_end(start, end, o)),
+        Null => v.exit_null_value(ctx, Spanning::new(span, ())),
+        Scalar(ref s) => v.exit_scalar_value(ctx, Spanning::new(span, s)),
+        Enum(ref s) => v.exit_enum_value(ctx, Spanning::new(span, s)),
+        Variable(ref s) => v.exit_variable_value(ctx, Spanning::new(span, s)),
+        List(ref l) => v.exit_list_value(ctx, Spanning::new(span, l)),
+        Object(ref o) => v.exit_object_value(ctx, Spanning::new(span, o)),
     }
 }