Repository navigation
[!; 0] incorrectly considered uninhabited #47563
Description
Activity
- addedI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
on Jan 19, 2018 That's weird. The inhabitedness-checking function explicitly checks whether arrays have size zero or not: https://github.com/rust-lang/rust/blob/master/src/librustc/ty/inhabitedness/mod.rs#L265
- addedA-type-systemArea: Type systemArea: Type systemT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.C-bugCategory: This is a bug.Category: This is a bug.
on Jan 19, 2018 @canndrew That check is incorrect, it should default to inhabited if
to_const_intorto_u64returnNone.That's a bug but it doesn't fix this bug right? Here it seems like len would be
Some(0).@dtolnay The length might be unevaluated. If it's possible to evaluate, sure, this code should trigger that, but it's incorrect to assume that the type is uninhabited if the length isn't known yet.
The issue is exactly as @eddyb suggests: the length is unevaluated in the program at the point
uninhabited_fromis called, so it then incorrectly looks at the inhabitedness of the array type becauselen.val.to_const_int() == None.- addedregression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
on Jan 19, 2018 @varkor A problem with your fix is that @dtolnay's code now fails to compile if you make the array have length 1. eg. I would expect this to compile fine:
#![feature(never_type)] enum Helper<T, U> { T(T, [!; 1]), #[allow(dead_code)] U(U), } fn make_the_array() -> [!; 1] { panic!("whoops!"); } fn transmute<T, U>(t: T) -> U { let Helper::U(u) = Helper::T(t, make_the_array()); // ?? u } fn main() { println!("{:?}", transmute::<&str, (*const u8, u64)>("type safety")); }
I think we should still merge it to fix the soundness bug, but why don't we know the value of the constant expression there?
This is an issue with the constant evaluation rather than the fix itself. For some reason, the sizes do not seem to have been evaluated by the time the inhabitedness checks are called. This seems like a bug, and I want to look into when I get some time.
This isn't really about ordering, but rather a lack of normalization.
<&! as Deref>::Target, for example, would exhibit the same problem.There seems to be a lot of bugs related to things not getting normalized. I know I've encountered a few before. Are they all the same bug?
@canndrew Depends. I've been trying to get @nikomatsakis to upstream his lazy normalization work, which would at least make it clear who's responsibility is to normalize anything (if you are traversing types and hit a
TyProjectionorTyAnon, or want the length ofTyArray).- addedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.and removedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Jan 25, 2018 triage: P-high
Regression, though only with
never_typefeature -- but we'd like to stabilize that!The fix is just waiting on bors. Should be in soon!
- added a commit that references this issue
on Jan 25, 2018
Output on my machine as of rustc 1.25.0-nightly (3bd4af8 2018-01-18):
Mentioning @eddyb and @arielb1 who were involved with #45225.
Mentioning the never_type tracking issue #35121.