Repository: rust-lang/rust
File: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs (Rust)

Code before:
        };

        let valtree = ty::ValTree::from_branches(tcx, opt_discr_const.into_iter().chain(fields));
        ty::Const::new_value(tcx, valtree, ty)
    }

    /// Lower a [resolved][hir::QPath::Resolved] path to a (type-level) constant.
    fn lower_resolved_const_path(
        &self,
        opt_self_ty: Option<Ty<'tcx>>,
        path: &hir::Path<'tcx>,
        hir_id: HirId,
    ) -> Const<'tcx> {
        let tcx = self.tcx();
        let span = path.span;
        let ct = match path.res {
            Res::Def(DefKind::ConstParam, def_id) => {
                assert_eq!(opt_self_ty, None);
                let _ = self.prohibit_generic_args(
                    path.segments.iter(),
                    GenericsArgsErrExtend::Param(def_id),
                );
                self.lower_const_param(def_id, hir_id)
            }
            Res::Def(DefKind::Const, did) => {
                if !find_attr!(self.tcx().get_all_attrs(did), AttributeKind::TypeConst(_)) {
                    let mut err = self.dcx().struct_span_err(
                        span,
                        "use of `const` in the type system without `#[type_const]`",
                    );
                    err.note("the declaration must be marked with `#[type_const]`");
                    return Const::new_error(self.tcx(), err.emit());
                }

                assert_eq!(opt_self_ty, None);
                let [leading_segments @ .., segment] = path.segments else { bug!() };
                let _ = self
                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
                let args = self.lower_generic_args_of_path_segment(span, did, segment);
                ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
            }
            Res::Def(DefKind::Ctor(ctor_of, CtorKind::Const), did) => {
                assert_eq!(opt_self_ty, None);
                let [leading_segments @ .., segment] = path.segments else { bug!() };
                let _ = self
                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);

                let parent_did = tcx.parent(did);
                let generics_did = match ctor_of {
                    CtorOf::Variant => tcx.parent(parent_did),
                    CtorOf::Struct => parent_did,

Review comment (refactor):
```suggestion
                if !self.tcx().is_type_const(did) {
```

I think it would also make sense to split this out to a function that can be shared between here and `lower_resolved_assoc_const_path`. Could you do that? :3

Code after:
                    GenericsArgsErrExtend::Param(def_id),
                );
                self.lower_const_param(def_id, hir_id)
            }
            Res::Def(DefKind::Const, did) => {
                if let Err(guar) = self.require_type_const_attribute(did, span) {
                    return Const::new_error(self.tcx(), guar);
                }

                assert_eq!(opt_self_ty, None);
                let [leading_segments @ .., segment] = path.segments else { bug!() };
                let _ = self
                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
                let args = self.lower_generic_args_of_path_segment(span, did, segment);
                ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
            }
            Res::Def(DefKind::Ctor(ctor_of, CtorKind::Const), did) => {
                assert_eq!(opt_self_ty, None);
                let [leading_segments @ .., segment] = path.segments else { bug!() };
                let _ = self
                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);

                let parent_did = tcx.parent(did);
                let generics_did = match ctor_of {
                    CtorOf::Variant => tcx.parent(parent_did),
                    CtorOf::Struct => parent_did,
                };
                let args = self.lower_generic_args_of_path_segment(span, generics_did, segment);

                self.construct_const_ctor_value(did, ctor_of, args)
            }
            Res::Def(DefKind::Ctor(_, CtorKind::Fn), did) => {
                assert_eq!(opt_self_ty, None);
                let [leading_segments @ .., segment] = path.segments else { bug!() };
                let _ = self
                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
                let parent_did = tcx.parent(did);
                let generics_did = if let DefKind::Ctor(CtorOf::Variant, _) = tcx.def_kind(did) {
                    tcx.parent(parent_did)
                } else {
                    parent_did
                };
                let args = self.lower_generic_args_of_path_segment(span, generics_did, segment);
                ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
            }
            Res::Def(DefKind::AssocConst, did) => {
                let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
                    let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
                    Some(trait_)
                } else {
                    None