Skip to content

Commit

Permalink
Fix nondeterministic code generation
Browse files Browse the repository at this point in the history
mockall_derive was internally using HashMap and HashSet and iterating
over their contents.  But by default those types use random internal
state, resulting in nondeterministic output.  Switch them to use
consistent state.

Reported by:	David Tolnay @dtolnay
  • Loading branch information
asomers committed Sep 10, 2021
1 parent 07693ec commit e2f5285
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions mockall_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use cfg_if::cfg_if;
use proc_macro2::{Span, TokenStream};
use quote::{ToTokens, format_ident, quote};
use std::{
collections::{HashMap, HashSet},
env,
hash::BuildHasherDefault
};
use syn::{
*,
Expand All @@ -34,6 +34,10 @@ use crate::mock_item::MockItem;
use crate::mock_item_struct::MockItemStruct;
use crate::mockable_item::MockableItem;

// Define deterministic aliases for these common types.
type HashMap<K, V> = std::collections::HashMap<K, V, BuildHasherDefault<std::collections::hash_map::DefaultHasher>>;
type HashSet<K> = std::collections::HashSet<K, BuildHasherDefault<std::collections::hash_map::DefaultHasher>>;

cfg_if! {
// proc-macro2's Span::unstable method requires the nightly feature, and it
// doesn't work in test mode.
Expand Down Expand Up @@ -126,7 +130,7 @@ fn deanonymize(literal_type: &mut Type) {
fn declosurefy(gen: &Generics, args: &Punctuated<FnArg, Token![,]>) ->
(Generics, Vec<FnArg>, Vec<TokenStream>)
{
let mut hm = HashMap::new();
let mut hm = HashMap::default();

let mut save_fn_types = |ident: &Ident, tpb: &TypeParamBound| {
if let TypeParamBound::Trait(tb) = tpb {
Expand Down

0 comments on commit e2f5285

Please sign in to comment.