Skip to content

Commit e50e270

Browse files
committed
Some fixes, and adds get_method_safe_to_unify
1 parent 695f87f commit e50e270

File tree

4 files changed

+47
-181
lines changed

4 files changed

+47
-181
lines changed

sway-core/src/semantic_analysis/ast_node/declaration/auto_impl/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ where
266266
&handler,
267267
impl_trait.trait_name.clone(),
268268
impl_trait.trait_type_arguments.clone(),
269+
impl_trait.impl_type_parameters.clone(),
269270
impl_trait.implementing_for.type_id,
270271
&impl_trait.items,
271272
&impl_trait.span,

sway-core/src/semantic_analysis/namespace/trait_map.rs

Lines changed: 10 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -200,36 +200,6 @@ enum TypeRootFilter {
200200
TraitType(String),
201201
}
202202

203-
#[derive(Clone, Hash, Eq, PartialEq, Debug)]
204-
enum TypeFilter {
205-
Unknown,
206-
Never,
207-
Placeholder,
208-
TypeParam(usize),
209-
StringSlice,
210-
StringArray(usize),
211-
U8,
212-
U16,
213-
U32,
214-
U64,
215-
U256,
216-
Bool,
217-
Custom(String),
218-
B256,
219-
Contract,
220-
ErrorRecovery,
221-
Tuple(usize, Vec<TypeFilter>),
222-
Enum(ParsedDeclId<EnumDeclaration>, Vec<TypeFilter>),
223-
Struct(ParsedDeclId<StructDeclaration>, Vec<TypeFilter>),
224-
ContractCaller(String),
225-
Array(usize, Box<TypeFilter>),
226-
RawUntypedPtr,
227-
RawUntypedSlice,
228-
Ptr(Box<TypeFilter>),
229-
Slice(Box<TypeFilter>),
230-
TraitType(String),
231-
}
232-
233203
/// Map holding trait implementations for types.
234204
///
235205
/// Note: "impl self" blocks are considered traits and are stored in the
@@ -238,7 +208,6 @@ enum TypeFilter {
238208
pub struct TraitMap {
239209
trait_impls: TraitImpls,
240210
satisfied_cache: HashSet<u64>,
241-
insert_for_type_cache: HashMap<TypeFilter, im::Vector<TypeId>>,
242211
}
243212

244213
pub(crate) enum IsImplSelf {
@@ -275,7 +244,6 @@ impl TraitMap {
275244
engines: &Engines,
276245
) -> Result<(), ErrorEmitted> {
277246
let type_id = engines.te().get_unaliased_type_id(type_id);
278-
let trait_map = &mut module.current_items_mut().implemented_traits;
279247

280248
let mut type_id_type_parameters = match &*engines.te().get(type_id) {
281249
TypeInfo::Enum(decl_id) => engines.de().get_enum(decl_id).type_parameters.clone(),
@@ -324,7 +292,11 @@ impl TraitMap {
324292
}
325293
}
326294

327-
let trait_impls = trait_map.get_impls_mut(engines, type_id).clone();
295+
let trait_impls = module
296+
.current_items_mut()
297+
.implemented_traits
298+
.get_impls_mut(engines, type_id)
299+
.clone();
328300

329301
// check to see if adding this trait will produce a conflicting definition
330302
for TraitEntry {
@@ -428,7 +400,7 @@ impl TraitMap {
428400
if type_id_type_parameter
429401
.type_id
430402
.is_concrete(engines, crate::TreatNumericAs::Abstract)
431-
&& TraitMap::check_if_trait_constraints_are_satisfied_for_type(
403+
&& Self::check_if_trait_constraints_are_satisfied_for_type(
432404
&Handler::default(),
433405
module,
434406
type_id_type_parameter.type_id,
@@ -524,7 +496,7 @@ impl TraitMap {
524496
});
525497

526498
// even if there is a conflicting definition, add the trait anyway
527-
trait_map.insert_inner(
499+
module.current_items_mut().implemented_traits.insert_inner(
528500
trait_name,
529501
impl_span.clone(),
530502
trait_decl_span,
@@ -569,7 +541,6 @@ impl TraitMap {
569541
let trait_map = TraitMap {
570542
trait_impls,
571543
satisfied_cache: HashSet::default(),
572-
insert_for_type_cache: HashMap::<TypeRootFilter, im::Vector<TypeId>>::new(),
573544
};
574545

575546
self.extend(trait_map, engines);
@@ -602,7 +573,10 @@ impl TraitMap {
602573
// If we have the same method in: impl<T> FromBytes for T
603574
// and: impl FromBytes for DataPoint
604575
// We keep the second implementation.
576+
// We don't care for the order this is checked
577+
#[allow(clippy::iter_over_hash_type)]
605578
for (name, item) in oe.value.trait_items.iter() {
579+
#[allow(clippy::iter_over_hash_type)]
606580
for (existing_name, existing_item) in
607581
self_vec[pos].value.trait_items.iter()
608582
{
@@ -1654,88 +1628,4 @@ impl TraitMap {
16541628
} => Self::get_type_root_filter(engines, referenced_type.type_id),
16551629
}
16561630
}
1657-
1658-
// This is used by the trait map to filter the entries into a HashMap with the return type string as key.
1659-
fn get_type_filter(engines: &Engines, type_id: TypeId) -> TypeFilter {
1660-
use TypeInfo::*;
1661-
match &*engines.te().get(type_id) {
1662-
Unknown => TypeFilter::Unknown,
1663-
Never => TypeFilter::Never,
1664-
UnknownGeneric { .. } | Placeholder(_) => TypeFilter::Placeholder,
1665-
TypeParam(n) => TypeFilter::TypeParam(*n),
1666-
StringSlice => TypeFilter::StringSlice,
1667-
StringArray(x) => TypeFilter::StringArray(x.val()),
1668-
UnsignedInteger(x) => match x {
1669-
IntegerBits::Eight => TypeFilter::U8,
1670-
IntegerBits::Sixteen => TypeFilter::U16,
1671-
IntegerBits::ThirtyTwo => TypeFilter::U32,
1672-
IntegerBits::SixtyFour => TypeFilter::U64,
1673-
IntegerBits::V256 => TypeFilter::U256,
1674-
},
1675-
Boolean => TypeFilter::Bool,
1676-
Custom {
1677-
qualified_call_path: call_path,
1678-
..
1679-
} => TypeFilter::Custom(call_path.call_path.suffix.to_string()),
1680-
B256 => TypeFilter::B256,
1681-
Numeric => TypeFilter::U64, // u64 is the default
1682-
Contract => TypeFilter::Contract,
1683-
ErrorRecovery(_) => TypeFilter::ErrorRecovery,
1684-
Tuple(fields) => TypeFilter::Tuple(
1685-
fields.len(),
1686-
fields
1687-
.iter()
1688-
.map(|f| Self::get_type_filter(engines, f.type_id))
1689-
.collect::<Vec<_>>(),
1690-
),
1691-
UntypedEnum(_) => unreachable!(),
1692-
UntypedStruct(_) => unreachable!(),
1693-
Enum(decl_id) => {
1694-
// TODO Remove unwrap once #6475 is fixed
1695-
TypeFilter::Enum(
1696-
engines.de().get_parsed_decl_id(decl_id).unwrap(),
1697-
engines
1698-
.de()
1699-
.get_enum(decl_id)
1700-
.type_parameters
1701-
.iter()
1702-
.map(|f| Self::get_type_filter(engines, f.type_id))
1703-
.collect::<Vec<_>>(),
1704-
)
1705-
}
1706-
Struct(decl_id) => {
1707-
// TODO Remove unwrap once #6475 is fixed
1708-
TypeFilter::Struct(
1709-
engines.de().get_parsed_decl_id(decl_id).unwrap(),
1710-
engines
1711-
.de()
1712-
.get_struct(decl_id)
1713-
.type_parameters
1714-
.iter()
1715-
.map(|f| Self::get_type_filter(engines, f.type_id))
1716-
.collect::<Vec<_>>(),
1717-
)
1718-
}
1719-
ContractCaller { abi_name, .. } => TypeFilter::ContractCaller(abi_name.to_string()),
1720-
Array(type_argument, length) => TypeFilter::Array(
1721-
length.val(),
1722-
Box::new(Self::get_type_filter(engines, type_argument.type_id)),
1723-
),
1724-
RawUntypedPtr => TypeFilter::RawUntypedPtr,
1725-
RawUntypedSlice => TypeFilter::RawUntypedSlice,
1726-
Ptr(type_argument) => TypeFilter::Ptr(Box::new(Self::get_type_filter(
1727-
engines,
1728-
type_argument.type_id,
1729-
))),
1730-
Slice(type_argument) => TypeFilter::Slice(Box::new(Self::get_type_filter(
1731-
engines,
1732-
type_argument.type_id,
1733-
))),
1734-
Alias { ty, .. } => Self::get_type_filter(engines, ty.type_id),
1735-
TraitType { name, .. } => TypeFilter::TraitType(name.to_string()),
1736-
Ref {
1737-
referenced_type, ..
1738-
} => Self::get_type_filter(engines, referenced_type.type_id),
1739-
}
1740-
}
17411631
}

sway-core/src/semantic_analysis/type_check_context.rs

Lines changed: 31 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
use std::collections::{HashMap, HashSet, VecDeque};
33

44
use crate::{
5-
decl_engine::{DeclEngineGet, DeclId, DeclRefFunction},
5+
decl_engine::{
6+
DeclEngineGet, DeclEngineGetParsedDeclId, DeclEngineInsert, DeclId, DeclRef,
7+
DeclRefFunction,
8+
},
69
engine_threading::*,
710
language::{
811
parsed::TreeType,
@@ -31,7 +34,6 @@ use sway_features::ExperimentalFeatures;
3134
use sway_types::{span::Span, Ident, IdentUnique, Spanned};
3235

3336
use super::{
34-
namespace::CodeBlockFirstPass,
3537
namespace::{Items, LexicalScopeId},
3638
symbol_collection_context::SymbolCollectionContext,
3739
type_resolve::{resolve_call_path, resolve_qualified_call_path, resolve_type, VisibilityCheck},
@@ -828,9 +830,6 @@ impl<'a> TypeCheckContext<'a> {
828830
type_engine.decay_numeric(handler, self.engines, type_id, &method_name.span())?;
829831
}
830832

831-
// Retrieve the implemented traits for the type and insert them in the namespace.
832-
self.insert_trait_implementation_for_type(type_id);
833-
834833
let mut matching_item_decl_refs =
835834
self.find_items_for_type(handler, type_id, method_prefix, method_name)?;
836835

@@ -962,21 +961,15 @@ impl<'a> TypeCheckContext<'a> {
962961
.zip(method_type_id_type_parameters.iter())
963962
{
964963
let handler = Handler::default();
965-
if self
966-
.namespace_mut()
967-
.module_mut(engines)
968-
.current_items_mut()
969-
.implemented_traits
970-
.check_if_trait_constraints_are_satisfied_for_type(
971-
&handler,
972-
type_id_type_parameter.type_id,
973-
&method_type_id_type_parameter.trait_constraints,
974-
&method.span(),
975-
engines,
976-
TryInsertingTraitImplOnFailure::Yes,
977-
CodeBlockFirstPass::No,
978-
)
979-
.is_err()
964+
if TraitMap::check_if_trait_constraints_are_satisfied_for_type(
965+
&handler,
966+
self.namespace_mut().current_module_mut(),
967+
type_id_type_parameter.type_id,
968+
&method_type_id_type_parameter.trait_constraints,
969+
&method.span(),
970+
engines,
971+
)
972+
.is_err()
980973
{
981974
let (errors, _) = handler.consume();
982975
let mut errors_strings = vec![];
@@ -1117,6 +1110,8 @@ impl<'a> TypeCheckContext<'a> {
11171110
method.implementing_for_typeid.map(|t| {
11181111
self.engines.help_out((*self.engines.te().get(t)).clone())
11191112
}),
1113+
method.name.clone().into(),
1114+
trait_decl.trait_decl_ref.is_none(),
11201115
);
11211116

11221117
if !skip_insert {
@@ -1130,25 +1125,6 @@ impl<'a> TypeCheckContext<'a> {
11301125
}
11311126
}
11321127

1133-
// If we have: impl<T> FromBytes for T
1134-
// and: impl FromBytes for DataPoint
1135-
// We pick the second implementation.
1136-
let mut non_blanket_impl_exists = false;
1137-
let mut impls_with_type_params = vec![];
1138-
let trait_method_clone = trait_methods.clone();
1139-
let existing_values = trait_method_clone.values().collect::<Vec<_>>();
1140-
for existing_value in existing_values.iter() {
1141-
let existing_method = decl_engine.get_function(*existing_value);
1142-
if !existing_method.is_from_blanket_impl(engines) {
1143-
non_blanket_impl_exists = true;
1144-
} else {
1145-
impls_with_type_params.push(existing_value.id());
1146-
}
1147-
}
1148-
if non_blanket_impl_exists {
1149-
trait_methods.retain(|_, v| !impls_with_type_params.contains(&v.id()));
1150-
}
1151-
11521128
// If we have: impl<T> FromBytes for T
11531129
// and: impl FromBytes for DataPoint
11541130
// We pick the second implementation.
@@ -1189,7 +1165,7 @@ impl<'a> TypeCheckContext<'a> {
11891165
if let Some(implementing_for_type) = method.implementing_for_typeid {
11901166
if eq_check
11911167
.with_unify_ref_mut(false)
1192-
.check(implementing_for_type, type_id)
1168+
.check(type_id, implementing_for_type)
11931169
{
11941170
exact_matching_methods.push(*trait_method_ref);
11951171
}
@@ -1514,23 +1490,21 @@ impl<'a> TypeCheckContext<'a> {
15141490
.iter()
15151491
.map(|item| ResolvedTraitImplItem::Typed(item.clone()))
15161492
.collect::<Vec<_>>();
1517-
self.namespace_mut()
1518-
.current_module_mut()
1519-
.current_items_mut()
1520-
.implemented_traits
1521-
.insert(
1522-
handler,
1523-
canonical_trait_path,
1524-
trait_type_args,
1525-
trait_type_parameters,
1526-
type_id,
1527-
&items,
1528-
impl_span,
1529-
trait_decl_span,
1530-
is_impl_self,
1531-
is_extending_existing_impl,
1532-
engines,
1533-
)
1493+
1494+
TraitMap::insert(
1495+
handler,
1496+
self.namespace_mut().current_module_mut(),
1497+
canonical_trait_path,
1498+
trait_type_args,
1499+
trait_type_parameters,
1500+
type_id,
1501+
&items,
1502+
impl_span,
1503+
trait_decl_span,
1504+
is_impl_self,
1505+
is_extending_existing_impl,
1506+
engines,
1507+
)
15341508
}
15351509

15361510
pub(crate) fn get_items_for_type_and_trait_name(

sway-types/src/span.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
use crate::SourceId;
21
use lazy_static::lazy_static;
32
use serde::{Deserialize, Serialize};
43

54
use crate::{SourceEngine, SourceId};
65

7-
use {
8-
lazy_static::lazy_static,
9-
std::{cmp, fmt, hash::Hash, sync::Arc},
6+
use std::{
7+
cmp,
8+
fmt::{self, Display},
9+
hash::Hash,
10+
sync::Arc,
1011
};
1112

1213
lazy_static! {

0 commit comments

Comments
 (0)