Skip to content

Commit 187146b

Browse files
xunilrjJoshuaBatty
andauthored
Cache in front of check_if_trait_constraints_are_satisfied_for_type (#5827)
## Description Partially fixes #5781. This reduces the problem of millions of `TypeInfo`s being created. For more details see: #5782 ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
1 parent bc2e603 commit 187146b

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

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

+55-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ use std::{
22
cmp::Ordering,
33
collections::{BTreeSet, HashMap},
44
fmt,
5+
hash::{DefaultHasher, Hash, Hasher},
56
};
67

8+
use hashbrown::HashSet;
79
use sway_error::{
810
error::CompileError,
911
handler::{ErrorEmitted, Handler},
@@ -148,6 +150,7 @@ type TraitImpls = Vec<TraitEntry>;
148150
#[derive(Clone, Debug, Default)]
149151
pub(crate) struct TraitMap {
150152
trait_impls: TraitImpls,
153+
satisfied_cache: hashbrown::HashSet<u64>,
151154
}
152155

153156
pub(crate) enum IsImplSelf {
@@ -425,7 +428,10 @@ impl TraitMap {
425428
};
426429
let entry = TraitEntry { key, value };
427430
let trait_impls: TraitImpls = vec![entry];
428-
let trait_map = TraitMap { trait_impls };
431+
let trait_map = TraitMap {
432+
trait_impls,
433+
satisfied_cache: HashSet::default(),
434+
};
429435

430436
self.extend(trait_map, engines);
431437
}
@@ -1176,6 +1182,53 @@ impl TraitMap {
11761182
) -> Result<(), ErrorEmitted> {
11771183
let type_engine = engines.te();
11781184

1185+
// resolving trait constraints require a concrete type, we need to default numeric to u64
1186+
type_engine.decay_numeric(handler, engines, type_id, access_span)?;
1187+
1188+
if constraints.is_empty() {
1189+
return Ok(());
1190+
}
1191+
1192+
// Check we can use the cache
1193+
let mut hasher = DefaultHasher::default();
1194+
type_id.hash(&mut hasher);
1195+
for c in constraints {
1196+
c.hash(&mut hasher, engines);
1197+
}
1198+
let hash = hasher.finish();
1199+
1200+
if self.satisfied_cache.contains(&hash) {
1201+
return Ok(());
1202+
}
1203+
1204+
// Call the real implementation and cache when true
1205+
match self.check_if_trait_constraints_are_satisfied_for_type_inner(
1206+
handler,
1207+
type_id,
1208+
constraints,
1209+
access_span,
1210+
engines,
1211+
try_inserting_trait_impl_on_failure,
1212+
) {
1213+
Ok(()) => {
1214+
self.satisfied_cache.insert(hash);
1215+
Ok(())
1216+
}
1217+
r => r,
1218+
}
1219+
}
1220+
1221+
fn check_if_trait_constraints_are_satisfied_for_type_inner(
1222+
&mut self,
1223+
handler: &Handler,
1224+
type_id: TypeId,
1225+
constraints: &[TraitConstraint],
1226+
access_span: &Span,
1227+
engines: &Engines,
1228+
try_inserting_trait_impl_on_failure: TryInsertingTraitImplOnFailure,
1229+
) -> Result<(), ErrorEmitted> {
1230+
let type_engine = engines.te();
1231+
11791232
// If the type is generic/placeholder, its definition needs to contains all
11801233
// constraints
11811234
match &*type_engine.get(type_id) {
@@ -1207,9 +1260,6 @@ impl TraitMap {
12071260
let _decl_engine = engines.de();
12081261
let unify_check = UnifyCheck::non_dynamic_equality(engines);
12091262

1210-
// resolving trait constraints require a concrete type, we need to default numeric to u64
1211-
type_engine.decay_numeric(handler, engines, type_id, access_span)?;
1212-
12131263
let all_impld_traits: BTreeSet<(Ident, TypeId)> = self
12141264
.trait_impls
12151265
.iter()
@@ -1307,6 +1357,7 @@ impl TraitMap {
13071357
});
13081358
}
13091359
}
1360+
13101361
Ok(())
13111362
})
13121363
}

test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-vec/reduced_lib.config

-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ revert.sw
88
vec.sw
99
iterator.sw
1010
convert.sw
11-

0 commit comments

Comments
 (0)