Skip to content

Type based dispatch based on arguments to calls #1586

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
1 of 3 tasks
philberty opened this issue Oct 13, 2022 · 1 comment
Open
1 of 3 tasks

Type based dispatch based on arguments to calls #1586

philberty opened this issue Oct 13, 2022 · 1 comment
Assignees
Labels

Comments

@philberty
Copy link
Member

philberty commented Oct 13, 2022

Rustc had this issue: rust-lang/rust#45510

The fix was: rust-lang/rust#55986

#![feature(fn_traits)] 
#![feature(unboxed_closures)]

struct Ishmael;
struct Maybe;
struct CallMe;

impl FnOnce<(Ishmael,)> for CallMe {
    type Output = ();
    extern "rust-call" fn call_once(self, _args: (Ishmael,)) -> () {
        println!("Split your lungs with blood and thunder!");
    }
}

impl FnOnce<(Maybe,)> for CallMe {
    type Output = ();
    extern "rust-call" fn call_once(self, _args: (Maybe,)) -> () {
        println!("So we just met, and this is crazy");
    }
}

fn main() {
    CallMe(Ishmael);
    CallMe(Maybe);
}

To fix this in gccrs there are a few things we need to do:

  • refactor MethodResolver::Probe to return a set so that we can get multiple candidate errors properly
  • refactor autoderef to take an optional list of arguments which can be used to match function calls against if it is available
  • support looking for call_once implementations on call-expr's like this so that this becomes:
let a = CallMe;
a.fn_once(args)

Originally posted by @philberty in #195 (comment)

@philberty
Copy link
Member Author

#[lang = "sized"]
trait Sized {}

extern "C" {
    fn printf(s: *const i8, ...);
}

#[lang = "fn_once"]
pub trait FnOnce<Args> {
    #[lang = "fn_once_output"]
    type Output;

    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

struct Ishmael;
struct Maybe;
struct CallMe;

impl FnOnce<(Ishmael,)> for CallMe {
    type Output = ();

    extern "rust-call" fn call_once(self, _args: (Ishmael,)) -> () {
        unsafe {
            let a = "Split your lungs with blood and thunder!";
            let b = a as *const str;
            let c = b as *const i8;

            printf(c);
        }
    }
}

impl FnOnce<(Maybe,)> for CallMe {
    type Output = ();

    extern "rust-call" fn call_once(self, _args: (Maybe,)) -> () {
        unsafe {
            let a = "So we just met, and this is crazy";
            let b = a as *const str;
            let c = b as *const i8;

            printf(c);
        }
    }
}

fn main() {
    CallMe(Ishmael);
    CallMe(Maybe);
}

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
Status: Todo
Development

No branches or pull requests

1 participant