Skip to content

Commit 2669f2a

Browse files
Do not consider traits that have unsatisfied const conditions to be conditionally const
1 parent 8c39ce5 commit 2669f2a

File tree

6 files changed

+34
-26
lines changed

6 files changed

+34
-26
lines changed

compiler/rustc_const_eval/src/check_consts/check.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ use crate::errors;
3535
type QualifResults<'mir, 'tcx, Q> =
3636
rustc_mir_dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'mir, 'mir, 'tcx, Q>>;
3737

38+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
39+
enum ConstConditionsHold {
40+
Yes,
41+
No,
42+
}
43+
3844
#[derive(Default)]
3945
pub(crate) struct Qualifs<'mir, 'tcx> {
4046
has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
@@ -376,15 +382,15 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
376382
callee: DefId,
377383
callee_args: ty::GenericArgsRef<'tcx>,
378384
call_span: Span,
379-
) -> bool {
385+
) -> Option<ConstConditionsHold> {
380386
let tcx = self.tcx;
381387
if !tcx.is_conditionally_const(callee) {
382-
return false;
388+
return None;
383389
}
384390

385391
let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args);
386392
if const_conditions.is_empty() {
387-
return false;
393+
return None;
388394
}
389395

390396
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> {
413419
}));
414420

415421
let errors = ocx.select_all_or_error();
416-
if !errors.is_empty() {
422+
if errors.is_empty() {
423+
Some(ConstConditionsHold::Yes)
424+
} else {
417425
tcx.dcx()
418426
.span_delayed_bug(call_span, "this should have reported a ~const error in HIR");
427+
Some(ConstConditionsHold::No)
419428
}
420-
421-
true
422429
}
423430

424431
pub fn check_drop_terminator(
@@ -706,7 +713,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
706713
trace!("attempting to call a trait method");
707714
let trait_is_const = tcx.is_const_trait(trait_did);
708715

709-
if trait_is_const {
716+
// Only consider a trait to be const if the const conditions hold.
717+
// Otherwise, it's really misleading to call something "conditionally"
718+
// const when it's very obviously not conditionally const.
719+
if trait_is_const && has_const_conditions == Some(ConstConditionsHold::Yes) {
710720
// Trait calls are always conditionally-const.
711721
self.check_op(ops::ConditionallyConstCall {
712722
callee,
@@ -730,7 +740,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
730740
}
731741

732742
// Even if we know the callee, ensure we can use conditionally-const calls.
733-
if has_const_conditions {
743+
if has_const_conditions.is_some() {
734744
self.check_op(ops::ConditionallyConstCall {
735745
callee,
736746
args: fn_args,

tests/ui/issues/issue-25901.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ struct A;
22
struct B;
33

44
static S: &'static B = &A;
5-
//~^ ERROR cannot perform conditionally-const deref coercion
5+
//~^ ERROR cannot perform non-const deref coercion
66

77
use std::ops::Deref;
88

tests/ui/issues/issue-25901.stderr

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0658]: cannot perform conditionally-const deref coercion on `A` in statics
1+
error[E0015]: cannot perform non-const deref coercion on `A` in statics
22
--> $DIR/issue-25901.rs:4:24
33
|
44
LL | static S: &'static B = &A;
@@ -10,11 +10,14 @@ note: deref defined here
1010
|
1111
LL | type Target = B;
1212
| ^^^^^^^^^^^
13+
note: impl defined here, but it is not `const`
14+
--> $DIR/issue-25901.rs:9:1
15+
|
16+
LL | impl Deref for A {
17+
| ^^^^^^^^^^^^^^^^
1318
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
14-
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
15-
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
16-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
19+
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
1720

1821
error: aborting due to 1 previous error
1922

20-
For more information about this error, try `rustc --explain E0658`.
23+
For more information about this error, try `rustc --explain E0015`.

tests/ui/self/arbitrary-self-from-method-substs-ice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ impl Foo {
1111
//~^ ERROR invalid generic `self` parameter type
1212
//~| ERROR destructor of `R` cannot be evaluated at compile-time
1313
self.0
14-
//~^ ERROR cannot perform conditionally-const deref coercion on `R` in constant functions
14+
//~^ ERROR cannot perform non-const deref coercion on `R` in constant functions
1515
}
1616
}
1717

tests/ui/self/arbitrary-self-from-method-substs-ice.stderr

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
error[E0658]: cannot perform conditionally-const deref coercion on `R` in constant functions
1+
error[E0015]: cannot perform non-const deref coercion on `R` in constant functions
22
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
33
|
44
LL | self.0
55
| ^^^^^^
66
|
77
= note: attempting to deref into `Foo`
88
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
9-
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
10-
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
11-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
129

1310
error[E0493]: destructor of `R` cannot be evaluated at compile-time
1411
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43
@@ -30,5 +27,5 @@ LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
3027

3128
error: aborting due to 3 previous errors
3229

33-
Some errors have detailed explanations: E0493, E0658, E0801.
34-
For more information about an error, try `rustc --explain E0493`.
30+
Some errors have detailed explanations: E0015, E0493, E0801.
31+
For more information about an error, try `rustc --explain E0015`.

tests/ui/traits/const-traits/cross-crate.stocknc.stderr

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
error[E0658]: cannot call conditionally-const method `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
1+
error[E0015]: cannot call non-const method `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
22
--> $DIR/cross-crate.rs:19:14
33
|
44
LL | NonConst.func();
55
| ^^^^^^
66
|
77
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
8-
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
9-
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
10-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
118

129
error[E0658]: cannot call conditionally-const method `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
1310
--> $DIR/cross-crate.rs:22:11
@@ -22,4 +19,5 @@ LL | Const.func();
2219

2320
error: aborting due to 2 previous errors
2421

25-
For more information about this error, try `rustc --explain E0658`.
22+
Some errors have detailed explanations: E0015, E0658.
23+
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)