auto merge of #14874 : pcwalton/rust/enum-to-float-casts-part-deux, r=alexcrichton
Closes #14794. If you're casting from an enum to a float, cast through an integer first. [breaking-change] r? @alexcrichton
This commit is contained in:
commit
dbd29ea96e
7 changed files with 32 additions and 18 deletions
|
|
@ -503,9 +503,8 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
let s = ty::type_is_signed(ety) as Bool;
|
||||
llvm::LLVMConstIntCast(iv, llty.to_ref(), s)
|
||||
}
|
||||
expr::cast_float => llvm::LLVMConstSIToFP(iv, llty.to_ref()),
|
||||
_ => cx.sess().bug("enum cast destination is not \
|
||||
integral or float")
|
||||
integral")
|
||||
}
|
||||
}
|
||||
(expr::cast_pointer, expr::cast_pointer) => {
|
||||
|
|
|
|||
|
|
@ -1685,6 +1685,14 @@ pub fn type_is_scalar(ty: t) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if this type is a floating point type and false otherwise.
|
||||
pub fn type_is_floating_point(ty: t) -> bool {
|
||||
match get(ty).sty {
|
||||
ty_float(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_needs_drop(cx: &ctxt, ty: t) -> bool {
|
||||
type_contents(cx, ty).needs_drop(cx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3042,12 +3042,24 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
let t_1_is_scalar = type_is_scalar(fcx, expr.span, t_1);
|
||||
let t_1_is_char = type_is_char(fcx, expr.span, t_1);
|
||||
let t_1_is_bare_fn = type_is_bare_fn(fcx, expr.span, t_1);
|
||||
let t_1_is_float = type_is_floating_point(fcx,
|
||||
expr.span,
|
||||
t_1);
|
||||
|
||||
// casts to scalars other than `char` and `bare fn` are trivial
|
||||
let t_1_is_trivial = t_1_is_scalar &&
|
||||
!t_1_is_char && !t_1_is_bare_fn;
|
||||
|
||||
if type_is_c_like_enum(fcx, expr.span, t_e) && t_1_is_trivial {
|
||||
if type_is_c_like_enum(fcx, expr.span, t_e) &&
|
||||
t_1_is_trivial {
|
||||
if t_1_is_float {
|
||||
fcx.type_error_message(expr.span, |actual| {
|
||||
format!("illegal cast; cast through an \
|
||||
integer first: `{}` as `{}`",
|
||||
actual,
|
||||
fcx.infcx().ty_to_str(t_1))
|
||||
}, t_e, None);
|
||||
}
|
||||
// casts from C-like enums are allowed
|
||||
} else if t_1_is_char {
|
||||
let te = fcx.infcx().resolve_type_vars_if_possible(te);
|
||||
|
|
@ -4206,6 +4218,11 @@ pub fn type_is_bare_fn(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
|||
return ty::type_is_bare_fn(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_floating_point(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_floating_point(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_unsafe_ptr(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_unsafe_ptr(typ_s);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue