Skip to content

Commit

Permalink
Extend lang items to assert correct target.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
davidtwco committed Oct 11, 2018
1 parent a534216 commit 2ecce7c
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 2ecce7c

Please sign in to comment.