Skip to content

Commit 704cd64

Browse files
committed
Fix a bug with region-parameterized enums etc where trans considered
them to be non-monomorphic. Merely having lifetime parameters is not enough to qualify for that status. Fixes #5243.
1 parent 67100dd commit 704cd64

File tree

8 files changed

+56
-21
lines changed

8 files changed

+56
-21
lines changed

src/librustc/front/test.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,14 @@ fn is_test_fn(i: @ast::item) -> bool {
178178

179179
fn has_test_signature(i: @ast::item) -> bool {
180180
match &i.node {
181-
&ast::item_fn(ref decl, _, ref tps, _) => {
181+
&ast::item_fn(ref decl, _, ref generics, _) => {
182182
let no_output = match decl.output.node {
183183
ast::ty_nil => true,
184184
_ => false
185185
};
186-
decl.inputs.is_empty() && no_output && tps.is_empty()
186+
decl.inputs.is_empty()
187+
&& no_output
188+
&& !generics.is_parameterized()
187189
}
188190
_ => false
189191
}

src/librustc/metadata/encoder.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,16 @@ fn encode_type(ecx: @EncodeContext, ebml_w: writer::Encoder, typ: ty::t) {
228228

229229
fn encode_symbol(ecx: @EncodeContext, ebml_w: writer::Encoder, id: node_id) {
230230
ebml_w.start_tag(tag_items_data_item_symbol);
231-
let sym = match ecx.item_symbols.find(&id) {
232-
Some(ref x) => (/*bad*/copy *x),
233-
None => {
234-
ecx.diag.handler().bug(
235-
fmt!("encode_symbol: id not found %d", id));
236-
}
237-
};
238-
ebml_w.writer.write(str::to_bytes(sym));
231+
match ecx.item_symbols.find(&id) {
232+
Some(ref x) => {
233+
debug!("encode_symbol(id=%?, str=%s)", id, *x);
234+
ebml_w.writer.write(str::to_bytes(*x));
235+
}
236+
None => {
237+
ecx.diag.handler().bug(
238+
fmt!("encode_symbol: id not found %d", id));
239+
}
240+
}
239241
ebml_w.end_tag();
240242
}
241243

@@ -264,6 +266,8 @@ fn encode_enum_variant_info(ecx: @EncodeContext, ebml_w: writer::Encoder,
264266
path: &[ast_map::path_elt],
265267
index: @mut ~[entry<int>],
266268
generics: &ast::Generics) {
269+
debug!("encode_enum_variant_info(id=%?)", id);
270+
267271
let mut disr_val = 0;
268272
let mut i = 0;
269273
let vi = ty::enum_variants(ecx.tcx,

src/librustc/middle/trans/base.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,15 +2079,15 @@ pub fn trans_item(ccx: @CrateContext, item: ast::item) {
20792079
_ => fail!(~"trans_item"),
20802080
};
20812081
match /*bad*/copy item.node {
2082-
ast::item_fn(ref decl, purity, ref tps, ref body) => {
2082+
ast::item_fn(ref decl, purity, ref generics, ref body) => {
20832083
if purity == ast::extern_fn {
20842084
let llfndecl = get_item_val(ccx, item.id);
20852085
foreign::trans_foreign_fn(ccx,
20862086
vec::append(
20872087
/*bad*/copy *path,
20882088
~[path_name(item.ident)]),
20892089
decl, body, llfndecl, item.id);
2090-
} else if tps.is_empty() {
2090+
} else if !generics.is_type_parameterized() {
20912091
let llfndecl = get_item_val(ccx, item.id);
20922092
trans_fn(ccx,
20932093
vec::append(/*bad*/copy *path, ~[path_name(item.ident)]),
@@ -2111,8 +2111,8 @@ pub fn trans_item(ccx: @CrateContext, item: ast::item) {
21112111
ast::item_mod(ref m) => {
21122112
trans_mod(ccx, m);
21132113
}
2114-
ast::item_enum(ref enum_definition, ref tps) => {
2115-
if tps.is_empty() {
2114+
ast::item_enum(ref enum_definition, ref generics) => {
2115+
if !generics.is_type_parameterized() {
21162116
let degen = (*enum_definition).variants.len() == 1u;
21172117
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
21182118
let mut i = 0;
@@ -2128,8 +2128,8 @@ pub fn trans_item(ccx: @CrateContext, item: ast::item) {
21282128
};
21292129
foreign::trans_foreign_mod(ccx, foreign_mod, abi);
21302130
}
2131-
ast::item_struct(struct_def, tps) => {
2132-
if tps.is_empty() {
2131+
ast::item_struct(struct_def, generics) => {
2132+
if !generics.is_type_parameterized() {
21332133
trans_struct_def(ccx, struct_def, path, item.id);
21342134
}
21352135
}

src/librustc/middle/typeck/collect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item)
861861
// like "foo<X>". This is because otherwise ty_to_str will
862862
// print the name as merely "foo", as it has no way to
863863
// reconstruct the value of X.
864-
if !generics.is_empty() { t0 } else {
864+
if generics.is_parameterized() { t0 } else {
865865
ty::mk_with_id(tcx, t0, def_id)
866866
}
867867
};

src/librustc/middle/typeck/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ fn check_main_fn_ty(ccx: @mut CrateCtxt,
315315
Some(ast_map::node_item(it,_)) => {
316316
match it.node {
317317
ast::item_fn(_, _, ref ps, _)
318-
if !ps.is_empty() => {
318+
if ps.is_parameterized() => {
319319
tcx.sess.span_err(
320320
main_span,
321321
~"main function is not allowed \

src/libsyntax/ast.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,14 @@ pub struct Generics {
161161
}
162162
163163
pub impl Generics {
164-
fn is_empty(&self) -> bool {
165-
self.lifetimes.len() + self.ty_params.len() == 0
164+
fn is_parameterized(&self) -> bool {
165+
self.lifetimes.len() + self.ty_params.len() > 0
166+
}
167+
fn is_lt_parameterized(&self) -> bool {
168+
self.lifetimes.len() > 0
169+
}
170+
fn is_type_parameterized(&self) -> bool {
171+
self.ty_params.len() > 0
166172
}
167173
}
168174

src/libsyntax/print/pprust.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ pub fn print_item(s: @ps, &&item: @ast::item) {
567567
568568
ast::item_impl(ref generics, opt_trait, ty, ref methods) => {
569569
head(s, visibility_qualified(item.vis, ~"impl"));
570-
if !generics.is_empty() {
570+
if generics.is_parameterized() {
571571
print_generics(s, generics);
572572
space(s.s);
573573
}

src/test/run-pass/issue-5243.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2012-2013 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+
// Check that merely have lifetime parameters is not
12+
// enough for trans to consider this as non-monomorphic,
13+
// which led to various assertions and failures in turn.
14+
15+
struct S<'self> {
16+
v: &'self int
17+
}
18+
19+
fn f<'lt>(_s: &S<'lt>) {}
20+
21+
fn main() {
22+
f(& S { v: &42 });
23+
}

0 commit comments

Comments
 (0)