use wasm_encoder::ValType;
use crate::ast::{Expr, MatchArm, Pattern, Spanned};
use crate::types::Type;
use super::super::WasmGcError;
use super::super::types::{TypeRegistry, aver_to_wasm};
pub(super) fn arm_is_option_pattern(arm: &MatchArm) -> bool {
if let Pattern::Constructor(name, _) = &arm.pattern {
let bare = name.rsplit('.').next().unwrap_or(name);
return name == "Option.Some"
|| name == "Option.None"
|| ((bare == "Some" || bare == "None") && name.starts_with("Option"));
}
false
}
pub(super) fn arm_is_result_pattern(arm: &MatchArm) -> bool {
if let Pattern::Constructor(name, _) = &arm.pattern {
let bare = name.rsplit('.').next().unwrap_or(name);
return name == "Result.Ok"
|| name == "Result.Err"
|| ((bare == "Ok" || bare == "Err") && name.starts_with("Result"));
}
false
}
#[track_caller]
pub(super) fn aver_type_of(expr: &Spanned<Expr>) -> &Type {
expr.ty().unwrap_or_else(|| {
panic!(
"wasm-gc emit: expression has no type — typecheck must run before codegen \
(Step 0 setter or synthesised AST without set_ty); offending node: {:?}",
expr.node
)
})
}
#[track_caller]
pub(super) fn aver_type_str_of(expr: &Spanned<Expr>) -> String {
aver_type_of(expr).display()
}
#[track_caller]
pub(super) fn wasm_type_of(
expr: &Spanned<Expr>,
registry: &TypeRegistry,
) -> Result<Option<ValType>, WasmGcError> {
aver_to_wasm(&aver_type_str_of(expr), Some(registry))
}
#[track_caller]
pub(super) fn aver_type_canonical(
expr: &Spanned<Expr>,
_return_type: &str,
_registry: &TypeRegistry,
) -> String {
let raw = aver_type_str_of(expr);
raw.chars().filter(|c| !c.is_whitespace()).collect()
}