Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type Propagation in Generics #6372

Closed
IGI-111 opened this issue Aug 7, 2024 · 1 comment · Fixed by #6455
Closed

Type Propagation in Generics #6372

IGI-111 opened this issue Aug 7, 2024 · 1 comment · Fixed by #6455
Assignees
Labels
audit-report Related to the audit report bug Something isn't working P: high Should be looked at if there are no critical issues left

Comments

@IGI-111
Copy link
Contributor

IGI-111 commented Aug 7, 2024

CS-FSSA-006

When the type inference meets a generic type with a placeholder it creates an unknown generic type.
Normally, when later more infomration is found the type should be updated. However, this is not the case
for the following example:

script;
trait Wrap {
 fn wrap(self) -> Vec<Self>;
}
impl<T> Wrap for Vec<T> {
 fn wrap(self) -> Vec<Self> {
 let mut v = Vec::new();
 v.push(self);
 v
 }
}
fn foo() {
 let mut a: Vec<_> = Vec::new();
 let b: Vec<Vec<_>> = a.wrap();
 let c: Vec<Vec<Vec<u8>>> = b.wrap();
 a.push("str");
}
fn main() {}

Here the types, and more specifically the unique type ids assigned to values a, b and c respectively
aren't properly updated due to the way unification is implemented. As a result, the compiler is not able to
deduce that a cannot be a vector of strings if c is a Vec<Vec<Vec>>.

@IGI-111 IGI-111 added bug Something isn't working P: high Should be looked at if there are no critical issues left audit-report Related to the audit report labels Aug 7, 2024
@tritao
Copy link
Contributor

tritao commented Aug 20, 2024

Seems like this is trait-specific, the following errors out as expected:

library;

struct Vec<T> {
}

impl<T> Vec<T> {
  fn new() -> Self { return Self {}}
  fn push(self, elem: T) {}
  fn wrap(self) -> Vec<Self> {
   let mut v = Vec::new();
   v.push(self);
   v
  }
}

fn main() {
 let mut a: Vec<_> = Vec::new();
 let b: Vec<Vec<_>> = a.wrap();
 let c: Vec<Vec<Vec<u8>>> = b.wrap();
 a.push("str");
}
error
  --> main.sw:20:9
   |
18 | 
19 |  let c: Vec<Vec<Vec<u8>>> = b.wrap();
20 |  a.push("str");
   |         ^^^^^ This parameter was declared as type u8, but argument of type str was provided.
21 | }
   |
____ 

tritao added a commit to tritao/sway that referenced this issue Aug 22, 2024
Trait methods end up passing an extra type parameter related to self.

What was happening is that we ended up creating a placeholder of a
placeholder in some cases, which threw the type inferencing system off.

The fix is to avoid creating a new type for a given type parameter if
its already a placeholder.

Fixes FuelLabs#6372.
tritao added a commit to tritao/sway that referenced this issue Aug 22, 2024
Trait methods end up passing an extra type parameter related to self.

What was happening is that we ended up creating a placeholder of a
placeholder in some cases, which threw the type inferencing system off.

The fix is to avoid creating a new type for a given type parameter if
its already a placeholder.

Fixes FuelLabs#6372.
tritao added a commit that referenced this issue Aug 24, 2024
## Description

Trait methods end up passing an extra type parameter related to self.

What was happening is that we ended up creating a placeholder of a
placeholder in some cases, which threw the type inferencing system off.

The fix is to avoid creating a new type for a given type parameter if
its already a placeholder.

Fixes #6372.

## 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
audit-report Related to the audit report bug Something isn't working P: high Should be looked at if there are no critical issues left
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants