@@ -2052,6 +2052,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20522052 }
20532053 }
20542054
2055+ /// Used when lowering a type argument that turned out to actually be a const argument.
2056+ ///
2057+ /// Only use for that purpose since otherwise it will create a duplicate def.
20552058 #[ instrument( level = "debug" , skip( self ) ) ]
20562059 fn lower_const_path_to_const_arg (
20572060 & mut self ,
@@ -2060,51 +2063,58 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20602063 ty_id : NodeId ,
20612064 span : Span ,
20622065 ) -> & ' hir hir:: ConstArg < ' hir > {
2063- let ct_kind = match res {
2064- Res :: Def ( DefKind :: ConstParam , _) => {
2065- let qpath = self . lower_qpath (
2066- ty_id,
2067- & None ,
2068- path,
2069- ParamMode :: Optional ,
2070- AllowReturnTypeNotation :: No ,
2071- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2072- None ,
2073- ) ;
2074- hir:: ConstArgKind :: Path ( qpath)
2075- }
2076- _ => {
2077- // Construct an AnonConst where the expr is the "ty"'s path.
2066+ let tcx = self . tcx ;
20782067
2079- let parent_def_id = self . current_def_id_parent ;
2080- let node_id = self . next_node_id ( ) ;
2081- let span = self . lower_span ( span) ;
2082-
2083- // Add a definition for the in-band const def.
2084- let def_id =
2085- self . create_def ( parent_def_id, node_id, kw:: Empty , DefKind :: AnonConst , span) ;
2086- let hir_id = self . lower_node_id ( node_id) ;
2068+ // FIXME(min_generic_const_args): we only allow one-segment const paths for now
2069+ let ct_kind = if path. is_potential_trivial_const_arg ( )
2070+ && ( tcx. features ( ) . min_generic_const_args ( )
2071+ || matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) )
2072+ {
2073+ let qpath = self . lower_qpath (
2074+ ty_id,
2075+ & None ,
2076+ path,
2077+ ParamMode :: Optional ,
2078+ AllowReturnTypeNotation :: No ,
2079+ // FIXME(min_generic_const_args): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2080+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2081+ None ,
2082+ ) ;
2083+ hir:: ConstArgKind :: Path ( qpath)
2084+ } else {
2085+ // Construct an AnonConst where the expr is the "ty"'s path.
2086+
2087+ let parent_def_id = self . current_def_id_parent ;
2088+ let node_id = self . next_node_id ( ) ;
2089+ let span = self . lower_span ( span) ;
2090+
2091+ // Add a definition for the in-band const def.
2092+ // We're lowering a const argument that was originally thought to be a type argument,
2093+ // so the def collector didn't create the def ahead of time. That's why we have to do
2094+ // it here.
2095+ let def_id =
2096+ self . create_def ( parent_def_id, node_id, kw:: Empty , DefKind :: AnonConst , span) ;
2097+ let hir_id = self . lower_node_id ( node_id) ;
2098+
2099+ let path_expr = Expr {
2100+ id : ty_id,
2101+ kind : ExprKind :: Path ( None , path. clone ( ) ) ,
2102+ span,
2103+ attrs : AttrVec :: new ( ) ,
2104+ tokens : None ,
2105+ } ;
20872106
2088- let path_expr = Expr {
2089- id : ty_id,
2090- kind : ExprKind :: Path ( None , path. clone ( ) ) ,
2107+ let ct = self . with_new_scopes ( span, |this| {
2108+ self . arena . alloc ( hir:: AnonConst {
2109+ def_id,
2110+ hir_id,
2111+ body : this. with_def_id_parent ( def_id, |this| {
2112+ this. lower_const_body ( path_expr. span , Some ( & path_expr) )
2113+ } ) ,
20912114 span,
2092- attrs : AttrVec :: new ( ) ,
2093- tokens : None ,
2094- } ;
2095-
2096- let ct = self . with_new_scopes ( span, |this| {
2097- self . arena . alloc ( hir:: AnonConst {
2098- def_id,
2099- hir_id,
2100- body : this. with_def_id_parent ( def_id, |this| {
2101- this. lower_const_body ( path_expr. span , Some ( & path_expr) )
2102- } ) ,
2103- span,
2104- } )
2105- } ) ;
2106- hir:: ConstArgKind :: Anon ( ct)
2107- }
2115+ } )
2116+ } ) ;
2117+ hir:: ConstArgKind :: Anon ( ct)
21082118 } ;
21092119
21102120 self . arena . alloc ( hir:: ConstArg {
@@ -2122,6 +2132,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21222132
21232133 #[ instrument( level = "debug" , skip( self ) ) ]
21242134 fn lower_anon_const_to_const_arg_direct ( & mut self , anon : & AnonConst ) -> hir:: ConstArg < ' hir > {
2135+ let tcx = self . tcx ;
21252136 // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
21262137 // currently have to be wrapped in curly brackets, so it's necessary to special-case.
21272138 let expr = if let ExprKind :: Block ( block, _) = & anon. value . kind
@@ -2135,18 +2146,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21352146 } ;
21362147 let maybe_res =
21372148 self . resolver . get_partial_res ( expr. id ) . and_then ( |partial_res| partial_res. full_res ( ) ) ;
2138- debug ! ( "res={:?}" , maybe_res ) ;
2139- // FIXME(min_generic_const_args): for now we only lower params to ConstArgKind ::Path
2140- if let Some ( res ) = maybe_res
2141- && let Res :: Def ( DefKind :: ConstParam , _ ) = res
2142- && let ExprKind :: Path ( qself , path ) = & expr . kind
2149+ // FIXME(min_generic_const_args): we only allow one-segment const paths for now
2150+ if let ExprKind :: Path ( None , path ) = & expr . kind
2151+ && path . is_potential_trivial_const_arg ( )
2152+ && ( tcx . features ( ) . min_generic_const_args ( )
2153+ || matches ! ( maybe_res , Some ( Res :: Def ( DefKind :: ConstParam , _ ) ) ) )
21432154 {
21442155 let qpath = self . lower_qpath (
21452156 expr. id ,
2146- qself ,
2157+ & None ,
21472158 path,
21482159 ParamMode :: Optional ,
21492160 AllowReturnTypeNotation :: No ,
2161+ // FIXME(min_generic_const_args): update for `fn foo() -> Bar<FOO<impl Trait>>` support
21502162 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
21512163 None ,
21522164 ) ;
0 commit comments