@@ -24,7 +24,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24
24
let lower_sub = |this : & mut Self | sub. as_ref ( ) . map ( |s| this. lower_pat ( & * s) ) ;
25
25
break self . lower_pat_ident ( pattern, binding_mode, ident, lower_sub) ;
26
26
}
27
- PatKind :: Lit ( ref e) => break hir:: PatKind :: Lit ( self . lower_expr ( e) ) ,
27
+ PatKind :: Lit ( ref e) => {
28
+ break hir:: PatKind :: Lit ( self . lower_expr_within_pat ( e, false ) ) ;
29
+ }
28
30
PatKind :: TupleStruct ( ref qself, ref path, ref pats) => {
29
31
let qpath = self . lower_qpath (
30
32
pattern. id ,
@@ -81,8 +83,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
81
83
}
82
84
PatKind :: Range ( ref e1, ref e2, Spanned { node : ref end, .. } ) => {
83
85
break hir:: PatKind :: Range (
84
- e1. as_deref ( ) . map ( |e| self . lower_expr ( e ) ) ,
85
- e2. as_deref ( ) . map ( |e| self . lower_expr ( e ) ) ,
86
+ e1. as_deref ( ) . map ( |e| self . lower_expr_within_pat ( e , true ) ) ,
87
+ e2. as_deref ( ) . map ( |e| self . lower_expr_within_pat ( e , true ) ) ,
86
88
self . lower_range_end ( end, e2. is_some ( ) ) ,
87
89
) ;
88
90
}
@@ -314,4 +316,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
314
316
RangeEnd :: Excluded | RangeEnd :: Included ( _) => hir:: RangeEnd :: Included ,
315
317
}
316
318
}
319
+
320
+ /// Matches `'-' lit | lit (cf. parser::Parser::parse_literal_maybe_minus)`,
321
+ /// or paths for ranges.
322
+ //
323
+ // FIXME: do we want to allow `expr -> pattern` conversion to create path expressions?
324
+ // That means making this work:
325
+ //
326
+ // ```rust,ignore (FIXME)
327
+ // struct S;
328
+ // macro_rules! m {
329
+ // ($a:expr) => {
330
+ // let $a = S;
331
+ // }
332
+ // }
333
+ // m!(S);
334
+ // ```
335
+ fn lower_expr_within_pat ( & mut self , expr : & Expr , allow_paths : bool ) -> & ' hir hir:: Expr < ' hir > {
336
+ match expr. kind {
337
+ ExprKind :: Lit ( ..) | ExprKind :: ConstBlock ( ..) | ExprKind :: Err => { }
338
+ ExprKind :: Path ( ..) if allow_paths => { }
339
+ ExprKind :: Unary ( UnOp :: Neg , ref inner) if matches ! ( inner. kind, ExprKind :: Lit ( _) ) => { }
340
+ _ => {
341
+ self . diagnostic ( )
342
+ . span_err ( expr. span , "arbitrary expressions aren't allowed in patterns" ) ;
343
+ return self . arena . alloc ( self . expr_err ( expr. span ) ) ;
344
+ }
345
+ }
346
+ self . lower_expr ( expr)
347
+ }
317
348
}
0 commit comments