diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 746dd206309..3b7889bd02f 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -189,6 +189,36 @@ enum TypeRootFilter { TraitType(String), } +#[derive(Clone, Hash, Eq, PartialEq, Debug)] +enum TypeFilter { + Unknown, + Never, + Placeholder, + TypeParam(usize), + StringSlice, + StringArray(usize), + U8, + U16, + U32, + U64, + U256, + Bool, + Custom(String), + B256, + Contract, + ErrorRecovery, + Tuple(usize, Vec), + Enum(ParsedDeclId, Vec), + Struct(ParsedDeclId, Vec), + ContractCaller(String), + Array(usize, Box), + RawUntypedPtr, + RawUntypedSlice, + Ptr(Box), + Slice(Box), + TraitType(String), +} + /// Map holding trait implementations for types. /// /// Note: "impl self" blocks are considered traits and are stored in the @@ -197,7 +227,7 @@ enum TypeRootFilter { pub(crate) struct TraitMap { trait_impls: TraitImpls, satisfied_cache: im::HashSet, - insert_for_type_cache: im::HashMap>, + insert_for_type_cache: im::HashMap>, } pub(crate) enum IsImplSelf { @@ -541,7 +571,7 @@ impl TraitMap { let trait_map = TraitMap { trait_impls, satisfied_cache: im::HashSet::default(), - insert_for_type_cache: im::HashMap::>::new(), + insert_for_type_cache: im::HashMap::>::new(), }; self.extend(trait_map, engines); @@ -639,7 +669,7 @@ impl TraitMap { type_id: TypeId, code_block_first_pass: CodeBlockFirstPass, ) { - let root_filter = TraitMap::get_type_root_filter(engines, type_id); + let root_filter = TraitMap::get_type_filter(engines, type_id); if let Some(values) = self.insert_for_type_cache.get_mut(&root_filter) { let unify_checker = UnifyCheck::non_dynamic_equality(engines).with_unify_ref_mut(false); if values.iter().any(|v| unify_checker.check(type_id, *v)) { @@ -1725,4 +1755,88 @@ impl TraitMap { } => Self::get_type_root_filter(engines, referenced_type.type_id), } } + + // This is used by the trait map to filter the entries into a HashMap with the return type string as key. + fn get_type_filter(engines: &Engines, type_id: TypeId) -> TypeFilter { + use TypeInfo::*; + match &*engines.te().get(type_id) { + Unknown => TypeFilter::Unknown, + Never => TypeFilter::Never, + UnknownGeneric { .. } | Placeholder(_) => TypeFilter::Placeholder, + TypeParam(n) => TypeFilter::TypeParam(*n), + StringSlice => TypeFilter::StringSlice, + StringArray(x) => TypeFilter::StringArray(x.val()), + UnsignedInteger(x) => match x { + IntegerBits::Eight => TypeFilter::U8, + IntegerBits::Sixteen => TypeFilter::U16, + IntegerBits::ThirtyTwo => TypeFilter::U32, + IntegerBits::SixtyFour => TypeFilter::U64, + IntegerBits::V256 => TypeFilter::U256, + }, + Boolean => TypeFilter::Bool, + Custom { + qualified_call_path: call_path, + .. + } => TypeFilter::Custom(call_path.call_path.suffix.to_string()), + B256 => TypeFilter::B256, + Numeric => TypeFilter::U64, // u64 is the default + Contract => TypeFilter::Contract, + ErrorRecovery(_) => TypeFilter::ErrorRecovery, + Tuple(fields) => TypeFilter::Tuple( + fields.len(), + fields + .iter() + .map(|f| Self::get_type_filter(engines, f.type_id)) + .collect::>(), + ), + UntypedEnum(_) => unreachable!(), + UntypedStruct(_) => unreachable!(), + Enum(decl_id) => { + // TODO Remove unwrap once #6475 is fixed + TypeFilter::Enum( + engines.de().get_parsed_decl_id(decl_id).unwrap(), + engines + .de() + .get_enum(decl_id) + .type_parameters + .iter() + .map(|f| Self::get_type_filter(engines, f.type_id)) + .collect::>(), + ) + } + Struct(decl_id) => { + // TODO Remove unwrap once #6475 is fixed + TypeFilter::Struct( + engines.de().get_parsed_decl_id(decl_id).unwrap(), + engines + .de() + .get_struct(decl_id) + .type_parameters + .iter() + .map(|f| Self::get_type_filter(engines, f.type_id)) + .collect::>(), + ) + } + ContractCaller { abi_name, .. } => TypeFilter::ContractCaller(abi_name.to_string()), + Array(type_argument, length) => TypeFilter::Array( + length.val(), + Box::new(Self::get_type_filter(engines, type_argument.type_id)), + ), + RawUntypedPtr => TypeFilter::RawUntypedPtr, + RawUntypedSlice => TypeFilter::RawUntypedSlice, + Ptr(type_argument) => TypeFilter::Ptr(Box::new(Self::get_type_filter( + engines, + type_argument.type_id, + ))), + Slice(type_argument) => TypeFilter::Slice(Box::new(Self::get_type_filter( + engines, + type_argument.type_id, + ))), + Alias { ty, .. } => Self::get_type_filter(engines, ty.type_id), + TraitType { name, .. } => TypeFilter::TraitType(name.to_string()), + Ref { + referenced_type, .. + } => Self::get_type_filter(engines, referenced_type.type_id), + } + } } diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 84a0def1c22..72fb69cef2e 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1224,18 +1224,6 @@ impl<'a> TypeCheckContext<'a> { .values() .filter_map(|method_ref| { let method = decl_engine.get_function(method_ref); - - //if method.name.clone().as_str() == "new" { - println!( - "find_method_for_type {:?} {:?}", - method.implementing_for_typeid.map(|t| { - self.engines - .help_out((*self.engines.te().get(t)).clone()) - }), - method.name.clone(), - ); - //} - method .span() .to_string_path_with_line_col(self.engines().se())