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 using slice patterns in const fn. #66934

Closed
matthewjasper opened this issue Dec 1, 2019 · 4 comments · Fixed by #67467
Closed

ICE when using slice patterns in const fn. #66934

matthewjasper opened this issue Dec 1, 2019 · 4 comments · Fixed by #67467
Labels
A-const-eval Area: Constant evaluation (MIR interpretation) A-slice-patterns Area: Slice patterns, https://github.com/rust-lang/rust/issues/23121 C-bug Category: This is a bug. F-slice_patterns `#![feature(slice_patterns)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@matthewjasper
Copy link
Contributor

The following code ICEs

#![feature(slice_patterns)]

const fn f() {
    let x = [()];
    let [y @ ..] = x;
}

Playground

Backtrace
   Compiling playground v0.0.1 (/playground)
warning: unused variable: `y`
 --> src/lib.rs:5:10
  |
5 |     let [y @ ..] = x;
  |          ^ help: consider prefixing with an underscore: `_y`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: function is never used: `f`
 --> src/lib.rs:3:10
  |
3 | const fn f() {
  |          ^
  |
  = note: `#[warn(dead_code)]` on by default

thread 'rustc' panicked at 'Layout mismatch when copying!
src: OpTy {
    op: Immediate(
        Scalar(
            <ZST>,
        ),
    ),
    layout: TyLayout {
        ty: (),
        details: LayoutDetails {
            variants: Single {
                index: 0,
            },
            fields: Arbitrary {
                offsets: [],
                memory_index: [],
            },
            abi: Aggregate {
                sized: true,
            },
            largest_niche: None,
            align: AbiAndPrefAlign {
                abi: Align {
                    pow2: 0,
                },
                pref: Align {
                    pow2: 3,
                },
            },
            size: Size {
                raw: 0,
            },
        },
    },
}
dest: PlaceTy {
    place: Local {
        frame: 0,
        local: _3,
    },
    layout: TyLayout {
        ty: [(); 1],
        details: LayoutDetails {
            variants: Single {
                index: 0,
            },
            fields: Array {
                stride: Size {
                    raw: 0,
                },
                count: 1,
            },
            abi: Aggregate {
                sized: true,
            },
            largest_niche: None,
            align: AbiAndPrefAlign {
                abi: Align {
                    pow2: 0,
                },
                pref: Align {
                    pow2: 3,
                },
            },
            size: Size {
                raw: 0,
            },
        },
    },
}', src/librustc_mir/interpret/place.rs:872:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:84
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1024
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1428
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:193
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:210
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:475
  12: rust_begin_unwind
             at src/libstd/panicking.rs:375
  13: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:326
  14: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_rvalue_into_place
  15: <rustc_mir::transform::const_prop::ConstPropagator as rustc::mir::visit::MutVisitor>::visit_statement
  16: <rustc_mir::transform::const_prop::ConstProp as rustc_mir::transform::MirPass>::run_pass
  17: rustc_mir::transform::run_passes
  18: rustc_mir::transform::run_optimization_passes
  19: rustc_mir::transform::optimized_mir
  20: rustc::ty::query::__query_compute::optimized_mir
  21: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::optimized_mir>::compute
  22: rustc::dep_graph::graph::DepGraph::with_task_impl
  23: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  24: rustc_metadata::rmeta::encoder::EncodeContext::encode_optimized_mir
  25: <rustc_metadata::rmeta::encoder::EncodeContext as rustc::hir::intravisit::Visitor>::visit_item
  26: rustc::hir::Crate::visit_all_item_likes
  27: rustc_metadata::rmeta::encoder::EncodeContext::encode_crate_root
  28: rustc::ty::context::tls::with_context::{{closure}}
  29: rustc_metadata::rmeta::encoder::encode_metadata
  30: rustc_metadata::rmeta::decoder::cstore_impl::<impl rustc::middle::cstore::CrateStore for rustc_metadata::creader::CStore>::encode_metadata
  31: rustc::ty::context::TyCtxt::encode_metadata
  32: rustc_interface::passes::start_codegen::{{closure}}
  33: rustc_interface::passes::start_codegen
  34: rustc::ty::context::tls::enter_global
  35: rustc_interface::queries::Queries::ongoing_codegen
  36: rustc_interface::interface::run_compiler_in_existing_thread_pool
  37: std::thread::local::LocalKey<T>::with
  38: scoped_tls::ScopedKey<T>::set
  39: syntax::with_globals
@matthewjasper matthewjasper added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ A-slice-patterns Area: Slice patterns, https://github.com/rust-lang/rust/issues/23121 A-const-eval Area: Constant evaluation (MIR interpretation) F-slice_patterns `#![feature(slice_patterns)]` labels Dec 1, 2019
@jonas-schievink jonas-schievink added C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 1, 2019
@Centril
Copy link
Contributor

Centril commented Dec 1, 2019

cc @wesleywiser

@eddyb
Copy link
Member

eddyb commented Dec 2, 2019

Maybe this ends up having type T instead of [T] / [T; N] (T being the element type, () here):

rust/src/librustc/mir/mod.rs

Lines 1790 to 1796 in 4af3ee8

/// These indices are generated by slice patterns.
///
/// slice[from:-to] in Python terms.
Subslice {
from: u32,
to: u32,
},

@eddyb
Copy link
Member

eddyb commented Dec 2, 2019

Yupp, this is wrong (cc @oli-obk):

Subslice { .. } | ConstantIndex { .. } | Index(_) => if base.layout.is_zst() {
OpTy {
op: Operand::Immediate(Scalar::zst().into()),
// the actual index doesn't matter, so we just pick a convenient one like 0
layout: base.layout.field(self, 0)?,
}
} else {
// The rest should only occur as mplace, we do not use Immediates for types
// allowing such operations. This matches place_projection forcing an allocation.
let mplace = base.assert_mem_place();
self.mplace_projection(mplace, proj_elem)?.into()
}

It should look more like this:

let inner_len = len - to - from;
let (meta, ty) = match base.layout.ty.kind {
// It is not nice to match on the type, but that seems to be the only way to
// implement this.
ty::Array(inner, _) =>
(None, self.tcx.mk_array(inner, inner_len)),


Note that this special-casing is limited to ZSTs, but not specific to CTFE.

And so this ICEs in standalone miri (playground):

#![feature(slice_patterns)]

fn main() {
    let x = [()];
    let [y @ ..] = x;
}

@Centril
Copy link
Contributor

Centril commented Dec 20, 2019

Marking as P-high as this is the last blocker for stabilizing #![feature(slice_patterns)].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation (MIR interpretation) A-slice-patterns Area: Slice patterns, https://github.com/rust-lang/rust/issues/23121 C-bug Category: This is a bug. F-slice_patterns `#![feature(slice_patterns)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants