typeck: Introduce reification for fn ptr casts.

This commit is contained in:
Eduard Burtescu 2016-02-18 15:18:46 +02:00
parent 8f07f8a4fa
commit 847f00738b
2 changed files with 15 additions and 3 deletions

View File

@ -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,
}
}

View File

@ -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)
}