Browse Source

引入intertrait库,支持trait之间的互相转换 (#395)

* 能过编译(test还没法跑)

* 初始化intertrait转换库

* update license of intertrait
LoGin 1 year ago
parent
commit
fba5623183
46 changed files with 2211 additions and 2 deletions
  1. 1 1
      .vscode/settings.json
  2. 6 0
      kernel/Cargo.toml
  3. 6 0
      kernel/src/init/c_adapter.rs
  4. 5 0
      kernel/src/init/mod.rs
  5. 9 1
      kernel/src/lib.rs
  6. 18 0
      kernel/src/libs/intertrait/.gitignore
  7. 27 0
      kernel/src/libs/intertrait/Cargo.toml
  8. 17 0
      kernel/src/libs/intertrait/LICENSE-MIT
  9. 163 0
      kernel/src/libs/intertrait/README.md
  10. 23 0
      kernel/src/libs/intertrait/macros/Cargo.toml
  11. 176 0
      kernel/src/libs/intertrait/macros/LICENSE-APACHE
  12. 17 0
      kernel/src/libs/intertrait/macros/LICENSE-MIT
  13. 76 0
      kernel/src/libs/intertrait/macros/src/args.rs
  14. 64 0
      kernel/src/libs/intertrait/macros/src/gen_caster.rs
  15. 82 0
      kernel/src/libs/intertrait/macros/src/item_impl.rs
  16. 31 0
      kernel/src/libs/intertrait/macros/src/item_type.rs
  17. 145 0
      kernel/src/libs/intertrait/macros/src/lib.rs
  18. 21 0
      kernel/src/libs/intertrait/src/cast.rs
  19. 45 0
      kernel/src/libs/intertrait/src/cast/cast_arc.rs
  20. 44 0
      kernel/src/libs/intertrait/src/cast/cast_box.rs
  21. 41 0
      kernel/src/libs/intertrait/src/cast/cast_mut.rs
  22. 44 0
      kernel/src/libs/intertrait/src/cast/cast_rc.rs
  23. 84 0
      kernel/src/libs/intertrait/src/cast/cast_ref.rs
  24. 28 0
      kernel/src/libs/intertrait/src/hasher.rs
  25. 584 0
      kernel/src/libs/intertrait/src/lib.rs
  26. 55 0
      kernel/src/libs/intertrait/tests/castable_to.rs
  27. 31 0
      kernel/src/libs/intertrait/tests/on-enum.rs
  28. 27 0
      kernel/src/libs/intertrait/tests/on-struct.rs
  29. 33 0
      kernel/src/libs/intertrait/tests/on-trait-impl-assoc-type1.rs
  30. 35 0
      kernel/src/libs/intertrait/tests/on-trait-impl-assoc-type2.rs
  31. 38 0
      kernel/src/libs/intertrait/tests/on-trait-impl-assoc-type3.rs
  32. 27 0
      kernel/src/libs/intertrait/tests/on-trait-impl.rs
  33. 54 0
      kernel/src/libs/intertrait/tests/on-type-multi-traits.rs
  34. 5 0
      kernel/src/libs/intertrait/tests/run.rs
  35. 27 0
      kernel/src/libs/intertrait/tests/ui/duplicate-flags.rs
  36. 5 0
      kernel/src/libs/intertrait/tests/ui/duplicate-flags.stderr
  37. 31 0
      kernel/src/libs/intertrait/tests/ui/on-generic-type.rs
  38. 5 0
      kernel/src/libs/intertrait/tests/ui/on-generic-type.stderr
  39. 14 0
      kernel/src/libs/intertrait/tests/ui/on-type-impl.rs
  40. 5 0
      kernel/src/libs/intertrait/tests/ui/on-type-impl.stderr
  41. 27 0
      kernel/src/libs/intertrait/tests/ui/unknown-flag.rs
  42. 5 0
      kernel/src/libs/intertrait/tests/ui/unknown-flag.stderr
  43. 1 0
      kernel/src/libs/mod.rs
  44. 26 0
      kernel/src/libs/rbtree.rs
  45. 2 0
      kernel/src/main.c
  46. 1 0
      kernel/src/mm/allocator/kernel_allocator.rs

+ 1 - 1
.vscode/settings.json

@@ -181,5 +181,5 @@
     "rust-analyzer.checkOnSave.allTargets": false,
     "rust-analyzer.linkedProjects": [
         "./kernel/Cargo.toml"
-    ]
+    ],
 }

+ 6 - 0
kernel/Cargo.toml

@@ -5,9 +5,13 @@ edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
+
 [lib]
 crate-type = ["staticlib"]
 
+[workspace]
+members = [ "src/libs/intertrait" ]
+
 # 运行时依赖项
 [dependencies]
 x86 = "0.52.0"
@@ -28,6 +32,8 @@ memoffset = "0.9.0"
 atomic_enum = "0.2.0"
 raw-cpuid = "11.0.1"
 acpi = "5.0.0"
+intertrait = { path = "src/libs/intertrait" }
+linkme = "0.2"
 
 # 构建时依赖项
 [build-dependencies]

+ 6 - 0
kernel/src/init/c_adapter.rs

@@ -0,0 +1,6 @@
+use super::init_intertrait;
+
+#[no_mangle]
+unsafe extern "C" fn rs_init_intertrait() {
+    init_intertrait();
+}

+ 5 - 0
kernel/src/init/mod.rs

@@ -0,0 +1,5 @@
+pub mod c_adapter;
+
+fn init_intertrait() {
+    intertrait::init_caster_map();
+}

+ 9 - 1
kernel/src/lib.rs

@@ -1,4 +1,3 @@
-#![no_std] // <1>
 #![no_main] // <1>
 #![feature(alloc_error_handler)]
 #![feature(allocator_api)]
@@ -15,6 +14,11 @@
 #![feature(trait_upcasting)]
 #![feature(slice_ptr_get)]
 #![feature(vec_into_raw_parts)]
+#![cfg_attr(target_os = "none", no_std)]
+
+#[cfg(test)]
+#[macro_use]
+extern crate std;
 
 #[allow(non_upper_case_globals)]
 #[allow(non_camel_case_types)]
@@ -31,6 +35,7 @@ mod include;
 mod driver; // 如果driver依赖了libs,应该在libs后面导出
 mod exception;
 mod filesystem;
+mod init;
 mod ipc;
 mod mm;
 mod net;
@@ -53,6 +58,8 @@ extern crate num;
 extern crate num_derive;
 extern crate smoltcp;
 extern crate thingbuf;
+#[macro_use]
+extern crate intertrait;
 #[cfg(target_arch = "x86_64")]
 extern crate x86;
 
@@ -65,6 +72,7 @@ use crate::process::ProcessManager;
 pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator;
 
 /// 全局的panic处理函数
+#[cfg(target_os = "none")]
 #[panic_handler]
 #[no_mangle]
 pub fn panic(info: &PanicInfo) -> ! {

+ 18 - 0
kernel/src/libs/intertrait/.gitignore

@@ -0,0 +1,18 @@
+# Cargo lock in subs
+**/Cargo.lock
+
+# Generated by Cargo
+**/target/
+
+**/*.rs.bk
+**/*.iml
+.idea/
+.vscode/
+/db/
+/snapshot/
+/log/
+/keys/
+/test/log/
+
+# macOS
+.DS_store

+ 27 - 0
kernel/src/libs/intertrait/Cargo.toml

@@ -0,0 +1,27 @@
+[package]
+name = "intertrait"
+version = "0.2.2"
+authors = ["CodeChain Team <[email protected]>"]
+license = "GPLv2(for code modified by dragonos) MIT OR Apache-2.0"
+description = "Allow for inter-trait casting"
+edition = "2018"
+repository = "https://github.com/CodeChain-io/intertrait"
+documentation = "https://docs.rs/intertrait"
+readme = "README.md"
+categories = ["rust-patterns"]
+keywords = ["trait", "cast", "any"]
+include = ["src/**/*", "Cargo.toml", "LICENSE-*", "README.md"]
+
+
+[dependencies]
+linkme = "0.2"
+hashbrown = "0.13.2"
+intertrait-macros = { version = "=0.2.2", path = "macros" }
+
+[target.'cfg(not(target_os = "none"))'.dependencies]
+once_cell = "1.4"
+
+[dev-dependencies]
+trybuild = "1.0"
+doc-comment = "0.3"
+

+ 17 - 0
kernel/src/libs/intertrait/LICENSE-MIT

@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 163 - 0
kernel/src/libs/intertrait/README.md

@@ -0,0 +1,163 @@
+# Intertrait
+
+We forked this lib from [intertrait](https://github.com/CodeChain-io/intertrait/) (revision d5d6dcb), and modified it to support `no_std` environment.
+
+## Notice
+
+The modified version is licensed under GPLv2 and later, while the original version is licensed under MIT/Apache license.(Codes modified by us are licensed under GPLv2 and later.)
+
+
+This library provides direct casting among trait objects implemented by a type.
+
+In Rust, a trait object for a sub-trait of [`std::any::Any`] can be downcast to a concrete type at runtime
+if the type is known. But no direct casting between two trait objects (i.e. without involving the concrete type
+of the backing value) is possible (even no coercion from a trait object for a trait to that for its super-trait yet).
+
+With this crate, any trait object for a sub-trait of [`CastFrom`] can be cast directly to a trait object
+for another trait implemented by the underlying type if the target traits are registered beforehand
+with the macros provided by this crate.
+
+# Dependencies
+Add the following two dependencies to your `Cargo.toml`:
+
+```toml
+[dependencies]
+intertrait = "0.2"
+linkme = "0.2"
+```
+
+The `linkme` dependency is required due to the use of `linkme` macro in the output of `intertrait` macros.
+
+# Usage
+
+```rust
+use intertrait::*;
+use intertrait::cast::*;
+
+struct Data;
+
+trait Source: CastFrom {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+#[cast_to]
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+impl Source for Data {}
+
+fn main() {
+    let data = Data;
+    let source: &dyn Source = &data;
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap().greet();
+}
+```
+
+Target traits must be explicitly designated beforehand. There are three ways of doing it:
+
+### `#[cast_to]` to `impl` item
+The trait implemented is designated as a target trait.
+
+```rust
+use intertrait::*;
+
+struct Data;
+trait Greet { fn greet(&self); }
+
+#[cast_to]
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+```
+
+### `#[cast_to(Trait)]` to type definition
+For the type, the traits specified as arguments to the `#[cast_to(...)]` attribute are designated as target traits.
+
+```rust
+use intertrait::*;
+
+trait Greet { fn greet(&self); }
+
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+#[cast_to(Greet, std::fmt::Debug)]
+#[derive(std::fmt::Debug)]
+struct Data;
+```
+
+### `castable_to!(Type => Trait1, Trait2)`
+For the type, the traits following `:` are designated as target traits.
+
+```rust
+use intertrait::*;
+
+#[derive(std::fmt::Debug)]
+struct Data;
+trait Greet { fn greet(&self); }
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+// Only in an item position due to the current limitation in the stable Rust.
+// https://github.com/rust-lang/rust/pull/68717
+castable_to!(Data => Greet, std::fmt::Debug);
+
+fn main() {}
+```
+
+## `Arc` Support
+`std::sync::Arc` is unique in that it implements `downcast` method only on `dyn Any + Send + Sync + 'static'.
+To use with `Arc`, the following steps should be taken:
+
+* Mark source traits with [`CastFromSync`] instead of [`CastFrom`]
+* Add `[sync]` flag to `#[cast_to]` and `castable_to!` as follows:
+  ```ignore
+  #[cast_to([sync])]
+  #[cast_to([sync] Trait1, Trait2)]
+  castable_to!(Type => [sync] Trait, Trait2);
+  ```
+
+# How it works
+First of all, [`CastFrom`] trait makes it possible to retrieve an object of [`std::any::Any`]
+from an object for a sub-trait of [`CastFrom`]. 
+
+And the macros provided by `intertrait` generates trampoline functions for downcasting a trait object
+for [`std::any::Any`] back to its concrete type and then creating a trait object for the target trait from it.
+
+Those trampoline functions are aggregated into a global registry
+using [`linkme`](https://github.com/dtolnay/linkme/) crate, which involves no (generally discouraged)
+life-before-main trick. The registry is keyed with a pair of [`TypeId`]s, which are those of the concrete type
+backing a trait object for a sub-trait of [`CastFrom`] and the target trait (the actual implementation
+is a bit different here, but conceptually so).
+
+In the course, it doesn't rely on any unstable Rust implementation details such as the layout of trait objects
+that may be changed in the future.
+
+# Credits
+`intertrait` has taken much of its core ideas from the great [`traitcast`](https://github.com/bch29/traitcast) crate.
+
+# License
+The modified version is licensed under GPLv2 and later, while the original version is licensed under MIT/Apache license.(Codes modified by us are licensed under GPLv2 and later.)
+
+Modified version(revision 0.2.0):
+ * GPLv2 and later (You can find the full text of the license in the root directory of this repository.)
+
+Original version(revision d5d6dcb):
+ * Apache License, Version 2.0
+   ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license
+   ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+

+ 23 - 0
kernel/src/libs/intertrait/macros/Cargo.toml

@@ -0,0 +1,23 @@
+[package]
+name = "intertrait-macros"
+description = "Macros for intertrait crate, which allows for direct casting between trait objects"
+version = "0.2.2"
+authors = ["CodeChain Team <[email protected]>"]
+license = "GPLv2(for code modified by dragonos) MIT OR Apache-2.0"
+edition = "2018"
+repository = "https://github.com/CodeChain-io/intertrait"
+include = ["src/**/*", "Cargo.toml", "LICENSE-*"]
+
+[lib]
+proc-macro = true
+
+[dependencies]
+hashbrown = "0.13.2"
+proc-macro2 = "1.0"
+syn = { version = "1.0", features = ["full"] }
+quote = "1.0"
+uuid = { version = "0.8", features = ["v4"] }
+
+[dev-dependencies]
+intertrait = { version = "=0.2.2", path = ".." }
+linkme = "0.2"

+ 176 - 0
kernel/src/libs/intertrait/macros/LICENSE-APACHE

@@ -0,0 +1,176 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS

+ 17 - 0
kernel/src/libs/intertrait/macros/LICENSE-MIT

@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 76 - 0
kernel/src/libs/intertrait/macros/src/args.rs

@@ -0,0 +1,76 @@
+use hashbrown::HashSet;
+use syn::bracketed;
+use syn::parse::{Parse, ParseStream, Result};
+use syn::punctuated::Punctuated;
+use syn::{Error, Ident, Path, Token, Type};
+
+#[derive(Hash, PartialEq, Eq)]
+pub enum Flag {
+    Sync,
+}
+
+impl Flag {
+    fn from(ident: &Ident) -> Result<Self> {
+        match ident.to_string().as_str() {
+            "sync" => Ok(Flag::Sync),
+            unknown => {
+                let msg = format!("Unknown flag: {}", unknown);
+                Err(Error::new_spanned(ident, msg))
+            }
+        }
+    }
+}
+
+pub struct Targets {
+    pub flags: HashSet<Flag>,
+    pub paths: Vec<Path>,
+}
+
+impl Parse for Targets {
+    fn parse(input: ParseStream) -> Result<Self> {
+        let mut flags = HashSet::new();
+        let mut paths = Vec::new();
+
+        if input.is_empty() {
+            return Ok(Targets { flags, paths });
+        }
+
+        if input.peek(syn::token::Bracket) {
+            let content;
+            bracketed!(content in input);
+            for ident in Punctuated::<Ident, Token![,]>::parse_terminated(&content)? {
+                if !flags.insert(Flag::from(&ident)?) {
+                    let msg = format!("Duplicated flag: {}", ident);
+                    return Err(Error::new_spanned(ident, msg));
+                }
+            }
+        }
+
+        if input.is_empty() {
+            return Ok(Targets { flags, paths });
+        }
+
+        paths = Punctuated::<Path, Token![,]>::parse_terminated(input)?
+            .into_iter()
+            .collect();
+
+        Ok(Targets { flags, paths })
+    }
+}
+
+pub struct Casts {
+    pub ty: Type,
+    pub targets: Targets,
+}
+
+impl Parse for Casts {
+    fn parse(input: ParseStream) -> Result<Self> {
+        let ty: Type = input.parse()?;
+        input.parse::<Token![=>]>()?;
+
+        Ok(Casts {
+            ty,
+            targets: input.parse()?,
+        })
+    }
+}

+ 64 - 0
kernel/src/libs/intertrait/macros/src/gen_caster.rs

@@ -0,0 +1,64 @@
+use core::str::from_utf8_unchecked;
+
+use proc_macro2::TokenStream;
+use uuid::adapter::Simple;
+use uuid::Uuid;
+
+use quote::format_ident;
+use quote::quote;
+use quote::ToTokens;
+
+pub fn generate_caster(ty: &impl ToTokens, trait_: &impl ToTokens, sync: bool) -> TokenStream {
+    let mut fn_buf = [0u8; FN_BUF_LEN];
+    let fn_ident = format_ident!("{}", new_fn_name(&mut fn_buf));
+    // 生成从dyn trait转换为具体类型结构体ty的caster
+    let new_caster = if sync {
+        quote! {
+            ::intertrait::Caster::<dyn #trait_>::new_sync(
+                |from| from.downcast_ref::<#ty>().unwrap(),
+                |from| from.downcast_mut::<#ty>().unwrap(),
+                |from| from.downcast::<#ty>().unwrap(),
+                |from| from.downcast::<#ty>().unwrap(),
+                |from| from.downcast::<#ty>().unwrap()
+            )
+        }
+    } else {
+        quote! {
+            ::intertrait::Caster::<dyn #trait_>::new(
+                |from| from.downcast_ref::<#ty>().unwrap(),
+                |from| from.downcast_mut::<#ty>().unwrap(),
+                |from| from.downcast::<#ty>().unwrap(),
+                |from| from.downcast::<#ty>().unwrap(),
+            )
+        }
+    };
+
+    // 由于过程宏是在预编译期执行的,这里的target_os是linux。
+    // 编译完成的proc macro会交给下一阶段进行编译,因此,#[cfg(target_os)]会在下一阶段生效。
+    // 我们必须在预处理阶段把两种代码的token stream都生成出来,然后在下一阶段选择性地使用其中一种。
+    quote! {
+
+        #[cfg(not(target_os = "none"))]
+        #[::linkme::distributed_slice(::intertrait::CASTERS)]
+        fn #fn_ident() -> (::std::any::TypeId, ::intertrait::BoxedCaster) {
+            (::std::any::TypeId::of::<#ty>(), Box::new(#new_caster))
+        }
+
+        #[cfg(target_os = "none")]
+        #[::linkme::distributed_slice(::intertrait::CASTERS)]
+        fn #fn_ident() -> (::core::any::TypeId, ::intertrait::BoxedCaster) {
+            (::core::any::TypeId::of::<#ty>(), alloc::boxed::Box::new(#new_caster))
+        }
+    }
+}
+
+const FN_PREFIX: &[u8] = b"__";
+const FN_BUF_LEN: usize = FN_PREFIX.len() + Simple::LENGTH;
+
+fn new_fn_name(buf: &mut [u8]) -> &str {
+    buf[..FN_PREFIX.len()].copy_from_slice(FN_PREFIX);
+    Uuid::new_v4()
+        .to_simple()
+        .encode_lower(&mut buf[FN_PREFIX.len()..]);
+    unsafe { from_utf8_unchecked(&buf[..FN_BUF_LEN]) }
+}

+ 82 - 0
kernel/src/libs/intertrait/macros/src/item_impl.rs

@@ -0,0 +1,82 @@
+use hashbrown::HashSet;
+use proc_macro2::TokenStream;
+use quote::{quote, quote_spanned, ToTokens};
+use syn::punctuated::Punctuated;
+use syn::spanned::Spanned;
+use syn::Token;
+use syn::{
+    AngleBracketedGenericArguments, Binding, GenericArgument, ImplItem, ItemImpl, Path,
+    PathArguments,
+};
+use PathArguments::AngleBracketed;
+
+use crate::args::Flag;
+use crate::gen_caster::generate_caster;
+
+pub fn process(flags: &HashSet<Flag>, input: ItemImpl) -> TokenStream {
+    let ItemImpl {
+        ref self_ty,
+        ref trait_,
+        ref items,
+        ..
+    } = input;
+
+    let generated = match trait_ {
+        None => quote_spanned! {
+            self_ty.span() => compile_error!("#[cast_to] should only be on an impl of a trait");
+        },
+        Some(trait_) => match trait_ {
+            (Some(bang), _, _) => quote_spanned! {
+                bang.span() => compile_error!("#[cast_to] is not for !Trait impl");
+            },
+            (None, path, _) => {
+                let path = fully_bound_trait(path, items);
+                generate_caster(self_ty, &path, flags.contains(&Flag::Sync))
+            }
+        },
+    };
+
+    quote! {
+        #input
+        #generated
+    }
+}
+
+fn fully_bound_trait(path: &Path, items: &[ImplItem]) -> impl ToTokens {
+    let bindings = items
+        .iter()
+        .filter_map(|item| {
+            if let ImplItem::Type(assoc_ty) = item {
+                Some(GenericArgument::Binding(Binding {
+                    ident: assoc_ty.ident.to_owned(),
+                    eq_token: Default::default(),
+                    ty: assoc_ty.ty.to_owned(),
+                }))
+            } else {
+                None
+            }
+        })
+        .collect::<Punctuated<_, Token![,]>>();
+
+    let mut path = path.clone();
+
+    if bindings.is_empty() {
+        return path;
+    }
+
+    if let Some(last) = path.segments.last_mut() {
+        match &mut last.arguments {
+            PathArguments::None => {
+                last.arguments = AngleBracketed(AngleBracketedGenericArguments {
+                    colon2_token: None,
+                    lt_token: Default::default(),
+                    args: bindings,
+                    gt_token: Default::default(),
+                })
+            }
+            AngleBracketed(args) => args.args.extend(bindings),
+            _ => {}
+        }
+    }
+    path
+}

+ 31 - 0
kernel/src/libs/intertrait/macros/src/item_type.rs

@@ -0,0 +1,31 @@
+use hashbrown::HashSet;
+use proc_macro2::TokenStream;
+use syn::spanned::Spanned;
+use syn::{DeriveInput, Path};
+
+use quote::{quote, quote_spanned};
+
+use crate::args::Flag;
+use crate::gen_caster::generate_caster;
+
+pub fn process(flags: &HashSet<Flag>, paths: Vec<Path>, input: DeriveInput) -> TokenStream {
+    let DeriveInput {
+        ref ident,
+        ref generics,
+        ..
+    } = input;
+    let generated = if generics.lt_token.is_some() {
+        quote_spanned! {
+            generics.span() => compile_error!("#[cast_to(..)] can't be used on a generic type definition");
+        }
+    } else {
+        paths
+            .into_iter()
+            .flat_map(|t| generate_caster(ident, &t, flags.contains(&Flag::Sync)))
+            .collect()
+    };
+    quote! {
+        #input
+        #generated
+    }
+}

+ 145 - 0
kernel/src/libs/intertrait/macros/src/lib.rs

@@ -0,0 +1,145 @@
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+use syn::{parse, parse_macro_input, DeriveInput, ItemImpl};
+
+use args::{Casts, Flag, Targets};
+use gen_caster::generate_caster;
+
+mod args;
+mod gen_caster;
+mod item_impl;
+mod item_type;
+
+/// Attached on an `impl` item or type definition, registers traits as targets for casting.
+///
+/// If on an `impl` item, no argument is allowed. But on a type definition, the target traits
+/// must be listed explicitly.
+///
+/// Add `[sync]` before the list of traits if the underlying type is `Sync + Send` and you
+/// need `std::sync::Arc`.
+///
+/// # Examples
+/// ## On a trait impl
+/// ```
+/// use intertrait::*;
+///
+/// struct Data;
+///
+/// trait Greet {
+///     fn greet(&self);
+/// }
+///
+/// // Greet can be cast into from any sub-trait of CastFrom implemented by Data.
+/// #[cast_to]
+/// impl Greet for Data {
+///     fn greet(&self) {
+///         println!("Hello");
+///     }
+/// }
+/// ```
+///
+/// ## On a type definition
+/// Use when a target trait is derived or implemented in an external crate.
+/// ```
+/// use intertrait::*;
+///
+/// // Debug can be cast into from any sub-trait of CastFrom implemented by Data
+/// #[cast_to(std::fmt::Debug)]
+/// #[derive(std::fmt::Debug)]
+/// struct Data;
+/// ```
+///
+/// ## For Arc
+/// Use when the underlying type is `Sync + Send` and you want to use `Arc`.
+/// ```
+/// use intertrait::*;
+///
+/// // Debug can be cast into from any sub-trait of CastFrom implemented by Data
+/// #[cast_to([sync] std::fmt::Debug)]
+/// #[derive(std::fmt::Debug)]
+/// struct Data;
+/// ```
+
+#[proc_macro_attribute]
+pub fn cast_to(args: TokenStream, input: TokenStream) -> TokenStream {
+    match parse::<Targets>(args) {
+        Ok(Targets { flags, paths }) => {
+            if paths.is_empty() {
+                item_impl::process(&flags, parse_macro_input!(input as ItemImpl))
+            } else {
+                item_type::process(&flags, paths, parse_macro_input!(input as DeriveInput))
+            }
+        }
+        Err(err) => vec![err.to_compile_error(), input.into()]
+            .into_iter()
+            .collect(),
+    }
+    .into()
+}
+
+/// Declares target traits for casting implemented by a type.
+///
+/// This macro is for registering both a concrete type and its traits to be targets for casting.
+/// Useful when the type definition and the trait implementations are in an external crate.
+///
+/// **Note**: this macro cannot be used in an expression or statement prior to Rust 1.45.0,
+/// due to [a previous limitation](https://github.com/rust-lang/rust/pull/68717).
+/// If you want to use it in an expression or statement, use Rust 1.45.0 or later.
+///
+/// # Examples
+/// ```
+/// use intertrait::*;
+///
+/// #[derive(std::fmt::Debug)]
+/// enum Data {
+///     A, B, C
+/// }
+/// trait Greet {
+///     fn greet(&self);
+/// }
+/// impl Greet for Data {
+///     fn greet(&self) {
+///         println!("Hello");
+///     }
+/// }
+///
+/// castable_to! { Data => std::fmt::Debug, Greet }
+///
+/// # fn main() {}
+/// ```
+///
+/// When the type is `Sync + Send` and is used with `Arc`:
+/// ```
+/// use intertrait::*;
+///
+/// #[derive(std::fmt::Debug)]
+/// enum Data {
+///     A, B, C
+/// }
+/// trait Greet {
+///     fn greet(&self);
+/// }
+/// impl Greet for Data {
+///     fn greet(&self) {
+///         println!("Hello");
+///     }
+/// }
+/// castable_to! { Data => [sync] std::fmt::Debug, Greet }
+///
+/// # fn main() {}
+/// ```
+#[proc_macro]
+pub fn castable_to(input: TokenStream) -> TokenStream {
+    let Casts {
+        ty,
+        targets: Targets { flags, paths },
+    } = parse_macro_input!(input);
+
+    paths
+        .iter()
+        .map(|t| generate_caster(&ty, t, flags.contains(&Flag::Sync)))
+        .collect::<proc_macro2::TokenStream>()
+        .into()
+}

+ 21 - 0
kernel/src/libs/intertrait/src/cast.rs

@@ -0,0 +1,21 @@
+//! `cast` module contains traits to provide `cast` method for various references
+//! and smart pointers.
+//!
+//! In source files requiring casts, import all of the traits as follows:
+//!
+//! ```ignore
+//! use intertrait::cast::*;
+//! ```
+//!
+//! Since there exists single trait for each receiver type, the same `cast` method is overloaded.
+mod cast_arc;
+mod cast_box;
+mod cast_mut;
+mod cast_rc;
+mod cast_ref;
+
+pub use cast_arc::*;
+pub use cast_box::*;
+pub use cast_mut::*;
+pub use cast_rc::*;
+pub use cast_ref::*;

+ 45 - 0
kernel/src/libs/intertrait/src/cast/cast_arc.rs

@@ -0,0 +1,45 @@
+use alloc::sync::Arc;
+
+use crate::{caster, CastFromSync};
+
+/// A trait that is blanket-implemented for traits extending `CastFrom` to allow for casting
+/// of a trait object for it behind an `Rc` to a trait object for another trait
+/// implemented by the underlying value.
+///
+/// # Examples
+/// ```
+/// # use std::sync::Arc;
+/// # use intertrait::*;
+/// use intertrait::cast::*;
+///
+/// # #[cast_to([sync] Greet)]
+/// # struct Data;
+/// # trait Source: CastFrom {}
+/// # trait Greet {
+/// #     fn greet(&self);
+/// # }
+/// # impl Greet for Data {
+/// #    fn greet(&self) {
+/// #        println!("Hello");
+/// #    }
+/// # }
+/// impl Source for Data {}
+/// let data = Data;
+/// let source = Arc::new(data);
+/// let greet = source.cast::<dyn Greet>();
+/// greet.unwrap_or_else(|_| panic!("must not happen")).greet();
+/// ```
+pub trait CastArc {
+    /// Casts an `Arc` for this trait into that for type `T`.
+    fn cast<T: ?Sized + 'static>(self: Arc<Self>) -> Result<Arc<T>, Arc<Self>>;
+}
+
+/// A blanket implementation of `CastArc` for traits extending `CastFrom`, `Sync`, and `Send`.
+impl<S: ?Sized + CastFromSync> CastArc for S {
+    fn cast<T: ?Sized + 'static>(self: Arc<Self>) -> Result<Arc<T>, Arc<Self>> {
+        match caster::<T>((*self).type_id()) {
+            Some(caster) => Ok((caster.cast_arc)(self.arc_any())),
+            None => Err(self),
+        }
+    }
+}

+ 44 - 0
kernel/src/libs/intertrait/src/cast/cast_box.rs

@@ -0,0 +1,44 @@
+use alloc::boxed::Box;
+
+use crate::{caster, CastFrom};
+
+/// A trait that is blanket-implemented for traits extending `CastFrom` to allow for casting
+/// of a trait object for it behind a `Box` to a trait object for another trait
+/// implemented by the underlying value.
+///
+/// # Examples
+/// ```
+/// # use intertrait::*;
+/// use intertrait::cast::*;
+///
+/// # #[cast_to(Greet)]
+/// # struct Data;
+/// # trait Source: CastFrom {}
+/// # trait Greet {
+/// #     fn greet(&self);
+/// # }
+/// # impl Greet for Data {
+/// #    fn greet(&self) {
+/// #        println!("Hello");
+/// #    }
+/// # }
+/// impl Source for Data {}
+/// let data = Box::new(Data);
+/// let source: Box<dyn Source> = data;
+/// let greet = source.cast::<dyn Greet>();
+/// greet.unwrap_or_else(|_| panic!("casting failed")).greet();
+/// ```
+pub trait CastBox {
+    /// Casts a box to this trait into that of type `T`. If fails, returns the receiver.
+    fn cast<T: ?Sized + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>>;
+}
+
+/// A blanket implementation of `CastBox` for traits extending `CastFrom`.
+impl<S: ?Sized + CastFrom> CastBox for S {
+    fn cast<T: ?Sized + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
+        match caster::<T>((*self).type_id()) {
+            Some(caster) => Ok((caster.cast_box)(self.box_any())),
+            None => Err(self),
+        }
+    }
+}

+ 41 - 0
kernel/src/libs/intertrait/src/cast/cast_mut.rs

@@ -0,0 +1,41 @@
+use crate::{caster, CastFrom};
+
+/// A trait that is blanket-implemented for traits extending `CastFrom` to allow for casting
+/// of a trait object for it behind an mutable reference to a trait object for another trait
+/// implemented by the underlying value.
+///
+/// # Examples
+/// ```
+/// # use intertrait::*;
+/// use intertrait::cast::*;
+///
+/// # #[cast_to(Greet)]
+/// # struct Data;
+/// # trait Source: CastFrom {}
+/// # trait Greet {
+/// #     fn greet(&self);
+/// # }
+/// # impl Greet for Data {
+/// #    fn greet(&self) {
+/// #        println!("Hello");
+/// #    }
+/// # }
+/// impl Source for Data {}
+/// let mut data = Data;
+/// let source: &mut dyn Source = &mut data;
+/// let greet = source.cast::<dyn Greet>();
+/// greet.unwrap().greet();
+/// ```
+pub trait CastMut {
+    /// Casts a mutable reference to this trait into that of type `T`.
+    fn cast<T: ?Sized + 'static>(&mut self) -> Option<&mut T>;
+}
+
+/// A blanket implementation of `CastMut` for traits extending `CastFrom`.
+impl<S: ?Sized + CastFrom> CastMut for S {
+    fn cast<T: ?Sized + 'static>(&mut self) -> Option<&mut T> {
+        let any = self.mut_any();
+        let caster = caster::<T>((*any).type_id())?;
+        (caster.cast_mut)(any).into()
+    }
+}

+ 44 - 0
kernel/src/libs/intertrait/src/cast/cast_rc.rs

@@ -0,0 +1,44 @@
+use crate::{caster, CastFrom};
+use alloc::rc::Rc;
+
+/// A trait that is blanket-implemented for traits extending `CastFrom` to allow for casting
+/// of a trait object for it behind an `Rc` to a trait object for another trait
+/// implemented by the underlying value.
+///
+/// # Examples
+/// ```
+/// # use std::rc::Rc;
+/// # use intertrait::*;
+/// use intertrait::cast::*;
+///
+/// # #[cast_to(Greet)]
+/// # struct Data;
+/// # trait Source: CastFrom {}
+/// # trait Greet {
+/// #     fn greet(&self);
+/// # }
+/// # impl Greet for Data {
+/// #    fn greet(&self) {
+/// #        println!("Hello");
+/// #    }
+/// # }
+/// impl Source for Data {}
+/// let data = Data;
+/// let source = Rc::new(data);
+/// let greet = source.cast::<dyn Greet>();
+/// greet.unwrap_or_else(|_| panic!("must not happen")).greet();
+/// ```
+pub trait CastRc {
+    /// Casts an `Rc` for this trait into that for type `T`.
+    fn cast<T: ?Sized + 'static>(self: Rc<Self>) -> Result<Rc<T>, Rc<Self>>;
+}
+
+/// A blanket implementation of `CastRc` for traits extending `CastFrom`.
+impl<S: ?Sized + CastFrom> CastRc for S {
+    fn cast<T: ?Sized + 'static>(self: Rc<Self>) -> Result<Rc<T>, Rc<Self>> {
+        match caster::<T>((*self).type_id()) {
+            Some(caster) => Ok((caster.cast_rc)(self.rc_any())),
+            None => Err(self),
+        }
+    }
+}

+ 84 - 0
kernel/src/libs/intertrait/src/cast/cast_ref.rs

@@ -0,0 +1,84 @@
+use core::any::TypeId;
+
+use crate::{caster, CastFrom, Caster};
+
+/// A trait that is blanket-implemented for traits extending `CastFrom` to allow for casting
+/// of a trait object for it behind an immutable reference to a trait object for another trait
+/// implemented by the underlying value.
+///
+/// # Examples
+/// ## Casting an immutable reference
+/// ```
+/// # use intertrait::*;
+/// use intertrait::cast::*;
+///
+/// # #[cast_to(Greet)]
+/// # struct Data;
+/// # trait Source: CastFrom {}
+/// # trait Greet {
+/// #     fn greet(&self);
+/// # }
+/// # impl Greet for Data {
+/// #    fn greet(&self) {
+/// #        println!("Hello");
+/// #    }
+/// # }
+/// impl Source for Data {}
+/// let data = Data;
+/// let source: &dyn Source = &data;
+/// let greet = source.cast::<dyn Greet>();
+/// greet.unwrap().greet();
+/// ```
+///
+/// ## Testing if a cast is possible
+/// ```
+/// # use intertrait::*;
+/// use intertrait::cast::*;
+///
+/// # #[cast_to(Greet)]
+/// # struct Data;
+/// # trait Source: CastFrom {}
+/// # trait Greet {
+/// #     fn greet(&self);
+/// # }
+/// # impl Greet for Data {
+/// #    fn greet(&self) {
+/// #        println!("Hello");
+/// #    }
+/// # }
+/// impl Source for Data {}
+/// let data = Data;
+/// let source: &dyn Source = &data;
+/// assert!(source.impls::<dyn Greet>());
+/// assert!(!source.impls::<dyn std::fmt::Debug>());
+/// ```
+pub trait CastRef {
+    /// Casts a reference to this trait into that of type `T`.
+    fn cast<T: ?Sized + 'static>(&self) -> Option<&T>;
+
+    /// Tests if this trait object can be cast into `T`.
+    fn impls<T: ?Sized + 'static>(&self) -> bool;
+}
+
+/// A blanket implementation of `CastRef` for traits extending `CastFrom`.
+impl<S: ?Sized + CastFrom> CastRef for S {
+    fn cast<T: ?Sized + 'static>(&self) -> Option<&T> {
+        let any = self.ref_any();
+        // 获取从 self 到 T 的转换器,如果不存在则返回 None
+        let caster = caster::<T>(any.type_id())?;
+        (caster.cast_ref)(any).into()
+    }
+
+    #[cfg(not(target_os = "none"))]
+    fn impls<T: ?Sized + 'static>(&self) -> bool {
+        use crate::CASTER_MAP;
+        CASTER_MAP.contains_key(&(self.type_id(), TypeId::of::<Caster<T>>()))
+    }
+
+    #[cfg(target_os = "none")]
+    fn impls<T: ?Sized + 'static>(&self) -> bool {
+        use crate::caster_map;
+
+        caster_map().contains_key(&(self.type_id(), TypeId::of::<Caster<T>>()))
+    }
+}

+ 28 - 0
kernel/src/libs/intertrait/src/hasher.rs

@@ -0,0 +1,28 @@
+use core::convert::TryInto;
+use core::hash::{BuildHasherDefault, Hasher};
+use core::mem::size_of;
+
+/// A simple `Hasher` implementation tuned for performance.
+#[derive(Default)]
+pub struct FastHasher(u64);
+
+/// A `BuildHasher` for `FastHasher`.
+pub type BuildFastHasher = BuildHasherDefault<FastHasher>;
+
+impl Hasher for FastHasher {
+    fn finish(&self) -> u64 {
+        self.0
+    }
+
+    fn write(&mut self, bytes: &[u8]) {
+        let mut bytes = bytes;
+        while bytes.len() > size_of::<u64>() {
+            let (u64_bytes, remaining) = bytes.split_at(size_of::<u64>());
+            self.0 ^= u64::from_ne_bytes(u64_bytes.try_into().unwrap());
+            bytes = remaining
+        }
+        self.0 ^= bytes
+            .iter()
+            .fold(0u64, |result, b| (result << 8) | *b as u64);
+    }
+}

+ 584 - 0
kernel/src/libs/intertrait/src/lib.rs

@@ -0,0 +1,584 @@
+//! A library providing direct casting among trait objects implemented by a type.
+//!
+//! In Rust, an object of a sub-trait of [`Any`] can be downcast to a concrete type
+//! at runtime if the type is known. But no direct casting between two trait objects
+//! (i.e. without involving the concrete type of the backing value) is possible
+//! (even no coercion from a trait object to that of its super-trait yet).
+//!
+//! With this crate, any trait object with [`CastFrom`] as its super-trait can be cast directly
+//! to another trait object implemented by the underlying type if the target traits are
+//! registered beforehand with the macros provided by this crate.
+//!
+//! # Usage
+//! ```
+//! use intertrait::*;
+//! use intertrait::cast::*;
+//!
+//! struct Data;
+//!
+//! trait Source: CastFrom {}
+//!
+//! trait Greet {
+//!     fn greet(&self);
+//! }
+//!
+//! #[cast_to]
+//! impl Greet for Data {
+//!     fn greet(&self) {
+//!         println!("Hello");
+//!     }
+//! }
+//!
+//! impl Source for Data {}
+//!
+//! let data = Data;
+//! let source: &dyn Source = &data;
+//! let greet = source.cast::<dyn Greet>();
+//! greet.unwrap().greet();
+//! ```
+//!
+//! Target traits must be explicitly designated beforehand. There are three ways to do it:
+//!
+//! * [`#[cast_to]`][cast_to] to `impl` item
+//! * [`#[cast_to(Trait)]`][cast_to] to type definition
+//! * [`castable_to!(Type => Trait1, Trait2)`][castable_to]
+//!
+//! If the underlying type involved is `Sync + Send` and you want to use it with [`Arc`],
+//! use [`CastFromSync`] in place of [`CastFrom`] and add `[sync]` flag before the list
+//! of traits in the macros. Refer to the documents for each of macros for details.
+//!
+//! For casting, refer to traits defined in [`cast`] module.
+//!
+//! [cast_to]: ./attr.cast_to.html
+//! [castable_to]: ./macro.castable_to.html
+//! [`CastFrom`]: ./trait.CastFrom.html
+//! [`CastFromSync`]: ./trait.CastFromSync.html
+//! [`cast`]: ./cast/index.html
+//! [`Any`]: https://doc.rust-lang.org/std/any/trait.Any.html
+//! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
+
+#![cfg_attr(target_os = "none", no_std)]
+
+extern crate alloc;
+extern crate core;
+
+use core::{
+    any::{Any, TypeId},
+    marker::{Send, Sync},
+};
+
+use alloc::boxed::Box;
+use alloc::rc::Rc;
+use alloc::sync::Arc;
+
+use hashbrown::HashMap;
+use linkme::distributed_slice;
+
+pub use intertrait_macros::*;
+
+use crate::hasher::BuildFastHasher;
+
+pub mod cast;
+mod hasher;
+
+#[doc(hidden)]
+pub type BoxedCaster = Box<dyn Any + Send + Sync>;
+
+#[cfg(doctest)]
+doc_comment::doctest!("../README.md");
+
+/// A distributed slice gathering constructor functions for [`Caster<T>`]s.
+///
+/// A constructor function returns `TypeId` of a concrete type involved in the casting
+/// and a `Box` of a trait object backed by a [`Caster<T>`].
+///
+/// [`Caster<T>`]: ./struct.Caster.html
+#[doc(hidden)]
+#[distributed_slice]
+pub static CASTERS: [fn() -> (TypeId, BoxedCaster)] = [..];
+
+/// A `HashMap` mapping `TypeId` of a [`Caster<T>`] to an instance of it.
+///
+/// [`Caster<T>`]: ./struct.Caster.html
+#[cfg(not(target_os = "none"))]
+static CASTER_MAP: once_cell::sync::Lazy<HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher>> =
+    once_cell::sync::Lazy::new(|| {
+        CASTERS
+            .iter()
+            .map(|f| {
+                let (type_id, caster) = f();
+                ((type_id, (*caster).type_id()), caster)
+            })
+            .collect()
+    });
+
+/// CasterMap
+///
+/// key.0: type_id of source
+/// key.1: type_id of target
+///
+/// value: A BoxedCaster which can cast source to target
+#[cfg(target_os = "none")]
+static mut CASTER_MAP: Option<HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher>> = None;
+
+#[cfg(target_os = "none")]
+pub fn caster_map() -> &'static HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher> {
+    return unsafe {
+        CASTER_MAP.as_ref().unwrap_or_else(|| {
+            panic!("intertrait_caster_map() must be called after CASTER_MAP is initialized")
+        })
+    };
+}
+
+/// Initializes the global [`CASTER_MAP`] with [`CASTERS`].
+///
+/// no_std环境下,需要手动调用此函数初始化CASTER_MAP
+#[cfg(target_os = "none")]
+pub fn init_caster_map() {
+    use core::sync::atomic::AtomicBool;
+
+    let pd = AtomicBool::new(false);
+    let r = pd.compare_exchange(
+        false,
+        true,
+        core::sync::atomic::Ordering::SeqCst,
+        core::sync::atomic::Ordering::SeqCst,
+    );
+
+    if r.is_err() {
+        panic!("init_caster_map() must be called only once");
+    }
+
+    let hashmap = CASTERS
+        .iter()
+        .map(|f| {
+            let (type_id, caster) = f();
+            ((type_id, (*caster).type_id()), caster)
+        })
+        .collect();
+
+    unsafe { CASTER_MAP = Some(hashmap) };
+}
+
+fn cast_arc_panic<T: ?Sized + 'static>(_: Arc<dyn Any + Sync + Send>) -> Arc<T> {
+    panic!("Prepend [sync] to the list of target traits for Sync + Send types")
+}
+
+/// A `Caster` knows how to cast a reference to or `Box` of a trait object for `Any`
+/// to a trait object of trait `T`. Each `Caster` instance is specific to a concrete type.
+/// That is, it knows how to cast to single specific trait implemented by single specific type.
+///
+/// An implementation of a trait for a concrete type doesn't need to manually provide
+/// a `Caster`. Instead attach `#[cast_to]` to the `impl` block.
+#[doc(hidden)]
+pub struct Caster<T: ?Sized + 'static> {
+    /// Casts an immutable reference to a trait object for `Any` to a reference
+    /// to a trait object for trait `T`.
+    pub cast_ref: fn(from: &dyn Any) -> &T,
+
+    /// Casts a mutable reference to a trait object for `Any` to a mutable reference
+    /// to a trait object for trait `T`.
+    pub cast_mut: fn(from: &mut dyn Any) -> &mut T,
+
+    /// Casts a `Box` holding a trait object for `Any` to another `Box` holding a trait object
+    /// for trait `T`.
+    pub cast_box: fn(from: Box<dyn Any>) -> Box<T>,
+
+    /// Casts an `Rc` holding a trait object for `Any` to another `Rc` holding a trait object
+    /// for trait `T`.
+    pub cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
+
+    /// Casts an `Arc` holding a trait object for `Any + Sync + Send + 'static`
+    /// to another `Arc` holding a trait object for trait `T`.
+    pub cast_arc: fn(from: Arc<dyn Any + Sync + Send + 'static>) -> Arc<T>,
+}
+
+impl<T: ?Sized + 'static> Caster<T> {
+    pub fn new(
+        cast_ref: fn(from: &dyn Any) -> &T,
+        cast_mut: fn(from: &mut dyn Any) -> &mut T,
+        cast_box: fn(from: Box<dyn Any>) -> Box<T>,
+        cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
+    ) -> Caster<T> {
+        Caster::<T> {
+            cast_ref,
+            cast_mut,
+            cast_box,
+            cast_rc,
+            cast_arc: cast_arc_panic,
+        }
+    }
+
+    pub fn new_sync(
+        cast_ref: fn(from: &dyn Any) -> &T,
+        cast_mut: fn(from: &mut dyn Any) -> &mut T,
+        cast_box: fn(from: Box<dyn Any>) -> Box<T>,
+        cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
+        cast_arc: fn(from: Arc<dyn Any + Sync + Send>) -> Arc<T>,
+    ) -> Caster<T> {
+        Caster::<T> {
+            cast_ref,
+            cast_mut,
+            cast_box,
+            cast_rc,
+            cast_arc,
+        }
+    }
+}
+
+/// Returns a `Caster<S, T>` from a concrete type `S` to a trait `T` implemented by it.
+///
+/// ## 参数
+///
+/// - type_id: 源类型的type_id
+///
+/// T: 目标trait
+fn caster<T: ?Sized + 'static>(type_id: TypeId) -> Option<&'static Caster<T>> {
+    #[cfg(not(target_os = "none"))]
+    {
+        CASTER_MAP
+            .get(&(type_id, TypeId::of::<Caster<T>>()))
+            .and_then(|caster| caster.downcast_ref::<Caster<T>>())
+    }
+
+    #[cfg(target_os = "none")]
+    {
+        caster_map()
+            .get(&(type_id, TypeId::of::<Caster<T>>()))
+            .and_then(|caster| caster.downcast_ref::<Caster<T>>())
+    }
+}
+
+/// `CastFrom` must be extended by a trait that wants to allow for casting into another trait.
+///
+/// It is used for obtaining a trait object for [`Any`] from a trait object for its sub-trait,
+/// and blanket implemented for all `Sized + Any + 'static` types.
+///
+/// # Examples
+/// ```ignore
+/// trait Source: CastFrom {
+///     ...
+/// }
+/// ```
+pub trait CastFrom: Any + 'static {
+    /// Returns a immutable reference to `Any`, which is backed by the type implementing this trait.
+    fn ref_any(&self) -> &dyn Any;
+
+    /// Returns a mutable reference to `Any`, which is backed by the type implementing this trait.
+    fn mut_any(&mut self) -> &mut dyn Any;
+
+    /// Returns a `Box` of `Any`, which is backed by the type implementing this trait.
+    fn box_any(self: Box<Self>) -> Box<dyn Any>;
+
+    /// Returns an `Rc` of `Any`, which is backed by the type implementing this trait.
+    fn rc_any(self: Rc<Self>) -> Rc<dyn Any>;
+}
+
+/// `CastFromSync` must be extended by a trait that is `Any + Sync + Send + 'static`
+/// and wants to allow for casting into another trait behind references and smart pointers
+/// especially including `Arc`.
+///
+/// It is used for obtaining a trait object for [`Any + Sync + Send + 'static`] from an object
+/// for its sub-trait, and blanket implemented for all `Sized + Sync + Send + 'static` types.
+///
+/// # Examples
+/// ```ignore
+/// trait Source: CastFromSync {
+///     ...
+/// }
+/// ```
+pub trait CastFromSync: CastFrom + Sync + Send + 'static {
+    fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static>;
+}
+
+impl<T: Sized + Any + 'static> CastFrom for T {
+    fn ref_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn mut_any(&mut self) -> &mut dyn Any {
+        self
+    }
+
+    fn box_any(self: Box<Self>) -> Box<dyn Any> {
+        self
+    }
+
+    fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
+        self
+    }
+}
+
+impl CastFrom for dyn Any + 'static {
+    fn ref_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn mut_any(&mut self) -> &mut dyn Any {
+        self
+    }
+
+    fn box_any(self: Box<Self>) -> Box<dyn Any> {
+        self
+    }
+
+    fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
+        self
+    }
+}
+
+impl<T: Sized + Sync + Send + 'static> CastFromSync for T {
+    fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static> {
+        self
+    }
+}
+
+impl CastFrom for dyn Any + Sync + Send + 'static {
+    fn ref_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn mut_any(&mut self) -> &mut dyn Any {
+        self
+    }
+
+    fn box_any(self: Box<Self>) -> Box<dyn Any> {
+        self
+    }
+
+    fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
+        self
+    }
+}
+
+impl CastFromSync for dyn Any + Sync + Send + 'static {
+    fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static> {
+        self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    extern crate std;
+    use std::any::{Any, TypeId};
+    use std::fmt::{Debug, Display};
+
+    use linkme::distributed_slice;
+
+    use crate::{BoxedCaster, CastFromSync};
+
+    use super::cast::*;
+    use super::*;
+
+    #[distributed_slice(super::CASTERS)]
+    static TEST_CASTER: fn() -> (TypeId, BoxedCaster) = create_test_caster;
+
+    #[derive(Debug)]
+    struct TestStruct;
+
+    trait SourceTrait: CastFromSync {}
+
+    impl SourceTrait for TestStruct {}
+
+    fn create_test_caster() -> (TypeId, BoxedCaster) {
+        let type_id = TypeId::of::<TestStruct>();
+        let caster = Box::new(Caster::<dyn Debug> {
+            cast_ref: |from| from.downcast_ref::<TestStruct>().unwrap(),
+            cast_mut: |from| from.downcast_mut::<TestStruct>().unwrap(),
+            cast_box: |from| from.downcast::<TestStruct>().unwrap(),
+            cast_rc: |from| from.downcast::<TestStruct>().unwrap(),
+            cast_arc: |from| from.downcast::<TestStruct>().unwrap(),
+        });
+        (type_id, caster)
+    }
+
+    #[test]
+    fn cast_ref() {
+        let ts = TestStruct;
+        let st: &dyn SourceTrait = &ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_some());
+    }
+
+    #[test]
+    fn cast_mut() {
+        let mut ts = TestStruct;
+        let st: &mut dyn SourceTrait = &mut ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_some());
+    }
+
+    #[test]
+    fn cast_box() {
+        let ts = Box::new(TestStruct);
+        let st: Box<dyn SourceTrait> = ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_ok());
+    }
+
+    #[test]
+    fn cast_rc() {
+        let ts = Rc::new(TestStruct);
+        let st: Rc<dyn SourceTrait> = ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_ok());
+    }
+
+    #[test]
+    fn cast_arc() {
+        let ts = Arc::new(TestStruct);
+        let st: Arc<dyn SourceTrait> = ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_ok());
+    }
+
+    #[test]
+    fn cast_ref_wrong() {
+        let ts = TestStruct;
+        let st: &dyn SourceTrait = &ts;
+        let display = st.cast::<dyn Display>();
+        assert!(display.is_none());
+    }
+
+    #[test]
+    fn cast_mut_wrong() {
+        let mut ts = TestStruct;
+        let st: &mut dyn SourceTrait = &mut ts;
+        let display = st.cast::<dyn Display>();
+        assert!(display.is_none());
+    }
+
+    #[test]
+    fn cast_box_wrong() {
+        let ts = Box::new(TestStruct);
+        let st: Box<dyn SourceTrait> = ts;
+        let display = st.cast::<dyn Display>();
+        assert!(display.is_err());
+    }
+
+    #[test]
+    fn cast_rc_wrong() {
+        let ts = Rc::new(TestStruct);
+        let st: Rc<dyn SourceTrait> = ts;
+        let display = st.cast::<dyn Display>();
+        assert!(display.is_err());
+    }
+
+    #[test]
+    fn cast_arc_wrong() {
+        let ts = Arc::new(TestStruct);
+        let st: Arc<dyn SourceTrait> = ts;
+        let display = st.cast::<dyn Display>();
+        assert!(display.is_err());
+    }
+
+    #[test]
+    fn cast_ref_from_any() {
+        let ts = TestStruct;
+        let st: &dyn Any = &ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_some());
+    }
+
+    #[test]
+    fn cast_mut_from_any() {
+        let mut ts = TestStruct;
+        let st: &mut dyn Any = &mut ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_some());
+    }
+
+    #[test]
+    fn cast_box_from_any() {
+        let ts = Box::new(TestStruct);
+        let st: Box<dyn Any> = ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_ok());
+    }
+
+    #[test]
+    fn cast_rc_from_any() {
+        let ts = Rc::new(TestStruct);
+        let st: Rc<dyn Any> = ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_ok());
+    }
+
+    #[test]
+    fn cast_arc_from_any() {
+        let ts = Arc::new(TestStruct);
+        let st: Arc<dyn Any + Send + Sync> = ts;
+        let debug = st.cast::<dyn Debug>();
+        assert!(debug.is_ok());
+    }
+
+    #[test]
+    fn impls_ref() {
+        let ts = TestStruct;
+        let st: &dyn SourceTrait = &ts;
+        assert!(st.impls::<dyn Debug>());
+    }
+
+    #[test]
+    fn impls_mut() {
+        let mut ts = TestStruct;
+        let st: &mut dyn SourceTrait = &mut ts;
+        assert!((*st).impls::<dyn Debug>());
+    }
+
+    #[test]
+    fn impls_box() {
+        let ts = Box::new(TestStruct);
+        let st: Box<dyn SourceTrait> = ts;
+        assert!((*st).impls::<dyn Debug>());
+    }
+
+    #[test]
+    fn impls_rc() {
+        let ts = Rc::new(TestStruct);
+        let st: Rc<dyn SourceTrait> = ts;
+        assert!((*st).impls::<dyn Debug>());
+    }
+
+    #[test]
+    fn impls_arc() {
+        let ts = Arc::new(TestStruct);
+        let st: Arc<dyn SourceTrait> = ts;
+        assert!((*st).impls::<dyn Debug>());
+    }
+
+    #[test]
+    fn impls_not_ref() {
+        let ts = TestStruct;
+        let st: &dyn SourceTrait = &ts;
+        assert!(!st.impls::<dyn Display>());
+    }
+
+    #[test]
+    fn impls_not_mut() {
+        let mut ts = TestStruct;
+        let st: &mut dyn Any = &mut ts;
+        assert!(!(*st).impls::<dyn Display>());
+    }
+
+    #[test]
+    fn impls_not_box() {
+        let ts = Box::new(TestStruct);
+        let st: Box<dyn SourceTrait> = ts;
+        assert!(!st.impls::<dyn Display>());
+    }
+
+    #[test]
+    fn impls_not_rc() {
+        let ts = Rc::new(TestStruct);
+        let st: Rc<dyn SourceTrait> = ts;
+        assert!(!(*st).impls::<dyn Display>());
+    }
+
+    #[test]
+    fn impls_not_arc() {
+        let ts = Arc::new(TestStruct);
+        let st: Arc<dyn SourceTrait> = ts;
+        assert!(!(*st).impls::<dyn Display>());
+    }
+}

+ 55 - 0
kernel/src/libs/intertrait/tests/castable_to.rs

@@ -0,0 +1,55 @@
+use intertrait::cast::*;
+use intertrait::*;
+
+struct Data;
+
+trait Source: CastFrom {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+trait Greet1 {
+    fn greet1(&self);
+}
+
+impl Greet1 for Data {
+    fn greet1(&self) {
+        println!("Hello1");
+    }
+}
+
+trait Greet2 {
+    fn greet2(&self);
+}
+
+impl Greet2 for Data {
+    fn greet2(&self) {
+        println!("Hello2");
+    }
+}
+
+impl Source for Data {}
+
+castable_to! { Data => crate::Greet, Greet1, Greet2 }
+
+#[test]
+fn test_multi_traits_on_struct() {
+    let data = Data;
+    let source: &dyn Source = &data;
+
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap().greet();
+
+    let greet1 = source.cast::<dyn Greet1>();
+    greet1.unwrap().greet1();
+
+    let greet2 = source.cast::<dyn Greet2>();
+    greet2.unwrap().greet2();
+}

+ 31 - 0
kernel/src/libs/intertrait/tests/on-enum.rs

@@ -0,0 +1,31 @@
+use intertrait::cast::*;
+use intertrait::*;
+
+#[cast_to(Greet)]
+#[allow(dead_code)]
+enum Data {
+    Var1,
+    Var2(u32),
+}
+
+trait Source: CastFrom {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+impl Source for Data {}
+
+#[test]
+fn test_cast_to_on_enum() {
+    let data = Data::Var2(1);
+    let source: &dyn Source = &data;
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap().greet();
+}

+ 27 - 0
kernel/src/libs/intertrait/tests/on-struct.rs

@@ -0,0 +1,27 @@
+use intertrait::cast::*;
+use intertrait::*;
+
+#[cast_to(Greet)]
+struct Data;
+
+trait Source: CastFrom {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+impl Source for Data {}
+
+#[test]
+fn test_cast_to_on_struct() {
+    let data = Data;
+    let source: &dyn Source = &data;
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap().greet();
+}

+ 33 - 0
kernel/src/libs/intertrait/tests/on-trait-impl-assoc-type1.rs

@@ -0,0 +1,33 @@
+use std::fmt::Debug;
+
+use intertrait::cast::*;
+use intertrait::*;
+
+struct I32Data(i32);
+
+trait Source: CastFrom {}
+
+trait Producer {
+    type Output: Debug;
+
+    fn produce(&self) -> Self::Output;
+}
+
+#[cast_to]
+impl Producer for I32Data {
+    type Output = i32;
+
+    fn produce(&self) -> Self::Output {
+        self.0
+    }
+}
+
+impl Source for I32Data {}
+
+#[test]
+fn test_cast_to_on_trait_impl_with_assoc_type1() {
+    let data = I32Data(100);
+    let source: &dyn Source = &data;
+    let producer = source.cast::<dyn Producer<Output = i32>>();
+    assert_eq!(producer.unwrap().produce(), data.0);
+}

+ 35 - 0
kernel/src/libs/intertrait/tests/on-trait-impl-assoc-type2.rs

@@ -0,0 +1,35 @@
+use std::fmt::Debug;
+
+use intertrait::cast::*;
+use intertrait::*;
+
+struct Data;
+
+trait Source: CastFrom {}
+
+trait Concat {
+    type I1: Debug;
+    type I2: Debug;
+
+    fn concat(&self, a: Self::I1, b: Self::I2) -> String;
+}
+
+#[cast_to]
+impl Concat for Data {
+    type I1 = i32;
+    type I2 = &'static str;
+
+    fn concat(&self, a: Self::I1, b: Self::I2) -> String {
+        format!("Data: {} - {}", a, b)
+    }
+}
+
+impl Source for Data {}
+
+#[test]
+fn test_cast_to_on_trait_impl_with_assoc_type2() {
+    let data = Data;
+    let source: &dyn Source = &data;
+    let concat = source.cast::<dyn Concat<I1 = i32, I2 = &'static str>>();
+    assert_eq!(concat.unwrap().concat(101, "hello"), "Data: 101 - hello");
+}

+ 38 - 0
kernel/src/libs/intertrait/tests/on-trait-impl-assoc-type3.rs

@@ -0,0 +1,38 @@
+use std::fmt::Debug;
+
+use intertrait::cast::*;
+use intertrait::*;
+
+struct Data;
+
+trait Source: CastFrom {}
+
+trait Concat<T: Debug> {
+    type I1: Debug;
+    type I2: Debug;
+
+    fn concat(&self, prefix: T, a: Self::I1, b: Self::I2) -> String;
+}
+
+#[cast_to]
+impl Concat<String> for Data {
+    type I1 = i32;
+    type I2 = &'static str;
+
+    fn concat(&self, prefix: String, a: Self::I1, b: Self::I2) -> String {
+        format!("{}: {} - {}", prefix, a, b)
+    }
+}
+
+impl Source for Data {}
+
+#[test]
+fn test_cast_to_on_trait_impl_with_assoc_type3() {
+    let data = Data;
+    let source: &dyn Source = &data;
+    let concat = source.cast::<dyn Concat<String, I1 = i32, I2 = &'static str>>();
+    assert_eq!(
+        concat.unwrap().concat("Data".to_owned(), 101, "hello"),
+        "Data: 101 - hello"
+    );
+}

+ 27 - 0
kernel/src/libs/intertrait/tests/on-trait-impl.rs

@@ -0,0 +1,27 @@
+use intertrait::cast::*;
+use intertrait::*;
+
+struct Data;
+
+trait Source: CastFrom {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+#[cast_to]
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+impl Source for Data {}
+
+#[test]
+fn test_cast_to_on_trait_impl() {
+    let data = Data;
+    let source: &dyn Source = &data;
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap().greet();
+}

+ 54 - 0
kernel/src/libs/intertrait/tests/on-type-multi-traits.rs

@@ -0,0 +1,54 @@
+use intertrait::cast::*;
+use intertrait::*;
+
+#[cast_to(Greet, Greet1, Greet2)]
+struct Data;
+
+trait Source: CastFrom {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+trait Greet1 {
+    fn greet1(&self);
+}
+
+impl Greet1 for Data {
+    fn greet1(&self) {
+        println!("Hello1");
+    }
+}
+
+trait Greet2 {
+    fn greet2(&self);
+}
+
+impl Greet2 for Data {
+    fn greet2(&self) {
+        println!("Hello2");
+    }
+}
+
+impl Source for Data {}
+
+#[test]
+fn test_multi_traits_on_struct() {
+    let data = Data;
+    let source: &dyn Source = &data;
+
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap().greet();
+
+    let greet1 = source.cast::<dyn Greet1>();
+    greet1.unwrap().greet1();
+
+    let greet2 = source.cast::<dyn Greet2>();
+    greet2.unwrap().greet2();
+}

+ 5 - 0
kernel/src/libs/intertrait/tests/run.rs

@@ -0,0 +1,5 @@
+#[test]
+fn tests() {
+    let t = trybuild::TestCases::new();
+    t.compile_fail("tests/ui/*.rs");
+}

+ 27 - 0
kernel/src/libs/intertrait/tests/ui/duplicate-flags.rs

@@ -0,0 +1,27 @@
+use intertrait::cast::*;
+use intertrait::*;
+use std::sync::Arc;
+
+#[cast_to([sync, sync] Greet)]
+struct Data;
+
+trait Source: CastFromSync {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+impl Source for Data {}
+
+fn main() {
+    let data = Arc::new(Data);
+    let source: Arc<dyn Source> = data;
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap_or_else(|_| panic!("can't happen")).greet();
+}

+ 5 - 0
kernel/src/libs/intertrait/tests/ui/duplicate-flags.stderr

@@ -0,0 +1,5 @@
+error: Duplicated flag: sync
+ --> $DIR/duplicate-flags.rs:5:18
+  |
+5 | #[cast_to([sync, sync] Greet)]
+  |                  ^^^^

+ 31 - 0
kernel/src/libs/intertrait/tests/ui/on-generic-type.rs

@@ -0,0 +1,31 @@
+use intertrait::*;
+use intertrait::cast::*;
+use std::marker::PhantomData;
+
+#[cast_to(Greet)]
+struct Data<T: 'static> {
+    phantom: PhantomData<T>,
+}
+
+trait Source: CastFrom {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+impl<T: 'static> Greet for Data<T> {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+impl<T: 'static> Source for Data<T> {}
+
+fn main() {
+    let data = Data::<i32> {
+        phantom: PhantomData,
+    };
+    let source: &dyn Source = &data;
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap().greet();
+}

+ 5 - 0
kernel/src/libs/intertrait/tests/ui/on-generic-type.stderr

@@ -0,0 +1,5 @@
+error: #[cast_to(..)] can't be used on a generic type definition
+ --> tests/ui/on-generic-type.rs:6:12
+  |
+6 | struct Data<T: 'static> {
+  |            ^^^^^^^^^^^^

+ 14 - 0
kernel/src/libs/intertrait/tests/ui/on-type-impl.rs

@@ -0,0 +1,14 @@
+use intertrait::*;
+
+struct Data;
+
+#[cast_to]
+impl Data {
+    fn hello() {
+        println!("hello!");
+    }
+}
+
+fn main() {
+    let _ = Data;
+}

+ 5 - 0
kernel/src/libs/intertrait/tests/ui/on-type-impl.stderr

@@ -0,0 +1,5 @@
+error: #[cast_to] should only be on an impl of a trait
+ --> $DIR/on-type-impl.rs:6:6
+  |
+6 | impl Data {
+  |      ^^^^

+ 27 - 0
kernel/src/libs/intertrait/tests/ui/unknown-flag.rs

@@ -0,0 +1,27 @@
+use intertrait::cast::*;
+use intertrait::*;
+use std::sync::Arc;
+
+#[cast_to([sync, send] Greet)]
+struct Data;
+
+trait Source: CastFromSync {}
+
+trait Greet {
+    fn greet(&self);
+}
+
+impl Greet for Data {
+    fn greet(&self) {
+        println!("Hello");
+    }
+}
+
+impl Source for Data {}
+
+fn main() {
+    let data = Arc::new(Data);
+    let source: Arc<dyn Source> = data;
+    let greet = source.cast::<dyn Greet>();
+    greet.unwrap_or_else(|_| panic!("can't happen")).greet();
+}

+ 5 - 0
kernel/src/libs/intertrait/tests/ui/unknown-flag.stderr

@@ -0,0 +1,5 @@
+error: Unknown flag: send
+ --> $DIR/unknown-flag.rs:5:18
+  |
+5 | #[cast_to([sync, send] Greet)]
+  |                  ^^^^

+ 1 - 0
kernel/src/libs/mod.rs

@@ -11,6 +11,7 @@ pub mod lib_ui;
 pub mod mutex;
 pub mod notifier;
 pub mod once;
+#[macro_use]
 pub mod printk;
 pub mod rbtree;
 #[macro_use]

+ 26 - 0
kernel/src/libs/rbtree.rs

@@ -1416,10 +1416,12 @@ impl<K: Ord, V> RBTree<K, V> {
     }
 }
 
+#[cfg(test)]
 mod tests {
 
     #[test]
     fn test_insert() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         assert_eq!(m.len(), 0);
         m.insert(1, 2);
@@ -1435,6 +1437,7 @@ mod tests {
 
     #[test]
     fn test_replace() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         assert_eq!(m.len(), 0);
         m.insert(2, 4);
@@ -1446,6 +1449,7 @@ mod tests {
 
     #[test]
     fn test_clone() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         assert_eq!(m.len(), 0);
         m.insert(1, 2);
@@ -1461,12 +1465,14 @@ mod tests {
 
     #[test]
     fn test_empty_remove() {
+        use crate::libs::rbtree::RBTree;
         let mut m: RBTree<isize, bool> = RBTree::new();
         assert_eq!(m.remove(&0), None);
     }
 
     #[test]
     fn test_empty_iter() {
+        use crate::libs::rbtree::RBTree;
         let mut m: RBTree<isize, bool> = RBTree::new();
         assert_eq!(m.iter().next(), None);
         assert_eq!(m.iter_mut().next(), None);
@@ -1477,6 +1483,7 @@ mod tests {
 
     #[test]
     fn test_lots_of_insertions() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
 
         // Try this a few times to make sure we never screw up the hashmap's
@@ -1540,6 +1547,7 @@ mod tests {
 
     #[test]
     fn test_find_mut() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         m.insert(1, 12);
         m.insert(2, 8);
@@ -1554,6 +1562,7 @@ mod tests {
 
     #[test]
     fn test_remove() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         m.insert(1, 2);
         assert_eq!(*m.get(&1).unwrap(), 2);
@@ -1571,6 +1580,7 @@ mod tests {
 
     #[test]
     fn test_is_empty() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         m.insert(1, 2);
         assert!(!m.is_empty());
@@ -1580,6 +1590,7 @@ mod tests {
 
     #[test]
     fn test_pop() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         m.insert(2, 4);
         m.insert(1, 2);
@@ -1595,6 +1606,7 @@ mod tests {
 
     #[test]
     fn test_iterate() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         for i in 0..32 {
             m.insert(i, i * 2);
@@ -1612,6 +1624,7 @@ mod tests {
 
     #[test]
     fn test_keys() {
+        use crate::libs::rbtree::RBTree;
         let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
         let map: RBTree<_, _> = vec.into_iter().collect();
         let keys: Vec<_> = map.keys().cloned().collect();
@@ -1623,6 +1636,7 @@ mod tests {
 
     #[test]
     fn test_values() {
+        use crate::libs::rbtree::RBTree;
         let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
         let map: RBTree<_, _> = vec.into_iter().collect();
         let values: Vec<_> = map.values().cloned().collect();
@@ -1634,6 +1648,7 @@ mod tests {
 
     #[test]
     fn test_values_mut() {
+        use crate::libs::rbtree::RBTree;
         let vec = vec![(1, 1), (2, 2), (3, 3)];
         let mut map: RBTree<_, _> = vec.into_iter().collect();
         for value in map.values_mut() {
@@ -1648,6 +1663,7 @@ mod tests {
 
     #[test]
     fn test_find() {
+        use crate::libs::rbtree::RBTree;
         let mut m = RBTree::new();
         assert!(m.get(&1).is_none());
         m.insert(1, 2);
@@ -1659,6 +1675,7 @@ mod tests {
 
     #[test]
     fn test_eq() {
+        use crate::libs::rbtree::RBTree;
         let mut m1 = RBTree::new();
         m1.insert(1, 2);
         m1.insert(2, 3);
@@ -1677,6 +1694,7 @@ mod tests {
 
     #[test]
     fn test_show() {
+        use crate::libs::rbtree::RBTree;
         let mut map = RBTree::new();
         let empty: RBTree<i32, i32> = RBTree::new();
 
@@ -1691,6 +1709,7 @@ mod tests {
 
     #[test]
     fn test_from_iter() {
+        use crate::libs::rbtree::RBTree;
         let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
 
         let map: RBTree<_, _> = xs.iter().cloned().collect();
@@ -1702,6 +1721,7 @@ mod tests {
 
     #[test]
     fn test_size_hint() {
+        use crate::libs::rbtree::RBTree;
         let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
 
         let map: RBTree<_, _> = xs.iter().cloned().collect();
@@ -1715,6 +1735,7 @@ mod tests {
 
     #[test]
     fn test_iter_len() {
+        use crate::libs::rbtree::RBTree;
         let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
 
         let map: RBTree<_, _> = xs.iter().cloned().collect();
@@ -1728,6 +1749,7 @@ mod tests {
 
     #[test]
     fn test_mut_size_hint() {
+        use crate::libs::rbtree::RBTree;
         let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
 
         let mut map: RBTree<_, _> = xs.iter().cloned().collect();
@@ -1741,6 +1763,7 @@ mod tests {
 
     #[test]
     fn test_iter_mut_len() {
+        use crate::libs::rbtree::RBTree;
         let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
 
         let mut map: RBTree<_, _> = xs.iter().cloned().collect();
@@ -1754,6 +1777,7 @@ mod tests {
 
     #[test]
     fn test_index() {
+        use crate::libs::rbtree::RBTree;
         let mut map = RBTree::new();
 
         map.insert(1, 2);
@@ -1766,6 +1790,7 @@ mod tests {
     #[test]
     #[should_panic]
     fn test_index_nonexistent() {
+        use crate::libs::rbtree::RBTree;
         let mut map = RBTree::new();
 
         map.insert(1, 2);
@@ -1777,6 +1802,7 @@ mod tests {
 
     #[test]
     fn test_extend_iter() {
+        use crate::libs::rbtree::RBTree;
         let mut a = RBTree::new();
         a.insert(1, "one");
         let mut b = RBTree::new();

+ 2 - 0
kernel/src/main.c

@@ -38,6 +38,7 @@ extern void rs_softirq_init();
 extern void rs_mm_init();
 extern int rs_video_init();
 extern void rs_kthread_init();
+extern void rs_init_intertrait();
 
 ul bsp_idt_size, bsp_gdt_size;
 
@@ -101,6 +102,7 @@ void system_initialize()
     scm_reinit();
     rs_textui_init();
 
+    rs_init_intertrait();
     // kinfo("vaddr:%#018lx", video_frame_buffer_info.vaddr);
     io_mfence();
 

+ 1 - 0
kernel/src/mm/allocator/kernel_allocator.rs

@@ -95,6 +95,7 @@ unsafe impl GlobalAlloc for KernelAllocator {
 }
 
 /// 内存分配错误处理函数
+#[cfg(target_os = "none")]
 #[alloc_error_handler]
 pub fn global_alloc_err_handler(layout: Layout) -> ! {
     panic!("global_alloc_error, layout: {:?}", layout);