diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index cefd8d48b8a..34567c1178f 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -149,6 +149,21 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, }, } } + + // If we see a const here, that's because it evaluates to a type with zero size. We + // should be able to just discard it, since const expressions are guaranteed not to + // have side effects. This seems to be reached through tuple struct constructors being + // passed zero-size constants. + if let hir::ExprPath(..) = expr.node { + match bcx.def(expr.id) { + Def::Const(_) | Def::AssociatedConst(_) => { + assert!(type_is_zero_size(bcx.ccx(), bcx.tcx().node_id_to_type(expr.id))); + return bcx; + } + _ => {} + } + } + // Even if we don't have a value to emit, and the expression // doesn't have any side-effects, we still have to translate the // body of any closures. @@ -160,7 +175,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, match expr.node { hir::ExprPath(..) => { match bcx.def(expr.id) { - Def::Const(did) => { + Def::Const(did) | Def::AssociatedConst(did) => { let empty_substs = bcx.tcx().mk_substs(Substs::trans_empty()); let const_expr = consts::get_const_expr(bcx.ccx(), did, expr, empty_substs); @@ -896,7 +911,7 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let lval = Lvalue::new("expr::trans_def"); DatumBlock::new(bcx, Datum::new(val, const_ty, LvalueExpr(lval))) } - Def::Const(_) => { + Def::Const(_) | Def::AssociatedConst(_) => { bcx.sess().span_bug(ref_expr.span, "constant expression should not reach expr::trans_def") } diff --git a/src/test/run-pass/issue-31267-additional.rs b/src/test/run-pass/issue-31267-additional.rs new file mode 100644 index 00000000000..a6b42525887 --- /dev/null +++ b/src/test/run-pass/issue-31267-additional.rs @@ -0,0 +1,30 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(associated_consts)] + +#[derive(Clone, Copy, Debug)] +struct Bar; + +const BAZ: Bar = Bar; + +#[derive(Debug)] +struct Foo([Bar; 1]); + +struct Biz; + +impl Biz { + const BAZ: Foo = Foo([BAZ; 1]); +} + +fn main() { + let foo = Biz::BAZ; + println!("{:?}", foo); +} diff --git a/src/test/run-pass/issue-31267.rs b/src/test/run-pass/issue-31267.rs new file mode 100644 index 00000000000..90eb0f6c841 --- /dev/null +++ b/src/test/run-pass/issue-31267.rs @@ -0,0 +1,24 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for issue #31267 + +#![feature(associated_consts)] + +struct Foo; + +impl Foo { + const FOO: [i32; 3] = [0; 3]; +} + +pub fn main() { + let foo = Foo::FOO; + assert_eq!(foo, [0i32, 0, 0]); +}