Skip to content

Commit 3b8efe9

Browse files
esdrubalJoshuaBattysdankel
authored
Fixes insert_trait_implementaion for nested generics. (#6827)
## Description The unify_checker was returning false when comparing `MyOption<T>` with `T`. And filter_by_type_inner type substitution when adding methods from `MyOption<T>` to `MyOption<MyOption<T>>` was replacing MyOption<T> in its own type, ending up by inserting into type `MyOption<MyOption<MyOption<T>>>` instead of `MyOption<MyOption<T>>`. Fixes #6825 ## 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: Joshua Batty <joshpbatty@gmail.com> Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com>
1 parent 1bdd2ce commit 3b8efe9

File tree

8 files changed

+150
-6
lines changed

8 files changed

+150
-6
lines changed

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

-5
Original file line numberDiff line numberDiff line change
@@ -933,11 +933,6 @@ impl TraitMap {
933933
*map_type_id,
934934
*type_id,
935935
);
936-
type_id.subst(&SubstTypesContext::new(
937-
engines,
938-
&type_mapping,
939-
matches!(code_block_first_pass, CodeBlockFirstPass::No),
940-
));
941936
let trait_items: TraitItems = map_trait_items
942937
.clone()
943938
.into_iter()

sway-core/src/type_system/unify/unify_check.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,8 @@ impl<'a> UnifyCheck<'a> {
510510
// any type can be coerced into a generic,
511511
// except if the type already contains the generic
512512
(_e, _g @ UnknownGeneric { .. }) => {
513-
!OccursCheck::new(self.engines).check(right, left)
513+
matches!(self.mode, ConstraintSubset)
514+
|| !OccursCheck::new(self.engines).check(right, left)
514515
}
515516

516517
(Alias { ty: l_ty, .. }, Alias { ty: r_ty, .. }) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[[package]]
2+
name = "core"
3+
source = "path+from-root-9C31758901D851EE"
4+
5+
[[package]]
6+
name = "nested_generics"
7+
source = "member"
8+
dependencies = ["std"]
9+
10+
[[package]]
11+
name = "std"
12+
source = "path+from-root-9C31758901D851EE"
13+
dependencies = ["core"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[project]
2+
authors = ["Fuel Labs <contact@fuel.sh>"]
3+
entry = "main.sw"
4+
license = "Apache-2.0"
5+
name = "nested_generics"
6+
7+
[dependencies]
8+
std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"configurables": [],
3+
"functions": [
4+
{
5+
"attributes": null,
6+
"inputs": [],
7+
"name": "main",
8+
"output": {
9+
"name": "",
10+
"type": 0,
11+
"typeArguments": null
12+
}
13+
}
14+
],
15+
"loggedTypes": [],
16+
"messagesTypes": [],
17+
"types": [
18+
{
19+
"components": null,
20+
"type": "bool",
21+
"typeId": 0,
22+
"typeParameters": null
23+
}
24+
]
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"concreteTypes": [
3+
{
4+
"concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903",
5+
"type": "bool"
6+
}
7+
],
8+
"configurables": [],
9+
"encodingVersion": "1",
10+
"functions": [
11+
{
12+
"attributes": null,
13+
"inputs": [],
14+
"name": "main",
15+
"output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
16+
}
17+
],
18+
"loggedTypes": [],
19+
"messagesTypes": [],
20+
"metadataTypes": [],
21+
"programType": "script",
22+
"specVersion": "1"
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
script;
2+
3+
enum MyOption<T> {
4+
Some: T,
5+
None: (),
6+
}
7+
8+
impl<T> MyOption<T> {
9+
fn new() -> Self {
10+
Self::None
11+
}
12+
13+
fn is_none(self) -> bool {
14+
true
15+
}
16+
}
17+
18+
fn generic_arg_in_function_method_call<T>() {
19+
let o: MyOption<u64> = MyOption::None;
20+
let _ = o.is_none();
21+
22+
let o: MyOption<MyOption<u64>> = MyOption::None;
23+
let _ = o.is_none();
24+
25+
let o: MyOption<T> = MyOption::None;
26+
let _ = o.is_none();
27+
28+
let o: MyOption<MyOption<T>> = MyOption::None;
29+
let _ = o.is_none();
30+
31+
let _ = MyOption::is_none(o);
32+
}
33+
34+
fn generic_arg_in_function_associated_function_call<T>() {
35+
let _ = MyOption::<u64>::new();
36+
let o: MyOption<u64> = MyOption::new();
37+
38+
let _ = MyOption::<MyOption<u64>>::new();
39+
let o: MyOption<MyOption<u64>> = MyOption::new();
40+
41+
let _ = MyOption::<T>::new();
42+
let o: MyOption<T> = MyOption::new();
43+
44+
let _ = MyOption::<MyOption<T>>::new();
45+
}
46+
47+
struct S<T> { }
48+
49+
impl<T> S<T> {
50+
fn generic_arg_in_type() {
51+
let o: MyOption<u64> = MyOption::None;
52+
let _ = o.is_none();
53+
54+
let o: MyOption<MyOption<u64>> = MyOption::None;
55+
let _ = o.is_none();
56+
57+
let o: MyOption<T> = MyOption::None;
58+
let _ = o.is_none();
59+
60+
let o: MyOption<MyOption<T>> = MyOption::None;
61+
let _ = o.is_none();
62+
63+
let _ = MyOption::is_none(o);
64+
}
65+
}
66+
67+
pub fn main() -> bool {
68+
generic_arg_in_function_method_call::<(())>();
69+
S::<()>::generic_arg_in_type();
70+
71+
generic_arg_in_function_associated_function_call::<()>();
72+
73+
true
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
category = "run"
2+
expected_result = { action = "return", value = 1 }
3+
expected_result_new_encoding = { action = "return_data", value = "01" }
4+
validate_abi = true
5+
expected_warnings = 30

0 commit comments

Comments
 (0)