Move error collection one level out of type checker
diff --git a/gen/src/mod.rs b/gen/src/mod.rs
index c7b3c3c..0cfdc59 100644
--- a/gen/src/mod.rs
+++ b/gen/src/mod.rs
@@ -8,6 +8,7 @@
 
 use self::error::{format_err, Error, Result};
 use crate::syntax::namespace::Namespace;
+use crate::syntax::report::Errors;
 use crate::syntax::{self, check, Types};
 use quote::quote;
 use std::fs;
@@ -42,12 +43,14 @@
     };
     match (|| -> Result<_> {
         proc_macro2::fallback::force();
+        let ref mut errors = Errors::new();
         let syntax = syn::parse_file(&source)?;
         let bridge = find_bridge_mod(syntax)?;
         let ref namespace = bridge.namespace;
         let ref apis = syntax::parse_items(bridge.module)?;
         let ref types = Types::collect(apis)?;
-        check::typecheck(namespace, apis, types)?;
+        check::typecheck(errors, namespace, apis, types);
+        errors.propagate()?;
         let out = write::gen(namespace, apis, types, opt, header);
         Ok(out)
     })() {
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 737c389..f5cbbf2 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -1,5 +1,6 @@
 use crate::syntax::atom::Atom::{self, *};
 use crate::syntax::namespace::Namespace;
+use crate::syntax::report::Errors;
 use crate::syntax::symbol::Symbol;
 use crate::syntax::{
     self, check, mangle, Api, Enum, ExternFn, ExternType, Signature, Struct, Type, Types,
@@ -9,6 +10,7 @@
 use syn::{parse_quote, Error, ItemMod, Result, Token};
 
 pub fn bridge(namespace: &Namespace, ffi: ItemMod) -> Result<TokenStream> {
+    let ref mut errors = Errors::new();
     let ident = &ffi.ident;
     let content = ffi.content.ok_or(Error::new(
         Span::call_site(),
@@ -16,7 +18,8 @@
     ))?;
     let ref apis = syntax::parse_items(content.1)?;
     let ref types = Types::collect(apis)?;
-    check::typecheck(namespace, apis, types)?;
+    check::typecheck(errors, namespace, apis, types);
+    errors.propagate()?;
 
     let mut expanded = TokenStream::new();
     let mut hidden = TokenStream::new();
diff --git a/syntax/check.rs b/syntax/check.rs
index 3fb0d06..72b4a6c 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -10,7 +10,6 @@
 use std::collections::HashSet;
 use std::fmt::Display;
 use std::u32;
-use syn::Result;
 
 pub(crate) struct Check<'a> {
     namespace: &'a Namespace,
@@ -19,16 +18,13 @@
     errors: &'a mut Errors,
 }
 
-pub(crate) fn typecheck(namespace: &Namespace, apis: &[Api], types: &Types) -> Result<()> {
-    let mut errors = Errors::new();
-    let mut cx = Check {
+pub(crate) fn typecheck(cx: &mut Errors, namespace: &Namespace, apis: &[Api], types: &Types) {
+    do_typecheck(&mut Check {
         namespace,
         apis,
         types,
-        errors: &mut errors,
-    };
-    do_typecheck(&mut cx);
-    errors.propagate()
+        errors: cx,
+    });
 }
 
 fn do_typecheck(cx: &mut Check) {