Repository: rust-lang/rust
File: compiler/rustc_const_eval/src/check_consts/ops.rs (Rust)

Code before:
        _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::FmtArgumentsNew) => {
            ccx.dcx().create_err(errors::NonConstFmtMacroCall {
                span,
                kind: ccx.const_kind(),
                non_or_conditionally,
            })
        }
        _ => {
            let def_descr = ccx.tcx.def_descr(callee);
            let mut err = ccx.dcx().create_err(errors::NonConstFnCall {
                span,
                def_descr,
                def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
                kind: ccx.const_kind(),
                non_or_conditionally,
            });
            let context_span = ccx.tcx.def_span(ccx.def_id());
            err.span_label(context_span, format!(
                "calls in {}s are limited to constant functions, tuple structs and tuple variants",
                ccx.const_kind(),
            ));
            note = false;
            let def_kind = ccx.tcx.def_kind(callee);
            if let DefKind::AssocTy | DefKind::AssocConst | DefKind::AssocFn = def_kind {
                let parent = ccx.tcx.parent(callee);
                if let DefKind::Trait = ccx.tcx.def_kind(parent)
                    && !ccx.tcx.is_const_trait(parent)
                {
                    let assoc_span = ccx.tcx.def_span(callee);
                    let assoc_name = ccx.tcx.item_name(callee);
                    let mut span: MultiSpan = ccx.tcx.def_span(parent).into();
                    span.push_span_label(assoc_span, format!("this {def_descr} is not const"));
                    let trait_descr = ccx.tcx.def_descr(parent);
                    let trait_span = ccx.tcx.def_span(parent);
                    let trait_name = ccx.tcx.item_name(parent);
                    span.push_span_label(trait_span, format!("this {trait_descr} is not const"));
                    err.span_note(
                        span,
                        format!(
                            "{def_descr} `{assoc_name}` is not const because {trait_descr} \
                            `{trait_name}` is not const",
                        ),
                    );
                    if parent.is_local() && ccx.tcx.sess.is_nightly_build() {
                        if !ccx.tcx.features().const_trait_impl() {
                            err.help(
                                "add `#![feature(const_trait_impl)]` to the crate attributes to \
                                 enable `#[const_trait]`",
                            );
                        }
                        let indentation = ccx

Review comment (suggestion):
This whole check could be simplified if you looked at `opt_associated_item` and checked both the `AssocKind` and the `AssocItemContainer`, rather than using manual parenting logic.

Code after:
            })
        }
        _ => {
            let def_descr = ccx.tcx.def_descr(callee);
            let mut err = ccx.dcx().create_err(errors::NonConstFnCall {
                span,
                def_descr,
                def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
                kind: ccx.const_kind(),
                non_or_conditionally,
            });
            if let Some(item) = ccx.tcx.opt_associated_item(callee) {
                if let AssocContainer::Trait = item.container
                    && let parent = item.container_id(ccx.tcx)
                    && !ccx.tcx.is_const_trait(parent)
                {
                    let assoc_span = ccx.tcx.def_span(callee);
                    let assoc_name = ccx.tcx.item_name(callee);
                    let mut span: MultiSpan = ccx.tcx.def_span(parent).into();
                    span.push_span_label(assoc_span, format!("this {def_descr} is not const"));
                    let trait_descr = ccx.tcx.def_descr(parent);
                    let trait_span = ccx.tcx.def_span(parent);
                    let trait_name = ccx.tcx.item_name(parent);
                    span.push_span_label(trait_span, format!("this {trait_descr} is not const"));
                    err.span_note(
                        span,
                        format!(
                            "{def_descr} `{assoc_name}` is not const because {trait_descr} \
                            `{trait_name}` is not const",
                        ),
                    );
                    if parent.is_local() && ccx.tcx.sess.is_nightly_build() {
                        if !ccx.tcx.features().const_trait_impl() {
                            err.help(
                                "add `#![feature(const_trait_impl)]` to the crate attributes to \
                                 enable `#[const_trait]`",
                            );
                        }
                        let indentation = ccx
                            .tcx
                            .sess
                            .source_map()
                            .indentation_before(trait_span)
                            .unwrap_or_default();
                        err.span_suggestion_verbose(
                            trait_span.shrink_to_lo(),
                            format!("consider making trait `{trait_name}` const"),
                            format!("#[const_trait]\n{indentation}"),
                            Applicability::MaybeIncorrect,
                        );
                    } else if !ccx.tcx.sess.is_nightly_build() {