Skip to content

Commit

Permalink
Auto merge of #54997 - davidtwco:issue-54896, r=nagisa
Browse files Browse the repository at this point in the history
The #[panic_handler] attribute can be applied to non-functions

Fixes #54896.

This commit extends the existing lang items functionality to assert
that the `#[lang_item]` attribute is only found on the appropriate item
for any given lang item. That is, language items representing traits
must only ever have their corresponding attribute placed on a trait, for
example.

r? @nagisa
  • Loading branch information
bors committed Oct 13, 2018
2 parents 2d81989 + 2ecce7c commit 24faa97
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 162 deletions.
18 changes: 16 additions & 2 deletions src/librustc/diagnostics.rs
Expand Up @@ -637,8 +637,8 @@ Erroneous code example:
```compile_fail,E0152
#![feature(lang_items)]
#[lang = "panic_impl"]
struct Foo; // error: duplicate lang item found: `panic_impl`
#[lang = "arc"]
struct Foo; // error: duplicate lang item found: `arc`
```
Lang items are already implemented in the standard library. Unless you are
Expand Down Expand Up @@ -2116,6 +2116,20 @@ struct Foo;
```
"##,

E0718: r##"
This error indicates that a `#[lang = ".."]` attribute was placed
on the wrong type of item.
Examples of erroneous code:
```compile_fail,E0718
#![feature(lang_items)]
#[lang = "arc"]
static X: u32 = 42;
```
"##,

}


Expand Down
74 changes: 57 additions & 17 deletions src/librustc/hir/check_attr.rs
Expand Up @@ -14,40 +14,80 @@
//! conflicts between multiple such attributes attached to the same
//! item.

use syntax_pos::Span;
use ty::TyCtxt;

use hir;
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use ty::TyCtxt;
use std::fmt::{self, Display};
use syntax_pos::Span;

#[derive(Copy, Clone, PartialEq)]
enum Target {
pub(crate) enum Target {
ExternCrate,
Use,
Static,
Const,
Fn,
Closure,
Mod,
ForeignMod,
GlobalAsm,
Ty,
Existential,
Enum,
Struct,
Union,
Enum,
Const,
ForeignMod,
Trait,
TraitAlias,
Impl,
Expression,
Statement,
Closure,
Static,
Trait,
Other,
}

impl Display for Target {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", match *self {
Target::ExternCrate => "extern crate",
Target::Use => "use",
Target::Static => "static item",
Target::Const => "constant item",
Target::Fn => "function",
Target::Closure => "closure",
Target::Mod => "module",
Target::ForeignMod => "foreign module",
Target::GlobalAsm => "global asm",
Target::Ty => "type alias",
Target::Existential => "existential type",
Target::Enum => "enum",
Target::Struct => "struct",
Target::Union => "union",
Target::Trait => "trait",
Target::TraitAlias => "trait alias",
Target::Impl => "item",
Target::Expression => "expression",
Target::Statement => "statement",
})
}
}

impl Target {
fn from_item(item: &hir::Item) -> Target {
pub(crate) fn from_item(item: &hir::Item) -> Target {
match item.node {
hir::ItemKind::ExternCrate(..) => Target::ExternCrate,
hir::ItemKind::Use(..) => Target::Use,
hir::ItemKind::Static(..) => Target::Static,
hir::ItemKind::Const(..) => Target::Const,
hir::ItemKind::Fn(..) => Target::Fn,
hir::ItemKind::Mod(..) => Target::Mod,
hir::ItemKind::ForeignMod(..) => Target::ForeignMod,
hir::ItemKind::GlobalAsm(..) => Target::GlobalAsm,
hir::ItemKind::Ty(..) => Target::Ty,
hir::ItemKind::Existential(..) => Target::Existential,
hir::ItemKind::Enum(..) => Target::Enum,
hir::ItemKind::Struct(..) => Target::Struct,
hir::ItemKind::Union(..) => Target::Union,
hir::ItemKind::Enum(..) => Target::Enum,
hir::ItemKind::Const(..) => Target::Const,
hir::ItemKind::ForeignMod(..) => Target::ForeignMod,
hir::ItemKind::Static(..) => Target::Static,
hir::ItemKind::Trait(..) => Target::Trait,
_ => Target::Other,
hir::ItemKind::TraitAlias(..) => Target::TraitAlias,
hir::ItemKind::Impl(..) => Target::Impl,
}
}
}
Expand Down
304 changes: 164 additions & 140 deletions src/librustc/middle/lang_items.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0152.rs
Expand Up @@ -10,7 +10,7 @@

#![feature(lang_items)]

#[lang = "panic_impl"]
#[lang = "arc"]
struct Foo; //~ ERROR E0152

fn main() {
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/error-codes/E0152.stderr
@@ -1,10 +1,10 @@
error[E0152]: duplicate lang item found: `panic_impl`.
error[E0152]: duplicate lang item found: `arc`.
--> $DIR/E0152.rs:14:1
|
LL | struct Foo; //~ ERROR E0152
| ^^^^^^^^^^^
|
= note: first defined in crate `std`.
= note: first defined in crate `alloc`.

error: aborting due to previous error

Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/error-codes/E0718.rs
@@ -0,0 +1,17 @@
// Copyright 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.

#![feature(lang_items)]

// Arc is expected to be a struct, so this will error.
#[lang = "arc"]
static X: u32 = 42;

fn main() {}
9 changes: 9 additions & 0 deletions src/test/ui/error-codes/E0718.stderr
@@ -0,0 +1,9 @@
error[E0718]: `arc` language item must be applied to a struct
--> $DIR/E0718.rs:14:1
|
LL | #[lang = "arc"]
| ^^^^^^^^^^^^^^^ attribute should be applied to a struct, not a static item

error: aborting due to previous error

For more information about this error, try `rustc --explain E0718`.
18 changes: 18 additions & 0 deletions src/test/ui/panic-handler/panic-handler-wrong-location.rs
@@ -0,0 +1,18 @@
// Copyright 2018 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.

// compile-flags:-C panic=abort

#![no_std]
#![no_main]

#[panic_handler]
#[no_mangle]
static X: u32 = 42;
11 changes: 11 additions & 0 deletions src/test/ui/panic-handler/panic-handler-wrong-location.stderr
@@ -0,0 +1,11 @@
error[E0718]: `panic_impl` language item must be applied to a function
--> $DIR/panic-handler-wrong-location.rs:16:1
|
LL | #[panic_handler]
| ^^^^^^^^^^^^^^^^ attribute should be applied to a function, not a static item

error: `#[panic_handler]` function required, but not found

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0718`.

0 comments on commit 24faa97

Please sign in to comment.