提交 216f5fba 编写于 作者: V Vadim Petrochenkov

Separate bindings from other patterns in HIR

上级 ab7c35fa
......@@ -99,7 +99,7 @@ fn decl(&mut self, decl: &hir::Decl, pred: CFGIndex) -> CFGIndex {
fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
match pat.node {
PatKind::Ident(_, _, None) |
PatKind::Binding(_, _, None) |
PatKind::Path(..) |
PatKind::QPath(..) |
PatKind::Lit(..) |
......@@ -110,7 +110,7 @@ fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
PatKind::Box(ref subpat) |
PatKind::Ref(ref subpat, _) |
PatKind::Ident(_, _, Some(ref subpat)) => {
PatKind::Binding(_, _, Some(ref subpat)) => {
let subpat_exit = self.pat(&subpat, pred);
self.add_ast_node(pat.id, &[subpat_exit])
}
......
......@@ -914,8 +914,8 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
id: folder.new_id(id),
node: match node {
PatKind::Wild => PatKind::Wild,
PatKind::Ident(binding_mode, pth1, sub) => {
PatKind::Ident(binding_mode,
PatKind::Binding(binding_mode, pth1, sub) => {
PatKind::Binding(binding_mode,
Spanned {
span: folder.new_span(pth1.span),
node: folder.fold_name(pth1.node),
......
......@@ -485,7 +485,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
PatKind::Ref(ref subpattern, _) => {
visitor.visit_pat(subpattern)
}
PatKind::Ident(_, ref pth1, ref optional_subpattern) => {
PatKind::Binding(_, ref pth1, ref optional_subpattern) => {
visitor.visit_name(pth1.span, pth1.node);
walk_list!(visitor, visit_pat, optional_subpattern);
}
......
......@@ -866,14 +866,16 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
PatKind::Wild => hir::PatKind::Wild,
PatKind::Ident(ref binding_mode, pth1, ref sub) => {
self.with_parent_def(p.id, |this| {
let name = match this.resolver.get_resolution(p.id).map(|d| d.full_def()) {
// Only pattern bindings are renamed
None | Some(Def::Local(..)) => this.lower_ident(pth1.node),
_ => pth1.node.name,
};
hir::PatKind::Ident(this.lower_binding_mode(binding_mode),
respan(pth1.span, name),
sub.as_ref().map(|x| this.lower_pat(x)))
match this.resolver.get_resolution(p.id).map(|d| d.full_def()) {
// `None` can occur in body-less function signatures
None | Some(Def::Local(..)) => {
hir::PatKind::Binding(this.lower_binding_mode(binding_mode),
respan(pth1.span,
this.lower_ident(pth1.node)),
sub.as_ref().map(|x| this.lower_pat(x)))
}
_ => hir::PatKind::Path(hir::Path::from_name(pth1.span, pth1.node.name))
}
})
}
PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
......@@ -1868,7 +1870,7 @@ fn pat_ident(&mut self, span: Span, name: Name) -> P<hir::Pat> {
fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode)
-> P<hir::Pat> {
let pat_ident = hir::PatKind::Ident(bm,
let pat_ident = hir::PatKind::Binding(bm,
Spanned {
span: span,
node: name,
......
......@@ -165,7 +165,7 @@ fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
}
fn visit_pat(&mut self, pat: &'ast Pat) {
let node = if let PatKind::Ident(..) = pat.node {
let node = if let PatKind::Binding(..) = pat.node {
NodeLocal(pat)
} else {
NodePat(pat)
......
......@@ -396,7 +396,7 @@ fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
fn visit_pat(&mut self, pat: &'ast hir::Pat) {
let parent_def = self.parent_def;
if let hir::PatKind::Ident(_, name, _) = pat.node {
if let hir::PatKind::Binding(_, name, _) = pat.node {
let def = self.create_def(pat.id, DefPathData::Binding(name.node));
self.parent_def = Some(def);
}
......
......@@ -561,7 +561,7 @@ pub fn name(&self, id: NodeId) -> Name {
NodeVariant(v) => v.node.name,
NodeLifetime(lt) => lt.name,
NodeTyParam(tp) => tp.name,
NodeLocal(&Pat { node: PatKind::Ident(_,l,_), .. }) => l.node,
NodeLocal(&Pat { node: PatKind::Binding(_,l,_), .. }) => l.node,
NodeStructCtor(_) => self.name(self.get_parent(id)),
_ => bug!("no name for {}", self.node_to_string(id))
}
......
......@@ -466,7 +466,7 @@ fn walk_<G>(&self, it: &mut G) -> bool
}
match self.node {
PatKind::Ident(_, _, Some(ref p)) => p.walk_(it),
PatKind::Binding(_, _, Some(ref p)) => p.walk_(it),
PatKind::Struct(_, ref fields, _) => {
fields.iter().all(|field| field.node.pat.walk_(it))
}
......@@ -484,7 +484,7 @@ fn walk_<G>(&self, it: &mut G) -> bool
PatKind::Wild |
PatKind::Lit(_) |
PatKind::Range(_, _) |
PatKind::Ident(_, _, _) |
PatKind::Binding(..) |
PatKind::Path(..) |
PatKind::QPath(_, _) => {
true
......@@ -532,7 +532,7 @@ pub enum PatKind {
/// which it is. The resolver determines this, and
/// records this pattern's `NodeId` in an auxiliary
/// set (of "PatIdents that refer to unit patterns or constants").
Ident(BindingMode, Spanned<Name>, Option<P<Pat>>),
Binding(BindingMode, Spanned<Name>, Option<P<Pat>>),
/// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
/// The `bool` is `true` in the presence of a `..`.
......@@ -1144,7 +1144,7 @@ pub enum SelfKind {
impl Arg {
pub fn to_self(&self) -> Option<ExplicitSelf> {
if let PatKind::Ident(BindByValue(mutbl), name, _) = self.pat.node {
if let PatKind::Binding(BindByValue(mutbl), name, _) = self.pat.node {
if name.node.unhygienize() == keywords::SelfValue.name() {
return match self.ty.node {
TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
......@@ -1160,7 +1160,7 @@ pub fn to_self(&self) -> Option<ExplicitSelf> {
}
pub fn is_self(&self) -> bool {
if let PatKind::Ident(_, name, _) = self.pat.node {
if let PatKind::Binding(_, name, _) = self.pat.node {
name.node.unhygienize() == keywords::SelfValue.name()
} else {
false
......
......@@ -70,7 +70,6 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true,
PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::Ident(_, _, None) |
PatKind::Struct(..) => {
match dm.get(&pat.id).map(|d| d.full_def()) {
Some(Def::Variant(..)) => true,
......@@ -86,7 +85,6 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::Ident(_, _, None) |
PatKind::Struct(..) => {
match dm.get(&pat.id).map(|d| d.full_def()) {
Some(Def::Variant(..)) | Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => true,
......@@ -99,7 +97,7 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
PatKind::Path(..) | PatKind::QPath(..) => {
match dm.get(&pat.id).map(|d| d.full_def()) {
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
_ => false
......@@ -113,7 +111,7 @@ pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
// returned instead of a panic.
pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
PatKind::Path(..) | PatKind::QPath(..) => {
match dm.get(&pat.id)
.and_then(|d| if d.depth == 0 { Some(d.base_def) }
else { None } ) {
......@@ -125,32 +123,28 @@ pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
}
}
pub fn pat_is_binding(dm: &DefMap, pat: &hir::Pat) -> bool {
pub fn pat_is_binding(_: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
PatKind::Ident(..) => {
!pat_is_variant_or_struct(dm, pat) &&
!pat_is_const(dm, pat)
}
PatKind::Binding(..) => true,
_ => false
}
}
pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
pub fn pat_is_binding_or_wild(_: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
PatKind::Ident(..) => pat_is_binding(dm, pat),
PatKind::Wild => true,
PatKind::Binding(..) | PatKind::Wild => true,
_ => false
}
}
/// Call `it` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }`
pub fn pat_bindings<I>(dm: &RefCell<DefMap>, pat: &hir::Pat, mut it: I) where
pub fn pat_bindings<I>(_: &RefCell<DefMap>, pat: &hir::Pat, mut it: I) where
I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<ast::Name>),
{
pat.walk(|p| {
match p.node {
PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => {
PatKind::Binding(binding_mode, ref pth, _) => {
it(binding_mode, p.id, p.span, &respan(pth.span, pth.node));
}
_ => {}
......@@ -221,7 +215,7 @@ pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> {
match pat.node {
PatKind::Ident(hir::BindByValue(_), ref path1, None) => {
PatKind::Binding(hir::BindByValue(..), ref path1, None) => {
Some(path1.node)
}
_ => {
......@@ -241,7 +235,6 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
match p.node {
PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::Ident(_, _, None) |
PatKind::Struct(..) => {
match dm.get(&p.id) {
Some(&PathResolution { base_def: Def::Variant(_, id), .. }) => {
......
......@@ -1716,7 +1716,7 @@ pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
// is that it doesn't matter
match pat.node {
PatKind::Wild => word(&mut self.s, "_")?,
PatKind::Ident(binding_mode, ref path1, ref sub) => {
PatKind::Binding(binding_mode, ref path1, ref sub) => {
match binding_mode {
hir::BindByRef(mutbl) => {
self.word_nbsp("ref")?;
......@@ -2170,7 +2170,7 @@ pub fn print_arg(&mut self, input: &hir::Arg, is_closure: bool) -> io::Result<()
if let Some(eself) = input.to_self() {
self.print_explicit_self(&eself)?;
} else {
let invalid = if let PatKind::Ident(_, name, _) = input.pat.node {
let invalid = if let PatKind::Binding(_, name, _) = input.pat.node {
name.node == keywords::Invalid.name()
} else {
false
......
......@@ -935,9 +935,9 @@ fn determine_pat_move_mode(&mut self,
let def_map = &self.tcx().def_map;
if pat_util::pat_is_binding(&def_map.borrow(), pat) {
match pat.node {
PatKind::Ident(hir::BindByRef(_), _, _) =>
PatKind::Binding(hir::BindByRef(_), _, _) =>
mode.lub(BorrowingMatch),
PatKind::Ident(hir::BindByValue(_), _, _) => {
PatKind::Binding(hir::BindByValue(_), _, _) => {
match copy_or_move(self.mc.infcx, &cmt_pat, PatBindingMove) {
Copy => mode.lub(CopyingMatch),
Move(_) => mode.lub(MovingMatch),
......@@ -989,14 +989,14 @@ fn walk_pat(&mut self,
// It is also a borrow or copy/move of the value being matched.
match pat.node {
PatKind::Ident(hir::BindByRef(m), _, _) => {
PatKind::Binding(hir::BindByRef(m), _, _) => {
if let ty::TyRef(&r, _) = pat_ty.sty {
let bk = ty::BorrowKind::from_mutbl(m);
delegate.borrow(pat.id, pat.span, cmt_pat,
r, bk, RefBinding);
}
}
PatKind::Ident(hir::BindByValue(_), _, _) => {
PatKind::Binding(hir::BindByValue(_), _, _) => {
let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
debug!("walk_pat binding consuming pat");
delegate.consume_pat(pat, cmt_pat, mode);
......@@ -1057,8 +1057,8 @@ fn walk_pat(&mut self,
let tcx = infcx.tcx;
match pat.node {
PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) |
PatKind::Ident(_, _, None) | PatKind::Struct(..) => {
PatKind::Struct(..) | PatKind::TupleStruct(..) |
PatKind::Path(..) | PatKind::QPath(..) => {
match def_map.get(&pat.id).map(|d| d.full_def()) {
None => {
// no definition found: pat is not a
......@@ -1094,8 +1094,7 @@ fn walk_pat(&mut self,
}
Some(Def::Const(..)) |
Some(Def::AssociatedConst(..)) |
Some(Def::Local(..)) => {
Some(Def::AssociatedConst(..)) => {
// This is a leaf (i.e. identifier binding
// or constant value to match); thus no
// `matched_pat` call.
......@@ -1121,16 +1120,10 @@ fn walk_pat(&mut self,
}
}
PatKind::Ident(_, _, Some(_)) => {
// Do nothing; this is a binding (not an enum
// variant or struct), and the cat_pattern call
// will visit the substructure recursively.
}
PatKind::Wild | PatKind::Tuple(..) | PatKind::Box(..) |
PatKind::Ref(..) | PatKind::Lit(..) | PatKind::Range(..) |
PatKind::Vec(..) => {
// Similarly, each of these cases does not
PatKind::Vec(..) | PatKind::Binding(..) => {
// Each of these cases does not
// correspond to an enum variant or struct, so we
// do not do any `matched_pat` calls for these
// cases either.
......
......@@ -306,7 +306,7 @@ fn from_pointer_kind(base_mutbl: MutabilityCategory,
fn from_local(tcx: TyCtxt, id: ast::NodeId) -> MutabilityCategory {
let ret = match tcx.map.get(id) {
ast_map::NodeLocal(p) => match p.node {
PatKind::Ident(bind_mode, _, _) => {
PatKind::Binding(bind_mode, _, _) => {
if bind_mode == hir::BindByValue(hir::MutMutable) {
McDeclared
} else {
......@@ -398,7 +398,7 @@ fn pat_ty(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
// *being borrowed* is. But ideally we would put in a more
// fundamental fix to this conflated use of the node id.
let ret_ty = match pat.node {
PatKind::Ident(hir::BindByRef(_), _, _) => {
PatKind::Binding(hir::BindByRef(_), _, _) => {
// a bind-by-ref means that the base_ty will be the type of the ident itself,
// but what we want here is the type of the underlying value being borrowed.
// So peel off one-level, turning the &T into T.
......@@ -1276,11 +1276,11 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F)
}
}
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Ident(_, _, None) => {
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Binding(_, _, None) => {
// Lone constant, or unit variant or identifier: ignore
}
PatKind::Ident(_, _, Some(ref subpat)) => {
PatKind::Binding(_, _, Some(ref subpat)) => {
self.cat_pattern_(cmt, &subpat, op)?;
}
......
......@@ -752,13 +752,9 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) {
fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) {
visitor.new_node_extent(pat.id);
// If this is a binding (or maybe a binding, I'm too lazy to check
// the def map) then record the lifetime of that binding.
match pat.node {
PatKind::Ident(..) => {
record_var_lifetime(visitor, pat.id, pat.span);
}
_ => { }
// If this is a binding then record the lifetime of that binding.
if let PatKind::Binding(..) = pat.node {
record_var_lifetime(visitor, pat.id, pat.span);
}
intravisit::walk_pat(visitor, pat);
......@@ -958,7 +954,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
/// | box P&
fn is_binding_pat(pat: &hir::Pat) -> bool {
match pat.node {
PatKind::Ident(hir::BindByRef(_), _, _) => true,
PatKind::Binding(hir::BindByRef(_), _, _) => true,
PatKind::Struct(_, ref field_pats, _) => {
field_pats.iter().any(|fp| is_binding_pat(&fp.node.pat))
......
......@@ -2216,7 +2216,7 @@ pub fn local_var_name_str(self, id: NodeId) -> InternedString {
match self.map.find(id) {
Some(ast_map::NodeLocal(pat)) => {
match pat.node {
PatKind::Ident(_, ref path1, _) => path1.node.as_str(),
PatKind::Binding(_, ref path1, _) => path1.node.as_str(),
_ => {
bug!("Variable id {} maps to {:?}, not local", id, pat);
},
......
......@@ -98,7 +98,7 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
move_pat: &hir::Pat,
cmt: mc::cmt<'tcx>) {
let pat_span_path_opt = match move_pat.node {
PatKind::Ident(_, ref path1, _) => {
PatKind::Binding(_, ref path1, _) => {
Some(MoveSpanAndPath{span: move_pat.span,
name: path1.node})
},
......
......@@ -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 @@ fn visit_id(&mut self, node_id: NodeId) {
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 @@ fn visit_pat(&mut self, pat: &Pat) {
}
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);
......
......@@ -274,9 +274,9 @@ fn check_lifetime_def(&mut self, cx: &LateContext, t: &hir::LifetimeDef) {
}
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
if let &PatKind::Ident(_, ref path1, _) = &p.node {
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
if let Some(Def::Local(..)) = def {
if let &PatKind::Binding(_, ref path1, _) = &p.node {
// Exclude parameter names from foreign functions (they have no `Def`)
if cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()).is_some() {
self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span));
}
}
......@@ -360,12 +360,14 @@ fn check_impl_item(&mut self, cx: &LateContext, ii: &hir::ImplItem) {
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
// Lint for constants that look like binding identifiers (#7526)
match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
(&PatKind::Ident(_, ref path1, _), Some(Def::Const(..))) => {
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
path1.node, p.span);
if let PatKind::Path(ref path) = p.node {
if !path.global && path.segments.len() == 1 && path.segments[0].parameters.is_empty() {
if let Some(Def::Const(..)) = cx.tcx.def_map.borrow().get(&p.id)
.map(|d| d.full_def()) {
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
path.segments[0].name, path.span);
}
}
_ => {}
}
}
}
......@@ -171,7 +171,7 @@ fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
}
});
for fieldpat in field_pats {
if let PatKind::Ident(_, ident, None) = fieldpat.node.pat.node {
if let PatKind::Binding(_, ident, None) = fieldpat.node.pat.node {
if ident.node.unhygienize() == fieldpat.node.name {
cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
&format!("the `{}:` in this pattern is redundant and can \
......
......@@ -744,7 +744,7 @@ fn encode_method_argument_names(rbml_w: &mut Encoder,
rbml_w.start_tag(tag_method_argument_names);
for arg in &decl.inputs {
let tag = tag_method_argument_name;
if let PatKind::Ident(_, ref path1, _) = arg.pat.node {
if let PatKind::Binding(_, ref path1, _) = arg.pat.node {
let name = path1.node.as_str();
rbml_w.wr_tagged_bytes(tag, name.as_bytes());
} else {
......
......@@ -14,7 +14,6 @@
use rustc::mir::repr::*;
use rustc_data_structures::fnv::FnvHashMap;
use rustc::hir;
use rustc::hir::pat_util::pat_is_binding;
use std::ops::{Index, IndexMut};
use syntax::abi::Abi;
use syntax::ast;
......@@ -221,7 +220,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
by_ref: by_ref
};
if let Some(hir::map::NodeLocal(pat)) = tcx.map.find(fv.def.var_id()) {
if let hir::PatKind::Ident(_, ref ident, _) = pat.node {
if let hir::PatKind::Binding(_, ref ident, _) = pat.node {
decl.debug_name = ident.node;
}
}
......@@ -333,10 +332,8 @@ fn args_and_body<A>(&mut self,
let mut name = keywords::Invalid.name();
if let Some(pat) = pattern {
if let hir::PatKind::Ident(_, ref ident, _) = pat.node {
if pat_is_binding(&self.hir.tcx().def_map.borrow(), pat) {
name = ident.node;
}
if let hir::PatKind::Binding(_, ref ident, _) = pat.node {
name = ident.node;
}
}
......
......@@ -13,7 +13,7 @@
use rustc_data_structures::fnv::FnvHashMap;
use rustc_const_eval as const_eval;
use rustc::hir::def::Def;
use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const, pat_is_binding};
use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
use rustc::ty::{self, Ty};
use rustc::mir::repr::*;
use rustc::hir::{self, PatKind};
......@@ -81,7 +81,7 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
PatternKind::Range { lo: lo, hi: hi }
},
PatKind::Path(..) | PatKind::Ident(..) | PatKind::QPath(..)
PatKind::Path(..) | PatKind::QPath(..)
if pat_is_resolved_const(&self.cx.tcx.def_map.borrow(), pat) =>
{
let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
......@@ -167,9 +167,7 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
}
}
PatKind::Ident(bm, ref ident, ref sub)
if pat_is_binding(&self.cx.tcx.def_map.borrow(), pat) =>
{
PatKind::Binding(bm, ref ident, ref sub) => {
let id = match self.binding_map {
None => pat.id,
Some(ref map) => map[&ident.node],
......@@ -210,7 +208,7 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
}
}
PatKind::Ident(..) | PatKind::Path(..) => {
PatKind::Path(..) => {
self.variant_or_leaf(pat, vec![])
}
......
......@@ -424,12 +424,11 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn has_nested_bindings(m: &[Match], col: usize) -> bool {
for br in m {
match br.pats[col].node {
PatKind::Ident(_, _, Some(_)) => return true,
_ => ()
if let PatKind::Binding(_, _, Some(..)) = br.pats[col].node {
return true
}
}
return false;
false
}
// As noted in `fn match_datum`, we should eventually pass around a
......@@ -481,7 +480,7 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let mut pat = br.pats[col];
loop {
pat = match pat.node {
PatKind::Ident(_, ref path, Some(ref inner)) => {
PatKind::Binding(_, ref path, Some(ref inner)) => {
bound_ptrs.push((path.node, val.val));
&inner
},
......@@ -501,7 +500,6 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
dm: &RefCell<DefMap>,
m: &[Match<'a, 'p, 'blk, 'tcx>],
col: usize,
val: MatchInput,
......@@ -518,13 +516,11 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
let this = br.pats[col];
let mut bound_ptrs = br.bound_ptrs.clone();
match this.node {
PatKind::Ident(_, ref path, None) => {
if pat_is_binding(&dm.borrow(), &this) {
bound_ptrs.push((path.node, val.val));
}
PatKind::Binding(_, ref path, None) => {
bound_ptrs.push((path.node, val.val));
}
PatKind::Vec(ref before, Some(ref slice), ref after) => {
if let PatKind::Ident(_, ref path, None) = slice.node {
if let PatKind::Binding(_, ref path, None) = slice.node {
let subslice_val = bind_subslice_pat(
bcx, this.id, val,
before.len(), after.len());
......@@ -554,7 +550,7 @@ fn enter_default<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let _indenter = indenter();
// Collect all of the matches that can match against anything.
enter_match(bcx, dm, m, col, val, |pats| {
enter_match(bcx, m, col, val, |pats| {
if pat_is_binding_or_wild(&dm.borrow(), &pats[col]) {
let mut r = pats[..col].to_vec();
r.extend_from_slice(&pats[col + 1..]);
......@@ -596,7 +592,6 @@ fn enter_default<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
fn enter_opt<'a, 'p, 'blk, 'tcx>(
bcx: Block<'blk, 'tcx>,
_: ast::NodeId,
dm: &RefCell<DefMap>,
m: &[Match<'a, 'p, 'blk, 'tcx>],
opt: &Opt,
col: usize,
......@@ -628,7 +623,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
tcx: bcx.tcx(),
param_env: param_env,
};
enter_match(bcx, dm, m, col, val, |pats|
enter_match(bcx, m, col, val, |pats|
check_match::specialize(&mcx, &pats[..], &ctor, col, variant_size)
)
}
......@@ -659,9 +654,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
PatKind::Lit(ref l) => {
ConstantValue(ConstantExpr(&l), debug_loc)
}
PatKind::Ident(..) | PatKind::Path(..) |
PatKind::TupleStruct(..) | PatKind::Struct(..) => {
// This is either an enum variant or a variable binding.
PatKind::Path(..) | PatKind::TupleStruct(..) | PatKind::Struct(..) => {
let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
match opt_def {
Some(Def::Variant(enum_id, var_id)) => {
......@@ -793,8 +786,7 @@ fn any_irrefutable_adt_pat(tcx: TyCtxt, m: &[Match], col: usize) -> bool {
let pat = br.pats[col];
match pat.node {
PatKind::Tuple(..) => true,
PatKind::Struct(..) | PatKind::TupleStruct(..) |
PatKind::Path(..) | PatKind::Ident(_, _, None) => {
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => {
match tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
Def::Struct(..) | Def::TyAlias(..) => true,
_ => false,
......@@ -839,7 +831,7 @@ fn handle_fail(&self, bcx: Block) {
fn pick_column_to_specialize(def_map: &RefCell<DefMap>, m: &[Match]) -> Option<usize> {
fn pat_score(def_map: &RefCell<DefMap>, pat: &hir::Pat) -> usize {
match pat.node {
PatKind::Ident(_, _, Some(ref inner)) => pat_score(def_map, &inner),
PatKind::Binding(_, _, Some(ref inner)) => pat_score(def_map, &inner),
_ if pat_is_refutable(&def_map.borrow(), pat) => 1,
_ => 0
}
......@@ -1226,7 +1218,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
};
match adt_vals {
Some(field_vals) => {
let pats = enter_match(bcx, dm, m, col, val, |pats|
let pats = enter_match(bcx, m, col, val, |pats|
check_match::specialize(&mcx, pats,
&Constructor::Single, col,
field_vals.len())
......@@ -1391,7 +1383,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
ConstantValue(..) | ConstantRange(..) => ()
}
let opt_ms = enter_opt(opt_cx, pat_id, dm, m, opt, col, size, val);
let opt_ms = enter_opt(opt_cx, pat_id, m, opt, col, size, val);
let mut opt_vals: Vec<_> = unpacked.into_iter()
.map(|v|MatchInput::from_val(v))
.collect();
......@@ -1796,38 +1788,35 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let tcx = bcx.tcx();
let ccx = bcx.ccx();
match pat.node {
PatKind::Ident(pat_binding_mode, ref path1, ref inner) => {
if pat_is_binding(&tcx.def_map.borrow(), &pat) {
// Allocate the stack slot where the value of this
// binding will live and place it into the appropriate
// map.
bcx = mk_binding_alloca(
bcx, pat.id, path1.node, cleanup_scope, (),
"_match::bind_irrefutable_pat",
|(), bcx, Datum { val: llval, ty, kind: _ }| {
match pat_binding_mode {
hir::BindByValue(_) => {
// By value binding: move the value that `val`
// points at into the binding's stack slot.
let d = val.to_datum(ty);
d.store_to(bcx, llval)
}
PatKind::Binding(pat_binding_mode, ref path1, ref inner) => {
// Allocate the stack slot where the value of this
// binding will live and place it into the appropriate
// map.
bcx = mk_binding_alloca(bcx, pat.id, path1.node, cleanup_scope, (),
"_match::bind_irrefutable_pat",
|(), bcx, Datum { val: llval, ty, kind: _ }| {
match pat_binding_mode {
hir::BindByValue(_) => {
// By value binding: move the value that `val`
// points at into the binding's stack slot.
let d = val.to_datum(ty);
d.store_to(bcx, llval)
}
hir::BindByRef(_) => {
// By ref binding: the value of the variable
// is the pointer `val` itself or fat pointer referenced by `val`
if type_is_fat_ptr(bcx.tcx(), ty) {
expr::copy_fat_ptr(bcx, val.val, llval);
}
else {
Store(bcx, val.val, llval);
}
bcx
}
hir::BindByRef(_) => {
// By ref binding: the value of the variable
// is the pointer `val` itself or fat pointer referenced by `val`
if type_is_fat_ptr(bcx.tcx(), ty) {
expr::copy_fat_ptr(bcx, val.val, llval);
}
});
}
else {
Store(bcx, val.val, llval);
}
bcx
}
}
});
if let Some(ref inner_pat) = *inner {
bcx = bind_irrefutable_pat(bcx, &inner_pat, val, cleanup_scope);
......@@ -1941,7 +1930,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let val = if type_is_fat_ptr(tcx, pat_ty) {
// We need to check for this, as the pattern could be binding
// a fat pointer by-value.
if let PatKind::Ident(hir::BindByRef(_),_,_) = inner.node {
if let PatKind::Binding(hir::BindByRef(..),_,_) = inner.node {
val.val
} else {
Load(bcx, val.val)
......@@ -1960,7 +1949,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let val = if type_is_fat_ptr(tcx, pat_ty) {
// We need to check for this, as the pattern could be binding
// a fat pointer by-value.
if let PatKind::Ident(hir::BindByRef(_),_,_) = inner.node {
if let PatKind::Binding(hir::BindByRef(..),_,_) = inner.node {
val.val
} else {
Load(bcx, val.val)
......@@ -2001,8 +1990,8 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
cleanup_scope)
});
}
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Wild | PatKind::Lit(_) |
PatKind::Range(_, _) => ()
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Wild |
PatKind::Lit(..) | PatKind::Range(..) => ()
}
return bcx;
}
......@@ -235,76 +235,66 @@ fn walk_pattern(cx: &CrateContext,
pat: &hir::Pat,
scope_stack: &mut Vec<ScopeStackEntry> ,
scope_map: &mut NodeMap<DIScope>) {
let def_map = &cx.tcx().def_map;
// Unfortunately, we cannot just use pat_util::pat_bindings() or
// ast_util::walk_pat() here because we have to visit *all* nodes in
// order to put them into the scope map. The above functions don't do that.
match pat.node {
PatKind::Ident(_, ref path1, ref sub_pat_opt) => {
// Check if this is a binding. If so we need to put it on the
// scope stack and maybe introduce an artificial scope
if pat_util::pat_is_binding(&def_map.borrow(), &pat) {
let name = path1.node.unhygienize();
// LLVM does not properly generate 'DW_AT_start_scope' fields
// for variable DIEs. For this reason we have to introduce
// an artificial scope at bindings whenever a variable with
// the same name is declared in *any* parent scope.
//
// Otherwise the following error occurs:
//
// let x = 10;
//
// do_something(); // 'gdb print x' correctly prints 10
//
// {
// do_something(); // 'gdb print x' prints 0, because it
// // already reads the uninitialized 'x'
// // from the next line...
// let x = 100;
// do_something(); // 'gdb print x' correctly prints 100
// }
// Is there already a binding with that name?
// N.B.: this comparison must be UNhygienic... because
// gdb knows nothing about the context, so any two
// variables with the same name will cause the problem.
let need_new_scope = scope_stack
.iter()
.any(|entry| entry.name == Some(name));
if need_new_scope {
// Create a new lexical scope and push it onto the stack
let loc = span_start(cx, pat.span);
let file_metadata = file_metadata(cx, &loc.file.name);
let parent_scope = scope_stack.last().unwrap().scope_metadata;
let scope_metadata = unsafe {
llvm::LLVMDIBuilderCreateLexicalBlock(
DIB(cx),
parent_scope,
file_metadata,
loc.line as c_uint,
loc.col.to_usize() as c_uint)
};
scope_stack.push(ScopeStackEntry {
scope_metadata: scope_metadata,
name: Some(name)
});
} else {
// Push a new entry anyway so the name can be found
let prev_metadata = scope_stack.last().unwrap().scope_metadata;
scope_stack.push(ScopeStackEntry {
scope_metadata: prev_metadata,
name: Some(name)
});
}
PatKind::Binding(_, ref path1, ref sub_pat_opt) => {
// LLVM does not properly generate 'DW_AT_start_scope' fields
// for variable DIEs. For this reason we have to introduce
// an artificial scope at bindings whenever a variable with
// the same name is declared in *any* parent scope.
//
// Otherwise the following error occurs:
//
// let x = 10;
//
// do_something(); // 'gdb print x' correctly prints 10
//
// {
// do_something(); // 'gdb print x' prints 0, because it
// // already reads the uninitialized 'x'
// // from the next line...
// let x = 100;
// do_something(); // 'gdb print x' correctly prints 100
// }
// Is there already a binding with that name?
// N.B.: this comparison must be UNhygienic... because
// gdb knows nothing about the context, so any two
// variables with the same name will cause the problem.
let name = path1.node.unhygienize();
let need_new_scope = scope_stack
.iter()
.any(|entry| entry.name == Some(name));
if need_new_scope {
// Create a new lexical scope and push it onto the stack
let loc = span_start(cx, pat.span);
let file_metadata = file_metadata(cx, &loc.file.name);
let parent_scope = scope_stack.last().unwrap().scope_metadata;
let scope_metadata = unsafe {
llvm::LLVMDIBuilderCreateLexicalBlock(
DIB(cx),
parent_scope,
file_metadata,
loc.line as c_uint,
loc.col.to_usize() as c_uint)
};
scope_stack.push(ScopeStackEntry {
scope_metadata: scope_metadata,
name: Some(name)
});
} else {
// Push a new entry anyway so the name can be found
let prev_metadata = scope_stack.last().unwrap().scope_metadata;
scope_stack.push(ScopeStackEntry {
scope_metadata: prev_metadata,
name: Some(name)
});
}
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
......
......@@ -1945,7 +1945,7 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
Some(hir_map::NodeLocal(pat)) => {
match pat.node {
PatKind::Ident(_, ref path1, _) => {
PatKind::Binding(_, ref path1, _) => {
path1.node
}
_ => {
......
......@@ -149,8 +149,7 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
// subtyping doesn't matter here, as the value is some kind of scalar
self.demand_eqtype(pat.span, expected, lhs_ty);
}
PatKind::Path(..) | PatKind::Ident(..)
if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
PatKind::Path(..) if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
if let Some(pat_def) = tcx.def_map.borrow().get(&pat.id) {
let const_did = pat_def.def_id();
let const_scheme = tcx.lookup_item_type(const_did);
......@@ -170,8 +169,7 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
self.write_error(pat.id);
}
}
PatKind::Ident(bm, ref path, ref sub)
if pat_is_binding(&tcx.def_map.borrow(), pat) => {
PatKind::Binding(bm, ref path, ref sub) => {
let typ = self.local_ty(pat.span, pat.id);
match bm {
hir::BindByRef(mutbl) => {
......@@ -211,10 +209,6 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
}
}
}
PatKind::Ident(_, ref path, _) => {
let path = hir::Path::from_name(path.span, path.node);
self.check_pat_enum(pat, &path, &[], None, expected, false);
}
PatKind::TupleStruct(ref path, ref subpats, ddpos) => {
self.check_pat_enum(pat, path, &subpats, ddpos, expected, true);
}
......
......@@ -572,19 +572,17 @@ fn visit_local(&mut self, local: &'gcx hir::Local) {
// Add pattern bindings.
fn visit_pat(&mut self, p: &'gcx hir::Pat) {
if let PatKind::Ident(_, ref path1, _) = p.node {
if pat_util::pat_is_binding(&self.fcx.tcx.def_map.borrow(), p) {
let var_ty = self.assign(p.span, p.id, None);
self.fcx.require_type_is_sized(var_ty, p.span,
traits::VariableType(p.id));
debug!("Pattern binding {} is assigned to {} with type {:?}",
path1.node,
self.fcx.ty_to_string(
self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
var_ty);
}
if let PatKind::Binding(_, ref path1, _) = p.node {
let var_ty = self.assign(p.span, p.id, None);
self.fcx.require_type_is_sized(var_ty, p.span,
traits::VariableType(p.id));
debug!("Pattern binding {} is assigned to {} with type {:?}",
path1.node,
self.fcx.ty_to_string(
self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
var_ty);
}
intravisit::walk_pat(self, p);
}
......
......@@ -1160,7 +1160,7 @@ fn link_pattern<'t>(&self,
let _ = mc.cat_pattern(discr_cmt, root_pat, |mc, sub_cmt, sub_pat| {
match sub_pat.node {
// `ref x` pattern
PatKind::Ident(hir::BindByRef(mutbl), _, _) => {
PatKind::Binding(hir::BindByRef(mutbl), _, _) => {
self.link_region_from_node_type(sub_pat.span, sub_pat.id,
mutbl, sub_cmt);
}
......
......@@ -2152,12 +2152,9 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
{
for i in &decl.inputs {
match i.pat.node {
PatKind::Ident(_, _, _) => (),
PatKind::Wild => (),
_ => {
span_err!(ccx.tcx.sess, i.pat.span, E0130,
"patterns aren't allowed in foreign function declarations");
}
PatKind::Binding(..) | PatKind::Wild => {}
_ => span_err!(ccx.tcx.sess, i.pat.span, E0130,
"patterns aren't allowed in foreign function declarations")
}
}
......
......@@ -2578,7 +2578,7 @@ fn name_from_pat(p: &hir::Pat) -> String {
match p.node {
PatKind::Wild => "_".to_string(),
PatKind::Ident(_, ref p, _) => p.node.to_string(),
PatKind::Binding(_, ref p, _) => p.node.to_string(),
PatKind::TupleStruct(ref p, _, _) | PatKind::Path(ref p) => path_to_string(p),
PatKind::QPath(..) => panic!("tried to get argument name from PatKind::QPath, \
which is not allowed in function arguments"),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册