From bea6905b61e1df8d742e226b26a818cc2ec27af5 Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Tue, 1 Dec 2020 11:38:12 +0300 Subject: [PATCH 1/5] Document lang items --- src/SUMMARY.md | 1 + src/lang-items.md | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/lang-items.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 3f14c2642..5fa267601 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -81,6 +81,7 @@ - [Panic Implementation](./panic-implementation.md) - [AST Validation](./ast-validation.md) - [Feature Gate Checking](./feature-gate-ck.md) + - [Lang Items](./lang-items.md) - [The HIR (High-level IR)](./hir.md) - [Lowering AST to HIR](./lowering.md) - [Debugging](./hir-debugging.md) diff --git a/src/lang-items.md b/src/lang-items.md new file mode 100644 index 000000000..fb0fef00e --- /dev/null +++ b/src/lang-items.md @@ -0,0 +1,41 @@ +# Lang items + +The compiler has certain pluggable operations, that is, functionality that isn't hard-coded into +the language, but is implemented in libraries, with a special marker to tell the compiler it +exists. The marker is the attribute `#[lang = "..."]` and there are various different values of +`...`, i.e. various different 'lang items'. + +Many such lang items can be implemented only in one sensible way, such as `add` (`trait +core::ops::Add`) or `future_trait` (`trait core::future::Future`). Others can be overriden to +achieve some specific goals; for example, you can control your binary's entrypoint. + +Features provided by lang items include: + +- overloadable operators via traits: the traits corresponding to the + `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all + marked with lang items; those specific four are `eq`, `ord`, + `deref`, and `add` respectively. +- stack unwinding and general failure; the `eh_personality`, `panic` and + `panic_bounds_checks` lang items. +- the traits in `std::marker` used to indicate properties of types used by the compiler; + lang items `send`, `sync` and `copy`. +- the special marker types used for variance indicators found in + `core::marker`; lang item `phantom_data`. + +Lang items are loaded lazily by the compiler; e.g. if one never uses `Box` +then there is no need to define functions for `exchange_malloc` and +`box_free`. `rustc` will emit an error when an item is needed but not found +in the current crate or any that it depends on. + +Most lang items are defined by `libcore`, but if you're trying to build an +executable with `#![no_std]`, you'll run into the need for lang items. + +## List of all language items + +You can find language items in the following places: +- An exhaustive reference in the compiler documentation: [`rustc_hir::LangItem`] +- An auto-generated list with source locations by using ripgrep: `rg '#\[.*lang =' library/` + +Note that language items are explicitly unstable and may change in any new release. + +[`rustc_hir::LangItem`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/lang_items/enum.LangItem.html From 1082425c69433acea42197e57e3adf286d008f0c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 30 Apr 2021 09:34:42 -0400 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Camelid --- src/lang-items.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/lang-items.md b/src/lang-items.md index fb0fef00e..97b2d8cf9 100644 --- a/src/lang-items.md +++ b/src/lang-items.md @@ -1,8 +1,8 @@ # Lang items -The compiler has certain pluggable operations, that is, functionality that isn't hard-coded into +The compiler has certain pluggable operations; that is, functionality that isn't hard-coded into the language, but is implemented in libraries, with a special marker to tell the compiler it -exists. The marker is the attribute `#[lang = "..."]` and there are various different values of +exists. The marker is the attribute `#[lang = "..."]`, and there are various different values of `...`, i.e. various different 'lang items'. Many such lang items can be implemented only in one sensible way, such as `add` (`trait @@ -12,10 +12,10 @@ achieve some specific goals; for example, you can control your binary's entrypoi Features provided by lang items include: - overloadable operators via traits: the traits corresponding to the - `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all + `==`, `<`, dereference (`*`), `+`, etc. operators are all marked with lang items; those specific four are `eq`, `ord`, `deref`, and `add` respectively. -- stack unwinding and general failure; the `eh_personality`, `panic` and +- panicking and stack unwinding; the `eh_personality`, `panic` and `panic_bounds_checks` lang items. - the traits in `std::marker` used to indicate properties of types used by the compiler; lang items `send`, `sync` and `copy`. @@ -27,8 +27,9 @@ then there is no need to define functions for `exchange_malloc` and `box_free`. `rustc` will emit an error when an item is needed but not found in the current crate or any that it depends on. -Most lang items are defined by `libcore`, but if you're trying to build an -executable with `#![no_std]`, you'll run into the need for lang items. +Most lang items are defined by the `core` library, but if you're trying to build an +executable with `#![no_std]`, you'll still need to define a few lang items that are +usually provided by `std`. ## List of all language items From f70aea00df73a6568ca97492103128465b35d4c4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 30 Apr 2021 09:44:08 -0400 Subject: [PATCH 3/5] Add an example of retrieving lang items --- src/lang-items.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lang-items.md b/src/lang-items.md index 97b2d8cf9..2e36a6c48 100644 --- a/src/lang-items.md +++ b/src/lang-items.md @@ -31,6 +31,30 @@ Most lang items are defined by the `core` library, but if you're trying to build executable with `#![no_std]`, you'll still need to define a few lang items that are usually provided by `std`. +## Retrieving a language item + +You can retrieve lang items by calling [`tcx.lang_items()`]. + +Here's a small example of retrieving the `trait Sized {}` language item: + +```rust +// Note that in case of `#![no_core]`, the trait is not available. +if let Some(sized_trait_def_id) = tcx.lang_items().sized_trait() { + // do something with `sized_trait_def_id` +} +``` + +Note that `sized_trait()` returns an `Option`, not the `DefId` itself. +That's because language items are defined in the standard libray, so if someone compiles with +`#![no_core]` (or for items, `#![no_std]`), the lang item may not be present. You can either: + +- Give a hard error if the lang item is necessary to continue (don't panic, since this can happen in + user code). +- Proceed with limited functionality, by just omitting whatever you were going to do with the + `DefId`. + +[`tcx.lang_items()`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.lang_items + ## List of all language items You can find language items in the following places: From dadb2f969573888cb845ecfd4c361da45c4c1108 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sun, 4 Jul 2021 17:02:39 -0700 Subject: [PATCH 4/5] Add two missing words --- src/lang-items.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lang-items.md b/src/lang-items.md index 2e36a6c48..bca899f45 100644 --- a/src/lang-items.md +++ b/src/lang-items.md @@ -46,7 +46,7 @@ if let Some(sized_trait_def_id) = tcx.lang_items().sized_trait() { Note that `sized_trait()` returns an `Option`, not the `DefId` itself. That's because language items are defined in the standard libray, so if someone compiles with -`#![no_core]` (or for items, `#![no_std]`), the lang item may not be present. You can either: +`#![no_core]` (or for some lang items, `#![no_std]`), the lang item may not be present. You can either: - Give a hard error if the lang item is necessary to continue (don't panic, since this can happen in user code). From 04f436ec0cd8fd2ffe1eb40417f847efcf55ef55 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sun, 4 Jul 2021 17:05:54 -0700 Subject: [PATCH 5/5] Fix line lengths --- src/lang-items.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lang-items.md b/src/lang-items.md index bca899f45..c5774c43b 100644 --- a/src/lang-items.md +++ b/src/lang-items.md @@ -46,7 +46,8 @@ if let Some(sized_trait_def_id) = tcx.lang_items().sized_trait() { Note that `sized_trait()` returns an `Option`, not the `DefId` itself. That's because language items are defined in the standard libray, so if someone compiles with -`#![no_core]` (or for some lang items, `#![no_std]`), the lang item may not be present. You can either: +`#![no_core]` (or for some lang items, `#![no_std]`), the lang item may not be present. +You can either: - Give a hard error if the lang item is necessary to continue (don't panic, since this can happen in user code).