fn check_sig_compat(
        &mut self,
        sig: ty::FnSig<'tcx>,
        real_sig: ty::FnSig<'tcx>,
    ) -> EvalResult<'tcx, bool> {
        fn check_ty_compat<'tcx>(ty: Ty<'tcx>, real_ty: Ty<'tcx>) -> bool {
            if ty == real_ty {
                return true;
            } // This is actually a fast pointer comparison
            return match (&ty.sty, &real_ty.sty) {
                // Permit changing the pointer type of raw pointers and references as well as
                // mutability of raw pointers.
                // FIXME: Should not be allowed when fat pointers are involved.
                (&ty::RawPtr(_), &ty::RawPtr(_)) => true,
                (&ty::Ref(_, _, _), &ty::Ref(_, _, _)) => {
                    ty.is_mutable_pointer() == real_ty.is_mutable_pointer()
                }
                // rule out everything else
                _ => false,
            };
        }

        if sig.abi == real_sig.abi && sig.variadic == real_sig.variadic &&
            sig.inputs_and_output.len() == real_sig.inputs_and_output.len() &&
            sig.inputs_and_output
                .iter()
                .zip(real_sig.inputs_and_output)
                .all(|(ty, real_ty)| check_ty_compat(ty, real_ty))
        {
            // Definitely good.
            return Ok(true);
        }

        if sig.variadic || real_sig.variadic {
            // We're not touching this
            return Ok(false);
        }

        // We need to allow what comes up when a non-capturing closure is cast to a fn().
        match (sig.abi, real_sig.abi) {
            (Abi::Rust, Abi::RustCall) // check the ABIs.  This makes the test here non-symmetric.
                if check_ty_compat(sig.output(), real_sig.output())
                    && real_sig.inputs_and_output.len() == 3 => {
                // First argument of real_sig must be a ZST
                let fst_ty = real_sig.inputs_and_output[0];
                if self.layout_of(fst_ty)?.is_zst() {
                    // Second argument must be a tuple matching the argument list of sig
                    let snd_ty = real_sig.inputs_and_output[1];
                    match snd_ty.sty {
                        ty::Tuple(tys) if sig.inputs().len() == tys.len() =>
                            if sig.inputs()
                                .iter()
                                .zip(tys)
                                .all(|(ty, real_ty)| check_ty_compat(ty, real_ty)) {
                                return Ok(true)
                            },
                        _ => {}
                    }
                }
            }
            _ => {}
        };

        // Nope, this doesn't work.
        return Ok(false);
    }
/// Decides whether it is okay to call the method with signature `real_sig`
/// using signature `sig`.
/// FIXME: This should take into account the platform-dependent ABI description.
Decides whether it is okay to call the method with signature `real_sig`
using signature `sig`.
FIXME: This should take into account the platform-dependent ABI description.
Decides whether it is okay to call the method with signature ` real_sig ` using signature ` sig ` . FIXME : This should take into account the platform - dependent ABI description .
fn check_sig_compat(
        &mut self,
        sig: ty::FnSig<'tcx>,
        real_sig: ty::FnSig<'tcx>,
    ) -> EvalResult<'tcx, bool> {
        fn check_ty_compat<'tcx>(ty: Ty<'tcx>, real_ty: Ty<'tcx>) -> bool {
            if ty == real_ty {
                return true;
            } // This is actually a fast pointer comparison
            return match (&ty.sty, &real_ty.sty) {
                // Permit changing the pointer type of raw pointers and references as well as
                // mutability of raw pointers.
                // FIXME: Should not be allowed when fat pointers are involved.
                (&ty::RawPtr(_), &ty::RawPtr(_)) => true,
                (&ty::Ref(_, _, _), &ty::Ref(_, _, _)) => {
                    ty.is_mutable_pointer() == real_ty.is_mutable_pointer()
                }
                // rule out everything else
                _ => false,
            };
        }
        if sig.abi == real_sig.abi && sig.variadic == real_sig.variadic &&
            sig.inputs_and_output.len() == real_sig.inputs_and_output.len() &&
            sig.inputs_and_output
                .iter()
                .zip(real_sig.inputs_and_output)
                .all(|(ty, real_ty)| check_ty_compat(ty, real_ty))
        {
            // Definitely good.
            return Ok(true);
        }
        if sig.variadic || real_sig.variadic {
            // We're not touching this
            return Ok(false);
        }
        // We need to allow what comes up when a non-capturing closure is cast to a fn().
        match (sig.abi, real_sig.abi) {
            (Abi::Rust, Abi::RustCall) // check the ABIs.  This makes the test here non-symmetric.
                if check_ty_compat(sig.output(), real_sig.output())
                    && real_sig.inputs_and_output.len() == 3 => {
                // First argument of real_sig must be a ZST
                let fst_ty = real_sig.inputs_and_output[0];
                if self.layout_of(fst_ty)?.is_zst() {
                    // Second argument must be a tuple matching the argument list of sig
                    let snd_ty = real_sig.inputs_and_output[1];
                    match snd_ty.sty {
                        ty::Tuple(tys) if sig.inputs().len() == tys.len() =>
                            if sig.inputs()
                                .iter()
                                .zip(tys)
                                .all(|(ty, real_ty)| check_ty_compat(ty, real_ty)) {
                                return Ok(true)
                            },
                        _ => {}
                    }
                }
            }
            _ => {}
        };
        // Nope, this doesn't work.
        return Ok(false);
    }
fn check_sig_compat ( & mut self , sig : ty :: FnSig < ' tcx > , real_sig : ty :: FnSig < ' tcx > , ) -> EvalResult < ' tcx , bool > { fn check_ty_compat < ' tcx > ( ty : Ty < ' tcx > , real_ty : Ty < ' tcx > ) -> bool { if ty == real_ty { return true ; } // This is actually a fast pointer comparison return match ( & ty . sty , & real_ty . sty ) { // Permit changing the pointer type of raw pointers and references as well as // mutability of raw pointers. // FIXME: Should not be allowed when fat pointers are involved. ( & ty :: RawPtr ( _ ) , & ty :: RawPtr ( _ ) ) => true , ( & ty :: Ref ( _ , _ , _ ) , & ty :: Ref ( _ , _ , _ ) ) => { ty . is_mutable_pointer ( ) == real_ty . is_mutable_pointer ( ) } // rule out everything else _ => false , } ; } if sig . abi == real_sig . abi && sig . variadic == real_sig . variadic && sig . inputs_and_output . len ( ) == real_sig . inputs_and_output . len ( ) && sig . inputs_and_output . iter ( ) . zip ( real_sig . inputs_and_output ) . all ( | ( ty , real_ty ) | check_ty_compat ( ty , real_ty ) ) { // Definitely good. return Ok ( true ) ; } if sig . variadic || real_sig . variadic { // We're not touching this return Ok ( false ) ; } // We need to allow what comes up when a non-capturing closure is cast to a fn(). match ( sig . abi , real_sig . abi ) { ( Abi :: Rust , Abi :: RustCall ) // check the ABIs.  This makes the test here non-symmetric. if check_ty_compat ( sig . output ( ) , real_sig . output ( ) ) && real_sig . inputs_and_output . len ( ) == 3 => { // First argument of real_sig must be a ZST let fst_ty = real_sig . inputs_and_output [ 0 ] ; if self . layout_of ( fst_ty ) ? . is_zst ( ) { // Second argument must be a tuple matching the argument list of sig let snd_ty = real_sig . inputs_and_output [ 1 ] ; match snd_ty . sty { ty :: Tuple ( tys ) if sig . inputs ( ) . len ( ) == tys . len ( ) => if sig . inputs ( ) . iter ( ) . zip ( tys ) . all ( | ( ty , real_ty ) | check_ty_compat ( ty , real_ty ) ) { return Ok ( true ) } , _ => { } } } } _ => { } } ; // Nope, this doesn't work. return Ok ( false ) ; }
Decides whether it is okay to call the method with signature `real_sig`
using signature `sig`.
Decides whether it is okay to call the method with signature ` real_sig ` using signature ` sig ` .
&mut self
sig
ty::FnSig<'tcx>
real_sig
ty::FnSig<'tcx>