@@ -1206,7 +1206,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12061206 . and_then ( |partial_res| partial_res. full_res ( ) )
12071207 {
12081208 if !res. matches_ns ( Namespace :: TypeNS )
1209- && path. is_potential_trivial_const_arg ( false )
1209+ && path. is_potential_trivial_const_arg ( )
12101210 {
12111211 debug ! (
12121212 "lower_generic_arg: Lowering type argument as const argument: {:?}" ,
@@ -2275,11 +2275,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22752275 ) -> & ' hir hir:: ConstArg < ' hir > {
22762276 let tcx = self . tcx ;
22772277
2278- let ct_kind = if path
2279- . is_potential_trivial_const_arg ( tcx. features ( ) . min_generic_const_args ( ) )
2280- && ( tcx. features ( ) . min_generic_const_args ( )
2281- || matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) )
2282- {
2278+ let is_trivial_path = path. is_potential_trivial_const_arg ( )
2279+ && matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) ;
2280+ let ct_kind = if is_trivial_path || tcx. features ( ) . min_generic_const_args ( ) {
22832281 let qpath = self . lower_qpath (
22842282 ty_id,
22852283 & None ,
@@ -2358,6 +2356,53 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23582356 }
23592357 }
23602358
2359+ #[ instrument( level = "debug" , skip( self ) , ret) ]
2360+ fn lower_expr_to_const_arg_direct ( & mut self , expr : & Expr ) -> hir:: ConstArg < ' hir > {
2361+ let overly_complex_const = |this : & mut Self | {
2362+ let e = this. dcx ( ) . struct_span_err (
2363+ expr. span ,
2364+ "complex const arguments must be placed inside of a `const` block" ,
2365+ ) ;
2366+
2367+ ConstArg { hir_id : this. next_id ( ) , kind : hir:: ConstArgKind :: Error ( expr. span , e. emit ( ) ) }
2368+ } ;
2369+
2370+ match & expr. kind {
2371+ ExprKind :: Path ( qself, path) => {
2372+ let qpath = self . lower_qpath (
2373+ expr. id ,
2374+ qself,
2375+ path,
2376+ ParamMode :: Explicit ,
2377+ AllowReturnTypeNotation :: No ,
2378+ // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2379+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2380+ None ,
2381+ ) ;
2382+
2383+ ConstArg { hir_id : self . next_id ( ) , kind : hir:: ConstArgKind :: Path ( qpath) }
2384+ }
2385+ ExprKind :: Underscore => ConstArg {
2386+ hir_id : self . lower_node_id ( expr. id ) ,
2387+ kind : hir:: ConstArgKind :: Infer ( expr. span , ( ) ) ,
2388+ } ,
2389+ ExprKind :: Block ( block, _) => {
2390+ if let [ stmt] = block. stmts . as_slice ( )
2391+ && let StmtKind :: Expr ( expr) = & stmt. kind
2392+ && matches ! (
2393+ expr. kind,
2394+ ExprKind :: Block ( ..) | ExprKind :: Path ( ..) | ExprKind :: Struct ( ..)
2395+ )
2396+ {
2397+ return self . lower_expr_to_const_arg_direct ( expr) ;
2398+ }
2399+
2400+ overly_complex_const ( self )
2401+ }
2402+ _ => overly_complex_const ( self ) ,
2403+ }
2404+ }
2405+
23612406 /// See [`hir::ConstArg`] for when to use this function vs
23622407 /// [`Self::lower_anon_const_to_anon_const`].
23632408 fn lower_anon_const_to_const_arg ( & mut self , anon : & AnonConst ) -> & ' hir hir:: ConstArg < ' hir > {
@@ -2367,6 +2412,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23672412 #[ instrument( level = "debug" , skip( self ) ) ]
23682413 fn lower_anon_const_to_const_arg_direct ( & mut self , anon : & AnonConst ) -> hir:: ConstArg < ' hir > {
23692414 let tcx = self . tcx ;
2415+
2416+ // We cannot change parsing depending on feature gates available,
2417+ // we can only require feature gates to be active as a delayed check.
2418+ // Thus we just parse anon consts generally and make the real decision
2419+ // making in ast lowering.
2420+ // FIXME(min_generic_const_args): revisit once stable
2421+ if tcx. features ( ) . min_generic_const_args ( ) {
2422+ return match anon. mgca_disambiguation {
2423+ MgcaDisambiguation :: AnonConst => {
2424+ let lowered_anon = self . lower_anon_const_to_anon_const ( anon) ;
2425+ ConstArg { hir_id : self . next_id ( ) , kind : hir:: ConstArgKind :: Anon ( lowered_anon) }
2426+ }
2427+ MgcaDisambiguation :: Direct => self . lower_expr_to_const_arg_direct ( & anon. value ) ,
2428+ } ;
2429+ }
2430+
23702431 // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
23712432 // currently have to be wrapped in curly brackets, so it's necessary to special-case.
23722433 let expr = if let ExprKind :: Block ( block, _) = & anon. value . kind
@@ -2378,20 +2439,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23782439 } else {
23792440 & anon. value
23802441 } ;
2442+
23812443 let maybe_res =
23822444 self . resolver . get_partial_res ( expr. id ) . and_then ( |partial_res| partial_res. full_res ( ) ) ;
23832445 if let ExprKind :: Path ( qself, path) = & expr. kind
2384- && path. is_potential_trivial_const_arg ( tcx. features ( ) . min_generic_const_args ( ) )
2385- && ( tcx. features ( ) . min_generic_const_args ( )
2386- || matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) ) )
2446+ && path. is_potential_trivial_const_arg ( )
2447+ && matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) )
23872448 {
23882449 let qpath = self . lower_qpath (
23892450 expr. id ,
23902451 qself,
23912452 path,
23922453 ParamMode :: Explicit ,
23932454 AllowReturnTypeNotation :: No ,
2394- // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
23952455 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
23962456 None ,
23972457 ) ;
0 commit comments