Skip to content

Commit ed56533

Browse files
committed
---
yaml --- r: 214725 b: refs/heads/beta c: 6665758 h: refs/heads/master i: 214723: fe6a514 v: v3
1 parent 583ed1b commit ed56533

File tree

5 files changed

+76
-16
lines changed

5 files changed

+76
-16
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: fbe8066ac39546073b4d76bcb9928cf83886e8b2
26+
refs/heads/beta: 666575861405712d302fe32cbe563ced8d98b8ad
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: 8c0aa6d64ebab528f7eb182812007155d6044972
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/librustc/middle/const_eval.rs

+35-13
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
126126
Some(ref_id) => {
127127
let trait_id = ty::trait_of_item(tcx, def_id)
128128
.unwrap();
129+
let substs = ty::node_id_item_substs(tcx, ref_id)
130+
.substs;
129131
resolve_trait_associated_const(tcx, ti, trait_id,
130-
ref_id)
132+
substs)
131133
}
132134
// Technically, without knowing anything about the
133135
// expression that generates the obligation, we could
@@ -172,8 +174,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
172174
// a trait-associated const if the caller gives us
173175
// the expression that refers to it.
174176
Some(ref_id) => {
177+
let substs = ty::node_id_item_substs(tcx, ref_id)
178+
.substs;
175179
resolve_trait_associated_const(tcx, ti, trait_id,
176-
ref_id).map(|e| e.id)
180+
substs).map(|e| e.id)
177181
}
178182
None => None
179183
}
@@ -633,9 +637,23 @@ pub_fn_checked_op!{ const_uint_checked_shr_via_int(a: u64, b: i64,.. UintTy) {
633637
uint_shift_body overflowing_shr const_uint ShiftRightWithOverflow
634638
}}
635639

640+
// After type checking, `eval_const_expr_partial` should always suffice. The
641+
// reason for providing `eval_const_expr_with_substs` is to allow
642+
// trait-associated consts to be evaluated *during* type checking, when the
643+
// substs for each expression have not been written into `tcx` yet.
636644
pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
637645
e: &Expr,
638646
ty_hint: Option<Ty<'tcx>>) -> EvalResult {
647+
eval_const_expr_with_substs(tcx, e, ty_hint, |id| {
648+
ty::node_id_item_substs(tcx, id).substs
649+
})
650+
}
651+
652+
pub fn eval_const_expr_with_substs<'tcx, S>(tcx: &ty::ctxt<'tcx>,
653+
e: &Expr,
654+
ty_hint: Option<Ty<'tcx>>,
655+
get_substs: S) -> EvalResult
656+
where S: Fn(ast::NodeId) -> subst::Substs<'tcx> {
639657
fn fromb(b: bool) -> const_val { const_int(b as i64) }
640658

641659
let ety = ty_hint.or_else(|| ty::expr_ty_opt(tcx, e));
@@ -826,8 +844,11 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
826844
def::FromTrait(trait_id) => match tcx.map.find(def_id.node) {
827845
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
828846
ast::ConstTraitItem(ref ty, _) => {
829-
(resolve_trait_associated_const(tcx, ti,
830-
trait_id, e.id),
847+
let substs = get_substs(e.id);
848+
(resolve_trait_associated_const(tcx,
849+
ti,
850+
trait_id,
851+
substs),
831852
Some(&**ty))
832853
}
833854
_ => (None, None)
@@ -926,10 +947,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
926947
fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
927948
ti: &'tcx ast::TraitItem,
928949
trait_id: ast::DefId,
929-
ref_id: ast::NodeId)
950+
rcvr_substs: subst::Substs<'tcx>)
930951
-> Option<&'tcx Expr>
931952
{
932-
let rcvr_substs = ty::node_id_item_substs(tcx, ref_id).substs;
933953
let subst::SeparateVecsPerParamSpace {
934954
types: rcvr_type,
935955
selfs: rcvr_self,
@@ -1081,19 +1101,21 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<Ordering> {
10811101
})
10821102
}
10831103

1084-
pub fn compare_lit_exprs<'tcx>(tcx: &ty::ctxt<'tcx>,
1085-
a: &Expr,
1086-
b: &Expr,
1087-
ty_hint: Option<Ty<'tcx>>)
1088-
-> Option<Ordering> {
1089-
let a = match eval_const_expr_partial(tcx, a, ty_hint) {
1104+
pub fn compare_lit_exprs<'tcx, S>(tcx: &ty::ctxt<'tcx>,
1105+
a: &Expr,
1106+
b: &Expr,
1107+
ty_hint: Option<Ty<'tcx>>,
1108+
get_substs: S) -> Option<Ordering>
1109+
where S: Fn(ast::NodeId) -> subst::Substs<'tcx> {
1110+
let a = match eval_const_expr_with_substs(tcx, a, ty_hint,
1111+
|id| {get_substs(id)}) {
10901112
Ok(a) => a,
10911113
Err(e) => {
10921114
tcx.sess.span_err(a.span, &e.description());
10931115
return None;
10941116
}
10951117
};
1096-
let b = match eval_const_expr_partial(tcx, b, ty_hint) {
1118+
let b = match eval_const_expr_with_substs(tcx, b, ty_hint, get_substs) {
10971119
Ok(b) => b,
10981120
Err(e) => {
10991121
tcx.sess.span_err(b.span, &e.description());

branches/beta/src/librustc_trans/trans/_match.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ struct ConstantExpr<'a>(&'a ast::Expr);
233233

234234
impl<'a> ConstantExpr<'a> {
235235
fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool {
236-
match const_eval::compare_lit_exprs(tcx, self.0, other.0, None) {
236+
match const_eval::compare_lit_exprs(tcx, self.0, other.0, None,
237+
|id| {ty::node_id_item_substs(tcx, id).substs}) {
237238
Some(result) => result == Ordering::Equal,
238239
None => panic!("compare_list_exprs: type mismatch"),
239240
}

branches/beta/src/librustc_typeck/check/_match.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
9898
lhs_eq_rhs && (ty::type_is_numeric(lhs_ty) || ty::type_is_char(lhs_ty));
9999

100100
if numeric_or_char {
101-
match const_eval::compare_lit_exprs(tcx, &**begin, &**end, Some(lhs_ty)) {
101+
match const_eval::compare_lit_exprs(tcx, &**begin, &**end, Some(lhs_ty),
102+
|id| {fcx.item_substs()[&id].substs
103+
.clone()}) {
102104
Some(Ordering::Less) |
103105
Some(Ordering::Equal) => {}
104106
Some(Ordering::Greater) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2015 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(associated_consts)]
12+
13+
struct Foo;
14+
15+
trait HasNum {
16+
const NUM: isize;
17+
}
18+
impl HasNum for Foo {
19+
const NUM: isize = 1;
20+
}
21+
22+
fn main() {
23+
assert!(match 2 {
24+
Foo::NUM ... 3 => true,
25+
_ => false,
26+
});
27+
assert!(match 0 {
28+
-1 ... <Foo as HasNum>::NUM => true,
29+
_ => false,
30+
});
31+
assert!(match 1 {
32+
<Foo as HasNum>::NUM ... <Foo>::NUM => true,
33+
_ => false,
34+
});
35+
}

0 commit comments

Comments
 (0)