@@ -1962,6 +1962,7 @@ impl<'a> Parser<'a> {
1962
1962
sym:: unwrap_binder => {
1963
1963
Some ( this. parse_expr_unsafe_binder_cast ( lo, UnsafeBinderCastKind :: Unwrap ) ?)
1964
1964
}
1965
+ sym:: is => Some ( this. parse_expr_is ( lo) ?) ,
1965
1966
_ => None ,
1966
1967
} )
1967
1968
} )
@@ -2046,6 +2047,17 @@ impl<'a> Parser<'a> {
2046
2047
Ok ( self . mk_expr ( span, ExprKind :: UnsafeBinderCast ( kind, expr, ty) ) )
2047
2048
}
2048
2049
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
+
2049
2061
/// Returns a string literal if the next token is a string literal.
2050
2062
/// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
2051
2063
/// and returns `None` if the next token is not literal at all.
@@ -3436,6 +3448,10 @@ impl<'a> Parser<'a> {
3436
3448
fn parse_match_arm_guard ( & mut self ) -> PResult < ' a , Option < P < Expr > > > {
3437
3449
// Used to check the `if_let_guard` feature mostly by scanning
3438
3450
// `&&` 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.
3439
3455
fn has_let_expr ( expr : & Expr ) -> bool {
3440
3456
match & expr. kind {
3441
3457
ExprKind :: Binary ( BinOp { node : BinOpKind :: And , .. } , lhs, rhs) => {
@@ -4123,6 +4139,16 @@ impl MutVisitor for CondChecker<'_> {
4123
4139
}
4124
4140
}
4125
4141
}
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
+ }
4126
4152
ExprKind :: Binary ( Spanned { node : BinOpKind :: And , .. } , _, _) => {
4127
4153
mut_visit:: walk_expr ( self , e) ;
4128
4154
}
0 commit comments