@@ -1219,7 +1219,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12191219 . and_then ( |partial_res| partial_res. full_res ( ) )
12201220 {
12211221 if !res. matches_ns ( Namespace :: TypeNS )
1222- && path. is_potential_trivial_const_arg ( false )
1222+ && path. is_potential_trivial_const_arg ( )
12231223 {
12241224 debug ! (
12251225 "lower_generic_arg: Lowering type argument as const argument: {:?}" ,
@@ -2287,11 +2287,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22872287 ) -> & ' hir hir:: ConstArg < ' hir > {
22882288 let tcx = self . tcx ;
22892289
2290- let ct_kind = if path
2291- . is_potential_trivial_const_arg ( tcx. features ( ) . min_generic_const_args ( ) )
2292- && ( tcx. features ( ) . min_generic_const_args ( )
2293- || matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) )
2294- {
2290+ let is_trivial_path = path. is_potential_trivial_const_arg ( )
2291+ && matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) ;
2292+ let ct_kind = if is_trivial_path || tcx. features ( ) . min_generic_const_args ( ) {
22952293 let qpath = self . lower_qpath (
22962294 ty_id,
22972295 & None ,
@@ -2370,6 +2368,53 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23702368 }
23712369 }
23722370
2371+ #[ instrument( level = "debug" , skip( self ) , ret) ]
2372+ fn lower_expr_to_const_arg_direct ( & mut self , expr : & Expr ) -> hir:: ConstArg < ' hir > {
2373+ let overly_complex_const = |this : & mut Self | {
2374+ let e = this. dcx ( ) . struct_span_err (
2375+ expr. span ,
2376+ "complex const arguments must be placed inside of a `const` block" ,
2377+ ) ;
2378+
2379+ ConstArg { hir_id : this. next_id ( ) , kind : hir:: ConstArgKind :: Error ( expr. span , e. emit ( ) ) }
2380+ } ;
2381+
2382+ match & expr. kind {
2383+ ExprKind :: Path ( qself, path) => {
2384+ let qpath = self . lower_qpath (
2385+ expr. id ,
2386+ qself,
2387+ path,
2388+ ParamMode :: Explicit ,
2389+ AllowReturnTypeNotation :: No ,
2390+ // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2391+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2392+ None ,
2393+ ) ;
2394+
2395+ ConstArg { hir_id : self . next_id ( ) , kind : hir:: ConstArgKind :: Path ( qpath) }
2396+ }
2397+ ExprKind :: Underscore => ConstArg {
2398+ hir_id : self . lower_node_id ( expr. id ) ,
2399+ kind : hir:: ConstArgKind :: Infer ( expr. span , ( ) ) ,
2400+ } ,
2401+ ExprKind :: Block ( block, _) => {
2402+ if let [ stmt] = block. stmts . as_slice ( )
2403+ && let StmtKind :: Expr ( expr) = & stmt. kind
2404+ && matches ! (
2405+ expr. kind,
2406+ ExprKind :: Block ( ..) | ExprKind :: Path ( ..) | ExprKind :: Struct ( ..)
2407+ )
2408+ {
2409+ return self . lower_expr_to_const_arg_direct ( expr) ;
2410+ }
2411+
2412+ overly_complex_const ( self )
2413+ }
2414+ _ => overly_complex_const ( self ) ,
2415+ }
2416+ }
2417+
23732418 /// See [`hir::ConstArg`] for when to use this function vs
23742419 /// [`Self::lower_anon_const_to_anon_const`].
23752420 fn lower_anon_const_to_const_arg ( & mut self , anon : & AnonConst ) -> & ' hir hir:: ConstArg < ' hir > {
@@ -2379,6 +2424,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23792424 #[ instrument( level = "debug" , skip( self ) ) ]
23802425 fn lower_anon_const_to_const_arg_direct ( & mut self , anon : & AnonConst ) -> hir:: ConstArg < ' hir > {
23812426 let tcx = self . tcx ;
2427+
2428+ // We cannot change parsing depending on feature gates available,
2429+ // we can only require feature gates to be active as a delayed check.
2430+ // Thus we just parse anon consts generally and make the real decision
2431+ // making in ast lowering.
2432+ // FIXME(min_generic_const_args): revisit once stable
2433+ if tcx. features ( ) . min_generic_const_args ( ) {
2434+ return match anon. mgca_disambiguation {
2435+ MgcaDisambiguation :: AnonConst => {
2436+ let lowered_anon = self . lower_anon_const_to_anon_const ( anon) ;
2437+ ConstArg { hir_id : self . next_id ( ) , kind : hir:: ConstArgKind :: Anon ( lowered_anon) }
2438+ }
2439+ MgcaDisambiguation :: Direct => self . lower_expr_to_const_arg_direct ( & anon. value ) ,
2440+ } ;
2441+ }
2442+
23822443 // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
23832444 // currently have to be wrapped in curly brackets, so it's necessary to special-case.
23842445 let expr = if let ExprKind :: Block ( block, _) = & anon. value . kind
@@ -2390,20 +2451,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23902451 } else {
23912452 & anon. value
23922453 } ;
2454+
23932455 let maybe_res =
23942456 self . resolver . get_partial_res ( expr. id ) . and_then ( |partial_res| partial_res. full_res ( ) ) ;
23952457 if let ExprKind :: Path ( qself, path) = & expr. kind
2396- && path. is_potential_trivial_const_arg ( tcx. features ( ) . min_generic_const_args ( ) )
2397- && ( tcx. features ( ) . min_generic_const_args ( )
2398- || matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) ) )
2458+ && path. is_potential_trivial_const_arg ( )
2459+ && matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) )
23992460 {
24002461 let qpath = self . lower_qpath (
24012462 expr. id ,
24022463 qself,
24032464 path,
24042465 ParamMode :: Explicit ,
24052466 AllowReturnTypeNotation :: No ,
2406- // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
24072467 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
24082468 None ,
24092469 ) ;
0 commit comments