aboutsummaryrefslogtreecommitdiff
path: root/crates/test_utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/test_utils/src')
-rw-r--r--crates/test_utils/src/fixture.rs194
-rw-r--r--crates/test_utils/src/lib.rs55
-rw-r--r--crates/test_utils/src/minicore.rs549
3 files changed, 778 insertions, 20 deletions
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index d0bddf7d8..44656267f 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -77,6 +77,11 @@ pub struct Fixture {
77 pub introduce_new_source_root: bool, 77 pub introduce_new_source_root: bool,
78} 78}
79 79
80pub struct MiniCore {
81 activated_flags: Vec<String>,
82 valid_flags: Vec<String>,
83}
84
80impl Fixture { 85impl Fixture {
81 /// Parses text which looks like this: 86 /// Parses text which looks like this:
82 /// 87 ///
@@ -86,12 +91,28 @@ impl Fixture {
86 /// line 2 91 /// line 2
87 /// //- other meta 92 /// //- other meta
88 /// ``` 93 /// ```
89 pub fn parse(ra_fixture: &str) -> Vec<Fixture> { 94 ///
95 /// Fixture can also start with a minicore declaration:
96 ///
97 /// ```
98 /// //- minicore: sized
99 /// ```
100 ///
101 /// That will include a subset of `libcore` into the fixture, see
102 /// `minicore.rs` for what's available.
103 pub fn parse(ra_fixture: &str) -> (Option<MiniCore>, Vec<Fixture>) {
90 let fixture = trim_indent(ra_fixture); 104 let fixture = trim_indent(ra_fixture);
91 105 let mut fixture = fixture.as_str();
106 let mut mini_core = None;
92 let mut res: Vec<Fixture> = Vec::new(); 107 let mut res: Vec<Fixture> = Vec::new();
93 108
94 let default = if ra_fixture.contains("//-") { None } else { Some("//- /main.rs") }; 109 if fixture.starts_with("//- minicore:") {
110 let first_line = fixture.split_inclusive('\n').next().unwrap();
111 mini_core = Some(MiniCore::parse(first_line));
112 fixture = &fixture[first_line.len()..];
113 }
114
115 let default = if fixture.contains("//-") { None } else { Some("//- /main.rs") };
95 116
96 for (ix, line) in default.into_iter().chain(fixture.split_inclusive('\n')).enumerate() { 117 for (ix, line) in default.into_iter().chain(fixture.split_inclusive('\n')).enumerate() {
97 if line.contains("//-") { 118 if line.contains("//-") {
@@ -108,12 +129,22 @@ impl Fixture {
108 if line.starts_with("//-") { 129 if line.starts_with("//-") {
109 let meta = Fixture::parse_meta_line(line); 130 let meta = Fixture::parse_meta_line(line);
110 res.push(meta) 131 res.push(meta)
111 } else if let Some(entry) = res.last_mut() { 132 } else {
112 entry.text.push_str(line); 133 if line.starts_with("// ")
134 && line.contains(':')
135 && !line.contains("::")
136 && line.chars().all(|it| !it.is_uppercase())
137 {
138 panic!("looks like invalid metadata line: {:?}", line)
139 }
140
141 if let Some(entry) = res.last_mut() {
142 entry.text.push_str(line);
143 }
113 } 144 }
114 } 145 }
115 146
116 res 147 (mini_core, res)
117 } 148 }
118 149
119 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo 150 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
@@ -123,7 +154,7 @@ impl Fixture {
123 let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); 154 let components = meta.split_ascii_whitespace().collect::<Vec<_>>();
124 155
125 let path = components[0].to_string(); 156 let path = components[0].to_string();
126 assert!(path.starts_with('/')); 157 assert!(path.starts_with('/'), "fixture path does not start with `/`: {:?}", path);
127 158
128 let mut krate = None; 159 let mut krate = None;
129 let mut deps = Vec::new(); 160 let mut deps = Vec::new();
@@ -133,7 +164,9 @@ impl Fixture {
133 let mut env = FxHashMap::default(); 164 let mut env = FxHashMap::default();
134 let mut introduce_new_source_root = false; 165 let mut introduce_new_source_root = false;
135 for component in components[1..].iter() { 166 for component in components[1..].iter() {
136 let (key, value) = component.split_once(':').unwrap(); 167 let (key, value) = component
168 .split_once(':')
169 .unwrap_or_else(|| panic!("invalid meta line: {:?}", meta));
137 match key { 170 match key {
138 "crate" => krate = Some(value.to_string()), 171 "crate" => krate = Some(value.to_string()),
139 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(), 172 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(),
@@ -172,6 +205,139 @@ impl Fixture {
172 } 205 }
173} 206}
174 207
208impl MiniCore {
209 fn has_flag(&self, flag: &str) -> bool {
210 self.activated_flags.iter().any(|it| it == flag)
211 }
212
213 #[track_caller]
214 fn assert_valid_flag(&self, flag: &str) {
215 if !self.valid_flags.iter().any(|it| it == flag) {
216 panic!("invalid flag: {:?}, valid flags: {:?}", flag, self.valid_flags);
217 }
218 }
219
220 fn parse(line: &str) -> MiniCore {
221 let mut res = MiniCore { activated_flags: Vec::new(), valid_flags: Vec::new() };
222
223 let line = line.strip_prefix("//- minicore:").unwrap().trim();
224 for entry in line.split(", ") {
225 if res.has_flag(entry) {
226 panic!("duplicate minicore flag: {:?}", entry)
227 }
228 res.activated_flags.push(entry.to_string())
229 }
230
231 res
232 }
233
234 /// Strips parts of minicore.rs which are flagged by inactive flags.
235 ///
236 /// This is probably over-engineered to support flags dependencies.
237 pub fn source_code(mut self) -> String {
238 let mut buf = String::new();
239 let raw_mini_core = include_str!("./minicore.rs");
240 let mut lines = raw_mini_core.split_inclusive('\n');
241
242 let mut parsing_flags = false;
243 let mut implications = Vec::new();
244
245 // Parse `//!` preamble and extract flags and dependencies.
246 for line in lines.by_ref() {
247 let line = match line.strip_prefix("//!") {
248 Some(it) => it,
249 None => {
250 assert!(line.trim().is_empty());
251 break;
252 }
253 };
254
255 if parsing_flags {
256 let (flag, deps) = line.split_once(':').unwrap();
257 let flag = flag.trim();
258 self.valid_flags.push(flag.to_string());
259 for dep in deps.split(", ") {
260 let dep = dep.trim();
261 if !dep.is_empty() {
262 self.assert_valid_flag(dep);
263 implications.push((flag, dep));
264 }
265 }
266 }
267
268 if line.contains("Available flags:") {
269 parsing_flags = true;
270 }
271 }
272
273 for flag in &self.activated_flags {
274 self.assert_valid_flag(flag);
275 }
276
277 // Fixed point loop to compute transitive closure of flags.
278 loop {
279 let mut changed = false;
280 for &(u, v) in implications.iter() {
281 if self.has_flag(u) && !self.has_flag(v) {
282 self.activated_flags.push(v.to_string());
283 changed = true;
284 }
285 }
286 if !changed {
287 break;
288 }
289 }
290
291 let mut active_regions = Vec::new();
292 let mut seen_regions = Vec::new();
293 for line in lines {
294 let trimmed = line.trim();
295 if let Some(region) = trimmed.strip_prefix("// region:") {
296 active_regions.push(region);
297 continue;
298 }
299 if let Some(region) = trimmed.strip_prefix("// endregion:") {
300 let prev = active_regions.pop().unwrap();
301 assert_eq!(prev, region);
302 continue;
303 }
304
305 let mut line_region = false;
306 if let Some(idx) = trimmed.find("// :") {
307 line_region = true;
308 active_regions.push(&trimmed[idx + "// :".len()..]);
309 }
310
311 let mut keep = true;
312 for &region in &active_regions {
313 assert!(
314 !region.starts_with(' '),
315 "region marker starts with a space: {:?}",
316 region
317 );
318 self.assert_valid_flag(region);
319 seen_regions.push(region);
320 keep &= self.has_flag(region);
321 }
322
323 if keep {
324 buf.push_str(line)
325 }
326 if line_region {
327 active_regions.pop().unwrap();
328 }
329 }
330
331 for flag in &self.valid_flags {
332 if !seen_regions.iter().any(|it| it == flag) {
333 panic!("unused minicore flag: {:?}", flag);
334 }
335 }
336 format!("{}", buf);
337 buf
338 }
339}
340
175#[test] 341#[test]
176#[should_panic] 342#[should_panic]
177fn parse_fixture_checks_further_indented_metadata() { 343fn parse_fixture_checks_further_indented_metadata() {
@@ -189,12 +355,14 @@ fn parse_fixture_checks_further_indented_metadata() {
189 355
190#[test] 356#[test]
191fn parse_fixture_gets_full_meta() { 357fn parse_fixture_gets_full_meta() {
192 let parsed = Fixture::parse( 358 let (mini_core, parsed) = Fixture::parse(
193 r" 359 r#"
194 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo 360//- minicore: coerce_unsized
195 mod m; 361//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo
196 ", 362mod m;
363"#,
197 ); 364 );
365 assert_eq!(mini_core.unwrap().activated_flags, vec!["coerce_unsized".to_string()]);
198 assert_eq!(1, parsed.len()); 366 assert_eq!(1, parsed.len());
199 367
200 let meta = &parsed[0]; 368 let meta = &parsed[0];
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index b2fe25f82..d9c22c180 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -11,6 +11,7 @@ mod fixture;
11mod assert_linear; 11mod assert_linear;
12 12
13use std::{ 13use std::{
14 collections::BTreeMap,
14 convert::{TryFrom, TryInto}, 15 convert::{TryFrom, TryInto},
15 env, fs, 16 env, fs,
16 path::{Path, PathBuf}, 17 path::{Path, PathBuf},
@@ -23,7 +24,10 @@ use text_size::{TextRange, TextSize};
23pub use dissimilar::diff as __diff; 24pub use dissimilar::diff as __diff;
24pub use rustc_hash::FxHashMap; 25pub use rustc_hash::FxHashMap;
25 26
26pub use crate::{assert_linear::AssertLinear, fixture::Fixture}; 27pub use crate::{
28 assert_linear::AssertLinear,
29 fixture::{Fixture, MiniCore},
30};
27 31
28pub const CURSOR_MARKER: &str = "$0"; 32pub const CURSOR_MARKER: &str = "$0";
29pub const ESCAPED_CURSOR_MARKER: &str = "\\$0"; 33pub const ESCAPED_CURSOR_MARKER: &str = "\\$0";
@@ -202,14 +206,25 @@ pub fn add_cursor(text: &str, offset: TextSize) -> String {
202/// 206///
203/// // ^^^ first line 207/// // ^^^ first line
204/// // | second line 208/// // | second line
209///
210/// Annotations point to the last line that actually was long enough for the
211/// range, not counting annotations themselves. So overlapping annotations are
212/// possible:
213/// ```no_run
214/// // stuff other stuff
215/// // ^^ 'st'
216/// // ^^^^^ 'stuff'
217/// // ^^^^^^^^^^^ 'other stuff'
218/// ```
205pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> { 219pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> {
206 let mut res = Vec::new(); 220 let mut res = Vec::new();
207 let mut prev_line_start: Option<TextSize> = Some(0.into()); 221 // map from line length to beginning of last line that had that length
222 let mut line_start_map = BTreeMap::new();
208 let mut line_start: TextSize = 0.into(); 223 let mut line_start: TextSize = 0.into();
209 let mut prev_line_annotations: Vec<(TextSize, usize)> = Vec::new(); 224 let mut prev_line_annotations: Vec<(TextSize, usize)> = Vec::new();
210 for line in text.split_inclusive('\n') { 225 for line in text.split_inclusive('\n') {
211 let mut this_line_annotations = Vec::new(); 226 let mut this_line_annotations = Vec::new();
212 if let Some(idx) = line.find("//") { 227 let line_length = if let Some(idx) = line.find("//") {
213 let annotation_offset = TextSize::of(&line[..idx + "//".len()]); 228 let annotation_offset = TextSize::of(&line[..idx + "//".len()]);
214 for annotation in extract_line_annotations(&line[idx + "//".len()..]) { 229 for annotation in extract_line_annotations(&line[idx + "//".len()..]) {
215 match annotation { 230 match annotation {
@@ -219,7 +234,9 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> {
219 let range = if file { 234 let range = if file {
220 TextRange::up_to(TextSize::of(text)) 235 TextRange::up_to(TextSize::of(text))
221 } else { 236 } else {
222 range + prev_line_start.unwrap() 237 let line_start = line_start_map.range(range.end()..).next().unwrap();
238
239 range + line_start.1
223 }; 240 };
224 res.push((range, content)) 241 res.push((range, content))
225 } 242 }
@@ -235,9 +252,14 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> {
235 } 252 }
236 } 253 }
237 } 254 }
238 } 255 idx.try_into().unwrap()
256 } else {
257 TextSize::of(line)
258 };
259
260 line_start_map = line_start_map.split_off(&line_length);
261 line_start_map.insert(line_length, line_start);
239 262
240 prev_line_start = Some(line_start);
241 line_start += TextSize::of(line); 263 line_start += TextSize::of(line);
242 264
243 prev_line_annotations = this_line_annotations; 265 prev_line_annotations = this_line_annotations;
@@ -293,7 +315,7 @@ fn extract_line_annotations(mut line: &str) -> Vec<LineAnnotation> {
293} 315}
294 316
295#[test] 317#[test]
296fn test_extract_annotations() { 318fn test_extract_annotations_1() {
297 let text = stdx::trim_indent( 319 let text = stdx::trim_indent(
298 r#" 320 r#"
299fn main() { 321fn main() {
@@ -318,6 +340,25 @@ fn main() {
318 assert_eq!(res[3].0.len(), 115); 340 assert_eq!(res[3].0.len(), 115);
319} 341}
320 342
343#[test]
344fn test_extract_annotations_2() {
345 let text = stdx::trim_indent(
346 r#"
347fn main() {
348 (x, y);
349 //^ a
350 // ^ b
351 //^^^^^^^^ c
352}"#,
353 );
354 let res = extract_annotations(&text)
355 .into_iter()
356 .map(|(range, ann)| (&text[range], ann))
357 .collect::<Vec<_>>();
358
359 assert_eq!(res, [("x", "a".into()), ("y", "b".into()), ("(x, y)", "c".into())]);
360}
361
321/// Returns `false` if slow tests should not run, otherwise returns `true` and 362/// Returns `false` if slow tests should not run, otherwise returns `true` and
322/// also creates a file at `./target/.slow_tests_cookie` which serves as a flag 363/// also creates a file at `./target/.slow_tests_cookie` which serves as a flag
323/// that slow tests did run. 364/// that slow tests did run.
diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs
new file mode 100644
index 000000000..ce6ad8541
--- /dev/null
+++ b/crates/test_utils/src/minicore.rs
@@ -0,0 +1,549 @@
1//! This is a fixture we use for tests that need lang items.
2//!
3//! We want to include the minimal subset of core for each test, so this file
4//! supports "conditional compilation". Tests use the following syntax to include minicore:
5//!
6//! //- minicore: flag1, flag2
7//!
8//! We then strip all the code marked with other flags.
9//!
10//! Available flags:
11//! sized:
12//! unsize: sized
13//! coerce_unsized: unsize
14//! slice:
15//! range:
16//! deref: sized
17//! deref_mut: deref
18//! index: sized
19//! fn:
20//! pin:
21//! future: pin
22//! option:
23//! result:
24//! iterator: option
25//! iterators: iterator, fn
26//! default: sized
27//! clone: sized
28//! copy: clone
29//! from: sized
30//! eq: sized
31//! ord: eq, option
32//! derive:
33
34pub mod marker {
35 // region:sized
36 #[lang = "sized"]
37 #[fundamental]
38 #[rustc_specialization_trait]
39 pub trait Sized {}
40 // endregion:sized
41
42 // region:unsize
43 #[lang = "unsize"]
44 pub trait Unsize<T: ?Sized> {}
45 // endregion:unsize
46
47 // region:copy
48 #[lang = "copy"]
49 pub trait Copy: Clone {}
50 // region:derive
51 #[rustc_builtin_macro]
52 pub macro Copy($item:item) {}
53 // endregion:derive
54
55 mod copy_impls {
56 use super::Copy;
57
58 macro_rules! impl_copy {
59 ($($t:ty)*) => {
60 $(
61 impl Copy for $t {}
62 )*
63 }
64 }
65
66 impl_copy! {
67 usize u8 u16 u32 u64 u128
68 isize i8 i16 i32 i64 i128
69 f32 f64
70 bool char
71 }
72
73 impl<T: ?Sized> Copy for *const T {}
74 impl<T: ?Sized> Copy for *mut T {}
75 impl<T: ?Sized> Copy for &T {}
76 }
77 // endregion:copy
78}
79
80// region:default
81pub mod default {
82 pub trait Default: Sized {
83 fn default() -> Self;
84 }
85}
86// endregion:default
87
88// region:clone
89pub mod clone {
90 #[lang = "clone"]
91 pub trait Clone: Sized {
92 fn clone(&self) -> Self;
93 }
94 // region:derive
95 #[rustc_builtin_macro]
96 pub macro Clone($item:item) {}
97 // endregion:derive
98}
99// endregion:clone
100
101// region:from
102pub mod convert {
103 pub trait From<T>: Sized {
104 fn from(_: T) -> Self;
105 }
106 pub trait Into<T>: Sized {
107 fn into(self) -> T;
108 }
109
110 impl<T, U> Into<U> for T
111 where
112 U: From<T>,
113 {
114 fn into(self) -> U {
115 U::from(self)
116 }
117 }
118
119 impl<T> From<T> for T {
120 fn from(t: T) -> T {
121 t
122 }
123 }
124}
125// endregion:from
126
127pub mod ops {
128 // region:coerce_unsized
129 mod unsize {
130 use crate::marker::Unsize;
131
132 #[lang = "coerce_unsized"]
133 pub trait CoerceUnsized<T: ?Sized> {}
134
135 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
136 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
137 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
138 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
139
140 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
141 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
142
143 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
144 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
145 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
146 }
147 pub use self::unsize::CoerceUnsized;
148 // endregion:coerce_unsized
149
150 // region:deref
151 mod deref {
152 #[lang = "deref"]
153 pub trait Deref {
154 #[lang = "deref_target"]
155 type Target: ?Sized;
156 fn deref(&self) -> &Self::Target;
157 }
158 // region:deref_mut
159 #[lang = "deref_mut"]
160 pub trait DerefMut: Deref {
161 fn deref_mut(&mut self) -> &mut Self::Target;
162 }
163 // endregion:deref_mut
164 }
165 pub use self::deref::{
166 Deref,
167 DerefMut, // :deref_mut
168 };
169 // endregion:deref
170
171 // region:index
172 mod index {
173 #[lang = "index"]
174 pub trait Index<Idx: ?Sized> {
175 type Output: ?Sized;
176 fn index(&self, index: Idx) -> &Self::Output;
177 }
178 #[lang = "index_mut"]
179 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
180 fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
181 }
182
183 // region:slice
184 impl<T, I> Index<I> for [T]
185 where
186 I: SliceIndex<[T]>,
187 {
188 type Output = I::Output;
189 fn index(&self, index: I) -> &I::Output {
190 loop {}
191 }
192 }
193 impl<T, I> IndexMut<I> for [T]
194 where
195 I: SliceIndex<[T]>,
196 {
197 fn index_mut(&mut self, index: I) -> &mut I::Output {
198 loop {}
199 }
200 }
201
202 pub unsafe trait SliceIndex<T: ?Sized> {
203 type Output: ?Sized;
204 }
205 unsafe impl<T> SliceIndex<[T]> for usize {
206 type Output = T;
207 }
208 // endregion:slice
209 }
210 pub use self::index::{Index, IndexMut};
211 // endregion:index
212
213 // region:range
214 mod range {
215 #[lang = "RangeFull"]
216 pub struct RangeFull;
217
218 #[lang = "Range"]
219 pub struct Range<Idx> {
220 pub start: Idx,
221 pub end: Idx,
222 }
223
224 #[lang = "RangeFrom"]
225 pub struct RangeFrom<Idx> {
226 pub start: Idx,
227 }
228
229 #[lang = "RangeTo"]
230 pub struct RangeTo<Idx> {
231 pub end: Idx,
232 }
233
234 #[lang = "RangeInclusive"]
235 pub struct RangeInclusive<Idx> {
236 pub(crate) start: Idx,
237 pub(crate) end: Idx,
238 pub(crate) exhausted: bool,
239 }
240
241 #[lang = "RangeToInclusive"]
242 pub struct RangeToInclusive<Idx> {
243 pub end: Idx,
244 }
245 }
246 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
247 pub use self::range::{RangeInclusive, RangeToInclusive};
248 // endregion:range
249
250 // region:fn
251 mod function {
252 #[lang = "fn"]
253 #[fundamental]
254 pub trait Fn<Args>: FnMut<Args> {}
255
256 #[lang = "fn_mut"]
257 #[fundamental]
258 pub trait FnMut<Args>: FnOnce<Args> {}
259
260 #[lang = "fn_once"]
261 #[fundamental]
262 pub trait FnOnce<Args> {
263 #[lang = "fn_once_output"]
264 type Output;
265 }
266 }
267 pub use self::function::{Fn, FnMut, FnOnce};
268 // endregion:fn
269}
270
271// region:eq
272pub mod cmp {
273 #[lang = "eq"]
274 pub trait PartialEq<Rhs: ?Sized = Self> {
275 fn eq(&self, other: &Rhs) -> bool;
276 }
277
278 pub trait Eq: PartialEq<Self> {}
279
280 // region:derive
281 #[rustc_builtin_macro]
282 pub macro PartialEq($item:item) {}
283 #[rustc_builtin_macro]
284 pub macro Eq($item:item) {}
285 // endregion:derive
286
287 // region:ord
288 #[lang = "partial_ord"]
289 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
290 fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
291 }
292
293 pub trait Ord: Eq + PartialOrd<Self> {
294 fn cmp(&self, other: &Self) -> Ordering;
295 }
296
297 pub enum Ordering {
298 Less = -1,
299 Equal = 0,
300 Greater = 1,
301 }
302
303 // region:derive
304 #[rustc_builtin_macro]
305 pub macro PartialOrd($item:item) {}
306 #[rustc_builtin_macro]
307 pub macro Ord($item:item) {}
308 // endregion:derive
309
310 // endregion:ord
311}
312// endregion:eq
313
314// region:slice
315pub mod slice {
316 #[lang = "slice"]
317 impl<T> [T] {
318 pub fn len(&self) -> usize {
319 loop {}
320 }
321 }
322}
323// endregion:slice
324
325// region:option
326pub mod option {
327 pub enum Option<T> {
328 #[lang = "None"]
329 None,
330 #[lang = "Some"]
331 Some(T),
332 }
333}
334// endregion:option
335
336// region:result
337pub mod result {
338 pub enum Result<T, E> {
339 #[lang = "Ok"]
340 Ok(T),
341 #[lang = "Err"]
342 Err(E),
343 }
344}
345// endregion:result
346
347// region:pin
348pub mod pin {
349 #[lang = "pin"]
350 #[fundamental]
351 pub struct Pin<P> {
352 pointer: P,
353 }
354}
355// endregion:pin
356
357// region:future
358pub mod future {
359 use crate::{
360 pin::Pin,
361 task::{Context, Poll},
362 };
363
364 #[lang = "future_trait"]
365 pub trait Future {
366 type Output;
367 #[lang = "poll"]
368 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
369 }
370}
371pub mod task {
372 pub enum Poll<T> {
373 #[lang = "Ready"]
374 Ready(T),
375 #[lang = "Pending"]
376 Pending,
377 }
378
379 pub struct Context<'a> {
380 waker: &'a (),
381 }
382}
383// endregion:future
384
385// region:iterator
386pub mod iter {
387 // region:iterators
388 mod adapters {
389 pub struct Take<I> {
390 iter: I,
391 n: usize,
392 }
393 impl<I> Iterator for Take<I>
394 where
395 I: Iterator,
396 {
397 type Item = <I as Iterator>::Item;
398
399 fn next(&mut self) -> Option<<I as Iterator>::Item> {
400 loop {}
401 }
402 }
403
404 pub struct FilterMap<I, F> {
405 iter: I,
406 f: F,
407 }
408 impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
409 where
410 F: FnMut(I::Item) -> Option<B>,
411 {
412 type Item = B;
413
414 #[inline]
415 fn next(&mut self) -> Option<B> {
416 loop {}
417 }
418 }
419 }
420 pub use self::adapters::Take;
421
422 mod sources {
423 mod repeat {
424 pub fn repeat<T>(elt: T) -> Repeat<T> {
425 loop {}
426 }
427
428 pub struct Repeat<A> {
429 element: A,
430 }
431
432 impl<A> Iterator for Repeat<A> {
433 type Item = A;
434
435 fn next(&mut self) -> Option<A> {
436 loop {}
437 }
438 }
439 }
440 pub use self::repeat::{repeat, Repeat};
441 }
442 pub use self::sources::{repeat, Repeat};
443 // endregion:iterators
444
445 mod traits {
446 mod iterator {
447 use super::super::Take;
448
449 pub trait Iterator {
450 type Item;
451 #[lang = "next"]
452 fn next(&mut self) -> Option<Self::Item>;
453 fn nth(&mut self, n: usize) -> Option<Self::Item> {
454 loop {}
455 }
456 fn by_ref(&mut self) -> &mut Self
457 where
458 Self: Sized,
459 {
460 self
461 }
462 // region:iterators
463 fn take(self, n: usize) -> crate::iter::Take<Self> {
464 loop {}
465 }
466 fn filter_map<B, F>(self, f: F) -> crate::iter::FilterMap<Self, F>
467 where
468 Self: Sized,
469 F: FnMut(Self::Item) -> Option<B>,
470 {
471 loop {}
472 }
473 // endregion:iterators
474 }
475 impl<I: Iterator + ?Sized> Iterator for &mut I {
476 type Item = I::Item;
477 fn next(&mut self) -> Option<I::Item> {
478 (**self).next()
479 }
480 }
481 }
482 pub use self::iterator::Iterator;
483
484 mod collect {
485 pub trait IntoIterator {
486 type Item;
487 type IntoIter: Iterator<Item = Self::Item>;
488 #[lang = "into_iter"]
489 fn into_iter(self) -> Self::IntoIter;
490 }
491 impl<I: Iterator> IntoIterator for I {
492 type Item = I::Item;
493 type IntoIter = I;
494 fn into_iter(self) -> I {
495 self
496 }
497 }
498 }
499 pub use self::collect::IntoIterator;
500 }
501 pub use self::traits::{IntoIterator, Iterator};
502}
503// endregion:iterator
504
505// region:derive
506mod macros {
507 pub(crate) mod builtin {
508 #[rustc_builtin_macro]
509 pub macro derive($item:item) {
510 /* compiler built-in */
511 }
512 }
513}
514// endregion:derive
515
516pub mod prelude {
517 pub mod v1 {
518 pub use crate::{
519 clone::Clone, // :clone
520 cmp::{Eq, PartialEq}, // :eq
521 cmp::{Ord, PartialOrd}, // :ord
522 convert::{From, Into}, // :from
523 default::Default, // :default
524 iter::{IntoIterator, Iterator}, // :iterator
525 macros::builtin::derive, // :derive
526 marker::Copy, // :copy
527 marker::Sized, // :sized
528 ops::{Fn, FnMut, FnOnce}, // :fn
529 option::Option::{self, None, Some}, // :option
530 result::Result::{self, Err, Ok}, // :result
531 };
532 }
533
534 pub mod rust_2015 {
535 pub use super::v1::*;
536 }
537
538 pub mod rust_2018 {
539 pub use super::v1::*;
540 }
541
542 pub mod rust_2021 {
543 pub use super::v1::*;
544 }
545}
546
547#[prelude_import]
548#[allow(unused)]
549use prelude::v1::*;