Skip to content

Commit 8a9b78f

Browse files
committed
rustc: use ty::Const for the length of TyArray.
1 parent 3ce31eb commit 8a9b78f

File tree

34 files changed

+215
-60
lines changed

34 files changed

+215
-60
lines changed

src/librustc/middle/const_val.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,18 +247,23 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
247247
}
248248

249249
/// Returns the value of the length-valued expression
250-
pub fn eval_length(tcx: TyCtxt,
251-
count: hir::BodyId,
252-
reason: &str)
253-
-> Result<ConstUsize, ErrorReported>
250+
pub fn eval_length<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
251+
count: hir::BodyId,
252+
reason: &str)
253+
-> Result<&'gcx ty::Const<'gcx>, ErrorReported>
254254
{
255255
let count_expr = &tcx.hir.body(count).value;
256256
let count_def_id = tcx.hir.body_owner_def_id(count);
257257
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
258258
let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
259259
match tcx.at(count_expr.span).const_eval(param_env.and((count_def_id, substs))) {
260-
Ok(&ty::Const { val: Integral(Usize(count)), .. }) => Ok(count),
261-
Ok(_) | Err(ConstEvalErr { kind: ErrKind::TypeckError, .. }) => Err(ErrorReported),
260+
Ok(count) => {
261+
// Elsewhere in the compiler this is enforced even in the presence
262+
// of erroneous code (type mismatch error has already been emitted).
263+
assert_eq!(count.ty, tcx.types.usize);
264+
Ok(count)
265+
}
266+
Err(ConstEvalErr { kind: ErrKind::TypeckError, .. }) => Err(ErrorReported),
262267
Err(err) => {
263268
let mut diag = err.struct_error(tcx, count_expr.span, reason);
264269

src/librustc/middle/mem_categorization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
876876

877877
// Always promote `[T; 0]` (even when e.g. borrowed mutably).
878878
let promotable = match expr_ty.sty {
879-
ty::TyArray(_, len) if len.as_u64() == 0 => true,
879+
ty::TyArray(_, len) if len.val.to_const_int().unwrap().to_u64().unwrap() == 0 => true,
880880
_ => promotable,
881881
};
882882

src/librustc/mir/tcx.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
7070
LvalueTy::Ty {
7171
ty: match ty.sty {
7272
ty::TyArray(inner, size) => {
73-
let len = size.as_u64() - (from as u64) - (to as u64);
73+
let size = size.val.to_const_int().unwrap().to_u64().unwrap();
74+
let len = size - (from as u64) - (to as u64);
7475
tcx.mk_array(inner, len)
7576
}
7677
ty::TySlice(..) => ty,
@@ -148,7 +149,7 @@ impl<'tcx> Rvalue<'tcx> {
148149
match *self {
149150
Rvalue::Use(ref operand) => operand.ty(local_decls, tcx),
150151
Rvalue::Repeat(ref operand, count) => {
151-
tcx.mk_array(operand.ty(local_decls, tcx), count.as_u64())
152+
tcx.mk_array_const_usize(operand.ty(local_decls, tcx), count)
152153
}
153154
Rvalue::Ref(reg, bk, ref lv) => {
154155
let lv_ty = lv.ty(local_decls, tcx).to_ty(tcx);

src/librustc/ty/context.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use hir::map as hir_map;
2121
use hir::map::DefPathHash;
2222
use lint::{self, Lint};
2323
use ich::{self, StableHashingContext, NodeIdHashingMode};
24+
use middle::const_val::ConstVal;
2425
use middle::free_region::FreeRegionMap;
2526
use middle::lang_items;
2627
use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
@@ -49,7 +50,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
4950
StableHasherResult};
5051

5152
use arena::{TypedArena, DroplessArena};
52-
use rustc_const_math::ConstUsize;
53+
use rustc_const_math::{ConstInt, ConstUsize};
5354
use rustc_data_structures::indexed_vec::IndexVec;
5455
use std::borrow::Borrow;
5556
use std::cell::{Cell, RefCell};
@@ -1757,7 +1758,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
17571758

17581759
pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
17591760
let n = ConstUsize::new(n, self.sess.target.usize_ty).unwrap();
1760-
self.mk_ty(TyArray(ty, n))
1761+
self.mk_array_const_usize(ty, n)
1762+
}
1763+
1764+
pub fn mk_array_const_usize(self, ty: Ty<'tcx>, n: ConstUsize) -> Ty<'tcx> {
1765+
self.mk_ty(TyArray(ty, self.mk_const(ty::Const {
1766+
val: ConstVal::Integral(ConstInt::Usize(n)),
1767+
ty: self.types.usize
1768+
})))
17611769
}
17621770

17631771
pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {

src/librustc/ty/error.rs

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

1111
use hir::def_id::DefId;
1212
use infer::type_variable;
13+
use middle::const_val::ConstVal;
1314
use ty::{self, BoundRegion, DefIdTree, Region, Ty, TyCtxt};
1415

1516
use std::fmt;
@@ -18,7 +19,7 @@ use syntax::ast;
1819
use errors::DiagnosticBuilder;
1920
use syntax_pos::Span;
2021

21-
use rustc_const_math::ConstUsize;
22+
use rustc_const_math::ConstInt;
2223

2324
use hir;
2425

@@ -36,7 +37,7 @@ pub enum TypeError<'tcx> {
3637
AbiMismatch(ExpectedFound<abi::Abi>),
3738
Mutability,
3839
TupleSize(ExpectedFound<usize>),
39-
FixedArraySize(ExpectedFound<ConstUsize>),
40+
FixedArraySize(ExpectedFound<u64>),
4041
ArgCount,
4142

4243
RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
@@ -181,7 +182,13 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
181182
ty::TyTuple(ref tys, _) if tys.is_empty() => self.to_string(),
182183

183184
ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)),
184-
ty::TyArray(_, n) => format!("array of {} elements", n),
185+
ty::TyArray(_, n) => {
186+
if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
187+
format!("array of {} elements", n)
188+
} else {
189+
"array".to_string()
190+
}
191+
}
185192
ty::TySlice(_) => "slice".to_string(),
186193
ty::TyRawPtr(_) => "*-ptr".to_string(),
187194
ty::TyRef(region, tymut) => {

src/librustc/ty/flags.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use middle::const_val::{ConstVal, ConstAggregate};
1112
use ty::subst::Substs;
1213
use ty::{self, Ty, TypeFlags, TypeFoldable};
1314

@@ -145,7 +146,12 @@ impl FlagComputation {
145146
self.add_region(r);
146147
}
147148

148-
&ty::TyArray(tt, _) | &ty::TySlice(tt) => {
149+
&ty::TyArray(tt, len) => {
150+
self.add_ty(tt);
151+
self.add_const(len);
152+
}
153+
154+
&ty::TySlice(tt) => {
149155
self.add_ty(tt)
150156
}
151157

@@ -202,6 +208,36 @@ impl FlagComputation {
202208
}
203209
}
204210

211+
fn add_const(&mut self, constant: &ty::Const) {
212+
self.add_ty(constant.ty);
213+
match constant.val {
214+
ConstVal::Integral(_) |
215+
ConstVal::Float(_) |
216+
ConstVal::Str(_) |
217+
ConstVal::ByteStr(_) |
218+
ConstVal::Bool(_) |
219+
ConstVal::Char(_) |
220+
ConstVal::Variant(_) => {}
221+
ConstVal::Function(_, substs) => {
222+
self.add_substs(substs);
223+
}
224+
ConstVal::Aggregate(ConstAggregate::Struct(fields)) => {
225+
for &(_, v) in fields {
226+
self.add_const(v);
227+
}
228+
}
229+
ConstVal::Aggregate(ConstAggregate::Tuple(fields)) |
230+
ConstVal::Aggregate(ConstAggregate::Array(fields)) => {
231+
for v in fields {
232+
self.add_const(v);
233+
}
234+
}
235+
ConstVal::Aggregate(ConstAggregate::Repeat(v, _)) => {
236+
self.add_const(v);
237+
}
238+
}
239+
}
240+
205241
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection) {
206242
self.add_substs(projection.substs);
207243
self.add_ty(projection.ty);

src/librustc/ty/inhabitedness/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
205205
}))
206206
},
207207
TyArray(ty, len) => {
208-
if len.as_u64() == 0 {
208+
if len.val.to_const_int().unwrap().to_u64().unwrap() == 0 {
209209
DefIdForest::empty()
210210
} else {
211211
ty.uninhabited_from(visited, tcx)

src/librustc/ty/layout.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ impl<'a, 'tcx> Struct {
837837

838838
// Is this a fixed-size array of something non-zero
839839
// with at least one element?
840-
(_, &ty::TyArray(ety, d)) if d.as_u64() > 0 => {
840+
(_, &ty::TyArray(ety, d)) if d.val.to_const_int().unwrap().to_u64().unwrap() != 0 => {
841841
Struct::non_zero_field_paths(
842842
tcx,
843843
param_env,
@@ -1177,7 +1177,7 @@ impl<'a, 'tcx> Layout {
11771177
ty::TyArray(element, count) => {
11781178
let element = element.layout(tcx, param_env)?;
11791179
let element_size = element.size(dl);
1180-
let count = count.as_u64();
1180+
let count = count.val.to_const_int().unwrap().to_u64().unwrap();
11811181
if element_size.checked_mul(count, dl).is_none() {
11821182
return Err(LayoutError::SizeOverflow(ty));
11831183
}

src/librustc/ty/relate.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,14 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
428428
(&ty::TyArray(a_t, sz_a), &ty::TyArray(b_t, sz_b)) =>
429429
{
430430
let t = relation.relate(&a_t, &b_t)?;
431-
if sz_a == sz_b {
432-
Ok(tcx.mk_array(t, sz_a.as_u64()))
431+
assert_eq!(sz_a.ty, tcx.types.usize);
432+
assert_eq!(sz_b.ty, tcx.types.usize);
433+
let sz_a_u64 = sz_a.val.to_const_int().unwrap().to_u64().unwrap();
434+
let sz_b_u64 = sz_b.val.to_const_int().unwrap().to_u64().unwrap();
435+
if sz_a_u64 == sz_b_u64 {
436+
Ok(tcx.mk_ty(ty::TyArray(t, sz_a)))
433437
} else {
434-
Err(TypeError::FixedArraySize(expected_found(relation, &sz_a, &sz_b)))
438+
Err(TypeError::FixedArraySize(expected_found(relation, &sz_a_u64, &sz_b_u64)))
435439
}
436440
}
437441

src/librustc/ty/structural_impls.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
552552
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
553553
let sty = match self.sty {
554554
ty::TyRawPtr(tm) => ty::TyRawPtr(tm.fold_with(folder)),
555-
ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz),
555+
ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz.fold_with(folder)),
556556
ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)),
557557
ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)),
558558
ty::TyDynamic(ref trait_ty, ref region) =>
@@ -590,7 +590,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
590590
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
591591
match self.sty {
592592
ty::TyRawPtr(ref tm) => tm.visit_with(visitor),
593-
ty::TyArray(typ, _sz) => typ.visit_with(visitor),
593+
ty::TyArray(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor),
594594
ty::TySlice(typ) => typ.visit_with(visitor),
595595
ty::TyAdt(_, substs) => substs.visit_with(visitor),
596596
ty::TyDynamic(ref trait_ty, ref reg) =>

0 commit comments

Comments
 (0)