Skip to content

Commit 140ab5a

Browse files
committed
Allow access to unit and tuple variants of an enum through a type alias of the enum
1 parent 54475e9 commit 140ab5a

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

src/librustc_typeck/check/_match.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,9 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
640640
};
641641

642642
// Items that were partially resolved before should have been resolved to
643-
// associated constants (i.e. not methods).
644-
if path_res.depth != 0 && !check_assoc_item_is_const(pcx, def, pat.span) {
643+
// variants or associated constants (i.e. not methods).
644+
if let Def::Variant(..) = def {
645+
} else if path_res.depth != 0 && !check_assoc_item_is_const(pcx, def, pat.span) {
645646
fcx.write_error(pat.id);
646647
return;
647648
}
@@ -675,10 +676,9 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
675676
}
676677
};
677678

678-
// If we didn't have a fully resolved path to start with, we had an
679-
// associated const, and we should quit now, since the rest of this
680-
// function uses checks specific to structs and enums.
681-
if path_res.depth != 0 {
679+
// If we have an associated const, and we should quit now, since
680+
// the rest of this function uses checks specific to structs and enums.
681+
if let Def::AssociatedConst(..) = def {
682682
if is_tuple_struct_pat {
683683
report_bad_struct_kind(false);
684684
} else {

src/librustc_typeck/check/method/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,15 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
336336
expr_id: ast::NodeId)
337337
-> Result<(Def, LastPrivate), MethodError<'tcx>>
338338
{
339+
// First check if method_name is a variant of self_ty
340+
if let &ty::TyS { sty: ty::TyEnum(adt_def, _), .. } = self_ty {
341+
for variant in adt_def.variants.iter() {
342+
if variant.name == method_name {
343+
return Ok((Def::Variant(adt_def.did, variant.did), LastMod(AllPublic)))
344+
}
345+
}
346+
}
347+
339348
let mode = probe::Mode::Path;
340349
let pick = try!(probe::probe(fcx, span, mode, method_name, self_ty, expr_id));
341350
let def_id = pick.item.def_id();
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Checks that unit and tuple enum variants can be accessed through a type alias of the enum
12+
13+
enum Foo {
14+
Unit,
15+
Bar(i32),
16+
}
17+
18+
type Alias = Foo;
19+
20+
impl Default for Foo {
21+
fn default() -> Self {
22+
Self::Unit
23+
}
24+
}
25+
26+
fn main() {
27+
let t = Alias::Bar(0);
28+
match t {
29+
Alias::Unit => {}
30+
Alias::Bar(_i) => {}
31+
}
32+
}

0 commit comments

Comments
 (0)