Skip to content

Commit

Permalink
Fixes insert_trait_implementaion for nested generics. (#6827)
Browse files Browse the repository at this point in the history
## 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 <[email protected]>
Co-authored-by: Sophie Dankel <[email protected]>
  • Loading branch information
3 people authored Jan 28, 2025
1 parent 1bdd2ce commit 3b8efe9
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 6 deletions.
5 changes: 0 additions & 5 deletions sway-core/src/semantic_analysis/namespace/trait_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -933,11 +933,6 @@ impl TraitMap {
*map_type_id,
*type_id,
);
type_id.subst(&SubstTypesContext::new(
engines,
&type_mapping,
matches!(code_block_first_pass, CodeBlockFirstPass::No),
));
let trait_items: TraitItems = map_trait_items
.clone()
.into_iter()
Expand Down
3 changes: 2 additions & 1 deletion sway-core/src/type_system/unify/unify_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,8 @@ impl<'a> UnifyCheck<'a> {
// any type can be coerced into a generic,
// except if the type already contains the generic
(_e, _g @ UnknownGeneric { .. }) => {
!OccursCheck::new(self.engines).check(right, left)
matches!(self.mode, ConstraintSubset)
|| !OccursCheck::new(self.engines).check(right, left)
}

(Alias { ty: l_ty, .. }, Alias { ty: r_ty, .. }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[package]]
name = "core"
source = "path+from-root-9C31758901D851EE"

[[package]]
name = "nested_generics"
source = "member"
dependencies = ["std"]

[[package]]
name = "std"
source = "path+from-root-9C31758901D851EE"
dependencies = ["core"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
name = "nested_generics"

[dependencies]
std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"configurables": [],
"functions": [
{
"attributes": null,
"inputs": [],
"name": "main",
"output": {
"name": "",
"type": 0,
"typeArguments": null
}
}
],
"loggedTypes": [],
"messagesTypes": [],
"types": [
{
"components": null,
"type": "bool",
"typeId": 0,
"typeParameters": null
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"concreteTypes": [
{
"concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903",
"type": "bool"
}
],
"configurables": [],
"encodingVersion": "1",
"functions": [
{
"attributes": null,
"inputs": [],
"name": "main",
"output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
}
],
"loggedTypes": [],
"messagesTypes": [],
"metadataTypes": [],
"programType": "script",
"specVersion": "1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
script;

enum MyOption<T> {
Some: T,
None: (),
}

impl<T> MyOption<T> {
fn new() -> Self {
Self::None
}

fn is_none(self) -> bool {
true
}
}

fn generic_arg_in_function_method_call<T>() {
let o: MyOption<u64> = MyOption::None;
let _ = o.is_none();

let o: MyOption<MyOption<u64>> = MyOption::None;
let _ = o.is_none();

let o: MyOption<T> = MyOption::None;
let _ = o.is_none();

let o: MyOption<MyOption<T>> = MyOption::None;
let _ = o.is_none();

let _ = MyOption::is_none(o);
}

fn generic_arg_in_function_associated_function_call<T>() {
let _ = MyOption::<u64>::new();
let o: MyOption<u64> = MyOption::new();

let _ = MyOption::<MyOption<u64>>::new();
let o: MyOption<MyOption<u64>> = MyOption::new();

let _ = MyOption::<T>::new();
let o: MyOption<T> = MyOption::new();

let _ = MyOption::<MyOption<T>>::new();
}

struct S<T> { }

impl<T> S<T> {
fn generic_arg_in_type() {
let o: MyOption<u64> = MyOption::None;
let _ = o.is_none();

let o: MyOption<MyOption<u64>> = MyOption::None;
let _ = o.is_none();

let o: MyOption<T> = MyOption::None;
let _ = o.is_none();

let o: MyOption<MyOption<T>> = MyOption::None;
let _ = o.is_none();

let _ = MyOption::is_none(o);
}
}

pub fn main() -> bool {
generic_arg_in_function_method_call::<(())>();
S::<()>::generic_arg_in_type();

generic_arg_in_function_associated_function_call::<()>();

true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
category = "run"
expected_result = { action = "return", value = 1 }
expected_result_new_encoding = { action = "return_data", value = "01" }
validate_abi = true
expected_warnings = 30

0 comments on commit 3b8efe9

Please sign in to comment.