From 847f00738b93575aa19e1707c5d0216e0e36447e Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 18 Feb 2016 15:18:46 +0200 Subject: [PATCH] typeck: Introduce reification for fn ptr casts. --- src/librustc/middle/ty/cast.rs | 4 +--- src/librustc_typeck/check/cast.rs | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/ty/cast.rs b/src/librustc/middle/ty/cast.rs index ac308f564340..b25d6e0476d9 100644 --- a/src/librustc/middle/ty/cast.rs +++ b/src/librustc/middle/ty/cast.rs @@ -69,9 +69,7 @@ impl<'tcx> CastTy<'tcx> { Some(CastTy::Int(IntTy::CEnum)), ty::TyRawPtr(ref mt) => Some(CastTy::Ptr(mt)), ty::TyRef(_, ref mt) => Some(CastTy::RPtr(mt)), - // FIXME: Treating TyFnDef as a pointer here is a bit dubious; - // we should be coercing the operand to an actual pointer. - ty::TyFnDef(..) | ty::TyFnPtr(..) => Some(CastTy::FnPtr), + ty::TyFnPtr(..) => Some(CastTy::FnPtr), _ => None, } } diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 2ea0df280db2..7168873c1b8a 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -235,6 +235,20 @@ impl<'tcx> CastCheck<'tcx> { let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty)) { (Some(t_from), Some(t_cast)) => (t_from, t_cast), + // Function item types may need to be reified before casts. + (None, Some(t_cast)) => { + if let ty::TyFnDef(_, _, f) = self.expr_ty.sty { + // Attempt a coercion to a fn pointer type. + let res = coercion::mk_assignty(fcx, &self.expr, + self.expr_ty, fcx.tcx().mk_ty(ty::TyFnPtr(f))); + if !res.is_ok() { + return Err(CastError::NonScalar); + } + (FnPtr, t_cast) + } else { + return Err(CastError::NonScalar); + } + } _ => { return Err(CastError::NonScalar) }