diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 7a5f6c1726846..6c940124193c7 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -35,6 +35,12 @@ use crate::errors; type QualifResults<'mir, 'tcx, Q> = rustc_mir_dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'mir, 'mir, 'tcx, Q>>; +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum ConstConditionsHold { + Yes, + No, +} + #[derive(Default)] pub(crate) struct Qualifs<'mir, 'tcx> { has_mut_interior: Option>, @@ -376,15 +382,15 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { callee: DefId, callee_args: ty::GenericArgsRef<'tcx>, call_span: Span, - ) -> bool { + ) -> Option { let tcx = self.tcx; if !tcx.is_conditionally_const(callee) { - return false; + return None; } let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args); if const_conditions.is_empty() { - return false; + return None; } let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx)); @@ -413,12 +419,13 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { })); let errors = ocx.select_all_or_error(); - if !errors.is_empty() { + if errors.is_empty() { + Some(ConstConditionsHold::Yes) + } else { tcx.dcx() .span_delayed_bug(call_span, "this should have reported a ~const error in HIR"); + Some(ConstConditionsHold::No) } - - true } pub fn check_drop_terminator( @@ -706,7 +713,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { trace!("attempting to call a trait method"); let trait_is_const = tcx.is_const_trait(trait_did); - if trait_is_const { + // Only consider a trait to be const if the const conditions hold. + // Otherwise, it's really misleading to call something "conditionally" + // const when it's very obviously not conditionally const. + if trait_is_const && has_const_conditions == Some(ConstConditionsHold::Yes) { // Trait calls are always conditionally-const. self.check_op(ops::ConditionallyConstCall { callee, @@ -730,7 +740,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } // Even if we know the callee, ensure we can use conditionally-const calls. - if has_const_conditions { + if has_const_conditions.is_some() { self.check_op(ops::ConditionallyConstCall { callee, args: fn_args, diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs index bfcee1ac503a2..0ca34da95f55d 100644 --- a/tests/ui/issues/issue-25901.rs +++ b/tests/ui/issues/issue-25901.rs @@ -2,7 +2,7 @@ struct A; struct B; static S: &'static B = &A; -//~^ ERROR cannot perform conditionally-const deref coercion +//~^ ERROR cannot perform non-const deref coercion use std::ops::Deref; diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr index a954f38af8397..233b5bfee5075 100644 --- a/tests/ui/issues/issue-25901.stderr +++ b/tests/ui/issues/issue-25901.stderr @@ -1,4 +1,4 @@ -error[E0658]: cannot perform conditionally-const deref coercion on `A` in statics +error[E0015]: cannot perform non-const deref coercion on `A` in statics --> $DIR/issue-25901.rs:4:24 | LL | static S: &'static B = &A; @@ -10,11 +10,14 @@ note: deref defined here | LL | type Target = B; | ^^^^^^^^^^^ +note: impl defined here, but it is not `const` + --> $DIR/issue-25901.rs:9:1 + | +LL | impl Deref for A { + | ^^^^^^^^^^^^^^^^ = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: see issue #67792 for more information - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs index 2d6df816bb1ec..46e4afd8532e1 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs @@ -11,7 +11,7 @@ impl Foo { //~^ ERROR invalid generic `self` parameter type //~| ERROR destructor of `R` cannot be evaluated at compile-time self.0 - //~^ ERROR cannot perform conditionally-const deref coercion on `R` in constant functions + //~^ ERROR cannot perform non-const deref coercion on `R` in constant functions } } diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr index e6319d5a2c9c4..f217370b024b5 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr @@ -1,4 +1,4 @@ -error[E0658]: cannot perform conditionally-const deref coercion on `R` in constant functions +error[E0015]: cannot perform non-const deref coercion on `R` in constant functions --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9 | LL | self.0 @@ -6,9 +6,6 @@ LL | self.0 | = note: attempting to deref into `Foo` = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = note: see issue #67792 for more information - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0493]: destructor of `R` cannot be evaluated at compile-time --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43 @@ -30,5 +27,5 @@ LL | const fn get>(self: R) -> u32 { error: aborting due to 3 previous errors -Some errors have detailed explanations: E0493, E0658, E0801. -For more information about an error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0015, E0493, E0801. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr index 2358731c901f6..fb47bf9169fe2 100644 --- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr @@ -1,13 +1,10 @@ -error[E0658]: cannot call conditionally-const method `::func` in constant functions +error[E0015]: cannot call non-const method `::func` in constant functions --> $DIR/cross-crate.rs:19:14 | LL | NonConst.func(); | ^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = note: see issue #67792 for more information - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: cannot call conditionally-const method `::func` in constant functions --> $DIR/cross-crate.rs:22:11 @@ -22,4 +19,5 @@ LL | Const.func(); error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0015, E0658. +For more information about an error, try `rustc --explain E0015`.