diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 021c1c176d788..9880e7fef5a30 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -5,6 +5,7 @@ use std::{fs, io}; use rustc_abi::Size; use rustc_ast::InlineAsmTemplatePiece; +use rustc_hir::Constness; use tracing::trace; use ty::print::PrettyPrinter; @@ -340,12 +341,18 @@ pub fn write_mir_pretty<'tcx>(tcx: TyCtxt<'tcx>, w: &mut dyn io::Write) -> io::R // For `const fn` we want to render both the optimized MIR and the MIR for ctfe. if tcx.is_const_fn(def_id) { - render_body(w, tcx.optimized_mir(def_id))?; - writeln!(w)?; - writeln!(w, "// MIR FOR CTFE")?; - // Do not use `render_body`, as that would render the promoteds again, but these - // are shared between mir_for_ctfe and optimized_mir - writer.write_mir_fn(tcx.mir_for_ctfe(def_id), w)?; + // In case where comptime const fn, should only render the MIR for ctfe, + // since comptime functions cannot have their MIR optimized + if matches!(tcx.constness(def_id), Constness::Const { always: true }) { + render_body(w, tcx.mir_for_ctfe(def_id))?; + } else { + render_body(w, tcx.optimized_mir(def_id))?; + writeln!(w)?; + writeln!(w, "// MIR FOR CTFE")?; + // Do not use `render_body`, as that would render the promoteds again, but these + // are shared between mir_for_ctfe and optimized_mir + writer.write_mir_fn(tcx.mir_for_ctfe(def_id), w)?; + } } else { if let Some((val, ty)) = tcx.trivial_const(def_id) { ty::print::with_forced_impl_filename_line! { diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index c48c7f25f3522..d4c4f5ab475e9 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -7,7 +7,7 @@ use clippy_utils::{fn_has_unsatisfiable_clauses, sym}; use rustc_errors::Applicability; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::intravisit::FnKind; -use rustc_hir::{Body, FnDecl, def_id}; +use rustc_hir::{Body, Constness, FnDecl, def_id}; use rustc_lint::{LateContext, LateLintPass, declare_lint_pass}; use rustc_middle::mir; use rustc_middle::ty::{self, Ty}; @@ -69,7 +69,13 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { return; } - let mir = cx.tcx.optimized_mir(def_id.to_def_id()); + // Optimizing MIR for `#[rustc_comptime]` functions causes ICE, + // so giving MIR for CTFE for comptime functions instead + let mir = if matches!(cx.tcx.constness(def_id.to_def_id()), Constness::Const { always: true }) { + cx.tcx.mir_for_ctfe(def_id.to_def_id()) + } else { + cx.tcx.optimized_mir(def_id.to_def_id()) + }; let mut possible_borrower = PossibleBorrowerMap::new(cx, mir); diff --git a/src/tools/clippy/tests/ui/redundant_clone-comptime.fixed b/src/tools/clippy/tests/ui/redundant_clone-comptime.fixed new file mode 100644 index 0000000000000..fe45e58c947fb --- /dev/null +++ b/src/tools/clippy/tests/ui/redundant_clone-comptime.fixed @@ -0,0 +1,20 @@ +// rustfix-only-machine-applicable +#![feature(rustc_attrs, const_trait_impl, const_clone, const_destruct)] +#![warn(clippy::redundant_clone)] + +struct S; + +const impl Clone for S { + fn clone(&self) -> Self { + Self + } +} + +#[rustc_comptime] +fn comptime_func() { + let a = S; + let _a = a; + //~^ redundant_clone +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/redundant_clone-comptime.rs b/src/tools/clippy/tests/ui/redundant_clone-comptime.rs new file mode 100644 index 0000000000000..1adaaad68ac27 --- /dev/null +++ b/src/tools/clippy/tests/ui/redundant_clone-comptime.rs @@ -0,0 +1,20 @@ +// rustfix-only-machine-applicable +#![feature(rustc_attrs, const_trait_impl, const_clone, const_destruct)] +#![warn(clippy::redundant_clone)] + +struct S; + +const impl Clone for S { + fn clone(&self) -> Self { + Self + } +} + +#[rustc_comptime] +fn comptime_func() { + let a = S; + let _a = a.clone(); + //~^ redundant_clone +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/redundant_clone-comptime.stderr b/src/tools/clippy/tests/ui/redundant_clone-comptime.stderr new file mode 100644 index 0000000000000..98457a1122ab9 --- /dev/null +++ b/src/tools/clippy/tests/ui/redundant_clone-comptime.stderr @@ -0,0 +1,16 @@ +error: redundant clone + --> tests/ui/redundant_clone-comptime.rs:16:15 + | +LL | let _a = a.clone(); + | ^^^^^^^^ help: remove this + | +note: this value is dropped without further use + --> tests/ui/redundant_clone-comptime.rs:16:14 + | +LL | let _a = a.clone(); + | ^ + = note: `-D clippy::redundant-clone` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui/comptime/emit-mir.rs b/tests/ui/comptime/emit-mir.rs new file mode 100644 index 0000000000000..5fcf2534ae5aa --- /dev/null +++ b/tests/ui/comptime/emit-mir.rs @@ -0,0 +1,8 @@ +//@ check-pass +//@ compile-flags: --emit=mir +#![feature(rustc_attrs)] + +#[rustc_comptime] +fn comptime_fn() {} + +fn main() {}