use alloc::boxed::Box;
use midenc_hir::{derive::operation, effects::*, smallvec, traits::*, *};
use crate::*;
#[operation(
dialect = UndefinedBehaviorDialect,
traits(ConstantLike),
implements(InferTypeOpInterface, MemoryEffectOpInterface, Foldable)
)]
pub struct Poison {
#[attr(hidden)]
value: PoisonAttr,
#[result]
result: AnyType,
}
impl EffectOpInterface<MemoryEffect> for Poison {
fn has_no_effect(&self) -> bool {
true
}
fn effects(&self) -> EffectIterator<MemoryEffect> {
EffectIterator::from_smallvec(smallvec![])
}
}
impl Foldable for Poison {
fn fold(&self, results: &mut SmallVec<[OpFoldResult; 1]>) -> FoldResult {
results.push(OpFoldResult::Attribute(Box::new(self.value().clone())));
FoldResult::Ok(())
}
fn fold_with(
&self,
_operands: &[Option<Box<dyn AttributeValue>>],
results: &mut SmallVec<[OpFoldResult; 1]>,
) -> FoldResult {
results.push(OpFoldResult::Attribute(Box::new(self.value().clone())));
FoldResult::Ok(())
}
}
impl InferTypeOpInterface for Poison {
fn infer_return_types(&mut self, _context: &Context) -> Result<(), Report> {
let poison_ty = self.value().ty().clone();
self.result_mut().set_type(poison_ty);
Ok(())
}
}
#[operation(
dialect = UndefinedBehaviorDialect,
traits(Terminator),
implements(MemoryEffectOpInterface)
)]
pub struct Unreachable {}
impl EffectOpInterface<MemoryEffect> for Unreachable {
fn effects(&self) -> EffectIterator<MemoryEffect> {
EffectIterator::from_smallvec(smallvec![EffectInstance::new(MemoryEffect::Write)])
}
}