@@ -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 } ;
@@ -364,6 +365,60 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
364365 // end of evaluation.
365366 !is_transient
366367 }
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+ }
367422}
368423
369424impl < ' tcx > Visitor < ' tcx > for Checker < ' _ , ' tcx > {
@@ -588,31 +643,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
588643 }
589644 } ;
590645
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,
601650 terminator. source_info . span ,
602- self . body . source . def_id ( ) . expect_local ( ) ,
603- ObligationCauseCode :: WhereClause ( callee, DUMMY_SP ) ,
604651 ) ;
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- }
616652
617653 let mut is_trait = false ;
618654 // Attempting to call a trait method?
0 commit comments