@@ -1962,6 +1962,7 @@ impl<'a> Parser<'a> {
19621962 sym:: unwrap_binder => {
19631963 Some ( this. parse_expr_unsafe_binder_cast ( lo, UnsafeBinderCastKind :: Unwrap ) ?)
19641964 }
1965+ sym:: is => Some ( this. parse_expr_is ( lo) ?) ,
19651966 _ => None ,
19661967 } )
19671968 } )
@@ -2046,6 +2047,17 @@ impl<'a> Parser<'a> {
20462047 Ok ( self . mk_expr ( span, ExprKind :: UnsafeBinderCast ( kind, expr, ty) ) )
20472048 }
20482049
2050+ /// Parse placeholder built-in syntax for `is` (rfcs#3573)
2051+ fn parse_expr_is ( & mut self , lo : Span ) -> PResult < ' a , P < Expr > > {
2052+ let scrutinee = self . parse_expr ( ) ?;
2053+ self . expect_keyword ( exp ! ( Is ) ) ?;
2054+ // Likely this will need to be `parse_pat_no_top_alt` for the final syntax.
2055+ // FIXME(is): If so, we'll want a `PatternLocation` variant for `is` for diagnostics.
2056+ let pat = self . parse_pat_no_top_alt ( None , None ) ?;
2057+ let span = lo. to ( self . token . span ) ;
2058+ Ok ( self . mk_expr ( span, ExprKind :: Is ( scrutinee, pat) ) )
2059+ }
2060+
20492061 /// Returns a string literal if the next token is a string literal.
20502062 /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
20512063 /// and returns `None` if the next token is not literal at all.
@@ -3436,6 +3448,10 @@ impl<'a> Parser<'a> {
34363448 fn parse_match_arm_guard ( & mut self ) -> PResult < ' a , Option < P < Expr > > > {
34373449 // Used to check the `if_let_guard` feature mostly by scanning
34383450 // `&&` tokens.
3451+ // FIXME(is): This can't catch `is` expressions. In order to implement placeholder
3452+ // macro-based syntax for `is`, `is` within a macro expansion is treated as part of whatever
3453+ // condition it expands into. As such, gating `is` in match guards would need to be part of
3454+ // the `feature_gate` AST pass.
34393455 fn has_let_expr ( expr : & Expr ) -> bool {
34403456 match & expr. kind {
34413457 ExprKind :: Binary ( BinOp { node : BinOpKind :: And , .. } , lhs, rhs) => {
@@ -4123,6 +4139,16 @@ impl MutVisitor for CondChecker<'_> {
41234139 }
41244140 }
41254141 }
4142+ ExprKind :: Is ( _, _) => {
4143+ // FIXME(is): Handle edition-dependent rules for `is` in `&&`-chains. Currently,
4144+ // `is` desugars to `let` where `let`-chains are permitted, and otherwise desugars
4145+ // to `if let`. In the latter case, we could change the desugaring to rescope its
4146+ // temporaries to work on all Editions. For `is` inside an existing `if`
4147+ // expression's condition, however, temporaries in the condition live too long to
4148+ // permit all `&&` chains in Editions ≤ 2021. Since `is` will be a new keyword, it
4149+ // may only be possible for this to arise through the use of mixed-edition macro
4150+ // expansion or raw keywords (rfcs#3098).
4151+ }
41264152 ExprKind :: Binary ( Spanned { node : BinOpKind :: And , .. } , _, _) => {
41274153 mut_visit:: walk_expr ( self , e) ;
41284154 }
0 commit comments