diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 6b109e8b8e2f4..1670e2da71fb3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -180,6 +180,9 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let llfn = cx.get_fn(instance); let mut mir = tcx.instance_mir(instance.def); + // Note that the ABI logic has deduced facts about the functions' parameters based on the MIR we + // got here (`deduce_param_attrs`). That means we can *not* apply arbitrary further MIR + // transforms as that may invalidate those deduced facts! let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty()); debug!("fn_abi: {:?}", fn_abi); @@ -317,6 +320,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } +/// Replace `clone` calls that come from `use` statements with direct copies if possible. // FIXME: Move this function to mir::transform when post-mono MIR passes land. fn optimize_use_clone<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, diff --git a/compiler/rustc_middle/src/middle/deduced_param_attrs.rs b/compiler/rustc_middle/src/middle/deduced_param_attrs.rs index f9177a067b413..68d1c852f0e27 100644 --- a/compiler/rustc_middle/src/middle/deduced_param_attrs.rs +++ b/compiler/rustc_middle/src/middle/deduced_param_attrs.rs @@ -3,7 +3,7 @@ use rustc_macros::{Decodable, Encodable, HashStable}; use crate::ty::{Ty, TyCtxt, TypingEnv}; /// Flags that dictate how a parameter is mutated. If the flags are empty, the param is -/// read-only. If non-empty, it is read-only with conditions. +/// read-only. If non-empty, it is read-only if *all* flags' conditions are met. #[derive(Clone, Copy, PartialEq, Debug, Decodable, Encodable, HashStable)] pub struct DeducedReadOnlyParam(u8); @@ -53,6 +53,7 @@ impl DeducedParamAttrs { ty: Ty<'tcx>, ) -> bool { let read_only = self.read_only; + // We have to check *all* set bits; only if all checks pass is this truly read-only. if read_only.contains(DeducedReadOnlyParam::MUTATED) { return false; } diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs index 2ba1aa05024f3..e421e47bd1615 100644 --- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs +++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs @@ -4,6 +4,10 @@ //! body of the function instead of just the signature. These can be useful for optimization //! purposes on a best-effort basis. We compute them here and store them into the crate metadata so //! dependent crates can use them. +//! +//! Note that this *crucially* relies on codegen *not* doing any more MIR-level transformations +//! after `optimized_mir`! We check for things that are *not* guaranteed to be preserved by MIR +//! transforms, such as which local variables happen to be mutated. use rustc_hir::def_id::LocalDefId; use rustc_index::IndexVec;