Skip to content

Commit 7e209ea

Browse files
esdrubalsdankelJoshuaBatty
authored
Fixes ignored where clause. (#5799)
## Description When we have a impl type parameter that has a method where clause, the type parameter in the namespace would not include the method where clause. This fix shadows the impl type parameter with a new method type parameter that contains the where clause. PartialEqWithEnginesContext is now used to pass down engines and other variables in PartialEqWithEngines. OrdWithEnginesContext is now used to pass down engines and other variables in OrdWithEngines. This allows us to pass the variable is_inside_trait_constraint and break the infinite recursion when where clauses such as `T:MyTrait<T>` are used. Fixes #5735 Also fixes #5693 ## Checklist - [x] I have linked to any relevant issues. - [x] 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) - [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. --------- Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com> Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
1 parent e0593b9 commit 7e209ea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+682
-381
lines changed

sway-core/src/decl_engine/engine.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,17 @@ impl DeclEngine {
261261
(
262262
AssociatedItemDeclId::TraitFn(x_id),
263263
AssociatedItemDeclId::TraitFn(curr_parent_id),
264-
) => self.get(x_id).eq(&self.get(curr_parent_id), engines),
264+
) => self.get(x_id).eq(
265+
&self.get(curr_parent_id),
266+
&PartialEqWithEnginesContext::new(engines),
267+
),
265268
(
266269
AssociatedItemDeclId::Function(x_id),
267270
AssociatedItemDeclId::Function(curr_parent_id),
268-
) => self.get(x_id).eq(&self.get(curr_parent_id), engines),
271+
) => self.get(x_id).eq(
272+
&self.get(curr_parent_id),
273+
&PartialEqWithEnginesContext::new(engines),
274+
),
269275
_ => false,
270276
}) {
271277
left_to_check.push_back(curr_parent.clone());

sway-core/src/decl_engine/ref.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ where
196196
DeclEngine: DeclEngineIndex<T>,
197197
T: Named + Spanned + PartialEqWithEngines,
198198
{
199-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
200-
let decl_engine = engines.de();
199+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
200+
let decl_engine = ctx.engines().de();
201201
let DeclRef {
202202
name: ln,
203203
id: lid,
@@ -216,7 +216,7 @@ where
216216
// temporarily omitted
217217
subst_list: _,
218218
} = other;
219-
ln == rn && decl_engine.get(lid).eq(&decl_engine.get(rid), engines)
219+
ln == rn && decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
220220
}
221221
}
222222

@@ -243,18 +243,18 @@ where
243243

244244
impl EqWithEngines for DeclRefMixedInterface {}
245245
impl PartialEqWithEngines for DeclRefMixedInterface {
246-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
247-
let decl_engine = engines.de();
246+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
247+
let decl_engine = ctx.engines().de();
248248
match (&self.id, &other.id) {
249249
(InterfaceDeclId::Abi(self_id), InterfaceDeclId::Abi(other_id)) => {
250250
let left = decl_engine.get(self_id);
251251
let right = decl_engine.get(other_id);
252-
self.name == other.name && left.eq(&right, engines)
252+
self.name == other.name && left.eq(&right, ctx)
253253
}
254254
(InterfaceDeclId::Trait(self_id), InterfaceDeclId::Trait(other_id)) => {
255255
let left = decl_engine.get(self_id);
256256
let right = decl_engine.get(other_id);
257-
self.name == other.name && left.eq(&right, engines)
257+
self.name == other.name && left.eq(&right, ctx)
258258
}
259259
_ => false,
260260
}

sway-core/src/engine_threading.rs

+84-21
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ impl<T: HashWithEngines> Hash for WithEngines<'_, T> {
107107

108108
impl<T: PartialEqWithEngines> PartialEq for WithEngines<'_, T> {
109109
fn eq(&self, rhs: &Self) -> bool {
110-
self.thing.eq(&rhs.thing, self.engines)
110+
self.thing
111+
.eq(&rhs.thing, &PartialEqWithEnginesContext::new(self.engines))
111112
}
112113
}
113114

@@ -118,7 +119,10 @@ where
118119
T: PartialEqWithEngines,
119120
{
120121
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
121-
Some(self.thing.cmp(&other.thing, self.engines))
122+
Some(
123+
self.thing
124+
.cmp(&other.thing, &OrdWithEnginesContext::new(self.engines)),
125+
)
122126
}
123127
}
124128

@@ -127,7 +131,8 @@ where
127131
T: EqWithEngines,
128132
{
129133
fn cmp(&self, other: &Self) -> Ordering {
130-
self.thing.cmp(&other.thing, self.engines)
134+
self.thing
135+
.cmp(&other.thing, &OrdWithEnginesContext::new(self.engines))
131136
}
132137
}
133138

@@ -246,30 +251,88 @@ impl<T: HashWithEngines> HashWithEngines for Box<T> {
246251

247252
pub trait EqWithEngines: PartialEqWithEngines {}
248253

254+
pub struct PartialEqWithEnginesContext<'a> {
255+
engines: &'a Engines,
256+
is_inside_trait_constraint: bool,
257+
}
258+
259+
impl<'a> PartialEqWithEnginesContext<'a> {
260+
pub(crate) fn new(engines: &'a Engines) -> Self {
261+
Self {
262+
engines,
263+
is_inside_trait_constraint: false,
264+
}
265+
}
266+
267+
pub(crate) fn with_is_inside_trait_constraint(&self) -> Self {
268+
Self {
269+
is_inside_trait_constraint: true,
270+
..*self
271+
}
272+
}
273+
274+
pub(crate) fn engines(&self) -> &Engines {
275+
self.engines
276+
}
277+
278+
pub(crate) fn is_inside_trait_constraint(&self) -> bool {
279+
self.is_inside_trait_constraint
280+
}
281+
}
282+
249283
pub trait PartialEqWithEngines {
250-
fn eq(&self, other: &Self, engines: &Engines) -> bool;
284+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool;
285+
}
286+
287+
pub struct OrdWithEnginesContext<'a> {
288+
engines: &'a Engines,
289+
is_inside_trait_constraint: bool,
290+
}
291+
292+
impl<'a> OrdWithEnginesContext<'a> {
293+
pub(crate) fn new(engines: &'a Engines) -> Self {
294+
Self {
295+
engines,
296+
is_inside_trait_constraint: false,
297+
}
298+
}
299+
300+
pub(crate) fn with_is_inside_trait_constraint(&self) -> Self {
301+
Self {
302+
is_inside_trait_constraint: true,
303+
..*self
304+
}
305+
}
306+
307+
pub(crate) fn engines(&self) -> &Engines {
308+
self.engines
309+
}
310+
311+
pub(crate) fn is_inside_trait_constraint(&self) -> bool {
312+
self.is_inside_trait_constraint
313+
}
251314
}
252315

253316
pub trait OrdWithEngines {
254-
fn cmp(&self, other: &Self, engines: &Engines) -> Ordering;
317+
fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering;
255318
}
256319

257320
impl<T: EqWithEngines + ?Sized> EqWithEngines for &T {}
258321
impl<T: PartialEqWithEngines + ?Sized> PartialEqWithEngines for &T {
259-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
260-
(*self).eq(*other, engines)
322+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
323+
(*self).eq(*other, ctx)
261324
}
262325
}
263326
impl<T: OrdWithEngines + ?Sized> OrdWithEngines for &T {
264-
fn cmp(&self, other: &Self, engines: &Engines) -> Ordering {
265-
(*self).cmp(*other, engines)
327+
fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering {
328+
(*self).cmp(*other, ctx)
266329
}
267330
}
268331

269332
impl<T: OrdWithEngines> OrdWithEngines for Option<T> {
270-
fn cmp(&self, other: &Self, engines: &Engines) -> Ordering {
333+
fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering {
271334
match (self, other) {
272-
(Some(x), Some(y)) => x.cmp(y, engines),
335+
(Some(x), Some(y)) => x.cmp(y, ctx),
273336
(Some(_), None) => Ordering::Less,
274337
(None, Some(_)) => Ordering::Greater,
275338
(None, None) => Ordering::Equal,
@@ -278,40 +341,40 @@ impl<T: OrdWithEngines> OrdWithEngines for Option<T> {
278341
}
279342

280343
impl<T: OrdWithEngines> OrdWithEngines for Box<T> {
281-
fn cmp(&self, other: &Self, engines: &Engines) -> Ordering {
282-
(**self).cmp(&(**other), engines)
344+
fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering {
345+
(**self).cmp(&(**other), ctx)
283346
}
284347
}
285348

286349
impl<T: EqWithEngines> EqWithEngines for Option<T> {}
287350
impl<T: PartialEqWithEngines> PartialEqWithEngines for Option<T> {
288-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
351+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
289352
match (self, other) {
290353
(None, None) => true,
291-
(Some(x), Some(y)) => x.eq(y, engines),
354+
(Some(x), Some(y)) => x.eq(y, ctx),
292355
_ => false,
293356
}
294357
}
295358
}
296359

297360
impl<T: EqWithEngines> EqWithEngines for Box<T> {}
298361
impl<T: PartialEqWithEngines> PartialEqWithEngines for Box<T> {
299-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
300-
(**self).eq(&(**other), engines)
362+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
363+
(**self).eq(&(**other), ctx)
301364
}
302365
}
303366

304367
impl<T: EqWithEngines> EqWithEngines for [T] {}
305368
impl<T: PartialEqWithEngines> PartialEqWithEngines for [T] {
306-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
307-
self.len() == other.len() && self.iter().zip(other.iter()).all(|(x, y)| x.eq(y, engines))
369+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
370+
self.len() == other.len() && self.iter().zip(other.iter()).all(|(x, y)| x.eq(y, ctx))
308371
}
309372
}
310373
impl<T: OrdWithEngines> OrdWithEngines for [T] {
311-
fn cmp(&self, other: &Self, engines: &Engines) -> Ordering {
374+
fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering {
312375
self.iter()
313376
.zip(other.iter())
314-
.map(|(x, y)| x.cmp(y, engines))
377+
.map(|(x, y)| x.cmp(y, ctx))
315378
.find(|o| o.is_ne())
316379
.unwrap_or_else(|| self.len().cmp(&other.len()))
317380
}

sway-core/src/ir_generation/function.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,10 @@ impl<'eng> FnCompiler<'eng> {
952952
// Validate that the val_exp is of the right type. We couldn't do it
953953
// earlier during type checking as the type arguments may not have been resolved.
954954
let val_ty = engines.te().get_unaliased(val_exp.return_type);
955-
if !val_ty.eq(&TypeInfo::RawUntypedPtr, engines) {
955+
if !val_ty.eq(
956+
&TypeInfo::RawUntypedPtr,
957+
&PartialEqWithEnginesContext::new(engines),
958+
) {
956959
return Err(CompileError::IntrinsicUnsupportedArgType {
957960
name: kind.to_string(),
958961
span,

sway-core/src/language/call_path.rs

+10-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88
use crate::{
99
engine_threading::{
1010
DebugWithEngines, DisplayWithEngines, EqWithEngines, HashWithEngines, OrdWithEngines,
11-
PartialEqWithEngines,
11+
OrdWithEnginesContext, PartialEqWithEngines, PartialEqWithEnginesContext,
1212
},
1313
Engines, Ident, Namespace,
1414
};
@@ -40,18 +40,17 @@ impl HashWithEngines for CallPathTree {
4040

4141
impl EqWithEngines for CallPathTree {}
4242
impl PartialEqWithEngines for CallPathTree {
43-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
43+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
4444
let CallPathTree {
4545
qualified_call_path,
4646
children,
4747
} = self;
48-
qualified_call_path.eq(&other.qualified_call_path, engines)
49-
&& children.eq(&other.children, engines)
48+
qualified_call_path.eq(&other.qualified_call_path, ctx) && children.eq(&other.children, ctx)
5049
}
5150
}
5251

5352
impl OrdWithEngines for CallPathTree {
54-
fn cmp(&self, other: &Self, engines: &Engines) -> Ordering {
53+
fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering {
5554
let CallPathTree {
5655
qualified_call_path: l_call_path,
5756
children: l_children,
@@ -61,8 +60,8 @@ impl OrdWithEngines for CallPathTree {
6160
children: r_children,
6261
} = other;
6362
l_call_path
64-
.cmp(r_call_path, engines)
65-
.then_with(|| l_children.cmp(r_children, engines))
63+
.cmp(r_call_path, ctx)
64+
.then_with(|| l_children.cmp(r_children, ctx))
6665
}
6766
}
6867

@@ -121,18 +120,17 @@ impl HashWithEngines for QualifiedCallPath {
121120

122121
impl EqWithEngines for QualifiedCallPath {}
123122
impl PartialEqWithEngines for QualifiedCallPath {
124-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
123+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
125124
let QualifiedCallPath {
126125
call_path,
127126
qualified_path_root,
128127
} = self;
129-
call_path.eq(&other.call_path)
130-
&& qualified_path_root.eq(&other.qualified_path_root, engines)
128+
call_path.eq(&other.call_path) && qualified_path_root.eq(&other.qualified_path_root, ctx)
131129
}
132130
}
133131

134132
impl OrdWithEngines for QualifiedCallPath {
135-
fn cmp(&self, other: &Self, engines: &Engines) -> Ordering {
133+
fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering {
136134
let QualifiedCallPath {
137135
call_path: l_call_path,
138136
qualified_path_root: l_qualified_path_root,
@@ -143,7 +141,7 @@ impl OrdWithEngines for QualifiedCallPath {
143141
} = other;
144142
l_call_path
145143
.cmp(r_call_path)
146-
.then_with(|| l_qualified_path_root.cmp(r_qualified_path_root, engines))
144+
.then_with(|| l_qualified_path_root.cmp(r_qualified_path_root, ctx))
147145
}
148146
}
149147

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ pub struct FunctionParameter {
4646

4747
impl EqWithEngines for FunctionParameter {}
4848
impl PartialEqWithEngines for FunctionParameter {
49-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
49+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
5050
self.name == other.name
5151
&& self.is_reference == other.is_reference
5252
&& self.is_mutable == other.is_mutable
5353
&& self.mutability_span == other.mutability_span
54-
&& self.type_argument.eq(&other.type_argument, engines)
54+
&& self.type_argument.eq(&other.type_argument, ctx)
5555
}
5656
}
5757

sway-core/src/language/parsed/declaration/trait.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl Spanned for Supertrait {
4747

4848
impl EqWithEngines for Supertrait {}
4949
impl PartialEqWithEngines for Supertrait {
50-
fn eq(&self, other: &Self, engines: &Engines) -> bool {
50+
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
5151
let Supertrait {
5252
name: ln,
5353
decl_ref: ldr,
@@ -56,7 +56,7 @@ impl PartialEqWithEngines for Supertrait {
5656
name: rn,
5757
decl_ref: rdr,
5858
} = other;
59-
ln == rn && ldr.eq(rdr, engines)
59+
ln == rn && ldr.eq(rdr, ctx)
6060
}
6161
}
6262

0 commit comments

Comments
 (0)