Skip to content

Commit

Permalink
Fix vector indexing in consts so it works with the enum vector const …
Browse files Browse the repository at this point in the history
…fix.
  • Loading branch information
jld committed Feb 8, 2013
1 parent de8dc02 commit e89d985
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ pub extern mod llvm {
pub unsafe fn LLVMGetUsedValue(U: UseRef) -> ValueRef;

/* Operations on Users */
pub unsafe fn LLVMGetNumOperands(Val: ValueRef) -> c_int;
pub unsafe fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
pub unsafe fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);

Expand Down
22 changes: 12 additions & 10 deletions src/librustc/middle/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,17 @@ pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
// call. Despite that being "a const", it's not the kind of
// const you can ask for the integer-value of, evidently. This
// might be an LLVM bug, not sure. In any case, to work around
// this we drop down to the array-type level here and just ask
// how long the array-type itself is, ignoring the length we
// pulled out of the slice. This in turn only works because we
// picked out the original globalvar via const_deref and so can
// recover the array-size of the underlying array, and all this
// will hold together exactly as long as we _don't_ support
// const sub-slices (that is, slices that represent something
// other than a whole array). At that point we'll have more and
// uglier work to do here, but for now this should work.
// this we obtain the initializer and count how many elements it
// has, ignoring the length we pulled out of the slice. (Note
// that the initializer might be a struct rather than an array,
// if enums are involved.) This only works because we picked out
// the original globalvar via const_deref and so can recover the
// array-size of the underlying array (or the element count of
// the underlying struct), and all this will hold together
// exactly as long as we _don't_ support const sub-slices (that
// is, slices that represent something other than a whole
// array). At that point we'll have more and uglier work to do
// here, but for now this should work.
//
// In the future, what we should be doing here is the
// moral equivalent of:
Expand All @@ -305,7 +307,7 @@ pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
// not want to consider sizeof() a constant expression
// we can get the value (as a number) out of.

let len = llvm::LLVMGetArrayLength(val_ty(arr)) as u64;
let len = llvm::LLVMGetNumOperands(arr) as u64;
let len = match ty::get(bt).sty {
ty::ty_estr(*) => {assert len > 0; len - 1},
_ => len
Expand Down
25 changes: 25 additions & 0 deletions src/test/run-pass/const-enum-vec-index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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 E { V1(int), V0 }
const C: &[E] = &[V0, V1(0xDEADBEE)];
const C0: E = C[0];
const C1: E = C[1];

fn main() {
match C0 {
V0 => (),
_ => die!()
}
match C1 {
V1(n) => assert(n == 0xDEADBEE),
_ => die!()
}
}

1 comment on commit e89d985

@graydon
Copy link

@graydon graydon commented on e89d985 Feb 8, 2013

Choose a reason for hiding this comment

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

r+ p=45

Please sign in to comment.