Rust: Type validation mistreats layout errors

Created on 20 Apr 2020  路  30Comments  路  Source: rust-lang/rust

The original problem got fixed by avoiding the broken code paths; this issue now tracks fixing those code paths.

Original issue

In the ffi_helpers crate we have a Nullable trait which gives you a generic way to do null pointer checks.

pub trait Nullable {
    const NULL: Self;

    fn is_null(&self) -> bool;
}

A user recently reported that the crate no longer compiles on nightly (https://github.com/Michael-F-Bryan/ffi_helpers/issues/2) because type validation detects that std::ptr::null() and std::ptr::null_mut() create uninitialized raw pointers.

  Compiling playground v0.0.1 (/playground)
error[E0080]: it is undefined behavior to use this value
  --> src/lib.rs:17:5
   |
17 |     const NULL: Self = std::ptr::null_mut();
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized raw pointer
   |
   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

error: aborting due to previous error

For more information about this error, try `rustc --explain E0080`.
error: could not compile `playground`.

I can reproduce this on the playground with the latest nightly, 1.44.0-nightly (2020-04-19 dbf8b6bf116c7bece298).

Is the use shown in that playground example (*self == Self::NULL on a *mut T) actually UB?

Also, I noticed that calling the is_null() method defined on a raw pointer with <*const T>::is_null(*self) doesn't trigger this error, implying that the problem isn't with declaring a constant that contains a null pointer (const NULL: Self = std::ptr::null_mut()), but the fact that we're using it for a comparison. Was this intended, or is it just an oversight in the error detection code?


Full example with output

pub trait Nullable {
    const NULL: Self;

    fn is_null(&self) -> bool;
}

impl<T> Nullable for *const T {
    const NULL: Self = std::ptr::null();

    #[inline]
    fn is_null(&self) -> bool {
        <*const T>::is_null(*self)
    }
}

impl<T> Nullable for *mut T {
    const NULL: Self = std::ptr::null_mut();

    #[inline]
    fn is_null(&self) -> bool {
        *self == Self::NULL
    }
}
Compiling playground v0.0.1 (/playground)
error[E0080]: it is undefined behavior to use this value
  --> src/lib.rs:17:5
   |
17 |     const NULL: Self = std::ptr::null_mut();
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized raw pointer
   |
   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

error: aborting due to previous error

For more information about this error, try `rustc --explain E0080`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

CC: @RalfJung because it looks like they were the last person to touch that error message (9ee4d1aadc7f4151193a7f53d1fcbb4fddf40ece).


This issue has been assigned to @jumbatm via this comment.


A-const-eval C-cleanup T-compiler

Most helpful comment

The beta PR landed, master PR by @pnkfelix is on the way.

All 30 comments

Cc @rust-lang/wg-const-eval

This is definitely not intended, that example you gave is entirely safe code and should compile just fine.

The odd thing is, I am indeed responsible for the error but that was back in https://github.com/rust-lang/rust/pull/66147 which has long arrived on stable -- so the error itself cannot be the source of the regression. Would be good to get the regression narrowed down a bit more.

I also don't understand why == seems to be needed to trigger this. Might be some interaction with promotion?

The error message is probably (hopefully!) just wrong, I doubt the pointer is actually uninitialized. We just show that error when anything goes wrong in this line:
https://github.com/rust-lang/rust/blob/4ca5fd2d7b6b1d75b6cb8f679e8523fb3e7b19e2/src/librustc_mir/interpret/validity.rs#L487-L491
Likely ref_to_mplace really doesn't like that the pointer is NULL. The thing is, this code works fine, and that just makes no sense:

fn main() {
    const NULL: *mut i32 = std::ptr::null_mut();
    println!("{:?}", NULL);
}

@rustbot ping bisect

Hey Cleanup Crew ICE-breakers! This bug has been identified as a good
"Cleanup ICE-breaking candidate". In case it's useful, here are some
[instructions] for tackling these sorts of bugs. Maybe take a look?
Thanks! <3

cc @AminArria @chrissimpkins @contrun @DutchGhost @elshize @ethanboxx @h-michael @HallerPatrick @hdhoang @hellow554 @imtsuki @jakevossen5 @kanru @KarlK90 @LeSeulArtichaut @MAdrianMattocks @matheus-consoli @mental32 @nmccarty @Noah-Kennedy @pard68 @PeytonT @pierreN @Redblueflame @RobbieClarken @RobertoSnap @robjtede @SarthakSingh31 @senden9 @shekohex @sinato @spastorino @turboladen @woshilapin @yerke

It's not an ICE, but if ICE-breakers also help with other bisects then yes this would be awesome. :)

If it helps pinpoint when the error was introduced, my rustc is usually within a couple days of the latest nightly and I made a release of that crate on 2020-04-07 without hitting any compilation errors.

Regression in nightly-2020-04-17. Looking currently for regression commit between 2020-04-17 and 2020-04-16.

searched nightlies: from nightly-2020-04-07 to nightly-2020-04-19
regressed nightly: nightly-2020-04-17
searched commits: from https://github.com/rust-lang/rust/commit/d2230290f7220e740ec08f4d844bf5951e1b74b8 to https://github.com/rust-lang/rust/commit/7f3df5772439eee1c512ed2eb540beef1124d236
regressed commit: https://github.com/rust-lang/rust/commit/7f3df5772439eee1c512ed2eb540beef1124d236

Full Log:

root@ubuntu-c-32-64gib-fra1-01:~# cargo bisect-rustc --preserve --test-dir=foo --start=2020-04-07 --end=2020-04-19installing nightly-2020-04-07
testing...
RESULT: nightly-2020-04-07, ===> No

installing nightly-2020-04-19
testing...
RESULT: nightly-2020-04-19, ===> Yes

installing nightly-2020-04-13
testing...
RESULT: nightly-2020-04-13, ===> No

installing nightly-2020-04-16
testing...
RESULT: nightly-2020-04-16, ===> No

installing nightly-2020-04-17
testing...
RESULT: nightly-2020-04-17, ===> Yes

searched toolchains nightly-2020-04-07 through nightly-2020-04-19
regression in nightly-2020-04-17
fetching https://static.rust-lang.org/dist/2020-04-17/channel-rust-nightly-git-commit-hash.txt
converted 2020-04-17 to 7f3df5772439eee1c512ed2eb540beef1124d236
fetching https://static.rust-lang.org/dist/2020-04-16/channel-rust-nightly-git-commit-hash.txt
converted 2020-04-16 to d2230290f7220e740ec08f4d844bf5951e1b74b8
looking for regression commit between 2020-04-17 and 2020-04-16
opening existing repository at "rust.git"
refreshing repository
fetching (via local git) commits from d2230290f7220e740ec08f4d844bf5951e1b74b8 to 7f3df5772439eee1c512ed2eb540beef1124d236
opening existing repository at "rust.git"
refreshing repository
looking up first commit
looking up second commit
checking that commits are by bors and thus have ci artifacts...
finding bors merge commits
found 7 bors merge commits in the specified range
  commit[0] 2020-04-15UTC: Auto merge of #71139 - matthiaskrgr:submodule_upd, r=Dylan-DPC
  commit[1] 2020-04-15UTC: Auto merge of #71180 - Dylan-DPC:rollup-pscpg6q, r=Dylan-DPC
  commit[2] 2020-04-16UTC: Auto merge of #71159 - topecongiro:rustfmt-1.4.14, r=Dylan-DPC
  commit[3] 2020-04-16UTC: Auto merge of #71173 - RalfJung:miri, r=RalfJung
  commit[4] 2020-04-16UTC: Auto merge of #70831 - sfackler:shrink-future-stack, r=matthewjasper
  commit[5] 2020-04-16UTC: Auto merge of #70755 - wesleywiser:simplify_locals_2_electric_boogaloo, r=oli-obk
  commit[6] 2020-04-16UTC: Auto merge of #71201 - Dylan-DPC:rollup-23202uf, r=Dylan-DPC
validated commits found, specifying toolchains
installing d2230290f7220e740ec08f4d844bf5951e1b74b8
testing...
RESULT: d2230290f7220e740ec08f4d844bf5951e1b74b8, ===> No

installing 7f3df5772439eee1c512ed2eb540beef1124d236
testing...
RESULT: 7f3df5772439eee1c512ed2eb540beef1124d236, ===> Yes

installing 534a41a32952d36ec73656357777ebbea707aeb4
testing...
RESULT: 534a41a32952d36ec73656357777ebbea707aeb4, ===> No

installing 4e4d49d60fd696c4036d438292673a2d7fd34519
testing...
RESULT: 4e4d49d60fd696c4036d438292673a2d7fd34519, ===> No

installing 7fb5187d0423f4cd0441526571b8cd61927123c9
testing...
RESULT: 7fb5187d0423f4cd0441526571b8cd61927123c9, ===> No

searched toolchains d2230290f7220e740ec08f4d844bf5951e1b74b8 through 7f3df5772439eee1c512ed2eb540beef1124d236
installing 7f3df5772439eee1c512ed2eb540beef1124d236
testing...
regression in 7f3df5772439eee1c512ed2eb540beef1124d236


searched nightlies: from nightly-2020-04-07 to nightly-2020-04-19
regressed nightly: nightly-2020-04-17
searched commits: from https://github.com/rust-lang/rust/commit/d2230290f7220e740ec08f4d844bf5951e1b74b8 to https://github.com/rust-lang/rust/commit/7f3df5772439eee1c512ed2eb540beef1124d236
regressed commit: https://github.com/rust-lang/rust/commit/7f3df5772439eee1c512ed2eb540beef1124d236
source code: URL OF A REPOSITORY THAT REPRODUCES THE ERROR

If it regressed in 7f3df57, I guess the only PR that could have caused this is #71141? It might explain why == is needed to trigger the error. Otherwise the culprit might be #71149?

@senden9 awesome, thanks a lot.

I am very sure it's not #71149, that would ICE complaining about bad types in a function call.

I doubt it's https://github.com/rust-lang/rust/pull/71141, that doesn't sound likely to me.

My guess is that it's https://github.com/rust-lang/rust/pull/70566 (Cc @jumbatm), which affects const-prop and what code const-eval gets run on. But still that doesn't explain why it would suddenly stop liking NULL pointers. In fact it's not just NULL, this also fails:

impl<T> Nullable for *mut T {
    const NULL: Self = 4usize as *mut _;

    #[inline]
    fn is_null(&self) -> bool {
        *self == Self::NULL
    }
}

Hm... actually... that const-prop change will mean we run const-prop on some generic code. Maybe it tries to evaluate that == test up there, but because the code is generic cannot actually evaluate enough operands and then some stuff is still uninitialized.

Bingo, the RUSTC_MIRI_BACKTRACE also points at const-prop:

backtrace where errors is created

   0: <rustc_middle::mir::interpret::error::InterpErrorInfo as core::convert::From<rustc_middle::mir::interpret::error::InterpError>>::from
             at src/librustc_middle/mir/interpret/error.rs:268
   1: rustc_mir::interpret::validity::ValidityVisitor<M>::try_visit_primitive
             at src/librustc_mir/interpret/validity.rs:486
   2: <rustc_mir::interpret::validity::ValidityVisitor<M> as rustc_mir::interpret::visitor::ValueVisitor<M>>::visit_value
             at src/librustc_mir/interpret/validity.rs:662
      rustc_mir::interpret::validity::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::validate_operand_internal
             at src/librustc_mir/interpret/validity.rs:834
   3: rustc_mir::interpret::validity::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::const_validate_operand
             at src/librustc_mir/interpret/validity.rs:859
      rustc_mir::const_eval::eval_queries::validate_and_turn_into_const::{{closure}}
             at src/librustc_mir/const_eval/eval_queries.rs:192
      rustc_mir::const_eval::eval_queries::validate_and_turn_into_const
             at src/librustc_mir/const_eval/eval_queries.rs:184
      rustc_mir::const_eval::eval_queries::const_eval_validated_provider::{{closure}}
             at src/librustc_mir/const_eval/eval_queries.rs:257
      core::result::Result<T,E>::and_then
             at /home/r/src/rust/rustc/src/libcore/result.rs:729
      rustc_mir::const_eval::eval_queries::const_eval_validated_provider
             at src/librustc_mir/const_eval/eval_queries.rs:257
   4: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::const_eval_validated>::compute
             at /home/r/src/rust/rustc/src/librustc_middle/ty/query/plumbing.rs:362
   5: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
             at /home/r/src/rust/rustc/src/librustc_query_system/dep_graph/graph.rs:303
      rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
             at /home/r/src/rust/rustc/src/librustc_query_system/dep_graph/graph.rs:200
   6: rustc_query_system::query::plumbing::force_query_with_job::{{closure}}::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:593
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/query/plumbing.rs:71
      rustc_middle::ty::context::tls::enter_context::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1698
      rustc_middle::ty::context::tls::set_tlv
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1682
      rustc_middle::ty::context::tls::enter_context
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1698
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/query/plumbing.rs:71
      rustc_middle::ty::context::tls::with_related_context::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1786
      rustc_middle::ty::context::tls::with_context::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1770
      rustc_middle::ty::context::tls::with_context_opt
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1759
      rustc_middle::ty::context::tls::with_context
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1770
      rustc_middle::ty::context::tls::with_related_context
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1783
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query
             at /home/r/src/rust/rustc/src/librustc_middle/ty/query/plumbing.rs:60
      rustc_query_system::query::plumbing::force_query_with_job::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:583
      rustc_query_system::query::plumbing::with_diagnostics
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:293
      rustc_query_system::query::plumbing::force_query_with_job
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:582
      rustc_query_system::query::plumbing::try_execute_query
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:410
      rustc_query_system::query::plumbing::get_query::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:627
      <rustc_query_system::query::caches::DefaultCache<K,V> as rustc_query_system::query::caches::QueryCache>::lookup
             at /home/r/src/rust/rustc/src/librustc_query_system/query/caches.rs:91
      rustc_query_system::query::plumbing::try_get_cached
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:368
      rustc_query_system::query::plumbing::get_query
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:619
   7: rustc_middle::ty::query::TyCtxtAt::const_eval_validated
             at /home/r/src/rust/rustc/src/librustc_middle/ty/query/plumbing.rs:467
      rustc_middle::ty::query::<impl rustc_middle::ty::context::TyCtxt>::const_eval_validated
             at /home/r/src/rust/rustc/src/librustc_middle/ty/query/plumbing.rs:430
      rustc_mir::const_eval::eval_queries::const_eval_validated_provider
             at src/librustc_mir/const_eval/eval_queries.rs:234
   8: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::const_eval_validated>::compute
             at src/librustc_middle/ty/query/plumbing.rs:362
   9: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
             at /home/r/src/rust/rustc/src/librustc_query_system/dep_graph/graph.rs:303
      rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
             at /home/r/src/rust/rustc/src/librustc_query_system/dep_graph/graph.rs:200
  10: rustc_query_system::query::plumbing::force_query_with_job::{{closure}}::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:593
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}::{{closure}}
             at src/librustc_middle/ty/query/plumbing.rs:71
      rustc_middle::ty::context::tls::enter_context::{{closure}}
             at src/librustc_middle/ty/context.rs:1698
      rustc_middle::ty::context::tls::set_tlv
             at src/librustc_middle/ty/context.rs:1682
      rustc_middle::ty::context::tls::enter_context
             at src/librustc_middle/ty/context.rs:1698
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}
             at src/librustc_middle/ty/query/plumbing.rs:71
      rustc_middle::ty::context::tls::with_related_context::{{closure}}
             at src/librustc_middle/ty/context.rs:1786
      rustc_middle::ty::context::tls::with_context::{{closure}}
             at src/librustc_middle/ty/context.rs:1770
      rustc_middle::ty::context::tls::with_context_opt
             at src/librustc_middle/ty/context.rs:1759
      rustc_middle::ty::context::tls::with_context
             at src/librustc_middle/ty/context.rs:1770
      rustc_middle::ty::context::tls::with_related_context
             at src/librustc_middle/ty/context.rs:1783
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query
             at src/librustc_middle/ty/query/plumbing.rs:60
      rustc_query_system::query::plumbing::force_query_with_job::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:583
      rustc_query_system::query::plumbing::with_diagnostics
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:293
      rustc_query_system::query::plumbing::force_query_with_job
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:582
      rustc_query_system::query::plumbing::try_execute_query
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:410
      rustc_query_system::query::plumbing::get_query::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:627
      <rustc_query_system::query::caches::DefaultCache<K,V> as rustc_query_system::query::caches::QueryCache>::lookup
             at /home/r/src/rust/rustc/src/librustc_query_system/query/caches.rs:91
      rustc_query_system::query::plumbing::try_get_cached
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:368
      rustc_query_system::query::plumbing::get_query
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:619
  11: rustc_middle::mir::interpret::queries::<impl rustc_middle::ty::context::TyCtxt>::const_eval_global_id
             at src/librustc_middle/mir/interpret/queries.rs:0
      rustc_middle::mir::interpret::queries::<impl rustc_middle::ty::context::TyCtxt>::const_eval_resolve
             at src/librustc_middle/mir/interpret/queries.rs:45
  12: rustc_middle::ty::sty::Const::eval
             at /home/r/src/rust/rustc/src/librustc_middle/ty/sty.rs:2366
      <rustc_trait_selection::traits::query::normalize::QueryNormalizer as rustc_middle::ty::fold::TypeFolder>::fold_const
             at src/librustc_trait_selection/traits/query/normalize.rs:206
  13: rustc_middle::ty::structural_impls::<impl rustc_middle::ty::fold::TypeFoldable for &rustc_middle::ty::sty::Const>::fold_with
             at /home/r/src/rust/rustc/src/librustc_middle/ty/structural_impls.rs:1005
      <rustc_middle::ty::subst::GenericArg as rustc_middle::ty::fold::TypeFoldable>::super_fold_with
             at /home/r/src/rust/rustc/src/librustc_middle/ty/subst.rs:158
      rustc_middle::ty::fold::TypeFoldable::fold_with
             at /home/r/src/rust/rustc/src/librustc_middle/ty/fold.rs:49
  14: <rustc_infer::infer::at::At as rustc_trait_selection::traits::query::normalize::AtExt>::normalize
             at /home/r/src/rust/rustc/src/librustc_trait_selection/traits/query/normalize.rs:62
  15: rustc_traits::normalize_erasing_regions::normalize_generic_arg_after_erasing_regions::{{closure}}
             at src/librustc_traits/normalize_erasing_regions.rs:24
      rustc_infer::infer::InferCtxtBuilder::enter::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_infer/infer/mod.rs:595
      rustc_middle::ty::context::GlobalCtxt::enter_local::{{closure}}::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1530
      rustc_middle::ty::context::tls::enter_context::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1698
      rustc_middle::ty::context::tls::set_tlv
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1682
      rustc_middle::ty::context::tls::enter_context
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1698
      rustc_middle::ty::context::GlobalCtxt::enter_local::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1530
      rustc_middle::ty::context::tls::with_related_context::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1786
      rustc_middle::ty::context::tls::with_context::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1770
      rustc_middle::ty::context::tls::with_context_opt
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1759
      rustc_middle::ty::context::tls::with_context
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1770
      rustc_middle::ty::context::tls::with_related_context
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1783
      rustc_middle::ty::context::GlobalCtxt::enter_local
             at /home/r/src/rust/rustc/src/librustc_middle/ty/context.rs:1522
  16: rustc_infer::infer::InferCtxtBuilder::enter
             at /home/r/src/rust/rustc/src/librustc_infer/infer/mod.rs:594
  17: rustc_traits::normalize_erasing_regions::normalize_generic_arg_after_erasing_regions
             at src/librustc_traits/normalize_erasing_regions.rs:22
  18: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::normalize_generic_arg_after_erasing_regions>::compute
             at src/librustc_middle/ty/query/plumbing.rs:362
  19: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
             at /home/r/src/rust/rustc/src/librustc_query_system/dep_graph/graph.rs:303
      rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
             at /home/r/src/rust/rustc/src/librustc_query_system/dep_graph/graph.rs:200
  20: rustc_query_system::query::plumbing::force_query_with_job::{{closure}}::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:593
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}::{{closure}}
             at src/librustc_middle/ty/query/plumbing.rs:71
      rustc_middle::ty::context::tls::enter_context::{{closure}}
             at src/librustc_middle/ty/context.rs:1698
      rustc_middle::ty::context::tls::set_tlv
             at src/librustc_middle/ty/context.rs:1682
      rustc_middle::ty::context::tls::enter_context
             at src/librustc_middle/ty/context.rs:1698
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}
             at src/librustc_middle/ty/query/plumbing.rs:71
      rustc_middle::ty::context::tls::with_related_context::{{closure}}
             at src/librustc_middle/ty/context.rs:1786
      rustc_middle::ty::context::tls::with_context::{{closure}}
             at src/librustc_middle/ty/context.rs:1770
      rustc_middle::ty::context::tls::with_context_opt
             at src/librustc_middle/ty/context.rs:1759
      rustc_middle::ty::context::tls::with_context
             at src/librustc_middle/ty/context.rs:1770
      rustc_middle::ty::context::tls::with_related_context
             at src/librustc_middle/ty/context.rs:1783
      rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query
             at src/librustc_middle/ty/query/plumbing.rs:60
      rustc_query_system::query::plumbing::force_query_with_job::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:583
      rustc_query_system::query::plumbing::with_diagnostics
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:293
      rustc_query_system::query::plumbing::force_query_with_job
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:582
      rustc_query_system::query::plumbing::try_execute_query
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:410
      rustc_query_system::query::plumbing::get_query::{{closure}}
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:627
      <rustc_query_system::query::caches::DefaultCache<K,V> as rustc_query_system::query::caches::QueryCache>::lookup
             at /home/r/src/rust/rustc/src/librustc_query_system/query/caches.rs:91
      rustc_query_system::query::plumbing::try_get_cached
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:368
      rustc_query_system::query::plumbing::get_query
             at /home/r/src/rust/rustc/src/librustc_query_system/query/plumbing.rs:619
  21: rustc_middle::ty::query::TyCtxtAt::normalize_generic_arg_after_erasing_regions
             at src/librustc_middle/ty/query/plumbing.rs:467
      rustc_middle::ty::query::<impl rustc_middle::ty::context::TyCtxt>::normalize_generic_arg_after_erasing_regions
             at src/librustc_middle/ty/query/plumbing.rs:430
      <rustc_middle::ty::normalize_erasing_regions::NormalizeAfterErasingRegionsFolder as rustc_middle::ty::fold::TypeFolder>::fold_const
             at src/librustc_middle/ty/normalize_erasing_regions.rs:103
  22: rustc_middle::ty::structural_impls::<impl rustc_middle::ty::fold::TypeFoldable for &rustc_middle::ty::sty::Const>::fold_with
             at /home/r/src/rust/rustc/src/librustc_middle/ty/structural_impls.rs:1005
      rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::normalize_erasing_regions
             at /home/r/src/rust/rustc/src/librustc_middle/ty/normalize_erasing_regions.rs:37
  23: rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::subst_and_normalize_erasing_regions
             at /home/r/src/rust/rustc/src/librustc_middle/ty/normalize_erasing_regions.rs:82
  24: rustc_mir::interpret::eval_context::InterpCx<M>::subst_from_frame_and_normalize_erasing_regions
             at src/librustc_mir/interpret/eval_context.rs:442
      rustc_mir::interpret::eval_context::InterpCx<M>::subst_from_current_frame_and_normalize_erasing_regions
             at src/librustc_mir/interpret/eval_context.rs:431
      rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_operand
             at src/librustc_mir/interpret/operand.rs:489
  25: rustc_mir::transform::const_prop::ConstPropagator::check_binary_op::{{closure}}
             at src/librustc_mir/transform/const_prop.rs:534
      rustc_mir::transform::const_prop::ConstPropagator::use_ecx
             at src/librustc_mir/transform/const_prop.rs:417
  26: rustc_mir::transform::const_prop::ConstPropagator::check_binary_op
             at src/librustc_mir/transform/const_prop.rs:534
  27: rustc_mir::transform::const_prop::ConstPropagator::const_prop
             at src/librustc_mir/transform/const_prop.rs:0
      <rustc_mir::transform::const_prop::ConstPropagator as rustc_middle::mir::visit::MutVisitor>::visit_statement
             at src/librustc_mir/transform/const_prop.rs:836
  28: rustc_middle::mir::visit::MutVisitor::super_basic_block_data
             at /home/r/src/rust/rustc/src/librustc_middle/mir/visit.rs:322
      rustc_middle::mir::visit::MutVisitor::visit_basic_block_data
             at /home/r/src/rust/rustc/src/librustc_middle/mir/visit.rs:93
      rustc_middle::mir::visit::MutVisitor::super_body
             at /home/r/src/rust/rustc/src/librustc_middle/mir/visit.rs:275
      rustc_middle::mir::visit::MutVisitor::visit_body
             at /home/r/src/rust/rustc/src/librustc_middle/mir/visit.rs:87
  29: <rustc_mir::transform::const_prop::ConstProp as rustc_mir::transform::MirPass>::run_pass
             at src/librustc_mir/transform/const_prop.rs:155
  30: rustc_mir::transform::run_passes::{{closure}}
             at src/librustc_mir/transform/mod.rs:165
      rustc_mir::transform::run_passes
             at src/librustc_mir/transform/mod.rs:172
  31: rustc_mir::transform::run_optimization_passes
             at src/librustc_mir/transform/mod.rs:270
  32: rustc_mir::transform::optimized_mir
             at src/librustc_mir/transform/mod.rs:337

If it regressed in 7f3df57, I guess the only PR that could have caused this is #71141?

Oops, I meant #70566. I can't even copy-paste correcly 馃槃

But then it gets weird. We end up here:

https://github.com/rust-lang/rust/blob/33500a2bbfec4482e0f149eafdeb9e111feeb5fc/src/librustc_mir/interpret/operand.rs#L489

and then here

https://github.com/rust-lang/rust/blob/33500a2bbfec4482e0f149eafdeb9e111feeb5fc/src/librustc_mir/interpret/eval_context.rs#L444

And then somehow we end up evaluating a const (?!?) even though we just wanted to subst on a Const (not eval, that would be the next thing eval_operand does). And that evaluation goes very wrong as the const is somehow not initialized.

I can see it evaluating <*mut T as Nullable>::NULL. That is quite strange because we don't actually know T, so this really cannot be evaluated... but somehow we do not have sanity checks that catch this?

We already have a very similar test for Nullable. It's curious that it didn't catch this.

https://github.com/rust-lang/rust/blob/20fc02f836f3035b86b56a7cedb97c5cd4ed9612/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs#L1-L18

Ah, changing the test case to // build-pass and adding #![crate_type = "lib"] reproduces the error.

Ah, good catch! Probably it was a mistake to not add #![crate_type = "lib]" there in the first place, because built as a binary these impl are just dead code.

The test was added in https://github.com/rust-lang/rust/pull/51852.

@rustbot claim

Independent of what we do on master, I propose that to fix the regression on beta (which just recently branched, with this bug) we revert https://github.com/rust-lang/rust/pull/70566 in that branch. The change is diagnostics-only, it's a tiny patch, I think the risk is very low.

Is it okay to make that a beta-only PR?

Maybe ask @Mark-Simulacrum?

Yeah, anything that just needs a fix on beta (and we want an entirely different fix on master) can be a beta-only PR, though likely I should not the reviewer for it.

See https://github.com/rust-lang/rust/pull/71386#discussion_r412848970 for some more analysis and a proposed solution.

Namely, the proposed solution is to:

  • Equip try_validation! with a pattern of errors to catch, the rest is forwarded. (Figuring out all the right patterns will take a few runs of the test suite here.)
  • Forward InvalidProgram errors out of validation instead of ICEing.

The beta PR landed, master PR by @pnkfelix is on the way.

This bug is now fixed, so I will remove all the critical label. But let's keep this open to track the issue of validation swallowing TooGeneric errors.

The reversion on master landed on PR #71533 .

Still need to assign a priority to the remaining issue of validation swallowing TooGeneric errors, so ...

@rustbot prioritize

Assigning P-medium as discussed as part of the Prioritization Working Group process and removing I-prioritize.

@Mark-Simulacrum As this problem raised in the Crater run, should #71663 be nominated to be backported to beta?

My understanding is that https://github.com/rust-lang/rust/pull/71441 was the intended fix for beta and we expect #71663 to go with the trains, i.e. there is no need for a backport. But if I'm wrong, we should indeed nominate it.

Indeed, the beta fix was to revert the original incorrect PR. This PR that just landed now just fixed https://github.com/rust-lang/rust/issues/69021, which doesn't need backporting.

However, I am going to re-open this issue because validation still swallows layout errors in many cases -- just this one particular case got fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

withoutboats picture withoutboats  路  211Comments

withoutboats picture withoutboats  路  308Comments

GuillaumeGomez picture GuillaumeGomez  路  300Comments

Leo1003 picture Leo1003  路  898Comments

nikomatsakis picture nikomatsakis  路  274Comments