@@ -1201,7 +1201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12011201 . and_then ( |partial_res| partial_res. full_res ( ) )
12021202 {
12031203 if !res. matches_ns ( Namespace :: TypeNS )
1204- && path. is_potential_trivial_const_arg ( false )
1204+ && path. is_potential_trivial_const_arg ( )
12051205 {
12061206 debug ! (
12071207 "lower_generic_arg: Lowering type argument as const argument: {:?}" ,
@@ -2271,11 +2271,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22712271 ) -> & ' hir hir:: ConstArg < ' hir > {
22722272 let tcx = self . tcx ;
22732273
2274- let ct_kind = if path
2275- . is_potential_trivial_const_arg ( tcx. features ( ) . min_generic_const_args ( ) )
2276- && ( tcx. features ( ) . min_generic_const_args ( )
2277- || matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) )
2278- {
2274+ let is_trivial_path = path. is_potential_trivial_const_arg ( )
2275+ && matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) ;
2276+ let ct_kind = if is_trivial_path || tcx. features ( ) . min_generic_const_args ( ) {
22792277 let qpath = self . lower_qpath (
22802278 ty_id,
22812279 & None ,
@@ -2354,6 +2352,50 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23542352 }
23552353 }
23562354
2355+ #[ instrument( level = "debug" , skip( self ) , ret) ]
2356+ fn lower_expr_to_const_arg_direct ( & mut self , expr : & Expr ) -> hir:: ConstArg < ' hir > {
2357+ let overly_complex_const = |this : & mut Self | {
2358+ let e = this. dcx ( ) . struct_span_err (
2359+ expr. span ,
2360+ "complex const arguments must be placed inside of a `const` block" ,
2361+ ) ;
2362+
2363+ ConstArg { hir_id : this. next_id ( ) , kind : hir:: ConstArgKind :: Error ( expr. span , e. emit ( ) ) }
2364+ } ;
2365+
2366+ match & expr. kind {
2367+ ExprKind :: Path ( qself, path) => {
2368+ let qpath = self . lower_qpath (
2369+ expr. id ,
2370+ qself,
2371+ path,
2372+ ParamMode :: Explicit ,
2373+ AllowReturnTypeNotation :: No ,
2374+ // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2375+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2376+ None ,
2377+ ) ;
2378+
2379+ ConstArg { hir_id : self . next_id ( ) , kind : hir:: ConstArgKind :: Path ( qpath) }
2380+ }
2381+ ExprKind :: Underscore => ConstArg {
2382+ hir_id : self . lower_node_id ( expr. id ) ,
2383+ kind : hir:: ConstArgKind :: Infer ( expr. span , ( ) ) ,
2384+ } ,
2385+ ExprKind :: Block ( block, _) => {
2386+ if let [ stmt] = block. stmts . as_slice ( )
2387+ && let StmtKind :: Expr ( expr) = & stmt. kind
2388+ && matches ! ( expr. kind, ExprKind :: Path ( ..) | ExprKind :: Struct ( ..) )
2389+ {
2390+ return self . lower_expr_to_const_arg_direct ( expr) ;
2391+ }
2392+
2393+ overly_complex_const ( self )
2394+ }
2395+ _ => overly_complex_const ( self ) ,
2396+ }
2397+ }
2398+
23572399 /// See [`hir::ConstArg`] for when to use this function vs
23582400 /// [`Self::lower_anon_const_to_anon_const`].
23592401 fn lower_anon_const_to_const_arg ( & mut self , anon : & AnonConst ) -> & ' hir hir:: ConstArg < ' hir > {
@@ -2374,20 +2416,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23742416 } else {
23752417 & anon. value
23762418 } ;
2419+
2420+ if tcx. features ( ) . min_generic_const_args ( ) {
2421+ match anon. mgca_disambiguation {
2422+ MgcaDisambiguation :: AnonConst => {
2423+ let lowered_anon = self . lower_anon_const_to_anon_const ( anon) ;
2424+ return ConstArg {
2425+ hir_id : self . next_id ( ) ,
2426+ kind : hir:: ConstArgKind :: Anon ( lowered_anon) ,
2427+ } ;
2428+ }
2429+ MgcaDisambiguation :: Direct => return self . lower_expr_to_const_arg_direct ( expr) ,
2430+ }
2431+ }
2432+
23772433 let maybe_res =
23782434 self . resolver . get_partial_res ( expr. id ) . and_then ( |partial_res| partial_res. full_res ( ) ) ;
23792435 if let ExprKind :: Path ( qself, path) = & expr. kind
2380- && path. is_potential_trivial_const_arg ( tcx. features ( ) . min_generic_const_args ( ) )
2381- && ( tcx. features ( ) . min_generic_const_args ( )
2382- || matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) ) )
2436+ && path. is_potential_trivial_const_arg ( )
2437+ && matches ! ( maybe_res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) )
23832438 {
23842439 let qpath = self . lower_qpath (
23852440 expr. id ,
23862441 qself,
23872442 path,
23882443 ParamMode :: Explicit ,
23892444 AllowReturnTypeNotation :: No ,
2390- // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
23912445 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
23922446 None ,
23932447 ) ;
0 commit comments