Skip to content

Commit c16f24b

Browse files
authored
Merge pull request rust-lang#177 from RalfJung/drop-glue
remove our array drop glue and use rustc's instead
2 parents 14848b3 + 1b5f77e commit c16f24b

File tree

8 files changed

+174
-330
lines changed

8 files changed

+174
-330
lines changed

src/eval_context.rs

Lines changed: 10 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::fmt::Write;
44
use rustc::hir::def_id::DefId;
55
use rustc::hir::map::definitions::DefPathData;
66
use rustc::middle::const_val::ConstVal;
7-
use rustc_const_math::{ConstInt, ConstUsize};
87
use rustc::mir;
98
use rustc::traits::Reveal;
109
use rustc::ty::layout::{self, Layout, Size};
@@ -15,7 +14,6 @@ use rustc_data_structures::indexed_vec::Idx;
1514
use syntax::codemap::{self, DUMMY_SP, Span};
1615
use syntax::ast;
1716
use syntax::abi::Abi;
18-
use syntax::symbol::Symbol;
1917

2018
use error::{EvalError, EvalResult};
2119
use lvalue::{Global, GlobalId, Lvalue, LvalueExtra};
@@ -43,9 +41,6 @@ pub struct EvalContext<'a, 'tcx: 'a> {
4341
/// This prevents infinite loops and huge computations from freezing up const eval.
4442
/// Remove once halting problem is solved.
4543
pub(crate) steps_remaining: u64,
46-
47-
/// Drop glue for arrays and slices
48-
pub(crate) seq_drop_glue: &'tcx mir::Mir<'tcx>,
4944
}
5045

5146
/// A stack frame.
@@ -127,188 +122,13 @@ impl Default for ResourceLimits {
127122

128123
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
129124
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, limits: ResourceLimits) -> Self {
130-
// Register array drop glue code
131-
let source_info = mir::SourceInfo {
132-
span: DUMMY_SP,
133-
scope: mir::ARGUMENT_VISIBILITY_SCOPE
134-
};
135-
// i = 0; len = Len(*a0); goto head;
136-
let start_block = mir::BasicBlockData {
137-
statements: vec![
138-
mir::Statement {
139-
source_info,
140-
kind: mir::StatementKind::Assign(
141-
mir::Lvalue::Local(mir::Local::new(2)),
142-
mir::Rvalue::Use(mir::Operand::Constant(Box::new(mir::Constant {
143-
span: DUMMY_SP,
144-
ty: tcx.types.usize,
145-
literal: mir::Literal::Value {
146-
value: ConstVal::Integral(ConstInt::Usize(ConstUsize::new(0, tcx.sess.target.uint_type).unwrap())),
147-
},
148-
})))
149-
)
150-
},
151-
mir::Statement {
152-
source_info,
153-
kind: mir::StatementKind::Assign(
154-
mir::Lvalue::Local(mir::Local::new(3)),
155-
mir::Rvalue::Len(mir::Lvalue::Projection(Box::new(mir::LvalueProjection {
156-
base: mir::Lvalue::Local(mir::Local::new(1)),
157-
elem: mir::ProjectionElem::Deref,
158-
}))),
159-
)
160-
},
161-
],
162-
terminator: Some(mir::Terminator {
163-
source_info: source_info,
164-
kind: mir::TerminatorKind::Goto { target: mir::BasicBlock::new(1) },
165-
}),
166-
is_cleanup: false
167-
};
168-
// head: done = i == len; switch done { 1 => ret, 0 => loop }
169-
let head = mir::BasicBlockData {
170-
statements: vec![
171-
mir::Statement {
172-
source_info,
173-
kind: mir::StatementKind::Assign(
174-
mir::Lvalue::Local(mir::Local::new(4)),
175-
mir::Rvalue::BinaryOp(
176-
mir::BinOp::Eq,
177-
mir::Operand::Consume(mir::Lvalue::Local(mir::Local::new(2))),
178-
mir::Operand::Consume(mir::Lvalue::Local(mir::Local::new(3))),
179-
)
180-
)
181-
},
182-
],
183-
terminator: Some(mir::Terminator {
184-
source_info: source_info,
185-
kind: mir::TerminatorKind::SwitchInt {
186-
targets: vec![
187-
mir::BasicBlock::new(2),
188-
mir::BasicBlock::new(4),
189-
],
190-
discr: mir::Operand::Consume(mir::Lvalue::Local(mir::Local::new(4))),
191-
switch_ty: tcx.types.bool,
192-
values: vec![ConstInt::U8(0)].into(),
193-
},
194-
}),
195-
is_cleanup: false
196-
};
197-
// loop: drop (*a0)[i]; goto inc;
198-
let loop_ = mir::BasicBlockData {
199-
statements: Vec::new(),
200-
terminator: Some(mir::Terminator {
201-
source_info: source_info,
202-
kind: mir::TerminatorKind::Drop {
203-
target: mir::BasicBlock::new(3),
204-
unwind: None,
205-
location: mir::Lvalue::Projection(Box::new(
206-
mir::LvalueProjection {
207-
base: mir::Lvalue::Projection(Box::new(
208-
mir::LvalueProjection {
209-
base: mir::Lvalue::Local(mir::Local::new(1)),
210-
elem: mir::ProjectionElem::Deref,
211-
}
212-
)),
213-
elem: mir::ProjectionElem::Index(mir::Operand::Consume(mir::Lvalue::Local(mir::Local::new(2)))),
214-
}
215-
)),
216-
},
217-
}),
218-
is_cleanup: false
219-
};
220-
// inc: i++; goto head;
221-
let inc = mir::BasicBlockData {
222-
statements: vec![
223-
mir::Statement {
224-
source_info,
225-
kind: mir::StatementKind::Assign(
226-
mir::Lvalue::Local(mir::Local::new(2)),
227-
mir::Rvalue::BinaryOp(
228-
mir::BinOp::Add,
229-
mir::Operand::Consume(mir::Lvalue::Local(mir::Local::new(2))),
230-
mir::Operand::Constant(Box::new(mir::Constant {
231-
span: DUMMY_SP,
232-
ty: tcx.types.usize,
233-
literal: mir::Literal::Value {
234-
value: ConstVal::Integral(ConstInt::Usize(ConstUsize::new(1, tcx.sess.target.uint_type).unwrap())),
235-
},
236-
})),
237-
)
238-
)
239-
},
240-
],
241-
terminator: Some(mir::Terminator {
242-
source_info: source_info,
243-
kind: mir::TerminatorKind::Goto { target: mir::BasicBlock::new(1) },
244-
}),
245-
is_cleanup: false
246-
};
247-
// ret: return;
248-
let ret = mir::BasicBlockData {
249-
statements: Vec::new(),
250-
terminator: Some(mir::Terminator {
251-
source_info: source_info,
252-
kind: mir::TerminatorKind::Return,
253-
}),
254-
is_cleanup: false
255-
};
256-
let locals = vec![
257-
mir::LocalDecl {
258-
mutability: mir::Mutability::Mut,
259-
ty: tcx.mk_nil(),
260-
name: None,
261-
source_info,
262-
is_user_variable: false,
263-
},
264-
mir::LocalDecl {
265-
mutability: mir::Mutability::Mut,
266-
ty: tcx.mk_mut_ptr(tcx.mk_slice(tcx.mk_param(0, Symbol::intern("T")))),
267-
name: None,
268-
source_info,
269-
is_user_variable: false,
270-
},
271-
mir::LocalDecl {
272-
mutability: mir::Mutability::Mut,
273-
ty: tcx.types.usize,
274-
name: None,
275-
source_info,
276-
is_user_variable: false,
277-
},
278-
mir::LocalDecl {
279-
mutability: mir::Mutability::Mut,
280-
ty: tcx.types.usize,
281-
name: None,
282-
source_info,
283-
is_user_variable: false,
284-
},
285-
mir::LocalDecl {
286-
mutability: mir::Mutability::Mut,
287-
ty: tcx.types.bool,
288-
name: None,
289-
source_info,
290-
is_user_variable: false,
291-
},
292-
];
293-
let seq_drop_glue = mir::Mir::new(
294-
vec![start_block, head, loop_, inc, ret].into_iter().collect(),
295-
Vec::new().into_iter().collect(), // vis scopes
296-
Vec::new().into_iter().collect(), // promoted
297-
tcx.mk_nil(), // return type
298-
locals.into_iter().collect(),
299-
1, // arg_count
300-
Vec::new(), // upvars
301-
DUMMY_SP,
302-
);
303-
let seq_drop_glue = tcx.alloc_mir(seq_drop_glue);
304125
EvalContext {
305126
tcx,
306127
memory: Memory::new(&tcx.data_layout, limits.memory_size),
307128
globals: HashMap::new(),
308129
stack: Vec::new(),
309130
stack_limit: limits.stack_limit,
310131
steps_remaining: limits.step_limit,
311-
seq_drop_glue: seq_drop_glue,
312132
}
313133
}
314134

@@ -823,8 +643,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
823643
self.write_primval(dest, PrimVal::Ptr(ptr), dest_ty)?;
824644
}
825645

826-
NullaryOp(mir::NullOp::SizeOf, _ty) => {
827-
unimplemented!()
646+
NullaryOp(mir::NullOp::SizeOf, ty) => {
647+
let size = self.type_size(ty)?.expect("SizeOf nullary MIR operator called for unsized type");
648+
self.write_primval(dest, PrimVal::from_u128(size as u128), dest_ty)?;
828649
}
829650

830651
Cast(kind, ref operand, cast_ty) => {
@@ -1020,6 +841,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1020841
}
1021842
}
1022843

844+
pub(super) fn pointer_offset(&self, ptr: Pointer, pointee_ty: Ty<'tcx>, offset: i64) -> EvalResult<'tcx, Pointer> {
845+
// FIXME: assuming here that type size is < i64::max_value()
846+
let pointee_size = self.type_size(pointee_ty)?.expect("cannot offset a pointer to an unsized type") as i64;
847+
// FIXME: Check overflow, out-of-bounds
848+
Ok(ptr.signed_offset(offset * pointee_size))
849+
}
850+
1023851
pub(super) fn eval_operand_to_primval(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<'tcx, PrimVal> {
1024852
let value = self.eval_operand(op)?;
1025853
let ty = self.operand_ty(op);

src/lvalue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
362362
let n_ptr = self.eval_operand(operand)?;
363363
let usize = self.tcx.types.usize;
364364
let n = self.value_to_primval(n_ptr, usize)?.to_u64()?;
365-
assert!(n < len);
365+
assert!(n < len, "Tried to access element {} of array/slice with length {}", n, len);
366366
let ptr = base_ptr.offset(n * elem_size);
367367
(ptr, LvalueExtra::None)
368368
}

0 commit comments

Comments
 (0)