rust-lang / rust-lang/rust

Lang items are not appropriately named

Open
#162,968 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-lang-item C-cleanup needs-triage T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Going to file this as an issue for now since changing this has several downstream effects.

But essentially, we have a mix between lang items that are capitalised correctly according to the items they define, and those which are not.

Relevant docs: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_ir/lang_items/enum.LangItem.html

My extremely jank list of #[lang] attributes and their items, created through a combination of regexp and manual editing:

#[lang = "add_assign"] pub trait AddAssign
#[lang = "add"] pub trait Add
#[lang = "align_offset"] pub(crate) unsafe fn align_offset
#[lang = "alloc_layout"] pub struct Layout
#[lang = "array"] impl<T, const N> [T; N]
#[lang = "async_drop_in_place"] pub async unsafe fn async_drop_in_place
#[lang = "async_drop"] pub trait AsyncDrop
#[lang = "async_fn_kind_helper"] trait AsyncFnKindHelper
#[lang = "async_fn_kind_upvars"] type Upvars
#[lang = "async_fn_mut"] pub trait AsyncFnMut
#[lang = "async_fn_once_output"] type Output
#[lang = "async_fn_once"] pub trait AsyncFnOnce
#[lang = "async_fn"] pub trait AsyncFn
#[lang = "AsyncGenFinished"] pub const FINISHED
#[lang = "AsyncGenPending"] pub const PENDING
#[lang = "AsyncGenReady"] pub fn async_gen_ready
#[lang = "async_iterator_poll_next"] fn poll_next
#[lang = "async_iterator"] pub trait AsyncIterator
#[lang = "bikeshed_guaranteed_no_drop"] pub trait BikeshedGuaranteedNoDrop
#[lang = "bitand_assign"] pub trait BitAndAssign
#[lang = "bitand"] pub trait BitAnd
#[lang = "bitor_assign"] pub trait BitOrAssign
#[lang = "bitor"] pub trait BitOr
#[lang = "bitxor_assign"] pub trait BitXorAssign
#[lang = "bitxor"] pub trait BitXor
#[lang = "bool"] impl bool
#[lang = "branch"] fn branch
#[lang = "Break"] Break(B)
#[lang = "call_once_future"] type CallOnceFuture
#[lang = "call_ref_future"] type CallRefFuture
#[lang = "char"] impl char
#[lang = "clone_fn"] fn clone
#[lang = "clone"] pub trait Clone
#[lang = "code"] pub type Code
#[lang = "coerce_pointee_validated"] pub trait CoercePointeeValidated
#[lang = "coerce_shared"] pub trait CoerceShared
#[lang = "coerce_unsized"] pub trait CoerceUnsized
#[lang = "compiler_copy"] pub fn compiler_copy
#[lang = "compiler_move"] pub fn compiler_move
#[lang = "complex"] pub struct Complex
#[lang = "const_panic_fmt"] pub const fn const_panic_fmt
#[lang = "const_param_ty"] pub trait ConstParamTy_
#[lang = "const_ptr"] impl<T> *const T
#[lang = "const_slice_ptr"] impl<T> *const [T]
#[lang = "Context"] pub struct Context
#[lang = "Continue"] Continue(C)
#[lang = "contract_build_check_ensures"] pub const fn build_check_ensures
#[lang = "contract_check_ensures"] pub const fn contract_check_ensures
#[lang = "contract_check_requires"] pub const fn contract_check_requires
#[lang = "copy"] pub trait Copy
#[lang = "coroutine"] pub trait Coroutine
#[lang = "coroutine_resume"] fn resume
#[lang = "coroutine_return"] type Return
#[lang = "coroutine_state"] pub enum CoroutineState
#[lang = "coroutine_yield"] type Yield
#[lang = "covariant_unsafe_cell"] pub struct CovariantUnsafeCell
#[lang = "CStr"] pub struct CStr
#[lang = "c_void"] pub enum c_void
#[lang = "deref_mut"] pub trait DerefMut
#[lang = "deref"] pub trait Deref
#[lang = "deref_pure"] pub unsafe trait DerefPure
#[lang = "deref_target"] type Target
#[lang = "destruct"] pub const trait Destruct
#[lang = "discriminant_kind"] pub trait DiscriminantKind
#[lang = "discriminant_type"] type Discriminant
#[lang = "dispatch_from_dyn"] pub trait DispatchFromDyn
#[lang = "div_assign"] pub trait DivAssign
#[lang = "div"] pub trait Div
#[lang = "drop_glue"] pub unsafe fn drop_glue
#[lang = "drop_in_place"] pub unsafe fn drop_in_place
#[lang = "drop"] pub trait Drop
#[lang = "dyn_metadata"] pub struct DynMetadata
#[lang = "eh_personality"] fn eh_personality() -> !
#[lang = "eq"] pub trait PartialEq
#[lang = "Err"] Err(E)
#[lang = "exchange_malloc"] unsafe fn allocate
#[lang = "f32"] impl f32
#[lang = "f64"] impl f64
#[lang = "field_base"] type Base
#[lang = "field_offset"] const OFFSET
#[lang = "field"] pub unsafe trait Field
#[lang = "field_representing_type"] pub struct FieldRepresentingType
#[lang = "field_type"] type Type
#[lang = "fn_mut"] pub trait FnMut
#[lang = "fn_once_output"] type Output
#[lang = "fn_once"] pub trait FnOnce
#[lang = "fn_ptr_as_ptr"] fn as_ptr
#[lang = "fn_ptr_from_ptr"] unsafe fn from_ptr
#[lang = "FnPtr"] pub struct FnPtr
#[lang = "fn_ptr_trait"] pub trait FnPtr
#[lang = "fn"] pub trait Fn
#[lang = "format_alignment"] pub enum Alignment
#[lang = "format_argument"] pub struct Argument
#[lang = "format_arguments"] pub struct Arguments
#[lang = "freeze"] pub(crate) unsafe auto trait Freeze
#[lang = "from_error"] fn from_error
#[lang = "from"] fn from
#[lang = "from_generator"] pub const fn from_generator
#[lang = "from_ok"] fn from_ok
#[lang = "from_output"] fn from_output
#[lang = "From"] pub const trait From
#[lang = "from_residual"] fn from_residual
#[lang = "from_yeet"] pub fn from_yeet
#[lang = "fused_iterator"] pub trait FusedIterator
#[lang = "future_output"] type Output
#[lang = "future_trait"] pub trait Future
#[lang = "generator"] pub trait Generator
#[lang = "generator_state"] pub enum GeneratorState
#[lang = "get_context"] pub unsafe fn get_context
#[lang = "global_alloc_ty"] pub struct Global
#[lang = "i128"] impl i128
#[lang = "i16"] impl i16
#[lang = "i32"] impl i32
#[lang = "i64"] impl i64
#[lang = "i8"] impl i32
#[lang = "i8"] impl i8
#[lang = "index_mut"] pub trait IndexMut
#[lang = "index"] pub trait Index
#[lang = "into_async_iter_into_iter"] fn into_async_iter
#[lang = "into_future"] fn into_future
#[lang = "into_iter"] fn into_iter
#[lang = "into_result"] fn into_result
#[lang = "into_try_type"] pub const fn residual_into_try_type
#[lang = "isize"] impl isize
#[lang = "iterator"] pub trait Iterator
#[lang = "legacy_receiver"] pub trait LegacyReceiver
#[lang = "manually_drop"] pub struct ManuallyDrop
#[lang = "maybe_dangling"] pub struct MaybeDangling
#[lang = "maybe_uninit"] pub union MaybeUninit
#[lang = "mem_align_const"] const ALIGN
#[lang = "mem_size_const"] const SIZE
#[lang = "metadata_type"] type Metadata
#[lang = "meta_sized"] pub trait MetaSized
#[lang = "mul_assign"] pub trait MulAssign
#[lang = "mul"] pub trait Mul
#[lang = "mut_ptr"] impl<T> *mut T
#[lang = "mut_slice_ptr"] impl<T> *mut [T]
#[lang = "neg"] pub trait Neg
#[lang = "new_unchecked"] pub const unsafe fn new_unchecked
#[lang = "next"] fn next
#[lang = "None"] None
#[lang = "non_null"] pub struct NonNull
#[lang = "not"] pub trait Not
#[lang = "offset_of"] pub fn offset_of
#[lang = "Ok"] Ok(T)
#[lang = "Option"] pub enum Option
#[lang = "Ordering"] pub enum Ordering
#[lang = "owned_box"] pub struct Box
#[lang = "panic_bounds_check"] fn panic_bounds_check
#[lang = "panic_cannot_unwind"] fn panic_cannot_unwind
#[lang = "panic_display"] pub const fn panic_display
#[lang = "panic_fmt"] pub const fn panic_fmt
#[lang = "panic_impl"] fn panic_impl
#[lang = "panic_in_cleanup"] fn panic_in_cleanup
#[lang = "panic_info"] pub struct PanicInfo
#[lang = "panic_invalid_enum_construction"] fn panic_invalid_enum_construction
#[lang = "panic_location"] pub struct Location
#[lang = "panic_misaligned_pointer_dereference"] fn panic_misaligned_pointer_dereference
#[lang = "panic_nounwind"] pub const fn panic_nounwind
#[lang = "panic_null_pointer_dereference"] fn panic_null_pointer_dereference
#[lang = "panic_null_reference_constructed"] fn panic_null_reference_constructed
#[lang = "panic"] pub const fn panic
#[lang = "partial_ord"] pub trait PartialOrd
#[lang = "Pending"] Pending
#[lang = "phantom_data"] pub struct PhantomData
#[lang = "pin"] pub struct Pin
#[lang = "pointee_sized"] pub trait PointeeSized
#[lang = "pointee_trait"] pub trait Pointee
#[lang = "poll"] fn poll
#[lang = "Poll"] pub enum Poll
#[lang = "RangeCopy"] pub struct Range
#[lang = "RangeFromCopy"] pub struct RangeFrom
#[lang = "RangeFrom"] pub struct RangeFrom
#[lang = "RangeFull"] pub struct RangeFull
#[lang = "RangeInclusiveCopy"] pub struct RangeInclusive
#[lang = "range_inclusive_new"] pub const fn new
#[lang = "RangeInclusive"] pub struct RangeInclusive
#[lang = "RangeMax"] const MAX
#[lang = "RangeMin"] const MIN
#[lang = "Range"] pub struct Range
#[lang = "RangeSub"] fn sub_one
#[lang = "RangeToInclusiveCopy"] pub struct RangeToInclusive
#[lang = "RangeToInclusive"] pub struct RangeToInclusive
#[lang = "RangeTo"] pub struct RangeTo
#[lang = "Ready"] Ready(T)
#[lang = "reborrow"] pub trait Reborrow
#[lang = "receiver"] pub trait Receiver
#[lang = "receiver_target"] type Target
#[lang = "rem_assign"] pub trait RemAssign
#[lang = "rem"] pub trait Rem
#[lang = "ResumeTy"] pub struct ResumeTy
#[lang = "shl_assign"] pub trait ShlAssign
#[lang = "shl"] pub trait Shl
#[lang = "shr_assign"] pub trait ShrAssign
#[lang = "shr"] pub trait Shr
#[lang = "sized"] pub trait Sized
#[lang = "slice"] impl<T> [T]
#[lang = "slice_len_fn"] pub const fn len
#[lang = "slice_u8"] impl [u8]
#[lang = "Some"] Some(T)
#[lang = "start"] fn lang_start
#[lang = "str"] impl str
#[lang = "String"] pub struct String
#[lang = "structural_peq"] pub trait StructuralPartialEq
#[lang = "structural_teq"] pub trait StructuralEq
#[lang = "sub_assign"] pub trait SubAssign
#[lang = "sub"] pub trait Sub
#[lang = "sync"] pub unsafe auto trait Sync
#[lang = "transmute_opts"] pub struct Assume
#[lang = "transmute_trait"] pub unsafe trait TransmuteFrom
#[lang = "trivial_clone"] pub const unsafe trait TrivialClone
#[lang = "try_as_dyn"] pub trait TryAsDynCompatible
#[lang = "try"] pub trait Try
#[lang = "Try"] pub trait Try
#[lang = "tuple_trait"] pub trait Tuple
#[lang = "type_id"] pub struct TypeId
#[lang = "type_info_generic"] pub enum Generic
#[lang = "type_info"] pub struct Type
#[lang = "u128"] impl u128
#[lang = "u16"] impl u16
#[lang = "u32"] impl u32
#[lang = "u64"] impl u64
#[lang = "u8"] impl u8
#[lang = "unpin"] pub auto trait Unpin
#[lang = "unsafe_cell"] pub struct UnsafeCell
#[lang = "unsafe_pinned"] pub struct UnsafePinned
#[lang = "unsafe_unpin"] pub unsafe auto trait UnsafeUnpin
#[lang = "unsize"] pub trait Unsize
#[lang = "use_cloned"] pub trait UseCloned
#[lang = "usize"] impl usize
#[lang = "va_arg_safe"] pub impl(self) unsafe trait VaArgSafe
#[lang = "va_list"] pub struct VaList
#[lang = "va_list"] pub struct VaListImpl

The awful command that created the initial list:

rg --sort-files --multiline --multiline-dotall '\n\s*#\[lang = [^\]]+\]\s*(#\[[^\]]+\]\s*|//[^\n]+\n\s*)*[\w\s]+[^\n]+' --only-matching --no-filename --no-line-number --glob '!mini_core*.rs' --glob '!tests/' --glob '!error_codes/' | sd --across '#\[(doc|(un)?stable|rustc|track_caller|diagnostic|fundamental|repr|derive|allow|expect|deny|warn|must_use|inline|unsafe|marker|cfg)[^]]*\]' '' | sed -e 's/\/\/.*$//;s/^[[:space:]]*//;/^[[:space:]]*$/d;s/{}\?$//;s/;$//;s/:[[:alnum:][:space:]+]*//;s/<[^>]*>\s*$//' | sd --across '(#\[lang = [^\]]+\])\s*(\S)' '$1 $2' | sort -u > matches

I'm not going to sift through the list for now, but here's at least my proposal for some guidelines:

  • Ideally, the lang item should be capitalized in the same way. This means that, e.g. add_assign becomes AddAssign.
  • In general, associated methods and traits should be named as regular paths, with the :: replaced with _. This means that, e.g. clone_fn becomes Clone_clone and fn_once_output becomes FnOnce_output.
  • We're allowed to not include the full path if something is prelude-exported, e.g. Some can remain Some.
  • Some path parts can be omitted if they're canonical/obvious enough, even if not prelude-exported. For example, branch can be renamed to just Try_branch instead of ops_Try_branch.
  • Path parts can be omitted if they're redundant. So, field_FieldRepresentingType can just be FieldRepresentingType.
  • ??? probably other rules

Basically, the drifting-out-of-date of lang items kind of makes it a bit annoying to interact with the compiler as someone who understands the standard library, since names don't exist. Also, things that differ only by capitalization are mega-confusing.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked LangItem documentation and reproduce the listed rg/sd command to inspect the current matches. Review the proposed capitalization and path-based naming guidelines, then identify the full set of affected lang items and downstream references; done requires agreed rules and a complete, consistent migration scope.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.