You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: coerce.rs
    path of file: ./repos/rust-analyzer/crates/hir-ty/src/infer
    
    the code of the file until where you have to start completion: //! Coercion logic. Coercions are certain type conversions that can implicitly
//! happen in certain places, e.g. weakening `&mut` to `&` or deref coercions
//! like going from `&Vec<T>` to `&[T]`.
//!
//! See <https://doc.rust-lang.org/nomicon/coercions.html> and
//! `rustc_hir_analysis/check/coercion.rs`.

use std::iter;

use chalk_ir::{cast::Cast, BoundVar, Goal, Mutability, TyKind, TyVariableKind};
use hir_def::{
    hir::ExprId,
    lang_item::{LangItem, LangItemTarget},
};
use stdx::always;
use triomphe::Arc;

use crate::{
    autoderef::{Autoderef, AutoderefKind},
    db::HirDatabase,
    infer::{
        Adjust, Adjustment, AutoBorrow, InferOk, InferenceContext, OverloadedDeref, PointerCast,
        TypeError, TypeMismatch,
    },
    static_lifetime,
    utils::ClosureSubst,
    Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
    Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
};

use super::unify::InferenceTable;

pub(crate) type CoerceResult = Result<InferOk<(Vec<Adjustment>, Ty)>, TypeError>;

/// Do not require any adjustments, i.e. coerce `x -> x`.
fn identity(_: Ty) -> Vec<Adjustment> {
    vec![]
}

fn simple(kind: Adjust) -> impl FnOnce(Ty) -> Vec<Adjustment> {
    move |target| vec![Adjustment { kind, target }]
}

/// This always returns `Ok(...)`.
fn success(
    adj: Vec<Adjustment>,
    target: Ty,
    goals: Vec<InEnvironment<Goal<Interner>>>,
) -> CoerceResult {
    Ok(InferOk { goals, value: (adj, target) })
}

pub(super) enum CoercionCause {
    // FIXME: Make better use of this. Right now things like return and break without a value
    // use it to point to themselves, causing us to report a mismatch on those expressions even
    // though technically they themselves are `!`
    Expr(ExprId),
}

#[derive(Clone, Debug)]
pub(super) struct CoerceMany {
    expected_ty: Ty,
    final_ty: Option<Ty>,
    expressions: Vec<ExprId>,
}

impl CoerceMany {
    pub(super) fn new(expected: Ty) -> Self {
        CoerceMany { expected_ty: expected, final_ty: None, expressions: vec![] }
    }

    /// Returns the "expected type" with which this coercion was
    /// constructed. This represents the "downward propagated" type
    /// that was given to us at the start of typing whatever construct
    /// we are typing (e.g., the match expression).
    ///
    /// Typically, this is used as the expected type when
    /// type-checking each of the alternative expressions whose types
    /// we are trying to merge.
    pub(super) fn expected_ty(&self) -> Ty {
        self.expected_ty.clone()
    }

    /// Returns the current "merged type", representing our best-guess
    /// at the LUB of the expressions we've seen so far (if any). This
    /// isn't *final* until you call `self.complete()`, which will return
    /// the merged type.
    pub(super) fn merged_ty(&self) -> Ty {
        self.final_ty.clone().unwrap_or_else(|| self.expected_ty.clone())
    }

    pub(super) fn complete(self, ctx: &mut InferenceContext<'_>) -> Ty {
        if let Some(final_ty) = self.final_ty {
            final_ty
        } else {
            ctx.result.standard_types.never.clone()
        }
    }

    pub(super) fn coerce_forced_unit(
        &mut self,
        ctx: &mut InferenceContext<'_>,
        cause: CoercionCause,
    ) {
        self.coerce(ctx, None, &ctx.result.standard_types.unit.clone(), cause)
    }

    /// Merge two 
    
    fn try_coerce_unsized(&mut self, from_ty: &Ty, to_ty: &Ty) -> CoerceResult {
        // These 'if' statements require some explanation.
        // The `CoerceUnsized` trait is special - it is only
        // possible to write `impl CoerceUnsized<B> for A` where
        // A and B have 'matching' fields. This rules out the following
        // two types of blanket impls:
        //
        // `impl<T> CoerceUnsized<T> for SomeType`
        // `impl<T> CoerceUnsized<SomeType> for T`
        //
        // Both of these trigger a special `CoerceUnsized`-related error (E0376)
        //
        // We can take advantage of this fact to avoid performing unnecessary work.
        // If either `source` or `target` is a type variable, then any applicable impl
        // would need to be generic over the self-type (`impl<T> CoerceUnsized<SomeType> for T`)
        // or generic over the `CoerceUnsized` type parameter (`impl<T> CoerceUnsized<T> for
        // SomeType`).
        //
        // However, these are exactly the kinds of impls which are forbidden by
        // the compiler! Therefore, we can be sure that coercion will always fail
        // when either the source or target type is a type variable. This allows us
        // to skip performing any trait selection, and immediately bail out.
        if from_ty.is_ty_var() {
            return Err(TypeError);
        }
        if to_ty.is_ty_var() {
            return Err(TypeError);
        }

        // Handle reborrows before trying to solve `Source: CoerceUnsized<Target>`.
        let reborrow = match (from_ty.kind(Interner), to_ty.kind(Interner)) {
            (TyKind::Ref(from_mt, _, from_inner), &TyKind::Ref(to_mt, _, _)) => {
                coerce_mutabilities(*from_mt, to_mt)?;

                let lt = static_lifetime();
                Some((
                    Adjustment { kind: Adjust::Deref(None), target: from_inner.clone() },
                    Adjustment {
                        kind: Adjust::Borrow(AutoBorrow::Ref(to_mt)),
                        target: TyKind::Ref(to_mt, lt, from_inner.clone()).intern(Interner),
                    },
                ))
            }
            (TyKind::Ref(from_mt, _, from_inner), &TyKind::Raw(to_mt, _)) => {
                coerce_mutabilities(*from_mt, to_mt)?;

                Some((
                    Adjustment { kind: Adjust::Deref(None), target: from_inner.clone() },
                    Adjustment {
                        kind: Adjust::Borrow(AutoBorrow::RawPtr(to_mt)),
                        target: TyKind::Raw(to_mt, from_inner.clone()).intern(Interner),
                    },
                ))
            }
            _ => None,
        };
        let coerce_from =
            reborrow.as_ref().map_or_else(|| from_ty.clone(), |(_, adj)| adj.target.clone());

        let krate = self.trait_env.krate;
        let coerce_unsized_trait = match self.db.lang_item(krate, LangItem::CoerceUnsized) {
            Some(LangItemTarget::Trait(trait_)) => trait_,
            _ => return Err(TypeError),
        };

        let coerce_unsized_tref = {
            let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait);
            if b.remaining() != 2 {
                // The CoerceUnsized trait should have two generic params: Self and T.
                return Err(TypeError);
            }
            b.push(coerce_from).push(to_ty.clone()).build()
        };

        let goal: InEnvironment<DomainGoal> =
            InEnvironment::new(&self.trait_env.env, coerce_unsized_tref.cast(Interner));

        let canonicalized = self.canonicalize_with_free_vars(goal);

        // FIXME: rustc's coerce_unsized is more specialized -- it only tries to
        // solve `CoerceUnsized` and `Unsize` goals at this point and leaves the
        // rest for later. Also, there's some logic about sized type variables.
        // Need to find out in what cases this is necessary
        let solution = self
            .db
            .trait_solve(krate, self.trait_env.block, canonicalized.value.clone().cast(Interner))
            .ok_or(TypeError)?;

        match solution {
            Solution::Unique(v) => {
                canonicalized.apply_solution(
                    self,
                    Canonical {
                        binders: v.binders,
                        // FIXME handle constraints
                        value: v.value.subst,
                    },
                );
            }
            Solution::Ambig(Guidance::Definite(subst)) => {
                // FIXME need to record an obligation here
                canonicalized.apply_solution(self, subst)
            }
            // FIXME actually we maybe should also accept unknown guidance here
            _ => return Err(TypeError),
        };
        let unsize =
            Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target: to_ty.clone() };
        let adjustments = match reborrow {
            None => vec![unsize],
            Some((deref, autoref)) => vec![deref, autoref, unsize],
        };
        success(adjustments, to_ty.clone(), vec![])
    }