Skip to content

Commit

Permalink
Allow access to unit and tuple variants of an enum through a type ali…
Browse files Browse the repository at this point in the history
…as of the enum
  • Loading branch information
jseyfried committed Jan 25, 2016
1 parent 54475e9 commit 140ab5a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,9 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
};

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

// If we didn't have a fully resolved path to start with, we had an
// associated const, and we should quit now, since the rest of this
// function uses checks specific to structs and enums.
if path_res.depth != 0 {
// If we have an associated const, and we should quit now, since
// the rest of this function uses checks specific to structs and enums.
if let Def::AssociatedConst(..) = def {
if is_tuple_struct_pat {
report_bad_struct_kind(false);
} else {
Expand Down
9 changes: 9 additions & 0 deletions src/librustc_typeck/check/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,15 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
expr_id: ast::NodeId)
-> Result<(Def, LastPrivate), MethodError<'tcx>>
{
// First check if method_name is a variant of self_ty
if let &ty::TyS { sty: ty::TyEnum(adt_def, _), .. } = self_ty {
for variant in adt_def.variants.iter() {
if variant.name == method_name {
return Ok((Def::Variant(adt_def.did, variant.did), LastMod(AllPublic)))
}
}
}

let mode = probe::Mode::Path;
let pick = try!(probe::probe(fcx, span, mode, method_name, self_ty, expr_id));
let def_id = pick.item.def_id();
Expand Down
32 changes: 32 additions & 0 deletions src/test/run-pass/enum-alias-access-variant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Checks that unit and tuple enum variants can be accessed through a type alias of the enum

enum Foo {
Unit,
Bar(i32),
}

type Alias = Foo;

impl Default for Foo {
fn default() -> Self {
Self::Unit
}
}

fn main() {
let t = Alias::Bar(0);
match t {
Alias::Unit => {}
Alias::Bar(_i) => {}
}
}

0 comments on commit 140ab5a

Please sign in to comment.