@@ -10,19 +10,23 @@ 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 , Unnormalized } ;
21+ use rustc_middle:: ty:: {
22+ self , ConstInt , GenericArgKind , GenericParamDefKind , ScalarInt , Ty , TyCtxt , TypeVisitableExt ,
23+ Unnormalized ,
24+ } ;
25+ use rustc_session:: lint:: builtin:: UNCONDITIONAL_PANIC ;
2226use rustc_span:: Span ;
2327use tracing:: { debug, instrument, trace} ;
2428
25- use crate :: errors:: { AssertLint , AssertLintKind } ;
29+ use crate :: errors:: { AssertLint , AssertLintKind , ConstNIsZero } ;
2630
2731pub ( super ) struct KnownPanicsLint ;
2832
@@ -768,6 +772,38 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
768772 }
769773 // We failed to evaluate the discriminant, fallback to visiting all successors.
770774 }
775+ TerminatorKind :: Call { func, args : _, .. } => {
776+ if let Some ( ( def_id, generic_args) ) = func. const_fn_def ( ) {
777+ for ( index, arg) in generic_args. iter ( ) . enumerate ( ) {
778+ if let GenericArgKind :: Const ( ct) = arg. kind ( ) {
779+ let generics = self . tcx . generics_of ( def_id) ;
780+ let param_def = generics. param_at ( index, self . tcx ) ;
781+
782+ if let GenericParamDefKind :: Const { .. } = param_def. kind
783+ && find_attr ! ( self . tcx, param_def. def_id, RustcPanicsWhenZero )
784+ && let Some ( 0 ) = ct. try_to_target_usize ( self . tcx )
785+ {
786+ // We managed to figure-out that the value of a
787+ // `#[rustc_panics_when_zero]` const-generic parameter is zero.
788+ //
789+ // Let's report it as an unconditional panic.
790+ let source_info = self . body . source_info ( location) ;
791+ if let Some ( lint_root) = self . lint_root ( * source_info) {
792+ self . tcx . emit_node_span_lint (
793+ UNCONDITIONAL_PANIC ,
794+ lint_root,
795+ source_info. span ,
796+ ConstNIsZero {
797+ const_param_span : source_info. span ,
798+ const_param_name : param_def. name ,
799+ } ,
800+ ) ;
801+ }
802+ }
803+ }
804+ }
805+ }
806+ }
771807 // None of these have Operands to const-propagate.
772808 TerminatorKind :: Goto { .. }
773809 | TerminatorKind :: UnwindResume
@@ -780,7 +816,6 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
780816 | TerminatorKind :: CoroutineDrop
781817 | TerminatorKind :: FalseEdge { .. }
782818 | TerminatorKind :: FalseUnwind { .. }
783- | TerminatorKind :: Call { .. }
784819 | TerminatorKind :: InlineAsm { .. } => { }
785820 }
786821
0 commit comments