Item

From Rust Community Wiki

See also: Reference – Items

An item is a syntax that is neither a statement nor an expression, and can appear in places where statements or expressions are illegal.

Different kinds of items

Example

// in the global scope, only items are allowed:

struct Struct;

const S: Struct = Struct;

mod inner {
    // in a module block, only items are allowed:

    pub trait Trait {
        type Assoc;
    }

    impl Trait for Struct {
        type Assoc = ();
    }
}

use inner::Trait;

macro_rules! foo {
    ($a:ident) => { $a };
}

fn main() {
    // within a function, statements and
    // expressions are allowed as well:
    foo!(S);
}


Where items can appear

Except for associated items, they can appear in any scope, including the global scope. Notably, they can appear within a function, for example:

enum Enum<T> {
    Foo(T),
    Bar,
}

fn main() {
    use Enum::*;
    type E = Enum<()>;
    
    impl Default for E {
        fn default() -> E { Bar }
    }
}


Associated items (i.e. associated functions, types and constants) must appear in a trait, an impl block or an extern block.

Lang items

Lang items are attributes on items that are treated special by the compiler.

For example, the BoxThis links to official Rust documentation type is special in that it allows moving a value out of the box by dereferencing it. The UnsafeCellThis links to official Rust documentation type is special, because it provides interior mutability. The Sized trait is special, because it is implemented automatically (even though it is not an auto trait), and cannot be implemented manually. Here's the full list of lang items.

Declaring lang items

This part is relevant if you want to create your own version of the core, alloc and/or std crates.

Lang items are a nightly-only feature and will never be stabilized. They're declared with the #[lang] attribute:

#![feature(no_core, lang_items)]
#![no_core]

#[lang = "sized"]
pub trait CustomSized {}

Lang items are defined in the Rust compiler. It is not possible to define new lang items in Rust.

Note that we used the experimental #![no_core] attribute to remove the core crate from our dependencies. Otherwise, there would be two sized lang items, but each lang item can only be declared once:

#![feature(lang_items)]

#[lang = "sized"]
pub trait CustomSized {}

error[E0152]: found duplicate lang item `sized` | 4 | pub trait CustomSized {} | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `core` (which `std` depends on) = note: first definition in `core` loaded from /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-1b9531b95148beca.rlib = note: second definition in the local crate (`playground`)

See also