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

rustc panics during compilation #23217

Closed
CtrlZvi opened this issue Mar 9, 2015 · 5 comments
Closed

rustc panics during compilation #23217

CtrlZvi opened this issue Mar 9, 2015 · 5 comments
Labels
A-resolve Area: Name/path resolution done by `rustc_resolve` specifically E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@CtrlZvi
Copy link

CtrlZvi commented Mar 9, 2015

I tried this code:

#![feature(core, libc, os, unicode)]
extern crate libc;
extern crate unicode;

use std::mem;
use std::num::ToPrimitive;
use std::os;

#[cfg(target_family = "windows")]
#[link(name = "kernel32")]
#[allow(non_snake_case)]
extern "system" {
    fn SetEnvironmentVariableW(lpName : *const ::libc::wchar_t, lpValue: *const ::libc::wchar_t) -> ::libc::c_int;
    fn GetModuleHandleW(lpModuleName : *const ::libc::wchar_t) -> HINSTANCE;
}

#[stable]
pub fn get_module_handle(name: Option<&str>) -> Result<Module, String> {
    let handle = match name {
        Some(val) => {
            let n = unicode::str::Utf16Encoder::new(val.chars()).collect::<Vec<::libc::wchar_t>>();
            unsafe { GetModuleHandleW(n.as_ptr()) }
        },
        None => unsafe { GetModuleHandleW(0 as *const ::libc::wchar_t) },
    };
    match handle {
        val if val != 0 as HINSTANCE => Ok(Module { handle : val }),
        _ => Err(os::last_os_error()),
    }
}

#[stable]
pub fn set_environment_variable(name: &str, value: &str) -> Result<(), String> {
    let n = unicode::str::Utf16Encoder::new(name.chars()).collect::<Vec<::libc::wchar_t>>();
    let v = unicode::str::Utf16Encoder::new(value.chars()).collect::<Vec<::libc::wchar_t>>();
    let error = unsafe { SetEnvironmentVariableW(n.as_ptr(), v.as_ptr()) };
    match error {
        0 => Err(os::last_os_error()),
        _ => Ok(()),
    }
}

type HANDLE = *mut ::libc::c_void;
type HWND = HANDLE;
type HMENU = HANDLE;
type HINSTANCE = HANDLE;
type HICON = HANDLE;
type HCURSOR = HANDLE;
type HBRUSH = HANDLE;
pub type WNDPROC = extern "system" fn(HWND, u32, ::libc::uintptr_t, ::libc::uintptr_t) -> ::libc::uintptr_t;

#[repr(C)]
#[allow(non_snake_case)]
struct WNDCLASSEX {
    cbSize : ::libc::c_uint,
    style : ::libc::c_uint,
    lpfnWndProc : WNDPROC,
    cbClsExtra : ::libc::c_int,
    cbWndExtra : ::libc::c_int,
    hInstance : HINSTANCE,
    hIcon : HICON,
    hCursor : HCURSOR,
    hbrBackground : HBRUSH,
    lpszMenuName : *const ::libc::wchar_t,
    lpszClassName : *const ::libc::wchar_t,
    hIconSm : HICON,
}

#[repr(C)]
#[allow(non_snake_case)]
struct POINT {
    x : ::libc::c_long,
    y : ::libc::c_long,
}

#[repr(C)]
#[allow(non_snake_case)]
struct MSG {
    hwnd : HWND,
    message : ::libc::c_uint,
    wParam : ::libc::uintptr_t,
    lParam : ::libc::uintptr_t,
    time : u32,
    pt : POINT,
}

#[cfg(target_family = "windows")]
#[link(name = "user32")]
#[allow(non_snake_case)]
extern "system" {
    fn CreateWindowExW(dwExStyle: u32, lpClassName: *const ::libc::wchar_t, lpWindowName: *const ::libc::wchar_t, dwStyle: u32, x: ::libc::c_int, y: ::libc::c_int, nWidth: ::libc::c_int, nHeight: ::libc::c_int, hWndParent: HWND, hMenu : HMENU, hInstance : HINSTANCE, lpParam : *mut ::libc::c_void) -> HWND;
    fn ShowWindow(hWnd : HWND, nCmdShow : ::libc::c_int) -> ::libc::c_int;
    fn RegisterClassExW(lpwcx : *const WNDCLASSEX) -> u16;
    fn GetMessageW(lpMsg : *mut MSG, hWnd : HWND, wMsgFilterMin : ::libc::c_uint, wMsgFilterMax : ::libc::c_uint) -> ::libc::c_int;
    fn TranslateMessage(lpMsg : *const MSG) -> ::libc::c_int;
    fn DispatchMessageW(lpMsg : *const MSG) -> ::libc::uintptr_t;
    fn DefWindowProcW(hWnd : HWND, Msg : u32, wParam : ::libc::uintptr_t, lParam : ::libc::uintptr_t) -> ::libc::uintptr_t;
}

#[unstable]
pub fn default_window_procedure(window_handle : *mut ::libc::c_void, message_identifier : u32, parameter1 : ::libc::uintptr_t, parameter2 : ::libc::uintptr_t) -> ::libc::uintptr_t {
    unsafe { DefWindowProcW(window_handle, message_identifier, parameter1, parameter2) }
}

pub struct Message {
    message : MSG,
    pub number : ::libc::c_uint,
}

#[unstable]
pub fn show_window(window : &Window, show_command : ::libc::c_int) -> bool {
    match unsafe { ShowWindow(window.handle, show_command) } {
        0 => true,
        _ => false,
    }
}

#[unstable]
pub fn get_message(window : Option<&Window>, message_filter_minimum : ::libc::c_uint, message_filter_maximum : ::libc::c_uint) -> Result<Message, String> {
    let mut message = MSG {
        hwnd : 0 as HWND,
        message : 0,
        wParam : 0,
        lParam : 0,
        time : 0,
        pt : POINT { x : 0, y : 0 },
    };
    let result = unsafe { GetMessageW(
        &mut message,
        match window {
            Some(val) => val.handle,
            None => 0 as HWND,
        },
        message_filter_minimum,
        message_filter_maximum
    ) };
    match result {
        -1 => Err(os::last_os_error()),
        0 => Ok(Message { number : message.message, message : message }), // TODO(zeffron 2015 03 03) Figure out how to indicate WM_QUIT without requiring the user to read the message number (probably via Enum)
        _ => Ok(Message { number : message.message, message : message,  }),
    }
}

#[unstable]
pub fn translate_message(message : &Message) -> bool {
    let result = unsafe { TranslateMessage(&message.message) };
    match result {
        0 => false,
        _ => true,
    }
}

#[unstable]
pub fn dispatch_message(message : &Message) -> ::libc::uintptr_t {
    unsafe { DispatchMessageW(&message.message) }
}    

pub struct WindowClassExtended {
    pub style : ::libc::c_uint,
    pub window_procedure : WNDPROC,
    pub class_extra : ::libc::c_int,
    pub window_extra : ::libc::c_int,
    pub module : Option<Module>,
    pub icon : Option<Icon>,
    pub cursor : Option<Cursor>,
    pub background_brush : Option<Brush>,
    pub menu_name : String,
    pub class_name : String,
    pub small_icon : Option<Icon>,
}

#[unstable]
pub fn register_class_extended(class : WindowClassExtended) -> Result<u16, String> {
    let window_class = WNDCLASSEX {
        cbSize : mem::size_of::<WNDCLASSEX>().to_u32().unwrap(),
        style : class.style,
        lpfnWndProc : class.window_procedure,
        cbClsExtra : class.class_extra,
        cbWndExtra : class.window_extra,
        hInstance : match class.module {
            Some(val) => val.handle,
            None => 0 as *mut ::libc::c_void,
        },
        hIcon : match class.icon {
            Some(val) => val.handle,
            None => 0 as *mut ::libc::c_void,
        },
        hCursor : match class.cursor {
            Some(val) => val.handle,
            None => 0 as *mut ::libc::c_void,
        },
        hbrBackground : match class.background_brush {
            Some(val) => val.handle,
            None => 0 as *mut ::libc::c_void,
        },
        lpszMenuName : unicode::str::Utf16Encoder::new(class.menu_name.chars()).collect::<Vec<::libc::wchar_t>>().as_ptr(),
        lpszClassName : unicode::str::Utf16Encoder::new(class.class_name.chars()).collect::<Vec<::libc::wchar_t>>().as_ptr(),
        hIconSm : match class.small_icon {
            Some(val) => val.handle,
            None => 0 as *mut ::libc::c_void,
        },
    };
    let atom = unsafe { RegisterClassExW(&window_class) };
    match atom {
        0 =>  Err(os::last_os_error()),
        val => Ok(val),
    }
}

pub struct Window {
    handle : HWND,
}

pub struct Menu {
    handle : HMENU,
}

pub struct Module {
    handle : HINSTANCE,
}

pub struct Icon {
    handle : HICON,
}

pub struct Cursor {
    handle : HCURSOR,
}

pub struct Brush {
    handle : HBRUSH,
}

const CW_USEDEFAULT : ::libc::c_int = -0x80000000;

#[unstable]
pub fn create_window_extended(extended_style: u32, class_name: Option<&str>, window_name: Option<&str>, style: u32, x: Option<::libc::c_int>, y: Option<::libc::c_int>, width: Option<::libc::c_int>, height: Option<::libc::c_int>, parent_window : Option<&Window>, menu : Option<&Menu>, module : Option<&Module>) -> Result<Window, String> {
    let window_handle = unsafe { CreateWindowExW(
        extended_style,
        match class_name {
            Some(val) => unicode::str::Utf16Encoder::new(val.chars()).collect::<Vec<::libc::wchar_t>>().as_ptr(),
            None => 0 as *const ::libc::wchar_t,
        },
        match window_name {
            Some(val) => unicode::str::Utf16Encoder::new(val.chars()).collect::<Vec<::libc::wchar_t>>().as_ptr(),
            None => 0 as *const ::libc::wchar_t,
        },
        style,
        match x {
            Some(val) => val,
            None => CW_USEDEFAULT,
        },
        match y {
            Some(val) => val,
            None => CW_USEDEFAULT,
        },
        match width {
            Some(val) => val,
            None => CW_USEDEFAULT,
        },
        match height {
            Some(val) => val,
            None => CW_USEDEFAULT,
        },
        match parent_window {
            Some(val) => val.handle,
            None => 0 as HWND,
        },
        match menu {
            Some(val) => val.handle,
            None => 0 as HMENU,
        },
        match module{
            Some(val) => val.handle,
            None => 0 as HINSTANCE,
        },
        0 as *mut ::libc::c_void
    )};
    match window_handle {
        val if val == 0 as HWND => Err(os::last_os_error()),
        val => Ok(Window { handle : val as *mut ::libc::c_void }),
    }
}

#[stable]
#[repr(u32)]
pub enum ClassStyle {
    VerticalRedraw = 0x0001,
    HorizontalRedraw = 0x0002,
    DoubleClicks = 0x0008,
    OwnDeviceContext = 0x0020,
    ClassDeviceContext = 0x0040,
    ParentDeviceContext = 0x0080,
    NoClose = 0x0200,
    SaveBits = 0x0800,
    ByteAlignClient = 0x1000,
    ByteAlignWindow = 0x2000,
    GlobalClass = 0x4000,
    DropShadow = 0x00020000,
}

#[stable]
#[repr(u32)]
pub enum WindowStyle {
    Border = 0x00800000,
    Caption = 0x00C00000,
    Child = 0x40000000,
    ClipChildren = 0x02000000,
    ClipSiblings = 0x04000000,
    Disabled = 0x08000000,
    DialogFrame = 0x00400000,
    Group = 0x00020000,
    HorizontalScrollBar = 0x00100000,
    Maximize = 0x01000000,
    MaximizeBox = 0x00010000 | WindowStyle::SystemMenu as u32,
    Minimize = 0x20000000,
    MinimizeBox = 0x00020000 | WindowStyle::SystemMenu as u32,
    Overlapped = 0x00000000,
    OverlappedWindow = WindowStyle::Overlapped as u32 | WindowStyle::Caption as u32 | WindowStyle::SystemMenu as u32 | WindowStyle::ThickFrame as u32 | WindowStyle::MinimizeBox as u32 | WindowStyle::MaximizeBox as u32,
    Popup = 0x80000000,
    PopupWindow = WindowStyle::Popup as u32 | WindowStyle::Border as u32 | WindowStyle::SystemMenu as u32,
    SizeBox = 0x00040000,
    SystemMenu = 0x00080000,
    TabStop = 0x00010000,
    Visible = 0x10000000,
    VerticalScrollBar = 0x00200000,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_get_module_handle_current_module() {
        assert!(match get_module_handle(None) {
            Ok(_) => true,
            Err(_) => false,
        });
    }

    #[test]
    fn test_get_module_handle_unknown_module() {
        assert!(match get_module_handle("foo") {
            Ok(_) => false,
            Err(_) => true,
        });
    }

    #[test]
    fn test_set_environment_variable() {
        use std::env;

        let name = "key";
        let value = "value";
        assert!(set_environment_variable(name, value) == Ok(()));
        assert!(env::var(name) == Ok(value.to_string()));
    }

    #[test]
    fn test_register_class_extended() {
        extern "system" fn window_procedure(window_handle : *mut ::libc::c_void, message_identifier : u32, parameter1 : ::libc::uintptr_t, parameter2 : ::libc::uintptr_t) -> ::libc::uintptr_t {
            match message_identifier {
                _ => default_window_procedure(window_handle, message_identifier, parameter1, parameter2)
            }
        }
        let window_class = WindowClassExtended {
            style : 0,
            window_procedure : window_procedure,
            class_extra : 0,
            window_extra : 0,
            module : None,
            icon : None,
            cursor : None,
            background_brush : None,
            menu_name : "".to_string(),
            class_name : "RustSampleWindowClass".to_string(),
            small_icon : None,
        };
        let atom = register_class_extended(window_class);
        assert!(match atom {
            Ok(_) => true,
            Err(_) => false,
        });
    }
}

Then ran this command:

rustc minimumrepro.rs --crate-name win32 --crate-type lib -g --emit=dep-info,link --verbose

I expected to see successful compilation followed by tests running.

Instead, this happened:

error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/m
aster/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'path not fully resolved: PathResolution { base_def:
DefTy(DefId { krate: 0, node: 894 }, true), last_private: LastMod(AllPublic), de
pth: 1 }', C:/bot/slave/nightly-dist-rustc-win-64/build/src/librustc\middle\def.
rs:79

stack backtrace:
   1:         0x71217094 - sys::backtrace::write::h669f8e0f2a2c73f7UVA
   2:         0x71231708 - rt::unwind::register::hcda86f4971e7940bZpJ
   3:         0x71183427 - rt::unwind::begin_unwind_inner::ha77dc9ac3cfb5574onJ
   4:         0x71183beb - rt::unwind::begin_unwind_fmt::h8ea5d25622c032c4ZlJ
   5:          0x15991f7 - middle::const_eval::eval_const_expr_partial::ha9d8d88f013a10ad7lh
   6:          0x1597788 - middle::const_eval::eval_const_expr_partial::ha9d8d88f013a10ad7lh
   7:          0x1597baa - middle::const_eval::eval_const_expr_partial::ha9d8d88f013a10ad7lh

Meta

rustc --version --verbose:
rustc 1.0.0-nightly (2fc8b1e 2015-03-07) (built 2015-03-08)
binary: rustc
commit-hash: 2fc8b1e
commit-date: 2015-03-07
build-date: 2015-03-08
host: x86_64-pc-windows-gnu
release: 1.0.0-nightly

Backtrace:
1: 0x71217094 - sys::backtrace::write::h669f8e0f2a2c73f7UVA
2: 0x71231708 - rt::unwind::register::hcda86f4971e7940bZpJ
3: 0x71183427 - rt::unwind::begin_unwind_inner::ha77dc9ac3cfb5574onJ
4: 0x71183beb - rt::unwind::begin_unwind_fmt::h8ea5d25622c032c4ZlJ
5: 0x15991f7 - middle::const_eval::eval_const_expr_partial::ha9d8d88f013a10ad7lh
6: 0x1597788 - middle::const_eval::eval_const_expr_partial::ha9d8d88f013a10ad7lh
7: 0x1597baa - middle::const_eval::eval_const_expr_partial::ha9d8d88f013a10ad7lh

@jdm jdm added A-resolve Area: Name/path resolution done by `rustc_resolve` specifically I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ labels Mar 9, 2015
@Stebalien
Copy link
Contributor

The bug is that WindowStyle::ThickFrame is undefined. Minimal test case:

pub enum SomeEnum {
    B = SomeEnum::A,
}

fn main() {}

@CtrlZvi
Copy link
Author

CtrlZvi commented May 12, 2015

Thanks for noticing that, @Stebalien ! Much better test case, and allows me to fix my code so I'm not blocked.

@lholden
Copy link

lholden commented Sep 9, 2015

I am seeing this same bug with an undefined type. Seems to be the same as above, so not including a test case. This is on the nightly channel.

  Compiling xxxx v0.1.0 (file:///home/lholden/Projects/xxxx)
src/systems/input.rs:28:17: 28:43 error: no associated item named `UserInput` found for type `protocol::Protocol` in the current scope
src/systems/input.rs:28                 Protocol::UserInput(input) => input,
                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of while let expansion
src/systems/input.rs:22:9: 42:10 note: expansion site
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
thread 'rustc' panicked at 'path not fully resolved: PathResolution { base_def: DefTy(DefId { krate: 0, node: 15 => protocol::Protocol }, true), last_private: LastMod(AllPublic), depth: 1 }', ../src/librustc/middle/def.rs:82

stack backtrace:
   1:     0x7f4d6de36ef9 - sys::backtrace::tracing::imp::write::h2dd719d6a90d1694REs
   2:     0x7f4d6de3dba6 - panicking::on_panic::hcdc970a599b2a4877ox
   3:     0x7f4d6de0167e - rt::unwind::begin_unwind_inner::h6793c7a97a7e3d7cDRw
   4:     0x7f4d6de023c7 - rt::unwind::begin_unwind_fmt::hf41ce6a5eab0f5e3JQw
   5:     0x7f4d6bb87af6 - middle::mem_categorization::MemCategorizationContext<'t, 'a, 'tcx>::cat_pattern_::h15751778615198713220
   6:     0x7f4d6bb86f72 - middle::expr_use_visitor::ExprUseVisitor<'d, 't, 'a, 'tcx>::determine_pat_move_mode::hbea6ec65ddad4bacEHr
   7:     0x7f4d6bb5b5f0 - middle::expr_use_visitor::ExprUseVisitor<'d, 't, 'a, 'tcx>::walk_expr::he39be1fe2073ca9e6Rq

@bltavares
Copy link
Contributor

I was not able to reproduce the minimal test case as an ICE. Now it returns a compiler error:

error: constant evaluation error: unresolved path in constant expression [E0080]
rustc 1.6.0-nightly (8ca0acc25 2015-10-28)
binary: rustc
commit-hash: 8ca0acc25adb00d29e52b015bded4b2872a1170c
commit-date: 2015-10-28
host: x86_64-apple-darwin
release: 1.6.0-nightly

@steveklabnik steveklabnik added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. and removed I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ labels Nov 1, 2015
@steveklabnik
Copy link
Member

Same. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-resolve Area: Name/path resolution done by `rustc_resolve` specifically E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
Development

No branches or pull requests

6 participants