@@ -524,6 +524,9 @@ impl<'a, 'tcx> SpecCollector<'a, 'tcx> {
524524 ( "invariant" , hir:: AttrArgs :: Delimited ( dargs) ) => {
525525 self . parse ( dargs, ParseSess :: parse_expr, FluxAttrKind :: Invariant ) ?
526526 }
527+ ( "no_panic_if" , hir:: AttrArgs :: Delimited ( dargs) ) => {
528+ self . parse ( dargs, ParseSess :: parse_expr, FluxAttrKind :: NoPanicIf ) ?
529+ }
527530 ( "constant" , hir:: AttrArgs :: Delimited ( dargs) ) => {
528531 self . parse ( dargs, ParseSess :: parse_constant_info, FluxAttrKind :: Constant ) ?
529532 }
@@ -587,6 +590,16 @@ impl<'a, 'tcx> SpecCollector<'a, 'tcx> {
587590
588591 fn report_dups ( & mut self , attrs : & FluxAttrs ) -> Result {
589592 let mut err = None ;
593+
594+ // look for a NoPanic and a NoPanicIf
595+ let has_no_panic_if = attrs. has_no_panic_if ( ) ;
596+ if has_no_panic_if && let Some ( no_panic_attr_span) = attrs. has_no_panic ( ) {
597+ err. collect ( self . errors . emit ( errors:: DuplicatedAttr {
598+ span : no_panic_attr_span,
599+ name : "NoPanic and NoPanicIf" ,
600+ } ) ) ;
601+ }
602+
590603 for ( name, dups) in attrs. dups ( ) {
591604 for attr in dups {
592605 if attr. allow_dups ( ) {
@@ -671,6 +684,7 @@ enum FluxAttrKind {
671684 ShouldFail ,
672685 ExternSpec ,
673686 NoPanic ,
687+ NoPanicIf ( surface:: Expr ) ,
674688 /// See `detachXX.rs`
675689 DetachedSpecs ( surface:: DetachedSpecs ) ,
676690}
@@ -741,7 +755,13 @@ impl FluxAttrs {
741755 }
742756
743757 fn fn_sig ( & mut self ) -> Option < surface:: FnSig > {
744- read_attr ! ( self , FnSig )
758+ let mut fn_sig = read_attr ! ( self , FnSig ) ;
759+ // FIXME(nilehmann) the `no_panic_if` annotation should work even if there's no `flux::spec`
760+ // annotation or we should at least show an error.
761+ if let Some ( fn_sig) = & mut fn_sig {
762+ fn_sig. no_panic = read_attr ! ( self , NoPanicIf ) ;
763+ }
764+ fn_sig
745765 }
746766
747767 fn ty_alias ( & mut self ) -> Option < Box < surface:: TyAlias > > {
@@ -756,6 +776,17 @@ impl FluxAttrs {
756776 read_attr ! ( self , Generics )
757777 }
758778
779+ fn has_no_panic ( & self ) -> Option < Span > {
780+ self . map
781+ . get ( attr_name ! ( NoPanic ) )
782+ . and_then ( |attrs| attrs. first ( ) )
783+ . map ( |attr| attr. span )
784+ }
785+
786+ fn has_no_panic_if ( & self ) -> bool {
787+ read_flag ! ( self , NoPanicIf )
788+ }
789+
759790 fn trait_assoc_refts ( & mut self ) -> Vec < surface:: TraitAssocReft > {
760791 read_attrs ! ( self , TraitAssocReft )
761792 . into_iter ( )
@@ -821,7 +852,8 @@ impl FluxAttrs {
821852 | FluxAttrKind :: Variant ( _)
822853 | FluxAttrKind :: Invariant ( _)
823854 | FluxAttrKind :: ExternSpec
824- | FluxAttrKind :: DetachedSpecs ( _) => continue ,
855+ | FluxAttrKind :: DetachedSpecs ( _)
856+ | FluxAttrKind :: NoPanicIf ( _) => continue ,
825857 } ;
826858 attrs. push ( attr) ;
827859 }
@@ -856,6 +888,7 @@ impl FluxAttrKind {
856888 FluxAttrKind :: ExternSpec => attr_name ! ( ExternSpec ) ,
857889 FluxAttrKind :: DetachedSpecs ( _) => attr_name ! ( DetachedSpecs ) ,
858890 FluxAttrKind :: NoPanic => attr_name ! ( NoPanic ) ,
891+ FluxAttrKind :: NoPanicIf ( _) => attr_name ! ( NoPanicIf ) ,
859892 }
860893 }
861894}
0 commit comments