Skip to main content

melior/ir/operation/
result.rs

1use crate::{
2    ir::{OperationRef, Value, ValueLike},
3    Error,
4};
5use mlir_sys::{mlirOpResultGetOwner, mlirOpResultGetResultNumber, MlirValue};
6use std::fmt::{self, Display, Formatter};
7
8/// An operation result.
9#[derive(Clone, Copy, Debug)]
10pub struct OperationResult<'c, 'a> {
11    value: Value<'c, 'a>,
12}
13
14impl<'c> OperationResult<'c, '_> {
15    /// Returns a result number.
16    pub fn result_number(&self) -> usize {
17        unsafe { mlirOpResultGetResultNumber(self.value.to_raw()) as usize }
18    }
19
20    /// Returns an owner operation.
21    pub fn owner(&self) -> OperationRef<'c, '_> {
22        unsafe { OperationRef::from_raw(mlirOpResultGetOwner(self.value.to_raw())) }
23    }
24
25    /// Creates an operation result from a raw object.
26    ///
27    /// # Safety
28    ///
29    /// A raw object must be valid.
30    pub unsafe fn from_raw(value: MlirValue) -> Self {
31        Self {
32            value: Value::from_raw(value),
33        }
34    }
35}
36
37impl<'c> ValueLike<'c> for OperationResult<'c, '_> {
38    fn to_raw(&self) -> MlirValue {
39        self.value.to_raw()
40    }
41}
42
43impl Display for OperationResult<'_, '_> {
44    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
45        Value::from(*self).fmt(formatter)
46    }
47}
48
49impl<'c, 'a> TryFrom<Value<'c, 'a>> for OperationResult<'c, 'a> {
50    type Error = Error;
51
52    fn try_from(value: Value<'c, 'a>) -> Result<Self, Self::Error> {
53        if value.is_operation_result() {
54            Ok(Self { value })
55        } else {
56            Err(Error::OperationResultExpected(value.to_string()))
57        }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use crate::{
64        ir::{operation::OperationBuilder, Block, Location, Type},
65        test::create_test_context,
66    };
67
68    #[test]
69    fn result_number() {
70        let context = create_test_context();
71        context.set_allow_unregistered_dialects(true);
72
73        let r#type = Type::parse(&context, "index").unwrap();
74        let operation = OperationBuilder::new("foo", Location::unknown(&context))
75            .add_results(&[r#type])
76            .build()
77            .unwrap();
78
79        assert_eq!(operation.result(0).unwrap().result_number(), 0);
80    }
81
82    #[test]
83    fn owner() {
84        let context = create_test_context();
85        let r#type = Type::parse(&context, "index").unwrap();
86        let block = Block::new(&[(r#type, Location::unknown(&context))]);
87
88        assert_eq!(&*block.argument(0).unwrap().owner(), &block);
89    }
90}