@@ -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