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)
+ }
+}