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

[BUG] cannot implicitly convert 'K' value to 'K' in assignment in condicional conformance #3437

Closed
msaelices opened this issue Aug 31, 2024 · 1 comment
Labels
bug Something isn't working mojo-repo Tag all issues with this label

Comments

@msaelices
Copy link
Contributor

msaelices commented Aug 31, 2024

Bug description

I think the Mojo compiler is not able to infer the correct types when there is a trait inheritance, and we use conditional conformance with two versions of the same method, like the __init__() below.

This is making a potential keyed-string x2 speed-up to fail: #3436

Steps to reproduce

Test code for reproducing the issue:

trait SizedHashable(Hashable, Sized):
    pass

@value
struct HashedInt(Hashable):
    var x: Int

    fn __hash__(self) -> UInt:
        return self.x

@value
struct DummyInt(SizedHashable):  # dummy example with minimum code

    fn __hash__(self) -> UInt:
        return 10 * len(self)

    fn __len__(self) -> Int:
        return 2

fn sized_hash[T: SizedHashable](x: T) -> Int:
    return hash(x) * len(x)

struct HashedKey[K: Hashable]:
    var key: K
    var hash: Int

    fn __init__[K: Hashable](inout self, key: K):
        self.key = key
        self.hash = hash(key)

    fn __init__[K: SizedHashable](inout self, key: K):
        self.key = key
        self.hash = sized_hash(key)

fn main() raises:
    var x = DummyInt()
    print(HashedKey(x).hash)

This is the error when compiling:

❯ mojo parametrized_traits.mojo 
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:37:20: error: no matching function in initialization
    print(HashedKey(x).hash)
          ~~~~~~~~~^~~
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:27:8: note: candidate not viable: could not deduce parameter 'K' of parent struct 'HashedKey'
    fn __init__[K: Hashable](inout self, key: K):
       ^
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:23:8: note:  struct declared here
struct HashedKey[K: Hashable]:
       ^
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:37:20: note: failed to infer parameter #0, parameter isn't used in any argument
    print(HashedKey(x).hash)
          ~~~~~~~~~^~~
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:31:8: note: candidate not viable: could not deduce parameter 'K' of parent struct 'HashedKey'
    fn __init__[K: SizedHashable](inout self, key: K):
       ^
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:23:8: note:  struct declared here
struct HashedKey[K: Hashable]:
       ^
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:37:20: note: failed to infer parameter #0, parameter isn't used in any argument
    print(HashedKey(x).hash)
          ~~~~~~~~~^~~
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:28:20: error: cannot implicitly convert 'K' value to 'K' in assignment
        self.key = key
                   ^~~
/home/msaelices/src/mojo-examples/parametrized_traits.mojo:32:20: error: cannot implicitly convert 'K' value to 'K' in assignment
        self.key = key
                   ^~~
mojo: error: failed to parse the provided Mojo source module

It's funny to receive a cannot implicitly convert 'K' value to 'K' in assignment error :)

Thanks to @helehex , I know that it can be fixed by explicitly type the self object, like so:

    fn __init__[K: SizedHashable](inout self: HashedKey[K], key: K):
        self.key = key
        self.hash = sized_hash(key)

To me, this should not be needed and be inferred by the compiler.

System information

❯ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.4 LTS"
❯ mojo -v
mojo 2024.8.3005 (12110d9c)
❯ modular -v
modular 0.8.0 (39a426b5)
@msaelices msaelices added bug Something isn't working mojo-repo Tag all issues with this label labels Aug 31, 2024
@msaelices msaelices changed the title [BUG] Cannot implicitly convert 'K' value to 'K' in assignment in parametrized traits [BUG] cannot implicitly convert 'K' value to 'K' in assignment in parametrized traits Aug 31, 2024
@msaelices msaelices changed the title [BUG] cannot implicitly convert 'K' value to 'K' in assignment in parametrized traits [BUG] cannot implicitly convert 'K' value to 'K' in assignment in condicional conformance Aug 31, 2024
msaelices added a commit to msaelices/mojo that referenced this issue Sep 1, 2024
Workaround of modularml#3437

Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Copy link
Contributor

Mogball commented Sep 17, 2024



trait SizedHashable(Sized, Hashable, Copyable):
    pass


@value
struct DummyInt(SizedHashable):  # dummy example with minimum code
    fn __hash__(self) -> UInt:
        return 10 * len(self)

    fn __len__(self) -> Int:
        return 2


fn sized_hash[T: SizedHashable](x: T) -> Int:
    return hash(x) * len(x)


struct HashedKey[K: Hashable]:
    var key: K
    var hash: Int

    fn __init__(inout self, key: K):
        self.key = key
        self.hash = hash(key)

    fn __init__[U: SizedHashable](inout self: HashedKey[U], key: U):
        self.key = key
        self.hash = sized_hash(key)


fn main() raises:
    var x = DummyInt()
    print(HashedKey(x).hash)

this works

@Mogball Mogball closed this as not planned Won't fix, can't repro, duplicate, stale Sep 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mojo-repo Tag all issues with this label
Projects
None yet
Development

No branches or pull requests

2 participants