Skip to content

Commit 35c810e

Browse files
authored
Optimize retrieve_interface_surface_and_items_and_implemented_items_for_type (#5837)
## Description Partially addresses #5781. This reduces the problem of millions of TyFunctionDecl being created. For more details see: #5782 ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] 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) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] 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). - [x] I have requested a review from the relevant team or maintainers.
1 parent 89e5708 commit 35c810e

31 files changed

+427
-318
lines changed

sway-core/src/decl_engine/id.rs

+56-24
Original file line numberDiff line numberDiff line change
@@ -97,67 +97,99 @@ impl<T> Into<usize> for DeclId<T> {
9797
}
9898

9999
impl SubstTypes for DeclId<TyFunctionDecl> {
100-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
100+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
101101
let decl_engine = engines.de();
102102
let mut decl = (*decl_engine.get(self)).clone();
103-
decl.subst(type_mapping, engines);
104-
decl_engine.replace(*self, decl);
103+
if decl.subst(type_mapping, engines).has_changes() {
104+
decl_engine.replace(*self, decl);
105+
HasChanges::Yes
106+
} else {
107+
HasChanges::No
108+
}
105109
}
106110
}
107111
impl SubstTypes for DeclId<TyTraitDecl> {
108-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
112+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
109113
let decl_engine = engines.de();
110114
let mut decl = (*decl_engine.get(self)).clone();
111-
decl.subst(type_mapping, engines);
112-
decl_engine.replace(*self, decl);
115+
if decl.subst(type_mapping, engines).has_changes() {
116+
decl_engine.replace(*self, decl);
117+
HasChanges::Yes
118+
} else {
119+
HasChanges::No
120+
}
113121
}
114122
}
115123
impl SubstTypes for DeclId<TyTraitFn> {
116-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
124+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
117125
let decl_engine = engines.de();
118126
let mut decl = (*decl_engine.get(self)).clone();
119-
decl.subst(type_mapping, engines);
120-
decl_engine.replace(*self, decl);
127+
if decl.subst(type_mapping, engines).has_changes() {
128+
decl_engine.replace(*self, decl);
129+
HasChanges::Yes
130+
} else {
131+
HasChanges::No
132+
}
121133
}
122134
}
123135
impl SubstTypes for DeclId<TyImplTrait> {
124-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
136+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
125137
let decl_engine = engines.de();
126138
let mut decl = (*decl_engine.get(self)).clone();
127-
decl.subst(type_mapping, engines);
128-
decl_engine.replace(*self, decl);
139+
if decl.subst(type_mapping, engines).has_changes() {
140+
decl_engine.replace(*self, decl);
141+
HasChanges::Yes
142+
} else {
143+
HasChanges::No
144+
}
129145
}
130146
}
131147
impl SubstTypes for DeclId<TyStructDecl> {
132-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
148+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
133149
let decl_engine = engines.de();
134150
let mut decl = (*decl_engine.get(self)).clone();
135-
decl.subst(type_mapping, engines);
136-
decl_engine.replace(*self, decl);
151+
if decl.subst(type_mapping, engines).has_changes() {
152+
decl_engine.replace(*self, decl);
153+
HasChanges::Yes
154+
} else {
155+
HasChanges::No
156+
}
137157
}
138158
}
139159
impl SubstTypes for DeclId<TyEnumDecl> {
140-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
160+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
141161
let decl_engine = engines.de();
142162
let mut decl = (*decl_engine.get(self)).clone();
143-
decl.subst(type_mapping, engines);
144-
decl_engine.replace(*self, decl);
163+
if decl.subst(type_mapping, engines).has_changes() {
164+
decl_engine.replace(*self, decl);
165+
HasChanges::Yes
166+
} else {
167+
HasChanges::No
168+
}
145169
}
146170
}
147171
impl SubstTypes for DeclId<TyTypeAliasDecl> {
148-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
172+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
149173
let decl_engine = engines.de();
150174
let mut decl = (*decl_engine.get(self)).clone();
151-
decl.subst(type_mapping, engines);
152-
decl_engine.replace(*self, decl);
175+
if decl.subst(type_mapping, engines).has_changes() {
176+
decl_engine.replace(*self, decl);
177+
HasChanges::Yes
178+
} else {
179+
HasChanges::No
180+
}
153181
}
154182
}
155183

156184
impl SubstTypes for DeclId<TyTraitType> {
157-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
185+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
158186
let decl_engine = engines.de();
159187
let mut decl = (*decl_engine.get(self)).clone();
160-
decl.subst(type_mapping, engines);
161-
decl_engine.replace(*self, decl);
188+
if decl.subst(type_mapping, engines).has_changes() {
189+
decl_engine.replace(*self, decl);
190+
HasChanges::Yes
191+
} else {
192+
HasChanges::No
193+
}
162194
}
163195
}

sway-core/src/decl_engine/ref.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,14 @@ where
112112
&self,
113113
type_mapping: &TypeSubstMap,
114114
engines: &Engines,
115-
) -> Self {
115+
) -> Option<Self> {
116116
let decl_engine = engines.de();
117117
let mut decl = (*decl_engine.get(&self.id)).clone();
118-
decl.subst(type_mapping, engines);
119-
decl_engine.insert(decl)
118+
if decl.subst(type_mapping, engines).has_changes() {
119+
Some(decl_engine.insert(decl))
120+
} else {
121+
None
122+
}
120123
}
121124
}
122125

@@ -145,13 +148,18 @@ where
145148
&self,
146149
type_mapping: &TypeSubstMap,
147150
engines: &Engines,
148-
) -> Self {
151+
) -> Option<Self> {
149152
let decl_engine = engines.de();
150153
let mut decl = (*decl_engine.get(&self.id)).clone();
151-
decl.subst(type_mapping, engines);
152-
decl_engine
153-
.insert(decl)
154-
.with_parent(decl_engine, self.id.into())
154+
if decl.subst(type_mapping, engines).has_changes() {
155+
Some(
156+
decl_engine
157+
.insert(decl)
158+
.with_parent(decl_engine, self.id.into()),
159+
)
160+
} else {
161+
None
162+
}
155163
}
156164
}
157165

@@ -291,11 +299,15 @@ where
291299
DeclEngine: DeclEngineIndex<T>,
292300
T: Named + Spanned + SubstTypes + Clone,
293301
{
294-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
302+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
295303
let decl_engine = engines.de();
296304
let mut decl = (*decl_engine.get(&self.id)).clone();
297-
decl.subst(type_mapping, engines);
298-
decl_engine.replace(self.id, decl);
305+
if decl.subst(type_mapping, engines).has_changes() {
306+
decl_engine.replace(self.id, decl);
307+
HasChanges::Yes
308+
} else {
309+
HasChanges::No
310+
}
299311
}
300312
}
301313

sway-core/src/language/ty/ast_node.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,11 @@ impl DebugWithEngines for TyAstNode {
6161
}
6262

6363
impl SubstTypes for TyAstNode {
64-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
64+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
6565
match self.content {
6666
TyAstNodeContent::Declaration(ref mut decl) => decl.subst(type_mapping, engines),
6767
TyAstNodeContent::Expression(ref mut expr) => expr.subst(type_mapping, engines),
68-
TyAstNodeContent::SideEffect(_) => (),
69-
TyAstNodeContent::Error(_, _) => (),
68+
TyAstNodeContent::SideEffect(_) | TyAstNodeContent::Error(_, _) => HasChanges::No,
7069
}
7170
}
7271
}

sway-core/src/language/ty/code_block.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ impl HashWithEngines for TyCodeBlock {
3838
}
3939

4040
impl SubstTypes for TyCodeBlock {
41-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
42-
self.contents
43-
.iter_mut()
44-
.for_each(|x| x.subst(type_mapping, engines));
41+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
42+
self.contents.subst(type_mapping, engines)
4543
}
4644
}
4745

sway-core/src/language/ty/declaration/constant.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use sway_types::{Ident, Named, Span, Spanned};
99
use crate::{
1010
decl_engine::{DeclMapping, ReplaceDecls},
1111
engine_threading::*,
12+
has_changes,
1213
language::{ty::*, CallPath, Visibility},
1314
semantic_analysis::TypeCheckContext,
1415
transform,
@@ -94,11 +95,11 @@ impl Spanned for TyConstantDecl {
9495
}
9596

9697
impl SubstTypes for TyConstantDecl {
97-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
98-
self.return_type.subst(type_mapping, engines);
99-
self.type_ascription.subst(type_mapping, engines);
100-
if let Some(expr) = &mut self.value {
101-
expr.subst(type_mapping, engines);
98+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
99+
has_changes! {
100+
self.return_type.subst(type_mapping, engines);
101+
self.type_ascription.subst(type_mapping, engines);
102+
self.value.subst(type_mapping, engines);
102103
}
103104
}
104105
}

sway-core/src/language/ty/declaration/declaration.rs

+10-26
Original file line numberDiff line numberDiff line change
@@ -296,55 +296,39 @@ impl HashWithEngines for TyDecl {
296296
}
297297

298298
impl SubstTypes for TyDecl {
299-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
299+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
300300
match self {
301301
TyDecl::VariableDecl(ref mut var_decl) => var_decl.subst(type_mapping, engines),
302302
TyDecl::FunctionDecl(FunctionDecl {
303303
ref mut decl_id, ..
304-
}) => {
305-
decl_id.subst(type_mapping, engines);
306-
}
304+
}) => decl_id.subst(type_mapping, engines),
307305
TyDecl::TraitDecl(TraitDecl {
308306
ref mut decl_id, ..
309-
}) => {
310-
decl_id.subst(type_mapping, engines);
311-
}
307+
}) => decl_id.subst(type_mapping, engines),
312308
TyDecl::StructDecl(StructDecl {
313309
ref mut decl_id, ..
314-
}) => {
315-
decl_id.subst(type_mapping, engines);
316-
}
310+
}) => decl_id.subst(type_mapping, engines),
317311
TyDecl::EnumDecl(EnumDecl {
318312
ref mut decl_id, ..
319-
}) => {
320-
decl_id.subst(type_mapping, engines);
321-
}
313+
}) => decl_id.subst(type_mapping, engines),
322314
TyDecl::EnumVariantDecl(EnumVariantDecl {
323315
ref mut enum_ref, ..
324-
}) => {
325-
enum_ref.subst(type_mapping, engines);
326-
}
316+
}) => enum_ref.subst(type_mapping, engines),
327317
TyDecl::ImplTrait(ImplTrait {
328318
ref mut decl_id, ..
329-
}) => {
330-
decl_id.subst(type_mapping, engines);
331-
}
319+
}) => decl_id.subst(type_mapping, engines),
332320
TyDecl::TypeAliasDecl(TypeAliasDecl {
333321
ref mut decl_id, ..
334-
}) => {
335-
decl_id.subst(type_mapping, engines);
336-
}
322+
}) => decl_id.subst(type_mapping, engines),
337323
TyDecl::TraitTypeDecl(TraitTypeDecl {
338324
ref mut decl_id, ..
339-
}) => {
340-
decl_id.subst(type_mapping, engines);
341-
}
325+
}) => decl_id.subst(type_mapping, engines),
342326
// generics in an ABI is unsupported by design
343327
TyDecl::AbiDecl(_)
344328
| TyDecl::ConstantDecl(_)
345329
| TyDecl::StorageDecl(_)
346330
| TyDecl::GenericTypeForFunctionScope(_)
347-
| TyDecl::ErrorRecovery(..) => (),
331+
| TyDecl::ErrorRecovery(..) => HasChanges::No,
348332
}
349333
}
350334
}

sway-core/src/language/ty/declaration/enum.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use sway_types::{Ident, Named, Span, Spanned};
1111

1212
use crate::{
1313
engine_threading::*,
14+
has_changes,
1415
language::{CallPath, Visibility},
1516
semantic_analysis::type_check_context::MonomorphizeHelper,
1617
transform,
@@ -63,13 +64,11 @@ impl HashWithEngines for TyEnumDecl {
6364
}
6465

6566
impl SubstTypes for TyEnumDecl {
66-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
67-
self.variants
68-
.iter_mut()
69-
.for_each(|x| x.subst(type_mapping, engines));
70-
self.type_parameters
71-
.iter_mut()
72-
.for_each(|x| x.subst(type_mapping, engines));
67+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
68+
has_changes! {
69+
self.variants.subst(type_mapping, engines);
70+
self.type_parameters.subst(type_mapping, engines);
71+
}
7372
}
7473
}
7574

@@ -173,7 +172,7 @@ impl OrdWithEngines for TyEnumVariant {
173172
}
174173

175174
impl SubstTypes for TyEnumVariant {
176-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
177-
self.type_argument.subst_inner(type_mapping, engines);
175+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
176+
self.type_argument.subst_inner(type_mapping, engines)
178177
}
179178
}

sway-core/src/language/ty/declaration/function.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use sha2::{Digest, Sha256};
88
use sway_error::handler::{ErrorEmitted, Handler};
99

1010
use crate::{
11+
has_changes,
1112
language::{parsed::FunctionDeclarationKind, CallPath},
1213
semantic_analysis::type_check_context::MonomorphizeHelper,
1314
transform::AttributeKind,
@@ -195,17 +196,13 @@ impl HashWithEngines for TyFunctionDecl {
195196
}
196197

197198
impl SubstTypes for TyFunctionDecl {
198-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
199-
self.type_parameters
200-
.iter_mut()
201-
.for_each(|x| x.subst(type_mapping, engines));
202-
self.parameters
203-
.iter_mut()
204-
.for_each(|x| x.subst(type_mapping, engines));
205-
self.return_type.subst(type_mapping, engines);
206-
self.body.subst(type_mapping, engines);
207-
if let Some(implementing_for) = self.implementing_for_typeid.as_mut() {
208-
implementing_for.subst(type_mapping, engines);
199+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
200+
has_changes! {
201+
self.type_parameters.subst(type_mapping, engines);
202+
self.parameters.subst(type_mapping, engines);
203+
self.return_type.subst(type_mapping, engines);
204+
self.body.subst(type_mapping, engines);
205+
self.implementing_for_typeid.subst(type_mapping, engines);
209206
}
210207
}
211208
}
@@ -525,8 +522,8 @@ impl HashWithEngines for TyFunctionParameter {
525522
}
526523

527524
impl SubstTypes for TyFunctionParameter {
528-
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
529-
self.type_argument.type_id.subst(type_mapping, engines);
525+
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
526+
self.type_argument.type_id.subst(type_mapping, engines)
530527
}
531528
}
532529

0 commit comments

Comments
 (0)