@@ -10,19 +10,22 @@ use rustc_const_eval::interpret::{
1010 ImmTy , InterpCx , InterpResult , Projectable , Scalar , format_interp_error, interp_ok,
1111} ;
1212use rustc_data_structures:: fx:: FxHashSet ;
13- use rustc_hir:: HirId ;
1413use rustc_hir:: def:: DefKind ;
14+ use rustc_hir:: { HirId , find_attr} ;
1515use rustc_index:: IndexVec ;
1616use rustc_index:: bit_set:: DenseBitSet ;
1717use rustc_middle:: bug;
1818use rustc_middle:: mir:: visit:: { MutatingUseContext , NonMutatingUseContext , PlaceContext , Visitor } ;
1919use rustc_middle:: mir:: * ;
2020use rustc_middle:: ty:: layout:: { LayoutError , LayoutOf , LayoutOfHelpers , TyAndLayout } ;
21- use rustc_middle:: ty:: { self , ConstInt , ScalarInt , Ty , TyCtxt , TypeVisitableExt } ;
21+ use rustc_middle:: ty:: {
22+ self , ConstInt , GenericArgKind , GenericParamDefKind , ScalarInt , Ty , TyCtxt , TypeVisitableExt ,
23+ } ;
24+ use rustc_session:: lint:: builtin:: UNCONDITIONAL_PANIC ;
2225use rustc_span:: Span ;
2326use tracing:: { debug, instrument, trace} ;
2427
25- use crate :: errors:: { AssertLint , AssertLintKind } ;
28+ use crate :: errors:: { AssertLint , AssertLintKind , ConstNIsZero } ;
2629
2730pub ( super ) struct KnownPanicsLint ;
2831
@@ -765,6 +768,35 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
765768 }
766769 // We failed to evaluate the discriminant, fallback to visiting all successors.
767770 }
771+ TerminatorKind :: Call { func, args : _, .. } => {
772+ if let Some ( ( def_id, generic_args) ) = func. const_fn_def ( ) {
773+ for ( index, arg) in generic_args. iter ( ) . enumerate ( ) {
774+ if let GenericArgKind :: Const ( ct) = arg. kind ( ) {
775+ let generics = self . tcx . generics_of ( def_id) ;
776+ let param_def = generics. param_at ( index, self . tcx ) ;
777+
778+ if let GenericParamDefKind :: Const { .. } = param_def. kind
779+ && find_attr ! ( self . tcx, param_def. def_id, RustcPanicsWhenZero )
780+ && let Some ( 0 ) = ct. try_to_target_usize ( self . tcx )
781+ {
782+ // We managed to figure-out that the value of a
783+ // `#[rustc_panics_when_zero]` const-generic parameter is zero.
784+ //
785+ // Let's report it as an unconditional panic.
786+ let source_info = self . body . source_info ( location) ;
787+ if let Some ( lint_root) = self . lint_root ( * source_info) {
788+ self . tcx . emit_node_span_lint (
789+ UNCONDITIONAL_PANIC ,
790+ lint_root,
791+ source_info. span ,
792+ ConstNIsZero { const_param : source_info. span } ,
793+ ) ;
794+ }
795+ }
796+ }
797+ }
798+ }
799+ }
768800 // None of these have Operands to const-propagate.
769801 TerminatorKind :: Goto { .. }
770802 | TerminatorKind :: UnwindResume
@@ -777,7 +809,6 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
777809 | TerminatorKind :: CoroutineDrop
778810 | TerminatorKind :: FalseEdge { .. }
779811 | TerminatorKind :: FalseUnwind { .. }
780- | TerminatorKind :: Call { .. }
781812 | TerminatorKind :: InlineAsm { .. } => { }
782813 }
783814
0 commit comments