1
- use super :: errors:: { InvalidAbi , InvalidAbiSuggestion , MisplacedRelaxTraitBound } ;
1
+ use super :: errors:: { InvalidAbi , InvalidAbiReason , InvalidAbiSuggestion , MisplacedRelaxTraitBound } ;
2
2
use super :: ResolverAstLoweringExt ;
3
3
use super :: { AstOwner , ImplTraitContext , ImplTraitPosition } ;
4
4
use super :: { FnDeclKind , LoweringContext , ParamMode } ;
@@ -90,6 +90,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
90
90
allow_try_trait : Some ( [ sym:: try_trait_v2, sym:: yeet_desugar_details] [ ..] . into ( ) ) ,
91
91
allow_gen_future,
92
92
generics_def_id_map : Default :: default ( ) ,
93
+ host_param_id : None ,
93
94
} ;
94
95
lctx. with_hir_id_owner ( owner, |lctx| f ( lctx) ) ;
95
96
@@ -144,8 +145,24 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
144
145
// This is used to track which lifetimes have already been defined,
145
146
// and which need to be replicated when lowering an async fn.
146
147
147
- if let hir:: ItemKind :: Impl ( impl_) = parent_hir. node ( ) . expect_item ( ) . kind {
148
- lctx. is_in_trait_impl = impl_. of_trait . is_some ( ) ;
148
+ match parent_hir. node ( ) . expect_item ( ) . kind {
149
+ hir:: ItemKind :: Impl ( impl_) => {
150
+ lctx. is_in_trait_impl = impl_. of_trait . is_some ( ) ;
151
+ }
152
+ hir:: ItemKind :: Trait ( _, _, generics, _, _) if lctx. tcx . features ( ) . effects => {
153
+ lctx. host_param_id = generics
154
+ . params
155
+ . iter ( )
156
+ . find ( |param| {
157
+ parent_hir
158
+ . attrs
159
+ . get ( param. hir_id . local_id )
160
+ . iter ( )
161
+ . any ( |attr| attr. has_name ( sym:: rustc_host) )
162
+ } )
163
+ . map ( |param| param. def_id ) ;
164
+ }
165
+ _ => { }
149
166
}
150
167
151
168
match ctxt {
@@ -389,6 +406,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
389
406
self . lower_generics ( ast_generics, * constness, id, & itctx, |this| {
390
407
let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
391
408
this. lower_trait_ref (
409
+ * constness,
392
410
trait_ref,
393
411
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Trait ) ,
394
412
)
@@ -419,7 +437,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
419
437
polarity,
420
438
defaultness,
421
439
defaultness_span,
422
- constness : self . lower_constness ( * constness) ,
423
440
generics,
424
441
of_trait : trait_ref,
425
442
self_ty : lowered_ty,
@@ -1254,8 +1271,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
1254
1271
}
1255
1272
1256
1273
pub ( super ) fn lower_abi ( & mut self , abi : StrLit ) -> abi:: Abi {
1257
- abi:: lookup ( abi. symbol_unescaped . as_str ( ) ) . unwrap_or_else ( || {
1258
- self . error_on_invalid_abi ( abi) ;
1274
+ abi:: lookup ( abi. symbol_unescaped . as_str ( ) ) . unwrap_or_else ( |err | {
1275
+ self . error_on_invalid_abi ( abi, err ) ;
1259
1276
abi:: Abi :: Rust
1260
1277
} )
1261
1278
}
@@ -1268,7 +1285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1268
1285
}
1269
1286
}
1270
1287
1271
- fn error_on_invalid_abi ( & self , abi : StrLit ) {
1288
+ fn error_on_invalid_abi ( & self , abi : StrLit , err : abi :: AbiUnsupported ) {
1272
1289
let abi_names = abi:: enabled_names ( self . tcx . features ( ) , abi. span )
1273
1290
. iter ( )
1274
1291
. map ( |s| Symbol :: intern ( s) )
@@ -1277,6 +1294,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
1277
1294
self . tcx . sess . emit_err ( InvalidAbi {
1278
1295
abi : abi. symbol_unescaped ,
1279
1296
span : abi. span ,
1297
+ explain : match err {
1298
+ abi:: AbiUnsupported :: Reason { explain } => Some ( InvalidAbiReason ( explain) ) ,
1299
+ _ => None ,
1300
+ } ,
1280
1301
suggestion : suggested_name. map ( |suggested_name| InvalidAbiSuggestion {
1281
1302
span : abi. span ,
1282
1303
suggestion : format ! ( "\" {suggested_name}\" " ) ,
@@ -1363,6 +1384,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
1363
1384
}
1364
1385
}
1365
1386
1387
+ // Desugar `~const` bound in generics into an additional `const host: bool` param
1388
+ // if the effects feature is enabled. This needs to be done before we lower where
1389
+ // clauses since where clauses need to bind to the DefId of the host param
1390
+ let host_param_parts = if let Const :: Yes ( span) = constness && self . tcx . features ( ) . effects {
1391
+ if let Some ( param) = generics. params . iter ( ) . find ( |x| {
1392
+ x. attrs . iter ( ) . any ( |x| x. has_name ( sym:: rustc_host) )
1393
+ } ) {
1394
+ // user has manually specified a `rustc_host` param, in this case, we set
1395
+ // the param id so that lowering logic can use that. But we don't create
1396
+ // another host param, so this gives `None`.
1397
+ self . host_param_id = Some ( self . local_def_id ( param. id ) ) ;
1398
+ None
1399
+ } else {
1400
+ let param_node_id = self . next_node_id ( ) ;
1401
+ let hir_id = self . next_id ( ) ;
1402
+ let def_id = self . create_def ( self . local_def_id ( parent_node_id) , param_node_id, DefPathData :: TypeNs ( sym:: host) , span) ;
1403
+ self . host_param_id = Some ( def_id) ;
1404
+ Some ( ( span, hir_id, def_id) )
1405
+ }
1406
+ } else {
1407
+ None
1408
+ } ;
1409
+
1366
1410
let mut predicates: SmallVec < [ hir:: WherePredicate < ' hir > ; 4 ] > = SmallVec :: new ( ) ;
1367
1411
predicates. extend ( generics. params . iter ( ) . filter_map ( |param| {
1368
1412
self . lower_generic_bound_predicate (
@@ -1410,22 +1454,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
1410
1454
let impl_trait_bounds = std:: mem:: take ( & mut self . impl_trait_bounds ) ;
1411
1455
predicates. extend ( impl_trait_bounds. into_iter ( ) ) ;
1412
1456
1413
- // Desugar `~const` bound in generics into an additional `const host: bool` param
1414
- // if the effects feature is enabled.
1415
- if let Const :: Yes ( span) = constness && self . tcx . features ( ) . effects
1416
- // Do not add host param if it already has it (manually specified)
1417
- && !params. iter ( ) . any ( |x| {
1418
- self . attrs . get ( & x. hir_id . local_id ) . map_or ( false , |attrs| {
1419
- attrs. iter ( ) . any ( |x| x. has_name ( sym:: rustc_host) )
1420
- } )
1421
- } )
1422
- {
1423
- let param_node_id = self . next_node_id ( ) ;
1457
+ if let Some ( ( span, hir_id, def_id) ) = host_param_parts {
1424
1458
let const_node_id = self . next_node_id ( ) ;
1425
- let def_id = self . create_def ( self . local_def_id ( parent_node_id ) , param_node_id , DefPathData :: TypeNs ( sym :: host ) , span ) ;
1426
- let anon_const : LocalDefId = self . create_def ( def_id, const_node_id, DefPathData :: AnonConst , span) ;
1459
+ let anon_const : LocalDefId =
1460
+ self . create_def ( def_id, const_node_id, DefPathData :: AnonConst , span) ;
1427
1461
1428
- let hir_id = self . next_id ( ) ;
1429
1462
let const_id = self . next_id ( ) ;
1430
1463
let const_expr_id = self . next_id ( ) ;
1431
1464
let bool_id = self . next_id ( ) ;
@@ -1435,14 +1468,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
1435
1468
1436
1469
let attr_id = self . tcx . sess . parse_sess . attr_id_generator . mk_attr_id ( ) ;
1437
1470
1438
- let attrs = self . arena . alloc_from_iter ( [
1439
- Attribute {
1440
- kind : AttrKind :: Normal ( P ( NormalAttr :: from_ident ( Ident :: new ( sym:: rustc_host, span ) ) ) ) ,
1471
+ let attrs = self . arena . alloc_from_iter ( [ Attribute {
1472
+ kind : AttrKind :: Normal ( P ( NormalAttr :: from_ident ( Ident :: new (
1473
+ sym:: rustc_host,
1441
1474
span,
1442
- id : attr_id,
1443
- style : AttrStyle :: Outer ,
1444
- } ,
1445
- ] ) ;
1475
+ ) ) ) ) ,
1476
+ span,
1477
+ id : attr_id,
1478
+ style : AttrStyle :: Outer ,
1479
+ } ] ) ;
1446
1480
self . attrs . insert ( hir_id. local_id , attrs) ;
1447
1481
1448
1482
let const_body = self . lower_body ( |this| {
@@ -1481,7 +1515,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
1481
1515
} ) ,
1482
1516
) ) ,
1483
1517
) ) ,
1484
- default : Some ( hir:: AnonConst { def_id : anon_const, hir_id : const_id, body : const_body } ) ,
1518
+ default : Some ( hir:: AnonConst {
1519
+ def_id : anon_const,
1520
+ hir_id : const_id,
1521
+ body : const_body,
1522
+ } ) ,
1485
1523
} ,
1486
1524
colon_span : None ,
1487
1525
pure_wrt_drop : false ,
0 commit comments