@@ -35,6 +35,12 @@ use crate::errors;
35
35
type QualifResults < ' mir , ' tcx , Q > =
36
36
rustc_mir_dataflow:: ResultsCursor < ' mir , ' tcx , FlowSensitiveAnalysis < ' mir , ' mir , ' tcx , Q > > ;
37
37
38
+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
39
+ enum ConstConditionsHold {
40
+ Yes ,
41
+ No ,
42
+ }
43
+
38
44
#[ derive( Default ) ]
39
45
pub ( crate ) struct Qualifs < ' mir , ' tcx > {
40
46
has_mut_interior : Option < QualifResults < ' mir , ' tcx , HasMutInterior > > ,
@@ -376,15 +382,15 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
376
382
callee : DefId ,
377
383
callee_args : ty:: GenericArgsRef < ' tcx > ,
378
384
call_span : Span ,
379
- ) -> bool {
385
+ ) -> Option < ConstConditionsHold > {
380
386
let tcx = self . tcx ;
381
387
if !tcx. is_conditionally_const ( callee) {
382
- return false ;
388
+ return None ;
383
389
}
384
390
385
391
let const_conditions = tcx. const_conditions ( callee) . instantiate ( tcx, callee_args) ;
386
392
if const_conditions. is_empty ( ) {
387
- return false ;
393
+ return None ;
388
394
}
389
395
390
396
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> {
413
419
} ) ) ;
414
420
415
421
let errors = ocx. select_all_or_error ( ) ;
416
- if !errors. is_empty ( ) {
422
+ if errors. is_empty ( ) {
423
+ Some ( ConstConditionsHold :: Yes )
424
+ } else {
417
425
tcx. dcx ( )
418
426
. span_delayed_bug ( call_span, "this should have reported a ~const error in HIR" ) ;
427
+ Some ( ConstConditionsHold :: No )
419
428
}
420
-
421
- true
422
429
}
423
430
424
431
pub fn check_drop_terminator (
@@ -706,7 +713,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
706
713
trace ! ( "attempting to call a trait method" ) ;
707
714
let trait_is_const = tcx. is_const_trait ( trait_did) ;
708
715
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 ) {
710
720
// Trait calls are always conditionally-const.
711
721
self . check_op ( ops:: ConditionallyConstCall {
712
722
callee,
@@ -730,7 +740,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
730
740
}
731
741
732
742
// 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 ( ) {
734
744
self . check_op ( ops:: ConditionallyConstCall {
735
745
callee,
736
746
args : fn_args,
0 commit comments