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-28 00:54:29 +0300 |
| commit | 216f5fba043ff787ba2dd6bbf01e0e077304adf0 (patch) | |
| tree | 9b24ca0a92fe4d0629afe3059424b0544b1dfddb /src/librustc_const_eval | |
| parent | ab7c35fa0fcd725cdc207487b760d85fd07ecdd7 (diff) | |
| download | rust-216f5fba043ff787ba2dd6bbf01e0e077304adf0.tar.gz rust-216f5fba043ff787ba2dd6bbf01e0e077304adf0.zip | |
Separate bindings from other patterns in HIR
Diffstat (limited to 'src/librustc_const_eval')
| -rw-r--r-- | src/librustc_const_eval/check_match.rs | 107 |
1 files changed, 44 insertions, 63 deletions
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 16b61534ee9..46e05d218fc 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -239,31 +239,28 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) { fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) { pat.walk(|p| { - match p.node { - PatKind::Ident(hir::BindByValue(hir::MutImmutable), name, None) => { - let pat_ty = cx.tcx.pat_ty(p); - if let ty::TyEnum(edef, _) = pat_ty.sty { - let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()); - if let Some(Def::Local(..)) = def { - if edef.variants.iter().any(|variant| - variant.name == name.node.unhygienize() - && variant.kind() == VariantKind::Unit - ) { - let ty_path = cx.tcx.item_path_str(edef.did); - let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, - "pattern binding `{}` is named the same as one \ - of the variants of the type `{}`", - name.node, ty_path); - help!(err, - "if you meant to match on a variant, \ - consider making the path in the pattern qualified: `{}::{}`", - ty_path, name.node); - err.emit(); - } + if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), name, None) = p.node { + let pat_ty = cx.tcx.pat_ty(p); + if let ty::TyEnum(edef, _) = pat_ty.sty { + let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()); + if let Some(Def::Local(..)) = def { + if edef.variants.iter().any(|variant| + variant.name == name.node.unhygienize() + && variant.kind() == VariantKind::Unit + ) { + let ty_path = cx.tcx.item_path_str(edef.did); + let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, + "pattern binding `{}` is named the same as one \ + of the variants of the type `{}`", + name.node, ty_path); + help!(err, + "if you meant to match on a variant, \ + consider making the path in the pattern qualified: `{}::{}`", + ty_path, name.node); + err.emit(); } } } - _ => () } true }); @@ -371,8 +368,8 @@ fn check_arms(cx: &MatchCheckCtxt, /// Checks for common cases of "catchall" patterns that may not be intended as such. fn pat_is_catchall(dm: &DefMap, p: &Pat) -> bool { match p.node { - PatKind::Ident(_, _, None) => pat_is_binding(dm, p), - PatKind::Ident(_, _, Some(ref s)) => pat_is_catchall(dm, &s), + PatKind::Binding(_, _, None) => true, + PatKind::Binding(_, _, Some(ref s)) => pat_is_catchall(dm, &s), PatKind::Ref(ref s, _) => pat_is_catchall(dm, &s), PatKind::Tuple(ref v, _) => v.iter().all(|p| pat_is_catchall(dm, &p)), _ => false @@ -381,7 +378,7 @@ fn pat_is_catchall(dm: &DefMap, p: &Pat) -> bool { fn raw_pat(p: &Pat) -> &Pat { match p.node { - PatKind::Ident(_, _, Some(ref s)) => raw_pat(&s), + PatKind::Binding(_, _, Some(ref s)) => raw_pat(&s), _ => p } } @@ -487,11 +484,10 @@ impl<'map> IdVisitingOperation for RenamingRecorder<'map> { impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> { return match pat.node { - PatKind::Ident(..) | PatKind::Path(..) | PatKind::QPath(..) => { + PatKind::Path(..) | PatKind::QPath(..) => { let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()); match def { - Some(Def::AssociatedConst(did)) | - Some(Def::Const(did)) => { + Some(Def::AssociatedConst(did)) | Some(Def::Const(did)) => { let substs = Some(self.tcx.node_id_item_substs(pat.id).substs); if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) { match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) { @@ -717,7 +713,7 @@ fn is_useful(cx: &MatchCheckCtxt, let left_ty = cx.tcx.pat_ty(&real_pat); match real_pat.node { - PatKind::Ident(hir::BindByRef(..), _, _) => { + PatKind::Binding(hir::BindByRef(..), _, _) => { left_ty.builtin_deref(false, NoPreference).unwrap().ty } _ => left_ty, @@ -804,38 +800,37 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> { let pat = raw_pat(p); match pat.node { - PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Ident(..) => + PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() { Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat.span, "const pattern should've \ been rewritten"), Def::Struct(..) | Def::TyAlias(..) => vec![Single], Def::Variant(_, id) => vec![Variant(id)], - Def::Local(..) => vec![], def => span_bug!(pat.span, "pat_constructors: unexpected \ definition {:?}", def), }, PatKind::QPath(..) => span_bug!(pat.span, "const pattern should've been rewritten"), PatKind::Lit(ref expr) => - vec!(ConstantValue(eval_const_expr(cx.tcx, &expr))), + vec![ConstantValue(eval_const_expr(cx.tcx, &expr))], PatKind::Range(ref lo, ref hi) => - vec!(ConstantRange(eval_const_expr(cx.tcx, &lo), eval_const_expr(cx.tcx, &hi))), + vec![ConstantRange(eval_const_expr(cx.tcx, &lo), eval_const_expr(cx.tcx, &hi))], PatKind::Vec(ref before, ref slice, ref after) => match left_ty.sty { - ty::TyArray(_, _) => vec!(Single), + ty::TyArray(_, _) => vec![Single], _ => if slice.is_some() { (before.len() + after.len()..max_slice_length+1) .map(|length| Slice(length)) .collect() } else { - vec!(Slice(before.len() + after.len())) + vec![Slice(before.len() + after.len())] } }, PatKind::Box(..) | PatKind::Tuple(..) | PatKind::Ref(..) => - vec!(Single), - PatKind::Wild => - vec!(), + vec![Single], + PatKind::Binding(..) | PatKind::Wild => + vec![], } } @@ -897,10 +892,10 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], id: pat_id, ref node, span: pat_span } = raw_pat(r[col]); let head: Option<Vec<&Pat>> = match *node { - PatKind::Wild => + PatKind::Binding(..) | PatKind::Wild => Some(vec![DUMMY_WILD_PAT; arity]), - PatKind::Path(..) | PatKind::Ident(..) => { + PatKind::Path(..) => { let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def(); match def { Def::Const(..) | Def::AssociatedConst(..) => @@ -908,7 +903,6 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], been rewritten"), Def::Variant(_, id) if *constructor != Variant(id) => None, Def::Variant(..) | Def::Struct(..) => Some(Vec::new()), - Def::Local(..) => Some(vec![DUMMY_WILD_PAT; arity]), _ => span_bug!(pat_span, "specialize: unexpected \ definition {:?}", def), } @@ -1128,28 +1122,15 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, for pat in pats { pat.walk(|p| { - if pat_is_binding(&def_map.borrow(), &p) { - match p.node { - PatKind::Ident(hir::BindByValue(_), _, ref sub) => { - let pat_ty = tcx.node_id_to_type(p.id); - //FIXME: (@jroesch) this code should be floated up as well - cx.tcx.infer_ctxt(None, Some(cx.param_env.clone()), - ProjectionMode::AnyFinal).enter(|infcx| { - if infcx.type_moves_by_default(pat_ty, pat.span) { - check_move(p, sub.as_ref().map(|p| &**p)); - } - }); + if let PatKind::Binding(hir::BindByValue(..), _, ref sub) = p.node { + let pat_ty = tcx.node_id_to_type(p.id); + //FIXME: (@jroesch) this code should be floated up as well + cx.tcx.infer_ctxt(None, Some(cx.param_env.clone()), + ProjectionMode::AnyFinal).enter(|infcx| { + if infcx.type_moves_by_default(pat_ty, pat.span) { + check_move(p, sub.as_ref().map(|p| &**p)); } - PatKind::Ident(hir::BindByRef(_), _, _) => { - } - _ => { - span_bug!( - p.span, - "binding pattern {} is not an identifier: {:?}", - p.id, - p.node); - } - } + }); } true }); @@ -1225,7 +1206,7 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> { } match pat.node { - PatKind::Ident(_, _, Some(_)) => { + PatKind::Binding(_, _, Some(_)) => { let bindings_were_allowed = self.bindings_allowed; self.bindings_allowed = false; intravisit::walk_pat(self, pat); |
