Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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] Unexpected constructor resolution due to implicit type casting #3351

Open
jjvraw opened this issue Aug 2, 2024 · 0 comments
Open

[BUG] Unexpected constructor resolution due to implicit type casting #3351

jjvraw opened this issue Aug 2, 2024 · 0 comments
Labels
bug Something isn't working Initiative: LSP mojo-repo Tag all issues with this label

Comments

@jjvraw
Copy link
Contributor

jjvraw commented Aug 2, 2024

Bug description

The interaction between implicit conversions and constructor overloading can lead to unintuitive constructor selection, particularly when multiple constructors are viable through different sets of implicit conversions.

For instance, in the provided example there exists an overloaded __init__, one accepting three SIMD[DType.uint8, 1] and one accepting a SIMD[DType.uint8, 4], Bool and Int. If we consider the calls to initialise the struct, despite all these implicit casts useful independently, this appears to lead in a preference of the second __init__ function, which was unintended in my case.

Perhaps there is an underlying feature-request for warnings on unused default arguments as well?

On the contrary, changing the second constructor to

fn __init__(
        inout self,
        data: SIMD[DType.uint8, 4],
        unused1: Bool = False,
        unused2: Bool = False,
    ):
        self.data = data

prompts the mojo-lsp-server to return the following Error:

ambiguous call to `__init__`, each candidate requires 3 implicit conversions, disambiguate with and explicit cast

However, the compiler still executes the script.

The LSP appears to have an existing check for ambiguous calls, which is not mirrored in the compiler's behavior. This seems to be a bug. Additionally, the discreprency between handling Bool, Bool and Bool, Int arguments does not seem consistent in defining an ambiguous call.

Steps to reproduce

struct Wrapper:
    var data: SIMD[DType.uint8, 4]

    fn __init__(inout self, a: UInt8, b: UInt8, c: UInt8):
        self.data = SIMD[DType.uint8, 4](a, b, c, 0)

    fn __init__(
        inout self,
        data: SIMD[DType.uint8, 4],
        unused1: Bool = False,
        # unused2: Int = False,
    ):
        self.data = data

fn main():
    var a = Wrapper(0, 30, 0)
    var b = Wrapper(30, 0, 30)

    print("a", a.data)
    print("b", b.data)

unused2 commented

a [0, 30, 0, 0]
b [30, 0, 30, 0]

unused2 uncommented

a [0, 0, 0, 0]
b [30, 30, 30, 30]

System information

- MacOS
- mojo 2024.8.105 (1fa11138)
- modular 0.9.1 (3460d12e)
@jjvraw jjvraw added bug Something isn't working mojo-repo Tag all issues with this label labels Aug 2, 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 Initiative: LSP mojo-repo Tag all issues with this label
Projects
None yet
Development

No branches or pull requests

2 participants