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

Unexpected compiler error when mistakenly pass a macro instead of function pointer #2049

Open
hucancode opened this issue Mar 16, 2025 · 2 comments
Assignees
Labels
Fixed Needs Verification Fixed, but needs verification that it works

Comments

@hucancode
Copy link

I am writing some code and get the error

⚠️ The compiler encountered an unexpected error: "Should be unreachable".

- Function: sema_trace_decl_liveness(...)
- Source file: /build/5wc7gif967l539vxk1vly1prqrcfc0q3-source/src/compiler/sema_liveness.c:625

🙏 Please consider taking the time to file an issue on GitHub, so that we can get it fixed:

https://github.com/c3lang/c3c/issues/new so that we can get it fixed.

Minimum reproducable example would be as follow

import std::io;

struct Container {
  int[] items;
}

macro int Container.get(&this, usz i) @operator([]) {
  return this.items[i];
}

alias ProcGetItem = fn int(usz);
fn void process(int input, ProcGetItem getter) {
  io::printfn("%d", getter(1) + getter(2) + input);
}

fn void main() {
  Container c = {
    .items = { 2, 3, 4, 5 }
  };
  // &c.get is not an fn, this should produce compile error
  process(10, &c.get);
}

And also, unrelated to the error above but I want to ask the correct way to write this. I have a function that take a getter as parameter, I also have a container providing get operator. How to connect these two without the function depending on the container implementation?

@hucancode hucancode changed the title Compiler encountered an unexpected error, mistakenly pass a macro instead of function pointer Unexpected compiler error when mistakenly pass a macro instead of function pointer Mar 16, 2025
lerno added a commit that referenced this issue Mar 16, 2025
- Incorrectly allowed getting pointer to a macro #2049.
@lerno lerno self-assigned this Mar 16, 2025
@lerno lerno added the Fixed Needs Verification Fixed, but needs verification that it works label Mar 16, 2025
@lerno
Copy link
Collaborator

lerno commented Mar 16, 2025

This should be fixed now. For the problem you had, how would you write it in C?

@hucancode
Copy link
Author

I can't find an equivalent in C, here is the C++ version of my intention. container.cpp only care about managing it's data. process.cpp only care about the business, they allow caller to pass an adder and it will call that while doing business.

// container.cpp
#include <vector>

struct Container {
    std::vector<int> items;
};

void container_add(Container* c, int value) {
    c->items.push_back(value);
}


// process.cpp
#include <iostream>

template<typename Adder>
void process(Adder adder, int a) {
    adder(a);
    std::cout << a <<" was just added to some container and I don't care about its implementation" << std::endl;
    // continue to the main business
}

// main.cpp
#include <functional>

int main() {
    Container my_container;
    auto adder = [&my_container](int value) {
        container_add(&my_container, value);
    };
    process(adder, 1);
    process(adder, 2);
    for (int item : my_container.items) {
        std::cout << item << " ";
    }
    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fixed Needs Verification Fixed, but needs verification that it works
Projects
None yet
Development

No branches or pull requests

2 participants