about summary refs log tree commit diff
path: root/crates/test-utils
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@dend.ro>2022-10-18 09:12:49 +0300
committerLaurențiu Nicola <lnicola@dend.ro>2022-10-18 09:12:49 +0300
commita99a48e78600b5dfd39dec730d7fedfae8f48ff6 (patch)
tree26184df803344b52f3cd9d012f00847511179ebf /crates/test-utils
parent8536eb016cba13d333574c0d6ba2f2b0b21792ac (diff)
downloadrust-a99a48e78600b5dfd39dec730d7fedfae8f48ff6.tar.gz
rust-a99a48e78600b5dfd39dec730d7fedfae8f48ff6.zip
:arrow_up: rust-analyzer
Diffstat (limited to 'crates/test-utils')
-rw-r--r--crates/test-utils/src/fixture.rs53
-rw-r--r--crates/test-utils/src/minicore.rs85
2 files changed, 85 insertions, 53 deletions
diff --git a/crates/test-utils/src/fixture.rs b/crates/test-utils/src/fixture.rs
index 8c806e7925b..c824f5af725 100644
--- a/crates/test-utils/src/fixture.rs
+++ b/crates/test-utils/src/fixture.rs
@@ -61,6 +61,8 @@
 //! "
 //! ```
 
+use std::iter;
+
 use rustc_hash::FxHashMap;
 use stdx::trim_indent;
 
@@ -259,7 +261,7 @@ impl MiniCore {
             if res.has_flag(entry) {
                 panic!("duplicate minicore flag: {:?}", entry);
             }
-            res.activated_flags.push(entry.to_string());
+            res.activated_flags.push(entry.to_owned());
         }
 
         res
@@ -273,35 +275,34 @@ impl MiniCore {
         let raw_mini_core = include_str!("./minicore.rs");
         let mut lines = raw_mini_core.split_inclusive('\n');
 
-        let mut parsing_flags = false;
         let mut implications = Vec::new();
 
         // Parse `//!` preamble and extract flags and dependencies.
-        for line in lines.by_ref() {
-            let line = match line.strip_prefix("//!") {
-                Some(it) => it,
-                None => {
-                    assert!(line.trim().is_empty());
-                    break;
-                }
-            };
-
-            if parsing_flags {
-                let (flag, deps) = line.split_once(':').unwrap();
-                let flag = flag.trim();
-                self.valid_flags.push(flag.to_string());
-                for dep in deps.split(", ") {
-                    let dep = dep.trim();
-                    if !dep.is_empty() {
-                        self.assert_valid_flag(dep);
-                        implications.push((flag, dep));
-                    }
-                }
+        let trim_doc: fn(&str) -> Option<&str> = |line| match line.strip_prefix("//!") {
+            Some(it) => Some(it),
+            None => {
+                assert!(line.trim().is_empty(), "expected empty line after minicore header");
+                None
             }
+        };
+        for line in lines
+            .by_ref()
+            .map_while(trim_doc)
+            .skip_while(|line| !line.contains("Available flags:"))
+            .skip(1)
+        {
+            let (flag, deps) = line.split_once(':').unwrap();
+            let flag = flag.trim();
+
+            self.valid_flags.push(flag.to_string());
+            implications.extend(
+                iter::repeat(flag)
+                    .zip(deps.split(", ").map(str::trim).filter(|dep| !dep.is_empty())),
+            );
+        }
 
-            if line.contains("Available flags:") {
-                parsing_flags = true;
-            }
+        for (_, dep) in &implications {
+            self.assert_valid_flag(dep);
         }
 
         for flag in &self.activated_flags {
@@ -332,7 +333,7 @@ impl MiniCore {
             }
             if let Some(region) = trimmed.strip_prefix("// endregion:") {
                 let prev = active_regions.pop().unwrap();
-                assert_eq!(prev, region);
+                assert_eq!(prev, region, "unbalanced region pairs");
                 continue;
             }
 
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 10386b5b7bc..59b1c147d7f 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -8,36 +8,37 @@
 //! We then strip all the code marked with other flags.
 //!
 //! Available flags:
-//!     sized:
-//!     unsize: sized
+//!     add:
+//!     as_ref: sized
+//!     bool_impl: option, fn
+//!     clone: sized
 //!     coerce_unsized: unsize
-//!     slice:
-//!     range:
-//!     deref: sized
+//!     copy: clone
+//!     default: sized
 //!     deref_mut: deref
-//!     index: sized
+//!     deref: sized
+//!     derive:
+//!     drop:
+//!     eq: sized
+//!     fmt: result
 //!     fn:
-//!     try:
-//!     pin:
+//!     from: sized
 //!     future: pin
-//!     option:
-//!     result:
+//!     generator: pin
+//!     hash:
+//!     index: sized
+//!     infallible:
 //!     iterator: option
 //!     iterators: iterator, fn
-//!     default: sized
-//!     hash:
-//!     clone: sized
-//!     copy: clone
-//!     from: sized
-//!     eq: sized
+//!     option:
 //!     ord: eq, option
-//!     derive:
-//!     fmt: result
-//!     bool_impl: option, fn
-//!     add:
-//!     as_ref: sized
-//!     drop:
-//!     generator: pin
+//!     pin:
+//!     range:
+//!     result:
+//!     sized:
+//!     slice:
+//!     try: infallible
+//!     unsize: sized
 
 pub mod marker {
     // region:sized
@@ -150,6 +151,9 @@ pub mod convert {
         fn as_ref(&self) -> &T;
     }
     // endregion:as_ref
+    // region:infallible
+    pub enum Infallible {}
+    // endregion:infallible
 }
 
 pub mod ops {
@@ -326,7 +330,7 @@ pub mod ops {
             Continue(C),
             Break(B),
         }
-        pub trait FromResidual<R = Self::Residual> {
+        pub trait FromResidual<R = <Self as Try>::Residual> {
             #[lang = "from_residual"]
             fn from_residual(residual: R) -> Self;
         }
@@ -342,13 +346,13 @@ pub mod ops {
 
         impl<B, C> Try for ControlFlow<B, C> {
             type Output = C;
-            type Residual = ControlFlow<B, convert::Infallible>;
+            type Residual = ControlFlow<B, crate::convert::Infallible>;
             fn from_output(output: Self::Output) -> Self {}
             fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {}
         }
 
         impl<B, C> FromResidual for ControlFlow<B, C> {
-            fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self {}
+            fn from_residual(residual: ControlFlow<B, crate::convert::Infallible>) -> Self {}
         }
     }
     pub use self::try_::{ControlFlow, FromResidual, Try};
@@ -469,6 +473,33 @@ pub mod option {
             }
         }
     }
+    // region:try
+    impl<T> crate::ops::Try for Option<T> {
+        type Output = T;
+        type Residual = Option<crate::convert::Infallible>;
+
+        #[inline]
+        fn from_output(output: Self::Output) -> Self {
+            Some(output)
+        }
+
+        #[inline]
+        fn branch(self) -> crate::ops::ControlFlow<Self::Residual, Self::Output> {
+            match self {
+                Some(v) => crate::ops::ControlFlow::Continue(v),
+                None => crate::ops::ControlFlow::Break(None),
+            }
+        }
+    }
+    impl<T> crate::ops::FromResidual for Option<T> {
+        #[inline]
+        fn from_residual(residual: Option<crate::convert::Infallible>) -> Self {
+            match residual {
+                None => None,
+            }
+        }
+    }
+    // endregion:try
 }
 // endregion:option
 
@@ -584,7 +615,7 @@ pub mod iter {
             }
         }
     }
-    pub use self::adapters::{Take, FilterMap};
+    pub use self::adapters::{FilterMap, Take};
 
     mod sources {
         mod repeat {