fn find_common_alias<'a, U>(
    unifier: &mut UnifierState<'a, U>,
    expected: &ArcType,
    actual: &ArcType,
    through_alias: &mut bool,
) -> Result<(ArcType, ArcType), ()>
where
    UnifierState<'a, U>: Unifier<State<'a>, ArcType>,
{
    // If the spine of the application consists of type variables we must first resolve those
    // before trying the alias as the resolve module does not know about type varaibles
    let mut r = resolve_application(actual, unifier.state.subs).unwrap_or_else(|| actual.clone());
    let mut l =
        resolve_application(expected, unifier.state.subs).unwrap_or_else(|| expected.clone());
    let mut l_root = None;
    let reduced_aliases_len = unifier.state.reduced_aliases.len();
    if let Some(r_id) = r.name() {
        l = match find_alias(unifier, l.clone(), r_id)? {
            FoundAlias::Root(root) => {
                l_root = Some(root);
                l
            }
            FoundAlias::AlreadyDone => l,
            FoundAlias::Found(typ) => {
                *through_alias = true;
                return Ok((typ, actual.clone()));
            }
        };
    }

    // Avoid triggering invalid self recursion checks from anything that the first find did
    let mut saved_aliases: SmallVec<[_; 5]> = unifier
        .state
        .reduced_aliases
        .drain(reduced_aliases_len..)
        .collect();

    let result = if let Some(l_id) = l.name() {
        Some(find_alias(unifier, r.clone(), l_id)?)
    } else {
        None
    };
    if let Some(result) = result {
        r = match result {
            FoundAlias::Root(root) => {
                *through_alias = true;
                if let Some(l_root) = l_root {
                    l = l_root;
                }
                root
            }
            FoundAlias::AlreadyDone => {
                saved_aliases.clear();
                r
            }
            FoundAlias::Found(typ) => {
                *through_alias = true;
                typ
            }
        };
    }

    unifier.state.reduced_aliases.extend(saved_aliases);

    Ok((l, r))
}
/// Attempt to find a common alias between two types. If the function is successful it returns
/// either the same types that were passed in or two types which have the same alias in their spine
///
/// Example:
///
/// ```f#
/// type Test a = | Test a Int
/// type Test2 = Test String
///
/// // find_common_alias(Test2, Test 0) => Ok((Test String, Test 0))
/// // find_common_alias(Float, Test 0) => Ok((Float, Test 0))
/// ```
Attempt to find a common alias between two types. If the function is successful it returns
either the same types that were passed in or two types which have the same alias in their spine



```f
type Test a = | Test a Int
type Test2 = Test String


Attempt to find a common alias between two types . If the function is successful it returns either the same types that were passed in or two types which have the same alias in their spine ` ` ` f type Test a = | Test a Int type Test2 = Test String
fn find_common_alias<'a, U>(
    unifier: &mut UnifierState<'a, U>,
    expected: &ArcType,
    actual: &ArcType,
    through_alias: &mut bool,
) -> Result<(ArcType, ArcType), ()>
where
    UnifierState<'a, U>: Unifier<State<'a>, ArcType>,
{
    // If the spine of the application consists of type variables we must first resolve those
    // before trying the alias as the resolve module does not know about type varaibles
    let mut r = resolve_application(actual, unifier.state.subs).unwrap_or_else(|| actual.clone());
    let mut l =
        resolve_application(expected, unifier.state.subs).unwrap_or_else(|| expected.clone());
    let mut l_root = None;
    let reduced_aliases_len = unifier.state.reduced_aliases.len();
    if let Some(r_id) = r.name() {
        l = match find_alias(unifier, l.clone(), r_id)? {
            FoundAlias::Root(root) => {
                l_root = Some(root);
                l
            }
            FoundAlias::AlreadyDone => l,
            FoundAlias::Found(typ) => {
                *through_alias = true;
                return Ok((typ, actual.clone()));
            }
        };
    }
    // Avoid triggering invalid self recursion checks from anything that the first find did
    let mut saved_aliases: SmallVec<[_; 5]> = unifier
        .state
        .reduced_aliases
        .drain(reduced_aliases_len..)
        .collect();
    let result = if let Some(l_id) = l.name() {
        Some(find_alias(unifier, r.clone(), l_id)?)
    } else {
        None
    };
    if let Some(result) = result {
        r = match result {
            FoundAlias::Root(root) => {
                *through_alias = true;
                if let Some(l_root) = l_root {
                    l = l_root;
                }
                root
            }
            FoundAlias::AlreadyDone => {
                saved_aliases.clear();
                r
            }
            FoundAlias::Found(typ) => {
                *through_alias = true;
                typ
            }
        };
    }
    unifier.state.reduced_aliases.extend(saved_aliases);
    Ok((l, r))
}
fn find_common_alias < ' a , U > ( unifier : & mut UnifierState < ' a , U > , expected : & ArcType , actual : & ArcType , through_alias : & mut bool , ) -> Result < ( ArcType , ArcType ) , ( ) > where UnifierState < ' a , U > : Unifier < State < ' a > , ArcType > , { // If the spine of the application consists of type variables we must first resolve those // before trying the alias as the resolve module does not know about type varaibles let mut r = resolve_application ( actual , unifier . state . subs ) . unwrap_or_else ( | | actual . clone ( ) ) ; let mut l = resolve_application ( expected , unifier . state . subs ) . unwrap_or_else ( | | expected . clone ( ) ) ; let mut l_root = None ; let reduced_aliases_len = unifier . state . reduced_aliases . len ( ) ; if let Some ( r_id ) = r . name ( ) { l = match find_alias ( unifier , l . clone ( ) , r_id ) ? { FoundAlias :: Root ( root ) => { l_root = Some ( root ) ; l } FoundAlias :: AlreadyDone => l , FoundAlias :: Found ( typ ) => { * through_alias = true ; return Ok ( ( typ , actual . clone ( ) ) ) ; } } ; } // Avoid triggering invalid self recursion checks from anything that the first find did let mut saved_aliases : SmallVec < [ _ ; 5 ] > = unifier . state . reduced_aliases . drain ( reduced_aliases_len .. ) . collect ( ) ; let result = if let Some ( l_id ) = l . name ( ) { Some ( find_alias ( unifier , r . clone ( ) , l_id ) ? ) } else { None } ; if let Some ( result ) = result { r = match result { FoundAlias :: Root ( root ) => { * through_alias = true ; if let Some ( l_root ) = l_root { l = l_root ; } root } FoundAlias :: AlreadyDone => { saved_aliases . clear ( ) ; r } FoundAlias :: Found ( typ ) => { * through_alias = true ; typ } } ; } unifier . state . reduced_aliases . extend ( saved_aliases ) ; Ok ( ( l , r ) ) }
Attempt to find a common alias between two types.
Attempt to find a common alias between two types .
unifier
&mut UnifierState<'a, U>
expected
&ArcType
actual
&ArcType
through_alias
&mut bool