hir_ty/next_solver/
abi.rs

1//! ABI-related things in the next-trait-solver.
2use rustc_type_ir::{error::TypeError, relate::Relate};
3
4use crate::FnAbi;
5
6use super::interner::DbInterner;
7
8#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
9pub enum Safety {
10    Unsafe,
11    Safe,
12}
13
14impl<'db> Relate<DbInterner<'db>> for Safety {
15    fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
16        _relation: &mut R,
17        a: Self,
18        b: Self,
19    ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> {
20        if a != b {
21            Err(TypeError::SafetyMismatch(rustc_type_ir::error::ExpectedFound::new(a, b)))
22        } else {
23            Ok(a)
24        }
25    }
26}
27
28impl<'db> rustc_type_ir::inherent::Safety<DbInterner<'db>> for Safety {
29    fn safe() -> Self {
30        Self::Safe
31    }
32
33    fn is_safe(self) -> bool {
34        matches!(self, Safety::Safe)
35    }
36
37    fn prefix_str(self) -> &'static str {
38        match self {
39            Self::Unsafe => "unsafe ",
40            Self::Safe => "",
41        }
42    }
43}
44
45impl<'db> Relate<DbInterner<'db>> for FnAbi {
46    fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
47        _relation: &mut R,
48        a: Self,
49        b: Self,
50    ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> {
51        if a == b {
52            Ok(a)
53        } else {
54            Err(TypeError::AbiMismatch(rustc_type_ir::error::ExpectedFound::new(a, b)))
55        }
56    }
57}
58
59impl<'db> rustc_type_ir::inherent::Abi<DbInterner<'db>> for FnAbi {
60    fn rust() -> Self {
61        FnAbi::Rust
62    }
63
64    fn is_rust(self) -> bool {
65        // TODO: rustc does not consider `RustCall` to be true here, but Chalk does
66        matches!(self, FnAbi::Rust | FnAbi::RustCall)
67    }
68}