Extract error collection to be not specific to check.rs
diff --git a/syntax/check.rs b/syntax/check.rs
index 5d442ce..3fb0d06 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -1,5 +1,6 @@
 use crate::syntax::atom::Atom::{self, *};
 use crate::syntax::namespace::Namespace;
+use crate::syntax::report::Errors;
 use crate::syntax::{
     error, ident, Api, Enum, ExternFn, ExternType, Lang, Receiver, Ref, Slice, Struct, Ty1, Type,
     Types,
@@ -9,17 +10,17 @@
 use std::collections::HashSet;
 use std::fmt::Display;
 use std::u32;
-use syn::{Error, Result};
+use syn::Result;
 
 pub(crate) struct Check<'a> {
     namespace: &'a Namespace,
     apis: &'a [Api],
     types: &'a Types<'a>,
-    errors: &'a mut Vec<Error>,
+    errors: &'a mut Errors,
 }
 
 pub(crate) fn typecheck(namespace: &Namespace, apis: &[Api], types: &Types) -> Result<()> {
-    let mut errors = Vec::new();
+    let mut errors = Errors::new();
     let mut cx = Check {
         namespace,
         apis,
@@ -27,7 +28,7 @@
         errors: &mut errors,
     };
     do_typecheck(&mut cx);
-    combine_errors(errors)
+    errors.propagate()
 }
 
 fn do_typecheck(cx: &mut Check) {
@@ -59,7 +60,7 @@
 
 impl Check<'_> {
     pub(crate) fn error(&mut self, sp: impl ToTokens, msg: impl Display) {
-        self.errors.push(Error::new_spanned(sp, msg));
+        self.errors.error(sp, msg);
     }
 }
 
@@ -373,18 +374,6 @@
     }
 }
 
-fn combine_errors(errors: Vec<Error>) -> Result<()> {
-    let mut iter = errors.into_iter();
-    let mut all_errors = match iter.next() {
-        Some(err) => err,
-        None => return Ok(()),
-    };
-    for err in iter {
-        all_errors.combine(err);
-    }
-    Err(all_errors)
-}
-
 fn describe(cx: &mut Check, ty: &Type) -> String {
     match ty {
         Type::Ident(ident) => {
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 9b1a7e5..e6c5bb8 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -10,6 +10,7 @@
 pub mod mangle;
 pub mod namespace;
 mod parse;
+pub mod report;
 pub mod set;
 pub mod symbol;
 mod tokens;
diff --git a/syntax/report.rs b/syntax/report.rs
new file mode 100644
index 0000000..04f21d8
--- /dev/null
+++ b/syntax/report.rs
@@ -0,0 +1,29 @@
+use quote::ToTokens;
+use std::fmt::Display;
+use syn::{Error, Result};
+
+pub struct Errors {
+    errors: Vec<Error>,
+}
+
+impl Errors {
+    pub fn new() -> Self {
+        Errors { errors: Vec::new() }
+    }
+
+    pub fn error(&mut self, sp: impl ToTokens, msg: impl Display) {
+        self.errors.push(Error::new_spanned(sp, msg));
+    }
+
+    pub fn propagate(&mut self) -> Result<()> {
+        let mut iter = self.errors.drain(..);
+        let mut all_errors = match iter.next() {
+            Some(err) => err,
+            None => return Ok(()),
+        };
+        for err in iter {
+            all_errors.combine(err);
+        }
+        Err(all_errors)
+    }
+}