@@ -11,7 +11,6 @@ use rustc_hir::def_id::DefId;
1111use rustc_hir:: { self as hir, LangItem } ;
1212use rustc_index:: bit_set:: BitSet ;
1313use rustc_infer:: infer:: TyCtxtInferExt ;
14- use rustc_infer:: traits:: ObligationCause ;
1514use rustc_middle:: mir:: visit:: Visitor ;
1615use rustc_middle:: mir:: * ;
1716use rustc_middle:: span_bug;
@@ -20,9 +19,11 @@ use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt};
2019use rustc_mir_dataflow:: Analysis ;
2120use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
2221use rustc_mir_dataflow:: storage:: always_storage_live_locals;
23- use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
22+ use rustc_span:: { Span , Symbol , sym} ;
2423use 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+ } ;
2627use tracing:: { debug, instrument, trace} ;
2728
2829use super :: ops:: { self , NonConstOp , Status } ;
@@ -360,6 +361,60 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
360361 // end of evaluation.
361362 !is_transient
362363 }
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 ( self . body . typing_mode ( tcx) ) ;
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+ }
363418}
364419
365420impl < ' tcx > Visitor < ' tcx > for Checker < ' _ , ' tcx > {
@@ -584,31 +639,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
584639 }
585640 } ;
586641
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 ( body. typing_mode ( tcx) ) ;
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,
597646 terminator. source_info . span ,
598- self . body . source . def_id ( ) . expect_local ( ) ,
599- ObligationCauseCode :: WhereClause ( callee, DUMMY_SP ) ,
600647 ) ;
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- }
612648
613649 let mut is_trait = false ;
614650 // Attempting to call a trait method?
0 commit comments