Skip to content

Commit

Permalink
Allow constant c-like enum to integral/float cast
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowone committed Mar 2, 2013
1 parent b7e7297 commit 7921810
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
35 changes: 33 additions & 2 deletions src/librustc/middle/trans/consts.rs
Expand Up @@ -10,7 +10,7 @@

use core::prelude::*;

use lib::llvm::{llvm, ValueRef, True, TypeRef, False};
use lib::llvm::{llvm, ValueRef, TypeRef, Bool, True, False};
use middle::const_eval;
use middle::trans::base;
use middle::trans::base::get_insn_ctxt;
Expand Down Expand Up @@ -304,7 +304,7 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
expr::cast_type_kind(ety)) {

(expr::cast_integral, expr::cast_integral) => {
let s = if ty::type_is_signed(basety) { True } else { False };
let s = ty::type_is_signed(basety) as Bool;
llvm::LLVMConstIntCast(v, llty, s)
}
(expr::cast_integral, expr::cast_float) => {
Expand All @@ -321,6 +321,37 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) }
else { llvm::LLVMConstFPToUI(v, llty) }
}
(expr::cast_enum, expr::cast_integral) |
(expr::cast_enum, expr::cast_float) => {
let def = ty::resolve_expr(cx.tcx, base);
let (enum_did, variant_did) = match def {
ast::def_variant(enum_did, variant_did) => {
(enum_did, variant_did)
}
_ => cx.sess.bug(~"enum cast source is not enum")
};
// Note that we know this is a C-like (nullary) enum
// variant or we wouldn't have gotten here
let variants = ty::enum_variants(cx.tcx, enum_did);
let iv = if variants.len() == 1 {
// Univariants don't have a discriminant field,
// because there's only one value it could have:
C_integral(T_i64(),
variants[0].disr_val as u64, True)
} else {
base::get_discrim_val(cx, e.span, enum_did, variant_did)
};
let ety_cast = expr::cast_type_kind(ety);
match ety_cast {
expr::cast_integral => {
let s = ty::type_is_signed(ety) as Bool;
llvm::LLVMConstIntCast(iv, llty, s)
}
expr::cast_float => llvm::LLVMConstUIToFP(iv, llty),
_ => cx.sess.bug(~"enum cast destination is not \
integral or float")
}
}
_ => {
cx.sess.impossible_case(e.span,
~"bad combination of types for cast")
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty.rs
Expand Up @@ -3017,7 +3017,7 @@ pub fn method_call_bounds(tcx: ctxt, method_map: typeck::method_map,
}
}

fn resolve_expr(tcx: ctxt, expr: @ast::expr) -> ast::def {
pub fn resolve_expr(tcx: ctxt, expr: @ast::expr) -> ast::def {
match tcx.def_map.find(&expr.id) {
Some(def) => def,
None => {
Expand Down
31 changes: 31 additions & 0 deletions src/test/run-pass/enum-cast.rs
@@ -0,0 +1,31 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

enum A { A1, A2 }
enum B { B1=0, B2=2 }

fn main () {
const c1: int = A2 as int;
const c2: int = B2 as int;
const c3: float = A2 as float;
const c4: float = B2 as float;
let a1 = A2 as int;
let a2 = B2 as int;
let a3 = A2 as float;
let a4 = B2 as float;
assert(c1 == 1);
assert(c2 == 2);
assert(c3 == 1.0);
assert(c4 == 2.0);
assert(a1 == 1);
assert(a2 == 2);
assert(a3 == 1.0);
assert(a4 == 2.0);
}

5 comments on commit 7921810

@bors
Copy link
Contributor

@bors bors commented on 7921810 Mar 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from brson
at youknowone@7921810

@bors
Copy link
Contributor

@bors bors commented on 7921810 Mar 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging youknowone/rust/enum-cast = 7921810 into auto

@bors
Copy link
Contributor

@bors bors commented on 7921810 Mar 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

youknowone/rust/enum-cast = 7921810 merged ok, testing candidate = 95c0747

@bors
Copy link
Contributor

@bors bors commented on 7921810 Mar 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 7921810 Mar 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding incoming to auto = 95c0747

Please sign in to comment.