Lang items are not appropriately named
Nobody has claimed this yet.
- 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_assignbecomesAddAssign. - In general, associated methods and traits should be named as regular paths, with the
::replaced with_. This means that, e.g.clone_fnbecomesClone_cloneandfn_once_outputbecomesFnOnce_output. - We're allowed to not include the full path if something is prelude-exported, e.g.
Somecan remainSome. - Some path parts can be omitted if they're canonical/obvious enough, even if not prelude-exported. For example,
branchcan be renamed to justTry_branchinstead ofops_Try_branch. - Path parts can be omitted if they're redundant. So,
field_FieldRepresentingTypecan just beFieldRepresentingType. - ??? 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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