Skip to content

Commit

Permalink
Get associated consts working in match patterns.
Browse files Browse the repository at this point in the history
  • Loading branch information
quantheory committed Apr 24, 2015
1 parent 91ae5e3 commit 29eb550
Show file tree
Hide file tree
Showing 25 changed files with 610 additions and 198 deletions.
1 change: 1 addition & 0 deletions src/librustc/middle/cfg/construct.rs
Expand Up @@ -105,6 +105,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
match pat.node {
ast::PatIdent(_, _, None) |
ast::PatEnum(_, None) |
ast::PatQPath(..) |
ast::PatLit(..) |
ast::PatRange(..) |
ast::PatWild(_) => {
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/middle/check_match.rs
Expand Up @@ -439,7 +439,7 @@ impl<'map> ast_util::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 {
ast::PatIdent(..) | ast::PatEnum(..) => {
ast::PatIdent(..) | ast::PatEnum(..) | ast::PatQPath(..) => {
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
match def {
Some(DefAssociatedConst(did, _)) |
Expand Down Expand Up @@ -762,6 +762,9 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
_ => vec!(Single)
},
ast::PatQPath(..) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
been rewritten"),
ast::PatStruct(..) =>
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
Expand Down Expand Up @@ -891,6 +894,11 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}
}

ast::PatQPath(_, _) => {
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
been rewritten")
}

ast::PatStruct(_, ref pattern_fields, _) => {
// Is this a struct or an enum variant?
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/expr_use_visitor.rs
Expand Up @@ -1147,7 +1147,8 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
let tcx = typer.tcx();

match pat.node {
ast::PatEnum(_, _) | ast::PatIdent(_, _, None) | ast::PatStruct(..) => {
ast::PatEnum(_, _) | ast::PatQPath(..) |
ast::PatIdent(_, _, None) | ast::PatStruct(..) => {
match def_map.get(&pat.id).map(|d| d.full_def()) {
None => {
// no definition found: pat is not a
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/middle/mem_categorization.rs
Expand Up @@ -1299,6 +1299,10 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
}
}

ast::PatQPath(..) => {
// Lone constant: ignore
}

ast::PatIdent(_, _, Some(ref subpat)) => {
try!(self.cat_pattern_(cmt, &**subpat, op));
}
Expand Down
20 changes: 18 additions & 2 deletions src/librustc/middle/pat_util.rs
Expand Up @@ -30,7 +30,7 @@ pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {

pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node {
ast::PatLit(_) | ast::PatRange(_, _) => true,
ast::PatLit(_) | ast::PatRange(_, _) | ast::PatQPath(..) => true,
ast::PatEnum(_, _) |
ast::PatIdent(_, _, None) |
ast::PatStruct(..) => {
Expand Down Expand Up @@ -60,7 +60,7 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {

pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node {
ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
ast::PatIdent(_, _, None) | ast::PatEnum(..) | ast::PatQPath(..) => {
match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefConst(..)) | Some(DefAssociatedConst(..)) => true,
_ => false
Expand All @@ -70,6 +70,22 @@ pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
}
}

// Same as above, except that partially-resolved defs cause `false` to be
// returned instead of a panic.
pub fn pat_is_resolved_const(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node {
ast::PatIdent(_, _, None) | ast::PatEnum(..) | ast::PatQPath(..) => {
match dm.borrow().get(&pat.id)
.and_then(|d| if d.depth == 0 { Some(d.base_def) }
else { None } ) {
Some(DefConst(..)) | Some(DefAssociatedConst(..)) => true,
_ => false
}
}
_ => false
}
}

pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node {
ast::PatIdent(..) => {
Expand Down
1 change: 0 additions & 1 deletion src/librustc_lint/builtin.rs
Expand Up @@ -1091,7 +1091,6 @@ impl LintPass for NonUpperCaseGlobals {
fn check_pat(&mut self, cx: &Context, p: &ast::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())) {
(&ast::PatIdent(_, ref path1, _), Some(def::DefAssociatedConst(..))) |
(&ast::PatIdent(_, ref path1, _), Some(def::DefConst(..))) => {
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
path1.node, p.span);
Expand Down

0 comments on commit 29eb550

Please sign in to comment.