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`?
This commit is contained in:
commit
d2e2bd1b44
@ -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
|
||||
|
@ -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));
|
||||
|
13
src/test/auxiliary/issue-19340-1.rs
Normal file
13
src/test/auxiliary/issue-19340-1.rs
Normal file
@ -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 },
|
||||
}
|
23
src/test/run-pass/issue-19340-1.rs
Normal file
23
src/test/run-pass/issue-19340-1.rs
Normal file
@ -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 } => (),
|
||||
};
|
||||
}
|
30
src/test/run-pass/issue-19340-2.rs
Normal file
30
src/test/run-pass/issue-19340-2.rs
Normal file
@ -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,
|
||||
} => (),
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user