Start working on proof of concept for exposing Backtrace in core by yaahc · Pull Request #77384 · rust-lang/rust (original) (raw)

I don't believe the compiler currently supports using lang items for splitting an inherent impl across three crates.

AFAIK rustc does allow it. The float types are primitives and thus not defined in any existing crate. They have inherent impls in both libcore and liballoc.

That is consistent with my understanding but the issue is we need libcore, liballoc, and libstd, not just libcore and liballoc. I tried double checking the impl and it looks like it is still only two impls to me, though surprisingly the second one appears to be in libstd not liballoc, but either way I don't understand how rustc would allow this.

from compiler/rustc_hir/src/lang_items.rs:

F32,                     sym::f32,                 f32_impl,                   Target::Impl,           GenericRequirement::None;
F64,                     sym::f64,                 f64_impl,                   Target::Impl,           GenericRequirement::None;
F32Runtime,              sym::f32_runtime,         f32_runtime_impl,           Target::Impl,           GenericRequirement::None;
F64Runtime,              sym::f64_runtime,         f64_runtime_impl,           Target::Impl,           GenericRequirement::None;

from compiler/rustc_typeck/src/coherence/inherent_impls.rs:

        ty::Float(ty::FloatTy::F32) => {
            self.check_primitive_impl(
                item.def_id,
                lang_items.f32_impl(),
                lang_items.f32_runtime_impl(),
                "f32",
                "f32",
                item.span,
                assoc_items,
            );
        }

from library/std/src/f32.rs:

#[cfg(not(test))] #[lang = "f32_runtime"] impl f32 {

from library/core/src/num/f32.rs

#[lang = "f32"] #[cfg(not(test))] impl f32 {

The limiting factor as I understand it is the signature of check_primative_id only taking two DefIDs, though I'm not positive I understand how the impl_def_id relates to the lang_def_ids. I think the impl_def_id refers to the type itself, in this case f32, and the lang_def_ids refer to the two impl blocks with lang item attributes attached, but I'm certainly no expert.

fn check_primitive_impl(
    &self,
    impl_def_id: LocalDefId,
    lang_def_id: Option<DefId>,
    lang_def_id2: Option<DefId>,
    lang: &str,
    ty: &str,
    span: Span,
    assoc_items: &[hir::ImplItemRef],
) {