@@ -46,19 +46,20 @@ use rustc_abi::ExternAbi;
4646use rustc_ast as ast;
4747use rustc_ast:: node_id:: NodeMap ;
4848use rustc_ast:: * ;
49- use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
49+ use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
5050use rustc_hir:: attrs:: { AttributeKind , InlineAttr } ;
5151use rustc_hir:: def_id:: { DefId , LocalDefId } ;
5252use rustc_hir:: { self as hir, FnDeclFlags } ;
5353use rustc_middle:: span_bug;
5454use rustc_middle:: ty:: { Asyncness , PerOwnerResolverData , TyCtxt } ;
5555use rustc_span:: symbol:: kw;
56- use rustc_span:: { ErrorGuaranteed , Ident , Span , Symbol } ;
56+ use rustc_span:: { ErrorGuaranteed , ExpnId , Ident , Span , Symbol } ;
5757
5858use crate :: delegation:: generics:: { GenericsGenerationResult , GenericsGenerationResults } ;
5959use crate :: diagnostics:: {
6060 CycleInDelegationSignatureResolution , DelegationAttemptedBlockWithDefsDeletion ,
61- DelegationBlockSpecifiedWhenNoParams , UnresolvedDelegationCallee ,
61+ DelegationBlockSpecifiedWhenNoParams , DelegationTargetExprDeletedEverywhere ,
62+ UnresolvedDelegationCallee ,
6263} ;
6364use crate :: {
6465 AllowReturnTypeNotation , ImplTraitContext , ImplTraitPosition , LoweringContext , ParamMode ,
@@ -168,6 +169,30 @@ fn check_for_cycles(tcx: TyCtxt<'_>, mut def_id: DefId, span: Span) -> Result<()
168169 }
169170}
170171
172+ pub ( crate ) fn check_unused_target_exprs_in_glob_delegations (
173+ tcx : TyCtxt < ' _ > ,
174+ delegations_ids : & FxIndexSet < LocalDefId > ,
175+ ) {
176+ let mut delegations_by_expansions = FxIndexMap :: default ( ) ;
177+ for & id in delegations_ids {
178+ let expn_id = tcx. expn_that_defined ( id) ;
179+ if expn_id == ExpnId :: root ( ) {
180+ continue ;
181+ }
182+
183+ let entry = delegations_by_expansions. entry ( expn_id) ;
184+ let entry = entry. or_insert_with ( || ( true , tcx. def_span ( id) ) ) ;
185+
186+ entry. 0 &= tcx. hir_opt_delegation_info ( id) . is_some_and ( |info| !info. generated_target_expr ) ;
187+ }
188+
189+ for ( _, state) in delegations_by_expansions {
190+ if state. 0 {
191+ tcx. dcx ( ) . emit_err ( DelegationTargetExprDeletedEverywhere { span : state. 1 } ) ;
192+ }
193+ }
194+ }
195+
171196impl < ' hir > LoweringContext < ' _ , ' hir > {
172197 fn is_method ( & self , def_id : DefId , span : Span ) -> bool {
173198 match self . tcx . def_kind ( def_id) {
@@ -213,6 +238,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
213238 self . lower_delegation_body ( delegation, sig_id, param_count, & mut generics, span) ;
214239
215240 let decl = self . lower_delegation_decl (
241+ delegation,
216242 sig_id,
217243 param_count,
218244 c_variadic,
@@ -375,6 +401,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
375401
376402 fn lower_delegation_decl (
377403 & mut self ,
404+ delegation : & Delegation ,
378405 sig_id : DefId ,
379406 param_count : usize ,
380407 c_variadic : bool ,
@@ -395,6 +422,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
395422 span,
396423 } ) ) ;
397424
425+ let is_method = self . is_method ( sig_id, span) ;
426+
427+ // Consider target expression generated if it was not specified, as now
428+ // it is used only for list/glob delegation's unused target expression diagnostic.
429+ let generated_target_expr = delegation. body . is_none ( )
430+ || ( param_count > 0 && self . should_generate_block ( delegation, sig_id, is_method) ) ;
431+
398432 let output = self . arena . alloc ( hir:: Ty {
399433 hir_id : self . next_id ( ) ,
400434 kind : hir:: TyKind :: InferDelegation ( hir:: InferDelegation :: Sig (
@@ -406,6 +440,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
406440 parent_args_segment_id : generics. parent . args_segment_id ,
407441 self_ty_id : generics. self_ty_id ,
408442 propagate_self_ty : generics. propagate_self_ty ,
443+ generated_target_expr,
409444 } ) ) ,
410445 ) ) ,
411446 span,
0 commit comments