Separate bindings from other patterns in HIR
This commit is contained in:
parent
ab7c35fa0f
commit
216f5fba04
29 changed files with 230 additions and 300 deletions
|
|
@ -99,7 +99,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
|
||||
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 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
|
||||
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 @@ impl<'a> LoweringContext<'a> {
|
|||
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 @@ impl<'a> LoweringContext<'a> {
|
|||
|
||||
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 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
|||
}
|
||||
|
||||
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 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
|
|||
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 @@ impl<'ast> Map<'ast> {
|
|||
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 @@ impl Pat {
|
|||
}
|
||||
|
||||
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 @@ impl Pat {
|
|||
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 type ExplicitSelf = Spanned<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 @@ impl Arg {
|
|||
}
|
||||
|
||||
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 @@ impl<'a> State<'a> {
|
|||
// 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 @@ impl<'a> State<'a> {
|
|||
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 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
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 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
|
||||
// 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 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
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 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
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 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ impl 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 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
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 @@ 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);
|
||||
|
|
|
|||
|
|
@ -274,9 +274,9 @@ impl LateLintPass for NonSnakeCase {
|
|||
}
|
||||
|
||||
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 @@ impl LateLintPass for NonUpperCaseGlobals {
|
|||
|
||||
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 @@ impl LateLintPass for NonShorthandFieldPatterns {
|
|||
}
|
||||
});
|
||||
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::ty::{self, Ty};
|
|||
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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||
|
||||
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 hair::cx::Cx;
|
|||
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 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, '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 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, '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 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
PatKind::Ident(..) | PatKind::Path(..) => {
|
||||
PatKind::Path(..) => {
|
||||
self.variant_or_leaf(pat, vec![])
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -424,12 +424,11 @@ impl<'a, 'p, 'blk, 'tcx> fmt::Debug for Match<'a, 'p, 'blk, 'tcx> {
|
|||
|
||||
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 @@ impl FailureHandler {
|
|||
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) => {
|
||||
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
|
||||
// }
|
||||
|
||||
// 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) {
|
||||
// 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));
|
||||
|
||||
let name = path1.node.unhygienize();
|
||||
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;
|
||||
|
||||
// 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
|
||||
// }
|
||||
let scope_metadata = unsafe {
|
||||
llvm::LLVMDIBuilderCreateLexicalBlock(
|
||||
DIB(cx),
|
||||
parent_scope,
|
||||
file_metadata,
|
||||
loc.line as c_uint,
|
||||
loc.col.to_usize() as c_uint)
|
||||
};
|
||||
|
||||
// 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));
|
||||
scope_stack.push(ScopeStackEntry {
|
||||
scope_metadata: scope_metadata,
|
||||
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)
|
||||
});
|
||||
}
|
||||
} 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 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
|
|||
|
||||
// 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);
|
||||
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));
|
||||
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);
|
||||
}
|
||||
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 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
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"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue