modular / modular/modular

[BUG] Nightly Async Mojo. error: LLVM Translation failed for operation: builtin.unrealized_conversion_cast

Open
#3,607 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug mojo mojo-repo
Dominant language
Mojo
Stars
29.8k
Forks
3.2k
PR merge metrics
No merged PRs in 30d

Description

Bug description

I'm guessing async is exposed in nightly and not stable because it is still in development, but I thought we could at least build something with it :/

The moment I try to do:

async fn pseudo_async_send_wrapper():
    ...

fn main():
    await pseudo_async_send_wrapper()

I get the error mentioned in the title

If I try to add async to main i.e. async fn main():

error: expected 'main' function to have no arguments

Fully sync works fine:

from sys.ffi import external_call
from sys.info import os_is_windows, is_64bit
from memory import UnsafePointer, stack_allocation, memcpy


fn pseudo_async_send_wrapper():
    var fd: Int = 0
    var length: Int = 0
    var flags: Int = 0
    var res = int(send(fd, UnsafePointer[C.void](), length, flags))
    if res == -1:
        print(char_ptr_to_string(strerror(get_errno())), file=2)
    else:
        print(res)

fn main():
    pseudo_async_send_wrapper()

fn send(
    socket: C.int, buffer: UnsafePointer[C.void], length: size_t, flags: C.int
) -> ssize_t:
    """Libc POSIX `send` function.

    Args:
        socket: The socket's file descriptor.
        buffer: Points to the buffer containing the message to send.
        length: Specifies the length of the message in bytes.
        flags: Specifies the type of message transmission.

    Returns:
        The number of bytes sent. Otherwise, -1 shall be returned and errno set
        to indicate the error.

    Notes:
        [Reference](https://man7.org/linux/man-pages/man3/send.3p.html).
        Fn signature: `ssize_t send(int socket, const void *buffer,
            size_t length, int flags)`.
    """
    return external_call[
        "send", ssize_t, C.int, UnsafePointer[C.void], size_t, C.int
    ](socket, buffer, length, flags)


struct C:
    """C types. This assumes that the platform is 32 or 64 bit, and char is
    always 8 bit (POSIX standard).
    """

    alias char = Int8
    """Type: `char`. The signedness of `char` is platform specific. Most
    systems, including x86 GNU/Linux and Windows, use `signed char`, but those
    based on PowerPC and ARM processors typically use `unsigned char`."""
    alias s_char = Int8
    """Type: `signed char`."""
    alias u_char = UInt8
    """Type: `unsigned char`."""
    alias short = Int16
    """Type: `short`."""
    alias u_short = UInt16
    """Type: `unsigned short`."""
    alias int = Int32
    """Type: `int`."""
    alias u_int = UInt32
    """Type: `unsigned int`."""
    alias long = Scalar[_c_long_dtype()]
    """Type: `long`."""
    alias u_long = Scalar[_c_u_long_dtype()]
    """Type: `unsigned long`."""
    alias long_long = Int64
    """Type: `long long`."""
    alias u_long_long = UInt64
    """Type: `unsigned long long`."""
    alias float = Float32
    """Type: `float`."""
    alias double = Float64
    """Type: `double`."""
    alias void = Int8
    """Type: `void`."""
    alias ptr_addr = Int
    """Type: A Pointer Address."""


alias size_t = C.u_long
"""Type: size_t."""
alias ssize_t = C.long
"""Type: ssize_t."""


fn _c_long_dtype() -> DType:
    # https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models

    @parameter
    if is_64bit() and os_is_windows():
        return DType.uint32  # LLP64
    elif is_64bit():
        return DType.uint64  # LP64
    else:
        return DType.uint32  # ILP32


fn _c_u_long_dtype() -> DType:
    # https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models

    @parameter
    if is_64bit() and os_is_windows():
        return DType.uint32  # LLP64
    elif is_64bit():
        return DType.uint64  # LP64
    else:
        return DType.uint32  # ILP32

fn get_errno() -> C.int:
    """Get a copy of the current value of the `errno` global variable for the
    current thread.

    Returns:
        A copy of the current value of `errno` for the current thread.
    """

    @parameter
    if os_is_windows():
        var errno = stack_allocation[1, C.int]()
        _ = external_call["_get_errno", C.void, UnsafePointer[C.int]](errno)
        return errno[]
    else:
        return external_call["__errno_location", UnsafePointer[C.int]]()[]

fn strerror(errnum: C.int) -> UnsafePointer[C.char]:
    """Libc POSIX `strerror` function.

    Args:
        errnum: The number of the error.

    Returns:
        A Pointer to the error message.

    Notes:
        [Reference](https://man7.org/linux/man-pages/man3/strerror.3.html).
        Fn signature: `char *strerror(int errnum)`.
    """
    return external_call["strerror", UnsafePointer[C.char], C.int](errnum)


fn char_ptr_to_string(s: UnsafePointer[C.char]) -> String:
    """Create a String **copying** a char pointer.

    Args:
        s: A pointer to a C string.

    Returns:
        The String.
    """
    var l = int(strlen(s)) + 1
    var buf = UnsafePointer[UInt8].alloc(l)
    memcpy(buf.bitcast[C.char](), s, l)
    return String(ptr=buf, len=l)


fn strlen(s: UnsafePointer[C.char]) -> size_t:
    """Libc POSIX `strlen` function.

    Args:
        s: A pointer to a C string.

    Returns:
        The length of the string.

    Notes:
        [Reference](https://man7.org/linux/man-pages/man3/strlen.3p.html).
        Fn signature: `size_t strlen(const char *s)`.
    """
    return external_call["strlen", size_t, UnsafePointer[C.char]](s)
Steps to reproduce
  • Include relevant code snippet or link to code that did not work as expected.
  • If applicable, add screenshots to help explain the problem.
  • If using the Playground, name the pre-existing notebook that failed and the steps that led to failure.
  • Include anything else that might help us debug the issue.
System information
- What OS did you do install Mojo on ?
`Ubuntu 22.04.5 LTS`

- Provide version information for Mojo by pasting the output of `mojo -v`
`mojo 2024.10.405`

- Provide Modular CLI version by pasting the output of `modular -v`
`magic 0.3.1 - (based on pixi 0.29.0)`

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the minimal async/await Mojo snippet with Mojo 2024.10.405 on Ubuntu 22.04.5 LTS, then compare it with the provided synchronous example and inspect where LLVM translation reports builtin.unrealized_conversion_cast. Done means the async example compiles and the expected behavior for async main is established or corrected.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.