Item

From Rust Community Wiki
Jump to navigation Jump to search

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[edit | edit source]

Example[edit | edit source]

// 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[edit | edit source]

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[edit | edit source]

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[edit | edit source]

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[edit | edit source]