use sway_types::{Span, Spanned};
use crate::{
decl_engine::DeclId,
language::{parsed, ty, Visibility},
};
use sway_error::handler::{ErrorEmitted, Handler};
use crate::{
semantic_analysis::{AbiMode, TypeCheckContext},
type_system::*,
};
impl ty::TyTraitFn {
pub(crate) fn type_check(
handler: &Handler,
mut ctx: TypeCheckContext,
trait_fn: parsed::TraitFn,
) -> Result<ty::TyTraitFn, ErrorEmitted> {
let parsed::TraitFn {
name,
span,
purity,
parameters,
mut return_type,
attributes,
} = trait_fn;
let type_engine = ctx.engines.te();
let engines = ctx.engines();
let mut fn_namespace = ctx.namespace.clone();
let mut ctx = ctx.by_ref().scoped(&mut fn_namespace).with_purity(purity);
let mut typed_parameters = vec![];
for param in parameters.into_iter() {
typed_parameters.push(
match ty::TyFunctionParameter::type_check_interface_parameter(
handler,
ctx.by_ref(),
param,
) {
Ok(res) => res,
Err(_) => continue,
},
);
}
return_type.type_id = ctx
.resolve_type_with_self(
handler,
return_type.type_id,
&return_type.span,
EnforceTypeArguments::Yes,
None,
)
.unwrap_or_else(|err| type_engine.insert(engines, TypeInfo::ErrorRecovery(err)));
let trait_fn = ty::TyTraitFn {
name,
span,
parameters: typed_parameters,
return_type,
purity,
attributes,
};
Ok(trait_fn)
}
pub(crate) fn to_dummy_func(&self, abi_mode: AbiMode) -> ty::TyFunctionDecl {
ty::TyFunctionDecl {
purity: self.purity,
name: self.name.clone(),
body: ty::TyCodeBlock { contents: vec![] },
parameters: self.parameters.clone(),
implementing_type: match abi_mode.clone() {
AbiMode::ImplAbiFn(abi_name, abi_decl_id) => {
Some(ty::TyDecl::AbiDecl(ty::AbiDecl {
name: abi_name,
decl_id: abi_decl_id.unwrap_or(DeclId::dummy()),
decl_span: Span::dummy(),
}))
}
AbiMode::NonAbi => None,
},
span: self.name.span(),
attributes: self.attributes.clone(),
return_type: self.return_type.clone(),
visibility: Visibility::Public,
type_parameters: vec![],
is_contract_call: matches!(abi_mode, AbiMode::ImplAbiFn(..)),
where_clause: vec![],
}
}
}