@@ -15,7 +15,7 @@ use rustc_middle::mir::visit::Visitor;
15
15
use rustc_middle:: mir:: * ;
16
16
use rustc_middle:: span_bug;
17
17
use rustc_middle:: ty:: adjustment:: PointerCoercion ;
18
- use rustc_middle:: ty:: { self , Instance , InstanceKind , Ty , TypeVisitableExt } ;
18
+ use rustc_middle:: ty:: { self , Ty , TypeVisitableExt } ;
19
19
use rustc_mir_dataflow:: Analysis ;
20
20
use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
21
21
use rustc_mir_dataflow:: storage:: always_storage_live_locals;
@@ -361,31 +361,21 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
361
361
!is_transient
362
362
}
363
363
364
+ /// Returns whether there are const-conditions.
364
365
fn revalidate_conditional_constness (
365
366
& mut self ,
366
367
callee : DefId ,
367
368
callee_args : ty:: GenericArgsRef < ' tcx > ,
368
- call_source : CallSource ,
369
369
call_span : Span ,
370
- ) {
370
+ ) -> bool {
371
371
let tcx = self . tcx ;
372
372
if !tcx. is_conditionally_const ( callee) {
373
- return ;
373
+ return false ;
374
374
}
375
375
376
376
let const_conditions = tcx. const_conditions ( callee) . instantiate ( tcx, callee_args) ;
377
- // If there are any const conditions on this fn and `const_trait_impl`
378
- // is not enabled, simply bail. We shouldn't be able to call conditionally
379
- // const functions on stable.
380
- if !const_conditions. is_empty ( ) && !tcx. features ( ) . const_trait_impl ( ) {
381
- self . check_op ( ops:: FnCallNonConst {
382
- callee,
383
- args : callee_args,
384
- span : call_span,
385
- call_source,
386
- feature : Some ( sym:: const_trait_impl) ,
387
- } ) ;
388
- return ;
377
+ if const_conditions. is_empty ( ) {
378
+ return false ;
389
379
}
390
380
391
381
let infcx = tcx. infer_ctxt ( ) . build ( self . body . typing_mode ( tcx) ) ;
@@ -421,6 +411,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
421
411
tcx. dcx ( )
422
412
. span_delayed_bug ( call_span, "this should have reported a ~const error in HIR" ) ;
423
413
}
414
+
415
+ true
424
416
}
425
417
}
426
418
@@ -627,11 +619,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
627
619
_ => unreachable ! ( ) ,
628
620
} ;
629
621
630
- let ConstCx { tcx, body, param_env , .. } = * self . ccx ;
622
+ let ConstCx { tcx, body, .. } = * self . ccx ;
631
623
632
624
let fn_ty = func. ty ( body, tcx) ;
633
625
634
- let ( mut callee, mut fn_args) = match * fn_ty. kind ( ) {
626
+ let ( callee, fn_args) = match * fn_ty. kind ( ) {
635
627
ty:: FnDef ( def_id, fn_args) => ( def_id, fn_args) ,
636
628
637
629
ty:: FnPtr ( ..) => {
@@ -645,57 +637,38 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
645
637
}
646
638
} ;
647
639
648
- self . revalidate_conditional_constness ( callee, fn_args, call_source, * fn_span) ;
640
+ let has_const_conditions =
641
+ self . revalidate_conditional_constness ( callee, fn_args, * fn_span) ;
649
642
650
- let mut is_trait = false ;
651
643
// Attempting to call a trait method?
652
644
if let Some ( trait_did) = tcx. trait_of_item ( callee) {
653
- trace ! ( "attempting to call a trait method" ) ;
645
+ // We can't determine the actual callee here, so we have to do different checks
646
+ // than usual.
654
647
648
+ trace ! ( "attempting to call a trait method" ) ;
655
649
let trait_is_const = tcx. is_const_trait ( trait_did) ;
656
- // trait method calls are only permitted when `effects` is enabled.
657
- // typeck ensures the conditions for calling a const trait method are met,
658
- // so we only error if the trait isn't const. We try to resolve the trait
659
- // into the concrete method, and uses that for const stability checks.
660
- // FIXME(const_trait_impl) we might consider moving const stability checks
661
- // to typeck as well.
662
- if tcx. features ( ) . const_trait_impl ( ) && trait_is_const {
663
- // This skips the check below that ensures we only call `const fn`.
664
- is_trait = true ;
665
-
666
- if let Ok ( Some ( instance) ) =
667
- Instance :: try_resolve ( tcx, param_env, callee, fn_args)
668
- && let InstanceKind :: Item ( def) = instance. def
669
- {
670
- // Resolve a trait method call to its concrete implementation, which may be in a
671
- // `const` trait impl. This is only used for the const stability check below, since
672
- // we want to look at the concrete impl's stability.
673
- fn_args = instance. args ;
674
- callee = def;
675
- }
650
+
651
+ if trait_is_const {
652
+ // Trait calls are always conditionally-const.
653
+ self . check_op ( ops:: ConditionallyConstCall { callee, args : fn_args } ) ;
654
+ // FIXME(const_trait_impl): do a more fine-grained check whether this
655
+ // particular trait can be const-stably called.
676
656
} else {
677
- // if the trait is const but the user has not enabled the feature(s),
678
- // suggest them.
679
- let feature = if trait_is_const {
680
- Some ( if tcx. features ( ) . const_trait_impl ( ) {
681
- sym:: effects
682
- } else {
683
- sym:: const_trait_impl
684
- } )
685
- } else {
686
- None
687
- } ;
657
+ // Not even a const trait.
688
658
self . check_op ( ops:: FnCallNonConst {
689
659
callee,
690
660
args : fn_args,
691
661
span : * fn_span,
692
662
call_source,
693
- feature,
694
663
} ) ;
695
- // If we allowed this, we're in miri-unleashed mode, so we might
696
- // as well skip the remaining checks.
697
- return ;
698
664
}
665
+ // That's all we can check here.
666
+ return ;
667
+ }
668
+
669
+ // Even if we know the callee, ensure we can use conditionally-const calls.
670
+ if has_const_conditions {
671
+ self . check_op ( ops:: ConditionallyConstCall { callee, args : fn_args } ) ;
699
672
}
700
673
701
674
// At this point, we are calling a function, `callee`, whose `DefId` is known...
@@ -783,14 +756,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
783
756
return ;
784
757
}
785
758
786
- // Trait functions are not `const fn` so we have to skip them here.
787
- if !tcx. is_const_fn ( callee) && !is_trait {
759
+ if !tcx. is_const_fn ( callee) {
788
760
self . check_op ( ops:: FnCallNonConst {
789
761
callee,
790
762
args : fn_args,
791
763
span : * fn_span,
792
764
call_source,
793
- feature : None ,
794
765
} ) ;
795
766
// If we allowed this, we're in miri-unleashed mode, so we might
796
767
// as well skip the remaining checks.
0 commit comments