auto merge of #8091 : kevinmehall/rust/const-struct-base, r=alexcrichton
With an expression like static w : foo = foo { a:5, ..x }; Rust currently gives the error "constant contains unimplemented expression type". This branch implements support for constant structs with `..base`.
This commit is contained in:
commit
27812ea5e0
@ -160,7 +160,7 @@ pub fn check_expr(sess: Session,
|
||||
expr_field(*) |
|
||||
expr_index(*) |
|
||||
expr_tup(*) |
|
||||
expr_struct(_, _, None) => { }
|
||||
expr_struct(*) => { }
|
||||
expr_addr_of(*) => {
|
||||
sess.span_err(
|
||||
e.span,
|
||||
|
@ -485,20 +485,30 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
|
||||
let vals = es.map(|&e| const_expr(cx, e));
|
||||
adt::trans_const(cx, repr, 0, vals)
|
||||
}
|
||||
ast::expr_struct(_, ref fs, None) => {
|
||||
ast::expr_struct(_, ref fs, ref base_opt) => {
|
||||
let ety = ty::expr_ty(cx.tcx, e);
|
||||
let repr = adt::represent_type(cx, ety);
|
||||
let tcx = cx.tcx;
|
||||
|
||||
let base_val = match *base_opt {
|
||||
Some(base) => Some(const_expr(cx, base)),
|
||||
None => None
|
||||
};
|
||||
|
||||
do expr::with_field_tys(tcx, ety, Some(e.id))
|
||||
|discr, field_tys| {
|
||||
let cs = field_tys.map(|field_ty| {
|
||||
let cs: ~[ValueRef] = field_tys.iter().enumerate()
|
||||
.transform(|(ix, &field_ty)| {
|
||||
match fs.iter().find_(|f| field_ty.ident == f.ident) {
|
||||
Some(f) => const_expr(cx, (*f).expr),
|
||||
None => {
|
||||
cx.tcx.sess.span_bug(e.span, "missing struct field");
|
||||
match base_val {
|
||||
Some(bv) => adt::const_get_field(cx, repr, bv, discr, ix),
|
||||
None => cx.tcx.sess.span_bug(e.span, "missing struct field")
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}).collect();
|
||||
adt::trans_const(cx, repr, discr, cs)
|
||||
}
|
||||
}
|
||||
|
@ -498,7 +498,7 @@ pub enum expr_ {
|
||||
expr_mac(mac),
|
||||
|
||||
// A struct literal expression.
|
||||
expr_struct(Path, ~[Field], Option<@expr>),
|
||||
expr_struct(Path, ~[Field], Option<@expr> /* base */),
|
||||
|
||||
// A vector literal constructed from one repeated element.
|
||||
expr_repeat(@expr /* element */, @expr /* count */, mutability),
|
||||
|
22
src/test/compile-fail/struct-base-wrong-type.rs
Normal file
22
src/test/compile-fail/struct-base-wrong-type.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// 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.
|
||||
|
||||
struct Foo { a: int, b: int }
|
||||
struct Bar { x: int }
|
||||
|
||||
static bar: Bar = Bar { x: 5 };
|
||||
static foo: Foo = Foo { a: 2, ..bar }; //~ ERROR mismatched types: expected `Foo` but found `Bar`
|
||||
static foo_i: Foo = Foo { a: 2, ..4 }; //~ ERROR mismatched types: expected `Foo`
|
||||
|
||||
fn main() {
|
||||
let b = Bar { x: 5 };
|
||||
let f = Foo { a: 2, ..b }; //~ ERROR mismatched types: expected `Foo` but found `Bar`
|
||||
let f_i = Foo { a: 2, ..4 }; //~ ERROR mismatched types: expected `Foo`
|
||||
}
|
@ -25,11 +25,14 @@ impl cmp::Eq for foo {
|
||||
static x : foo = foo { a:1, b:2, c: 3 };
|
||||
static y : foo = foo { b:2, c:3, a: 1 };
|
||||
static z : &'static foo = &foo { a: 10, b: 22, c: 12 };
|
||||
static w : foo = foo { a:5, ..x };
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(x.b, 2);
|
||||
assert_eq!(x, y);
|
||||
assert_eq!(z.b, 22);
|
||||
assert_eq!(w.a, 5);
|
||||
assert_eq!(w.c, 3);
|
||||
printfln!("0x%x", x.b as uint);
|
||||
printfln!("0x%x", z.c as uint);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user