diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-03-06 15:54:44 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-05-26 11:11:58 +0300 |
| commit | d69aeaf662c637b454e8c7a5ddbd69b4978ec211 (patch) | |
| tree | 45d5b4b43bac7f04ea48136ffb02048278dcfb3a /src/librustc_const_eval | |
| parent | d5759a3417fa395d439f4283825504dd4f78dc87 (diff) | |
| download | rust-d69aeaf662c637b454e8c7a5ddbd69b4978ec211.tar.gz rust-d69aeaf662c637b454e8c7a5ddbd69b4978ec211.zip | |
Implement `..` in tuple (struct) patterns
Diffstat (limited to 'src/librustc_const_eval')
| -rw-r--r-- | src/librustc_const_eval/check_match.rs | 33 | ||||
| -rw-r--r-- | src/librustc_const_eval/eval.rs | 9 | ||||
| -rw-r--r-- | src/librustc_const_eval/lib.rs | 1 |
3 files changed, 27 insertions, 16 deletions
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 2fb5d796589..f98734f21ad 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -374,7 +374,7 @@ fn pat_is_catchall(dm: &DefMap, p: &Pat) -> bool { PatKind::Ident(_, _, None) => pat_is_binding(dm, p), PatKind::Ident(_, _, Some(ref s)) => pat_is_catchall(dm, &s), PatKind::Ref(ref s, _) => pat_is_catchall(dm, &s), - PatKind::Tup(ref v) => v.iter().all(|p| pat_is_catchall(dm, &p)), + PatKind::Tuple(ref v, _) => v.iter().all(|p| pat_is_catchall(dm, &p)), _ => false } } @@ -398,7 +398,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: hir: hir::MatchSource::ForLoopDesugar => { // `witnesses[0]` has the form `Some(<head>)`, peel off the `Some` let witness = match witnesses[0].node { - PatKind::TupleStruct(_, Some(ref pats)) => match &pats[..] { + PatKind::TupleStruct(_, ref pats, _) => match &pats[..] { [ref pat] => &**pat, _ => bug!(), }, @@ -559,7 +559,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor, let pats_len = pats.len(); let mut pats = pats.into_iter().map(|p| P((*p).clone())); let pat = match left_ty.sty { - ty::TyTuple(_) => PatKind::Tup(pats.collect()), + ty::TyTuple(..) => PatKind::Tuple(pats.collect(), None), ty::TyEnum(adt, _) | ty::TyStruct(adt, _) => { let v = ctor.variant_for_adt(adt); @@ -580,7 +580,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor, PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields) } VariantKind::Tuple => { - PatKind::TupleStruct(def_to_path(cx.tcx, v.did), Some(pats.collect())) + PatKind::TupleStruct(def_to_path(cx.tcx, v.did), pats.collect(), None) } VariantKind::Unit => { PatKind::Path(def_to_path(cx.tcx, v.did)) @@ -832,7 +832,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, vec!(Slice(before.len() + after.len())) } }, - PatKind::Box(_) | PatKind::Tup(_) | PatKind::Ref(..) => + PatKind::Box(..) | PatKind::Tuple(..) | PatKind::Ref(..) => vec!(Single), PatKind::Wild => vec!(), @@ -914,7 +914,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], } } - PatKind::TupleStruct(_, ref args) => { + PatKind::TupleStruct(_, ref args, ddpos) => { let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def(); match def { Def::Const(..) | Def::AssociatedConst(..) => @@ -922,10 +922,15 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], been rewritten"), Def::Variant(_, id) if *constructor != Variant(id) => None, Def::Variant(..) | Def::Struct(..) => { - Some(match args { - &Some(ref args) => args.iter().map(|p| &**p).collect(), - &None => vec![DUMMY_WILD_PAT; arity], - }) + match ddpos { + Some(ddpos) => { + let mut pats = args[..ddpos].iter().map(|p| &**p).collect(): Vec<_>; + pats.extend(repeat(DUMMY_WILD_PAT).take(arity - args.len())); + pats.extend(args[ddpos..].iter().map(|p| &**p)); + Some(pats) + } + None => Some(args.iter().map(|p| &**p).collect()) + } } _ => None } @@ -952,7 +957,13 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], } } - PatKind::Tup(ref args) => + PatKind::Tuple(ref args, Some(ddpos)) => { + let mut pats = args[..ddpos].iter().map(|p| &**p).collect(): Vec<_>; + pats.extend(repeat(DUMMY_WILD_PAT).take(arity - args.len())); + pats.extend(args[ddpos..].iter().map(|p| &**p)); + Some(pats) + } + PatKind::Tuple(ref args, None) => Some(args.iter().map(|p| &**p).collect()), PatKind::Box(ref inner) | PatKind::Ref(ref inner, _) => diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 9db24fa4770..b727b778fcd 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -271,10 +271,9 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let pat = match expr.node { hir::ExprTup(ref exprs) => - PatKind::Tup(try!(exprs.iter() - .map(|expr| const_expr_to_pat(tcx, &expr, - pat_id, span)) - .collect())), + PatKind::Tuple(try!(exprs.iter() + .map(|expr| const_expr_to_pat(tcx, &expr, pat_id, span)) + .collect()), None), hir::ExprCall(ref callee, ref args) => { let def = *tcx.def_map.borrow().get(&callee.id).unwrap(); @@ -295,7 +294,7 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .map(|expr| const_expr_to_pat(tcx, &**expr, pat_id, span)) .collect()); - PatKind::TupleStruct(path, Some(pats)) + PatKind::TupleStruct(path, pats, None) } hir::ExprStruct(ref path, ref fields, None) => { diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs index 9ab6a437a5a..2c796690df4 100644 --- a/src/librustc_const_eval/lib.rs +++ b/src/librustc_const_eval/lib.rs @@ -31,6 +31,7 @@ #![feature(question_mark)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(type_ascription)] #[macro_use] extern crate syntax; #[macro_use] extern crate log; |
