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

Compiler internal error when using generic_const_exprs, and initialising struct in main #137917

Open
B83C opened this issue Mar 3, 2025 · 3 comments
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@B83C
Copy link

B83C commented Mar 3, 2025

Code

use std::ops::BitXor;

const P32: u32 = 0xB7E15163; /* e -2 */
const Q32: u32 = 0x9E3779B9; /* Golden Ratio -1 */
const LG_W: u32 = 32_usize.ilog2();

pub struct Rc6<const ROUNDS: usize>
where
    [(); 2 * ROUNDS + 4]: Sized,
{
    key: [u32; 2 * ROUNDS + 4],
}

pub fn align(block: &[u8]) -> &[u32] {
    let (p, blocks_aligned, _) = unsafe { block.align_to() };
    assert!(p.len() == 0);
    blocks_aligned
}

impl<const ROUNDS: usize> Rc6<ROUNDS>
where
    [(); 2 * ROUNDS + 4]: Sized,
{
    pub fn new(key: &[u32]) -> Self {
        let mut S = [0u32; 2 * ROUNDS + 4];
        let mut L = Vec::from(key);
        // L[0] = key[0];
        S[0] = P32;
        let mut last_key = S[0];
        for s in &mut S[1..] {
            *s = last_key.wrapping_add(Q32);
            last_key = *s;
        }
        let mut a = 0u32;
        let mut b = 0u32;
        for s in 0..3 * L.len().max(S.len()) {
            let i = (s).wrapping_rem(S.len());
            let j = (s).wrapping_rem(L.len());
            a = (S[i].wrapping_add(a).wrapping_add(b)).rotate_left(3);
            b = (L[j].wrapping_add(a).wrapping_add(b)).rotate_left(a.wrapping_add(b));
            S[i] = a;
            L[j] = b;
        }
        Self { key: S }
    }

    pub fn encrypt(&self, block_cipher: &[u32]) -> Vec<u8> {
        let (s, [s_2r2, s_2r3]) = self
            .key
            .split_last_chunk()
            .map(|(a, b)| (a, b.clone()))
            .unwrap();
        let (cipher_blocks, _) = block_cipher.as_chunks();
        cipher_blocks
            .iter()
            .cloned()
            .map(|[mut a, mut b, mut c, mut d]| {
                b = b.wrapping_add(s[0]);
                d = d.wrapping_add(s[1]);
                let (chunks, _) = s[2..].as_chunks();
                for [s_i, s_i1] in chunks.iter().cloned() {
                    let t = Self::round(b);
                    let u = Self::round(d);
                    a = a.bitxor(t).rotate_left(u).wrapping_add(s_i);
                    c = c.bitxor(u).rotate_left(t).wrapping_add(s_i1);
                    (a, b, c, d) = (b, c, d, a);
                }
                a = a.wrapping_add(s_2r2);
                c = c.wrapping_add(s_2r3);
                [a, b, c, d].map(|u| u.to_le_bytes()).concat()
            })
            .flatten()
            .collect::<Vec<_>>()
    }

    pub fn decrypt(&self, block_cipher: &[u32]) -> Vec<u8> {
        let (s, [s_2r2, s_2r3]) = self
            .key
            .split_last_chunk()
            .map(|(a, b)| (a, b.clone()))
            .unwrap();
        let (cipher_blocks, _) = block_cipher.as_chunks();
        cipher_blocks
            .iter()
            .cloned()
            .map(|[mut a, mut b, mut c, mut d]| {
                let (chunks, _) = s[2..].as_chunks();
                a = a.wrapping_sub(s_2r2);
                c = c.wrapping_sub(s_2r3);
                for [s_i, s_i1] in chunks.iter().rev().cloned() {
                    (a, b, c, d) = (d, a, b, c);
                    let t = Self::round(b);
                    let u = Self::round(d);
                    a = a.wrapping_sub(s_i).rotate_right(u).bitxor(t);
                    c = c.wrapping_sub(s_i1).rotate_right(t).bitxor(u);
                }
                b = b.wrapping_sub(s[0]);
                d = d.wrapping_sub(s[1]);
                [a, b, c, d].map(|u| u.to_le_bytes()).concat()
            })
            .flatten()
            .collect::<Vec<_>>()
    }

    fn round(i: u32) -> u32 {
        i.wrapping_mul(i.wrapping_mul(2).wrapping_add(1))
            .rotate_left(LG_W)
    }
}

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

    #[test]
    fn encrypt() {
        let rc6 = Rc6::<20>::new(&[0u32; 4]);
        let enc = rc6.encrypt(&[0u32; 4]);
        let res = [
            0x8f, 0xc3, 0xa5, 0x36, 0x56, 0xb1, 0xf7, 0x78, 0xc1, 0x29, 0xdf, 0x4e, 0x98, 0x48,
            0xa4, 0x1e,
        ];
        assert_eq!(enc, res);

        let key2 = vec![0x67452301, 0xefcdab89, 0x34231201, 0x78675645];
        let rc6 = Rc6::<20>::new(&key2);
        let enc2 = rc6.encrypt(align(&[
            0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf,
            0xe0, 0xf1,
        ]));
        let res2 = [
            0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23, 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4,
            0x3f, 0x18,
        ];
        assert_eq!(enc2, res2);
    }

    #[test]
    fn inverse() {
        // Encrypt and decrypt should be inverses of each other
        let cipher = [0u8; 4 * 4];
        let key = vec![0u32; 4];
        let rc6 = Rc6::<20>::new(&key);
        assert_eq!(
            cipher,
            rc6.decrypt(align(&rc6.encrypt(align(&cipher)))).as_slice()
        );

        let cipher = [
            0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf,
            0xe0, 0xf1,
        ];
        assert_eq!(
            cipher,
            rc6.decrypt(align(&rc6.encrypt(align(&cipher)))).as_slice()
        );
    }

    #[test]
    fn decrypt() {
        let key = vec![0u32; 4];
        let rc6 = Rc6::<20>::new(&key);
        let dec = rc6.decrypt(align(&[
            0x8f, 0xc3, 0xa5, 0x36, 0x56, 0xb1, 0xf7, 0x78, 0xc1, 0x29, 0xdf, 0x4e, 0x98, 0x48,
            0xa4, 0x1e,
        ]));
        let res = [
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00,
        ];
        assert_eq!(dec, res);

        let key2 = vec![0x67452301, 0xefcdab89, 0x34231201, 0x78675645];
        let rc6 = Rc6::<20>::new(&key2);
        let dec2 = rc6.decrypt(align(&[
            0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23, 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4,
            0x3f, 0x18,
        ]));
        let res2 = [
            0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf,
            0xe0, 0xf1,
        ];
        assert_eq!(dec2, res2);
    }
}

fn main() -> AppResult<()> {
    let args = Args::parse();

    let file = File::open(args.img)?;
    let mmap = unsafe { Mmap::map(&file)? };

    let header_rc6 = Rc6::<20>::new(&[0u32; 4]);
    let dec = header_rc6.decrypt(align(&mmap[0..1024]));
}

Meta

rustc --version --verbose:

rustc 1.87.0-nightly (f4a216d28 2025-03-02)
binary: rustc
commit-hash: f4a216d28ee635afce685b4206e713579f66e130
commit-date: 2025-03-02
host: x86_64-unknown-linux-gnu
release: 1.87.0-nightly
LLVM version: 20.1.0

Error output

warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
 --> src/lib.rs:1:12
  |
1 | #![feature(generic_const_exprs)]
  |            ^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
  = note: `#[warn(incomplete_features)]` on by default

note: no errors encountered even though delayed bugs were created

note: those delayed bugs will now be shown as internal compiler errors

error: internal compiler error: Encountered anon const with inference variable args but no error reported
  |
  = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:598:27 - disabled backtrace

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: please attach the file at `/home/b83c/r/phoenixcard-rs/rustc-ice-2025-03-03T06_25_41-363890.txt` to your bug report

note: compiler flags: --crate-type bin -C embed-bitcode=no -C debuginfo=2 -C linker=/usr/bin/clang -C incremental=[REDACTED] -C link-arg=--ld-path=/usr/bin/mold

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
end of query stack
Backtrace


error: internal compiler error: Encountered anon const with inference variable args but no error reported
  |
  = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:598:27
             0: <rustc_errors::DiagCtxtInner>::emit_diagnostic
             1: <rustc_errors::DiagCtxtHandle>::emit_diagnostic
             2: <rustc_span::ErrorGuaranteed as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
             3: <rustc_errors::DiagCtxtHandle>::delayed_bug::<&str>
             4: rustc_trait_selection::traits::try_evaluate_const.cold
             5: <rustc_trait_selection::traits::normalize::AssocTypeNormalizer as rustc_type_ir::fold::TypeFolder<rustc_middle::ty::context::TyCtxt>>::fold_const
             6: <rustc_middle::ty::Ty as rustc_type_ir::fold::TypeSuperFoldable<rustc_middle::ty::context::TyCtxt>>::try_super_fold_with::<rustc_trait_selection::traits::normalize::AssocTypeNormalizer>
             7: <&rustc_middle::ty::list::RawList<(), rustc_middle::ty::generic_args::GenericArg> as rustc_type_ir::fold::TypeFoldable<rustc_middle::ty::context::TyCtxt>>::try_fold_with::<rustc_trait_selection::traits::normalize::AssocTypeNormalizer>
             8: <rustc_middle::ty::InstantiatedPredicates as rustc_type_ir::fold::TypeFoldable<rustc_middle::ty::context::TyCtxt>>::try_fold_with::<rustc_trait_selection::traits::normalize::AssocTypeNormalizer>
             9: <rustc_infer::infer::at::At as rustc_trait_selection::traits::normalize::NormalizeExt>::normalize::<rustc_middle::ty::InstantiatedPredicates>
            10: <rustc_hir_typeck::fn_ctxt::FnCtxt>::instantiate_value_path
            11: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_path
            12: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
            13: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
            14: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_decl
            15: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_block
            16: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
            17: rustc_hir_typeck::check::check_fn
            18: rustc_hir_typeck::typeck_with_inspect::{closure#0}
            19: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::typeck::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 8]>>
            20: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_data_structures::vec_cache::VecCache<rustc_span::def_id::LocalDefId, rustc_middle::query::erase::Erased<[u8; 8]>, rustc_query_system::dep_graph::graph::DepNodeIndex>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, true>
            21: rustc_query_impl::query_impl::typeck::get_query_incr::__rust_end_short_backtrace
            22: <rustc_middle::ty::context::TyCtxt>::par_hir_body_owners::<rustc_hir_analysis::check_crate::{closure#3}>::{closure#0}
            23: rustc_hir_analysis::check_crate
            24: rustc_interface::passes::run_required_analyses
            25: rustc_interface::passes::analysis
            26: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 0]>>
            27: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::SingleCache<rustc_middle::query::erase::Erased<[u8; 0]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, true>
            28: rustc_query_impl::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
            29: rustc_interface::passes::create_and_enter_global_ctxt::<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
            30: rustc_interface::interface::run_compiler::<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}
            31: std::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
            32: <<std::thread::Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
            33: std::sys::pal::unix::thread::Thread::new::thread_start
            34: <unknown>
            35: <unknown>
          

error: internal compiler error: Encountered anon const with inference variable args but no error reported
  |
  = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:598:27
             0: <rustc_errors::DiagCtxtInner>::emit_diagnostic
             1: <rustc_errors::DiagCtxtHandle>::emit_diagnostic
             2: <rustc_span::ErrorGuaranteed as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
             3: <rustc_errors::DiagCtxtHandle>::delayed_bug::<&str>
             4: rustc_trait_selection::traits::try_evaluate_const.cold
             5: <rustc_trait_selection::traits::normalize::AssocTypeNormalizer as rustc_type_ir::fold::TypeFolder<rustc_middle::ty::context::TyCtxt>>::fold_const
             6: <rustc_middle::ty::InstantiatedPredicates as rustc_type_ir::fold::TypeFoldable<rustc_middle::ty::context::TyCtxt>>::try_fold_with::<rustc_trait_selection::traits::normalize::AssocTypeNormalizer>
             7: <rustc_infer::infer::at::At as rustc_trait_selection::traits::normalize::NormalizeExt>::normalize::<rustc_middle::ty::InstantiatedPredicates>
             8: <rustc_hir_typeck::fn_ctxt::FnCtxt>::instantiate_value_path
             9: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_path
            10: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
            11: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
            12: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_decl
            13: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_block
            14: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
            15: rustc_hir_typeck::check::check_fn
            16: rustc_hir_typeck::typeck_with_inspect::{closure#0}
            17: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::typeck::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 8]>>
            18: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_data_structures::vec_cache::VecCache<rustc_span::def_id::LocalDefId, rustc_middle::query::erase::Erased<[u8; 8]>, rustc_query_system::dep_graph::graph::DepNodeIndex>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, true>
            19: rustc_query_impl::query_impl::typeck::get_query_incr::__rust_end_short_backtrace
            20: <rustc_middle::ty::context::TyCtxt>::par_hir_body_owners::<rustc_hir_analysis::check_crate::{closure#3}>::{closure#0}
            21: rustc_hir_analysis::check_crate
            22: rustc_interface::passes::run_required_analyses
            23: rustc_interface::passes::analysis
            24: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 0]>>
            25: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::SingleCache<rustc_middle::query::erase::Erased<[u8; 0]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, true>
            26: rustc_query_impl::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
            27: rustc_interface::passes::create_and_enter_global_ctxt::<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
            28: rustc_interface::interface::run_compiler::<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}
            29: std::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
            30: <<std::thread::Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
            31: std::sys::pal::unix::thread::Thread::new::thread_start
            32: <unknown>
            33: <unknown>

@B83C B83C 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 Mar 3, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 3, 2025
@B83C
Copy link
Author

B83C commented Mar 3, 2025

cargo test works just fine when I don't initialise the struct in main (but instead in unit tests)

@cyrgani
Copy link
Contributor

cyrgani commented Mar 3, 2025

duplicate of #133199 maybe

@theemathas
Copy link
Contributor

theemathas commented Mar 3, 2025

This is incomplete code. At the very least, it's missing some imports and missing the #![feature]. Could you provide enough code that other people could compile to reproduce the error?

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) ❄️ needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. 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