Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow enum discriminants to not be uint, and use smallest possible size by default. #9006

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
};
let config = &mut config;
let cmds = props.debugger_cmds.connect("\n");
let check_lines = props.check_lines.clone();
let check_lines = &props.check_lines;

// compile test file (it shoud have 'compile-flags:-g' in the header)
let mut ProcRes = compile_test(config, props, testfile);
Expand Down Expand Up @@ -305,11 +305,34 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {

let num_check_lines = check_lines.len();
if num_check_lines > 0 {
// Allow check lines to leave parts unspecified (e.g., uninitialized
// bits in the wrong case of an enum) with the notation "[...]".
let check_fragments: ~[~[&str]] = check_lines.map(|s| s.split_str_iter("[...]").collect());
// check if each line in props.check_lines appears in the
// output (in order)
let mut i = 0u;
for line in ProcRes.stdout.line_iter() {
if check_lines[i].trim() == line.trim() {
let mut rest = line.trim();
let mut first = true;
let mut failed = false;
for &frag in check_fragments[i].iter() {
let found = if first {
if rest.starts_with(frag) { Some(0) } else { None }
} else {
rest.find_str(frag)
};
match found {
None => {
failed = true;
break;
}
Some(i) => {
rest = rest.slice_from(i + frag.len());
}
}
first = false;
}
if !failed && rest.len() == 0 {
i += 1u;
}
if i == num_check_lines {
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/enum_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ mod test {

use enum_set::*;

#[deriving(Eq)]
#[deriving(Eq)] #[repr(uint)]
enum Foo {
A, B, C
}
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ pub static Vector: TypeKind = 13;
pub static Metadata: TypeKind = 14;
pub static X86_MMX: TypeKind = 15;

#[repr(C)]
pub enum AtomicBinOp {
Xchg = 0,
Add = 1,
Expand All @@ -159,6 +160,7 @@ pub enum AtomicBinOp {
UMin = 10,
}

#[repr(C)]
pub enum AtomicOrdering {
NotAtomic = 0,
Unordered = 1,
Expand All @@ -171,6 +173,7 @@ pub enum AtomicOrdering {
}

// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
#[repr(C)]
pub enum FileType {
AssemblyFile = 0,
ObjectFile = 1
Expand All @@ -192,20 +195,23 @@ pub enum AsmDialect {
}

#[deriving(Eq)]
#[repr(C)]
pub enum CodeGenOptLevel {
CodeGenLevelNone = 0,
CodeGenLevelLess = 1,
CodeGenLevelDefault = 2,
CodeGenLevelAggressive = 3,
}

#[repr(C)]
pub enum RelocMode {
RelocDefault = 0,
RelocStatic = 1,
RelocPIC = 2,
RelocDynamicNoPic = 3,
}

#[repr(C)]
pub enum CodeGenModel {
CodeModelDefault = 0,
CodeModelJITDefault = 1,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub static tag_items_data_item_reexport_def_id: uint = 0x4e;
pub static tag_items_data_item_reexport_name: uint = 0x4f;

// used to encode crate_ctxt side tables
#[deriving(Eq)]
#[deriving(Eq)] #[repr(uint)]
pub enum astencode_tag { // Reserves 0x50 -- 0x6f
tag_ast = 0x50,

Expand Down Expand Up @@ -143,7 +143,7 @@ impl astencode_tag {
pub fn from_uint(value : uint) -> Option<astencode_tag> {
let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;
if !is_a_tag { None } else {
Some(unsafe { cast::transmute(value as int) })
Some(unsafe { cast::transmute(value) })
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_family(ebml_w, 't');
encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
encode_name(ecx, ebml_w, item.ident);
encode_attributes(ebml_w, item.attrs);
for v in (*enum_definition).variants.iter() {
encode_variant_id(ebml_w, local_def(v.node.id));
}
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@


use driver::session;
use middle::trans::adt; // for `adt::is_ffi_safe`
use middle::ty;
use middle::pat_util;
use metadata::csearch;
Expand Down Expand Up @@ -900,6 +901,14 @@ fn check_item_ctypes(cx: &Context, it: &ast::item) {
"found rust type `uint` in foreign module, while \
libc::c_uint or libc::c_ulong should be used");
}
ast::DefTy(def_id) => {
if !adt::is_ffi_safe(cx.tcx, def_id) {
cx.span_lint(ctypes, ty.span,
"found enum type without foreign-function-safe \
representation annotation in foreign module");
// NOTE this message could be more helpful
}
}
_ => ()
}
}
Expand Down
Loading