Skip to content

Commit bb6a6e0

Browse files
committed
move ty::List into a new submodule
1 parent 7c59a81 commit bb6a6e0

File tree

2 files changed

+155
-145
lines changed

2 files changed

+155
-145
lines changed

src/librustc_middle/ty/list.rs

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
use crate::arena::Arena;
2+
3+
use rustc_serialize::{Encodable, Encoder};
4+
5+
use std::cmp::{self, Ordering};
6+
use std::fmt;
7+
use std::hash::{Hash, Hasher};
8+
use std::mem;
9+
use std::ops::Deref;
10+
use std::ptr;
11+
use std::slice;
12+
13+
extern "C" {
14+
/// A dummy type used to force `List` to be unsized while not requiring references to it be wide
15+
/// pointers.
16+
type OpaqueListContents;
17+
}
18+
19+
/// A wrapper for slices with the additional invariant
20+
/// that the slice is interned and no other slice with
21+
/// the same contents can exist in the same context.
22+
/// This means we can use pointer for both
23+
/// equality comparisons and hashing.
24+
/// Note: `Slice` was already taken by the `Ty`.
25+
#[repr(C)]
26+
pub struct List<T> {
27+
len: usize,
28+
data: [T; 0],
29+
opaque: OpaqueListContents,
30+
}
31+
32+
unsafe impl<T: Sync> Sync for List<T> {}
33+
34+
impl<T: Copy> List<T> {
35+
#[inline]
36+
pub(super) fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> {
37+
assert!(!mem::needs_drop::<T>());
38+
assert!(mem::size_of::<T>() != 0);
39+
assert!(!slice.is_empty());
40+
41+
// Align up the size of the len (usize) field
42+
let align = mem::align_of::<T>();
43+
let align_mask = align - 1;
44+
let offset = mem::size_of::<usize>();
45+
let offset = (offset + align_mask) & !align_mask;
46+
47+
let size = offset + slice.len() * mem::size_of::<T>();
48+
49+
let mem = arena
50+
.dropless
51+
.alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
52+
unsafe {
53+
let result = &mut *(mem.as_mut_ptr() as *mut List<T>);
54+
// Write the length
55+
result.len = slice.len();
56+
57+
// Write the elements
58+
let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len);
59+
arena_slice.copy_from_slice(slice);
60+
61+
result
62+
}
63+
}
64+
}
65+
66+
impl<T: fmt::Debug> fmt::Debug for List<T> {
67+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68+
(**self).fmt(f)
69+
}
70+
}
71+
72+
impl<T: Encodable> Encodable for List<T> {
73+
#[inline]
74+
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
75+
(**self).encode(s)
76+
}
77+
}
78+
79+
impl<T> Ord for List<T>
80+
where
81+
T: Ord,
82+
{
83+
fn cmp(&self, other: &List<T>) -> Ordering {
84+
if self == other { Ordering::Equal } else { <[T] as Ord>::cmp(&**self, &**other) }
85+
}
86+
}
87+
88+
impl<T> PartialOrd for List<T>
89+
where
90+
T: PartialOrd,
91+
{
92+
fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> {
93+
if self == other {
94+
Some(Ordering::Equal)
95+
} else {
96+
<[T] as PartialOrd>::partial_cmp(&**self, &**other)
97+
}
98+
}
99+
}
100+
101+
impl<T: PartialEq> PartialEq for List<T> {
102+
#[inline]
103+
fn eq(&self, other: &List<T>) -> bool {
104+
ptr::eq(self, other)
105+
}
106+
}
107+
impl<T: Eq> Eq for List<T> {}
108+
109+
impl<T> Hash for List<T> {
110+
#[inline]
111+
fn hash<H: Hasher>(&self, s: &mut H) {
112+
(self as *const List<T>).hash(s)
113+
}
114+
}
115+
116+
impl<T> Deref for List<T> {
117+
type Target = [T];
118+
#[inline(always)]
119+
fn deref(&self) -> &[T] {
120+
self.as_ref()
121+
}
122+
}
123+
124+
impl<T> AsRef<[T]> for List<T> {
125+
#[inline(always)]
126+
fn as_ref(&self) -> &[T] {
127+
unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) }
128+
}
129+
}
130+
131+
impl<'a, T> IntoIterator for &'a List<T> {
132+
type Item = &'a T;
133+
type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
134+
#[inline(always)]
135+
fn into_iter(self) -> Self::IntoIter {
136+
self[..].iter()
137+
}
138+
}
139+
140+
impl<T> List<T> {
141+
#[inline(always)]
142+
pub fn empty<'a>() -> &'a List<T> {
143+
#[repr(align(64), C)]
144+
struct EmptySlice([u8; 64]);
145+
static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]);
146+
assert!(mem::align_of::<T>() <= 64);
147+
unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) }
148+
}
149+
}

src/librustc_middle/ty/mod.rs

+6-145
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ pub use self::BorrowKind::*;
44
pub use self::IntVarValue::*;
55
pub use self::Variance::*;
66

7-
use crate::arena::Arena;
87
use crate::hir::exports::ExportMap;
98
use crate::ich::StableHashingContext;
109
use crate::infer::canonical::Canonical;
@@ -43,13 +42,11 @@ use rustc_span::Span;
4342
use rustc_target::abi::{Align, VariantIdx};
4443

4544
use std::cell::RefCell;
46-
use std::cmp::{self, Ordering};
45+
use std::cmp::Ordering;
4746
use std::fmt;
4847
use std::hash::{Hash, Hasher};
49-
use std::ops::Deref;
5048
use std::ops::Range;
51-
use std::slice;
52-
use std::{mem, ptr};
49+
use std::ptr;
5350

5451
pub use self::sty::BoundRegion::*;
5552
pub use self::sty::InferTy::*;
@@ -81,6 +78,8 @@ pub use self::context::{
8178

8279
pub use self::instance::{Instance, InstanceDef};
8380

81+
pub use self::list::List;
82+
8483
pub use self::trait_def::TraitDef;
8584

8685
pub use self::query::queries;
@@ -112,6 +111,7 @@ pub mod walk;
112111
mod context;
113112
mod diagnostics;
114113
mod instance;
114+
mod list;
115115
mod structural_impls;
116116
mod sty;
117117

@@ -663,148 +663,9 @@ pub type Ty<'tcx> = &'tcx TyS<'tcx>;
663663

664664
impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {}
665665
impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {}
666-
667-
pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>;
668-
669-
extern "C" {
670-
/// A dummy type used to force `List` to be unsized while not requiring references to it be wide
671-
/// pointers.
672-
type OpaqueListContents;
673-
}
674-
675-
/// A wrapper for slices with the additional invariant
676-
/// that the slice is interned and no other slice with
677-
/// the same contents can exist in the same context.
678-
/// This means we can use pointer for both
679-
/// equality comparisons and hashing.
680-
/// Note: `Slice` was already taken by the `Ty`.
681-
#[repr(C)]
682-
pub struct List<T> {
683-
len: usize,
684-
data: [T; 0],
685-
opaque: OpaqueListContents,
686-
}
687-
688-
unsafe impl<T: Sync> Sync for List<T> {}
689-
690-
impl<T: Copy> List<T> {
691-
#[inline]
692-
fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> {
693-
assert!(!mem::needs_drop::<T>());
694-
assert!(mem::size_of::<T>() != 0);
695-
assert!(!slice.is_empty());
696-
697-
// Align up the size of the len (usize) field
698-
let align = mem::align_of::<T>();
699-
let align_mask = align - 1;
700-
let offset = mem::size_of::<usize>();
701-
let offset = (offset + align_mask) & !align_mask;
702-
703-
let size = offset + slice.len() * mem::size_of::<T>();
704-
705-
let mem = arena
706-
.dropless
707-
.alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
708-
unsafe {
709-
let result = &mut *(mem.as_mut_ptr() as *mut List<T>);
710-
// Write the length
711-
result.len = slice.len();
712-
713-
// Write the elements
714-
let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len);
715-
arena_slice.copy_from_slice(slice);
716-
717-
result
718-
}
719-
}
720-
}
721-
722-
impl<T: fmt::Debug> fmt::Debug for List<T> {
723-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
724-
(**self).fmt(f)
725-
}
726-
}
727-
728-
impl<T: Encodable> Encodable for List<T> {
729-
#[inline]
730-
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
731-
(**self).encode(s)
732-
}
733-
}
734-
735-
impl<T> Ord for List<T>
736-
where
737-
T: Ord,
738-
{
739-
fn cmp(&self, other: &List<T>) -> Ordering {
740-
if self == other { Ordering::Equal } else { <[T] as Ord>::cmp(&**self, &**other) }
741-
}
742-
}
743-
744-
impl<T> PartialOrd for List<T>
745-
where
746-
T: PartialOrd,
747-
{
748-
fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> {
749-
if self == other {
750-
Some(Ordering::Equal)
751-
} else {
752-
<[T] as PartialOrd>::partial_cmp(&**self, &**other)
753-
}
754-
}
755-
}
756-
757-
impl<T: PartialEq> PartialEq for List<T> {
758-
#[inline]
759-
fn eq(&self, other: &List<T>) -> bool {
760-
ptr::eq(self, other)
761-
}
762-
}
763-
impl<T: Eq> Eq for List<T> {}
764-
765-
impl<T> Hash for List<T> {
766-
#[inline]
767-
fn hash<H: Hasher>(&self, s: &mut H) {
768-
(self as *const List<T>).hash(s)
769-
}
770-
}
771-
772-
impl<T> Deref for List<T> {
773-
type Target = [T];
774-
#[inline(always)]
775-
fn deref(&self) -> &[T] {
776-
self.as_ref()
777-
}
778-
}
779-
780-
impl<T> AsRef<[T]> for List<T> {
781-
#[inline(always)]
782-
fn as_ref(&self) -> &[T] {
783-
unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) }
784-
}
785-
}
786-
787-
impl<'a, T> IntoIterator for &'a List<T> {
788-
type Item = &'a T;
789-
type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
790-
#[inline(always)]
791-
fn into_iter(self) -> Self::IntoIter {
792-
self[..].iter()
793-
}
794-
}
795-
796666
impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<Ty<'tcx>> {}
797667

798-
impl<T> List<T> {
799-
#[inline(always)]
800-
pub fn empty<'a>() -> &'a List<T> {
801-
#[repr(align(64), C)]
802-
struct EmptySlice([u8; 64]);
803-
static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]);
804-
assert!(mem::align_of::<T>() <= 64);
805-
unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) }
806-
}
807-
}
668+
pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>;
808669

809670
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
810671
pub struct UpvarPath {

0 commit comments

Comments
 (0)