From 95318b47831365e0fac4ea8af62e218cde9d1e3a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 9 Mar 2024 23:17:25 +0100 Subject: [PATCH 01/11] MIR: build up a list of required_fns --- compiler/rustc_middle/src/mir/mod.rs | 7 ++- .../rustc_mir_build/src/build/custom/mod.rs | 1 + compiler/rustc_mir_transform/src/lib.rs | 5 +- .../src/required_consts.rs | 46 +++++++++++++++++-- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 0221bc6c36383..f5e70b683ad35 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -9,7 +9,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{pretty_print_const, with_no_trimmed_paths}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::visit::TypeVisitableExt; -use crate::ty::{self, List, Ty, TyCtxt}; +use crate::ty::{self, Instance, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, UserTypeAnnotationIndex}; use crate::ty::{GenericArg, GenericArgsRef}; @@ -375,6 +375,9 @@ pub struct Body<'tcx> { /// We hold in this field all the constants we are not able to evaluate yet. pub required_consts: Vec>, + /// Functions that need to monomorphize successfully for this MIR to be well-formed. + pub required_fns: Vec>, + /// Does this body use generic parameters. This is used for the `ConstEvaluatable` check. /// /// Note that this does not actually mean that this body is not computable right now. @@ -445,6 +448,7 @@ impl<'tcx> Body<'tcx> { var_debug_info, span, required_consts: Vec::new(), + required_fns: Vec::new(), is_polymorphic: false, injection_phase: None, tainted_by_errors, @@ -473,6 +477,7 @@ impl<'tcx> Body<'tcx> { spread_arg: None, span: DUMMY_SP, required_consts: Vec::new(), + required_fns: Vec::new(), var_debug_info: Vec::new(), is_polymorphic: false, injection_phase: None, diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index c2bff9084c67e..3132083d0e9a5 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -56,6 +56,7 @@ pub(super) fn build_custom_mir<'tcx>( var_debug_info: Vec::new(), span, required_consts: Vec::new(), + required_fns: Vec::new(), is_polymorphic: false, tainted_by_errors: None, injection_phase: None, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index cd9b98e4f32cd..6f6921fc0bd3f 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -344,11 +344,14 @@ fn mir_promoted( } let mut required_consts = Vec::new(); - let mut required_consts_visitor = RequiredConstsVisitor::new(&mut required_consts); + let mut required_fns = Vec::new(); + let mut required_consts_visitor = + RequiredConstsVisitor::new(tcx, &body, &mut required_consts, &mut required_fns); for (bb, bb_data) in traversal::reverse_postorder(&body) { required_consts_visitor.visit_basic_block_data(bb, bb_data); } body.required_consts = required_consts; + body.required_fns = required_fns; // What we need to run borrowck etc. let promote_pass = promote_consts::PromoteTemps::default(); diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs index abde6a47e83aa..cd215d7659548 100644 --- a/compiler/rustc_mir_transform/src/required_consts.rs +++ b/compiler/rustc_mir_transform/src/required_consts.rs @@ -1,14 +1,23 @@ +use rustc_hir::LangItem; use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{Const, ConstOperand, Location}; -use rustc_middle::ty::ConstKind; +use rustc_middle::mir::{self, Const, ConstOperand, Location}; +use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, TyCtxt}; pub struct RequiredConstsVisitor<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + body: &'a mir::Body<'tcx>, required_consts: &'a mut Vec>, + required_fns: &'a mut Vec>, } impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> { - pub fn new(required_consts: &'a mut Vec>) -> Self { - RequiredConstsVisitor { required_consts } + pub fn new( + tcx: TyCtxt<'tcx>, + body: &'a mir::Body<'tcx>, + required_consts: &'a mut Vec>, + required_fns: &'a mut Vec>, + ) -> Self { + RequiredConstsVisitor { tcx, body, required_consts, required_fns } } } @@ -21,7 +30,34 @@ impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { _ => bug!("only ConstKind::Param/Value should be encountered here, got {:#?}", c), }, Const::Unevaluated(..) => self.required_consts.push(*constant), - Const::Val(..) => {} + Const::Val(_val, ty) => { + // This is how function items get referenced: via zero-sized constants of `FnDef` type + if let ty::FnDef(def_id, args) = ty.kind() { + debug!("adding to required_fns: {def_id:?}"); + // FIXME maybe we shouldn't use `Instance`? We can't use `Instance::new`, it is + // for codegen. But `Instance` feels like the right representation... Check what + // the regular collector does. + self.required_fns.push(Instance { def: InstanceDef::Item(*def_id), args }); + } + } + } + } + + fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) { + self.super_terminator(terminator, location); + + match terminator.kind { + // We don't need to handle `Call` as we already handled all function type operands in + // `visit_constant`. But we do need to handle `Drop`. + mir::TerminatorKind::Drop { place, .. } => { + let ty = place.ty(self.body, self.tcx).ty; + let def_id = self.tcx.require_lang_item(LangItem::DropInPlace, None); + let args = self.tcx.mk_args(&[ty.into()]); + // FIXME: same as above (we cannot use `Instance::resolve_drop_in_place` as this is + // still generic). + self.required_fns.push(Instance { def: InstanceDef::Item(def_id), args }); + } + _ => {} } } } From 937b3a42a2acc1723a52615b001af1bf80b656ab Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2024 11:19:55 +0100 Subject: [PATCH 02/11] introduce new type for required items of a MIR body --- compiler/rustc_middle/src/mir/mod.rs | 17 +++++++++---- .../rustc_mir_build/src/build/custom/mod.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 6 ++--- .../src/required_consts.rs | 24 +++++++------------ 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index f5e70b683ad35..9c141e3f7033a 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -9,7 +9,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{pretty_print_const, with_no_trimmed_paths}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::visit::TypeVisitableExt; -use crate::ty::{self, Instance, List, Ty, TyCtxt}; +use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, UserTypeAnnotationIndex}; use crate::ty::{GenericArg, GenericArgsRef}; @@ -310,6 +310,13 @@ impl<'tcx> CoroutineInfo<'tcx> { } } +/// Some item that needs to monomorphize successfully for a MIR body to be considered well-formed. +#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] +pub enum RequiredItem<'tcx> { + Fn(DefId, GenericArgsRef<'tcx>), + Drop(Ty<'tcx>), +} + /// The lowered representation of a single function. #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct Body<'tcx> { @@ -375,8 +382,8 @@ pub struct Body<'tcx> { /// We hold in this field all the constants we are not able to evaluate yet. pub required_consts: Vec>, - /// Functions that need to monomorphize successfully for this MIR to be well-formed. - pub required_fns: Vec>, + /// Further items that need to monomorphize successfully for this MIR to be well-formed. + pub required_items: Vec>, /// Does this body use generic parameters. This is used for the `ConstEvaluatable` check. /// @@ -448,7 +455,7 @@ impl<'tcx> Body<'tcx> { var_debug_info, span, required_consts: Vec::new(), - required_fns: Vec::new(), + required_items: Vec::new(), is_polymorphic: false, injection_phase: None, tainted_by_errors, @@ -477,7 +484,7 @@ impl<'tcx> Body<'tcx> { spread_arg: None, span: DUMMY_SP, required_consts: Vec::new(), - required_fns: Vec::new(), + required_items: Vec::new(), var_debug_info: Vec::new(), is_polymorphic: false, injection_phase: None, diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index 3132083d0e9a5..0ad6b22ee5405 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -56,7 +56,7 @@ pub(super) fn build_custom_mir<'tcx>( var_debug_info: Vec::new(), span, required_consts: Vec::new(), - required_fns: Vec::new(), + required_items: Vec::new(), is_polymorphic: false, tainted_by_errors: None, injection_phase: None, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 6f6921fc0bd3f..b76ee39b1ba97 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -344,14 +344,14 @@ fn mir_promoted( } let mut required_consts = Vec::new(); - let mut required_fns = Vec::new(); + let mut required_items = Vec::new(); let mut required_consts_visitor = - RequiredConstsVisitor::new(tcx, &body, &mut required_consts, &mut required_fns); + RequiredConstsVisitor::new(tcx, &body, &mut required_consts, &mut required_items); for (bb, bb_data) in traversal::reverse_postorder(&body) { required_consts_visitor.visit_basic_block_data(bb, bb_data); } body.required_consts = required_consts; - body.required_fns = required_fns; + body.required_items = required_items; // What we need to run borrowck etc. let promote_pass = promote_consts::PromoteTemps::default(); diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs index cd215d7659548..52dc9353fdc8b 100644 --- a/compiler/rustc_mir_transform/src/required_consts.rs +++ b/compiler/rustc_mir_transform/src/required_consts.rs @@ -1,13 +1,12 @@ -use rustc_hir::LangItem; use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{self, Const, ConstOperand, Location}; -use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, TyCtxt}; +use rustc_middle::mir::{self, Const, ConstOperand, Location, RequiredItem}; +use rustc_middle::ty::{self, ConstKind, TyCtxt}; pub struct RequiredConstsVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, required_consts: &'a mut Vec>, - required_fns: &'a mut Vec>, + required_items: &'a mut Vec>, } impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> { @@ -15,9 +14,9 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, required_consts: &'a mut Vec>, - required_fns: &'a mut Vec>, + required_items: &'a mut Vec>, ) -> Self { - RequiredConstsVisitor { tcx, body, required_consts, required_fns } + RequiredConstsVisitor { tcx, body, required_consts, required_items } } } @@ -33,11 +32,8 @@ impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { Const::Val(_val, ty) => { // This is how function items get referenced: via zero-sized constants of `FnDef` type if let ty::FnDef(def_id, args) = ty.kind() { - debug!("adding to required_fns: {def_id:?}"); - // FIXME maybe we shouldn't use `Instance`? We can't use `Instance::new`, it is - // for codegen. But `Instance` feels like the right representation... Check what - // the regular collector does. - self.required_fns.push(Instance { def: InstanceDef::Item(*def_id), args }); + debug!("adding to required_items: {def_id:?}"); + self.required_items.push(RequiredItem::Fn(*def_id, args)); } } } @@ -51,11 +47,7 @@ impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { // `visit_constant`. But we do need to handle `Drop`. mir::TerminatorKind::Drop { place, .. } => { let ty = place.ty(self.body, self.tcx).ty; - let def_id = self.tcx.require_lang_item(LangItem::DropInPlace, None); - let args = self.tcx.mk_args(&[ty.into()]); - // FIXME: same as above (we cannot use `Instance::resolve_drop_in_place` as this is - // still generic). - self.required_fns.push(Instance { def: InstanceDef::Item(def_id), args }); + self.required_items.push(RequiredItem::Drop(ty)); } _ => {} } From 3c7d61a2b66eb045440bf2a586dd672bec3effde Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2024 11:33:43 +0100 Subject: [PATCH 03/11] collect and extend our tests for monomorphization-related const errors --- .../consts/const-eval/erroneous-const.stderr | 15 ---------- .../consts/const-eval/erroneous-const2.stderr | 15 ---------- .../dead-code-in-called-fn.no-opt.stderr | 17 +++++++++++ .../dead-code-in-called-fn.opt.stderr | 17 +++++++++++ .../dead-code-in-called-fn.rs} | 17 ++++++----- ...dead-code-in-const-called-fn.no-opt.stderr | 17 +++++++++++ .../dead-code-in-const-called-fn.opt.stderr | 17 +++++++++++ .../dead-code-in-const-called-fn.rs} | 11 +++++--- .../dead-code-in-dead-fn.no-opt.stderr | 17 +++++++++++ .../dead-code-in-dead-fn.opt.stderr} | 8 +++--- .../monomorphization/dead-code-in-dead-fn.rs | 28 +++++++++++++++++++ .../dead-code-in-static.no-opt.stderr | 17 +++++++++++ .../dead-code-in-static.opt.stderr | 17 +++++++++++ .../dead-code-in-static.rs} | 10 ++++--- 14 files changed, 174 insertions(+), 49 deletions(-) delete mode 100644 tests/ui/consts/const-eval/erroneous-const.stderr delete mode 100644 tests/ui/consts/const-eval/erroneous-const2.stderr create mode 100644 tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr create mode 100644 tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr rename tests/ui/consts/{const-eval/unused-broken-const-late.rs => monomorphization/dead-code-in-called-fn.rs} (62%) create mode 100644 tests/ui/consts/monomorphization/dead-code-in-const-called-fn.no-opt.stderr create mode 100644 tests/ui/consts/monomorphization/dead-code-in-const-called-fn.opt.stderr rename tests/ui/consts/{const-eval/erroneous-const.rs => monomorphization/dead-code-in-const-called-fn.rs} (62%) create mode 100644 tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr rename tests/ui/consts/{const-eval/unused-broken-const-late.stderr => monomorphization/dead-code-in-dead-fn.opt.stderr} (53%) create mode 100644 tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs create mode 100644 tests/ui/consts/monomorphization/dead-code-in-static.no-opt.stderr create mode 100644 tests/ui/consts/monomorphization/dead-code-in-static.opt.stderr rename tests/ui/consts/{const-eval/erroneous-const2.rs => monomorphization/dead-code-in-static.rs} (61%) diff --git a/tests/ui/consts/const-eval/erroneous-const.stderr b/tests/ui/consts/const-eval/erroneous-const.stderr deleted file mode 100644 index bd25e96c2cf13..0000000000000 --- a/tests/ui/consts/const-eval/erroneous-const.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0080]: evaluation of `PrintName::::VOID` failed - --> $DIR/erroneous-const.rs:6:22 - | -LL | const VOID: () = [()][2]; - | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 - -note: erroneous constant encountered - --> $DIR/erroneous-const.rs:13:13 - | -LL | PrintName::::VOID; - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/erroneous-const2.stderr b/tests/ui/consts/const-eval/erroneous-const2.stderr deleted file mode 100644 index 6a5839e3dfb41..0000000000000 --- a/tests/ui/consts/const-eval/erroneous-const2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0080]: evaluation of `PrintName::::VOID` failed - --> $DIR/erroneous-const2.rs:6:22 - | -LL | const VOID: () = [()][2]; - | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 - -note: erroneous constant encountered - --> $DIR/erroneous-const2.rs:13:9 - | -LL | PrintName::::VOID; - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr new file mode 100644 index 0000000000000..b69d10d322e86 --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-called-fn.rs:9:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-called-fn.rs:9:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn called::` + --> $DIR/dead-code-in-called-fn.rs:22:5 + | +LL | called::(); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr new file mode 100644 index 0000000000000..b69d10d322e86 --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-called-fn.rs:9:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-called-fn.rs:9:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn called::` + --> $DIR/dead-code-in-called-fn.rs:22:5 + | +LL | called::(); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/unused-broken-const-late.rs b/tests/ui/consts/monomorphization/dead-code-in-called-fn.rs similarity index 62% rename from tests/ui/consts/const-eval/unused-broken-const-late.rs rename to tests/ui/consts/monomorphization/dead-code-in-called-fn.rs index c4916061f9e5a..cc7bafa7adb85 100644 --- a/tests/ui/consts/const-eval/unused-broken-const-late.rs +++ b/tests/ui/consts/monomorphization/dead-code-in-called-fn.rs @@ -1,20 +1,23 @@ +//@revisions: opt no-opt //@ build-fail -//@ compile-flags: -O +//@[opt] compile-flags: -O //! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is //! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) -struct PrintName(T); -impl PrintName { - const VOID: () = panic!(); //~ERROR evaluation of `PrintName::::VOID` failed +struct Fail(T); +impl Fail { + const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed } -fn no_codegen() { +#[inline(never)] +fn called() { // Any function that is called is guaranteed to have all consts that syntactically // appear in its body evaluated, even if they only appear in dead code. if false { - let _ = PrintName::::VOID; + let _ = Fail::::C; } } + pub fn main() { - no_codegen::(); + called::(); } diff --git a/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.no-opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.no-opt.stderr new file mode 100644 index 0000000000000..6448aef3ef501 --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.no-opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-const-called-fn.rs:8:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-const-called-fn.rs:8:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> $DIR/dead-code-in-const-called-fn.rs:16:9 + | +LL | Fail::::C; + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.opt.stderr new file mode 100644 index 0000000000000..6448aef3ef501 --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-const-called-fn.rs:8:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-const-called-fn.rs:8:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> $DIR/dead-code-in-const-called-fn.rs:16:9 + | +LL | Fail::::C; + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/erroneous-const.rs b/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.rs similarity index 62% rename from tests/ui/consts/const-eval/erroneous-const.rs rename to tests/ui/consts/monomorphization/dead-code-in-const-called-fn.rs index 74d44c5259a3e..9a5737831cdf0 100644 --- a/tests/ui/consts/const-eval/erroneous-const.rs +++ b/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.rs @@ -1,16 +1,19 @@ +//@revisions: opt no-opt +//@[opt] compile-flags: -O //! Make sure we error on erroneous consts even if they are unused. #![allow(unconditional_panic)] -struct PrintName(T); -impl PrintName { - const VOID: () = [()][2]; //~ERROR evaluation of `PrintName::::VOID` failed +struct Fail(T); +impl Fail { + const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed } +#[inline(never)] const fn no_codegen() { if false { // This bad constant is only used in dead code in a no-codegen function... and yet we still // must make sure that the build fails. - PrintName::::VOID; //~ constant + Fail::::C; //~ constant } } diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr new file mode 100644 index 0000000000000..884fcb4e415ca --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-dead-fn.rs:9:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-fn.rs:9:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn not_called::` + --> $DIR/dead-code-in-dead-fn.rs:22:9 + | +LL | not_called::(); + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/unused-broken-const-late.stderr b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr similarity index 53% rename from tests/ui/consts/const-eval/unused-broken-const-late.stderr rename to tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr index c2cf2f3813c5e..302bcae18331c 100644 --- a/tests/ui/consts/const-eval/unused-broken-const-late.stderr +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr @@ -1,8 +1,8 @@ -error[E0080]: evaluation of `PrintName::::VOID` failed - --> $DIR/unused-broken-const-late.rs:8:22 +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-dead-fn.rs:9:19 | -LL | const VOID: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unused-broken-const-late.rs:8:22 +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-fn.rs:9:19 | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs new file mode 100644 index 0000000000000..9fa335d4038f1 --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs @@ -0,0 +1,28 @@ +//@revisions: opt no-opt +//@ build-fail +//@[opt] compile-flags: -O +//! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is +//! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) + +struct Fail(T); +impl Fail { + const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed +} + +// This function is not actually called, but it is mentioned in a function that is called. +// Make sure we still find this error. +#[inline(never)] +fn not_called() { + let _ = Fail::::C; +} + +#[inline(never)] +fn called() { + if false { + not_called::(); + } +} + +pub fn main() { + called::(); +} diff --git a/tests/ui/consts/monomorphization/dead-code-in-static.no-opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-static.no-opt.stderr new file mode 100644 index 0000000000000..abd1456d5549f --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-static.no-opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-static.rs:8:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-static.rs:8:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> $DIR/dead-code-in-static.rs:15:9 + | +LL | Fail::::C; + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/monomorphization/dead-code-in-static.opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-static.opt.stderr new file mode 100644 index 0000000000000..abd1456d5549f --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-static.opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-static.rs:8:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-static.rs:8:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> $DIR/dead-code-in-static.rs:15:9 + | +LL | Fail::::C; + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/erroneous-const2.rs b/tests/ui/consts/monomorphization/dead-code-in-static.rs similarity index 61% rename from tests/ui/consts/const-eval/erroneous-const2.rs rename to tests/ui/consts/monomorphization/dead-code-in-static.rs index 61f2955f2d822..e8c69e7d74ea4 100644 --- a/tests/ui/consts/const-eval/erroneous-const2.rs +++ b/tests/ui/consts/monomorphization/dead-code-in-static.rs @@ -1,16 +1,18 @@ +//@revisions: opt no-opt +//@[opt] compile-flags: -O //! Make sure we error on erroneous consts even if they are unused. #![allow(unconditional_panic)] -struct PrintName(T); -impl PrintName { - const VOID: () = [()][2]; //~ERROR evaluation of `PrintName::::VOID` failed +struct Fail(T); +impl Fail { + const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed } pub static FOO: () = { if false { // This bad constant is only used in dead code in a static initializer... and yet we still // must make sure that the build fails. - PrintName::::VOID; //~ constant + Fail::::C; //~ constant } }; From 39a1d18ced86ef791391c048c7fe2e77201437f8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2024 11:56:00 +0100 Subject: [PATCH 04/11] monormophize required_itms --- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 32 ++++++++++++++++++- .../dead-code-in-called-fn.no-opt.stderr | 4 --- .../dead-code-in-called-fn.opt.stderr | 4 --- .../dead-code-in-dead-fn.no-opt.stderr | 4 --- .../dead-code-in-dead-fn.opt.stderr | 2 ++ ...st_monomorphization_error_backtrace.stderr | 8 ----- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9c141e3f7033a..a234a9d400226 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -311,7 +311,7 @@ impl<'tcx> CoroutineInfo<'tcx> { } /// Some item that needs to monomorphize successfully for a MIR body to be considered well-formed. -#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] +#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub enum RequiredItem<'tcx> { Fn(DefId, GenericArgsRef<'tcx>), Drop(Ty<'tcx>), diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 32f823a5ac68f..84d170bb4c8b8 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -345,7 +345,7 @@ fn collect_items_rec<'tcx>( return; } - let mut used_items = Vec::new(); + let mut used_items = MonoItems::new(); let recursion_depth_reset; // Post-monomorphization errors MVP @@ -734,6 +734,17 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { } impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { + fn visit_body(&mut self, body: &mir::Body<'tcx>) { + for item in &body.required_items { + // All these also need monomorphization to ensure that if that leads to error, we find + // those errors. + let item = self.monomorphize(*item); + visit_required_item(self.tcx, item, self.output); + } + + self.super_body(body); + } + fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) { debug!("visiting rvalue {:?}", *rvalue); @@ -915,6 +926,25 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { } } +fn visit_required_item<'tcx>( + tcx: TyCtxt<'tcx>, + item: mir::RequiredItem<'tcx>, + output: &mut MonoItems<'tcx>, +) { + let instance = match item { + mir::RequiredItem::Fn(def_id, args) => { + Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args) + } + mir::RequiredItem::Drop(ty) => Instance::resolve_drop_in_place(tcx, ty), + }; + // We pretend this is a direct call, just to make sure this is visited at all. + // "indirect" would mean we also generate some shims, but we don't care about the + // generated code, just about the side-effect of code generation causing errors, so we + // can skip the shims. + // FIXME: track the span so that we can show it here. + visit_instance_use(tcx, instance, /*is_direct_call*/ true, DUMMY_SP, output); +} + fn visit_drop_use<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, diff --git a/tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr index b69d10d322e86..6dbe2c8eeee35 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr +++ b/tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr @@ -7,10 +7,6 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn called::` - --> $DIR/dead-code-in-called-fn.rs:22:5 - | -LL | called::(); - | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr index b69d10d322e86..6dbe2c8eeee35 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr +++ b/tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr @@ -7,10 +7,6 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn called::` - --> $DIR/dead-code-in-called-fn.rs:22:5 - | -LL | called::(); - | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr index 884fcb4e415ca..4c4c5f85f697e 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr @@ -7,10 +7,6 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn not_called::` - --> $DIR/dead-code-in-dead-fn.rs:22:9 - | -LL | not_called::(); - | ^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr index 302bcae18331c..4c4c5f85f697e 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr @@ -6,6 +6,8 @@ LL | const C: () = panic!(); | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) +note: the above error was encountered while instantiating `fn not_called::` + error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/generics/post_monomorphization_error_backtrace.stderr b/tests/ui/generics/post_monomorphization_error_backtrace.stderr index 0d707d83d2660..ed44c07630d14 100644 --- a/tests/ui/generics/post_monomorphization_error_backtrace.stderr +++ b/tests/ui/generics/post_monomorphization_error_backtrace.stderr @@ -7,10 +7,6 @@ LL | const V: () = assert!(std::mem::size_of::() == 0); = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn assert_zst::` - --> $DIR/post_monomorphization_error_backtrace.rs:18:5 - | -LL | assert_zst::() - | ^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of `assert_zst::F::::V` failed --> $DIR/post_monomorphization_error_backtrace.rs:6:23 @@ -21,10 +17,6 @@ LL | const V: () = assert!(std::mem::size_of::() == 0); = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn assert_zst::` - --> $DIR/post_monomorphization_error_backtrace.rs:18:5 - | -LL | assert_zst::() - | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors From e7f4399c86a5dd5fe0c8b535d94b19ada706bc46 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2024 12:02:50 +0100 Subject: [PATCH 05/11] more extensive dead cases for more kinds of dead code --- .../dead-code-in-dead-drop.no-opt.stderr | 14 ++++++++ .../dead-code-in-dead-drop.opt.stderr | 14 ++++++++ .../dead-code-in-dead-drop.rs | 30 ++++++++++++++++ .../monomorphization/dead-code-in-dead-fn.rs | 4 +-- .../dead-code-in-dead-vtable.no-opt.stderr | 17 ++++++++++ .../dead-code-in-dead-vtable.rs | 34 +++++++++++++++++++ 6 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 tests/ui/consts/monomorphization/dead-code-in-dead-drop.no-opt.stderr create mode 100644 tests/ui/consts/monomorphization/dead-code-in-dead-drop.opt.stderr create mode 100644 tests/ui/consts/monomorphization/dead-code-in-dead-drop.rs create mode 100644 tests/ui/consts/monomorphization/dead-code-in-dead-vtable.no-opt.stderr create mode 100644 tests/ui/consts/monomorphization/dead-code-in-dead-vtable.rs diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-drop.no-opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-dead-drop.no-opt.stderr new file mode 100644 index 0000000000000..e3ef78842f77c --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-drop.no-opt.stderr @@ -0,0 +1,14 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-dead-drop.rs:9:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-drop.rs:9:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn as std::ops::Drop>::drop` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-drop.opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-dead-drop.opt.stderr new file mode 100644 index 0000000000000..e3ef78842f77c --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-drop.opt.stderr @@ -0,0 +1,14 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-dead-drop.rs:9:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-drop.rs:9:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn as std::ops::Drop>::drop` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-drop.rs b/tests/ui/consts/monomorphization/dead-code-in-dead-drop.rs new file mode 100644 index 0000000000000..fc1052858b64c --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-drop.rs @@ -0,0 +1,30 @@ +//@revisions: opt no-opt +//@ build-fail +//@[opt] compile-flags: -O +//! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is +//! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) + +struct Fail(T); +impl Fail { + const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed +} + +// This function is not actually called, but is mentioned implicitly as destructor in dead code in a +// function that is called. Make sure we still find this error. +impl Drop for Fail { + fn drop(&mut self) { + let _ = Fail::::C; + } +} + +#[inline(never)] +fn called(x: T) { + if false { + let v = Fail(x); + drop(v); + } +} + +pub fn main() { + called::(0); +} diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs index 9fa335d4038f1..79cb47f4b75ee 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs @@ -9,8 +9,8 @@ impl Fail { const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed } -// This function is not actually called, but it is mentioned in a function that is called. -// Make sure we still find this error. +// This function is not actually called, but it is mentioned in dead code in a function that is +// called. Make sure we still find this error. #[inline(never)] fn not_called() { let _ = Fail::::C; diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.no-opt.stderr b/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.no-opt.stderr new file mode 100644 index 0000000000000..eb8dd41cd567b --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.no-opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::::C` failed + --> $DIR/dead-code-in-dead-vtable.rs:9:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-vtable.rs:9:19 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn as MyTrait>::not_called` + --> $DIR/dead-code-in-dead-vtable.rs:28:40 + | +LL | let gen_vtable: &dyn MyTrait = &v; + | ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.rs b/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.rs new file mode 100644 index 0000000000000..70a9444125cb5 --- /dev/null +++ b/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.rs @@ -0,0 +1,34 @@ +//@revisions: opt no-opt +//@ build-fail +//@[opt] compile-flags: -O +//! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is +//! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) + +struct Fail(T); +impl Fail { + const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed +} + +trait MyTrait { + fn not_called(&self); +} + +// This function is not actually called, but it is mentioned in a vtable in a function that is +// called. Make sure we still find this error. +impl MyTrait for Vec { + fn not_called(&self) { + let _ = Fail::::C; + } +} + +#[inline(never)] +fn called() { + if false { + let v: Vec = Vec::new(); + let gen_vtable: &dyn MyTrait = &v; + } +} + +pub fn main() { + called::(); +} From 70612b7b4373a67121be0c39a65490577a662790 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 12 Mar 2024 14:07:17 +0100 Subject: [PATCH 06/11] reorganize tests a bit --- .../dead-code-in-called-fn.no-opt.stderr | 0 .../dead-code-in-called-fn.opt.stderr | 0 .../dead-code-in-called-fn.rs | 1 + .../dead-code-in-const-called-fn.no-opt.stderr | 2 +- .../dead-code-in-const-called-fn.opt.stderr | 2 +- .../dead-code-in-const-called-fn.rs | 1 + .../dead-code-in-dead-drop.no-opt.stderr | 0 .../dead-code-in-dead-drop.opt.stderr | 0 .../dead-code-in-dead-drop.rs | 0 .../dead-code-in-dead-fn.no-opt.stderr | 0 .../dead-code-in-dead-fn.opt.stderr | 0 .../dead-code-in-dead-fn.rs | 6 +++++- .../dead-code-in-dead-vtable.no-opt.stderr | 4 ++-- .../dead-code-in-dead-vtable.rs | 8 ++++++-- .../dead-code-in-static.no-opt.stderr | 2 +- .../dead-code-in-static.opt.stderr | 2 +- .../dead-code-in-static.rs | 1 + 17 files changed, 20 insertions(+), 9 deletions(-) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-called-fn.no-opt.stderr (100%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-called-fn.opt.stderr (100%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-called-fn.rs (87%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-const-called-fn.no-opt.stderr (93%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-const-called-fn.opt.stderr (93%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-const-called-fn.rs (87%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-dead-drop.no-opt.stderr (100%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-dead-drop.opt.stderr (100%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-dead-drop.rs (100%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-dead-fn.no-opt.stderr (100%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-dead-fn.opt.stderr (100%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-dead-fn.rs (76%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-dead-vtable.no-opt.stderr (85%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-dead-vtable.rs (70%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-static.no-opt.stderr (94%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-static.opt.stderr (94%) rename tests/ui/consts/{monomorphization => required-consts}/dead-code-in-static.rs (84%) diff --git a/tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-called-fn.no-opt.stderr similarity index 100% rename from tests/ui/consts/monomorphization/dead-code-in-called-fn.no-opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-called-fn.no-opt.stderr diff --git a/tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr b/tests/ui/consts/required-consts/dead-code-in-called-fn.opt.stderr similarity index 100% rename from tests/ui/consts/monomorphization/dead-code-in-called-fn.opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-called-fn.opt.stderr diff --git a/tests/ui/consts/monomorphization/dead-code-in-called-fn.rs b/tests/ui/consts/required-consts/dead-code-in-called-fn.rs similarity index 87% rename from tests/ui/consts/monomorphization/dead-code-in-called-fn.rs rename to tests/ui/consts/required-consts/dead-code-in-called-fn.rs index cc7bafa7adb85..2dd58b9e71d75 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-called-fn.rs +++ b/tests/ui/consts/required-consts/dead-code-in-called-fn.rs @@ -13,6 +13,7 @@ impl Fail { fn called() { // Any function that is called is guaranteed to have all consts that syntactically // appear in its body evaluated, even if they only appear in dead code. + // This relies on mono-item collection checking `required_consts` in collected functions. if false { let _ = Fail::::C; } diff --git a/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-const-called-fn.no-opt.stderr similarity index 93% rename from tests/ui/consts/monomorphization/dead-code-in-const-called-fn.no-opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-const-called-fn.no-opt.stderr index 6448aef3ef501..feacf51cfca0e 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.no-opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-const-called-fn.no-opt.stderr @@ -7,7 +7,7 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> $DIR/dead-code-in-const-called-fn.rs:16:9 + --> $DIR/dead-code-in-const-called-fn.rs:17:9 | LL | Fail::::C; | ^^^^^^^^^^^^ diff --git a/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.opt.stderr b/tests/ui/consts/required-consts/dead-code-in-const-called-fn.opt.stderr similarity index 93% rename from tests/ui/consts/monomorphization/dead-code-in-const-called-fn.opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-const-called-fn.opt.stderr index 6448aef3ef501..feacf51cfca0e 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-const-called-fn.opt.stderr @@ -7,7 +7,7 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> $DIR/dead-code-in-const-called-fn.rs:16:9 + --> $DIR/dead-code-in-const-called-fn.rs:17:9 | LL | Fail::::C; | ^^^^^^^^^^^^ diff --git a/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.rs b/tests/ui/consts/required-consts/dead-code-in-const-called-fn.rs similarity index 87% rename from tests/ui/consts/monomorphization/dead-code-in-const-called-fn.rs rename to tests/ui/consts/required-consts/dead-code-in-const-called-fn.rs index 9a5737831cdf0..03af0da78a3e3 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-const-called-fn.rs +++ b/tests/ui/consts/required-consts/dead-code-in-const-called-fn.rs @@ -13,6 +13,7 @@ const fn no_codegen() { if false { // This bad constant is only used in dead code in a no-codegen function... and yet we still // must make sure that the build fails. + // This relies on const-eval evaluating all `required_consts` of `const fn`. Fail::::C; //~ constant } } diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-drop.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-drop.no-opt.stderr similarity index 100% rename from tests/ui/consts/monomorphization/dead-code-in-dead-drop.no-opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-dead-drop.no-opt.stderr diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-drop.opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-drop.opt.stderr similarity index 100% rename from tests/ui/consts/monomorphization/dead-code-in-dead-drop.opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-dead-drop.opt.stderr diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-drop.rs b/tests/ui/consts/required-consts/dead-code-in-dead-drop.rs similarity index 100% rename from tests/ui/consts/monomorphization/dead-code-in-dead-drop.rs rename to tests/ui/consts/required-consts/dead-code-in-dead-drop.rs diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-fn.no-opt.stderr similarity index 100% rename from tests/ui/consts/monomorphization/dead-code-in-dead-fn.no-opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-dead-fn.no-opt.stderr diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-fn.opt.stderr similarity index 100% rename from tests/ui/consts/monomorphization/dead-code-in-dead-fn.opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-dead-fn.opt.stderr diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs b/tests/ui/consts/required-consts/dead-code-in-dead-fn.rs similarity index 76% rename from tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs rename to tests/ui/consts/required-consts/dead-code-in-dead-fn.rs index 79cb47f4b75ee..826149ca2a81f 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-dead-fn.rs +++ b/tests/ui/consts/required-consts/dead-code-in-dead-fn.rs @@ -11,9 +11,13 @@ impl Fail { // This function is not actually called, but it is mentioned in dead code in a function that is // called. Make sure we still find this error. +// This relies on mono-item collection checking `required_consts` in functions that syntactically +// are called in collected functions (even inside dead code). #[inline(never)] fn not_called() { - let _ = Fail::::C; + if false { + let _ = Fail::::C; + } } #[inline(never)] diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-vtable.no-opt.stderr similarity index 85% rename from tests/ui/consts/monomorphization/dead-code-in-dead-vtable.no-opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-dead-vtable.no-opt.stderr index eb8dd41cd567b..b70d675459236 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.no-opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-dead-vtable.no-opt.stderr @@ -7,9 +7,9 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn as MyTrait>::not_called` - --> $DIR/dead-code-in-dead-vtable.rs:28:40 + --> $DIR/dead-code-in-dead-vtable.rs:30:40 | -LL | let gen_vtable: &dyn MyTrait = &v; +LL | let gen_vtable: &dyn MyTrait = &v; // vtable "appears" here | ^^ error: aborting due to 1 previous error diff --git a/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.rs b/tests/ui/consts/required-consts/dead-code-in-dead-vtable.rs similarity index 70% rename from tests/ui/consts/monomorphization/dead-code-in-dead-vtable.rs rename to tests/ui/consts/required-consts/dead-code-in-dead-vtable.rs index 70a9444125cb5..642e12d5bfaac 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-dead-vtable.rs +++ b/tests/ui/consts/required-consts/dead-code-in-dead-vtable.rs @@ -15,9 +15,13 @@ trait MyTrait { // This function is not actually called, but it is mentioned in a vtable in a function that is // called. Make sure we still find this error. +// This relies on mono-item collection checking `required_consts` in functions that are referenced +// in vtables that syntactically appear in collected functions (even inside dead code). impl MyTrait for Vec { fn not_called(&self) { - let _ = Fail::::C; + if false { + let _ = Fail::::C; + } } } @@ -25,7 +29,7 @@ impl MyTrait for Vec { fn called() { if false { let v: Vec = Vec::new(); - let gen_vtable: &dyn MyTrait = &v; + let gen_vtable: &dyn MyTrait = &v; // vtable "appears" here } } diff --git a/tests/ui/consts/monomorphization/dead-code-in-static.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-static.no-opt.stderr similarity index 94% rename from tests/ui/consts/monomorphization/dead-code-in-static.no-opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-static.no-opt.stderr index abd1456d5549f..b64e2fc45f430 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-static.no-opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-static.no-opt.stderr @@ -7,7 +7,7 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> $DIR/dead-code-in-static.rs:15:9 + --> $DIR/dead-code-in-static.rs:16:9 | LL | Fail::::C; | ^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/monomorphization/dead-code-in-static.opt.stderr b/tests/ui/consts/required-consts/dead-code-in-static.opt.stderr similarity index 94% rename from tests/ui/consts/monomorphization/dead-code-in-static.opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-static.opt.stderr index abd1456d5549f..b64e2fc45f430 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-static.opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-static.opt.stderr @@ -7,7 +7,7 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> $DIR/dead-code-in-static.rs:15:9 + --> $DIR/dead-code-in-static.rs:16:9 | LL | Fail::::C; | ^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/monomorphization/dead-code-in-static.rs b/tests/ui/consts/required-consts/dead-code-in-static.rs similarity index 84% rename from tests/ui/consts/monomorphization/dead-code-in-static.rs rename to tests/ui/consts/required-consts/dead-code-in-static.rs index e8c69e7d74ea4..b1da8153e944b 100644 --- a/tests/ui/consts/monomorphization/dead-code-in-static.rs +++ b/tests/ui/consts/required-consts/dead-code-in-static.rs @@ -12,6 +12,7 @@ pub static FOO: () = { if false { // This bad constant is only used in dead code in a static initializer... and yet we still // must make sure that the build fails. + // This relies on const-eval evaluating all `required_consts` of the `static` MIR body. Fail::::C; //~ constant } }; From 2f88ecd7b8c18e75b682b87743aa62da899bed71 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Mar 2024 17:18:34 +0100 Subject: [PATCH 07/11] inliner: absorb callees required_items --- compiler/rustc_middle/src/mir/mod.rs | 3 ++- compiler/rustc_mir_transform/src/inline.rs | 15 ++++++++++++++- compiler/rustc_monomorphize/src/collector.rs | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index a234a9d400226..02333f4575344 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -311,7 +311,8 @@ impl<'tcx> CoroutineInfo<'tcx> { } /// Some item that needs to monomorphize successfully for a MIR body to be considered well-formed. -#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] +#[derive(Copy, Clone, PartialEq, Debug, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeFoldable, TypeVisitable)] pub enum RequiredItem<'tcx> { Fn(DefId, GenericArgsRef<'tcx>), Drop(Ty<'tcx>), diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index f6a0945c22297..22911d1ac82c1 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -565,7 +565,8 @@ impl<'tcx> Inliner<'tcx> { mut callee_body: Body<'tcx>, ) { let terminator = caller_body[callsite.block].terminator.take().unwrap(); - let TerminatorKind::Call { args, destination, unwind, target, .. } = terminator.kind else { + let TerminatorKind::Call { func, args, destination, unwind, target, .. } = terminator.kind + else { bug!("unexpected terminator kind {:?}", terminator.kind); }; @@ -717,6 +718,18 @@ impl<'tcx> Inliner<'tcx> { Const::Val(..) | Const::Unevaluated(..) => true, }, )); + // Now that we incorporated the callee's `required_consts`, we can remove the callee from + // `required_items` -- but we have to take their `required_consts` in return. + let callee_item = { + // We need to reconstruct the `required_item` for the callee. + let func_ty = func.ty(caller_body, self.tcx); + match func_ty.kind() { + ty::FnDef(def_id, args) => RequiredItem::Fn(*def_id, args), + _ => bug!(), + } + }; + caller_body.required_items.retain(|item| *item != callee_item); + caller_body.required_items.extend(callee_body.required_items); } fn make_call_args( diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 84d170bb4c8b8..0e838f132a2dc 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -983,7 +983,7 @@ fn visit_instance_use<'tcx>( source: Span, output: &mut MonoItems<'tcx>, ) { - debug!("visit_item_use({:?}, is_direct_call={:?})", instance, is_direct_call); + debug!("visit_instance_use({:?}, is_direct_call={:?})", instance, is_direct_call); if !should_codegen_locally(tcx, &instance) { return; } From f2b88663af5fe2923ebf3da0a22143ecefe23084 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Mar 2024 17:27:38 +0100 Subject: [PATCH 08/11] required_items: skip Drop for now --- compiler/rustc_mir_transform/src/required_consts.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs index 52dc9353fdc8b..a888956b39a90 100644 --- a/compiler/rustc_mir_transform/src/required_consts.rs +++ b/compiler/rustc_mir_transform/src/required_consts.rs @@ -2,6 +2,7 @@ use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{self, Const, ConstOperand, Location, RequiredItem}; use rustc_middle::ty::{self, ConstKind, TyCtxt}; +#[allow(unused)] pub struct RequiredConstsVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, @@ -39,7 +40,7 @@ impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { } } - fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) { + /*fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) { self.super_terminator(terminator, location); match terminator.kind { @@ -51,5 +52,5 @@ impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { } _ => {} } - } + }*/ } From 003214eff3766e92e30f8f788b4e28f029aa2286 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Mar 2024 22:38:43 +0100 Subject: [PATCH 09/11] adjust tests to reality --- ....stderr => dead-code-in-dead-drop.noopt.stderr} | 4 ++-- .../dead-code-in-dead-drop.opt.stderr | 14 -------------- .../required-consts/dead-code-in-dead-drop.rs | 9 ++++++--- ...tderr => dead-code-in-dead-vtable.noopt.stderr} | 6 +++--- .../required-consts/dead-code-in-dead-vtable.rs | 9 ++++++--- 5 files changed, 17 insertions(+), 25 deletions(-) rename tests/ui/consts/required-consts/{dead-code-in-dead-drop.no-opt.stderr => dead-code-in-dead-drop.noopt.stderr} (85%) delete mode 100644 tests/ui/consts/required-consts/dead-code-in-dead-drop.opt.stderr rename tests/ui/consts/required-consts/{dead-code-in-dead-vtable.no-opt.stderr => dead-code-in-dead-vtable.noopt.stderr} (82%) diff --git a/tests/ui/consts/required-consts/dead-code-in-dead-drop.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-drop.noopt.stderr similarity index 85% rename from tests/ui/consts/required-consts/dead-code-in-dead-drop.no-opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-dead-drop.noopt.stderr index e3ef78842f77c..14fe323272f0d 100644 --- a/tests/ui/consts/required-consts/dead-code-in-dead-drop.no-opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-dead-drop.noopt.stderr @@ -1,8 +1,8 @@ error[E0080]: evaluation of `Fail::::C` failed - --> $DIR/dead-code-in-dead-drop.rs:9:19 + --> $DIR/dead-code-in-dead-drop.rs:12:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-drop.rs:9:19 + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-drop.rs:12:19 | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/dead-code-in-dead-drop.opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-drop.opt.stderr deleted file mode 100644 index e3ef78842f77c..0000000000000 --- a/tests/ui/consts/required-consts/dead-code-in-dead-drop.opt.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0080]: evaluation of `Fail::::C` failed - --> $DIR/dead-code-in-dead-drop.rs:9:19 - | -LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-drop.rs:9:19 - | - = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: the above error was encountered while instantiating `fn as std::ops::Drop>::drop` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/dead-code-in-dead-drop.rs b/tests/ui/consts/required-consts/dead-code-in-dead-drop.rs index fc1052858b64c..d6ec873e99df1 100644 --- a/tests/ui/consts/required-consts/dead-code-in-dead-drop.rs +++ b/tests/ui/consts/required-consts/dead-code-in-dead-drop.rs @@ -1,12 +1,15 @@ -//@revisions: opt no-opt -//@ build-fail +//@revisions: noopt opt +//@[noopt] build-fail //@[opt] compile-flags: -O +//FIXME: `opt` revision currently does not stop with an error due to +//. +//@[opt] build-pass //! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is //! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) struct Fail(T); impl Fail { - const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed + const C: () = panic!(); //[noopt]~ERROR evaluation of `Fail::::C` failed } // This function is not actually called, but is mentioned implicitly as destructor in dead code in a diff --git a/tests/ui/consts/required-consts/dead-code-in-dead-vtable.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-vtable.noopt.stderr similarity index 82% rename from tests/ui/consts/required-consts/dead-code-in-dead-vtable.no-opt.stderr rename to tests/ui/consts/required-consts/dead-code-in-dead-vtable.noopt.stderr index b70d675459236..ab60450049546 100644 --- a/tests/ui/consts/required-consts/dead-code-in-dead-vtable.no-opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-dead-vtable.noopt.stderr @@ -1,13 +1,13 @@ error[E0080]: evaluation of `Fail::::C` failed - --> $DIR/dead-code-in-dead-vtable.rs:9:19 + --> $DIR/dead-code-in-dead-vtable.rs:12:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-vtable.rs:9:19 + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/dead-code-in-dead-vtable.rs:12:19 | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn as MyTrait>::not_called` - --> $DIR/dead-code-in-dead-vtable.rs:30:40 + --> $DIR/dead-code-in-dead-vtable.rs:35:40 | LL | let gen_vtable: &dyn MyTrait = &v; // vtable "appears" here | ^^ diff --git a/tests/ui/consts/required-consts/dead-code-in-dead-vtable.rs b/tests/ui/consts/required-consts/dead-code-in-dead-vtable.rs index 642e12d5bfaac..f21a1cc1fc2fd 100644 --- a/tests/ui/consts/required-consts/dead-code-in-dead-vtable.rs +++ b/tests/ui/consts/required-consts/dead-code-in-dead-vtable.rs @@ -1,12 +1,15 @@ -//@revisions: opt no-opt -//@ build-fail +//@revisions: noopt opt +//@[noopt] build-fail //@[opt] compile-flags: -O +//FIXME: `opt` revision currently does not stop with an error due to +//. +//@[opt] build-pass //! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is //! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) struct Fail(T); impl Fail { - const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed + const C: () = panic!(); //[noopt]~ERROR evaluation of `Fail::::C` failed } trait MyTrait { From fd02409b064612d59898dc01ca0cc1b97248dd4e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Mar 2024 22:44:41 +0100 Subject: [PATCH 10/11] nicer errors --- compiler/rustc_monomorphize/src/collector.rs | 6 ++++-- .../required-consts/dead-code-in-called-fn.no-opt.stderr | 4 ++++ .../required-consts/dead-code-in-called-fn.opt.stderr | 4 ++++ .../required-consts/dead-code-in-dead-fn.no-opt.stderr | 4 ++++ .../generics/post_monomorphization_error_backtrace.stderr | 8 ++++++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 0e838f132a2dc..e62861d42edbf 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -735,14 +735,16 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { fn visit_body(&mut self, body: &mir::Body<'tcx>) { + self.super_body(body); + + // Go over `required_items` *after* body, so if an item appears in both we reach it the + // "normal" way, via the body. for item in &body.required_items { // All these also need monomorphization to ensure that if that leads to error, we find // those errors. let item = self.monomorphize(*item); visit_required_item(self.tcx, item, self.output); } - - self.super_body(body); } fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) { diff --git a/tests/ui/consts/required-consts/dead-code-in-called-fn.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-called-fn.no-opt.stderr index 6dbe2c8eeee35..9a072ac1df697 100644 --- a/tests/ui/consts/required-consts/dead-code-in-called-fn.no-opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-called-fn.no-opt.stderr @@ -7,6 +7,10 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn called::` + --> $DIR/dead-code-in-called-fn.rs:23:5 + | +LL | called::(); + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/consts/required-consts/dead-code-in-called-fn.opt.stderr b/tests/ui/consts/required-consts/dead-code-in-called-fn.opt.stderr index 6dbe2c8eeee35..9a072ac1df697 100644 --- a/tests/ui/consts/required-consts/dead-code-in-called-fn.opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-called-fn.opt.stderr @@ -7,6 +7,10 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn called::` + --> $DIR/dead-code-in-called-fn.rs:23:5 + | +LL | called::(); + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/consts/required-consts/dead-code-in-dead-fn.no-opt.stderr b/tests/ui/consts/required-consts/dead-code-in-dead-fn.no-opt.stderr index 4c4c5f85f697e..5c410fc7c4570 100644 --- a/tests/ui/consts/required-consts/dead-code-in-dead-fn.no-opt.stderr +++ b/tests/ui/consts/required-consts/dead-code-in-dead-fn.no-opt.stderr @@ -7,6 +7,10 @@ LL | const C: () = panic!(); = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn not_called::` + --> $DIR/dead-code-in-dead-fn.rs:26:9 + | +LL | not_called::(); + | ^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/generics/post_monomorphization_error_backtrace.stderr b/tests/ui/generics/post_monomorphization_error_backtrace.stderr index ed44c07630d14..0d707d83d2660 100644 --- a/tests/ui/generics/post_monomorphization_error_backtrace.stderr +++ b/tests/ui/generics/post_monomorphization_error_backtrace.stderr @@ -7,6 +7,10 @@ LL | const V: () = assert!(std::mem::size_of::() == 0); = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn assert_zst::` + --> $DIR/post_monomorphization_error_backtrace.rs:18:5 + | +LL | assert_zst::() + | ^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of `assert_zst::F::::V` failed --> $DIR/post_monomorphization_error_backtrace.rs:6:23 @@ -17,6 +21,10 @@ LL | const V: () = assert!(std::mem::size_of::() == 0); = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn assert_zst::` + --> $DIR/post_monomorphization_error_backtrace.rs:18:5 + | +LL | assert_zst::() + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors From 28e616d647cff6481f487a2f3282cccb0df9fd44 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 14 Mar 2024 08:59:51 +0100 Subject: [PATCH 11/11] bless coverage tests... no idea why they change --- tests/coverage/async.cov-map | 24 ++++++++++++------------ tests/coverage/closure.cov-map | 18 +++++++++++------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map index e06d1676358fb..67d149076837a 100644 --- a/tests/coverage/async.cov-map +++ b/tests/coverage/async.cov-map @@ -37,21 +37,21 @@ Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 17, 20) to (start + 0, 25) -Function name: async::e (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 01, 00, 14] +Function name: async::e +Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 19, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20) -Function name: async::e::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 14, 00, 19] +Function name: async::e::{closure#0} +Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 19, 20) to (start + 0, 25) +- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25) Function name: async::f Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 14] @@ -69,21 +69,21 @@ Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 21, 20) to (start + 0, 25) -Function name: async::foo (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 01, 00, 1e] +Function name: async::foo +Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 1e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 23, 1) to (start + 0, 30) +- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 30) -Function name: async::foo::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 1e, 00, 2d] +Function name: async::foo::{closure#0} +Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 1e, 00, 2d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 23, 30) to (start + 0, 45) +- Code(Counter(0)) at (prev + 23, 30) to (start + 0, 45) Function name: async::g Raw bytes (9): 0x[01, 01, 00, 01, 01, 19, 01, 00, 17] diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map index 9f0d33745bcb5..2f2b75b8f3dd6 100644 --- a/tests/coverage/closure.cov-map +++ b/tests/coverage/closure.cov-map @@ -33,16 +33,20 @@ Number of file 0 mappings: 24 - Code(Expression(1, Add)) at (prev + 1, 5) to (start + 3, 2) = (c1 + (c0 - c1)) -Function name: closure::main::{closure#0} (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 28, 05, 02, 14, 00, 02, 15, 02, 0a, 00, 02, 0a, 00, 0b, 00, 01, 09, 01, 06] +Function name: closure::main::{closure#0} +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 28, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 0a, 00, 0b, 07, 01, 09, 01, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 0 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Zero) at (prev + 40, 5) to (start + 2, 20) -- Code(Zero) at (prev + 2, 21) to (start + 2, 10) -- Code(Zero) at (prev + 2, 10) to (start + 0, 11) -- Code(Zero) at (prev + 1, 9) to (start + 1, 6) +- Code(Counter(0)) at (prev + 40, 5) to (start + 2, 20) +- Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10) +- Code(Expression(0, Sub)) at (prev + 2, 10) to (start + 0, 11) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 1, 9) to (start + 1, 6) + = (c1 + (c0 - c1)) Function name: closure::main::{closure#10} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, 9b, 01, 07, 00, 21]