Repository: brendanzab/gl-rs (language: rust)

Issue:
Incorrect PROC typedef
The definition of [`PROC`](https://github.com/brendanzab/gl-rs/blob/master/gl_generator/generators/templates/types/wgl.rs#L29) causes issues on the latest [nightly](https://github.com/rust-lang/rust/issues/46182). The functions aren't allow to be zero, which rust makes use by annotating them with non-null. Unfortunately, the returned functions by `wglGetProcAddress` can be zero (e.g GL1.1 functions). Glutin currently checks if the functions are zero else it queries the addresses via `kernel32::GetProcAddress`. The rust compiler optimizes this call away as it assumes we don't have null functions.

The proposed solution is to replace `extern "system" fn()` with `*const ()`, which also fixes the issue for me locally.


Discussion / hints:
The fix makes sense to me.
Yeah, as you can see from the comment I had no idea what I was doing when I was translating those type defs! What does `PROC` look like in use? Would people have to transmute/cast to `*const ()`? 

I'm also guessing we would have to do a major release seeing as its an API change.
You can use what winapi does as an example of how it should be done. Raw pointer to an opaque type (can be replaced with `extern type` when that is stable enough).

https://github.com/retep998/winapi-rs/blob/b6eed13c28a8808bfdc54cdf50c4498132ce9176/src/shared/minwindef.rs#L76-L82
@retep998: That's still using a void enum - is it still UB to use that?

```rust
pub enum __some_function {}
/// Pointer to a function with unknown type signature.
pub type FARPROC = *mut __some_function;
```

cc. @eddyb
Wondering if we should just depend on winapi somehow for these types rather than having to maintain our own, but that's a separate issue 🤔 
The canonical equivalent for C function pointers into Rust is `Option<extern fn()>` (explicitly defined and whitelisted to do the right thing), and that is precisely what `bindgen` generates for them.

Fix patch:
diff --git a/gl/Cargo.toml b/gl/Cargo.toml
index 1024609a..0f1ba64d 100644
--- a/gl/Cargo.toml
+++ b/gl/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "gl"
-version = "0.7.0"
+version = "0.9.0"
 authors = [
     "Brendan Zabarauskas <bjzaba@yahoo.com.au>",
     "Corey Richardson",
@@ -17,7 +17,7 @@ categories = ["api-bindings", "rendering::graphics-api"]
 keywords = ["gl", "egl", "opengl", "khronos"]
 
 [build-dependencies]
-gl_generator = { version = "0.7.0", path = "../gl_generator" }
+gl_generator = { version = "0.8.0", path = "../gl_generator" }
 
 [dev-dependencies]
 glutin = "0.10.0"
diff --git a/gl_generator/Cargo.toml b/gl_generator/Cargo.toml
index b8329696..6a9b7621 100644
--- a/gl_generator/Cargo.toml
+++ b/gl_generator/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "gl_generator"
-version = "0.7.0"
+version = "0.8.0"
 authors = [
     "Brendan Zabarauskas <bjzaba@yahoo.com.au>",
     "Corey Richardson",
diff --git a/gl_generator/generators/templates/types/egl.rs b/gl_generator/generators/templates/types/egl.rs
index e79ed2c2..877638ab 100644
--- a/gl_generator/generators/templates/types/egl.rs
+++ b/gl_generator/generators/templates/types/egl.rs
@@ -32,7 +32,9 @@ pub type EGLDeviceEXT = *const super::__gl_imports::raw::c_void;
 pub type EGLDisplay = *const super::__gl_imports::raw::c_void;
 pub type EGLSurface = *const super::__gl_imports::raw::c_void;
 pub type EGLClientBuffer = *const super::__gl_imports::raw::c_void;
-pub type __eglMustCastToProperFunctionPointerType = extern "system" fn() -> ();
+pub enum __eglMustCastToProperFunctionPointerType_fn {}
+pub type __eglMustCastToProperFunctionPointerType =
+    *mut __eglMustCastToProperFunctionPointerType_fn;
 pub type EGLImageKHR = *const super::__gl_imports::raw::c_void;
 pub type EGLImage = *const super::__gl_imports::raw::c_void;
 pub type EGLOutputLayerEXT = *const super::__gl_imports::raw::c_void;
diff --git a/gl_generator/generators/templates/types/glx.rs b/gl_generator/generators/templates/types/glx.rs
index 04737aca..b0078da0 100644
--- a/gl_generator/generators/templates/types/glx.rs
+++ b/gl_generator/generators/templates/types/glx.rs
@@ -15,7 +15,8 @@ pub type GLXPixmap = XID;
 pub type GLXDrawable = XID;
 pub type GLXWindow = XID;
 pub type GLXPbuffer = XID;
-pub type __GLXextFuncPtr = extern "system" fn();
+pub enum __GLXextFuncPtr_fn {}
+pub type __GLXextFuncPtr = *mut __GLXextFuncPtr_fn;
 pub type GLXVideoCaptureDeviceNV = XID;
 pub type GLXVideoDeviceNV = super::__gl_imports::raw::c_int;
 pub type GLXVideoSourceSGIX = XID;
diff --git a/gl_generator/generators/templates/types/wgl.rs b/gl_generator/generators/templates/types/wgl.rs
index dd456d8b..a376d4fa 100644
--- a/gl_generator/generators/templates/types/wgl.rs
+++ b/gl_generator/generators/templates/types/wgl.rs
@@ -26,8 +26,8 @@ pub type HGLRC = *const super::__gl_imports::raw::c_void;
 pub type INT = super::__gl_imports::raw::c_int;
 pub type PVOID = *const super::__gl_imports::raw::c_void;
 pub type LPVOID = *const super::__gl_imports::raw::c_void;
-pub enum __proc_fn {}
-pub type PROC = *mut __proc_fn;
+pub enum __PROC_fn {}
+pub type PROC = *mut __PROC_fn;
 
 #[repr(C)]
 pub struct RECT {


Test patch: