Skip to content

Commit c484c2d

Browse files
Jakub Wieczorekalexcrichton
Jakub Wieczorek
authored andcommitted
Fix #15129
Add support for unit literals to const_eval.
1 parent 85effb9 commit c484c2d

File tree

7 files changed

+89
-11
lines changed

7 files changed

+89
-11
lines changed

src/librustc/middle/check_match.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#![allow(non_camel_case_types)]
1212

13-
use middle::const_eval::{compare_const_vals, const_bool, const_float, const_val};
13+
use middle::const_eval::{compare_const_vals, const_bool, const_float, const_nil, const_val};
1414
use middle::const_eval::{eval_const_expr, lookup_const_by_id};
1515
use middle::def::*;
1616
use middle::pat_util::*;
@@ -203,6 +203,7 @@ enum ctor {
203203
fn const_val_to_expr(value: &const_val) -> Gc<Expr> {
204204
let node = match value {
205205
&const_bool(b) => LitBool(b),
206+
&const_nil => LitNil,
206207
_ => unreachable!()
207208
};
208209
box(GC) Expr {
@@ -309,6 +310,9 @@ fn all_constructors(cx: &MatchCheckCtxt, m: &Matrix, left_ty: ty::t) -> Vec<ctor
309310
ty::ty_bool =>
310311
[true, false].iter().map(|b| val(const_bool(*b))).collect(),
311312

313+
ty::ty_nil =>
314+
vec!(val(const_nil)),
315+
312316
ty::ty_rptr(_, ty::mt { ty: ty, .. }) => match ty::get(ty).sty {
313317
ty::ty_vec(_, None) => vec_constructors(m),
314318
_ => vec!(single)
@@ -326,9 +330,6 @@ fn all_constructors(cx: &MatchCheckCtxt, m: &Matrix, left_ty: ty::t) -> Vec<ctor
326330
ty::ty_vec(_, Some(n)) =>
327331
vec!(vec(n)),
328332

329-
ty::ty_nil if !m.iter().all(|r| is_wild(cx, *r.get(0))) =>
330-
vec!(),
331-
332333
_ =>
333334
vec!(single)
334335
}

src/librustc/middle/const_eval.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ pub enum const_val {
299299
const_uint(u64),
300300
const_str(InternedString),
301301
const_binary(Rc<Vec<u8> >),
302-
const_bool(bool)
302+
const_bool(bool),
303+
const_nil
303304
}
304305

305306
pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val {
@@ -514,7 +515,7 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
514515
LitFloat(ref n, _) | LitFloatUnsuffixed(ref n) => {
515516
const_float(from_str::<f64>(n.get()).unwrap() as f64)
516517
}
517-
LitNil => const_int(0i64),
518+
LitNil => const_nil,
518519
LitBool(b) => const_bool(b)
519520
}
520521
}
@@ -530,6 +531,7 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<int> {
530531
(&const_str(ref a), &const_str(ref b)) => compare_vals(a, b),
531532
(&const_bool(a), &const_bool(b)) => compare_vals(a, b),
532533
(&const_binary(ref a), &const_binary(ref b)) => compare_vals(a, b),
534+
(&const_nil, &const_nil) => compare_vals((), ()),
533535
_ => None
534536
}
535537
}

src/librustc/middle/ty.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4184,6 +4184,12 @@ pub fn eval_repeat_count<T: ExprTyProvider>(tcx: &T, count_expr: &ast::Expr) ->
41844184
repeat count but found binary array");
41854185
return 0;
41864186
}
4187+
const_eval::const_nil => {
4188+
tcx.ty_ctxt().sess.span_err(count_expr.span,
4189+
"expected positive integer for \
4190+
repeat count but found ()");
4191+
return 0;
4192+
}
41874193
},
41884194
Err(..) => {
41894195
tcx.ty_ctxt().sess.span_err(count_expr.span,

src/test/compile-fail/issue-15129.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
pub enum T {
12+
T1(()),
13+
T2(())
14+
}
15+
16+
pub enum V {
17+
V1(int),
18+
V2(bool)
19+
}
20+
21+
fn main() {
22+
match (T1(()), V2(true)) {
23+
//~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered
24+
(T1(()), V1(i)) => (),
25+
(T2(()), V2(b)) => ()
26+
}
27+
}

src/test/compile-fail/non-exhaustive-pattern-witness.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,11 @@ fn vectors_with_nested_enums() {
6767
}
6868
}
6969

70-
fn main() {
71-
struct_with_a_nested_enum_and_vector();
72-
enum_with_multiple_missing_variants();
73-
enum_struct_variant();
70+
fn missing_nil() {
71+
match ((), false) {
72+
//~^ ERROR non-exhaustive patterns: `((), false)` not covered
73+
((), true) => ()
74+
}
7475
}
76+
77+
fn main() {}

src/test/compile-fail/repeat_count.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -13,4 +13,10 @@
1313
fn main() {
1414
let n = 1;
1515
let a = [0, ..n]; //~ ERROR expected constant integer for repeat count but found variable
16+
let b = [0, ..()]; //~ ERROR expected positive integer for repeat count but found ()
17+
let c = [0, ..true]; //~ ERROR expected positive integer for repeat count but found boolean
18+
let d = [0, ..0.5]; //~ ERROR expected positive integer for repeat count but found float
19+
let e = [0, .."foo"]; //~ ERROR expected positive integer for repeat count but found string
20+
let f = [0, ..-4];
21+
//~^ ERROR expected positive integer for repeat count but found negative integer
1622
}

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
pub enum T {
12+
T1(()),
13+
T2(())
14+
}
15+
16+
pub enum V {
17+
V1(int),
18+
V2(bool)
19+
}
20+
21+
fn foo(x: (T, V)) -> String {
22+
match x {
23+
(T1(()), V1(i)) => format!("T1(()), V1({})", i),
24+
(T2(()), V2(b)) => format!("T2(()), V2({})", b),
25+
_ => String::new()
26+
}
27+
}
28+
29+
30+
fn main() {
31+
assert_eq!(foo((T1(()), V1(99))), "T1(()), V1(99)".to_string());
32+
assert_eq!(foo((T2(()), V2(true))), "T2(()), V2(true)".to_string());
33+
}

0 commit comments

Comments
 (0)