@@ -2052,6 +2052,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2052
2052
}
2053
2053
}
2054
2054
2055
+ /// Used when lowering a type argument that turned out to actually be a const argument.
2056
+ ///
2057
+ /// Only use for that purpose since otherwise it will create a duplicate def.
2055
2058
#[ instrument( level = "debug" , skip( self ) ) ]
2056
2059
fn lower_const_path_to_const_arg (
2057
2060
& mut self ,
@@ -2060,51 +2063,58 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2060
2063
ty_id : NodeId ,
2061
2064
span : Span ,
2062
2065
) -> & ' hir hir:: ConstArg < ' hir > {
2063
- let ct_kind = match res {
2064
- Res :: Def ( DefKind :: ConstParam , _) => {
2065
- let qpath = self . lower_qpath (
2066
- ty_id,
2067
- & None ,
2068
- path,
2069
- ParamMode :: Optional ,
2070
- AllowReturnTypeNotation :: No ,
2071
- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2072
- None ,
2073
- ) ;
2074
- hir:: ConstArgKind :: Path ( qpath)
2075
- }
2076
- _ => {
2077
- // Construct an AnonConst where the expr is the "ty"'s path.
2066
+ let tcx = self . tcx ;
2078
2067
2079
- let parent_def_id = self . current_def_id_parent ;
2080
- let node_id = self . next_node_id ( ) ;
2081
- let span = self . lower_span ( span) ;
2082
-
2083
- // Add a definition for the in-band const def.
2084
- let def_id =
2085
- self . create_def ( parent_def_id, node_id, kw:: Empty , DefKind :: AnonConst , span) ;
2086
- let hir_id = self . lower_node_id ( node_id) ;
2068
+ // FIXME(min_generic_const_args): we only allow one-segment const paths for now
2069
+ let ct_kind = if path. is_potential_trivial_const_arg ( )
2070
+ && ( tcx. features ( ) . min_generic_const_args ( )
2071
+ || matches ! ( res, Res :: Def ( DefKind :: ConstParam , _) ) )
2072
+ {
2073
+ let qpath = self . lower_qpath (
2074
+ ty_id,
2075
+ & None ,
2076
+ path,
2077
+ ParamMode :: Optional ,
2078
+ AllowReturnTypeNotation :: No ,
2079
+ // FIXME(min_generic_const_args): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2080
+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2081
+ None ,
2082
+ ) ;
2083
+ hir:: ConstArgKind :: Path ( qpath)
2084
+ } else {
2085
+ // Construct an AnonConst where the expr is the "ty"'s path.
2086
+
2087
+ let parent_def_id = self . current_def_id_parent ;
2088
+ let node_id = self . next_node_id ( ) ;
2089
+ let span = self . lower_span ( span) ;
2090
+
2091
+ // Add a definition for the in-band const def.
2092
+ // We're lowering a const argument that was originally thought to be a type argument,
2093
+ // so the def collector didn't create the def ahead of time. That's why we have to do
2094
+ // it here.
2095
+ let def_id =
2096
+ self . create_def ( parent_def_id, node_id, kw:: Empty , DefKind :: AnonConst , span) ;
2097
+ let hir_id = self . lower_node_id ( node_id) ;
2098
+
2099
+ let path_expr = Expr {
2100
+ id : ty_id,
2101
+ kind : ExprKind :: Path ( None , path. clone ( ) ) ,
2102
+ span,
2103
+ attrs : AttrVec :: new ( ) ,
2104
+ tokens : None ,
2105
+ } ;
2087
2106
2088
- let path_expr = Expr {
2089
- id : ty_id,
2090
- kind : ExprKind :: Path ( None , path. clone ( ) ) ,
2107
+ let ct = self . with_new_scopes ( span, |this| {
2108
+ self . arena . alloc ( hir:: AnonConst {
2109
+ def_id,
2110
+ hir_id,
2111
+ body : this. with_def_id_parent ( def_id, |this| {
2112
+ this. lower_const_body ( path_expr. span , Some ( & path_expr) )
2113
+ } ) ,
2091
2114
span,
2092
- attrs : AttrVec :: new ( ) ,
2093
- tokens : None ,
2094
- } ;
2095
-
2096
- let ct = self . with_new_scopes ( span, |this| {
2097
- self . arena . alloc ( hir:: AnonConst {
2098
- def_id,
2099
- hir_id,
2100
- body : this. with_def_id_parent ( def_id, |this| {
2101
- this. lower_const_body ( path_expr. span , Some ( & path_expr) )
2102
- } ) ,
2103
- span,
2104
- } )
2105
- } ) ;
2106
- hir:: ConstArgKind :: Anon ( ct)
2107
- }
2115
+ } )
2116
+ } ) ;
2117
+ hir:: ConstArgKind :: Anon ( ct)
2108
2118
} ;
2109
2119
2110
2120
self . arena . alloc ( hir:: ConstArg {
@@ -2122,6 +2132,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2122
2132
2123
2133
#[ instrument( level = "debug" , skip( self ) ) ]
2124
2134
fn lower_anon_const_to_const_arg_direct ( & mut self , anon : & AnonConst ) -> hir:: ConstArg < ' hir > {
2135
+ let tcx = self . tcx ;
2125
2136
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
2126
2137
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
2127
2138
let expr = if let ExprKind :: Block ( block, _) = & anon. value . kind
@@ -2135,18 +2146,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2135
2146
} ;
2136
2147
let maybe_res =
2137
2148
self . resolver . get_partial_res ( expr. id ) . and_then ( |partial_res| partial_res. full_res ( ) ) ;
2138
- debug ! ( "res={:?}" , maybe_res ) ;
2139
- // FIXME(min_generic_const_args): for now we only lower params to ConstArgKind ::Path
2140
- if let Some ( res ) = maybe_res
2141
- && let Res :: Def ( DefKind :: ConstParam , _ ) = res
2142
- && let ExprKind :: Path ( qself , path ) = & expr . kind
2149
+ // FIXME(min_generic_const_args): we only allow one-segment const paths for now
2150
+ if let ExprKind :: Path ( None , path ) = & expr . kind
2151
+ && path . is_potential_trivial_const_arg ( )
2152
+ && ( tcx . features ( ) . min_generic_const_args ( )
2153
+ || matches ! ( maybe_res , Some ( Res :: Def ( DefKind :: ConstParam , _ ) ) ) )
2143
2154
{
2144
2155
let qpath = self . lower_qpath (
2145
2156
expr. id ,
2146
- qself ,
2157
+ & None ,
2147
2158
path,
2148
2159
ParamMode :: Optional ,
2149
2160
AllowReturnTypeNotation :: No ,
2161
+ // FIXME(min_generic_const_args): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2150
2162
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
2151
2163
None ,
2152
2164
) ;
0 commit comments