Skip to content

Commit d2e2bd1

Browse files
committed
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`?
2 parents da83ad8 + 086c949 commit d2e2bd1

File tree

5 files changed

+92
-16
lines changed

5 files changed

+92
-16
lines changed

src/librustc/metadata/decoder.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -683,14 +683,22 @@ pub fn get_enum_variants<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::Nod
683683
let ctor_ty = item_type(ast::DefId { krate: cdata.cnum, node: id},
684684
item, tcx, cdata);
685685
let name = item_name(&*intr, item);
686-
let (ctor_ty, arg_tys) = match ctor_ty.sty {
686+
let (ctor_ty, arg_tys, arg_names) = match ctor_ty.sty {
687687
ty::ty_bare_fn(ref f) =>
688-
(Some(ctor_ty), f.sig.inputs.clone()),
689-
_ => // Nullary or struct enum variant.
690-
(None, get_struct_fields(intr.clone(), cdata, did.node)
688+
(Some(ctor_ty), f.sig.inputs.clone(), None),
689+
_ => { // Nullary or struct enum variant.
690+
let mut arg_names = Vec::new();
691+
let arg_tys = get_struct_fields(intr.clone(), cdata, did.node)
691692
.iter()
692-
.map(|field_ty| get_type(cdata, field_ty.id.node, tcx).ty)
693-
.collect())
693+
.map(|field_ty| {
694+
arg_names.push(ast::Ident::new(field_ty.name));
695+
get_type(cdata, field_ty.id.node, tcx).ty
696+
})
697+
.collect();
698+
let arg_names = if arg_names.len() == 0 { None } else { Some(arg_names) };
699+
700+
(None, arg_tys, arg_names)
701+
}
694702
};
695703
match variant_disr_val(item) {
696704
Some(val) => { disr_val = val; }
@@ -700,7 +708,7 @@ pub fn get_enum_variants<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::Nod
700708
disr_val += 1;
701709
Rc::new(ty::VariantInfo {
702710
args: arg_tys,
703-
arg_names: None,
711+
arg_names: arg_names,
704712
ctor_ty: ctor_ty,
705713
name: name,
706714
// I'm not even sure if we encode visibility

src/librustc/middle/borrowck/fragments.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,10 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
346346
Rc<LoanPath<'tcx>>)>) {
347347
let parent_ty = parent_lp.to_type();
348348

349-
let add_fragment_sibling_local = |field_name| {
349+
let add_fragment_sibling_local = |field_name, variant_did| {
350350
add_fragment_sibling_core(
351-
this, tcx, gathered_fragments, parent_lp.clone(), mc, field_name, origin_lp);
351+
this, tcx, gathered_fragments, parent_lp.clone(), mc, field_name, origin_lp,
352+
variant_did);
352353
};
353354

354355
match (&parent_ty.sty, enum_variant_info) {
@@ -363,7 +364,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
363364
for i in range(0, tuple_len) {
364365
if i == tuple_idx { continue }
365366
let field_name = mc::PositionalField(i);
366-
add_fragment_sibling_local(field_name);
367+
add_fragment_sibling_local(field_name, None);
367368
}
368369
}
369370

@@ -376,7 +377,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
376377
continue;
377378
}
378379
let field_name = mc::NamedField(f.name);
379-
add_fragment_sibling_local(field_name);
380+
add_fragment_sibling_local(field_name, None);
380381
}
381382
}
382383
mc::PositionalField(tuple_idx) => {
@@ -385,7 +386,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
385386
continue
386387
}
387388
let field_name = mc::PositionalField(i);
388-
add_fragment_sibling_local(field_name);
389+
add_fragment_sibling_local(field_name, None);
389390
}
390391
}
391392
}
@@ -414,7 +415,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
414415
continue;
415416
}
416417
let field_name = mc::NamedField(variant_arg_ident.name);
417-
add_fragment_sibling_local(field_name);
418+
add_fragment_sibling_local(field_name, Some(variant_info.id));
418419
}
419420
}
420421
mc::PositionalField(tuple_idx) => {
@@ -424,7 +425,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
424425
continue;
425426
}
426427
let field_name = mc::PositionalField(i);
427-
add_fragment_sibling_local(field_name);
428+
add_fragment_sibling_local(field_name, None);
428429
}
429430
}
430431
}
@@ -447,10 +448,11 @@ fn add_fragment_sibling_core<'tcx>(this: &MoveData<'tcx>,
447448
parent: Rc<LoanPath<'tcx>>,
448449
mc: mc::MutabilityCategory,
449450
new_field_name: mc::FieldName,
450-
origin_lp: &Rc<LoanPath<'tcx>>) -> MovePathIndex {
451+
origin_lp: &Rc<LoanPath<'tcx>>,
452+
enum_variant_did: Option<ast::DefId>) -> MovePathIndex {
451453
let opt_variant_did = match parent.kind {
452454
LpDowncast(_, variant_did) => Some(variant_did),
453-
LpVar(..) | LpUpvar(..) | LpExtend(..) => None,
455+
LpVar(..) | LpUpvar(..) | LpExtend(..) => enum_variant_did,
454456
};
455457

456458
let loan_path_elem = LpInterior(mc::InteriorField(new_field_name));

src/test/auxiliary/issue-19340-1.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 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+
pub enum Homura {
12+
Madoka { name: String },
13+
}

src/test/run-pass/issue-19340-1.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2014 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+
// aux-build:issue-19340-1.rs
12+
13+
extern crate "issue-19340-1" as lib;
14+
15+
use lib::Homura;
16+
17+
fn main() {
18+
let homura = Homura::Madoka { name: "Kaname".into_string() };
19+
20+
match homura {
21+
Homura::Madoka { name } => (),
22+
};
23+
}

src/test/run-pass/issue-19340-2.rs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2014 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+
enum Homura {
12+
Madoka {
13+
name: String,
14+
age: u32,
15+
},
16+
}
17+
18+
fn main() {
19+
let homura = Homura::Madoka {
20+
name: "Akemi".into_string(),
21+
age: 14,
22+
};
23+
24+
match homura {
25+
Homura::Madoka {
26+
name,
27+
age,
28+
} => (),
29+
};
30+
}

0 commit comments

Comments
 (0)