Introduce UnorderedSet newtype
diff --git a/syntax/set.rs b/syntax/set.rs
index ee490e9..6508f55 100644
--- a/syntax/set.rs
+++ b/syntax/set.rs
@@ -2,15 +2,15 @@
use std::slice;
pub use self::ordered::OrderedSet;
+pub use self::unordered::UnorderedSet;
mod ordered {
- use super::Iter;
+ use super::{Iter, UnorderedSet};
use std::borrow::Borrow;
- use std::collections::HashSet;
use std::hash::Hash;
pub struct OrderedSet<T> {
- set: HashSet<T>,
+ set: UnorderedSet<T>,
vec: Vec<T>,
}
@@ -20,7 +20,7 @@
{
pub fn new() -> Self {
OrderedSet {
- set: HashSet::new(),
+ set: UnorderedSet::new(),
vec: Vec::new(),
}
}
@@ -59,6 +59,45 @@
}
}
+mod unordered {
+ use std::borrow::Borrow;
+ use std::collections::HashSet;
+ use std::hash::Hash;
+
+ // Wrapper prohibits accidentally introducing iteration over the set, which
+ // could lead to nondeterministic generated code.
+ pub struct UnorderedSet<T>(HashSet<T>);
+
+ impl<T> UnorderedSet<T>
+ where
+ T: Hash + Eq,
+ {
+ pub fn new() -> Self {
+ UnorderedSet(HashSet::new())
+ }
+
+ pub fn insert(&mut self, value: T) -> bool {
+ self.0.insert(value)
+ }
+
+ pub fn contains<Q>(&self, value: &Q) -> bool
+ where
+ T: Borrow<Q>,
+ Q: ?Sized + Hash + Eq,
+ {
+ self.0.contains(value)
+ }
+
+ pub fn get<Q>(&self, value: &Q) -> Option<&T>
+ where
+ T: Borrow<Q>,
+ Q: ?Sized + Hash + Eq,
+ {
+ self.0.get(value)
+ }
+ }
+}
+
pub struct Iter<'s, 'a, T>(slice::Iter<'s, &'a T>);
impl<'s, 'a, T> Iterator for Iter<'s, 'a, T> {
diff --git a/syntax/types.rs b/syntax/types.rs
index 50325d6..90a8221 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -1,14 +1,14 @@
use crate::syntax::atom::Atom::{self, *};
use crate::syntax::improper::ImproperCtype;
use crate::syntax::report::Errors;
-use crate::syntax::set::OrderedSet as Set;
+use crate::syntax::set::{OrderedSet as Set, UnorderedSet};
use crate::syntax::{
toposort, Api, Derive, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName, Struct, Type,
TypeAlias,
};
use proc_macro2::Ident;
use quote::ToTokens;
-use std::collections::{BTreeMap as Map, HashSet as UnorderedSet};
+use std::collections::BTreeMap as Map;
pub struct Types<'a> {
pub all: Set<&'a Type>,