diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 5156a8d3479..e901ca36dad 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -65,7 +65,7 @@ const BASE_IMPL: &[&str] = &[label_strs::associated_item_def_ids, label_strs::generics_of, label_strs::impl_trait_header]; -/// DepNodes for mir_built/Optimized, which is relevant in "executable" +/// DepNodes for exported mir bodies, which is relevant in "executable" /// code, i.e., functions+methods const BASE_MIR: &[&str] = &[label_strs::optimized_mir, label_strs::promoted_mir]; diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index b984df3646e..aa2cddad093 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -77,4 +77,10 @@ fn clone(&self) -> Self { *self } /// /// (Eligible functions might nevertheless be skipped for other reasons.) hook is_eligible_for_coverage(key: LocalDefId) -> bool; + + /// Create the MIR for a given `DefId` - this includes + /// unreachable code. + /// You do not want to call this yourself, instead use the cached version + /// via `mir_built` + hook build_mir(key: LocalDefId) -> mir::Body<'tcx>; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3984b3b61c2..38cfd11a016 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -505,21 +505,15 @@ separate_provide_extern } - /// Fetch the MIR for a given `DefId` right after it's built - this includes - /// unreachable code. + /// Build the MIR for a given `DefId` and prepare it for const qualification. + /// + /// See the [rustc dev guide] for more info. + /// + /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html query mir_built(key: LocalDefId) -> &'tcx Steal> { desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) } } - /// Fetch the MIR for a given `DefId` up till the point where it is - /// ready for const qualification. - /// - /// See the README for the `mir` module for details. - query mir_const(key: LocalDefId) -> &'tcx Steal> { - desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key) } - no_hash - } - /// Try to build an abstract representation of the given constant. query thir_abstract_const( key: DefId diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index 109ffedec55..0475bb8908b 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -6,7 +6,7 @@ //! present, and if so we branch off into this module, which implements the attribute by //! implementing a custom lowering from THIR to MIR. //! -//! The result of this lowering is returned "normally" from the `mir_built` query, with the only +//! The result of this lowering is returned "normally" from the `build_mir` hook, with the only //! notable difference being that the `injected` field in the body is set. Various components of the //! MIR pipeline, like borrowck and the pass manager will then consult this field (via //! `body.should_skip()`) to skip the parts of the MIR pipeline that precede the MIR phase the user diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index acadfe7b35e..a43aadab478 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -18,6 +18,7 @@ use rustc_middle::middle::region; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::*; +use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::{ self, BindingMode, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir, }; @@ -30,13 +31,6 @@ use super::lints; -pub(crate) fn mir_built( - tcx: TyCtxt<'_>, - def: LocalDefId, -) -> &rustc_data_structures::steal::Steal> { - tcx.alloc_steal_mir(mir_build(tcx, def)) -} - pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, @@ -54,7 +48,8 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( } /// Construct the MIR for a given `DefId`. -fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { +pub(crate) fn mir_build<'tcx>(tcx: TyCtxtAt<'tcx>, def: LocalDefId) -> Body<'tcx> { + let tcx = tcx.tcx; tcx.ensure_with_value().thir_abstract_const(def); if let Err(e) = tcx.check_match(def) { return construct_error(tcx, def, e); diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 7b22aea9158..82fb7d1ae4a 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -22,14 +22,14 @@ pub mod lints; mod thir; -use rustc_middle::query::Providers; +use rustc_middle::util::Providers; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn provide(providers: &mut Providers) { providers.check_match = thir::pattern::check_match; providers.lit_to_const = thir::constant::lit_to_const; - providers.mir_built = build::mir_built; + providers.hooks.build_mir = build::mir_build; providers.closure_saved_names_of_captured_variables = build::closure_saved_names_of_captured_variables; providers.check_unsafety = check_unsafety::check_unsafety; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 24bc263e5a7..15988c0ea6b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -127,7 +127,7 @@ pub fn provide(providers: &mut Providers) { cross_crate_inline::provide(providers); providers.queries = query::Providers { mir_keys, - mir_const, + mir_built, mir_const_qualif, mir_promoted, mir_drops_elaborated_and_const_checked, @@ -259,9 +259,9 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { // N.B., this `borrow()` is guaranteed to be valid (i.e., the value // cannot yet be stolen), because `mir_promoted()`, which steals - // from `mir_const()`, forces this query to execute before + // from `mir_built()`, forces this query to execute before // performing the steal. - let body = &tcx.mir_const(def).borrow(); + let body = &tcx.mir_built(def).borrow(); if body.return_ty().references_error() { // It's possible to reach here without an error being emitted (#121103). @@ -279,19 +279,13 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { validator.qualifs_in_return_place() } -/// Make MIR ready for const evaluation. This is run on all MIR, not just on consts! -/// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query). -/// We used to have this for pre-miri MIR based const eval. -fn mir_const(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal> { +fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal> { // MIR unsafety check uses the raw mir, so make sure it is run. if !tcx.sess.opts.unstable_opts.thir_unsafeck { tcx.ensure_with_value().mir_unsafety_check_result(def); } - // has_ffi_unwind_calls query uses the raw mir, so make sure it is run. - tcx.ensure_with_value().has_ffi_unwind_calls(def); - - let mut body = tcx.mir_built(def).steal(); + let mut body = tcx.build_mir(def); pass_manager::dump_mir_for_phase_change(tcx, &body); @@ -339,7 +333,9 @@ fn mir_promoted( | DefKind::AnonConst => tcx.mir_const_qualif(def), _ => ConstQualifs::default(), }; - let mut body = tcx.mir_const(def).steal(); + // has_ffi_unwind_calls query uses the raw mir, so make sure it is run. + tcx.ensure_with_value().has_ffi_unwind_calls(def); + let mut body = tcx.mir_built(def).steal(); if let Some(error_reported) = const_qualifs.tainted_by_errors { body.tainted_by_errors = Some(error_reported); } diff --git a/tests/ui/binding/issue-53114-safety-checks.stderr b/tests/ui/binding/issue-53114-safety-checks.stderr index b7d805d9171..9d909e915c2 100644 --- a/tests/ui/binding/issue-53114-safety-checks.stderr +++ b/tests/ui/binding/issue-53114-safety-checks.stderr @@ -1,3 +1,23 @@ +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:23:13 + | +LL | let _ = &p.b; + | ^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:28:17 + | +LL | let (_,) = (&p.b,); + | ^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:24:13 | @@ -31,20 +51,20 @@ LL | let (_,) = (&u2.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:23:13 + --> $DIR/issue-53114-safety-checks.rs:37:16 | -LL | let _ = &p.b; - | ^^^^ +LL | let _: _ = &p.b; + | ^^^^ | = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:28:17 + --> $DIR/issue-53114-safety-checks.rs:42:20 | -LL | let (_,) = (&p.b,); - | ^^^^ +LL | let (_,): _ = (&p.b,); + | ^^^^ | = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) @@ -83,20 +103,20 @@ LL | let (_,): _ = (&u2.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:37:16 + --> $DIR/issue-53114-safety-checks.rs:51:11 | -LL | let _: _ = &p.b; - | ^^^^ +LL | match &p.b { _ => { } } + | ^^^^ | = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:42:20 + --> $DIR/issue-53114-safety-checks.rs:56:12 | -LL | let (_,): _ = (&p.b,); - | ^^^^ +LL | match (&p.b,) { (_,) => { } } + | ^^^^ | = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) @@ -134,26 +154,6 @@ LL | match (&u2.a,) { (_,) => { } } | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:51:11 - | -LL | match &p.b { _ => { } } - | ^^^^ - | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses - = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - -error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:56:12 - | -LL | match (&p.b,) { (_,) => { } } - | ^^^^ - | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses - = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - error: aborting due to 18 previous errors Some errors have detailed explanations: E0133, E0793. diff --git a/tests/ui/coroutine/clone-rpit.next.stderr b/tests/ui/coroutine/clone-rpit.next.stderr index 02d3390496a..41aa2d63af0 100644 --- a/tests/ui/coroutine/clone-rpit.next.stderr +++ b/tests/ui/coroutine/clone-rpit.next.stderr @@ -14,11 +14,6 @@ note: ...which requires promoting constants in MIR for `foo::{closure#0}`... | LL | move |_: ()| { | ^^^^^^^^^^^^ -note: ...which requires preparing `foo::{closure#0}` for borrow checking... - --> $DIR/clone-rpit.rs:14:5 - | -LL | move |_: ()| { - | ^^^^^^^^^^^^ note: ...which requires checking if `foo::{closure#0}` contains FFI-unwind calls... --> $DIR/clone-rpit.rs:14:5 | diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr index b2d20af883a..98cad18d442 100644 --- a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr @@ -18,8 +18,8 @@ LL | struct Dealigned(u8, T); | = Box query stack during panic: -#0 [mir_const] preparing `::eq` for borrow checking -#1 [mir_promoted] promoting constants in MIR for `::eq` +#0 [mir_built] building MIR for `::eq` +#1 [check_unsafety] unsafety-checking `::eq` end of query stack error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/proc_macro_generated_packed.stderr b/tests/ui/resolve/proc_macro_generated_packed.stderr index 507e5867c90..4e716704610 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.stderr +++ b/tests/ui/resolve/proc_macro_generated_packed.stderr @@ -9,8 +9,8 @@ LL | struct Dealigned(u8, T); | = Box query stack during panic: -#0 [mir_const] preparing `::eq` for borrow checking -#1 [mir_promoted] promoting constants in MIR for `::eq` +#0 [mir_built] building MIR for `::eq` +#1 [check_unsafety] unsafety-checking `::eq` end of query stack error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr index df466609a12..084008d8b2a 100644 --- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr +++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -34,11 +34,6 @@ note: ...which requires const checking `Alpha::V3::{constant#0}`... | LL | V3 = Self::V1 {} as u8 + 2, | ^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires preparing `Alpha::V3::{constant#0}` for borrow checking... - --> $DIR/self-in-enum-definition.rs:5:10 - | -LL | V3 = Self::V1 {} as u8 + 2, - | ^^^^^^^^^^^^^^^^^^^^^ note: ...which requires building MIR for `Alpha::V3::{constant#0}`... --> $DIR/self-in-enum-definition.rs:5:10 |