@@ -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: {:?}" ,
@@ -2276,11 +2276,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22762276 ) -> & ' hir hir:: ConstArg < ' hir > {
22772277 let tcx = self . tcx ;
22782278
2279- let ct_kind = if path
2280- . is_potential_trivial_const_arg ( tcx. features ( ) . min_generic_const_args ( ) )
2281- && ( tcx. features ( ) . min_generic_const_args ( )
2282- || matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) )
2283- {
2279+ let is_trivial_path = path. is_potential_trivial_const_arg ( )
2280+ && matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) ;
2281+ let ct_kind = if is_trivial_path || tcx. features ( ) . min_generic_const_args ( ) {
22842282 let qpath = self . lower_qpath (
22852283 ty_id,
22862284 & None ,
@@ -2359,6 +2357,53 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23592357 }
23602358 }
23612359
2360+ #[ instrument( level = "debug" , skip( self ) , ret) ]
2361+ fn lower_expr_to_const_arg_direct ( & mut self , expr : & Expr ) -> hir:: ConstArg < ' hir > {
2362+ let overly_complex_const = |this : & mut Self | {
2363+ let e = this. dcx ( ) . struct_span_err (
2364+ expr. span ,
2365+ "complex const arguments must be placed inside of a `const` block" ,
2366+ ) ;
2367+
2368+ ConstArg { hir_id : this. next_id ( ) , kind : hir:: ConstArgKind :: Error ( expr. span , e. emit ( ) ) }
2369+ } ;
2370+
2371+ match & expr. kind {
2372+ ExprKind :: Path ( qself, path) => {
2373+ let qpath = self . lower_qpath (
2374+ expr. id ,
2375+ qself,
2376+ path,
2377+ ParamMode :: Explicit ,
2378+ AllowReturnTypeNotation :: No ,
2379+ // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2380+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2381+ None ,
2382+ ) ;
2383+
2384+ ConstArg { hir_id : self . next_id ( ) , kind : hir:: ConstArgKind :: Path ( qpath) }
2385+ }
2386+ ExprKind :: Underscore => ConstArg {
2387+ hir_id : self . lower_node_id ( expr. id ) ,
2388+ kind : hir:: ConstArgKind :: Infer ( expr. span , ( ) ) ,
2389+ } ,
2390+ ExprKind :: Block ( block, _) => {
2391+ if let [ stmt] = block. stmts . as_slice ( )
2392+ && let StmtKind :: Expr ( expr) = & stmt. kind
2393+ && matches ! (
2394+ expr. kind,
2395+ ExprKind :: Block ( ..) | ExprKind :: Path ( ..) | ExprKind :: Struct ( ..)
2396+ )
2397+ {
2398+ return self . lower_expr_to_const_arg_direct ( expr) ;
2399+ }
2400+
2401+ overly_complex_const ( self )
2402+ }
2403+ _ => overly_complex_const ( self ) ,
2404+ }
2405+ }
2406+
23622407 /// See [`hir::ConstArg`] for when to use this function vs
23632408 /// [`Self::lower_anon_const_to_anon_const`].
23642409 fn lower_anon_const_to_const_arg ( & mut self , anon : & AnonConst ) -> & ' hir hir:: ConstArg < ' hir > {
@@ -2368,6 +2413,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23682413 #[ instrument( level = "debug" , skip( self ) ) ]
23692414 fn lower_anon_const_to_const_arg_direct ( & mut self , anon : & AnonConst ) -> hir:: ConstArg < ' hir > {
23702415 let tcx = self . tcx ;
2416+
2417+ if tcx. features ( ) . min_generic_const_args ( ) {
2418+ match anon. mgca_disambiguation {
2419+ MgcaDisambiguation :: AnonConst => {
2420+ let lowered_anon = self . lower_anon_const_to_anon_const ( anon) ;
2421+ return ConstArg {
2422+ hir_id : self . next_id ( ) ,
2423+ kind : hir:: ConstArgKind :: Anon ( lowered_anon) ,
2424+ } ;
2425+ }
2426+ MgcaDisambiguation :: Direct => {
2427+ return self . lower_expr_to_const_arg_direct ( & anon. value ) ;
2428+ }
2429+ }
2430+ }
2431+
23712432 // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
23722433 // currently have to be wrapped in curly brackets, so it's necessary to special-case.
23732434 let expr = if let ExprKind :: Block ( block, _) = & anon. value . kind
@@ -2379,20 +2440,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23792440 } else {
23802441 & anon. value
23812442 } ;
2443+
23822444 let maybe_res =
23832445 self . resolver . get_partial_res ( expr. id ) . and_then ( |partial_res| partial_res. full_res ( ) ) ;
23842446 if let ExprKind :: Path ( qself, path) = & expr. kind
2385- && path. is_potential_trivial_const_arg ( tcx. features ( ) . min_generic_const_args ( ) )
2386- && ( tcx. features ( ) . min_generic_const_args ( )
2387- || matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) ) )
2447+ && path. is_potential_trivial_const_arg ( )
2448+ && matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) )
23882449 {
23892450 let qpath = self . lower_qpath (
23902451 expr. id ,
23912452 qself,
23922453 path,
23932454 ParamMode :: Explicit ,
23942455 AllowReturnTypeNotation :: No ,
2395- // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
23962456 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
23972457 None ,
23982458 ) ;
0 commit comments