Skip to content
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

'expected fn type' compiler panic caused by wrong "if let ..." #55513

Closed
tamasfe opened this issue Oct 30, 2018 · 4 comments
Closed

'expected fn type' compiler panic caused by wrong "if let ..." #55513

tamasfe opened this issue Oct 30, 2018 · 4 comments
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@tamasfe
Copy link
Contributor

tamasfe commented Oct 30, 2018

The if condition in the following code causes both the stable and nightly compilers to panic:

extern crate failure;
extern crate walkdir;

use failure::Error;
use std::ffi::OsStr;

use walkdir::WalkDir;

fn main() {
    let mut errors = Vec::<Error>::new();
    for file in WalkDir::new(".").follow_links(true) {
        let entry = match file {
            Ok(e) => e,
            Err(e) => {
                errors.push(Error::from(e));
                continue;
            }
        };

        if let Some(OsStr::new("yaml")) = entry.path().extension() { // <- Here
            // dostuff with yaml file
        }
    }
}

Now I know it doesn't work like this, but still shouldn't crash the compiler.

(Just out of curiosity, does something like if option? == some_value {...} exist in the language?)

Meta

rustc version:
rustc 1.31.0-nightly (d586d5d 2018-10-29)
binary: rustc
commit-hash: d586d5d
commit-date: 2018-10-29
host: x86_64-unknown-linux-gnu
release: 1.31.0-nightly
LLVM version: 8.0

OS is Fedora 28.
The bug also appears in the 1.30 stable release.

Backtrace:

thread 'main' panicked at 'expected fn type', libcore/option.rs:1008:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at libstd/sys_common/backtrace.rs:59
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:227
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:480
   6: std::panicking::continue_panic_fmt
             at libstd/panicking.rs:390
   7: rust_begin_unwind
             at libstd/panicking.rs:325
   8: core::panicking::panic_fmt
             at libcore/panicking.rs:77
   9: core::option::expect_failed
             at libcore/option.rs:1008
  10: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::check_pat_tuple_struct
  11: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::check_pat_walk
  12: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::check_pat_tuple_struct
  13: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::check_pat_walk
  14: rustc_typeck::check::FnCtxt::check_expr_kind
  15: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  16: rustc_typeck::check::FnCtxt::check_block_with_expected
  17: rustc_typeck::check::FnCtxt::check_expr_kind
  18: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  19: rustc_typeck::check::FnCtxt::check_expr_meets_expectation_or_error
  20: rustc_typeck::check::FnCtxt::check_block_with_expected
  21: rustc_typeck::check::FnCtxt::check_expr_kind
  22: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  23: rustc_typeck::check::FnCtxt::check_expr_kind
  24: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  25: rustc_typeck::check::FnCtxt::check_decl_local
  26: rustc_typeck::check::FnCtxt::check_block_with_expected
  27: rustc_typeck::check::FnCtxt::check_expr_kind
  28: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  29: rustc_typeck::check::FnCtxt::check_block_with_expected
  30: rustc_typeck::check::FnCtxt::check_expr_kind
  31: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  32: rustc_typeck::check::FnCtxt::check_return_expr
  33: rustc_typeck::check::check_fn
  34: rustc::ty::context::tls::with_related_context
  35: rustc::infer::InferCtxtBuilder::enter
  36: rustc_typeck::check::typeck_tables_of
  37: rustc::ty::query::__query_compute::typeck_tables_of
  38: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::typeck_tables_of<'tcx>>::compute
  39: rustc::ty::context::tls::with_context
  40: rustc::dep_graph::graph::DepGraph::with_task_impl
  41: rustc::ty::context::tls::with_related_context
  42: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  43: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  44: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
  45: rustc::session::Session::track_errors
  46: rustc_typeck::check::typeck_item_bodies
  47: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::typeck_item_bodies<'tcx>>::compute
  48: rustc::ty::context::tls::with_context
  49: rustc::dep_graph::graph::DepGraph::with_task_impl
  50: rustc::ty::context::tls::with_related_context
  51: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  52: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  53: rustc_typeck::check_crate
  54: rustc::ty::context::tls::enter_context
  55: <std::thread::local::LocalKey<T>>::with
  56: rustc::ty::context::TyCtxt::create_and_enter
  57: rustc_driver::driver::compile_input
  58: rustc_driver::run_compiler_with_pool
  59: rustc_driver::driver::spawn_thread_pool
  60: rustc_driver::run_compiler
  61: <scoped_tls::ScopedKey<T>>::set
  62: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  63: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:102
  64: rustc_driver::run
  65: rustc_driver::main
  66: std::rt::lang_start::{{closure}}
  67: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:310
  68: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:102
  69: std::rt::lang_start_internal
             at libstd/panicking.rs:289
             at libstd/panic.rs:392
             at libstd/rt.rs:58
  70: main
  71: __libc_start_main
  72: <unknown>
query stack during panic:
#0 [typeck_tables_of] processing `main`
#1 [typeck_item_bodies] type-checking all item bodies
end of query stack
@Centril Centril added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Oct 30, 2018
@Centril
Copy link
Contributor

Centril commented Oct 30, 2018

(Just out of curiosity, does something like if option? == some_value {...} exist in the language?)

Yes, this is built up of:

expr ::= "if" expr "{" statements expr_tail "}"
       | expr "==" expr
       | expr "?"
       | ...
       ;

so if expr { ... } -> if expr == expr { ... } -> if expr? == expr -> if option? == some_value.

@ljedrz
Copy link
Contributor

ljedrz commented Oct 31, 2018

I hit the same ICE by accident too; I was able to shrink the triggering code (and the stack trace) a little bit:

code:

use std::path::Path;
use std::ffi::OsStr;

fn main() {
    let path = Path::new("herp.derp");
    
    if let Some(OsStr::new("derp")) = path.extension() {}
}

trace:

thread 'main' panicked at 'expected fn type', libcore/option.rs:1008:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at libstd/sys_common/backtrace.rs:59
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:227
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:480
   6: std::panicking::continue_panic_fmt
             at libstd/panicking.rs:390
   7: rust_begin_unwind
             at libstd/panicking.rs:325
   8: core::panicking::panic_fmt
             at libcore/panicking.rs:77
   9: core::option::expect_failed
             at libcore/option.rs:1008
  10: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::check_pat_tuple_struct
  11: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::check_pat_walk
  12: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::check_pat_tuple_struct
  13: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::check_pat_walk
  14: rustc_typeck::check::FnCtxt::check_expr_kind
  15: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  16: rustc_typeck::check::FnCtxt::check_block_with_expected
  17: rustc_typeck::check::FnCtxt::check_expr_kind
  18: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  19: rustc_typeck::check::FnCtxt::check_return_expr
  20: rustc_typeck::check::check_fn
  21: rustc::ty::context::tls::with_related_context
  22: rustc::infer::InferCtxtBuilder::enter
  23: rustc_typeck::check::typeck_tables_of
  24: rustc::ty::query::__query_compute::typeck_tables_of
  25: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::typeck_tables_of<'tcx>>::compute
  26: rustc::dep_graph::graph::DepGraph::with_task_impl
  27: rustc::ty::context::tls::with_related_context
  28: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  29: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  30: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
  31: rustc::session::Session::track_errors
  32: rustc_typeck::check::typeck_item_bodies
  33: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::typeck_item_bodies<'tcx>>::compute
  34: rustc::dep_graph::graph::DepGraph::with_task_impl
  35: rustc::ty::context::tls::with_related_context
  36: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  37: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  38: rustc_typeck::check_crate
  39: rustc::ty::context::tls::enter_context
  40: <std::thread::local::LocalKey<T>>::with
  41: rustc::ty::context::TyCtxt::create_and_enter
  42: rustc_driver::driver::compile_input
  43: rustc_driver::run_compiler_with_pool
  44: rustc_driver::driver::spawn_thread_pool
  45: rustc_driver::run_compiler
  46: <scoped_tls::ScopedKey<T>>::set
  47: syntax::with_globals
  48: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:102
  49: rustc_driver::run
  50: rustc_driver::main
  51: std::rt::lang_start::{{closure}}
  52: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:310
  53: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:102
  54: std::rt::lang_start_internal
             at libstd/panicking.rs:289
             at libstd/panic.rs:392
             at libstd/rt.rs:58
  55: main
  56: __libc_start_main
  57: <unknown>
query stack during panic:
#0 [typeck_tables_of] processing `main`
#1 [typeck_item_bodies] type-checking all item bodies
end of query stack

@oli-obk
Copy link
Contributor

oli-obk commented Nov 4, 2018

If we implement the pattern integration of #24111 this will get fixed naturally. The code would even become legal if OsStr::new becomes a const function

@oli-obk
Copy link
Contributor

oli-obk commented Jan 14, 2019

now tracked in #57240

@oli-obk oli-obk closed this as completed Jan 14, 2019
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

4 participants