@@ -52,6 +52,8 @@ enum SyntaxAttr {
5252 Hide ,
5353 /// a `#[opaque]` attribute
5454 Opaque ,
55+ /// A `#[no_panic_if(...)]` attribute
56+ NoPanicIf ( Expr ) ,
5557}
5658
5759#[ derive( Default ) ]
@@ -91,6 +93,14 @@ impl ParsedAttrs {
9193 }
9294 }
9395
96+ fn no_panic_if ( & mut self ) -> Option < Expr > {
97+ let pos = self
98+ . syntax
99+ . iter ( )
100+ . position ( |x| matches ! ( x, SyntaxAttr :: NoPanicIf ( _) ) ) ?;
101+ if let SyntaxAttr :: NoPanicIf ( expr) = self . syntax . remove ( pos) { Some ( expr) } else { None }
102+ }
103+
94104 fn invariant ( & mut self ) -> Option < Expr > {
95105 let pos = self
96106 . syntax
@@ -277,9 +287,10 @@ fn ident_path(cx: &mut ParseCtxt, ident: Ident) -> ExprPath {
277287
278288fn parse_detached_fn_sig (
279289 cx : & mut ParseCtxt ,
280- attrs : ParsedAttrs ,
290+ mut attrs : ParsedAttrs ,
281291) -> ParseResult < DetachedItem < FnSig > > {
282- let fn_sig = parse_fn_sig ( cx, token:: Semi ) ?;
292+ let mut fn_sig = parse_fn_sig ( cx, token:: Semi ) ?;
293+ fn_sig. no_panic = attrs. no_panic_if ( ) ;
283294 let span = fn_sig. span ;
284295 let ident = fn_sig
285296 . ident
@@ -410,6 +421,10 @@ fn parse_attr(cx: &mut ParseCtxt, attrs: &mut ParsedAttrs) -> ParseResult {
410421 attrs
411422 . syntax
412423 . push ( SyntaxAttr :: Invariant ( delimited ( cx, Parenthesis , |cx| parse_expr ( cx, true ) ) ?) ) ;
424+ } else if lookahead. advance_if ( sym:: no_panic_if) {
425+ attrs
426+ . syntax
427+ . push ( SyntaxAttr :: NoPanicIf ( parse_expr ( cx, true ) ?) ) ;
413428 } else {
414429 return Err ( lookahead. into_error ( ) ) ;
415430 } ;
@@ -767,7 +782,7 @@ pub(crate) fn parse_fn_sig<T: PeekExpected>(cx: &mut ParseCtxt, end: T) -> Parse
767782 output : FnOutput { returns, ensures, node_id : cx. next_node_id ( ) } ,
768783 node_id : cx. next_node_id ( ) ,
769784 span : cx. mk_span ( lo, hi) ,
770- no_panic : None , // TODO (Andrew): complete mii!
785+ no_panic : None , // We attach the `no_panic` expr later
771786 } )
772787}
773788
0 commit comments