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

First use of a generic method fixes its generic type #1628

Closed
AlicanC opened this issue May 22, 2022 · 0 comments · Fixed by #2195
Closed

First use of a generic method fixes its generic type #1628

AlicanC opened this issue May 22, 2022 · 0 comments · Fixed by #2195
Assignees
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen P: critical Should be looked at before anything else

Comments

@AlicanC
Copy link
Contributor

AlicanC commented May 22, 2022

Here, the first use of fn write<T>(self, val: T, offset: u64) with a bool sets its T to bool and prevents it from being called with a u64 (or something else) later.

script;

use std::mem::*;
use std::intrinsics::*;
use std::assert::assert;

struct TestStruct {
    boo: bool,
    uwu: u64
}

fn main() -> bool {
    // Create a struct
    let foo = TestStruct { boo: true, uwu: 42 };
    let foo_len = size_of::<TestStruct>();
    assert(foo_len == 16);

    // Create a clone of the struct
    let buf = ~Buffer::alloc(foo_len);
    buf.write(true, 0);
    buf.write(42, size_of::<bool>());
//            ^^ This parameter was declared as type bool, but argument of type u64 was provided.
    let foo: TestStruct = buf.into_unchecked();
    assert(foo.boo == true);
    assert(foo.uwu == 42);

    true
}

The Buffer in question:

pub struct Buffer {
    ptr: Pointer,
    len: u64
}

impl Buffer {
    // ... snip ...

    /// Writes the given value into the buffer
    pub fn write<T>(self, val: T, offset: u64) {
        if is_reference_type::<T>() {
            let ptr = ~Pointer::from(val);
            let len = size_of::<T>();
            
            // We can't reference `self.write_unchecked` like this:
            // self.write_unchecked(ptr, len, offset);

            // Instead we inline
            copy(self.ptr.with_offset(offset), ptr, len);
        } else {
            let dst_ptr = self.ptr.with_offset(offset);
            asm(ptr: dst_ptr.val, val: val) {
                sw ptr val i0;
            };
        }
    }

    // ... snip ...
}

You can find the full code of Buffer (and std::mem) here: https://github.com/FuelLabs/sway/blob/522bf95b7f06e679161712ae4a0821c74f318a2c/sway-lib-std/src/mem.sw

@AlicanC AlicanC added the bug Something isn't working label May 22, 2022
@adlerjohn adlerjohn added the compiler General compiler. Should eventually become more specific as the issue is triaged label May 22, 2022
@mohammadfawaz mohammadfawaz added the P: critical Should be looked at before anything else label May 23, 2022
@mohammadfawaz mohammadfawaz added compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen and removed compiler General compiler. Should eventually become more specific as the issue is triaged labels May 30, 2022
@emilyaherbert emilyaherbert assigned emilyaherbert and unassigned sezna Jun 7, 2022
@emilyaherbert emilyaherbert linked a pull request Jun 30, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen P: critical Should be looked at before anything else
Projects
Archived in project
5 participants