Skip to content

Commit 4165edf

Browse files
committed
rustc: Implement translation of pattern matching for tuple structs and unit-like structs. r=nmatsakis
1 parent 106f997 commit 4165edf

File tree

13 files changed

+257
-79
lines changed

13 files changed

+257
-79
lines changed

src/rustc/middle/borrowck/gather_loans.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,8 @@ impl gather_loan_ctxt {
441441
alt_id: ast::node_id) {
442442
do self.bccx.cat_pattern(discr_cmt, root_pat) |cmt, pat| {
443443
match pat.node {
444-
ast::pat_ident(bm, _, _) if !self.pat_is_variant(pat) => {
444+
ast::pat_ident(bm, _, _)
445+
if !self.pat_is_variant_or_struct(pat) => {
445446
match bm {
446447
ast::bind_by_value | ast::bind_by_move => {
447448
// copying does not borrow anything, so no check
@@ -492,8 +493,8 @@ impl gather_loan_ctxt {
492493
}
493494
}
494495

495-
fn pat_is_variant(&self, pat: @ast::pat) -> bool {
496-
pat_util::pat_is_variant(self.bccx.tcx.def_map, pat)
496+
fn pat_is_variant_or_struct(&self, pat: @ast::pat) -> bool {
497+
pat_util::pat_is_variant_or_struct(self.bccx.tcx.def_map, pat)
497498
}
498499
}
499500

src/rustc/middle/pat_util.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use syntax::codemap::span;
77
use std::map::HashMap;
88

99
export pat_binding_ids, pat_bindings, pat_id_map, PatIdMap;
10-
export pat_is_variant, pat_is_binding_or_wild;
10+
export pat_is_variant_or_struct, pat_is_binding_or_wild;
1111

1212
type PatIdMap = std::map::HashMap<ident, node_id>;
1313

@@ -21,20 +21,21 @@ fn pat_id_map(dm: resolve::DefMap, pat: @pat) -> PatIdMap {
2121
return map;
2222
}
2323

24-
fn pat_is_variant(dm: resolve::DefMap, pat: @pat) -> bool {
24+
fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: @pat) -> bool {
2525
match pat.node {
26-
pat_enum(_, _) => true,
27-
pat_ident(_, _, None) | pat_struct(*) => match dm.find(pat.id) {
28-
Some(def_variant(_, _)) => true,
26+
pat_enum(_, _) | pat_ident(_, _, None) | pat_struct(*) => {
27+
match dm.find(pat.id) {
28+
Some(def_variant(*)) | Some(def_class(*)) => true,
29+
_ => false
30+
}
31+
}
2932
_ => false
30-
},
31-
_ => false
3233
}
3334
}
3435

3536
fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: @pat) -> bool {
3637
match pat.node {
37-
pat_ident(*) => !pat_is_variant(dm, pat),
38+
pat_ident(*) => !pat_is_variant_or_struct(dm, pat),
3839
pat_wild => true,
3940
_ => false
4041
}
@@ -44,7 +45,8 @@ fn pat_bindings(dm: resolve::DefMap, pat: @pat,
4445
it: fn(binding_mode, node_id, span, @path)) {
4546
do walk_pat(pat) |p| {
4647
match p.node {
47-
pat_ident(binding_mode, pth, _) if !pat_is_variant(dm, p) => {
48+
pat_ident(binding_mode, pth, _)
49+
if !pat_is_variant_or_struct(dm, p) => {
4850
it(binding_mode, p.id, p.span, pth);
4951
}
5052
_ => {}

src/rustc/middle/resolve.rs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,10 @@ impl AllowCapturingSelfFlag : cmp::Eq {
288288
pure fn ne(other: &AllowCapturingSelfFlag) -> bool { !self.eq(other) }
289289
}
290290

291-
enum EnumVariantOrConstResolution {
292-
FoundEnumVariant(def),
291+
enum BareIdentifierPatternResolution {
292+
FoundStructOrEnumVariant(def),
293293
FoundConst,
294-
EnumVariantOrConstNotFound
294+
BareIdentifierPatternUnresolved
295295
}
296296

297297
// Specifies how duplicates should be handled when adding a child item if
@@ -4187,28 +4187,31 @@ impl Resolver {
41874187
if !path.global && path.idents.len() == 1u => {
41884188
41894189
// The meaning of pat_ident with no type parameters
4190-
// depends on whether an enum variant with that name is in
4191-
// scope. The probing lookup has to be careful not to emit
4192-
// spurious errors. Only matching patterns (match) can
4193-
// match nullary variants. For binding patterns (let),
4194-
// matching such a variant is simply disallowed (since
4195-
// it's rarely what you want).
4190+
// depends on whether an enum variant or unit-like struct
4191+
// with that name is in scope. The probing lookup has to
4192+
// be careful not to emit spurious errors. Only matching
4193+
// patterns (match) can match nullary variants or
4194+
// unit-like structs. For binding patterns (let), matching
4195+
// such a value is simply disallowed (since it's rarely
4196+
// what you want).
41964197
41974198
let ident = path.idents[0];
41984199
4199-
match self.resolve_enum_variant_or_const(ident) {
4200-
FoundEnumVariant(def) if mode == RefutableMode => {
4200+
match self.resolve_bare_identifier_pattern(ident) {
4201+
FoundStructOrEnumVariant(def)
4202+
if mode == RefutableMode => {
42014203
debug!("(resolving pattern) resolving `%s` to \
4202-
enum variant",
4204+
struct or enum variant",
42034205
self.session.str_of(ident));
42044206
42054207
self.record_def(pattern.id, def);
42064208
}
4207-
FoundEnumVariant(_) => {
4209+
FoundStructOrEnumVariant(_) => {
42084210
self.session.span_err(pattern.span,
42094211
fmt!("declaration of `%s` \
42104212
shadows an enum \
4211-
that's in scope",
4213+
variant or unit-like \
4214+
struct in scope",
42124215
self.session
42134216
.str_of(ident)));
42144217
}
@@ -4218,7 +4221,7 @@ impl Resolver {
42184221
conflicts with a constant \
42194222
in scope");
42204223
}
4221-
EnumVariantOrConstNotFound => {
4224+
BareIdentifierPatternUnresolved => {
42224225
debug!("(resolving pattern) binding `%s`",
42234226
self.session.str_of(ident));
42244227

@@ -4349,13 +4352,11 @@ impl Resolver {
43494352
}
43504353
}
43514354
4352-
fn resolve_enum_variant_or_const(name: ident)
4353-
-> EnumVariantOrConstResolution {
4354-
4355+
fn resolve_bare_identifier_pattern(name: ident)
4356+
-> BareIdentifierPatternResolution {
43554357
match self.resolve_item_in_lexical_scope(self.current_module,
4356-
name,
4357-
ValueNS) {
4358-
4358+
name,
4359+
ValueNS) {
43594360
Success(target) => {
43604361
match target.bindings.value_def {
43614362
None => {
@@ -4364,14 +4365,14 @@ impl Resolver {
43644365
}
43654366
Some(def) => {
43664367
match def.def {
4367-
def @ def_variant(*) => {
4368-
return FoundEnumVariant(def);
4368+
def @ def_variant(*) | def @ def_class(*) => {
4369+
return FoundStructOrEnumVariant(def);
43694370
}
43704371
def_const(*) => {
43714372
return FoundConst;
43724373
}
43734374
_ => {
4374-
return EnumVariantOrConstNotFound;
4375+
return BareIdentifierPatternUnresolved;
43754376
}
43764377
}
43774378
}
@@ -4383,7 +4384,7 @@ impl Resolver {
43834384
}
43844385
43854386
Failed => {
4386-
return EnumVariantOrConstNotFound;
4387+
return BareIdentifierPatternUnresolved;
43874388
}
43884389
}
43894390
}

0 commit comments

Comments
 (0)