Move some test-only code to test files
This also relaxes the bounds on some structs and moves them to the impl block instead.
This commit is contained in:
parent
5c6d3bf389
commit
620ecc01a2
@ -297,22 +297,6 @@ impl<T> TypedArena<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the arena. Deallocates all but the longest chunk which may be reused.
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
// Clear the last chunk, which is partially filled.
|
|
||||||
let mut chunks_borrow = self.chunks.borrow_mut();
|
|
||||||
if let Some(mut last_chunk) = chunks_borrow.last_mut() {
|
|
||||||
self.clear_last_chunk(&mut last_chunk);
|
|
||||||
let len = chunks_borrow.len();
|
|
||||||
// If `T` is ZST, code below has no effect.
|
|
||||||
for mut chunk in chunks_borrow.drain(..len - 1) {
|
|
||||||
chunk.destroy(chunk.entries);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drops the contents of the last chunk. The last chunk is partially empty, unlike all other
|
// Drops the contents of the last chunk. The last chunk is partially empty, unlike all other
|
||||||
// chunks.
|
// chunks.
|
||||||
fn clear_last_chunk(&self, last_chunk: &mut TypedArenaChunk<T>) {
|
fn clear_last_chunk(&self, last_chunk: &mut TypedArenaChunk<T>) {
|
||||||
|
@ -11,6 +11,24 @@ struct Point {
|
|||||||
z: i32,
|
z: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> TypedArena<T> {
|
||||||
|
/// Clears the arena. Deallocates all but the longest chunk which may be reused.
|
||||||
|
fn clear(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
// Clear the last chunk, which is partially filled.
|
||||||
|
let mut chunks_borrow = self.chunks.borrow_mut();
|
||||||
|
if let Some(mut last_chunk) = chunks_borrow.last_mut() {
|
||||||
|
self.clear_last_chunk(&mut last_chunk);
|
||||||
|
let len = chunks_borrow.len();
|
||||||
|
// If `T` is ZST, code below has no effect.
|
||||||
|
for mut chunk in chunks_borrow.drain(..len - 1) {
|
||||||
|
chunk.destroy(chunk.entries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_unused() {
|
pub fn test_unused() {
|
||||||
let arena: TypedArena<Point> = TypedArena::default();
|
let arena: TypedArena<Point> = TypedArena::default();
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TinyList<T: PartialEq> {
|
pub struct TinyList<T> {
|
||||||
head: Option<Element<T>>,
|
head: Option<Element<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,20 +56,10 @@ impl<T: PartialEq> TinyList<T> {
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
let (mut elem, mut count) = (self.head.as_ref(), 0);
|
|
||||||
while let Some(ref e) = elem {
|
|
||||||
count += 1;
|
|
||||||
elem = e.next.as_deref();
|
|
||||||
}
|
|
||||||
count
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Element<T: PartialEq> {
|
struct Element<T> {
|
||||||
data: T,
|
data: T,
|
||||||
next: Option<Box<Element<T>>>,
|
next: Option<Box<Element<T>>>,
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,17 @@ use super::*;
|
|||||||
extern crate test;
|
extern crate test;
|
||||||
use test::{black_box, Bencher};
|
use test::{black_box, Bencher};
|
||||||
|
|
||||||
|
impl<T> TinyList<T> {
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
let (mut elem, mut count) = (self.head.as_ref(), 0);
|
||||||
|
while let Some(ref e) = elem {
|
||||||
|
count += 1;
|
||||||
|
elem = e.next.as_deref();
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_contains_and_insert() {
|
fn test_contains_and_insert() {
|
||||||
fn do_insert(i: u32) -> bool {
|
fn do_insert(i: u32) -> bool {
|
||||||
|
@ -9,7 +9,7 @@ use std::mem;
|
|||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TransitiveRelation<T: Eq + Hash> {
|
pub struct TransitiveRelation<T> {
|
||||||
// List of elements. This is used to map from a T to a usize.
|
// List of elements. This is used to map from a T to a usize.
|
||||||
elements: FxIndexSet<T>,
|
elements: FxIndexSet<T>,
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ struct Edge {
|
|||||||
target: Index,
|
target: Index,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> {
|
impl<T: Eq + Hash> TransitiveRelation<T> {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.edges.is_empty()
|
self.edges.is_empty()
|
||||||
}
|
}
|
||||||
@ -322,12 +322,6 @@ impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A "best" parent in some sense. See `parents` and
|
|
||||||
/// `postdom_upper_bound` for more details.
|
|
||||||
pub fn postdom_parent(&self, a: &T) -> Option<&T> {
|
|
||||||
self.mutual_immediate_postdominator(self.parents(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_closure<OP, R>(&self, op: OP) -> R
|
fn with_closure<OP, R>(&self, op: OP) -> R
|
||||||
where
|
where
|
||||||
OP: FnOnce(&BitMatrix<usize, usize>) -> R,
|
OP: FnOnce(&BitMatrix<usize, usize>) -> R,
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
impl<T: Eq + Hash> TransitiveRelation<T> {
|
||||||
|
/// A "best" parent in some sense. See `parents` and
|
||||||
|
/// `postdom_upper_bound` for more details.
|
||||||
|
fn postdom_parent(&self, a: &T) -> Option<&T> {
|
||||||
|
self.mutual_immediate_postdominator(self.parents(a))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_one_step() {
|
fn test_one_step() {
|
||||||
let mut relation = TransitiveRelation::default();
|
let mut relation = TransitiveRelation::default();
|
||||||
|
@ -453,41 +453,6 @@ impl SourceMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If
|
|
||||||
/// there are gaps between LHS and RHS, the resulting union will cross these gaps.
|
|
||||||
/// For this to work,
|
|
||||||
///
|
|
||||||
/// * the syntax contexts of both spans much match,
|
|
||||||
/// * the LHS span needs to end on the same line the RHS span begins,
|
|
||||||
/// * the LHS span must start at or before the RHS span.
|
|
||||||
pub fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span> {
|
|
||||||
// Ensure we're at the same expansion ID.
|
|
||||||
if sp_lhs.ctxt() != sp_rhs.ctxt() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let lhs_end = match self.lookup_line(sp_lhs.hi()) {
|
|
||||||
Ok(x) => x,
|
|
||||||
Err(_) => return None,
|
|
||||||
};
|
|
||||||
let rhs_begin = match self.lookup_line(sp_rhs.lo()) {
|
|
||||||
Ok(x) => x,
|
|
||||||
Err(_) => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we must cross lines to merge, don't merge.
|
|
||||||
if lhs_end.line != rhs_begin.line {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure these follow the expected order and that we don't overlap.
|
|
||||||
if (sp_lhs.lo() <= sp_rhs.lo()) && (sp_lhs.hi() <= sp_rhs.lo()) {
|
|
||||||
Some(sp_lhs.to(sp_rhs))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn span_to_string(&self, sp: Span) -> String {
|
pub fn span_to_string(&self, sp: Span) -> String {
|
||||||
if self.files.borrow().source_files.is_empty() && sp.is_dummy() {
|
if self.files.borrow().source_files.is_empty() && sp.is_dummy() {
|
||||||
return "no-location".to_string();
|
return "no-location".to_string();
|
||||||
@ -931,13 +896,6 @@ impl SourceMap {
|
|||||||
SourceFileAndBytePos { sf, pos: offset }
|
SourceFileAndBytePos { sf, pos: offset }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`.
|
|
||||||
pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
|
|
||||||
let idx = self.lookup_source_file_idx(bpos);
|
|
||||||
let sf = &(*self.files.borrow().source_files)[idx];
|
|
||||||
sf.bytepos_to_file_charpos(bpos)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the index of the `SourceFile` (in `self.files`) that contains `pos`.
|
// Returns the index of the `SourceFile` (in `self.files`) that contains `pos`.
|
||||||
// This index is guaranteed to be valid for the lifetime of this `SourceMap`,
|
// This index is guaranteed to be valid for the lifetime of this `SourceMap`,
|
||||||
// since `source_files` is a `MonotonicVec`
|
// since `source_files` is a `MonotonicVec`
|
||||||
|
@ -10,6 +10,50 @@ fn init_source_map() -> SourceMap {
|
|||||||
sm
|
sm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SourceMap {
|
||||||
|
/// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If
|
||||||
|
/// there are gaps between LHS and RHS, the resulting union will cross these gaps.
|
||||||
|
/// For this to work,
|
||||||
|
///
|
||||||
|
/// * the syntax contexts of both spans much match,
|
||||||
|
/// * the LHS span needs to end on the same line the RHS span begins,
|
||||||
|
/// * the LHS span must start at or before the RHS span.
|
||||||
|
fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span> {
|
||||||
|
// Ensure we're at the same expansion ID.
|
||||||
|
if sp_lhs.ctxt() != sp_rhs.ctxt() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lhs_end = match self.lookup_line(sp_lhs.hi()) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
let rhs_begin = match self.lookup_line(sp_rhs.lo()) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// If we must cross lines to merge, don't merge.
|
||||||
|
if lhs_end.line != rhs_begin.line {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure these follow the expected order and that we don't overlap.
|
||||||
|
if (sp_lhs.lo() <= sp_rhs.lo()) && (sp_lhs.hi() <= sp_rhs.lo()) {
|
||||||
|
Some(sp_lhs.to(sp_rhs))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`.
|
||||||
|
fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
|
||||||
|
let idx = self.lookup_source_file_idx(bpos);
|
||||||
|
let sf = &(*self.files.borrow().source_files)[idx];
|
||||||
|
sf.bytepos_to_file_charpos(bpos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Tests `lookup_byte_offset`.
|
/// Tests `lookup_byte_offset`.
|
||||||
#[test]
|
#[test]
|
||||||
fn t3() {
|
fn t3() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user