about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast_lowering')
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs17
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs96
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs105
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs13
7 files changed, 196 insertions, 45 deletions
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index ab55c09465b..a1e62699680 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -207,6 +207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                 &sym.path,
                                 ParamMode::Optional,
                                 &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                                None,
                             );
                             hir::InlineAsmOperand::SymStatic { path, def_id }
                         } else {
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 72dc52a6329..a63bd4f8a02 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -31,9 +31,26 @@ pub struct InvalidAbi {
     pub abi: Symbol,
     pub command: String,
     #[subdiagnostic]
+    pub explain: Option<InvalidAbiReason>,
+    #[subdiagnostic]
     pub suggestion: Option<InvalidAbiSuggestion>,
 }
 
+pub struct InvalidAbiReason(pub &'static str);
+
+impl rustc_errors::AddToDiagnostic for InvalidAbiReason {
+    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
+    where
+        F: Fn(
+            &mut rustc_errors::Diagnostic,
+            rustc_errors::SubdiagnosticMessage,
+        ) -> rustc_errors::SubdiagnosticMessage,
+    {
+        #[allow(rustc::untranslatable_diagnostic)]
+        diag.note(self.0);
+    }
+}
+
 #[derive(Subdiagnostic)]
 #[suggestion(
     ast_lowering_invalid_abi_suggestion,
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 42d0998d162..b23cee14f75 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -100,6 +100,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         ParamMode::Optional,
                         ParenthesizedGenericArgs::Err,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     ));
                     let receiver = self.lower_expr(receiver);
                     let args =
@@ -260,6 +261,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     hir::ExprKind::Path(qpath)
                 }
@@ -307,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             &se.path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         )),
                         self.arena
                             .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
@@ -1179,6 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     // Destructure like a tuple struct.
                     let tuple_struct_pat = hir::PatKind::TupleStruct(
@@ -1198,6 +1202,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     // Destructure like a unit struct.
                     let unit_struct_pat = hir::PatKind::Path(qpath);
@@ -1222,6 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &se.path,
                     ParamMode::Optional,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    None,
                 );
                 let fields_omitted = match &se.rest {
                     StructRest::Base(e) => {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index df73c721ade..a59c83de0f4 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1,4 +1,4 @@
-use super::errors::{InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
+use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
 use super::ResolverAstLoweringExt;
 use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
 use super::{FnDeclKind, LoweringContext, ParamMode};
@@ -90,6 +90,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
             allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
             allow_gen_future,
             generics_def_id_map: Default::default(),
+            host_param_id: None,
         };
         lctx.with_hir_id_owner(owner, |lctx| f(lctx));
 
@@ -144,8 +145,24 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
             // This is used to track which lifetimes have already been defined,
             // and which need to be replicated when lowering an async fn.
 
-            if let hir::ItemKind::Impl(impl_) = parent_hir.node().expect_item().kind {
-                lctx.is_in_trait_impl = impl_.of_trait.is_some();
+            match parent_hir.node().expect_item().kind {
+                hir::ItemKind::Impl(impl_) => {
+                    lctx.is_in_trait_impl = impl_.of_trait.is_some();
+                }
+                hir::ItemKind::Trait(_, _, generics, _, _) if lctx.tcx.features().effects => {
+                    lctx.host_param_id = generics
+                        .params
+                        .iter()
+                        .find(|param| {
+                            parent_hir
+                                .attrs
+                                .get(param.hir_id.local_id)
+                                .iter()
+                                .any(|attr| attr.has_name(sym::rustc_host))
+                        })
+                        .map(|param| param.def_id);
+                }
+                _ => {}
             }
 
             match ctxt {
@@ -389,6 +406,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.lower_generics(ast_generics, *constness, id, &itctx, |this| {
                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
                             this.lower_trait_ref(
+                                *constness,
                                 trait_ref,
                                 &ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
                             )
@@ -419,7 +437,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     polarity,
                     defaultness,
                     defaultness_span,
-                    constness: self.lower_constness(*constness),
                     generics,
                     of_trait: trait_ref,
                     self_ty: lowered_ty,
@@ -1254,8 +1271,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
-        abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
-            self.error_on_invalid_abi(abi);
+        abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|err| {
+            self.error_on_invalid_abi(abi, err);
             abi::Abi::Rust
         })
     }
@@ -1268,7 +1285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    fn error_on_invalid_abi(&self, abi: StrLit) {
+    fn error_on_invalid_abi(&self, abi: StrLit, err: abi::AbiUnsupported) {
         let abi_names = abi::enabled_names(self.tcx.features(), abi.span)
             .iter()
             .map(|s| Symbol::intern(s))
@@ -1277,6 +1294,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.tcx.sess.emit_err(InvalidAbi {
             abi: abi.symbol_unescaped,
             span: abi.span,
+            explain: match err {
+                abi::AbiUnsupported::Reason { explain } => Some(InvalidAbiReason(explain)),
+                _ => None,
+            },
             suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
                 span: abi.span,
                 suggestion: format!("\"{suggested_name}\""),
@@ -1363,6 +1384,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         }
 
+        // Desugar `~const` bound in generics into an additional `const host: bool` param
+        // if the effects feature is enabled. This needs to be done before we lower where
+        // clauses since where clauses need to bind to the DefId of the host param
+        let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects {
+            if let Some(param) = generics.params.iter().find(|x| {
+                x.attrs.iter().any(|x| x.has_name(sym::rustc_host))
+            }) {
+                // user has manually specified a `rustc_host` param, in this case, we set
+                // the param id so that lowering logic can use that. But we don't create
+                // another host param, so this gives `None`.
+                self.host_param_id = Some(self.local_def_id(param.id));
+                None
+            } else {
+                let param_node_id = self.next_node_id();
+                let hir_id = self.next_id();
+                let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span);
+                self.host_param_id = Some(def_id);
+                Some((span, hir_id, def_id))
+            }
+        } else {
+            None
+        };
+
         let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
         predicates.extend(generics.params.iter().filter_map(|param| {
             self.lower_generic_bound_predicate(
@@ -1410,22 +1454,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
         predicates.extend(impl_trait_bounds.into_iter());
 
-        // Desugar `~const` bound in generics into an additional `const host: bool` param
-        // if the effects feature is enabled.
-        if let Const::Yes(span) = constness && self.tcx.features().effects
-            // Do not add host param if it already has it (manually specified)
-            && !params.iter().any(|x| {
-                self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| {
-                    attrs.iter().any(|x| x.has_name(sym::rustc_host))
-                })
-            })
-        {
-            let param_node_id = self.next_node_id();
+        if let Some((span, hir_id, def_id)) = host_param_parts {
             let const_node_id = self.next_node_id();
-            let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span);
-            let anon_const: LocalDefId = self.create_def(def_id, const_node_id, DefPathData::AnonConst, span);
+            let anon_const: LocalDefId =
+                self.create_def(def_id, const_node_id, DefPathData::AnonConst, span);
 
-            let hir_id = self.next_id();
             let const_id = self.next_id();
             let const_expr_id = self.next_id();
             let bool_id = self.next_id();
@@ -1435,14 +1468,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
             let attr_id = self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
 
-            let attrs = self.arena.alloc_from_iter([
-                Attribute {
-                    kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
+            let attrs = self.arena.alloc_from_iter([Attribute {
+                kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(
+                    sym::rustc_host,
                     span,
-                    id: attr_id,
-                    style: AttrStyle::Outer,
-                },
-            ]);
+                )))),
+                span,
+                id: attr_id,
+                style: AttrStyle::Outer,
+            }]);
             self.attrs.insert(hir_id.local_id, attrs);
 
             let const_body = self.lower_body(|this| {
@@ -1481,7 +1515,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             }),
                         )),
                     )),
-                    default: Some(hir::AnonConst { def_id: anon_const, hir_id: const_id, body: const_body }),
+                    default: Some(hir::AnonConst {
+                        def_id: anon_const,
+                        hir_id: const_id,
+                        body: const_body,
+                    }),
                 },
                 colon_span: None,
                 pure_wrt_drop: false,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d29e9f9b3f6..89775bdee26 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -142,6 +142,8 @@ struct LoweringContext<'a, 'hir> {
     /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
     /// field from the original parameter 'a to the new parameter 'a1.
     generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
+
+    host_param_id: Option<LocalDefId>,
 }
 
 trait ResolverAstLoweringExt {
@@ -455,7 +457,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
 
     // Don't hash unless necessary, because it's expensive.
     let opt_hir_hash =
-        if tcx.sess.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
+        if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
     hir::Crate { owners, opt_hir_hash }
 }
 
@@ -646,7 +648,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let bodies = SortedMap::from_presorted_elements(bodies);
 
         // Don't hash unless necessary, because it's expensive.
-        let (opt_hash_including_bodies, attrs_hash) = if self.tcx.sess.needs_crate_hash() {
+        let (opt_hash_including_bodies, attrs_hash) = if self.tcx.needs_crate_hash() {
             self.tcx.with_stable_hashing_context(|mut hcx| {
                 let mut stable_hasher = StableHasher::new();
                 hcx.with_hir_bodies(node.def_id(), &bodies, |hcx| {
@@ -1262,6 +1264,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         span: t.span
                     },
                     itctx,
+                    ast::Const::No,
                 );
                 let bounds = this.arena.alloc_from_iter([bound]);
                 let lifetime_bound = this.elided_dyn_bound(t.span);
@@ -1272,7 +1275,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
 
         let id = self.lower_node_id(t.id);
-        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
+        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None);
         self.ty_path(id, t.span, qpath)
     }
 
@@ -1356,10 +1359,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
                             GenericBound::Trait(
                                 ty,
-                                TraitBoundModifier::None
+                                modifier @ (TraitBoundModifier::None
                                 | TraitBoundModifier::MaybeConst
-                                | TraitBoundModifier::Negative,
-                            ) => Some(this.lower_poly_trait_ref(ty, itctx)),
+                                | TraitBoundModifier::Negative),
+                            ) => {
+                                Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness()))
+                            }
                             // `~const ?Bound` will cause an error during AST validation
                             // anyways, so treat it like `?Bound` as compilation proceeds.
                             GenericBound::Trait(
@@ -1663,11 +1668,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             );
             debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params);
 
-            let lifetime_mapping = if in_trait {
-                Some(&*self.arena.alloc_slice(&synthesized_lifetime_args))
-            } else {
-                None
-            };
+            let lifetime_mapping = self.arena.alloc_slice(&synthesized_lifetime_args);
 
             let opaque_ty_item = hir::OpaqueTy {
                 generics: this.arena.alloc(hir::Generics {
@@ -1956,7 +1957,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> hir::GenericBound<'hir> {
         match tpb {
             GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
-                self.lower_poly_trait_ref(p, itctx),
+                self.lower_poly_trait_ref(p, itctx, modifier.to_constness()),
                 self.lower_trait_bound_modifier(*modifier),
             ),
             GenericBound::Outlives(lifetime) => {
@@ -2099,8 +2100,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
     }
 
-    fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> {
-        let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
+    fn lower_trait_ref(
+        &mut self,
+        constness: ast::Const,
+        p: &TraitRef,
+        itctx: &ImplTraitContext,
+    ) -> hir::TraitRef<'hir> {
+        let path = match self.lower_qpath(
+            p.ref_id,
+            &None,
+            &p.path,
+            ParamMode::Explicit,
+            itctx,
+            Some(constness),
+        ) {
             hir::QPath::Resolved(None, path) => path,
             qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
         };
@@ -2112,10 +2125,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         p: &PolyTraitRef,
         itctx: &ImplTraitContext,
+        constness: ast::Const,
     ) -> hir::PolyTraitRef<'hir> {
         let bound_generic_params =
             self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
-        let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx);
+        let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx);
         hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
     }
 
@@ -2469,6 +2483,67 @@ struct GenericArgsCtor<'hir> {
 }
 
 impl<'hir> GenericArgsCtor<'hir> {
+    fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) {
+        if !lcx.tcx.features().effects {
+            return;
+        }
+
+        // if bound is non-const, don't add host effect param
+        let ast::Const::Yes(span) = constness else { return };
+
+        let span = lcx.lower_span(span);
+
+        let id = lcx.next_node_id();
+        let hir_id = lcx.next_id();
+        let body = lcx.lower_body(|lcx| {
+            (
+                &[],
+                match constness {
+                    ast::Const::Yes(_) => {
+                        let hir_id = lcx.next_id();
+                        let res =
+                            Res::Def(DefKind::ConstParam, lcx.host_param_id.unwrap().to_def_id());
+                        let expr_kind = hir::ExprKind::Path(hir::QPath::Resolved(
+                            None,
+                            lcx.arena.alloc(hir::Path {
+                                span,
+                                res,
+                                segments: arena_vec![lcx; hir::PathSegment::new(Ident {
+                                    name: sym::host,
+                                    span,
+                                }, hir_id, res)],
+                            }),
+                        ));
+                        lcx.expr(span, expr_kind)
+                    }
+                    ast::Const::No => lcx.expr(
+                        span,
+                        hir::ExprKind::Lit(
+                            lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }),
+                        ),
+                    ),
+                },
+            )
+        });
+
+        let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
+        let attr = lcx.arena.alloc(Attribute {
+            kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
+            span,
+            id: attr_id,
+            style: AttrStyle::Outer,
+        });
+        lcx.attrs.insert(hir_id.local_id, std::slice::from_ref(attr));
+
+        let def_id =
+            lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span);
+        lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
+        self.args.push(hir::GenericArg::Const(hir::ConstArg {
+            value: hir::AnonConst { def_id, hir_id, body },
+            span,
+        }))
+    }
+
     fn is_empty(&self) -> bool {
         self.args.is_empty()
             && self.bindings.is_empty()
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2509b705639..a30f264bc7d 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
                         let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
                         break hir::PatKind::TupleStruct(qpath, pats, ddpos);
@@ -54,6 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
                         break hir::PatKind::Path(qpath);
                     }
@@ -64,6 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
 
                         let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 441282c05b4..899f92a9958 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -23,6 +23,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         p: &Path,
         param_mode: ParamMode,
         itctx: &ImplTraitContext,
+        // constness of the impl/bound if this is a trait path
+        constness: Option<ast::Const>,
     ) -> hir::QPath<'hir> {
         let qself_position = qself.as_ref().map(|q| q.position);
         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
@@ -73,6 +75,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         param_mode,
                         parenthesized_generic_args,
                         itctx,
+                        // if this is the last segment, add constness to the trait path
+                        if i == proj_start - 1 { constness } else { None },
                     )
                 },
             )),
@@ -119,6 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 param_mode,
                 ParenthesizedGenericArgs::Err,
                 itctx,
+                None,
             ));
             let qpath = hir::QPath::TypeRelative(ty, hir_segment);
 
@@ -159,6 +164,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     param_mode,
                     ParenthesizedGenericArgs::Err,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    None,
                 )
             })),
             span: self.lower_span(p.span),
@@ -172,8 +178,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         param_mode: ParamMode,
         parenthesized_generic_args: ParenthesizedGenericArgs,
         itctx: &ImplTraitContext,
+        constness: Option<ast::Const>,
     ) -> hir::PathSegment<'hir> {
-        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
+        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment);
         let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() {
             match generic_args {
                 GenericArgs::AngleBracketed(data) => {
@@ -231,6 +238,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             )
         };
 
+        if let Some(constness) = constness {
+            generic_args.push_constness(self, constness);
+        }
+
         let has_lifetimes =
             generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));