Skip to content

Type aliases can be silently shadowed #20702

Closed
@aidanhs

Description

@aidanhs

check.rs

extern crate libc;

use std::mem;

type VPtr = *mut ::libc::c_void;
type CbClosure<'s> = Fn<(&'s i32,), i32> + 's;

extern "C" fn callback(data: VPtr) {
    unsafe {
        let func: &CbClosure = mem::transmute::<VPtr, &CbClosure>(data);
        let x = 5;
        (*func)(&x);
    }
}

#[link(name = "extlib")]
extern {
   fn register_callback(cb: extern fn(VPtr)) -> i32;
   fn trigger_callback(val: VPtr);
}

fn main() {
    let func = |&mut: x: &i32| *x*2;
    go(func);
}

fn go<CbClosure>(func: CbClosure) {
    unsafe {
        register_callback(callback);
        let data: VPtr = mem::transmute::<&CbClosure, VPtr>(&func);
        trigger_callback(data);
    }
}

extlib.c

#include <stdint.h>

typedef void (*rust_callback)(void*);
rust_callback cb;

int32_t register_callback(rust_callback callback) {
    cb = callback;
    return 1;
}

void trigger_callback(void *val) {
  cb(val);
}
$ gcc extlib.c -fPIC -shared -o libextlib.so
$ rustc -L . check.rs
check.rs:10:32: 10:66 error: transmute called on types with different sizes: *mut libc::types::common::c95::c_void (64 bits) to &core::ops::Fn(&i32) -> i32 (128 bits)
check.rs:10         let func: &CbClosure = mem::transmute::<VPtr, &CbClosure>(data);
                                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

But if you comment out the whole unsafe block in callback...

$ rustc -L . check.rs 
check.rs:8:24: 8:28 warning: unused variable: `data`, #[warn(unused_variables)] on by default
check.rs:8 extern "C" fn callback(data: VPtr) {

despite there being a conversion the other way in go. Surely these type cannot vary in size?

To compound my confusion, you can add the line below to after let data: [...] in go and it will compile - this is exactly the same line as in callback, with a different variable name.

let func2: &CbClosure = mem::transmute::<VPtr, &CbClosure>(data);

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-resolveArea: Name/path resolution done by `rustc_resolve` specifically

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions