Skip to content

Commit

Permalink
Allow access to struct variants of an enum through a type alias of th…
Browse files Browse the repository at this point in the history
…e enum
  • Loading branch information
jseyfried committed Jan 25, 2016
1 parent 140ab5a commit 6729479
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 59 deletions.
23 changes: 0 additions & 23 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,29 +714,6 @@ match Something::NotFoo {
```
"##,

E0422: r##"
You are trying to use an identifier that is either undefined or not a
struct. For instance:
```
fn main () {
let x = Foo { x: 1, y: 2 };
}
```
In this case, `Foo` is undefined, so it inherently isn't anything, and
definitely not a struct.
```
fn main () {
let foo = 1;
let x = foo { x: 1, y: 2 };
}
```
In this case, `foo` is defined, but is not a struct, so Rust can't use
it as one.
"##,

E0423: r##"
A `struct` variant name was used like a function name. Example of
erroneous code:
Expand Down
37 changes: 8 additions & 29 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,6 @@ pub enum ResolutionError<'a> {
NotAnAssociatedConst(&'a str),
/// error E0421: unresolved associated const
UnresolvedAssociatedConst(&'a str),
/// error E0422: does not name a struct
DoesNotNameAStruct(&'a str),
/// error E0423: is a struct variant name, but this expression uses it like a function name
StructVariantUsedAsFunction(&'a str),
/// error E0424: `self` is not available in a static method
Expand Down Expand Up @@ -412,13 +410,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
"unresolved associated const `{}`",
name)
}
ResolutionError::DoesNotNameAStruct(name) => {
struct_span_err!(resolver.session,
span,
E0422,
"`{}` does not name a structure",
name)
}
ResolutionError::StructVariantUsedAsFunction(path_name) => {
struct_span_err!(resolver.session,
span,
Expand Down Expand Up @@ -2862,18 +2853,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}

PatStruct(ref path, _, _) => {
match self.resolve_path(pat_id, path, 0, TypeNS, false) {
Some(definition) => {
match self.resolve_possibly_assoc_item(pat_id, None, path, TypeNS, false) {
ResolveAttempt(Some(definition)) => {
self.record_def(pattern.id, definition);
}
result => {
debug!("(resolving pattern) didn't find struct def: {:?}", result);
resolve_error(
self,
path.span,
ResolutionError::DoesNotNameAStruct(
&*path_names_to_string(path, 0))
);
_ => {
self.resolve_path(pat_id, path, 0, TypeNS, false);
self.record_def(pattern.id, err_path_resolution());
}
}
Expand Down Expand Up @@ -3665,16 +3650,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Resolve the path to the structure it goes to. We don't
// check to ensure that the path is actually a structure; that
// is checked later during typeck.
match self.resolve_path(expr.id, path, 0, TypeNS, false) {
Some(definition) => self.record_def(expr.id, definition),
None => {
debug!("(resolving expression) didn't find struct def",);

resolve_error(self,
path.span,
ResolutionError::DoesNotNameAStruct(
&*path_names_to_string(path, 0))
);
match self.resolve_possibly_assoc_item(expr.id, None, path, TypeNS, false) {
ResolveAttempt(Some(definition)) => self.record_def(expr.id, definition),
_ => {
self.resolve_path(expr.id, path, 0, TypeNS, false);
self.record_def(expr.id, err_path_resolution());
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,12 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat,
let fcx = pcx.fcx;
let tcx = pcx.fcx.ccx.tcx;

let def = tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
let path_res = *tcx.def_map.borrow().get(&pat.id).unwrap();
let def = match resolve_ty_and_def_ufcs(fcx, path_res, None, path, pat.span, pat.id) {
Some((_, _, def)) => def,
None => Def::Err,
};

let variant = match fcx.def_struct_variant(def, path.span) {
Some((_, variant)) => variant,
None => {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3166,11 +3166,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
let tcx = fcx.tcx();

// Find the relevant variant
let def = lookup_full_def(tcx, path.span, expr.id);
if def == Def::Err {
check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
return;
}
let path_res = *tcx.def_map.borrow().get(&expr.id).unwrap();
let def = match resolve_ty_and_def_ufcs(fcx, path_res, None, path, expr.span, expr.id) {
Some((_, _, def)) => def,
None => Def::Err,
};
let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
Some((adt, variant)) => (adt, variant),
None => {
Expand Down
6 changes: 5 additions & 1 deletion src/test/run-pass/enum-alias-access-variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
enum Foo {
Unit,
Bar(i32),
Baz { i: i32 },
}

type Alias = Foo;
Expand All @@ -24,9 +25,12 @@ impl Default for Foo {
}

fn main() {
let t = Alias::Bar(0);
let _t = Alias::Bar(0);
let t = Alias::Baz { i: 0 };

match t {
Alias::Unit => {}
Alias::Bar(_i) => {}
Alias::Baz { i: _i } => {}
}
}

0 comments on commit 6729479

Please sign in to comment.