@@ -24,7 +24,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2424 let lower_sub = |this : & mut Self | sub. as_ref ( ) . map ( |s| this. lower_pat ( & * s) ) ;
2525 break self . lower_pat_ident ( pattern, binding_mode, ident, lower_sub) ;
2626 }
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+ }
2830 PatKind :: TupleStruct ( ref qself, ref path, ref pats) => {
2931 let qpath = self . lower_qpath (
3032 pattern. id ,
@@ -81,8 +83,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
8183 }
8284 PatKind :: Range ( ref e1, ref e2, Spanned { node : ref end, .. } ) => {
8385 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 ) ) ,
8688 self . lower_range_end ( end, e2. is_some ( ) ) ,
8789 ) ;
8890 }
@@ -314,4 +316,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
314316 RangeEnd :: Excluded | RangeEnd :: Included ( _) => hir:: RangeEnd :: Included ,
315317 }
316318 }
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+ }
317348}
0 commit comments