@@ -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};
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 } ;
@@ -364,6 +365,60 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
364
365
// end of evaluation.
365
366
!is_transient
366
367
}
368
+
369
+ fn revalidate_conditional_constness (
370
+ & self ,
371
+ callee : DefId ,
372
+ callee_args : ty:: GenericArgsRef < ' tcx > ,
373
+ call_source : CallSource ,
374
+ call_span : Span ,
375
+ ) {
376
+ let tcx = self . tcx ;
377
+ if !tcx. is_conditionally_const ( callee) {
378
+ return ;
379
+ }
380
+
381
+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
382
+ let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
383
+
384
+ let const_conditions = tcx. const_conditions ( callee) . instantiate ( tcx, callee_args) ;
385
+
386
+ let body_id = self . body . source . def_id ( ) . expect_local ( ) ;
387
+ let host_polarity = match self . const_kind ( ) {
388
+ hir:: ConstContext :: ConstFn => ty:: HostPolarity :: Maybe ,
389
+ hir:: ConstContext :: Static ( _) | hir:: ConstContext :: Const { .. } => {
390
+ ty:: HostPolarity :: Const
391
+ }
392
+ } ;
393
+ let const_conditions = ocx. normalize (
394
+ & ObligationCause :: misc ( call_span, body_id) ,
395
+ self . param_env ,
396
+ const_conditions,
397
+ ) ;
398
+ ocx. register_obligations ( const_conditions. into_iter ( ) . map ( |( trait_ref, span) | {
399
+ Obligation :: new (
400
+ tcx,
401
+ ObligationCause :: new (
402
+ call_span,
403
+ body_id,
404
+ ObligationCauseCode :: WhereClause ( callee, span) ,
405
+ ) ,
406
+ self . param_env ,
407
+ trait_ref. to_host_effect_clause ( tcx, host_polarity) ,
408
+ )
409
+ } ) ) ;
410
+
411
+ let errors = ocx. select_all_or_error ( ) ;
412
+ if !errors. is_empty ( ) {
413
+ // FIXME(effects): Soon this should be unconditionally delaying a bug.
414
+ if matches ! ( call_source, CallSource :: Normal ) && tcx. features ( ) . effects ( ) {
415
+ tcx. dcx ( )
416
+ . span_delayed_bug ( call_span, "this should have reported a ~const error in HIR" ) ;
417
+ } else {
418
+ infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ;
419
+ }
420
+ }
421
+ }
367
422
}
368
423
369
424
impl < ' tcx > Visitor < ' tcx > for Checker < ' _ , ' tcx > {
@@ -588,31 +643,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
588
643
}
589
644
} ;
590
645
591
- // Check that all trait bounds that are marked as `~const` can be satisfied.
592
- //
593
- // Typeck only does a "non-const" check since it operates on HIR and cannot distinguish
594
- // which path expressions are getting called on and which path expressions are only used
595
- // as function pointers. This is required for correctness.
596
- let infcx = tcx. infer_ctxt ( ) . build ( ) ;
597
- let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
598
-
599
- let predicates = tcx. predicates_of ( callee) . instantiate ( tcx, fn_args) ;
600
- let cause = ObligationCause :: new (
646
+ self . revalidate_conditional_constness (
647
+ callee,
648
+ fn_args,
649
+ call_source,
601
650
terminator. source_info . span ,
602
- self . body . source . def_id ( ) . expect_local ( ) ,
603
- ObligationCauseCode :: WhereClause ( callee, DUMMY_SP ) ,
604
651
) ;
605
- let normalized_predicates = ocx. normalize ( & cause, param_env, predicates) ;
606
- ocx. register_obligations ( traits:: predicates_for_generics (
607
- |_, _| cause. clone ( ) ,
608
- self . param_env ,
609
- normalized_predicates,
610
- ) ) ;
611
-
612
- let errors = ocx. select_all_or_error ( ) ;
613
- if !errors. is_empty ( ) {
614
- infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ;
615
- }
616
652
617
653
let mut is_trait = false ;
618
654
// Attempting to call a trait method?
0 commit comments