Skip to content

Commit 51d146a

Browse files
committed
rollup merge of rust-lang#19266: aochagavia/const
With this PR, the following code works: ``` #![feature(tuple_indexing)] struct MyStruct { field1: uint } const S: MyStruct = MyStruct { field1: 42u }; const T: (uint,) = (42u,); struct ConstCheck { array1: [int, ..S.field1], array2: [int, ..T.0], } ``` Closes rust-lang#19244 Related rust-lang#19265
2 parents 74f0ceb + 080e625 commit 51d146a

File tree

4 files changed

+86
-0
lines changed

4 files changed

+86
-0
lines changed

src/librustc/middle/const_eval.rs

+28
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,34 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
567567
None => Ok(const_int(0i64))
568568
}
569569
}
570+
ast::ExprTupField(ref base, index) => {
571+
// Get the base tuple if it is constant
572+
if let Some(&ast::ExprTup(ref fields)) = lookup_const(tcx, &**base).map(|s| &s.node) {
573+
// Check that the given index is within bounds and evaluate its value
574+
if fields.len() > index.node {
575+
return eval_const_expr_partial(tcx, &*fields[index.node])
576+
} else {
577+
return Err("tuple index out of bounds".to_string())
578+
}
579+
}
580+
581+
Err("non-constant struct in constant expr".to_string())
582+
}
583+
ast::ExprField(ref base, field_name) => {
584+
// Get the base expression if it is a struct and it is constant
585+
if let Some(&ast::ExprStruct(_, ref fields, _)) = lookup_const(tcx, &**base)
586+
.map(|s| &s.node) {
587+
// Check that the given field exists and evaluate it
588+
if let Some(f) = fields.iter().find(|f|
589+
f.ident.node.as_str() == field_name.node.as_str()) {
590+
return eval_const_expr_partial(tcx, &*f.expr)
591+
} else {
592+
return Err("nonexistent struct field".to_string())
593+
}
594+
}
595+
596+
Err("non-constant struct in constant expr".to_string())
597+
}
570598
_ => Err("unsupported constant expr".to_string())
571599
}
572600
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(tuple_indexing)]
12+
13+
const TUP: (uint,) = (42,);
14+
15+
fn main() {
16+
let a: [int, ..TUP.1];
17+
//~^ ERROR expected constant expr for array length: tuple index out of bounds
18+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct MyStruct { field: uint }
12+
const STRUCT: MyStruct = MyStruct { field: 42 };
13+
14+
fn main() {
15+
let a: [int, ..STRUCT.nonexistent_field];
16+
//~^ ERROR expected constant expr for array length: nonexistent struct field
17+
}

src/test/run-pass/issue-19244.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(tuple_indexing)]
12+
13+
struct MyStruct { field: uint }
14+
const STRUCT: MyStruct = MyStruct { field: 42 };
15+
const TUP: (uint,) = (43,);
16+
17+
fn main() {
18+
let a = [0i, ..STRUCT.field];
19+
let b = [0i, ..TUP.0];
20+
21+
assert!(a.len() == 42);
22+
assert!(b.len() == 43);
23+
}

0 commit comments

Comments
 (0)