Skip to content

Fix ICE in try_to_raw_bytes when array elements have mismatched#152794

Open
reddevilmidzy wants to merge 1 commit intorust-lang:mainfrom
reddevilmidzy:mgca-print
Open

Fix ICE in try_to_raw_bytes when array elements have mismatched#152794
reddevilmidzy wants to merge 1 commit intorust-lang:mainfrom
reddevilmidzy:mgca-print

Conversation

@reddevilmidzy
Copy link
Member

@reddevilmidzy reddevilmidzy commented Feb 18, 2026

close: #152683

After #152001, suffixed integer literals preserve their own type during const lowering, so try_to_raw_bytes could call .to_u8() on a scalar with size > 1, causing an ICE. Fix by using try_to_bits(Size::from_bytes(1)).ok() instead.

r? BoxyUwU

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 18, 2026
@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Feb 18, 2026
@rustbot
Copy link
Collaborator

rustbot commented Feb 18, 2026

BoxyUwU is currently at their maximum review capacity.
They may take a while to respond.

@reddevilmidzy
Copy link
Member Author

reddevilmidzy commented Feb 19, 2026

Ah, it seems like the issue is resolved in #152492, but would it be better to revert the change to try_to_raw_bytes and just add the test?

The error changes like this:

#![expect(incomplete_features)]
#![feature(adt_const_params, generic_const_parameter_types, min_generic_const_args)]
fn foo<const N: usize, const A: [u8; N]>() {}

fn main() {
    foo::<_, { [0, 1u8, 2u32, 8u64] }>();
    //~^ ERROR the constant `8` is not of type `u8`
    //~| ERROR the constant `2` is not of type `u8`
}

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 24, 2026

Hmm, I would expect it to still be possible to get this ICE somehow even with #152492 🤔 I'm not sure exactly what that would look like though. The underlying problem here remains that we assume nested valtrees are correct for the parent valtree's type.

Even if we check in wfcheck whether this is the case or not diagnostics will still need to handle such illformed valtrees correctly and I expect diagnostics to be calling this function

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 24, 2026

Though there's also #152906 which may have interactions here 🤔 Though probably not...

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 24, 2026

#![expect(incomplete_features)]
#![feature(adt_const_params, min_generic_const_args)]

struct ArrWrap<const N: [u8; 1]>;

fn main() {
    let _: ArrWrap<{ [1_u8] }>
          = ArrWrap::<{ [1_u16] }>;
}

does this ICE even with #152492?

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 24, 2026

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 24, 2026
@reddevilmidzy
Copy link
Member Author

#![expect(incomplete_features)]
#![feature(adt_const_params, min_generic_const_args)]

struct ArrWrap<const N: [u8; 1]>;

fn main() {
    let _: ArrWrap<{ [1_u8] }>
          = ArrWrap::<{ [1_u16] }>;
}

does this ICE even with #152492?

#152492 did not cover this case (ICE occurred even when 152492 was applied), and this PR seems to solve it.

@reddevilmidzy
Copy link
Member Author

Hmm, I would expect it to still be possible to get this ICE somehow even with #152492 🤔 I'm not sure exactly what that would look like though. The underlying problem here remains that we assume nested valtrees are correct for the parent valtree's type.

Even if we check in wfcheck whether this is the case or not diagnostics will still need to handle such illformed valtrees correctly and I expect diagnostics to be calling this function

That makes sense, thanks!

@rustbot
Copy link
Collaborator

rustbot commented Feb 25, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

// `&str` can be interpreted as raw bytes
ty::Str => {}
// `&[u8]` can be interpreted as raw bytes
ty::Slice(slice_ty) if *slice_ty == tcx.types.u8 => {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these checks for tcx.types.u8 are effectively meaningless under mGCA i think.

let iterator = self
.to_branch()
.into_iter()
.map(|ct| ct.try_to_leaf()?.try_to_bits(Size::from_bytes(1)).ok().map(|b| b as u8));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you instead check that the type of the of the element ty::Value is u8 then call to_u8? I expect we don't want to let this function succeed for an array of 1-byte sized ADTs wrapping a u8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ICE]: expected int of size 1, but got size 8

3 participants