about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-12-12 09:12:08 +0000
committerbors <bors@rust-lang.org>2014-12-12 09:12:08 +0000
commitd2e2bd1b442948d4754bb1eb09ff1914a83604dd (patch)
treee9dca85d4acf8fba54aa0753866591dff1645cdf /src
parentda83ad8e2c8e2c5f522dc59963e00f55b1f8c03b (diff)
parent086c9493c822e8de53bdb5ccf6b32d2e05c3963f (diff)
downloadrust-d2e2bd1b442948d4754bb1eb09ff1914a83604dd.tar.gz
rust-d2e2bd1b442948d4754bb1eb09ff1914a83604dd.zip
auto merge of #19568 : barosl/rust/enum-struct-variants-ice, r=alexcrichton
This pull request tries to fix #19340, which states two ICE cases related to enum struct variants.

It is my first attempt to fix the compiler. I found this solution by trial and error, so the method used to fix the issue looks very hacky. Please review it, and direct me to find a better solution.

I'm also to add test cases. Where should I put them? Maybe `src/test/run-pass/issue-19340.rs`?
Diffstat (limited to 'src')
-rw-r--r--src/librustc/metadata/decoder.rs22
-rw-r--r--src/librustc/middle/borrowck/fragments.rs20
-rw-r--r--src/test/auxiliary/issue-19340-1.rs13
-rw-r--r--src/test/run-pass/issue-19340-1.rs23
-rw-r--r--src/test/run-pass/issue-19340-2.rs30
5 files changed, 92 insertions, 16 deletions
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 0d51e044de9..232a0cc7f54 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -683,14 +683,22 @@ pub fn get_enum_variants<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::Nod
         let ctor_ty = item_type(ast::DefId { krate: cdata.cnum, node: id},
                                 item, tcx, cdata);
         let name = item_name(&*intr, item);
-        let (ctor_ty, arg_tys) = match ctor_ty.sty {
+        let (ctor_ty, arg_tys, arg_names) = match ctor_ty.sty {
             ty::ty_bare_fn(ref f) =>
-                (Some(ctor_ty), f.sig.inputs.clone()),
-            _ => // Nullary or struct enum variant.
-                (None, get_struct_fields(intr.clone(), cdata, did.node)
+                (Some(ctor_ty), f.sig.inputs.clone(), None),
+            _ => { // Nullary or struct enum variant.
+                let mut arg_names = Vec::new();
+                let arg_tys = get_struct_fields(intr.clone(), cdata, did.node)
                     .iter()
-                    .map(|field_ty| get_type(cdata, field_ty.id.node, tcx).ty)
-                    .collect())
+                    .map(|field_ty| {
+                        arg_names.push(ast::Ident::new(field_ty.name));
+                        get_type(cdata, field_ty.id.node, tcx).ty
+                    })
+                    .collect();
+                let arg_names = if arg_names.len() == 0 { None } else { Some(arg_names) };
+
+                (None, arg_tys, arg_names)
+            }
         };
         match variant_disr_val(item) {
             Some(val) => { disr_val = val; }
@@ -700,7 +708,7 @@ pub fn get_enum_variants<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::Nod
         disr_val += 1;
         Rc::new(ty::VariantInfo {
             args: arg_tys,
-            arg_names: None,
+            arg_names: arg_names,
             ctor_ty: ctor_ty,
             name: name,
             // I'm not even sure if we encode visibility
diff --git a/src/librustc/middle/borrowck/fragments.rs b/src/librustc/middle/borrowck/fragments.rs
index 5785972c484..056d4f9d732 100644
--- a/src/librustc/middle/borrowck/fragments.rs
+++ b/src/librustc/middle/borrowck/fragments.rs
@@ -346,9 +346,10 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
                                                                         Rc<LoanPath<'tcx>>)>) {
     let parent_ty = parent_lp.to_type();
 
-    let add_fragment_sibling_local = |field_name| {
+    let add_fragment_sibling_local = |field_name, variant_did| {
         add_fragment_sibling_core(
-            this, tcx, gathered_fragments, parent_lp.clone(), mc, field_name, origin_lp);
+            this, tcx, gathered_fragments, parent_lp.clone(), mc, field_name, origin_lp,
+            variant_did);
     };
 
     match (&parent_ty.sty, enum_variant_info) {
@@ -363,7 +364,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
             for i in range(0, tuple_len) {
                 if i == tuple_idx { continue }
                 let field_name = mc::PositionalField(i);
-                add_fragment_sibling_local(field_name);
+                add_fragment_sibling_local(field_name, None);
             }
         }
 
@@ -376,7 +377,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
                             continue;
                         }
                         let field_name = mc::NamedField(f.name);
-                        add_fragment_sibling_local(field_name);
+                        add_fragment_sibling_local(field_name, None);
                     }
                 }
                 mc::PositionalField(tuple_idx) => {
@@ -385,7 +386,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
                             continue
                         }
                         let field_name = mc::PositionalField(i);
-                        add_fragment_sibling_local(field_name);
+                        add_fragment_sibling_local(field_name, None);
                     }
                 }
             }
@@ -414,7 +415,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
                             continue;
                         }
                         let field_name = mc::NamedField(variant_arg_ident.name);
-                        add_fragment_sibling_local(field_name);
+                        add_fragment_sibling_local(field_name, Some(variant_info.id));
                     }
                 }
                 mc::PositionalField(tuple_idx) => {
@@ -424,7 +425,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
                             continue;
                         }
                         let field_name = mc::PositionalField(i);
-                        add_fragment_sibling_local(field_name);
+                        add_fragment_sibling_local(field_name, None);
                     }
                 }
             }
@@ -447,10 +448,11 @@ fn add_fragment_sibling_core<'tcx>(this: &MoveData<'tcx>,
                                    parent: Rc<LoanPath<'tcx>>,
                                    mc: mc::MutabilityCategory,
                                    new_field_name: mc::FieldName,
-                                   origin_lp: &Rc<LoanPath<'tcx>>) -> MovePathIndex {
+                                   origin_lp: &Rc<LoanPath<'tcx>>,
+                                   enum_variant_did: Option<ast::DefId>) -> MovePathIndex {
     let opt_variant_did = match parent.kind {
         LpDowncast(_, variant_did) => Some(variant_did),
-        LpVar(..) | LpUpvar(..) | LpExtend(..) => None,
+        LpVar(..) | LpUpvar(..) | LpExtend(..) => enum_variant_did,
     };
 
     let loan_path_elem = LpInterior(mc::InteriorField(new_field_name));
diff --git a/src/test/auxiliary/issue-19340-1.rs b/src/test/auxiliary/issue-19340-1.rs
new file mode 100644
index 00000000000..fc61b78d8a7
--- /dev/null
+++ b/src/test/auxiliary/issue-19340-1.rs
@@ -0,0 +1,13 @@
+// Copyright 2014 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.
+
+pub enum Homura {
+    Madoka { name: String },
+}
diff --git a/src/test/run-pass/issue-19340-1.rs b/src/test/run-pass/issue-19340-1.rs
new file mode 100644
index 00000000000..b7a6391ee04
--- /dev/null
+++ b/src/test/run-pass/issue-19340-1.rs
@@ -0,0 +1,23 @@
+// Copyright 2014 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.
+
+// aux-build:issue-19340-1.rs
+
+extern crate "issue-19340-1" as lib;
+
+use lib::Homura;
+
+fn main() {
+    let homura = Homura::Madoka { name: "Kaname".into_string() };
+
+    match homura {
+        Homura::Madoka { name } => (),
+    };
+}
diff --git a/src/test/run-pass/issue-19340-2.rs b/src/test/run-pass/issue-19340-2.rs
new file mode 100644
index 00000000000..5179c1e2acb
--- /dev/null
+++ b/src/test/run-pass/issue-19340-2.rs
@@ -0,0 +1,30 @@
+// Copyright 2014 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.
+
+enum Homura {
+    Madoka {
+        name: String,
+        age: u32,
+    },
+}
+
+fn main() {
+    let homura = Homura::Madoka {
+        name: "Akemi".into_string(),
+        age: 14,
+    };
+
+    match homura {
+        Homura::Madoka {
+            name,
+            age,
+        } => (),
+    };
+}