diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index fe94181047fcd..8696291e05875 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1304,7 +1304,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { } } - if self.mode == Mode::Fn { + // No need to do anything in constants and statics, as everything is "constant" anyway + // so promotion would be useless. + if self.mode != Mode::Static && self.mode != Mode::Const { let constant_args = callee_def_id.and_then(|id| { args_required_const(self.tcx, id) }).unwrap_or_default(); diff --git a/src/test/ui/consts/const_arg_promotable2.rs b/src/test/ui/consts/const_arg_promotable2.rs new file mode 100644 index 0000000000000..3399e51ed4edb --- /dev/null +++ b/src/test/ui/consts/const_arg_promotable2.rs @@ -0,0 +1,18 @@ +// This test is a regression test for a bug where we only checked function calls in no-const +// functions for `rustc_args_required_const` arguments. This meant that even though `bar` needs its +// argument to be const, inside a const fn (callable at runtime), the value for it may come from a +// non-constant (namely an argument to the const fn). + +#![feature(rustc_attrs)] +const fn foo(a: i32) { + bar(a); //~ ERROR argument 1 is required to be a constant +} + +#[rustc_args_required_const(0)] +const fn bar(_: i32) {} + +fn main() { + // this function call will pass a runtime-value (number of program arguments) to `foo`, which + // will in turn forward it to `bar`, which expects a compile-time argument + foo(std::env::args().count() as i32); +} diff --git a/src/test/ui/consts/const_arg_promotable2.stderr b/src/test/ui/consts/const_arg_promotable2.stderr new file mode 100644 index 0000000000000..149d1ce89408d --- /dev/null +++ b/src/test/ui/consts/const_arg_promotable2.stderr @@ -0,0 +1,8 @@ +error: argument 1 is required to be a constant + --> $DIR/const_arg_promotable2.rs:8:5 + | +LL | bar(a); + | ^^^^^^ + +error: aborting due to previous error +