1- use super :: errors:: { InvalidAbi , InvalidAbiSuggestion , MisplacedRelaxTraitBound } ;
1+ use super :: errors:: { InvalidAbi , InvalidAbiReason , InvalidAbiSuggestion , MisplacedRelaxTraitBound } ;
22use super :: ResolverAstLoweringExt ;
33use super :: { AstOwner , ImplTraitContext , ImplTraitPosition } ;
44use super :: { FnDeclKind , LoweringContext , ParamMode } ;
@@ -90,6 +90,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
9090 allow_try_trait : Some ( [ sym:: try_trait_v2, sym:: yeet_desugar_details] [ ..] . into ( ) ) ,
9191 allow_gen_future,
9292 generics_def_id_map : Default :: default ( ) ,
93+ host_param_id : None ,
9394 } ;
9495 lctx. with_hir_id_owner ( owner, |lctx| f ( lctx) ) ;
9596
@@ -144,8 +145,24 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
144145 // This is used to track which lifetimes have already been defined,
145146 // and which need to be replicated when lowering an async fn.
146147
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+ _ => { }
149166 }
150167
151168 match ctxt {
@@ -389,6 +406,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
389406 self . lower_generics ( ast_generics, * constness, id, & itctx, |this| {
390407 let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
391408 this. lower_trait_ref (
409+ * constness,
392410 trait_ref,
393411 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Trait ) ,
394412 )
@@ -419,7 +437,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
419437 polarity,
420438 defaultness,
421439 defaultness_span,
422- constness : self . lower_constness ( * constness) ,
423440 generics,
424441 of_trait : trait_ref,
425442 self_ty : lowered_ty,
@@ -1254,8 +1271,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
12541271 }
12551272
12561273 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 ) ;
12591276 abi:: Abi :: Rust
12601277 } )
12611278 }
@@ -1268,7 +1285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12681285 }
12691286 }
12701287
1271- fn error_on_invalid_abi ( & self , abi : StrLit ) {
1288+ fn error_on_invalid_abi ( & self , abi : StrLit , err : abi :: AbiUnsupported ) {
12721289 let abi_names = abi:: enabled_names ( self . tcx . features ( ) , abi. span )
12731290 . iter ( )
12741291 . map ( |s| Symbol :: intern ( s) )
@@ -1277,6 +1294,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
12771294 self . tcx . sess . emit_err ( InvalidAbi {
12781295 abi : abi. symbol_unescaped ,
12791296 span : abi. span ,
1297+ explain : match err {
1298+ abi:: AbiUnsupported :: Reason { explain } => Some ( InvalidAbiReason ( explain) ) ,
1299+ _ => None ,
1300+ } ,
12801301 suggestion : suggested_name. map ( |suggested_name| InvalidAbiSuggestion {
12811302 span : abi. span ,
12821303 suggestion : format ! ( "\" {suggested_name}\" " ) ,
@@ -1363,6 +1384,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
13631384 }
13641385 }
13651386
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+
13661410 let mut predicates: SmallVec < [ hir:: WherePredicate < ' hir > ; 4 ] > = SmallVec :: new ( ) ;
13671411 predicates. extend ( generics. params . iter ( ) . filter_map ( |param| {
13681412 self . lower_generic_bound_predicate (
@@ -1410,22 +1454,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
14101454 let impl_trait_bounds = std:: mem:: take ( & mut self . impl_trait_bounds ) ;
14111455 predicates. extend ( impl_trait_bounds. into_iter ( ) ) ;
14121456
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 {
14241458 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) ;
14271461
1428- let hir_id = self . next_id ( ) ;
14291462 let const_id = self . next_id ( ) ;
14301463 let const_expr_id = self . next_id ( ) ;
14311464 let bool_id = self . next_id ( ) ;
@@ -1435,14 +1468,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
14351468
14361469 let attr_id = self . tcx . sess . parse_sess . attr_id_generator . mk_attr_id ( ) ;
14371470
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,
14411474 span,
1442- id : attr_id,
1443- style : AttrStyle :: Outer ,
1444- } ,
1445- ] ) ;
1475+ ) ) ) ) ,
1476+ span,
1477+ id : attr_id,
1478+ style : AttrStyle :: Outer ,
1479+ } ] ) ;
14461480 self . attrs . insert ( hir_id. local_id , attrs) ;
14471481
14481482 let const_body = self . lower_body ( |this| {
@@ -1481,7 +1515,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
14811515 } ) ,
14821516 ) ) ,
14831517 ) ) ,
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+ } ) ,
14851523 } ,
14861524 colon_span : None ,
14871525 pure_wrt_drop : false ,
0 commit comments