librustc: Fix merge fallout.

This commit is contained in:
Patrick Walton 2013-09-18 18:18:45 -07:00
parent 90d3da9711
commit 3b1d3e5bf8
6 changed files with 244 additions and 168 deletions

View File

@ -30,31 +30,40 @@ pub mod rustrt {
macro_rules! locked { macro_rules! locked {
($expr:expr) => { ($expr:expr) => {
// FIXME #9105: can't use a static mutex in pure Rust yet. {
rustrt::rust_take_linenoise_lock(); // FIXME #9105: can't use a static mutex in pure Rust yet.
let x = $expr; rustrt::rust_take_linenoise_lock();
rustrt::rust_drop_linenoise_lock(); let x = $expr;
x rustrt::rust_drop_linenoise_lock();
x
}
} }
} }
/// Add a line to history /// Add a line to history
pub fn add_history(line: &str) -> bool { pub fn add_history(line: &str) -> bool {
do line.with_c_str |buf| { do line.with_c_str |buf| {
(locked!(rustrt::linenoiseHistoryAdd(buf))) == 1 as c_int unsafe {
(locked!(rustrt::linenoiseHistoryAdd(buf))) == 1 as c_int
}
} }
} }
/// Set the maximum amount of lines stored /// Set the maximum amount of lines stored
pub fn set_history_max_len(len: int) -> bool { pub fn set_history_max_len(len: int) -> bool {
(locked!(rustrt::linenoiseHistorySetMaxLen(len as c_int))) == 1 as c_int unsafe {
(locked!(rustrt::linenoiseHistorySetMaxLen(len as c_int))) == 1
as c_int
}
} }
/// Save line history to a file /// Save line history to a file
pub fn save_history(file: &str) -> bool { pub fn save_history(file: &str) -> bool {
do file.with_c_str |buf| { do file.with_c_str |buf| {
// 0 on success, -1 on failure // 0 on success, -1 on failure
(locked!(rustrt::linenoiseHistorySave(buf))) == 0 as c_int unsafe {
(locked!(rustrt::linenoiseHistorySave(buf))) == 0 as c_int
}
} }
} }
@ -62,14 +71,18 @@ pub fn save_history(file: &str) -> bool {
pub fn load_history(file: &str) -> bool { pub fn load_history(file: &str) -> bool {
do file.with_c_str |buf| { do file.with_c_str |buf| {
// 0 on success, -1 on failure // 0 on success, -1 on failure
(locked!(rustrt::linenoiseHistoryLoad(buf))) == 0 as c_int unsafe {
(locked!(rustrt::linenoiseHistoryLoad(buf))) == 0 as c_int
}
} }
} }
/// Print out a prompt and then wait for input and return it /// Print out a prompt and then wait for input and return it
pub fn read(prompt: &str) -> Option<~str> { pub fn read(prompt: &str) -> Option<~str> {
do prompt.with_c_str |buf| { do prompt.with_c_str |buf| {
let line = locked!(rustrt::linenoise(buf)); let line = unsafe {
locked!(rustrt::linenoise(buf))
};
if line.is_null() { None } if line.is_null() { None }
else { else {

View File

@ -1086,6 +1086,36 @@ fn pointer_type_metadata(cx: &mut CrateContext,
return ptr_metadata; return ptr_metadata;
} }
trait MemberDescriptionFactory {
fn create_member_descriptions(&self, cx: &mut CrateContext)
-> ~[MemberDescription];
}
struct StructMemberDescriptionFactory {
fields: ~[ty::field],
span: Span,
}
impl MemberDescriptionFactory for StructMemberDescriptionFactory {
fn create_member_descriptions(&self, cx: &mut CrateContext)
-> ~[MemberDescription] {
do self.fields.map |field| {
let name = if field.ident.name == special_idents::unnamed_field.name {
@""
} else {
token::ident_to_str(&field.ident)
};
MemberDescription {
name: name,
llvm_type: type_of::type_of(cx, field.mt.ty),
type_metadata: type_metadata(cx, field.mt.ty, self.span),
offset: ComputedMemberOffset,
}
}
}
}
fn prepare_struct_metadata(cx: &mut CrateContext, fn prepare_struct_metadata(cx: &mut CrateContext,
struct_type: ty::t, struct_type: ty::t,
def_id: ast::DefId, def_id: ast::DefId,
@ -1114,22 +1144,10 @@ fn prepare_struct_metadata(cx: &mut CrateContext,
metadata_stub: struct_metadata_stub, metadata_stub: struct_metadata_stub,
llvm_type: struct_llvm_type, llvm_type: struct_llvm_type,
file_metadata: file_metadata, file_metadata: file_metadata,
member_description_factory: |cx| { member_description_factory: @StructMemberDescriptionFactory {
do fields.map |field| { fields: fields,
let name = if field.ident.name == special_idents::unnamed_field.name { span: span,
@"" } as @MemberDescriptionFactory,
} else {
token::ident_to_str(&field.ident)
};
MemberDescription {
name: name,
llvm_type: type_of::type_of(cx, field.mt.ty),
type_metadata: type_metadata(cx, field.mt.ty, span),
offset: ComputedMemberOffset,
}
}
}
} }
} }
@ -1139,7 +1157,7 @@ enum RecursiveTypeDescription {
metadata_stub: DICompositeType, metadata_stub: DICompositeType,
llvm_type: Type, llvm_type: Type,
file_metadata: DIFile, file_metadata: DIFile,
member_description_factory: @fn(cx: &mut CrateContext) -> ~[MemberDescription], member_description_factory: @MemberDescriptionFactory,
}, },
FinalMetadata(DICompositeType) FinalMetadata(DICompositeType)
} }
@ -1167,7 +1185,8 @@ impl RecursiveTypeDescription {
debug_context(cx).created_types.insert(cache_id, metadata_stub); debug_context(cx).created_types.insert(cache_id, metadata_stub);
// ... then create the member descriptions ... // ... then create the member descriptions ...
let member_descriptions = member_description_factory(cx); let member_descriptions = member_description_factory.
create_member_descriptions(cx);
// ... and attach them to the stub to complete it. // ... and attach them to the stub to complete it.
set_members_of_composite_type(cx, set_members_of_composite_type(cx,
@ -1182,6 +1201,25 @@ impl RecursiveTypeDescription {
} }
} }
struct TupleMemberDescriptionFactory {
component_types: ~[ty::t],
span: Span,
}
impl MemberDescriptionFactory for TupleMemberDescriptionFactory {
fn create_member_descriptions(&self, cx: &mut CrateContext)
-> ~[MemberDescription] {
do self.component_types.map |&component_type| {
MemberDescription {
name: @"",
llvm_type: type_of::type_of(cx, component_type),
type_metadata: type_metadata(cx, component_type, self.span),
offset: ComputedMemberOffset,
}
}
}
}
fn prepare_tuple_metadata(cx: &mut CrateContext, fn prepare_tuple_metadata(cx: &mut CrateContext,
tuple_type: ty::t, tuple_type: ty::t,
component_types: &[ty::t], component_types: &[ty::t],
@ -1192,8 +1230,6 @@ fn prepare_tuple_metadata(cx: &mut CrateContext,
let loc = span_start(cx, span); let loc = span_start(cx, span);
let file_metadata = file_metadata(cx, loc.file.name); let file_metadata = file_metadata(cx, loc.file.name);
// Needs to be copied for closure below :(
let component_types = component_types.to_owned();
UnfinishedMetadata { UnfinishedMetadata {
cache_id: cache_id_for_type(tuple_type), cache_id: cache_id_for_type(tuple_type),
@ -1205,17 +1241,147 @@ fn prepare_tuple_metadata(cx: &mut CrateContext,
span), span),
llvm_type: tuple_llvm_type, llvm_type: tuple_llvm_type,
file_metadata: file_metadata, file_metadata: file_metadata,
member_description_factory: |cx| { member_description_factory: @TupleMemberDescriptionFactory {
do component_types.map |&component_type| { component_types: component_types.to_owned(),
span: span,
} as @MemberDescriptionFactory
}
}
struct GeneralMemberDescriptionFactory {
type_rep: @adt::Repr,
variants: @~[@ty::VariantInfo],
discriminant_type_metadata: ValueRef,
containing_scope: DIScope,
file_metadata: DIFile,
span: Span,
}
impl MemberDescriptionFactory for GeneralMemberDescriptionFactory {
fn create_member_descriptions(&self, cx: &mut CrateContext)
-> ~[MemberDescription] {
// Capture type_rep, so we don't have to copy the struct_defs array
let struct_defs = match *self.type_rep {
adt::General(ref struct_defs) => struct_defs,
_ => cx.sess.bug("unreachable")
};
do struct_defs
.iter()
.enumerate()
.map |(i, struct_def)| {
let (variant_type_metadata, variant_llvm_type, member_desc_factory) =
describe_variant(cx,
struct_def,
self.variants[i],
Some(self.discriminant_type_metadata),
self.containing_scope,
self.file_metadata,
self.span);
let member_descriptions =
member_desc_factory.create_member_descriptions(cx);
set_members_of_composite_type(cx,
variant_type_metadata,
variant_llvm_type,
member_descriptions,
self.file_metadata,
codemap::dummy_sp());
MemberDescription { MemberDescription {
name: @"", name: @"",
llvm_type: type_of::type_of(cx, component_type), llvm_type: variant_llvm_type,
type_metadata: type_metadata(cx, component_type, span), type_metadata: variant_type_metadata,
offset: ComputedMemberOffset, offset: FixedMemberOffset { bytes: 0 },
} }
}.collect()
}
}
struct EnumVariantMemberDescriptionFactory {
args: ~[(@str, ty::t)],
discriminant_type_metadata: Option<DIType>,
span: Span,
}
impl MemberDescriptionFactory for EnumVariantMemberDescriptionFactory {
fn create_member_descriptions(&self, cx: &mut CrateContext)
-> ~[MemberDescription] {
do self.args.iter().enumerate().map |(i, &(name, ty))| {
MemberDescription {
name: name,
llvm_type: type_of::type_of(cx, ty),
type_metadata: match self.discriminant_type_metadata {
Some(metadata) if i == 0 => metadata,
_ => type_metadata(cx, ty, self.span)
},
offset: ComputedMemberOffset,
}
}.collect()
}
}
fn describe_variant(cx: &mut CrateContext,
struct_def: &adt::Struct,
variant_info: &ty::VariantInfo,
discriminant_type_metadata: Option<DIType>,
containing_scope: DIScope,
file_metadata: DIFile,
span: Span)
-> (DICompositeType, Type, @MemberDescriptionFactory) {
let variant_name = token::ident_to_str(&variant_info.name);
let variant_llvm_type = Type::struct_(struct_def.fields.map(|&t| type_of::type_of(cx, t)),
struct_def.packed);
// Could some consistency checks here: size, align, field count, discr type
// Find the source code location of the variant's definition
let variant_definition_span = if variant_info.id.crate == ast::LOCAL_CRATE {
match cx.tcx.items.find(&variant_info.id.node) {
Some(&ast_map::node_variant(ref variant, _, _)) => variant.span,
ref node => {
cx.sess.span_warn(span,
fmt!("debuginfo::enum_metadata()::adt_struct_metadata() - Unexpected node \
type: %?. This is a bug.", node));
codemap::dummy_sp()
} }
} }
} else {
// For definitions from other crates we have no location information available.
codemap::dummy_sp()
};
let metadata_stub = create_struct_stub(cx,
variant_llvm_type,
variant_name,
containing_scope,
file_metadata,
variant_definition_span);
// Get the argument names from the enum variant info
let mut arg_names = match variant_info.arg_names {
Some(ref names) => do names.map |ident| { token::ident_to_str(ident) },
None => do variant_info.args.map |_| { @"" }
};
// If this is not a univariant enum, there is also the (unnamed) discriminant field
if discriminant_type_metadata.is_some() {
arg_names.insert(0, @"");
} }
// Build an array of (field name, field type) pairs to be captured in the factory closure.
let args: ~[(@str, ty::t)] = arg_names.iter()
.zip(struct_def.fields.iter())
.map(|(&s, &t)| (s, t))
.collect();
let member_description_factory =
@EnumVariantMemberDescriptionFactory {
args: args,
discriminant_type_metadata: discriminant_type_metadata,
span: span,
} as @MemberDescriptionFactory;
(metadata_stub, variant_llvm_type, member_description_factory)
} }
fn prepare_enum_metadata(cx: &mut CrateContext, fn prepare_enum_metadata(cx: &mut CrateContext,
@ -1336,42 +1502,14 @@ fn prepare_enum_metadata(cx: &mut CrateContext,
metadata_stub: enum_metadata, metadata_stub: enum_metadata,
llvm_type: enum_llvm_type, llvm_type: enum_llvm_type,
file_metadata: file_metadata, file_metadata: file_metadata,
member_description_factory: |cx| { member_description_factory: @GeneralMemberDescriptionFactory {
// Capture type_rep, so we don't have to copy the struct_defs array type_rep: type_rep,
let struct_defs = match *type_rep { variants: variants,
adt::General(ref struct_defs) => struct_defs, discriminant_type_metadata: discriminant_type_metadata,
_ => cx.sess.bug("unreachable") containing_scope: containing_scope,
}; file_metadata: file_metadata,
span: span,
do struct_defs } as @MemberDescriptionFactory,
.iter()
.enumerate()
.map |(i, struct_def)| {
let (variant_type_metadata, variant_llvm_type, member_desc_factory) =
describe_variant(cx,
struct_def,
variants[i],
Some(discriminant_type_metadata),
containing_scope,
file_metadata,
span);
let member_descriptions = member_desc_factory(cx);
set_members_of_composite_type(cx,
variant_type_metadata,
variant_llvm_type,
member_descriptions,
file_metadata,
codemap::dummy_sp());
MemberDescription {
name: @"",
llvm_type: variant_llvm_type,
type_metadata: variant_type_metadata,
offset: FixedMemberOffset { bytes: 0 },
}
}.collect()
}
} }
} }
adt::NullablePointer { nonnull: ref struct_def, nndiscr, _ } => { adt::NullablePointer { nonnull: ref struct_def, nndiscr, _ } => {
@ -1393,76 +1531,6 @@ fn prepare_enum_metadata(cx: &mut CrateContext,
} }
} }
}; };
fn describe_variant(cx: &mut CrateContext,
struct_def: &adt::Struct,
variant_info: &ty::VariantInfo,
discriminant_type_metadata: Option<DIType>,
containing_scope: DIScope,
file_metadata: DIFile,
span: Span)
-> (DICompositeType, Type, @fn(&mut CrateContext) -> ~[MemberDescription]) {
let variant_name = token::ident_to_str(&variant_info.name);
let variant_llvm_type = Type::struct_(struct_def.fields.map(|&t| type_of::type_of(cx, t)),
struct_def.packed);
// Could some consistency checks here: size, align, field count, discr type
// Find the source code location of the variant's definition
let variant_definition_span = if variant_info.id.crate == ast::LOCAL_CRATE {
match cx.tcx.items.find(&variant_info.id.node) {
Some(&ast_map::node_variant(ref variant, _, _)) => variant.span,
ref node => {
cx.sess.span_warn(span,
fmt!("debuginfo::enum_metadata()::adt_struct_metadata() - Unexpected node \
type: %?. This is a bug.", node));
codemap::dummy_sp()
}
}
} else {
// For definitions from other crates we have no location information available.
codemap::dummy_sp()
};
let metadata_stub = create_struct_stub(cx,
variant_llvm_type,
variant_name,
containing_scope,
file_metadata,
variant_definition_span);
// Get the argument names from the enum variant info
let mut arg_names = match variant_info.arg_names {
Some(ref names) => do names.map |ident| { token::ident_to_str(ident) },
None => do variant_info.args.map |_| { @"" }
};
// If this is not a univariant enum, there is also the (unnamed) discriminant field
if discriminant_type_metadata.is_some() {
arg_names.insert(0, @"");
}
// Build an array of (field name, field type) pairs to be captured in the factory closure.
let args: ~[(@str, ty::t)] = arg_names.iter()
.zip(struct_def.fields.iter())
.map(|(&s, &t)| (s, t))
.collect();
let member_description_factory: @fn(cx: &mut CrateContext) -> ~[MemberDescription] = |cx| {
do args.iter().enumerate().map |(i, &(name, ty))| {
MemberDescription {
name: name,
llvm_type: type_of::type_of(cx, ty),
type_metadata: match discriminant_type_metadata {
Some(metadata) if i == 0 => metadata,
_ => type_metadata(cx, ty, span)
},
offset: ComputedMemberOffset,
}
}.collect()
};
(metadata_stub, variant_llvm_type, member_description_factory)
}
} }
enum MemberOffset { enum MemberOffset {

View File

@ -1565,8 +1565,11 @@ fn test_linker_build() {
let matches = getopts([], optgroups()); let matches = getopts([], optgroups());
let options = build_session_options(@"rustpkg", let options = build_session_options(@"rustpkg",
matches.get_ref(), matches.get_ref(),
diagnostic::emit); @diagnostic::DefaultEmitter as
let sess = build_session(options, diagnostic::emit); @diagnostic::Emitter);
let sess = build_session(options,
@diagnostic::DefaultEmitter as
@diagnostic::Emitter);
command_line_test([test_sysroot().to_str(), command_line_test([test_sysroot().to_str(),
~"install", ~"install",
~"--linker", ~"--linker",

View File

@ -869,7 +869,7 @@ struct Duplicator {
} }
impl fold::ast_fold for Duplicator { impl fold::ast_fold for Duplicator {
fn new_id(&self, _: NodeId) -> NodeId { fn new_id(&self, _: NodeId) -> NodeId {
ast::DUMMY_NODE_ID ast::DUMMY_NODE_ID
} }
} }

View File

@ -30,20 +30,4 @@ impl Foo {
} }
} }
/*
#2074 duplicate symbols with enum in boxed closure
*/
fn foo() {
let one: @fn() -> uint = || {
enum r { a }
a as uint
};
let two: @fn() -> uint = || {
enum r { a }
a as uint
};
one(); two();
}
fn main() {} fn main() {}

View File

@ -22,6 +22,20 @@ use extra::rl;
static HISTORY_FILE: &'static str = "rl-human-test-history.txt"; static HISTORY_FILE: &'static str = "rl-human-test-history.txt";
struct TestCompleter;
impl rl::CompletionCb for TestCompleter {
fn complete(&self, line: ~str, suggest: &fn(~str)) {
if line.is_empty() {
suggest(~"empty")
} else {
for c in line.rev_iter().take(3) {
suggest(format!("{0}{1}{1}{1}", line, c))
}
}
}
}
fn main() { fn main() {
// don't run this in robot mode, but still typecheck it. // don't run this in robot mode, but still typecheck it.
if !cfg!(robot_mode) { if !cfg!(robot_mode) {
@ -42,14 +56,8 @@ The bool return values of each step are printed.",
println!("restricting history length: {}", rl::set_history_max_len(3)); println!("restricting history length: {}", rl::set_history_max_len(3));
do rl::complete |line, suggest| { unsafe {
if line.is_empty() { rl::complete(@TestCompleter as @rl::CompletionCb);
suggest(~"empty")
} else {
for c in line.rev_iter().take(3) {
suggest(format!("{0}{1}{1}{1}", line, c))
}
}
} }
println!("adding 'one': {}", rl::add_history("one")); println!("adding 'one': {}", rl::add_history("one"));