@@ -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,50 @@ 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 ! ( expr. kind, ExprKind :: Path ( ..) | ExprKind :: Struct ( ..) )
2394+ {
2395+ return self . lower_expr_to_const_arg_direct ( expr) ;
2396+ }
2397+
2398+ overly_complex_const ( self )
2399+ }
2400+ _ => overly_complex_const ( self ) ,
2401+ }
2402+ }
2403+
23622404 /// See [`hir::ConstArg`] for when to use this function vs
23632405 /// [`Self::lower_anon_const_to_anon_const`].
23642406 fn lower_anon_const_to_const_arg ( & mut self , anon : & AnonConst ) -> & ' hir hir:: ConstArg < ' hir > {
@@ -2379,20 +2421,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23792421 } else {
23802422 & anon. value
23812423 } ;
2424+
2425+ if tcx. features ( ) . min_generic_const_args ( ) {
2426+ match anon. mgca_disambiguation {
2427+ MgcaDisambiguation :: AnonConst => {
2428+ let lowered_anon = self . lower_anon_const_to_anon_const ( anon) ;
2429+ return ConstArg {
2430+ hir_id : self . next_id ( ) ,
2431+ kind : hir:: ConstArgKind :: Anon ( lowered_anon) ,
2432+ } ;
2433+ }
2434+ MgcaDisambiguation :: Direct => return self . lower_expr_to_const_arg_direct ( expr) ,
2435+ }
2436+ }
2437+
23822438 let maybe_res =
23832439 self . resolver . get_partial_res ( expr. id ) . and_then ( |partial_res| partial_res. full_res ( ) ) ;
23842440 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 , _) ) ) )
2441+ && path. is_potential_trivial_const_arg ( )
2442+ && matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) )
23882443 {
23892444 let qpath = self . lower_qpath (
23902445 expr. id ,
23912446 qself,
23922447 path,
23932448 ParamMode :: Explicit ,
23942449 AllowReturnTypeNotation :: No ,
2395- // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
23962450 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
23972451 None ,
23982452 ) ;
0 commit comments