rollup merge of #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 https://github.com/rust-lang/rust/issues/19244 Related https://github.com/rust-lang/rust/issues/19265
This commit is contained in:
commit
51d146a56a
4 changed files with 86 additions and 0 deletions
|
@ -567,6 +567,34 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
|
|||
None => Ok(const_int(0i64))
|
||||
}
|
||||
}
|
||||
ast::ExprTupField(ref base, index) => {
|
||||
// Get the base tuple if it is constant
|
||||
if let Some(&ast::ExprTup(ref fields)) = lookup_const(tcx, &**base).map(|s| &s.node) {
|
||||
// Check that the given index is within bounds and evaluate its value
|
||||
if fields.len() > index.node {
|
||||
return eval_const_expr_partial(tcx, &*fields[index.node])
|
||||
} else {
|
||||
return Err("tuple index out of bounds".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
Err("non-constant struct in constant expr".to_string())
|
||||
}
|
||||
ast::ExprField(ref base, field_name) => {
|
||||
// Get the base expression if it is a struct and it is constant
|
||||
if let Some(&ast::ExprStruct(_, ref fields, _)) = lookup_const(tcx, &**base)
|
||||
.map(|s| &s.node) {
|
||||
// Check that the given field exists and evaluate it
|
||||
if let Some(f) = fields.iter().find(|f|
|
||||
f.ident.node.as_str() == field_name.node.as_str()) {
|
||||
return eval_const_expr_partial(tcx, &*f.expr)
|
||||
} else {
|
||||
return Err("nonexistent struct field".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
Err("non-constant struct in constant expr".to_string())
|
||||
}
|
||||
_ => Err("unsupported constant expr".to_string())
|
||||
}
|
||||
}
|
||||
|
|
18
src/test/compile-fail/issue-19244-1.rs
Normal file
18
src/test/compile-fail/issue-19244-1.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
#![feature(tuple_indexing)]
|
||||
|
||||
const TUP: (uint,) = (42,);
|
||||
|
||||
fn main() {
|
||||
let a: [int, ..TUP.1];
|
||||
//~^ ERROR expected constant expr for array length: tuple index out of bounds
|
||||
}
|
17
src/test/compile-fail/issue-19244-2.rs
Normal file
17
src/test/compile-fail/issue-19244-2.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
struct MyStruct { field: uint }
|
||||
const STRUCT: MyStruct = MyStruct { field: 42 };
|
||||
|
||||
fn main() {
|
||||
let a: [int, ..STRUCT.nonexistent_field];
|
||||
//~^ ERROR expected constant expr for array length: nonexistent struct field
|
||||
}
|
23
src/test/run-pass/issue-19244.rs
Normal file
23
src/test/run-pass/issue-19244.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
#![feature(tuple_indexing)]
|
||||
|
||||
struct MyStruct { field: uint }
|
||||
const STRUCT: MyStruct = MyStruct { field: 42 };
|
||||
const TUP: (uint,) = (43,);
|
||||
|
||||
fn main() {
|
||||
let a = [0i, ..STRUCT.field];
|
||||
let b = [0i, ..TUP.0];
|
||||
|
||||
assert!(a.len() == 42);
|
||||
assert!(b.len() == 43);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue