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: index out of bounds: the len is 0 but the index is 18446744073709551615 #137588

Open
matthiaskrgr opened this issue Feb 25, 2025 · 4 comments
Assignees
Labels
A-strict-provenance Area: Strict provenance for raw pointers C-bug Category: This is a bug. F-contracts `#![feature(contracts)]` 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.

Comments

@matthiaskrgr
Copy link
Member

matthiaskrgr commented Feb 25, 2025

auto-reduced (treereduce-rust):

//@compile-flags: --edition=2024 -Wfuzzy-provenance-casts
#![feature(strict_provenance_lints)]
#![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]

pub(super) fn foo() -> *const Ts {
    unsafe {
        let p2 = 0x52 as *const u32;
    }
}

original:

#![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
#![feature(X211)]

pub(super) fn foo<F: Into<&'r#struct ()>>() -> *const Ts {
    extern "C" {
        fn deref(&self) -> &[T; N] {
        &self.0
    }
    }
    unsafe {
    let p1 = (0x42 as *const u32).wrapping_offset(4);
    let p2 = 0x52 as *const u32;
    p1.offset_from(p2) == 0
}
}

Version information

rustc 1.87.0-nightly (617aad8c2 2025-02-24)
binary: rustc
commit-hash: 617aad8c2e8783f6df8e5d1f8bb1e4bcdc70aa7b
commit-date: 2025-02-24
host: x86_64-unknown-linux-gnu
release: 1.87.0-nightly
LLVM version: 20.1.0

Possibly related line of code:

// If the last line is exactly equal to the line we need to add, we can skip both of
// them. This allows us to avoid output like the following:
// 2 - &
// 2 + if true { true } else { false }
// 3 - if true { true } else { false }
// If those lines aren't equal, we print their diff
let last_line_index = file_lines.lines[file_lines.lines.len() - 1].line_index;
let last_line = &file_lines.file.get_line(last_line_index).unwrap();
if last_line != line_to_add {
buffer.puts(
*row_num - 1,
0,
&self.maybe_anonymized(line_num + file_lines.lines.len() - 1),

Command:
/home/matthias/.rustup/toolchains/master/bin/rustc --edition=2024 -Zcrate-attr=feature(strict_provenance_lints) -Wfuzzy-provenance-casts

Program output

error[E0658]: use of unstable library feature `contracts`
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:4
  |
1 | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
  |    ^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
  = help: add `#![feature(contracts)]` to the crate attributes to enable
  = note: this compiler was built on 2025-02-24; consider upgrading it if it is out of date

error[E0658]: inner macro attributes are unstable
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:4
  |
1 | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
  |    ^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
  = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
  = note: this compiler was built on 2025-02-24; consider upgrading it if it is out of date

error[E0433]: failed to resolve: there are too many leading `super` keywords
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:1
  |
1 | / #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
2 | |
3 | | pub(super) fn foo() -> *const Ts {
4 | |     unsafe {
... |
7 | | }
  | |_^ there are too many leading `super` keywords

error[E0412]: cannot find type `Ts` in this scope
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:1
  |
1 | / #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
2 | |
3 | | pub(super) fn foo() -> *const Ts {
4 | |     unsafe {
... |
7 | | }
  | |_^ not found in this scope

error[E0658]: `#[prelude_import]` is for use by rustc only
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:1
  |
1 | / #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
2 | |
3 | | pub(super) fn foo() -> *const Ts {
4 | |     unsafe {
... |
7 | | }
  | |_^
  |
  = help: add `#![feature(prelude_import)]` to the crate attributes to enable
  = note: this compiler was built on 2025-02-24; consider upgrading it if it is out of date

warning: unused import: `#![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
         
         pub(super) fn foo() -> *const Ts {
             unsafe {
                 let p2 = 0x52 as *const u32;
             }
         }`
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:1
  |
1 | / #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
2 | |
3 | | pub(super) fn foo() -> *const Ts {
4 | |     unsafe {
... |
7 | | }
  | |_^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused `#[macro_use]` import
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:1
  |
1 | / #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
2 | |
3 | | pub(super) fn foo() -> *const Ts {
4 | |     unsafe {
... |
7 | | }
  | |_^

error[E0601]: `main` function not found in crate `mvce`
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:7:2
  |
7 | }
  |  ^ consider adding a `main` function to `/tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs`

error[E0282]: type annotations needed for `&_`
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:30
  |
1 | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
  |                              ^^^      ---------- type must be known at this point
  |
help: consider giving this closure parameter an explicit type, where the type for type parameter `Ret` is specified
  |
1 | #![core::contracts::ensures(|ret: &Ret| ret.is_none_or(Stars::is_valid))]
  |                                 ++++++

error[E0433]: failed to resolve: use of undeclared type `Stars`
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:50
  |
1 | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
  |                                                  ^^^^^ use of undeclared type `Stars`

warning: strict provenance disallows casting integer `usize` to pointer `*const u32`
 --> /tmp/icemaker_global_tempdir.k7JFg2tTZyVa/rustc_testrunner_tmpdir_reporting.GP1WXRQjER3Y/mvce.rs:1:1
  |
1 | / #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
2 | |
3 | | pub(super) fn foo() -> *const Ts {
4 | |     unsafe {
... |
7 | | }
  | |_^
  |
  = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
  = note: requested on the command line with `-W fuzzy-provenance-casts`

thread 'rustc' panicked at compiler/rustc_errors/src/emitter.rs:2562:51:
index out of bounds: the len is 0 but the index is 18446744073709551615
stack backtrace:
   0:     0x7f0a4637bb74 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h596be22ec28e1f3c
   1:     0x7f0a46a1632c - core::fmt::write::h99935240e04ae94a
   2:     0x7f0a47a9b251 - std::io::Write::write_fmt::hd7d0e16eb6e5b705
   3:     0x7f0a4637b9d2 - std::sys::backtrace::BacktraceLock::print::h5fdaf52f50772596
   4:     0x7f0a4637e1de - std::panicking::default_hook::{{closure}}::hb7462bb0b1897901
   5:     0x7f0a4637ddb4 - std::panicking::default_hook::ha25e0f2ba325eca3
   6:     0x7f0a454dc257 - std[42cfc4424709a4ae]::panicking::update_hook::<alloc[8e0abe553a3b8888]::boxed::Box<rustc_driver_impl[cc1cc8592b4b3991]::install_ice_hook::{closure#1}>>::{closure#0}
   7:     0x7f0a4637ea53 - std::panicking::rust_panic_with_hook::h1d0593281290ed3a
   8:     0x7f0a4637e74a - std::panicking::begin_panic_handler::{{closure}}::hbe93a2fb1f3eac26
   9:     0x7f0a4637c049 - std::sys::backtrace::__rust_end_short_backtrace::h818502b20cb893f0
  10:     0x7f0a4637e40d - rust_begin_unwind
  11:     0x7f0a4303e460 - core::panicking::panic_fmt::h97fe394eab998410
  12:     0x7f0a4448f5dc - core::panicking::panic_bounds_check::he97cc1def0115c2e
  13:     0x7f0a476fdaac - <rustc_errors[980ccc5251f847a6]::emitter::HumanEmitter>::draw_code_line
  14:     0x7f0a476fec25 - <rustc_errors[980ccc5251f847a6]::emitter::HumanEmitter>::emit_suggestion_default
  15:     0x7f0a476e7876 - <rustc_errors[980ccc5251f847a6]::emitter::HumanEmitter as rustc_errors[980ccc5251f847a6]::emitter::Emitter>::emit_diagnostic
  16:     0x7f0a476fbff5 - <rustc_errors[980ccc5251f847a6]::DiagCtxtInner>::emit_diagnostic::{closure#3}
  17:     0x7f0a47adbfd8 - rustc_interface[d4bbb1348e70a3ea]::callbacks::track_diagnostic::<core[d63e11fd8aaf2e06]::option::Option<rustc_span[c1c2594b3cfeb2f9]::ErrorGuaranteed>>
  18:     0x7f0a47adaa22 - <rustc_errors[980ccc5251f847a6]::DiagCtxtInner>::emit_diagnostic
  19:     0x7f0a47ada8dd - <rustc_errors[980ccc5251f847a6]::DiagCtxtHandle>::emit_diagnostic
  20:     0x7f0a47ad9d9f - <() as rustc_errors[980ccc5251f847a6]::diagnostic::EmissionGuarantee>::emit_producing_guarantee
  21:     0x7f0a47011019 - rustc_middle[e8e577a537212ebe]::lint::lint_level::lint_level_impl
  22:     0x7f0a47088f05 - <rustc_hir_typeck[bb5bb3924d5fb64e]::cast::CastCheck>::do_check
  23:     0x7f0a4709d96f - rustc_hir_typeck[bb5bb3924d5fb64e]::typeck_with_inspect::{closure#0}
  24:     0x7f0a4709a2c8 - rustc_query_impl[fb7a0f64e8eaa069]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[fb7a0f64e8eaa069]::query_impl::typeck::dynamic_query::{closure#2}::{closure#0}, rustc_middle[e8e577a537212ebe]::query::erase::Erased<[u8; 8usize]>>
  25:     0x7f0a46d2c1cc - rustc_query_system[3f74dc516bc5fce6]::query::plumbing::try_execute_query::<rustc_query_impl[fb7a0f64e8eaa069]::DynamicConfig<rustc_data_structures[72ae77860de7d9ec]::vec_cache::VecCache<rustc_span[c1c2594b3cfeb2f9]::def_id::LocalDefId, rustc_middle[e8e577a537212ebe]::query::erase::Erased<[u8; 8usize]>, rustc_query_system[3f74dc516bc5fce6]::dep_graph::graph::DepNodeIndex>, false, false, false>, rustc_query_impl[fb7a0f64e8eaa069]::plumbing::QueryCtxt, false>
  26:     0x7f0a46d2acaa - rustc_query_impl[fb7a0f64e8eaa069]::query_impl::typeck::get_query_non_incr::__rust_end_short_backtrace
  27:     0x7f0a46d2a94d - <rustc_middle[e8e577a537212ebe]::ty::context::TyCtxt>::par_hir_body_owners::<rustc_hir_analysis[bcbc1ae2e7d0e58d]::check_crate::{closure#3}>::{closure#0}
  28:     0x7f0a46d29fd5 - rustc_hir_analysis[bcbc1ae2e7d0e58d]::check_crate
  29:     0x7f0a46daa4dc - rustc_interface[d4bbb1348e70a3ea]::passes::run_required_analyses
  30:     0x7f0a47a971fa - rustc_interface[d4bbb1348e70a3ea]::passes::analysis
  31:     0x7f0a47a971d9 - rustc_query_impl[fb7a0f64e8eaa069]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[fb7a0f64e8eaa069]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[e8e577a537212ebe]::query::erase::Erased<[u8; 0usize]>>
  32:     0x7f0a47afe28b - rustc_query_system[3f74dc516bc5fce6]::query::plumbing::try_execute_query::<rustc_query_impl[fb7a0f64e8eaa069]::DynamicConfig<rustc_query_system[3f74dc516bc5fce6]::query::caches::SingleCache<rustc_middle[e8e577a537212ebe]::query::erase::Erased<[u8; 0usize]>>, false, false, false>, rustc_query_impl[fb7a0f64e8eaa069]::plumbing::QueryCtxt, false>
  33:     0x7f0a47afdf79 - rustc_query_impl[fb7a0f64e8eaa069]::query_impl::analysis::get_query_non_incr::__rust_end_short_backtrace
  34:     0x7f0a47b3727c - rustc_interface[d4bbb1348e70a3ea]::passes::create_and_enter_global_ctxt::<core[d63e11fd8aaf2e06]::option::Option<rustc_interface[d4bbb1348e70a3ea]::queries::Linker>, rustc_driver_impl[cc1cc8592b4b3991]::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
  35:     0x7f0a47aec120 - rustc_interface[d4bbb1348e70a3ea]::interface::run_compiler::<(), rustc_driver_impl[cc1cc8592b4b3991]::run_compiler::{closure#0}>::{closure#1}
  36:     0x7f0a479ac51c - std[42cfc4424709a4ae]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[d4bbb1348e70a3ea]::util::run_in_thread_with_globals<rustc_interface[d4bbb1348e70a3ea]::util::run_in_thread_pool_with_globals<rustc_interface[d4bbb1348e70a3ea]::interface::run_compiler<(), rustc_driver_impl[cc1cc8592b4b3991]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  37:     0x7f0a479ac940 - <<std[42cfc4424709a4ae]::thread::Builder>::spawn_unchecked_<rustc_interface[d4bbb1348e70a3ea]::util::run_in_thread_with_globals<rustc_interface[d4bbb1348e70a3ea]::util::run_in_thread_pool_with_globals<rustc_interface[d4bbb1348e70a3ea]::interface::run_compiler<(), rustc_driver_impl[cc1cc8592b4b3991]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[d63e11fd8aaf2e06]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  38:     0x7f0a479ad2ab - std::sys::pal::unix::thread::Thread::new::thread_start::h70bf909eb5817fb7
  39:     0x7f0a41ca370a - <unknown>
  40:     0x7f0a41d27aac - <unknown>
  41:                0x0 - <unknown>

error: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: please make sure that you have updated to the latest nightly

note: rustc 1.87.0-nightly (617aad8c2 2025-02-24) running on x86_64-unknown-linux-gnu

note: compiler flags: -Z crate-attr=feature(strict_provenance_lints) -Z dump-mir-dir=dir

query stack during panic:
#0 [typeck] type-checking `foo`
#1 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to 8 previous errors; 3 warnings emitted

Some errors have detailed explanations: E0282, E0412, E0433, E0601, E0658.
For more information about an error, try `rustc --explain E0282`.

@rustbot label +F-X211 +F-strict_provenance_lints

@matthiaskrgr matthiaskrgr added C-bug Category: This is a bug. 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. labels Feb 25, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Feb 25, 2025
@matthiaskrgr matthiaskrgr added A-strict-provenance Area: Strict provenance for raw pointers F-contracts `#![feature(contracts)]` and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Feb 25, 2025
@xizheyin
Copy link
Contributor

xizheyin commented Mar 9, 2025

@rustbot claim

@xizheyin
Copy link
Contributor

xizheyin commented Mar 9, 2025

The problem is a bit tricky, the span of this suggestion message goes from the beginning to the end of the program(maybe because attribute), however the beginning of the program is a dummy_span. resulting in empty file_lines (which should have been line 0 of the program). Is it possible for Span structures to span from 0:0 to 0:0 but not dummy?

let file_lines = sm
.span_to_lines(parts[0].span)
.expect("span_to_lines failed when emitting suggestion");

@workingjubilee
Copy link
Member

The problem is a bit tricky, the span of this suggestion message goes from the beginning to the end of the program(maybe because attribute), however the beginning of the program is a dummy_span. resulting in empty file_lines (which should have been line 0 of the program). Is it possible for Span structures to span from 0:0 to 0:0 but not dummy?

Hm. What do you mean? The dummy span is indeed the span from 0:0 to 0:0. Are you asking if anything important ever has the dummy span, or if there are other cases where we construct the 0:0 span that are not the dummy span?

@xizheyin
Copy link
Contributor

xizheyin commented Mar 17, 2025

The dummy line is where the diag suggestion starts. When a dummy span is passed, the span_to_lines method will return a empty lines.

return Ok(FileLines { file: lo.file, lines: Vec::new() });

The draw_code_line will panic here, because file_lines.len() is 0.
let last_line_index = file_lines.lines[file_lines.lines.len() - 1].line_index;

I don't tend to modify span_to_lines because it's relied on by many other components of rustc. But span_to_lines should indeed return a line that is not empty, i.e. line 0 of the file. @workingjubilee

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-strict-provenance Area: Strict provenance for raw pointers C-bug Category: This is a bug. F-contracts `#![feature(contracts)]` 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.
Projects
None yet
Development

No branches or pull requests

4 participants