Skip to content

Add E0517, E0518 for repr() errors #29716

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

Merged
merged 1 commit into from
Nov 22, 2015
Merged
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
73 changes: 73 additions & 0 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2039,6 +2039,79 @@ It is not possible to use stability attributes outside of the standard library.
Also, for now, it is not possible to write deprecation messages either.
"##,

E0517: r##"
This error indicates that a `#[repr(..)]` attribute was placed on an unsupported
item.

Examples of erroneous code:

```
#[repr(C)]
type Foo = u8;

#[repr(packed)]
enum Foo {Bar, Baz}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh whoah. Curly brace enums without field names.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ enums always have curly braces?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Man, how tired was I?

I though this was enum Foo { Foo { Bar, Baz } }


#[repr(u8)]
struct Foo {bar: bool, baz: bool}

#[repr(C)]
impl Foo {
...
}
```

- The `#[repr(C)]` attribute can only be placed on structs and enums
- The `#[repr(packed)]` and `#[repr(simd)]` attributes only work on structs
- The `#[repr(u8)]`, `#[repr(i16)]`, etc attributes only work on enums

These attributes do not work on typedefs, since typedefs are just aliases.

Representations like `#[repr(u8)]`, `#[repr(i64)]` are for selecting the
discriminant size for C-like enums (when there is no associated data, e.g. `enum
Color {Red, Blue, Green}`), effectively setting the size of the enum to the size
of the provided type. Such an enum can be cast to a value of the same type as
well. In short, `#[repr(u8)]` makes the enum behave like an integer with a
constrained set of allowed values.

Only C-like enums can be cast to numerical primitives, so this attribute will
not apply to structs.

`#[repr(packed)]` reduces padding to make the struct size smaller. The
representation of enums isn't strictly defined in Rust, and this attribute won't
work on enums.

`#[repr(simd)]` will give a struct consisting of a homogenous series of machine
types (i.e. `u8`, `i32`, etc) a representation that permits vectorization via
SIMD. This doesn't make much sense for enums since they don't consist of a
single list of data.
"##,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc all repr(simd) does is alignment := size. But yeah, just isn't really a coherent thing to care about with enums.


E0518: r##"
This error indicates that an `#[inline(..)]` attribute was incorrectly placed on
something other than a function or method.

Examples of erroneous code:

```
#[inline(always)]
struct Foo;

#[inline(never)]
impl Foo {
...
}
```

`#[inline]` hints the compiler whether or not to attempt to inline a method or
function. By default, the compiler does a pretty good job of figuring this out
itself, but if you feel the need for annotations, `#[inline(always)]` and
`#[inline(never)]` can override or force the compiler's decision.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also causes the function's AST to be serialized in the rlib so that it can be inline'd cross-crate (unnecessary for generic code). Possibly unimportant for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unimportant, both this and the above simd thing are internal implementation details, not necessary for diagnostics


If you wish to apply this attribute to all methods in an impl, manually annotate
each method; it is not possible to annotate the entire impl with an `#[inline]`
attribute.
"##,
}


Expand Down
29 changes: 14 additions & 15 deletions src/librustc/front/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ struct CheckAttrVisitor<'a> {
impl<'a> CheckAttrVisitor<'a> {
fn check_inline(&self, attr: &ast::Attribute, target: Target) {
if target != Target::Fn {
self.sess.span_err(
attr.span,
"attribute should be applied to function");
span_err!(self.sess, attr.span, E0518, "attribute should be applied to function");
}
}

Expand All @@ -56,33 +54,34 @@ impl<'a> CheckAttrVisitor<'a> {
};
for word in words {
let word: &str = &word.name();
match word {
let message = match word {
"C" => {
if target != Target::Struct && target != Target::Enum {
self.sess.span_err(
attr.span,
"attribute should be applied to struct or enum");
"attribute should be applied to struct or enum"
} else {
continue
}
}
"packed" |
"simd" => {
if target != Target::Struct {
self.sess.span_err(
attr.span,
"attribute should be applied to struct");
"attribute should be applied to struct"
} else {
continue
}
}
"i8" | "u8" | "i16" | "u16" |
"i32" | "u32" | "i64" | "u64" |
"isize" | "usize" => {
if target != Target::Enum {
self.sess.span_err(
attr.span,
"attribute should be applied to enum");
"attribute should be applied to enum"
} else {
continue
}
}
_ => (),
}
_ => continue,
};
span_err!(self.sess, attr.span, E0517, "{}", message);
}
}

Expand Down