Mercurial > hg
view rust/hg-core/src/copy_tracing/tests_support.rs @ 47287:402bd66cbdf2
rust: Add type annotation to fix inference on Rust Nightly
When compiling with Rust Nightly, the im-rs crate silently makes use of the
experimental language feature for trait impl specialization. This apperently
changes public its APIs in subtle ways such that type inference of some user
code can fail where it succeeds when specialization is disabled.
This made Mercurial’s Rust unit tests have compilation errors on Nightly.
I have not managed to find the exactl root cause, but I wrote down my findings
so far at https://github.com/bodil/im-rs/issues/188
This adds type annotation to make unit tests rely less on type inference
and work around the issue.
Differential Revision: https://phab.mercurial-scm.org/D10742
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Wed, 19 May 2021 15:08:27 +0200 |
parents | fa21633af201 |
children |
line wrap: on
line source
//! Supporting macros for `tests.rs` in the same directory. //! See comments there for usage. /// Python-like set literal macro_rules! set { ( $Type: ty { $( $value: expr ),* $(,)? } ) => {{ #[allow(unused_mut)] let mut set = <$Type>::new(); $( set.insert($value); )* set }} } /// `{key => value}` map literal macro_rules! map { ( $Type: ty { $( $key: expr => $value: expr ),* $(,)? } ) => {{ #[allow(unused_mut)] let mut set = <$Type>::new(); $( set.insert($key, $value); )* set }} } macro_rules! copy_source { ($rev: expr, $path: expr, $overwritten: tt) => { CopySource { rev: $rev, path: $path, overwritten: set!(OrdSet<Revision> $overwritten), } }; } macro_rules! compare_value { ( $merge_revision: expr, $merge_case_for_dest: ident, ($min_rev: expr, $min_path: expr, $min_overwrite: tt), ($maj_rev: expr, $maj_path: expr, $maj_overwrite: tt) $(,)? ) => { compare_value( $merge_revision, || $merge_case_for_dest, ©_source!($min_rev, $min_path, $min_overwrite), ©_source!($maj_rev, $maj_path, $maj_overwrite), ) }; } macro_rules! tokenized_path_copies { ( $path_map: ident, {$( $dest: expr => ( $src_rev: expr, $src_path: expr, $src_overwrite: tt ) ),*} $(,)* ) => { map!(InternalPathCopies {$( $path_map.tokenize(HgPath::new($dest)) => copy_source!( $src_rev, Option::map($src_path, |p: &str| { $path_map.tokenize(HgPath::new(p)) }), $src_overwrite ) )*}) } } macro_rules! merge_case_callback { ( $( $merge_path: expr => $merge_case: ident ),* $(,)? ) => { #[allow(unused)] |merge_path| -> MergeCase { $( if (merge_path == HgPath::new($merge_path)) { return $merge_case } )* MergeCase::Normal } }; } macro_rules! merge_copies_dict { ( $current_merge: expr, $minor_copies: tt, $major_copies: tt, $get_merge_case: tt $(,)? ) => { { #[allow(unused_mut)] let mut map = TwoWayPathMap::default(); let minor = tokenized_path_copies!(map, $minor_copies); let major = tokenized_path_copies!(map, $major_copies); merge_copies_dict( &map, $current_merge, minor, major, merge_case_callback! $get_merge_case, ) .into_iter() .map(|(token, source)| { ( map.untokenize(token).to_string(), ( source.rev, source.path.map(|t| map.untokenize(t).to_string()), source.overwritten.into_iter().collect(), ), ) }) .collect::<OrdMap< String, (Revision, Option<String>, OrdSet<Revision>) >>() } }; } macro_rules! internal_path_copies { ( $( $dest: expr => ( $src_rev: expr, $src_path: expr, $src_overwrite: tt $(,)? ) ),* $(,)* ) => { map!(OrdMap<_, _> {$( String::from($dest) => ( $src_rev, $src_path, set!(OrdSet<Revision> $src_overwrite) ) ),*}) }; } macro_rules! combine_changeset_copies { ( $children_count: tt, [ $( { rev: $rev: expr, p1: $p1: expr, p2: $p2: expr, actions: [ $( $Action: ident($( $action_path: expr ),+) ),* $(,)? ], merge_cases: $merge: tt $(,)? } ),* $(,)? ], $target_rev: expr $(,)* ) => {{ let count = map!(HashMap<Revision, usize> $children_count); let mut combine_changeset_copies = CombineChangesetCopies::new(count); $( let actions = vec![$( $Action($( HgPath::new($action_path) ),*) ),*]; combine_changeset_copies.add_revision_inner( $rev, $p1, $p2, actions.into_iter(), merge_case_callback! $merge ); )* combine_changeset_copies.finish($target_rev) }}; } macro_rules! path_copies { ( $( $expected_destination: expr => $expected_source: expr ),* $(,)? ) => { map!(PathCopies {$( HgPath::new($expected_destination).to_owned() => HgPath::new($expected_source).to_owned(), ),*}) }; }