@@ -11,7 +11,6 @@ use rustc_hir::def_id::DefId;
11
11
use rustc_hir:: { self as hir, LangItem } ;
12
12
use rustc_index:: bit_set:: BitSet ;
13
13
use rustc_infer:: infer:: TyCtxtInferExt ;
14
- use rustc_infer:: traits:: ObligationCause ;
15
14
use rustc_middle:: mir:: visit:: Visitor ;
16
15
use rustc_middle:: mir:: * ;
17
16
use rustc_middle:: span_bug;
@@ -20,9 +19,11 @@ use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt, Typin
20
19
use rustc_mir_dataflow:: Analysis ;
21
20
use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
22
21
use rustc_mir_dataflow:: storage:: always_storage_live_locals;
23
- use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
22
+ use rustc_span:: { Span , Symbol , sym} ;
24
23
use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
25
- use rustc_trait_selection:: traits:: { self , ObligationCauseCode , ObligationCtxt } ;
24
+ use rustc_trait_selection:: traits:: {
25
+ Obligation , ObligationCause , ObligationCauseCode , ObligationCtxt ,
26
+ } ;
26
27
use tracing:: { debug, instrument, trace} ;
27
28
28
29
use super :: ops:: { self , NonConstOp , Status } ;
@@ -360,6 +361,60 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
360
361
// end of evaluation.
361
362
!is_transient
362
363
}
364
+
365
+ fn revalidate_conditional_constness (
366
+ & self ,
367
+ callee : DefId ,
368
+ callee_args : ty:: GenericArgsRef < ' tcx > ,
369
+ call_source : CallSource ,
370
+ call_span : Span ,
371
+ ) {
372
+ let tcx = self . tcx ;
373
+ if !tcx. is_conditionally_const ( callee) {
374
+ return ;
375
+ }
376
+
377
+ let infcx = tcx. infer_ctxt ( ) . build ( TypingMode :: from_param_env ( self . param_env ) ) ;
378
+ let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
379
+
380
+ let const_conditions = tcx. const_conditions ( callee) . instantiate ( tcx, callee_args) ;
381
+
382
+ let body_id = self . body . source . def_id ( ) . expect_local ( ) ;
383
+ let host_polarity = match self . const_kind ( ) {
384
+ hir:: ConstContext :: ConstFn => ty:: BoundConstness :: Maybe ,
385
+ hir:: ConstContext :: Static ( _) | hir:: ConstContext :: Const { .. } => {
386
+ ty:: BoundConstness :: Const
387
+ }
388
+ } ;
389
+ let const_conditions = ocx. normalize (
390
+ & ObligationCause :: misc ( call_span, body_id) ,
391
+ self . param_env ,
392
+ const_conditions,
393
+ ) ;
394
+ ocx. register_obligations ( const_conditions. into_iter ( ) . map ( |( trait_ref, span) | {
395
+ Obligation :: new (
396
+ tcx,
397
+ ObligationCause :: new (
398
+ call_span,
399
+ body_id,
400
+ ObligationCauseCode :: WhereClause ( callee, span) ,
401
+ ) ,
402
+ self . param_env ,
403
+ trait_ref. to_host_effect_clause ( tcx, host_polarity) ,
404
+ )
405
+ } ) ) ;
406
+
407
+ let errors = ocx. select_all_or_error ( ) ;
408
+ if !errors. is_empty ( ) {
409
+ // FIXME(effects): Soon this should be unconditionally delaying a bug.
410
+ if matches ! ( call_source, CallSource :: Normal ) && tcx. features ( ) . effects ( ) {
411
+ tcx. dcx ( )
412
+ . span_delayed_bug ( call_span, "this should have reported a ~const error in HIR" ) ;
413
+ } else {
414
+ infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ;
415
+ }
416
+ }
417
+ }
363
418
}
364
419
365
420
impl < ' tcx > Visitor < ' tcx > for Checker < ' _ , ' tcx > {
@@ -584,31 +639,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
584
639
}
585
640
} ;
586
641
587
- // Check that all trait bounds that are marked as `~const` can be satisfied.
588
- //
589
- // Typeck only does a "non-const" check since it operates on HIR and cannot distinguish
590
- // which path expressions are getting called on and which path expressions are only used
591
- // as function pointers. This is required for correctness.
592
- let infcx = tcx. infer_ctxt ( ) . build ( TypingMode :: from_param_env ( param_env) ) ;
593
- let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
594
-
595
- let predicates = tcx. predicates_of ( callee) . instantiate ( tcx, fn_args) ;
596
- let cause = ObligationCause :: new (
642
+ self . revalidate_conditional_constness (
643
+ callee,
644
+ fn_args,
645
+ call_source,
597
646
terminator. source_info . span ,
598
- self . body . source . def_id ( ) . expect_local ( ) ,
599
- ObligationCauseCode :: WhereClause ( callee, DUMMY_SP ) ,
600
647
) ;
601
- let normalized_predicates = ocx. normalize ( & cause, param_env, predicates) ;
602
- ocx. register_obligations ( traits:: predicates_for_generics (
603
- |_, _| cause. clone ( ) ,
604
- self . param_env ,
605
- normalized_predicates,
606
- ) ) ;
607
-
608
- let errors = ocx. select_all_or_error ( ) ;
609
- if !errors. is_empty ( ) {
610
- infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ;
611
- }
612
648
613
649
let mut is_trait = false ;
614
650
// Attempting to call a trait method?
0 commit comments