Repository: apollographql/apollo-rs
Pull request #690 (2023-10-12 08:42:17)

Revert complier v0.11 changes hard to merge with v1.0
This reverts (except for changelog):
* https://github.com/apollographql/apollo-rs/pull/674
* https://github.com/apollographql/apollo-rs/pull/668

These PRs have been released in apollo-compiler 0.11.3 (so changelog is still relevant to describe that release), but are hard to merge with git into the `compiler-v1.0` branch because they make large changes to code that has diverged significantly or been rewritten in 1.0. Reverting will allow merging `compiler-v1.0` into `main` soon, with the intent that we’ll manually port the reverted functionality and improvements. I’ve pushed a [`compiler-v0.11`](https://github.com/apollographql/apollo-rs/commits/compiler-v0.11) branch with the current contents of `main` (before this PR) in case we need to make further 0.x versions.


Patch:
diff --git a/crates/apollo-compiler/Cargo.toml b/crates/apollo-compiler/Cargo.toml
index 1b0fe92..63d69f6 100644
--- a/crates/apollo-compiler/Cargo.toml
+++ b/crates/apollo-compiler/Cargo.toml
@@ -24,7 +24,6 @@ rowan = "0.15.5"
 salsa = "0.16.1"
 ordered-float = { version = "4.0.0", features = ["std"] }
 thiserror = "1.0.31"
-serde = { version = "1.0", features = ["derive"] }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 uuid = { version = "1.4", features = ["serde", "v4", "js"] }
@@ -36,7 +35,6 @@ miette = "5.0"
 notify = "6.0.0"
 criterion = "0.5.1"
 pretty_assertions = "1.3.0"
-serde_json = "1.0"
 
 [[bench]]
 name = "multi-source"
diff --git a/crates/apollo-compiler/src/database/inputs.rs b/crates/apollo-compiler/src/database/inputs.rs
index e940290..05f2d5f 100644
--- a/crates/apollo-compiler/src/database/inputs.rs
+++ b/crates/apollo-compiler/src/database/inputs.rs
@@ -9,63 +9,19 @@ use std::sync::Arc;
 #[error("Unknown file ID")]
 struct UnknownFileError;
 
-/// Source text structure with a precomputed index from byte offsets to character offsets and to
-/// line/column numbers.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct MappedSource {
-    ariadne: AriadneSource,
-    map: Vec<u32>,
-}
-
-impl MappedSource {
-    fn new(input: &str) -> Self {
-        let ariadne = AriadneSource::from(input);
-
-        let mut map = vec![0; input.len() + 1];
-        let mut char_index = 0;
-        for (byte_index, _) in input.char_indices() {
-            map[byte_index] = char_index;
-            char_index += 1;
-        }
-
-        // Support 1 past the end of the string, for use in exclusive ranges.
-        map[input.len()] = char_index;
-
-        Self { ariadne, map }
-    }
-
-    pub(crate) fn map_index(&self, byte_index: usize) -> usize {
-        self.map[byte_index] as usize
-    }
-}
-
 /// A Cache implementation for `ariadne` diagnostics.
 ///
 /// Use [`InputDatabase::source_cache`] to construct one.
 #[derive(Clone, PartialEq, Eq)]
 pub struct SourceCache {
-    sources: HashMap<FileId, Arc<MappedSource>>,
+    sources: HashMap<FileId, Arc<AriadneSource>>,
     paths: HashMap<FileId, PathBuf>,
 }
-
-impl SourceCache {
-    pub(crate) fn get_source(&self, id: FileId) -> Option<&'_ MappedSource> {
-        self.sources.get(&id).map(|arc| arc.as_ref())
-    }
-
-    pub fn get_line_column(&self, id: FileId, index: usize) -> Option<(usize, usize)> {
-        let source = self.sources.get(&id)?;
-        let char_index = source.map_index(index);
-        let (_, line, column) = source.ariadne.get_offset_line(char_index)?;
-        Some((line, column))
-    }
-}
-
 impl AriadneCache<FileId> for &SourceCache {
     fn fetch(&mut self, id: &FileId) -> Result<&AriadneSource, Box<dyn std::fmt::Debug>> {
         let source = self.sources.get(id);
         source
-            .map(|arc| &arc.ariadne)
+            .map(|arc| &**arc)
             .ok_or_else(|| Box::new(UnknownFileError) as Box<dyn std::fmt::Debug>)
     }
     fn display<'a>(&self, id: &'a FileId) -> Option<Box<dyn std::fmt::Display + 'a>> {
@@ -75,9 +31,12 @@ impl AriadneCache<FileId> for &SourceCache {
         // Ref https://github.com/zesterer/ariadne/issues/10
         // Ariadne assumes the `id` is meaningful to users, but in apollo-rs it's
         // an incrementing integer, and file paths are stored separately.
-        let path = self.paths.get(id)?;
-        let boxed = Box::new(path.to_str()?.to_string());
-        Some(boxed)
+        self.paths
+            .get(id)
+            .and_then(|path| path.to_str())
+            .map(ToOwned::to_owned)
+            .map(Box::new)
+            .map(|bx| bx as Box<dyn std::fmt::Display + 'static>)
     }
 }
 
@@ -130,7 +89,7 @@ pub trait InputDatabase {
     /// Get the GraphQL source text for a file, split up into lines for
     /// printing diagnostics.
     #[salsa::invoke(source_with_lines)]
-    fn source_with_lines(&self, file_id: FileId) -> Arc<MappedSource>;
+    fn source_with_lines(&self, file_id: FileId) -> Arc<AriadneSource>;
 
     /// Get all GraphQL sources known to the compiler, split up into lines
     /// for printing diagnostics.
@@ -167,9 +126,9 @@ fn source_type(db: &dyn InputDatabase, file_id: FileId) -> SourceType {
     db.input(file_id).source_type()
 }
 
-fn source_with_lines(db: &dyn InputDatabase, file_id: FileId) -> Arc<MappedSource> {
+fn source_with_lines(db: &dyn InputDatabase, file_id: FileId) -> Arc<AriadneSource> {
     let code = db.source_code(file_id);
-    Arc::new(MappedSource::new(&code))
+    Arc::new(AriadneSource::from(code))
 }
 
 fn source_cache(db: &dyn InputDatabase) -> Arc<SourceCache> {
diff --git a/crates/apollo-compiler/src/diagnostics.rs b/crates/apollo-compiler/src/diagnostics.rs
index 25a99ff..bc3c737 100644
--- a/crates/apollo-compiler/src/diagnostics.rs
+++ b/crates/apollo-compiler/src/diagnostics.rs
@@ -5,34 +5,26 @@ use crate::database::{InputDatabase, SourceCache};
 use crate::FileId;
 use thiserror::Error;
 
-/// A source location (line + column) for a GraphQL error.
-#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
-pub struct GraphQLLocation {
-    /// The line number for this location, starting at 1 for the first line.
-    pub line: usize,
-    /// The column number for this location, starting at 1 and counting characters (Unicode Scalar
-    /// Values) like [str::chars].
-    pub column: usize,
-}
-
-/// A serializable GraphQL error.
-#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
-pub struct GraphQLError {
-    /// The error message.
-    pub message: String,
-
-    /// Locations relevant to the error, if any.
-    #[serde(default, skip_serializing_if = "Vec::is_empty")]
-    pub locations: Vec<GraphQLLocation>,
-}
-
-#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct DiagnosticLocation {
     file_id: FileId,
     offset: usize,
     length: usize,
 }
 
+impl ariadne::Span for DiagnosticLocation {
+    type SourceId = FileId;
+    fn source(&self) -> &FileId {
+        &self.file_id
+    }
+    fn start(&self) -> usize {
+        self.offset
+    }
+    fn end(&self) -> usize {
+        self.offset + self.length
+    }
+}
+
 impl DiagnosticLocation {
     pub fn file_id(&self) -> FileId {
         self.file_id
@@ -131,17 +123,6 @@ impl ApolloDiagnostic {
         self.labels.push(label);
         self
     }
-
-    /// Get the line and column number where this diagnostic was raised.
-    pub fn get_line_column(&self) -> Option<GraphQLLocation> {
-        self.cache
-            .get_line_column(self.location.file_id, self.location.offset)
-            // Make 1-indexed
-            .map(|(line, column)| GraphQLLocation {
-                line: line + 1,
-                column: column + 1,
-            })
-    }
 }
 
 impl fmt::Display for ApolloDiagnostic {
@@ -164,49 +145,35 @@ pub enum DiagnosticData {
     LimitExceeded { message: String },
     #[error("expected identifier")]
     MissingIdent,
-    #[error(
-        "executable documents can only contain executable definitions, {}",
-        name.as_ref().map(|name| format!("but `{name}` is a(n) {kind}"))
-            .unwrap_or_else(|| format!("got {kind}"))
-    )]
-    ExecutableDefinition {
-        name: Option<String>,
-        kind: &'static str,
-    },
-    #[error("{ty} `{name}` is defined multiple times")]
+    #[error("executable documents must not contain {kind}")]
+    ExecutableDefinition { kind: &'static str },
+    #[error("the {ty} `{name}` is defined multiple times in the document")]
     UniqueDefinition {
         ty: &'static str,
         name: String,
         original_definition: DiagnosticLocation,
         redefined_definition: DiagnosticLocation,
     },
-    #[error("argument `{name}` is defined multiple times")]
+    #[error("the argument `{name}` is defined multiple times")]
     UniqueArgument {
         name: String,
         original_definition: DiagnosticLocation,
         redefined_definition: DiagnosticLocation,
     },
-    #[error("value `{name}` is defined multiple times")]
+    #[error("the value `{name}` is defined multiple times")]
     UniqueInputValue {
         name: String,
         original_value: DiagnosticLocation,
         redefined_value: DiagnosticLocation,
     },
-    #[error("enum member `{name}` is defined multiple times in `{coordinate}`")]
-    UniqueEnumValue {
-        name: String,
-        coordinate: String,
-        original_definition: DiagnosticLocation,
-        redefined_definition: DiagnosticLocation,
-    },
-    #[error("subscription operation has multiple root fields")]
+    #[error("subscription operations can only have one root field")]
     SingleRootField {
         // TODO(goto-bus-stop) if we keep this it should be a vec of the field names or nodes i think.
         // Else just remove as the labeling is done separately.
         fields: usize,
         subscription: DiagnosticLocation,
     },
-    #[error("operation type {ty} is not defined")]
+    #[error("{ty} root operation type is not defined")]
     UnsupportedOperation {
         // current operation type: subscription, mutation, query
         ty: &'static str,
@@ -218,14 +185,14 @@ pub enum DiagnosticData {
         /// Type name being queried
         ty: String,
     },
-    #[error("the argument `{name}` is not supported by {coordinate}")]
-    UndefinedArgument { name: String, coordinate: String },
-    #[error("type `{name}` is not defined")]
+    #[error("the argument `{name}` is not supported")]
+    UndefinedArgument { name: String },
+    #[error("cannot find type `{name}` in this document")]
     UndefinedDefinition {
         /// Name of the type not in scope
         name: String,
     },
-    #[error("directive `@{name}` is not defined")]
+    #[error("cannot find directive `{name}` in this document")]
     UndefinedDirective {
         /// Name of the missing directive
         name: String,
@@ -235,7 +202,7 @@ pub enum DiagnosticData {
         /// Name of the variable not in scope
         name: String,
     },
-    #[error("fragment `{name}` is not defined")]
+    #[error("cannot find fragment `{name}` in this document")]
     UndefinedFragment {
         /// Name of the fragment not in scope
         name: String,
@@ -256,93 +223,87 @@ pub enum DiagnosticData {
         /// Location of the extension
         extension: DiagnosticLocation,
     },
-    #[error("directive definition `{name}` references itself")]
+    #[error("`{name}` directive definition cannot reference itself")]
     RecursiveDirectiveDefinition { name: String },
-    #[error("interface `{name}` implements itself")]
+    #[error("interface {name} cannot implement itself")]
     RecursiveInterfaceDefinition { name: String },
-    #[error("input object `{name}` references itself")]
+    #[error("`{name}` input object cannot reference itself")]
     RecursiveInputObjectDefinition { name: String },
-    #[error("fragment `{name}` references itself")]
+    #[error("`{name}` fragment cannot reference itself")]
     RecursiveFragmentDefinition { name: String },
-    #[error("enum value `{value}` does not have a conventional all-caps name")]
+    #[error("values in an Enum Definition should be capitalized")]
     CapitalizedValue { value: String },
-    #[error("field `{field}` is declared multiple times")]
+    #[error("fields must be unique in a definition")]
     UniqueField {
         /// Name of the non-unique field.
         field: String,
         original_definition: DiagnosticLocation,
         redefined_definition: DiagnosticLocation,
     },
-    #[error("type `{name}` does not satisfy interface `{interface}` because it is missing field `{field}`")]
+    #[error("missing `{field}` field")]
     MissingField {
-        name: String,
-        interface: String,
         // current field that should be defined
         field: String,
     },
-    #[error("required argument `{coordinate}` is not provided")]
-    RequiredArgument { coordinate: String },
-    #[error("type `{ty}` implements interface `{interface}` multiple times")]
+    #[error("the required argument `{name}` is not provided")]
+    RequiredArgument { name: String },
+    #[error("type `{ty}` can only implement interface `{interface}` once")]
     DuplicateImplementsInterface { ty: String, interface: String },
-    // XXX(@goto-bus-stop): This error message would be better if it listed which other interface
-    // is responsible for `missing_interface` being required. It would require code changes in
-    // validation to pass that information on, so not doing it in 0.11.x--we should do it in 1.0 :)
-    #[error("type `{ty}` must implement `{missing_interface}`")]
+    #[error(
+        "Transitively implemented interfaces must also be defined on an implementing interface or object"
+    )]
     TransitiveImplementedInterfaces {
-        /// Name of the affected type
-        ty: String,
         // interface that should be defined
         missing_interface: String,
     },
-    #[error("`{name}` field does not return an output type")]
+    #[error("`{name}` field must return an output type")]
     OutputType {
         // field name
         name: String,
         // field type
         ty: &'static str,
     },
-    #[error("type `{ty}` for input field or argument `{name}` is not an input type")]
+    #[error("`{name}` field must be of an input type")]
     InputType {
         /// Field name.
         name: String,
-        /// Declared type.
-        ty: String,
-    },
-    #[error("custom scalar `{ty}` does not have an @specifiedBy directive")]
-    ScalarSpecificationURL {
-        /// Name of the scalar.
-        ty: String,
+        /// The kind of type that the field is declared with.
+        ty: &'static str,
     },
+    #[error(
+        "custom scalars should provide a scalar specification URL via the @specifiedBy directive"
+    )]
+    ScalarSpecificationURL,
     #[error("missing query root operation type in schema definition")]
     QueryRootOperationType,
     #[error("built-in scalars must be omitted for brevity")]
     BuiltInScalarDefinition,
-    #[error("type `{ty}` for variable `${name}` is not an input type")]
+    #[error("`${name}` variable must be of an input type")]
     VariableInputType {
-        /// Variable name.
+        /// Varialbe name.
         name: String,
-        /// Declared type.
-        ty: String,
+        /// The kind of type that the variable is declared with.
+        ty: &'static str,
     },
-    #[error("variable `{name}` is unused")]
+    #[error("unused variable: `{name}`")]
     UnusedVariable { name: String },
-    #[error("field `{name}` does not return an object type")]
+    #[error("`{name}` field must return an object type")]
     ObjectType {
         // union member
         name: String,
         // actual type
         ty: &'static str,
     },
-    #[error("directive `@{name}` can not be used on {dir_loc}")]
-    UnsupportedDirectiveLocation {
-        /// name of the directive
+    #[error("{name} directive is not supported for {dir_loc} location")]
+    UnsupportedLocation {
+        /// current directive definition
         name: String,
         /// current location where the directive is used
         dir_loc: DirectiveLocation,
         /// The source location where the directive that's being used was defined.
         directive_def: DiagnosticLocation,
     },
-    #[error("`{value}` cannot be assigned to type `{ty}`")]
+    #[error("{ty} cannot be represented by a {value} value")]
     UnsupportedValueType {
         // input value
         value: String,
@@ -361,26 +322,16 @@ pub enum DiagnosticData {
         original_call: DiagnosticLocation,
         conflicting_call: DiagnosticLocation,
     },
-    #[error("subscription operation uses introspection field `{field}` as a root field")]
+    #[error("subscription operations can not have an introspection field as a root field")]
     IntrospectionField {
         /// Name of the field
         field: String,
     },
-    #[error("field `{field}` has a subselection but its type `{ty}` is not a composite type")]
-    DisallowedSubselection {
-        /// Name of the field
-        field: String,
-        /// Name of the type
-        ty: String,
-    },
-    #[error("field `{field}` selects a composite type `{ty}` but does not have a subselection")]
-    MissingSubselection {
-        /// Name of the field
-        field: String,
-        /// Name of the type
-        ty: String,
-    },
-    #[error("operation selects different types into the same field name `{field}`")]
+    #[error("subselection set for scalar and enum types must be empty")]
+    DisallowedSubselection,
+    #[error("interface, union and object types must have a subselection set")]
+    MissingSubselection,
+    #[error("operation must not select different types using the same field name `{field}`")]
     ConflictingField {
         /// Name of the non-unique field.
         field: String,
@@ -392,23 +343,19 @@ pub enum DiagnosticData {
         /// Name of the type on which the fragment is declared
         ty: Option<String>,
     },
-    #[error("type condition `{ty}` is not a composite type")]
+    #[error("fragments can not be declared on primitive types")]
     InvalidFragmentTarget {
         /// Name of the type on which the fragment is declared
         ty: String,
     },
-    #[error(
-        "{} cannot be applied to type `{type_name}`",
-        name.as_ref().map(|name| format!("fragment `{name}`"))
-            .unwrap_or_else(|| "anonymous fragment".to_string()),
-    )]
+    #[error("fragment cannot be applied to this type")]
     InvalidFragmentSpread {
         /// Fragment name or None if it's an inline fragment
         name: Option<String>,
         /// Type name the fragment is being applied to
         type_name: String,
     },
-    #[error("fragment `{name}` is unused")]
+    #[error("fragment `{name}` must be used in an operation")]
     UnusedFragment {
         /// Name of the fragment
         name: String,
@@ -432,21 +379,18 @@ impl DiagnosticData {
         matches!(self, Self::CapitalizedValue { .. })
     }
     pub fn is_advice(&self) -> bool {
-        matches!(self, Self::ScalarSpecificationURL { .. })
+        matches!(self, Self::ScalarSpecificationURL)
     }
 }
 
-type AriadneSpan = (FileId, std::ops::Range<usize>);
-impl ApolloDiagnostic {
-    fn map_location(&self, location: DiagnosticLocation) -> AriadneSpan {
-        let id = location.file_id();
-        let source = self.cache.get_source(id).unwrap();
-        let start = source.map_index(location.offset);
-        let end = source.map_index(location.offset + location.length);
-        (id, start..end)
+impl From<Label> for ariadne::Label<DiagnosticLocation> {
+    fn from(label: Label) -> Self {
+        Self::new(label.location).with_message(label.text)
     }
+}
 
-    pub fn to_report(&self) -> ariadne::Report<'static, AriadneSpan> {
+impl ApolloDiagnostic {
+    pub fn to_report(&self) -> ariadne::Report<'static, DiagnosticLocation> {
         use ariadne::{ColorGenerator, Report, ReportKind};
 
         let severity = if self.data.is_advice() {
@@ -456,33 +400,17 @@ impl ApolloDiagnostic {
         } else {
             ReportKind::Error
         };
-
-        let span = self.map_location(self.location);
-
         let mut colors = ColorGenerator::new();
-        let mut builder =
-            Report::build(severity, self.location.file_id(), span.1.start).with_message(&self.data);
-        builder.add_labels(self.labels.iter().map(|label| {
-            ariadne::Label::new(self.map_location(label.location))
-                .with_message(&label.text)
-                .with_color(colors.next())
-        }));
+        let mut builder = Report::build(severity, self.location.file_id(), self.location.offset())
+            .with_message(&self.data);
+        builder.add_labels(
+            self.labels
+                .iter()
+                .map(|label| ariadne::Label::from(label.clone()).with_color(colors.next())),
+        );
         if let Some(help) = &self.help {
             builder = builder.with_help(help);
         }
         builder.finish()
     }
-
-    pub fn to_json(&self) -> GraphQLError {
-        let mut locations = vec![];
-
-        if let Some(location) = self.get_line_column() {
-            locations.push(location);
-        }
-
-        GraphQLError {
-            message: self.data.to_string(),
-            locations,
-        }
-    }
 }
diff --git a/crates/apollo-compiler/src/lib.rs b/crates/apollo-compiler/src/lib.rs
index 6f494d2..71900ed 100644
--- a/crates/apollo-compiler/src/lib.rs
+++ b/crates/apollo-compiler/src/lib.rs
@@ -12,7 +12,7 @@ use salsa::ParallelDatabase;
 use validation::ValidationDatabase;
 
 pub use database::{hir, AstDatabase, FileId, HirDatabase, InputDatabase, RootDatabase, Source};
-pub use diagnostics::{ApolloDiagnostic, GraphQLError, GraphQLLocation};
+pub use diagnostics::ApolloDiagnostic;
 
 pub struct ApolloCompiler {
     pub db: RootDatabase,
diff --git a/crates/apollo-compiler/src/validation/directive.rs b/crates/apollo-compiler/src/validation/directive.rs
index 113a3ce..fd023e7 100644
--- a/crates/apollo-compiler/src/validation/directive.rs
+++ b/crates/apollo-compiler/src/validation/directive.rs
@@ -204,7 +204,7 @@ pub fn validate_directives(
                 let mut diag = ApolloDiagnostic::new(
                         db,
                         loc.into(),
-                        DiagnosticData::UnsupportedDirectiveLocation {
+                        DiagnosticData::UnsupportedLocation {
                             name: name.into(),
                             dir_loc,
                             directive_def: directive_definition.loc.into(),
@@ -251,7 +251,6 @@ pub fn validate_directives(
                             arg.loc.into(),
                             DiagnosticData::UndefinedArgument {
                                 name: arg.name().into(),
-                                coordinate: format!("@{}", dir.name.src()),
                             },
                         )
                         .label(Label::new(arg.loc, "argument by this name not found"))
@@ -277,11 +276,7 @@ pub fn validate_directives(
                         db,
                         dir.loc.into(),
                         DiagnosticData::RequiredArgument {
-                            coordinate: format!(
-                                "@{}({}:)",
-                                directive_definition.name(),
-                                arg_def.name()
-                            ),
+                            name: arg_def.name().into(),
                         },
                     );
                     diagnostic = diagnostic.label(Label::new(
diff --git a/crates/apollo-compiler/src/validation/enum_.rs b/crates/apollo-compiler/src/validation/enum_.rs
index e6c7aca..57d55e7 100644
--- a/crates/apollo-compiler/src/validation/enum_.rs
+++ b/crates/apollo-compiler/src/validation/enum_.rs
@@ -58,9 +58,9 @@ pub fn validate_enum_definition(
                 ApolloDiagnostic::new(
                     db,
                     redefined_definition.into(),
-                    DiagnosticData::UniqueEnumValue {
+                    DiagnosticData::UniqueDefinition {
+                        ty: "enum value",
                         name: value.into(),
-                        coordinate: enum_def.name().to_string(),
                         original_definition: original_definition.into(),
                         redefined_definition: redefined_definition.into(),
                     },
diff --git a/crates/apollo-compiler/src/validation/field.rs b/crates/apollo-compiler/src/validation/field.rs
index f7d728f..97d4923 100644
--- a/crates/apollo-compiler/src/validation/field.rs
+++ b/crates/apollo-compiler/src/validation/field.rs
@@ -58,13 +58,6 @@ pub fn validate_field(
                             arg.loc.into(),
                             DiagnosticData::UndefinedArgument {
                                 name: arg.name().into(),
-                                coordinate: format!(
-                                    "{}.{}",
-                                    // Guaranteed to exist because `field.field_definition()`
-                                    // worked.
-                                    field.parent_obj.as_ref().unwrap(),
-                                    field.name.src(),
-                                ),
                             },
                         )
                         .labels(labels),
@@ -91,14 +84,7 @@ pub fn validate_field(
                     db,
                     field.loc.into(),
                     DiagnosticData::RequiredArgument {
-                        coordinate: format!(
-                            "{}.{}({}:)",
-                            // Guaranteed to exist as we wouldn't know about the expected arguments
-                            // for this field otherwise.
-                            field.parent_obj.as_ref().unwrap(),
-                            field.name(),
-                            arg_def.name()
-                        ),
+                        name: arg_def.name().into(),
                     },
                 );
                 diagnostic = diagnostic.label(Label::new(
@@ -288,17 +274,11 @@ pub fn validate_leaf_field_selection(
                 format!("field `{fname}` type `{tname}` is an interface and must select fields")
             }
             hir::TypeDefinition::UnionTypeDefinition(_) => {
-                format!("field `{fname}` type `{tname}` is a union and must select fields")
+                format!("field `{fname}` type `{tname}` is an union and must select fields")
             }
             _ => return Ok(()),
         };
-        (
-            label,
-            DiagnosticData::MissingSubselection {
-                field: fname,
-                ty: tname.clone(),
-            },
-        )
+        (label, DiagnosticData::MissingSubselection)
     } else {
         let label = match type_def {
             hir::TypeDefinition::EnumTypeDefinition(_) => {
@@ -309,13 +289,7 @@ pub fn validate_leaf_field_selection(
             ),
             _ => return Ok(()),
         };
-        (
-            label,
-            DiagnosticData::DisallowedSubselection {
-                field: fname,
-                ty: tname.clone(),
-            },
-        )
+        (label, DiagnosticData::DisallowedSubselection)
     };
 
     Err(ApolloDiagnostic::new(db, field.loc.into(), diagnostic_data)
diff --git a/crates/apollo-compiler/src/validation/input_object.rs b/crates/apollo-compiler/src/validation/input_object.rs
index 20324ef..d440dc5 100644
--- a/crates/apollo-compiler/src/validation/input_object.rs
+++ b/crates/apollo-compiler/src/validation/input_object.rs
@@ -193,7 +193,7 @@ pub fn validate_input_values(
                 diagnostics.push(
                     ApolloDiagnostic::new(db, loc.into(), DiagnosticData::InputType {
                         name: input_value.name().into(),
-                        ty: input_value.ty().name(),
+                        ty: field_ty.kind(),
                     })
                         .label(Label::new(loc, format!("this is of `{}` type", field_ty.kind())))
                         .help(format!("Scalars, Enums, and Input Objects are input types. Change `{}` field to take one of these input types.", input_value.name())),
diff --git a/crates/apollo-compiler/src/validation/interface.rs b/crates/apollo-compiler/src/validation/interface.rs
index cf52dde..8feb445 100644
--- a/crates/apollo-compiler/src/validation/interface.rs
+++ b/crates/apollo-compiler/src/validation/interface.rs
@@ -132,8 +132,6 @@ pub fn validate_interface_definition(
                         db,
                         interface_def.loc().into(),
                         DiagnosticData::MissingField {
-                            name: interface_def.name().to_string(),
-                            interface: super_interface.name().to_string(),
                             field: name.clone(),
                         },
                     )
@@ -234,7 +232,6 @@ pub fn validate_implements_interfaces(
                 db,
                 loc.into(),
                 DiagnosticData::TransitiveImplementedInterfaces {
-                    ty: implementor_name.clone(),
                     missing_interface: undefined.name.clone(),
                 },
             )
diff --git a/crates/apollo-compiler/src/validation/object.rs b/crates/apollo-compiler/src/validation/object.rs
index 4390902..e173afc 100644
--- a/crates/apollo-compiler/src/validation/object.rs
+++ b/crates/apollo-compiler/src/validation/object.rs
@@ -103,8 +103,6 @@ pub fn validate_object_type_definition(
                     db,
                     object.loc().into(),
                     DiagnosticData::MissingField {
-                        name: object.name().to_string(),
-                        interface: interface.name().to_string(),
                         field: name.to_string(),
                     },
                 )
diff --git a/crates/apollo-compiler/src/validation/scalar.rs b/crates/apollo-compiler/src/validation/scalar.rs
index 8ad581b..f6ba895 100644
--- a/crates/apollo-compiler/src/validation/scalar.rs
+++ b/crates/apollo-compiler/src/validation/scalar.rs
@@ -35,9 +35,7 @@ pub fn validate_scalar_definition(
                 ApolloDiagnostic::new(
                     db,
                     scalar_def.loc.into(),
-                    DiagnosticData::ScalarSpecificationURL {
-                        ty: scalar_def.name().into(),
-                    },
+                    DiagnosticData::ScalarSpecificationURL,
                 )
                 .label(Label::new(
                     scalar_def.loc,
diff --git a/crates/apollo-compiler/src/validation/validation_db.rs b/crates/apollo-compiler/src/validation/validation_db.rs
index 7f7b95a..32df7f9 100644
--- a/crates/apollo-compiler/src/validation/validation_db.rs
+++ b/crates/apollo-compiler/src/validation/validation_db.rs
@@ -547,10 +547,7 @@ fn validate_executable_inner(
                     ApolloDiagnostic::new(
                         db,
                         (file_id, def.syntax().text_range()).into(),
-                        DiagnosticData::ExecutableDefinition {
-                            name: def.name().map(|node| node.text().to_string()),
-                            kind: def.kind(),
-                        },
+                        DiagnosticData::ExecutableDefinition { kind: def.kind() },
                     )
                     .label(Label::new(
                         (file_id, def.syntax().text_range()),
@@ -589,7 +586,6 @@ pub fn validate_executable(db: &dyn ValidationDatabase, file_id: FileId) -> Vec<
 mod tests {
     use super::ValidationDatabase;
     use crate::ApolloCompiler;
-    use crate::GraphQLLocation;
     use crate::HirDatabase;
 
     #[test]
@@ -639,11 +635,7 @@ query {
         assert_eq!(diagnostics.len(), 1);
         assert_eq!(
             diagnostics[0].data.to_string(),
-            "executable documents can only contain executable definitions, but `Object` is a(n) ObjectTypeDefinition"
-        );
-        assert_eq!(
-            diagnostics[0].get_line_column(),
-            Some(GraphQLLocation { line: 2, column: 1 })
+            "executable documents must not contain ObjectTypeDefinition"
         );
     }
 
@@ -673,7 +665,7 @@ fragment q on Query {
         assert_eq!(diagnostics.len(), 1);
         assert_eq!(
             diagnostics[0].data.to_string(),
-            "fragment `q` references itself"
+            "`q` fragment cannot reference itself"
         );
     }
 
@@ -710,7 +702,7 @@ fragment q on TestObject {
         assert_eq!(diagnostics.len(), 1);
         assert_eq!(
             diagnostics[0].data.to_string(),
-            "fragment `q` references itself"
+            "`q` fragment cannot reference itself"
         );
     }
 
@@ -749,21 +741,6 @@ type TestObject {
             diagnostics[0].data.to_string(),
             "cannot query field `nickname` on type `TestObject`"
         );
-        assert_eq!(
-            diagnostics[0].get_line_column(),
-            Some(GraphQLLocation { line: 5, column: 9 })
-        );
-        let json = expect_test::expect![[r#"
-            {
-              "message": "cannot query field `nickname` on type `TestObject`",
-              "locations": [
-                {
-                  "line": 5,
-                  "column": 9
-                }
-              ]
-            }"#]];
-        json.assert_eq(&serde_json::to_string_pretty(&diagnostics[0].to_json()).unwrap());
     }
 
     #[test]
@@ -784,7 +761,10 @@ type TestObject {
         );
         let diagnostics = compiler.db.validate_standalone_executable(unused_frag_id);
         assert_eq!(diagnostics.len(), 1);
-        assert_eq!(diagnostics[0].data.to_string(), "fragment `A` is unused");
+        assert_eq!(
+            diagnostics[0].data.to_string(),
+            "fragment `A` must be used in an operation"
+        );
 
         let dupe_frag_id = compiler.add_executable(
             r#"
@@ -798,7 +778,7 @@ type TestObject {
         assert_eq!(diagnostics.len(), 1);
         assert_eq!(
             diagnostics[0].data.to_string(),
-            "fragment `A` is defined multiple times"
+            "the fragment `A` is defined multiple times in the document"
         );
 
         let unknown_frag_id = compiler.add_executable(r#"{ ...A }"#, "unknown_frag.graphql");
@@ -806,7 +786,7 @@ type TestObject {
         assert_eq!(diagnostics.len(), 1);
         assert_eq!(
             diagnostics[0].data.to_string(),
-            "fragment `A` is not defined"
+            "cannot find fragment `A` in this document"
         );
     }
 
diff --git a/crates/apollo-compiler/src/validation/value.rs b/crates/apollo-compiler/src/validation/value.rs
index 58be27c..bd65d59 100644
--- a/crates/apollo-compiler/src/validation/value.rs
+++ b/crates/apollo-compiler/src/validation/value.rs
@@ -243,7 +243,7 @@ pub fn value_of_correct_type(
                                 db,
                                 val.loc().into(),
                                 DiagnosticData::RequiredArgument {
-                                    coordinate: format!("{}.{}", input_obj.name(), f.name()),
+                                    name: f.name().into(),
                                 },
                             );
                             diagnostic = diagnostic.label(Label::new(
diff --git a/crates/apollo-compiler/src/validation/variable.rs b/crates/apollo-compiler/src/validation/variable.rs
index 9c73af8..0138296 100644
--- a/crates/apollo-compiler/src/validation/variable.rs
+++ b/crates/apollo-compiler/src/validation/variable.rs
@@ -35,8 +35,8 @@ pub fn validate_variable_definitions(
                     let ty_name = type_def.kind();
                     diagnostics.push(
                     ApolloDiagnostic::new(db, variable.loc().into(), DiagnosticData::VariableInputType {
-                        name: variable.name().to_string(),
-                        ty: type_def.name().to_string(),
+                        name: variable.name().into(),
+                        ty: ty_name,
                     })
                     .label(Label::new(ty.loc().unwrap(), format!("this is of `{ty_name}` type")))
                     .help("objects, unions, and interfaces cannot be used because variables can only be of input type"),


Test patch:
diff --git a/crates/apollo-compiler/test_data/diagnostics/0003_anonymous_and_named_operation.txt b/crates/apollo-compiler/test_data/diagnostics/0003_anonymous_and_named_operation.txt
index f9f28e0..b43a432 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0003_anonymous_and_named_operation.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0003_anonymous_and_named_operation.txt
@@ -93,7 +93,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "Mutation.addPet(name:)",
+            name: "name",
         },
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0017_schema_with_unspecified_scalar.txt b/crates/apollo-compiler/test_data/diagnostics/0017_schema_with_unspecified_scalar.txt
index 6ad01a9..e9c68a6 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0017_schema_with_unspecified_scalar.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0017_schema_with_unspecified_scalar.txt
@@ -24,8 +24,6 @@
             },
         ],
         help: None,
-        data: ScalarSpecificationURL {
-            ty: "URL",
-        },
+        data: ScalarSpecificationURL,
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0018_schema_with_specified_scalar_missing_values.txt b/crates/apollo-compiler/test_data/diagnostics/0018_schema_with_specified_scalar_missing_values.txt
index e96fc93..f868b50 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0018_schema_with_specified_scalar_missing_values.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0018_schema_with_specified_scalar_missing_values.txt
@@ -24,8 +24,6 @@
             },
         ],
         help: None,
-        data: ScalarSpecificationURL {
-            ty: "URL",
-        },
+        data: ScalarSpecificationURL,
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0019_enum_definition_with_duplicate_values.txt b/crates/apollo-compiler/test_data/diagnostics/0019_enum_definition_with_duplicate_values.txt
index 48d1459..cca3c5c 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0019_enum_definition_with_duplicate_values.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0019_enum_definition_with_duplicate_values.txt
@@ -36,9 +36,9 @@
         help: Some(
             "CAT must only be defined once in this enum.",
         ),
-        data: UniqueEnumValue {
+        data: UniqueDefinition {
+            ty: "enum value",
             name: "CAT",
-            coordinate: "Pet",
             original_definition: DiagnosticLocation {
                 file_id: FileId {
                     id: 19,
@@ -92,9 +92,9 @@
         help: Some(
             "THRIVE_PET_FOODS must only be defined once in this enum.",
         ),
-        data: UniqueEnumValue {
+        data: UniqueDefinition {
+            ty: "enum value",
             name: "THRIVE_PET_FOODS",
-            coordinate: "Snack",
             original_definition: DiagnosticLocation {
                 file_id: FileId {
                     id: 19,
diff --git a/crates/apollo-compiler/test_data/diagnostics/0025_interface_definition_with_missing_transitive_fields.txt b/crates/apollo-compiler/test_data/diagnostics/0025_interface_definition_with_missing_transitive_fields.txt
index b6be07b..40cac53 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0025_interface_definition_with_missing_transitive_fields.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0025_interface_definition_with_missing_transitive_fields.txt
@@ -37,8 +37,6 @@
             "An interface must be a super-set of all interfaces it implements",
         ),
         data: MissingField {
-            name: "Image",
-            interface: "Resource",
             field: "width",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0026_interface_definition_with_missing_implemetns_interface.txt b/crates/apollo-compiler/test_data/diagnostics/0026_interface_definition_with_missing_implemetns_interface.txt
index 242d757..a95923e 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0026_interface_definition_with_missing_implemetns_interface.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0026_interface_definition_with_missing_implemetns_interface.txt
@@ -25,7 +25,6 @@
         ],
         help: None,
         data: TransitiveImplementedInterfaces {
-            ty: "Image",
             missing_interface: "Node",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0028_interface_definition_with_missing_fields_implements_intrefaces_undefined_interfaces.txt b/crates/apollo-compiler/test_data/diagnostics/0028_interface_definition_with_missing_fields_implements_intrefaces_undefined_interfaces.txt
index 56a3ad4..d7b65f9 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0028_interface_definition_with_missing_fields_implements_intrefaces_undefined_interfaces.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0028_interface_definition_with_missing_fields_implements_intrefaces_undefined_interfaces.txt
@@ -37,8 +37,6 @@
             "An interface must be a super-set of all interfaces it implements",
         ),
         data: MissingField {
-            name: "Image",
-            interface: "Resource",
             field: "width",
         },
     },
@@ -68,7 +66,6 @@
         ],
         help: None,
         data: TransitiveImplementedInterfaces {
-            ty: "Image",
             missing_interface: "Node",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0034_object_type_definition_with_missing_transitive_fields.txt b/crates/apollo-compiler/test_data/diagnostics/0034_object_type_definition_with_missing_transitive_fields.txt
index 8b20714..6251382 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0034_object_type_definition_with_missing_transitive_fields.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0034_object_type_definition_with_missing_transitive_fields.txt
@@ -37,8 +37,6 @@
             "An object must provide all fields required by the interfaces it implements",
         ),
         data: MissingField {
-            name: "Query",
-            interface: "Node",
             field: "id",
         },
     },
@@ -80,8 +78,6 @@
             "An object must provide all fields required by the interfaces it implements",
         ),
         data: MissingField {
-            name: "Query",
-            interface: "Resource",
             field: "width",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0035_object_type_definition_with_missing_implements_interfaces_definition.txt b/crates/apollo-compiler/test_data/diagnostics/0035_object_type_definition_with_missing_implements_interfaces_definition.txt
index 5219dcf..a21b35f 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0035_object_type_definition_with_missing_implements_interfaces_definition.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0035_object_type_definition_with_missing_implements_interfaces_definition.txt
@@ -25,7 +25,6 @@
         ],
         help: None,
         data: TransitiveImplementedInterfaces {
-            ty: "Query",
             missing_interface: "Resource",
         },
     },
@@ -55,7 +54,6 @@
         ],
         help: None,
         data: TransitiveImplementedInterfaces {
-            ty: "Image",
             missing_interface: "Node",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0042_mutation_operation_with_undefined_fields.txt b/crates/apollo-compiler/test_data/diagnostics/0042_mutation_operation_with_undefined_fields.txt
index bed7e94..266e05b 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0042_mutation_operation_with_undefined_fields.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0042_mutation_operation_with_undefined_fields.txt
@@ -28,7 +28,7 @@
         ),
         data: InputType {
             name: "petType",
-            ty: "PetType",
+            ty: "UnionTypeDefinition",
         },
     },
     ApolloDiagnostic {
diff --git a/crates/apollo-compiler/test_data/diagnostics/0050_directives_in_invalid_locations.txt b/crates/apollo-compiler/test_data/diagnostics/0050_directives_in_invalid_locations.txt
index fa0f3d8..31d1eaf 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0050_directives_in_invalid_locations.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0050_directives_in_invalid_locations.txt
@@ -26,7 +26,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "skip",
             dir_loc: Interface,
             directive_def: DiagnosticLocation {
@@ -75,7 +75,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveB",
             dir_loc: FieldDefinition,
             directive_def: DiagnosticLocation {
@@ -114,7 +114,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "include",
             dir_loc: InputObject,
             directive_def: DiagnosticLocation {
@@ -153,7 +153,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "include",
             dir_loc: InputFieldDefinition,
             directive_def: DiagnosticLocation {
@@ -202,7 +202,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveB",
             dir_loc: Union,
             directive_def: DiagnosticLocation {
@@ -251,7 +251,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveA",
             dir_loc: Enum,
             directive_def: DiagnosticLocation {
@@ -300,7 +300,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveA",
             dir_loc: EnumValue,
             directive_def: DiagnosticLocation {
@@ -339,7 +339,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "deprecated",
             dir_loc: Object,
             directive_def: DiagnosticLocation {
@@ -378,7 +378,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "specifiedBy",
             dir_loc: ArgumentDefinition,
             directive_def: DiagnosticLocation {
@@ -417,7 +417,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "include",
             dir_loc: Schema,
             directive_def: DiagnosticLocation {
@@ -466,7 +466,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveB",
             dir_loc: Scalar,
             directive_def: DiagnosticLocation {
@@ -505,7 +505,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "skip",
             dir_loc: VariableDefinition,
             directive_def: DiagnosticLocation {
@@ -544,7 +544,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "skip",
             dir_loc: Query,
             directive_def: DiagnosticLocation {
@@ -583,7 +583,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "deprecated",
             dir_loc: Field,
             directive_def: DiagnosticLocation {
@@ -632,7 +632,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveB",
             dir_loc: FragmentSpread,
             directive_def: DiagnosticLocation {
@@ -681,7 +681,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveB",
             dir_loc: FragmentDefinition,
             directive_def: DiagnosticLocation {
@@ -730,7 +730,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveA",
             dir_loc: InlineFragment,
             directive_def: DiagnosticLocation {
@@ -779,7 +779,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "directiveA",
             dir_loc: Subscription,
             directive_def: DiagnosticLocation {
@@ -818,7 +818,7 @@
         help: Some(
             "the directive must be used in a location that the service has declared support for",
         ),
-        data: UnsupportedDirectiveLocation {
+        data: UnsupportedLocation {
             name: "skip",
             dir_loc: Mutation,
             directive_def: DiagnosticLocation {
diff --git a/crates/apollo-compiler/test_data/diagnostics/0053_argument_name_is_not_defined.txt b/crates/apollo-compiler/test_data/diagnostics/0053_argument_name_is_not_defined.txt
index bb168a7..3563d13 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0053_argument_name_is_not_defined.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0053_argument_name_is_not_defined.txt
@@ -36,7 +36,6 @@
         help: None,
         data: UndefinedArgument {
             name: "arg2",
-            coordinate: "Field.field",
         },
     },
     ApolloDiagnostic {
@@ -76,7 +75,6 @@
         help: None,
         data: UndefinedArgument {
             name: "arg3",
-            coordinate: "Field.field",
         },
     },
     ApolloDiagnostic {
@@ -116,7 +114,6 @@
         help: None,
         data: UndefinedArgument {
             name: "arg2",
-            coordinate: "Query.field",
         },
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0054_argument_not_provided.txt b/crates/apollo-compiler/test_data/diagnostics/0054_argument_not_provided.txt
index effa133..a65afa6 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0054_argument_not_provided.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0054_argument_not_provided.txt
@@ -35,7 +35,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleReqs(req1:)",
+            name: "req1",
         },
     },
     ApolloDiagnostic {
@@ -74,7 +74,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleReqs(req2:)",
+            name: "req2",
         },
     },
     ApolloDiagnostic {
@@ -168,7 +168,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleReqs(req1:)",
+            name: "req1",
         },
     },
     ApolloDiagnostic {
@@ -207,7 +207,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "@skip(if:)",
+            name: "if",
         },
     },
     ApolloDiagnostic {
@@ -246,7 +246,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "@include(if:)",
+            name: "if",
         },
     },
     ApolloDiagnostic {
@@ -286,7 +286,6 @@
         help: None,
         data: UndefinedArgument {
             name: "wrong",
-            coordinate: "@include",
         },
     },
     ApolloDiagnostic {
@@ -325,7 +324,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleReqs(req1:)",
+            name: "req1",
         },
     },
     ApolloDiagnostic {
@@ -364,7 +363,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleOptAndReq(req2:)",
+            name: "req2",
         },
     },
     ApolloDiagnostic {
@@ -403,7 +402,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleOptAndReq(req2:)",
+            name: "req2",
         },
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0056_variables_are_input_types.txt b/crates/apollo-compiler/test_data/diagnostics/0056_variables_are_input_types.txt
index c50d8fc..dc6b362 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0056_variables_are_input_types.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0056_variables_are_input_types.txt
@@ -28,7 +28,7 @@
         ),
         data: VariableInputType {
             name: "cat",
-            ty: "Cat",
+            ty: "ObjectTypeDefinition",
         },
     },
     ApolloDiagnostic {
@@ -100,7 +100,7 @@
         ),
         data: VariableInputType {
             name: "dog",
-            ty: "Dog",
+            ty: "ObjectTypeDefinition",
         },
     },
     ApolloDiagnostic {
@@ -172,7 +172,7 @@
         ),
         data: VariableInputType {
             name: "pets",
-            ty: "Pet",
+            ty: "InterfaceTypeDefinition",
         },
     },
     ApolloDiagnostic {
@@ -244,7 +244,7 @@
         ),
         data: VariableInputType {
             name: "catOrDog",
-            ty: "CatOrDog",
+            ty: "UnionTypeDefinition",
         },
     },
     ApolloDiagnostic {
diff --git a/crates/apollo-compiler/test_data/diagnostics/0065_subselection_of_enum.txt b/crates/apollo-compiler/test_data/diagnostics/0065_subselection_of_enum.txt
index 07326f8..cdb1927 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0065_subselection_of_enum.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0065_subselection_of_enum.txt
@@ -34,10 +34,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "pet1",
-            ty: "Pet",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -74,10 +71,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "pet2",
-            ty: "Pet",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -114,10 +108,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "pet3",
-            ty: "Pet",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -154,10 +145,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "pet4",
-            ty: "Pet",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -194,10 +182,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "pet5",
-            ty: "Pet",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -234,9 +219,6 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "pet6",
-            ty: "Pet",
-        },
+        data: DisallowedSubselection,
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0066_subselection_of_scalar.txt b/crates/apollo-compiler/test_data/diagnostics/0066_subselection_of_scalar.txt
index bf5f621..3b6bae9 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0066_subselection_of_scalar.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0066_subselection_of_scalar.txt
@@ -34,10 +34,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "url1",
-            ty: "URL",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -74,10 +71,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "url2",
-            ty: "URL",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -114,10 +108,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "url3",
-            ty: "URL",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -154,10 +145,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "url4",
-            ty: "URL",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -194,10 +182,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "url5",
-            ty: "URL",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -234,9 +219,6 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "url6",
-            ty: "URL",
-        },
+        data: DisallowedSubselection,
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0067_subselection_of_interface.txt b/crates/apollo-compiler/test_data/diagnostics/0067_subselection_of_interface.txt
index 4bb7dda..16a4815 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0067_subselection_of_interface.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0067_subselection_of_interface.txt
@@ -34,10 +34,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet1",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -74,10 +71,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet2",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -114,10 +108,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet3",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -154,10 +145,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet4",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -194,10 +182,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet5",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -234,9 +219,6 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet6",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0068_subselection_of_union.txt b/crates/apollo-compiler/test_data/diagnostics/0068_subselection_of_union.txt
index 153efc7..8956015 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0068_subselection_of_union.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0068_subselection_of_union.txt
@@ -20,7 +20,7 @@
                     offset: 27,
                     length: 4,
                 },
-                text: "field `pet1` type `CatOrDog` is a union and must select fields",
+                text: "field `pet1` type `CatOrDog` is an union and must select fields",
             },
             Label {
                 location: DiagnosticLocation {
@@ -34,10 +34,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet1",
-            ty: "CatOrDog",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -60,7 +57,7 @@
                     offset: 34,
                     length: 4,
                 },
-                text: "field `pet2` type `CatOrDog` is a union and must select fields",
+                text: "field `pet2` type `CatOrDog` is an union and must select fields",
             },
             Label {
                 location: DiagnosticLocation {
@@ -74,10 +71,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet2",
-            ty: "CatOrDog",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -100,7 +94,7 @@
                     offset: 41,
                     length: 4,
                 },
-                text: "field `pet3` type `CatOrDog` is a union and must select fields",
+                text: "field `pet3` type `CatOrDog` is an union and must select fields",
             },
             Label {
                 location: DiagnosticLocation {
@@ -114,10 +108,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet3",
-            ty: "CatOrDog",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -140,7 +131,7 @@
                     offset: 48,
                     length: 4,
                 },
-                text: "field `pet4` type `CatOrDog` is a union and must select fields",
+                text: "field `pet4` type `CatOrDog` is an union and must select fields",
             },
             Label {
                 location: DiagnosticLocation {
@@ -154,10 +145,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet4",
-            ty: "CatOrDog",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -180,7 +168,7 @@
                     offset: 55,
                     length: 4,
                 },
-                text: "field `pet5` type `CatOrDog` is a union and must select fields",
+                text: "field `pet5` type `CatOrDog` is an union and must select fields",
             },
             Label {
                 location: DiagnosticLocation {
@@ -194,10 +182,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet5",
-            ty: "CatOrDog",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -220,7 +205,7 @@
                     offset: 62,
                     length: 4,
                 },
-                text: "field `pet6` type `CatOrDog` is a union and must select fields",
+                text: "field `pet6` type `CatOrDog` is an union and must select fields",
             },
             Label {
                 location: DiagnosticLocation {
@@ -234,9 +219,6 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet6",
-            ty: "CatOrDog",
-        },
+        data: MissingSubselection,
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0069_subselection_of_object.txt b/crates/apollo-compiler/test_data/diagnostics/0069_subselection_of_object.txt
index a53ea46..87c0f5b 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0069_subselection_of_object.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0069_subselection_of_object.txt
@@ -34,10 +34,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet1",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -74,10 +71,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet2",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -114,10 +108,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet3",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -154,10 +145,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet4",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -194,10 +182,7 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet5",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
     ApolloDiagnostic {
         cache: {
@@ -234,9 +219,6 @@
             },
         ],
         help: None,
-        data: MissingSubselection {
-            field: "pet6",
-            ty: "Pet",
-        },
+        data: MissingSubselection,
     },
 ]
diff --git a/crates/apollo-compiler/test_data/diagnostics/0087_fragment_type_condition_on_composite_types.txt b/crates/apollo-compiler/test_data/diagnostics/0087_fragment_type_condition_on_composite_types.txt
index 5bf1b21..23bea64 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0087_fragment_type_condition_on_composite_types.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0087_fragment_type_condition_on_composite_types.txt
@@ -34,10 +34,7 @@
             },
         ],
         help: None,
-        data: DisallowedSubselection {
-            field: "price",
-            ty: "Int",
-        },
+        data: DisallowedSubselection,
     },
     ApolloDiagnostic {
         cache: {
diff --git a/crates/apollo-compiler/test_data/diagnostics/0091_recursive_interface_definition.txt b/crates/apollo-compiler/test_data/diagnostics/0091_recursive_interface_definition.txt
index a0b54fe..8ea6d3e 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0091_recursive_interface_definition.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0091_recursive_interface_definition.txt
@@ -25,7 +25,6 @@
         ],
         help: None,
         data: TransitiveImplementedInterfaces {
-            ty: "A",
             missing_interface: "A",
         },
     },
@@ -55,7 +54,6 @@
         ],
         help: None,
         data: TransitiveImplementedInterfaces {
-            ty: "B",
             missing_interface: "B",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0093_fragment_validation_with_recursive_type_system.txt b/crates/apollo-compiler/test_data/diagnostics/0093_fragment_validation_with_recursive_type_system.txt
index 4369f2e..6b831d2 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0093_fragment_validation_with_recursive_type_system.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0093_fragment_validation_with_recursive_type_system.txt
@@ -25,7 +25,6 @@
         ],
         help: None,
         data: TransitiveImplementedInterfaces {
-            ty: "A",
             missing_interface: "A",
         },
     },
@@ -55,7 +54,6 @@
         ],
         help: None,
         data: TransitiveImplementedInterfaces {
-            ty: "B",
             missing_interface: "B",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0094_object_type_extensions.txt b/crates/apollo-compiler/test_data/diagnostics/0094_object_type_extensions.txt
index c1e64ce..dbf33db 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0094_object_type_extensions.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0094_object_type_extensions.txt
@@ -240,8 +240,6 @@
             "An object must provide all fields required by the interfaces it implements",
         ),
         data: MissingField {
-            name: "ImplementsBaseButNotExtension",
-            interface: "ExtendedInterface",
             field: "fail",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0097_enum_extensions.txt b/crates/apollo-compiler/test_data/diagnostics/0097_enum_extensions.txt
index e5f52a9..4dc229b 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0097_enum_extensions.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0097_enum_extensions.txt
@@ -89,9 +89,9 @@
         help: Some(
             "MEMBER_2 must only be defined once in this enum.",
         ),
-        data: UniqueEnumValue {
+        data: UniqueDefinition {
+            ty: "enum value",
             name: "MEMBER_2",
-            coordinate: "E",
             original_definition: DiagnosticLocation {
                 file_id: FileId {
                     id: 94,
@@ -145,9 +145,9 @@
         help: Some(
             "MEMBER_4 must only be defined once in this enum.",
         ),
-        data: UniqueEnumValue {
+        data: UniqueDefinition {
+            ty: "enum value",
             name: "MEMBER_4",
-            coordinate: "E",
             original_definition: DiagnosticLocation {
                 file_id: FileId {
                     id: 94,
diff --git a/crates/apollo-compiler/test_data/diagnostics/0098_interface_extensions.txt b/crates/apollo-compiler/test_data/diagnostics/0098_interface_extensions.txt
index 09e7c84..05f8e0b 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0098_interface_extensions.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0098_interface_extensions.txt
@@ -145,8 +145,6 @@
             "An interface must be a super-set of all interfaces it implements",
         ),
         data: MissingField {
-            name: "Derived",
-            interface: "Base",
             field: "b",
         },
     },
diff --git a/crates/apollo-compiler/test_data/diagnostics/0102_invalid_string_values.txt b/crates/apollo-compiler/test_data/diagnostics/0102_invalid_string_values.txt
index 74cb26d..26dbc4d 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0102_invalid_string_values.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0102_invalid_string_values.txt
@@ -1164,7 +1164,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleReqs(req2:)",
+            name: "req2",
         },
     },
     ApolloDiagnostic {
@@ -1243,7 +1243,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleReqs(req1:)",
+            name: "req1",
         },
     },
     ApolloDiagnostic {
@@ -1282,7 +1282,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplicatedArgs.multipleReqs(req2:)",
+            name: "req2",
         },
     },
     ApolloDiagnostic {
@@ -1321,7 +1321,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplexInput.requiredField",
+            name: "requiredField",
         },
     },
     ApolloDiagnostic {
@@ -1590,7 +1590,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplexInput.requiredField",
+            name: "requiredField",
         },
     },
     ApolloDiagnostic {
@@ -1829,7 +1829,7 @@
         ],
         help: None,
         data: RequiredArgument {
-            coordinate: "ComplexInput.requiredField",
+            name: "requiredField",
         },
     },
     ApolloDiagnostic {
diff --git a/crates/apollo-compiler/test_data/diagnostics/0103_invalid_type_in_arg.txt b/crates/apollo-compiler/test_data/diagnostics/0103_invalid_type_in_arg.txt
index 7b49cdf..8560f4b 100644
--- a/crates/apollo-compiler/test_data/diagnostics/0103_invalid_type_in_arg.txt
+++ b/crates/apollo-compiler/test_data/diagnostics/0103_invalid_type_in_arg.txt
@@ -28,7 +28,7 @@
         ),
         data: InputType {
             name: "thisIsWrong",
-            ty: "OutputType",
+            ty: "ObjectTypeDefinition",
         },
     },
     ApolloDiagnostic {
@@ -118,7 +118,7 @@
         ),
         data: InputType {
             name: "a",
-            ty: "OutputType",
+            ty: "ObjectTypeDefinition",
         },
     },
     ApolloDiagnostic {
@@ -150,7 +150,7 @@
         ),
         data: InputType {
             name: "b",
-            ty: "OperationResult",
+            ty: "UnionTypeDefinition",
         },
     },
 ]