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

ICE When initializing a struct with update syntax in closure #50618

Closed
dlrobertson opened this issue May 10, 2018 · 7 comments
Closed

ICE When initializing a struct with update syntax in closure #50618

dlrobertson opened this issue May 10, 2018 · 7 comments
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone

Comments

@dlrobertson
Copy link
Contributor

dlrobertson commented May 10, 2018

TL;DR

When initializing a struct with update syntax inside a closure, an ICE occurs if a nonexistent or misspelled member is listed.

Example that Triggers ICE

struct Point {
    pub x: u64,
    pub y: u64,
}

const TEMPLATE: Point = Point {
    x: 0,
    y: 0
};

fn main() {
    let x = || {
        Point {
            nonexistent: 0,
            ..TEMPLATE
        }
    };
}
Backtrace

thread 'main' panicked at 'no index for a field', libcore/option.rs:914: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
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:227
   4: rustc::util::common::panic_hook
             at librustc/util/common.rs:54
   5: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:467
   6: std::panicking::begin_panic_fmt
             at libstd/panicking.rs:350
   7: rust_begin_unwind
             at libstd/panicking.rs:328
   8: core::panicking::panic_fmt
             at libcore/panicking.rs:71
   9: core::option::expect_failed
             at libcore/option.rs:914
  10: rustc::ty::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::field_index
             at /home/drobertson/git/rust/src/libcore/option.rs:302
             at librustc/ty/mod.rs:2410
  11: rustc::middle::expr_use_visitor::ExprUseVisitor::walk_expr
             at librustc/middle/expr_use_visitor.rs:665
             at /home/drobertson/git/rust/src/libcore/iter/iterator.rs:1689
             at /home/drobertson/git/rust/src/libcore/iter/iterator.rs:1519
             at /home/drobertson/git/rust/src/libcore/slice/mod.rs:2693
             at /home/drobertson/git/rust/src/libcore/iter/iterator.rs:1519
             at /home/drobertson/git/rust/src/libcore/iter/iterator.rs:1688
             at librustc/middle/expr_use_visitor.rs:664
             at librustc/middle/expr_use_visitor.rs:423
  12: rustc::middle::expr_use_visitor::ExprUseVisitor::consume_expr
             at librustc/middle/expr_use_visitor.rs:358
  13: rustc::middle::expr_use_visitor::ExprUseVisitor::walk_block
             at librustc/middle/expr_use_visitor.rs:639
  14: rustc::middle::expr_use_visitor::ExprUseVisitor::walk_expr
             at librustc/middle/expr_use_visitor.rs:0
  15: rustc::middle::expr_use_visitor::ExprUseVisitor::consume_expr
             at librustc/middle/expr_use_visitor.rs:358
  16: rustc::middle::expr_use_visitor::ExprUseVisitor::consume_body
             at librustc/middle/expr_use_visitor.rs:329
  17: rustc_typeck::check::upvar::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::analyze_closure
             at librustc_typeck/check/upvar.rs:171
  18: <rustc_typeck::check::upvar::InferBorrowKindVisitor<'a, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_expr
             at librustc_typeck/check/upvar.rs:80
  19: rustc::hir::intravisit::walk_local
             at /home/drobertson/git/rust/src/<walk_list macros>:2
  20: rustc::hir::intravisit::walk_block
             at /home/drobertson/git/rust/src/<walk_list macros>:2
  21: rustc_typeck::check::upvar::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::closure_analyze                                                                                                                                 
             at librustc_typeck/check/upvar.rs:59
  22: rustc::ty::context::tls::with_related_context
             at librustc_typeck/check/mod.rs:904
             at librustc_typeck/check/mod.rs:617
             at /home/drobertson/git/rust/src/librustc/infer/mod.rs:453
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1578
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1844
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1787
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1843
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1577
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1905
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1889
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1880
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1889
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1900
  23: rustc::ty::context::GlobalCtxt::enter_local
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1570
  24: rustc::infer::InferCtxtBuilder::enter
             at /home/drobertson/git/rust/src/librustc/infer/mod.rs:453
  25: rustc_typeck::check::InheritedBuilder::enter
             at librustc_typeck/check/mod.rs:617
  26: rustc_typeck::check::typeck_tables_of
             at librustc_typeck/check/mod.rs:855
  27: rustc::ty::maps::<impl rustc::ty::maps::config::QueryConfig<'tcx> for rustc::ty::maps::queries::typeck_tables_of<'tcx>>::compute
             at librustc/ty/maps/plumbing.rs:723
  28: rustc::dep_graph::graph::DepGraph::with_task_impl
             at librustc/dep_graph/graph.rs:343
  29: rustc::dep_graph::graph::DepGraph::with_task
             at librustc/dep_graph/graph.rs:209
  30: rustc::ty::context::tls::with_related_context
             at librustc/ty/maps/plumbing.rs:530
             at librustc/ty/maps/plumbing.rs:200
             at librustc/ty/context.rs:1844
             at librustc/ty/context.rs:1787
             at librustc/ty/context.rs:1843
             at librustc/ty/maps/plumbing.rs:199
             at librustc/ty/context.rs:1905
             at librustc/ty/context.rs:1889
             at librustc/ty/context.rs:1880
             at librustc/ty/context.rs:1889
             at librustc/ty/context.rs:1900
  31: <rustc::ty::maps::plumbing::JobOwner<'a, 'tcx, Q>>::start
             at librustc/ty/maps/plumbing.rs:189
  32: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
             at librustc/ty/maps/plumbing.rs:523
  33: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
             at librustc/ty/maps/plumbing.rs:372
             at librustc/ty/maps/plumbing.rs:599
             at librustc/ty/maps/plumbing.rs:606
  34: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
             at librustc/ty/maps/plumbing.rs:574
  35: rustc::session::Session::track_errors
             at librustc_typeck/check/mod.rs:715
             at /home/drobertson/git/rust/src/librustc/session/mod.rs:318
  36: rustc_typeck::check::typeck_item_bodies
             at librustc_typeck/check/mod.rs:713
  37: rustc::ty::maps::<impl rustc::ty::maps::config::QueryConfig<'tcx> for rustc::ty::maps::queries::typeck_item_bodies<'tcx>>::compute
             at librustc/ty/maps/plumbing.rs:723
  38: rustc::dep_graph::graph::DepGraph::with_task_impl
             at librustc/dep_graph/graph.rs:343
  39: rustc::dep_graph::graph::DepGraph::with_task
             at librustc/dep_graph/graph.rs:209
  40: rustc::ty::context::tls::with_related_context
             at librustc/ty/maps/plumbing.rs:530
             at librustc/ty/maps/plumbing.rs:200
             at librustc/ty/context.rs:1844
             at librustc/ty/context.rs:1787
             at librustc/ty/context.rs:1843
             at librustc/ty/maps/plumbing.rs:199
             at librustc/ty/context.rs:1905
             at librustc/ty/context.rs:1889
             at librustc/ty/context.rs:1880
             at librustc/ty/context.rs:1889
             at librustc/ty/context.rs:1900
  41: <rustc::ty::maps::plumbing::JobOwner<'a, 'tcx, Q>>::start
             at librustc/ty/maps/plumbing.rs:189
  42: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
             at librustc/ty/maps/plumbing.rs:523
  43: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
             at librustc/ty/maps/plumbing.rs:372
             at librustc/ty/maps/plumbing.rs:599
             at librustc/ty/maps/plumbing.rs:606
  44: rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::typeck_item_bodies
             at librustc/ty/maps/plumbing.rs:769
  45: rustc::util::common::time
             at librustc_typeck/lib.rs:344
             at /home/drobertson/git/rust/src/librustc/util/common.rs:166
             at /home/drobertson/git/rust/src/librustc/util/common.rs:160
  46: rustc_typeck::check_crate
             at librustc_typeck/lib.rs:344
  47: rustc::ty::context::tls::enter_context
             at librustc_driver/driver.rs:1121
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1867
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1844
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1787
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1843
  48: <std::thread::local::LocalKey<T>>::with
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1866
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1833
             at /home/drobertson/git/rust/src/libstd/thread/local.rs:294
             at /home/drobertson/git/rust/src/libstd/thread/local.rs:248
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1825
             at /home/drobertson/git/rust/src/libstd/thread/local.rs:294
             at /home/drobertson/git/rust/src/libstd/thread/local.rs:248
  49: rustc::ty::context::tls::enter_global
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1817
            at /home/drobertson/git/rust/src/librustc/ty/context.rs:1855
  50: rustc::ty::context::TyCtxt::create_and_enter
             at /home/drobertson/git/rust/src/librustc/ty/context.rs:1299
  51: rustc_driver::driver::phase_3_run_analysis_passes
             at librustc_driver/driver.rs:1095
  52: rustc_driver::driver::compile_input
             at librustc_driver/driver.rs:231
  53: rustc_driver::run_compiler_impl
             at librustc_driver/lib.rs:540
  54: <scoped_tls::ScopedKey<T>>::set
             at librustc_driver/lib.rs:457
             at /home/drobertson/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-0.1.1/src/lib.rs:155
             at /home/drobertson/git/rust/src/libsyntax/lib.rs:97
             at /home/drobertson/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-0.1.1/src/lib.rs:155
  55: syntax::with_globals
             at /home/drobertson/git/rust/src/libsyntax/lib.rs:96
  56: rustc_driver::run_compiler
             at librustc_driver/lib.rs:456
  57: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at librustc_driver/lib.rs:1684
             at librustc_driver/lib.rs:174
             at librustc_driver/lib.rs:1598
             at /home/drobertson/git/rust/src/libstd/panic.rs:305
  58: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  59: std::panicking::try
             at /home/drobertson/git/rust/src/libstd/panicking.rs:289
  60: rustc_driver::run
             at librustc_driver/lib.rs:1530
             at librustc_driver/lib.rs:1597
             at librustc_driver/lib.rs:173
  61: rustc_driver::main
             at librustc_driver/lib.rs:1677
  62: std::rt::lang_start::{{closure}}
             at /home/drobertson/git/rust/src/libstd/rt.rs:74
  63: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:310
  64: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  65: std::panicking::try
             at libstd/panicking.rs:289
  66: std::panic::catch_unwind
             at libstd/panic.rs:374
  67: std::rt::lang_start_internal
             at libstd/rt.rs:58
  68: std::rt::lang_start
             at /home/drobertson/git/rust/src/libstd/rt.rs:74
  69: __libc_start_main
  70: _start

Meta

$ rustc +stage1 --version --verbose
rustc 1.27.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.27.0-dev
LLVM version: 6.0
$ git rev-parse HEAD
0a223d139cd26e5bfab23a478a5cad845eaab131
@dlrobertson dlrobertson changed the title ICE: When initializing a struct with update syntax in closure ICE When initializing a struct with update syntax in closure May 10, 2018
@pietroalbini
Copy link
Member

Was this working before or did it never work?

@dlrobertson
Copy link
Contributor Author

Not sure honestly. Just hit the ICE randomly and then narrowed it down to a minimal example.

@pietroalbini
Copy link
Member

OK, don't worry, thanks!

@scottmcm
Copy link
Member

Looks like 1.26 doesn't ICE, but nightly does: https://godbolt.org/g/688aZ8

@dlrobertson
Copy link
Contributor Author

dlrobertson commented May 11, 2018

It looks like when analyzing the closuer we run walk_struct_expr on the malformed Point structure which causes a panic here. Since typeck didn't pass we can't trust the structure of the struct to be valid for walk_struct_expr. It works if we don't walk_struct_expr or don't run the is_mentioned check if the tcx().sess has errors, but someone more experienced should probably weigh in on that. I'm not sure if that is the right approach.

@pietroalbini pietroalbini added the regression-from-stable-to-beta Performance or correctness regression from stable to beta. label May 11, 2018
@pietroalbini pietroalbini added this to the 1.27 milestone May 11, 2018
@pietroalbini pietroalbini added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels May 11, 2018
@pietroalbini
Copy link
Member

This is actually a regression from stable to beta.

@dlrobertson
Copy link
Contributor Author

My initial theory was wrong. The problem is actually occurring in typeck here.

bors added a commit that referenced this issue May 13, 2018
typeck: Fix ICE with struct update syntax

If check_expr_struct_fields fails, do not continue to record update.
If we continue to record update, the struct may cause us to ICE later
on indexing a field that may or may not exist.

Fixes: #50618
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants