@@ -142,6 +142,8 @@ struct LoweringContext<'a, 'hir> {
142
142
/// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
143
143
/// field from the original parameter 'a to the new parameter 'a1.
144
144
generics_def_id_map : Vec < FxHashMap < LocalDefId , LocalDefId > > ,
145
+
146
+ host_param_id : Option < LocalDefId > ,
145
147
}
146
148
147
149
trait ResolverAstLoweringExt {
@@ -1267,6 +1269,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1267
1269
span : t. span
1268
1270
} ,
1269
1271
itctx,
1272
+ ast:: Const :: No ,
1270
1273
) ;
1271
1274
let bounds = this. arena . alloc_from_iter ( [ bound] ) ;
1272
1275
let lifetime_bound = this. elided_dyn_bound ( t. span ) ;
@@ -1277,7 +1280,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1277
1280
}
1278
1281
1279
1282
let id = self . lower_node_id ( t. id ) ;
1280
- let qpath = self . lower_qpath ( t. id , qself, path, param_mode, itctx) ;
1283
+ let qpath = self . lower_qpath ( t. id , qself, path, param_mode, itctx, None ) ;
1281
1284
self . ty_path ( id, t. span , qpath)
1282
1285
}
1283
1286
@@ -1361,10 +1364,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1361
1364
this. arena . alloc_from_iter ( bounds. iter ( ) . filter_map ( |bound| match bound {
1362
1365
GenericBound :: Trait (
1363
1366
ty,
1364
- TraitBoundModifier :: None
1367
+ modifier @ ( TraitBoundModifier :: None
1365
1368
| TraitBoundModifier :: MaybeConst
1366
- | TraitBoundModifier :: Negative ,
1367
- ) => Some ( this. lower_poly_trait_ref ( ty, itctx) ) ,
1369
+ | TraitBoundModifier :: Negative ) ,
1370
+ ) => {
1371
+ Some ( this. lower_poly_trait_ref ( ty, itctx, modifier. to_constness ( ) ) )
1372
+ }
1368
1373
// `~const ?Bound` will cause an error during AST validation
1369
1374
// anyways, so treat it like `?Bound` as compilation proceeds.
1370
1375
GenericBound :: Trait (
@@ -2189,7 +2194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2189
2194
) -> hir:: GenericBound < ' hir > {
2190
2195
match tpb {
2191
2196
GenericBound :: Trait ( p, modifier) => hir:: GenericBound :: Trait (
2192
- self . lower_poly_trait_ref ( p, itctx) ,
2197
+ self . lower_poly_trait_ref ( p, itctx, modifier . to_constness ( ) ) ,
2193
2198
self . lower_trait_bound_modifier ( * modifier) ,
2194
2199
) ,
2195
2200
GenericBound :: Outlives ( lifetime) => {
@@ -2332,8 +2337,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2332
2337
}
2333
2338
}
2334
2339
2335
- fn lower_trait_ref ( & mut self , p : & TraitRef , itctx : & ImplTraitContext ) -> hir:: TraitRef < ' hir > {
2336
- let path = match self . lower_qpath ( p. ref_id , & None , & p. path , ParamMode :: Explicit , itctx) {
2340
+ fn lower_trait_ref (
2341
+ & mut self ,
2342
+ constness : ast:: Const ,
2343
+ p : & TraitRef ,
2344
+ itctx : & ImplTraitContext ,
2345
+ ) -> hir:: TraitRef < ' hir > {
2346
+ let path = match self . lower_qpath (
2347
+ p. ref_id ,
2348
+ & None ,
2349
+ & p. path ,
2350
+ ParamMode :: Explicit ,
2351
+ itctx,
2352
+ Some ( constness) ,
2353
+ ) {
2337
2354
hir:: QPath :: Resolved ( None , path) => path,
2338
2355
qpath => panic ! ( "lower_trait_ref: unexpected QPath `{qpath:?}`" ) ,
2339
2356
} ;
@@ -2345,10 +2362,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2345
2362
& mut self ,
2346
2363
p : & PolyTraitRef ,
2347
2364
itctx : & ImplTraitContext ,
2365
+ constness : ast:: Const ,
2348
2366
) -> hir:: PolyTraitRef < ' hir > {
2349
2367
let bound_generic_params =
2350
2368
self . lower_lifetime_binder ( p. trait_ref . ref_id , & p. bound_generic_params ) ;
2351
- let trait_ref = self . lower_trait_ref ( & p. trait_ref , itctx) ;
2369
+ let trait_ref = self . lower_trait_ref ( constness , & p. trait_ref , itctx) ;
2352
2370
hir:: PolyTraitRef { bound_generic_params, trait_ref, span : self . lower_span ( p. span ) }
2353
2371
}
2354
2372
@@ -2702,6 +2720,57 @@ struct GenericArgsCtor<'hir> {
2702
2720
}
2703
2721
2704
2722
impl < ' hir > GenericArgsCtor < ' hir > {
2723
+ fn push_constness ( & mut self , lcx : & mut LoweringContext < ' _ , ' hir > , constness : ast:: Const ) {
2724
+ if !lcx. tcx . features ( ) . effects {
2725
+ return ;
2726
+ }
2727
+
2728
+ // if bound is non-const, don't add host effect param
2729
+ let ast:: Const :: Yes ( span) = constness else { return } ;
2730
+
2731
+ let span = lcx. lower_span ( span) ;
2732
+
2733
+ let id = lcx. next_node_id ( ) ;
2734
+ let hir_id = lcx. next_id ( ) ;
2735
+ let body = lcx. lower_body ( |lcx| {
2736
+ (
2737
+ & [ ] ,
2738
+ match constness {
2739
+ ast:: Const :: Yes ( _) => {
2740
+ let hir_id = lcx. next_id ( ) ;
2741
+ let res =
2742
+ Res :: Def ( DefKind :: ConstParam , lcx. host_param_id . unwrap ( ) . to_def_id ( ) ) ;
2743
+ let expr_kind = hir:: ExprKind :: Path ( hir:: QPath :: Resolved (
2744
+ None ,
2745
+ lcx. arena . alloc ( hir:: Path {
2746
+ span,
2747
+ res,
2748
+ segments : arena_vec ! [ lcx; hir:: PathSegment :: new( Ident {
2749
+ name: sym:: host,
2750
+ span,
2751
+ } , hir_id, res) ] ,
2752
+ } ) ,
2753
+ ) ) ;
2754
+ lcx. expr ( span, expr_kind)
2755
+ }
2756
+ ast:: Const :: No => lcx. expr (
2757
+ span,
2758
+ hir:: ExprKind :: Lit (
2759
+ lcx. arena . alloc ( hir:: Lit { span, node : ast:: LitKind :: Bool ( true ) } ) ,
2760
+ ) ,
2761
+ ) ,
2762
+ } ,
2763
+ )
2764
+ } ) ;
2765
+ let def_id =
2766
+ lcx. create_def ( lcx. current_hir_id_owner . def_id , id, DefPathData :: AnonConst , span) ;
2767
+ lcx. children . push ( ( def_id, hir:: MaybeOwner :: NonOwner ( hir_id) ) ) ;
2768
+ self . args . push ( hir:: GenericArg :: Const ( hir:: ConstArg {
2769
+ value : hir:: AnonConst { def_id, hir_id, body } ,
2770
+ span,
2771
+ } ) )
2772
+ }
2773
+
2705
2774
fn is_empty ( & self ) -> bool {
2706
2775
self . args . is_empty ( )
2707
2776
&& self . bindings . is_empty ( )
0 commit comments