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.
This commit is contained in:
parent
67100ddb35
commit
704cd648ac
@ -178,12 +178,14 @@ fn is_test_fn(i: @ast::item) -> bool {
|
||||
|
||||
fn has_test_signature(i: @ast::item) -> bool {
|
||||
match &i.node {
|
||||
&ast::item_fn(ref decl, _, ref tps, _) => {
|
||||
&ast::item_fn(ref decl, _, ref generics, _) => {
|
||||
let no_output = match decl.output.node {
|
||||
ast::ty_nil => true,
|
||||
_ => false
|
||||
};
|
||||
decl.inputs.is_empty() && no_output && tps.is_empty()
|
||||
decl.inputs.is_empty()
|
||||
&& no_output
|
||||
&& !generics.is_parameterized()
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
|
@ -228,14 +228,16 @@ fn encode_type(ecx: @EncodeContext, ebml_w: writer::Encoder, typ: ty::t) {
|
||||
|
||||
fn encode_symbol(ecx: @EncodeContext, ebml_w: writer::Encoder, id: node_id) {
|
||||
ebml_w.start_tag(tag_items_data_item_symbol);
|
||||
let sym = match ecx.item_symbols.find(&id) {
|
||||
Some(ref x) => (/*bad*/copy *x),
|
||||
None => {
|
||||
ecx.diag.handler().bug(
|
||||
fmt!("encode_symbol: id not found %d", id));
|
||||
}
|
||||
};
|
||||
ebml_w.writer.write(str::to_bytes(sym));
|
||||
match ecx.item_symbols.find(&id) {
|
||||
Some(ref x) => {
|
||||
debug!("encode_symbol(id=%?, str=%s)", id, *x);
|
||||
ebml_w.writer.write(str::to_bytes(*x));
|
||||
}
|
||||
None => {
|
||||
ecx.diag.handler().bug(
|
||||
fmt!("encode_symbol: id not found %d", id));
|
||||
}
|
||||
}
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
@ -264,6 +266,8 @@ fn encode_enum_variant_info(ecx: @EncodeContext, ebml_w: writer::Encoder,
|
||||
path: &[ast_map::path_elt],
|
||||
index: @mut ~[entry<int>],
|
||||
generics: &ast::Generics) {
|
||||
debug!("encode_enum_variant_info(id=%?)", id);
|
||||
|
||||
let mut disr_val = 0;
|
||||
let mut i = 0;
|
||||
let vi = ty::enum_variants(ecx.tcx,
|
||||
|
@ -2079,7 +2079,7 @@ pub fn trans_item(ccx: @CrateContext, item: ast::item) {
|
||||
_ => fail!(~"trans_item"),
|
||||
};
|
||||
match /*bad*/copy item.node {
|
||||
ast::item_fn(ref decl, purity, ref tps, ref body) => {
|
||||
ast::item_fn(ref decl, purity, ref generics, ref body) => {
|
||||
if purity == ast::extern_fn {
|
||||
let llfndecl = get_item_val(ccx, item.id);
|
||||
foreign::trans_foreign_fn(ccx,
|
||||
@ -2087,7 +2087,7 @@ pub fn trans_item(ccx: @CrateContext, item: ast::item) {
|
||||
/*bad*/copy *path,
|
||||
~[path_name(item.ident)]),
|
||||
decl, body, llfndecl, item.id);
|
||||
} else if tps.is_empty() {
|
||||
} else if !generics.is_type_parameterized() {
|
||||
let llfndecl = get_item_val(ccx, item.id);
|
||||
trans_fn(ccx,
|
||||
vec::append(/*bad*/copy *path, ~[path_name(item.ident)]),
|
||||
@ -2111,8 +2111,8 @@ pub fn trans_item(ccx: @CrateContext, item: ast::item) {
|
||||
ast::item_mod(ref m) => {
|
||||
trans_mod(ccx, m);
|
||||
}
|
||||
ast::item_enum(ref enum_definition, ref tps) => {
|
||||
if tps.is_empty() {
|
||||
ast::item_enum(ref enum_definition, ref generics) => {
|
||||
if !generics.is_type_parameterized() {
|
||||
let degen = (*enum_definition).variants.len() == 1u;
|
||||
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
|
||||
let mut i = 0;
|
||||
@ -2128,8 +2128,8 @@ pub fn trans_item(ccx: @CrateContext, item: ast::item) {
|
||||
};
|
||||
foreign::trans_foreign_mod(ccx, foreign_mod, abi);
|
||||
}
|
||||
ast::item_struct(struct_def, tps) => {
|
||||
if tps.is_empty() {
|
||||
ast::item_struct(struct_def, generics) => {
|
||||
if !generics.is_type_parameterized() {
|
||||
trans_struct_def(ccx, struct_def, path, item.id);
|
||||
}
|
||||
}
|
||||
|
@ -861,7 +861,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item)
|
||||
// like "foo<X>". This is because otherwise ty_to_str will
|
||||
// print the name as merely "foo", as it has no way to
|
||||
// reconstruct the value of X.
|
||||
if !generics.is_empty() { t0 } else {
|
||||
if generics.is_parameterized() { t0 } else {
|
||||
ty::mk_with_id(tcx, t0, def_id)
|
||||
}
|
||||
};
|
||||
|
@ -315,7 +315,7 @@ fn check_main_fn_ty(ccx: @mut CrateCtxt,
|
||||
Some(ast_map::node_item(it,_)) => {
|
||||
match it.node {
|
||||
ast::item_fn(_, _, ref ps, _)
|
||||
if !ps.is_empty() => {
|
||||
if ps.is_parameterized() => {
|
||||
tcx.sess.span_err(
|
||||
main_span,
|
||||
~"main function is not allowed \
|
||||
|
@ -161,8 +161,14 @@ pub struct Generics {
|
||||
}
|
||||
|
||||
pub impl Generics {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.lifetimes.len() + self.ty_params.len() == 0
|
||||
fn is_parameterized(&self) -> bool {
|
||||
self.lifetimes.len() + self.ty_params.len() > 0
|
||||
}
|
||||
fn is_lt_parameterized(&self) -> bool {
|
||||
self.lifetimes.len() > 0
|
||||
}
|
||||
fn is_type_parameterized(&self) -> bool {
|
||||
self.ty_params.len() > 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,7 +567,7 @@ pub fn print_item(s: @ps, &&item: @ast::item) {
|
||||
|
||||
ast::item_impl(ref generics, opt_trait, ty, ref methods) => {
|
||||
head(s, visibility_qualified(item.vis, ~"impl"));
|
||||
if !generics.is_empty() {
|
||||
if generics.is_parameterized() {
|
||||
print_generics(s, generics);
|
||||
space(s.s);
|
||||
}
|
||||
|
23
src/test/run-pass/issue-5243.rs
Normal file
23
src/test/run-pass/issue-5243.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2012-2013 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.
|
||||
|
||||
// Check that merely have lifetime parameters is not
|
||||
// enough for trans to consider this as non-monomorphic,
|
||||
// which led to various assertions and failures in turn.
|
||||
|
||||
struct S<'self> {
|
||||
v: &'self int
|
||||
}
|
||||
|
||||
fn f<'lt>(_s: &S<'lt>) {}
|
||||
|
||||
fn main() {
|
||||
f(& S { v: &42 });
|
||||
}
|
Loading…
Reference in New Issue
Block a user