Skip to content

Commit 50c87d0

Browse files
committed
---
yaml --- r: 90046 b: refs/heads/master c: 6ff697d h: refs/heads/master v: v3
1 parent da1238b commit 50c87d0

File tree

6 files changed

+72
-100
lines changed

6 files changed

+72
-100
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 720bcd81de9d5fbdb60761fc929d40e487005722
2+
refs/heads/master: 6ff697d3933754bf9ec5ee5875f487f02a7d087d
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d3e57dca68fde4effdda3e4ae2887aa535fcd6
55
refs/heads/try: b160761e35efcd1207112b3b782c06633cf441a8

trunk/src/etc/extract-tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#[ allow(unused_variable) ];\n
6464
#[ allow(dead_assignment) ];\n
6565
#[ allow(unused_mut) ];\n
66+
#[ allow(attribute_usage) ];\n
6667
#[ feature(macro_rules, globs, struct_variant, managed_boxes) ];\n
6768
""" + block
6869
if xfail:

trunk/src/librustc/middle/lint.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub enum lint {
7676
type_overflow,
7777
unused_unsafe,
7878
unsafe_block,
79+
attribute_usage,
7980

8081
managed_heap_memory,
8182
owned_heap_memory,
@@ -244,6 +245,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
244245
default: allow
245246
}),
246247

248+
("attribute_usage",
249+
LintSpec {
250+
lint: attribute_usage,
251+
desc: "detects bad use of attributes",
252+
default: warn
253+
}),
254+
247255
("unused_variable",
248256
LintSpec {
249257
lint: unused_variable,
@@ -790,6 +798,27 @@ fn check_heap_item(cx: &Context, it: &ast::item) {
790798
}
791799
}
792800

801+
// check if crate-level attribute is used on item,
802+
// since it is usually caused by mistake of semicolon omission.
803+
// also make error on obsolete attributes for less confusion.
804+
fn check_item_attribute_usage(cx: &Context, it: &ast::item) {
805+
let crate_attrs = ["crate_type", "link", "feature", "no_uv", "no_main", "no_std"];
806+
807+
for attr in it.attrs.iter() {
808+
let name = attr.node.value.name();
809+
for crate_attr in crate_attrs.iter() {
810+
if name.equiv(crate_attr) {
811+
let msg = match attr.node.style {
812+
ast::AttrOuter => "crate-level attribute should be an inner attribute: \
813+
add semicolon at end",
814+
ast::AttrInner => "crate-level attribute should be in the root module",
815+
};
816+
cx.span_lint(attribute_usage, attr.span, msg);
817+
}
818+
}
819+
}
820+
}
821+
793822
fn check_heap_expr(cx: &Context, e: &ast::Expr) {
794823
let ty = ty::expr_ty(cx.tcx, e);
795824
check_heap_type(cx, e.span, ty);
@@ -1110,6 +1139,7 @@ impl<'self> Visitor<()> for Context<'self> {
11101139
check_item_non_uppercase_statics(cx, it);
11111140
check_heap_item(cx, it);
11121141
check_missing_doc_item(cx, it);
1142+
check_item_attribute_usage(cx, it);
11131143

11141144
do cx.visit_ids |v| {
11151145
v.visit_item(it, ());

trunk/src/librustc/middle/trans/adt.rs

Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -366,41 +366,22 @@ pub fn ty_of_inttype(ity: IntType) -> ty::t {
366366

367367

368368
/**
369-
* LLVM-level types are a little complicated.
370-
*
371-
* C-like enums need to be actual ints, not wrapped in a struct,
372-
* because that changes the ABI on some platforms (see issue #10308).
373-
*
374-
* For nominal types, in some cases, we need to use LLVM named structs
375-
* and fill in the actual contents in a second pass to prevent
376-
* unbounded recursion; see also the comments in `trans::type_of`.
369+
* Returns the fields of a struct for the given representation.
370+
* All nominal types are LLVM structs, in order to be able to use
371+
* forward-declared opaque types to prevent circularity in `type_of`.
377372
*/
378-
pub fn type_of(cx: &mut CrateContext, r: &Repr) -> Type {
379-
generic_type_of(cx, r, None, false)
380-
}
381-
pub fn sizing_type_of(cx: &mut CrateContext, r: &Repr) -> Type {
382-
generic_type_of(cx, r, None, true)
373+
pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] {
374+
generic_fields_of(cx, r, false)
383375
}
384-
pub fn incomplete_type_of(cx: &mut CrateContext, r: &Repr, name: &str) -> Type {
385-
generic_type_of(cx, r, Some(name), false)
386-
}
387-
pub fn finish_type_of(cx: &mut CrateContext, r: &Repr, llty: &mut Type) {
388-
match *r {
389-
CEnum(*) | General(*) => { }
390-
Univariant(ref st, _) | NullablePointer{ nonnull: ref st, _ } =>
391-
llty.set_struct_body(struct_llfields(cx, st, false), st.packed)
392-
}
376+
/// Like `fields_of`, but for `type_of::sizing_type_of` (q.v.).
377+
pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] {
378+
generic_fields_of(cx, r, true)
393379
}
394-
395-
fn generic_type_of(cx: &mut CrateContext, r: &Repr, name: Option<&str>, sizing: bool) -> Type {
380+
fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] {
396381
match *r {
397-
CEnum(ity, _, _) => ll_inttype(cx, ity),
398-
Univariant(ref st, _) | NullablePointer{ nonnull: ref st, _ } => {
399-
match name {
400-
None => Type::struct_(struct_llfields(cx, st, sizing), st.packed),
401-
Some(name) => { assert_eq!(sizing, false); Type::named_struct(name) }
402-
}
403-
}
382+
CEnum(ity, _, _) => ~[ll_inttype(cx, ity)],
383+
Univariant(ref st, _dtor) => struct_llfields(cx, st, sizing),
384+
NullablePointer{ nonnull: ref st, _ } => struct_llfields(cx, st, sizing),
404385
General(ity, ref sts) => {
405386
// We need a representation that has:
406387
// * The alignment of the most-aligned field
@@ -413,7 +394,8 @@ fn generic_type_of(cx: &mut CrateContext, r: &Repr, name: Option<&str>, sizing:
413394
// more of its own type, then use alignment-sized ints to get the rest
414395
// of the size.
415396
//
416-
// FIXME #10604: this breaks when vector types are present.
397+
// Note: if/when we start exposing SIMD vector types (or f80, on some
398+
// platforms that have it), this will need some adjustment.
417399
let size = sts.iter().map(|st| st.size).max().unwrap();
418400
let most_aligned = sts.iter().max_by(|st| st.align).unwrap();
419401
let align = most_aligned.align;
@@ -429,17 +411,9 @@ fn generic_type_of(cx: &mut CrateContext, r: &Repr, name: Option<&str>, sizing:
429411
assert_eq!(machine::llalign_of_min(cx, pad_ty) as u64, align);
430412
let align_units = (size + align - 1) / align;
431413
assert_eq!(align % discr_size, 0);
432-
let fields = ~[discr_ty,
414+
~[discr_ty,
433415
Type::array(&discr_ty, align / discr_size - 1),
434-
Type::array(&pad_ty, align_units - 1)];
435-
match name {
436-
None => Type::struct_(fields, false),
437-
Some(name) => {
438-
let mut llty = Type::named_struct(name);
439-
llty.set_struct_body(fields, false);
440-
llty
441-
}
442-
}
416+
Type::array(&pad_ty, align_units - 1)]
443417
}
444418
}
445419
}
@@ -486,8 +460,7 @@ pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef, cast_to:
486460
signed = ity.is_signed();
487461
}
488462
General(ity, ref cases) => {
489-
let ptr = GEPi(bcx, scrutinee, [0, 0]);
490-
val = load_discr(bcx, ity, ptr, 0, (cases.len() - 1) as Disr);
463+
val = load_discr(bcx, ity, scrutinee, 0, (cases.len() - 1) as Disr);
491464
signed = ity.is_signed();
492465
}
493466
Univariant(*) => {
@@ -514,8 +487,9 @@ fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: Disr, ptrfield:
514487
}
515488

516489
/// Helper for cases where the discriminant is simply loaded.
517-
fn load_discr(bcx: @mut Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
490+
fn load_discr(bcx: @mut Block, ity: IntType, scrutinee: ValueRef, min: Disr, max: Disr)
518491
-> ValueRef {
492+
let ptr = GEPi(bcx, scrutinee, [0, 0]);
519493
let llty = ll_inttype(bcx.ccx(), ity);
520494
assert_eq!(val_ty(ptr), llty.ptr_to());
521495
let bits = machine::llbitsize_of_real(bcx.ccx(), llty);
@@ -572,7 +546,7 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: Disr) {
572546
CEnum(ity, min, max) => {
573547
assert_discr_in_range(ity, min, max, discr);
574548
Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true),
575-
val)
549+
GEPi(bcx, val, [0, 0]))
576550
}
577551
General(ity, _) => {
578552
Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true),

trunk/src/librustc/middle/trans/type_of.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,18 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type {
147147

148148
ty::ty_tup(*) | ty::ty_enum(*) => {
149149
let repr = adt::represent_type(cx, t);
150-
adt::sizing_type_of(cx, repr)
150+
Type::struct_(adt::sizing_fields_of(cx, repr), false)
151151
}
152152

153-
ty::ty_struct(*) => {
153+
ty::ty_struct(did, _) => {
154154
if ty::type_is_simd(cx.tcx, t) {
155155
let et = ty::simd_type(cx.tcx, t);
156156
let n = ty::simd_size(cx.tcx, t);
157157
Type::vector(&type_of(cx, et), n as u64)
158158
} else {
159159
let repr = adt::represent_type(cx, t);
160-
adt::sizing_type_of(cx, repr)
160+
let packed = ty::lookup_packed(cx.tcx, did);
161+
Type::struct_(adt::sizing_fields_of(cx, repr), packed)
161162
}
162163
}
163164

@@ -216,9 +217,8 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
216217
// fill it in *after* placing it into the type cache. This
217218
// avoids creating more than one copy of the enum when one
218219
// of the enum's variants refers to the enum itself.
219-
let repr = adt::represent_type(cx, t);
220-
let name = llvm_type_name(cx, an_enum, did, substs.tps);
221-
adt::incomplete_type_of(cx, repr, name)
220+
221+
Type::named_struct(llvm_type_name(cx, an_enum, did, substs.tps))
222222
}
223223
ty::ty_estr(ty::vstore_box) => {
224224
Type::box(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to()
@@ -287,7 +287,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
287287
ty::ty_type => cx.tydesc_type.ptr_to(),
288288
ty::ty_tup(*) => {
289289
let repr = adt::represent_type(cx, t);
290-
adt::type_of(cx, repr)
290+
Type::struct_(adt::fields_of(cx, repr), false)
291291
}
292292
ty::ty_opaque_closure_ptr(_) => Type::opaque_box(cx).ptr_to(),
293293
ty::ty_struct(did, ref substs) => {
@@ -299,9 +299,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
299299
// Only create the named struct, but don't fill it in. We fill it
300300
// in *after* placing it into the type cache. This prevents
301301
// infinite recursion with recursive struct types.
302-
let repr = adt::represent_type(cx, t);
303-
let name = llvm_type_name(cx, a_struct, did, substs.tps);
304-
adt::incomplete_type_of(cx, repr, name)
302+
Type::named_struct(llvm_type_name(cx, a_struct, did, substs.tps))
305303
}
306304
}
307305
ty::ty_self(*) => cx.tcx.sess.unimpl("type_of: ty_self"),
@@ -318,11 +316,19 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
318316

319317
// If this was an enum or struct, fill in the type now.
320318
match ty::get(t).sty {
321-
ty::ty_enum(*) | ty::ty_struct(*) if !ty::type_is_simd(cx.tcx, t) => {
322-
let repr = adt::represent_type(cx, t);
323-
adt::finish_type_of(cx, repr, &mut llty);
319+
ty::ty_enum(*) => {
320+
let repr = adt::represent_type(cx, t);
321+
llty.set_struct_body(adt::fields_of(cx, repr), false);
322+
}
323+
324+
ty::ty_struct(did, _) => {
325+
if !ty::type_is_simd(cx.tcx, t) {
326+
let repr = adt::represent_type(cx, t);
327+
let packed = ty::lookup_packed(cx.tcx, did);
328+
llty.set_struct_body(adt::fields_of(cx, repr), packed);
324329
}
325-
_ => ()
330+
}
331+
_ => ()
326332
}
327333

328334
return llty;

trunk/src/test/run-pass/enum-clike-ffi-as-int.rs

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)