Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/abi.rs')
| -rw-r--r-- | crates/hir-ty/src/next_solver/abi.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/crates/hir-ty/src/next_solver/abi.rs b/crates/hir-ty/src/next_solver/abi.rs new file mode 100644 index 0000000000..80d1ea4aa4 --- /dev/null +++ b/crates/hir-ty/src/next_solver/abi.rs @@ -0,0 +1,68 @@ +//! ABI-related things in the next-trait-solver. +use rustc_type_ir::{error::TypeError, relate::Relate}; + +use crate::FnAbi; + +use super::interner::DbInterner; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub enum Safety { + Unsafe, + Safe, +} + +impl<'db> Relate<DbInterner<'db>> for Safety { + fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>( + _relation: &mut R, + a: Self, + b: Self, + ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> { + if a != b { + Err(TypeError::SafetyMismatch(rustc_type_ir::error::ExpectedFound::new(a, b))) + } else { + Ok(a) + } + } +} + +impl<'db> rustc_type_ir::inherent::Safety<DbInterner<'db>> for Safety { + fn safe() -> Self { + Self::Safe + } + + fn is_safe(self) -> bool { + matches!(self, Safety::Safe) + } + + fn prefix_str(self) -> &'static str { + match self { + Self::Unsafe => "unsafe ", + Self::Safe => "", + } + } +} + +impl<'db> Relate<DbInterner<'db>> for FnAbi { + fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>( + _relation: &mut R, + a: Self, + b: Self, + ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> { + if a == b { + Ok(a) + } else { + Err(TypeError::AbiMismatch(rustc_type_ir::error::ExpectedFound::new(a, b))) + } + } +} + +impl<'db> rustc_type_ir::inherent::Abi<DbInterner<'db>> for FnAbi { + fn rust() -> Self { + FnAbi::Rust + } + + fn is_rust(self) -> bool { + // TODO: rustc does not consider `RustCall` to be true here, but Chalk does + matches!(self, FnAbi::Rust | FnAbi::RustCall) + } +} |