Skip to content
/ rust Public
forked from rust-lang/rust

Commit bda1f2e

Browse files
authored
Rollup merge of rust-lang#157601 - aerooneqq:delegation-glob-useless-target-expr-error, r=petrochenkov
Emit error for unused target expression in glob and list delegations This PR emits error if unuse target expression is specified for glob delegation. Second part of rust-lang#156798. Part of rust-lang#118212. r? @petrochenkov
2 parents d88bf6d + 6708111 commit bda1f2e

19 files changed

Lines changed: 918 additions & 65 deletions

File tree

compiler/rustc_ast/src/ast.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ use rustc_data_structures::tagged_ptr::Tag;
3131
use rustc_macros::{Decodable, Encodable, StableHash, Walkable};
3232
pub use rustc_span::AttrId;
3333
use rustc_span::{
34-
ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Spanned, Symbol, kw, respan, sym,
34+
ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, LocalExpnId, Span, Spanned, Symbol, kw, respan,
35+
sym,
3536
};
3637
use thin_vec::{ThinVec, thin_vec};
3738

@@ -3906,10 +3907,10 @@ pub struct EiiImpl {
39063907
pub is_default: bool,
39073908
}
39083909

3909-
#[derive(Clone, Encodable, Decodable, Debug, Walkable, PartialEq, Eq)]
3910+
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
39103911
pub enum DelegationSource {
39113912
Single,
3912-
List,
3913+
List(LocalExpnId),
39133914
Glob,
39143915
}
39153916

@@ -3923,6 +3924,7 @@ pub struct Delegation {
39233924
pub rename: Option<Ident>,
39243925
pub body: Option<Box<Block>>,
39253926
/// The item was expanded from a glob delegation item.
3927+
#[visitable(ignore)]
39263928
pub source: DelegationSource,
39273929
}
39283930

compiler/rustc_ast/src/visit.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ macro_rules! common_visitor_and_walkers {
431431
Delegation,
432432
DelegationMac,
433433
DelegationSuffixes,
434-
DelegationSource,
435434
DelimArgs,
436435
DelimSpan,
437436
EnumDef,

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ use crate::diagnostics::{
6262
};
6363
use crate::{
6464
AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
65-
ResolverAstLoweringExt, index_crate,
65+
index_crate,
6666
};
6767

6868
mod generics;
@@ -126,7 +126,7 @@ pub(crate) fn delegations_resolutions(
126126
let delegation = ast_index[def_id].delegation().expect("processing delegations");
127127
let span = delegation.last_segment_span();
128128

129-
if let Some(info) = resolver.delegation_info(def_id) {
129+
if let Some(info) = tcx.resolutions(()).delegation_infos.get(&def_id) {
130130
let res = info.resolution_id.map(|id| check_for_cycles(tcx, id, span).map(|_| id));
131131
result.insert(def_id, res.flatten());
132132
} else {
@@ -143,16 +143,14 @@ pub(crate) fn delegations_resolutions(
143143
fn check_for_cycles(tcx: TyCtxt<'_>, mut def_id: DefId, span: Span) -> Result<(), ErrorGuaranteed> {
144144
let mut visited: FxHashSet<DefId> = Default::default();
145145

146-
let (resolver, _) = &*tcx.hir_crate(()).delayed_resolver.borrow();
147-
148146
loop {
149147
visited.insert(def_id);
150148

151149
// If def_id is in local crate and it corresponds to another delegation
152150
// it means that we refer to another delegation as a callee, so in order to obtain
153151
// a signature DefId we obtain NodeId of the callee delegation and try to get signature from it.
154152
if let Some(local_id) = def_id.as_local()
155-
&& let Some(info) = resolver.delegation_info(local_id)
153+
&& let Some(info) = tcx.resolutions(()).delegation_infos.get(&local_id)
156154
&& let Ok(id) = info.resolution_id
157155
{
158156
def_id = id;
@@ -209,17 +207,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
209207

210208
let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method);
211209

212-
let (body_id, call_expr_id) =
210+
let (body_id, call_expr_id, unused_target_expr) =
213211
self.lower_delegation_body(delegation, sig_id, param_count, &mut generics, span);
214212

215213
let decl = self.lower_delegation_decl(
214+
delegation.source,
216215
sig_id,
217216
param_count,
218217
c_variadic,
219218
span,
220219
&generics,
221220
delegation.id,
222221
call_expr_id,
222+
unused_target_expr,
223223
);
224224

225225
let sig = self.lower_delegation_sig(sig_id, decl, span);
@@ -375,13 +375,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
375375

376376
fn lower_delegation_decl(
377377
&mut self,
378+
source: DelegationSource,
378379
sig_id: DefId,
379380
param_count: usize,
380381
c_variadic: bool,
381382
span: Span,
382383
generics: &GenericsGenerationResults<'hir>,
383384
call_path_node_id: NodeId,
384385
call_expr_id: HirId,
386+
unused_target_expr: bool,
385387
) -> &'hir hir::FnDecl<'hir> {
386388
// The last parameter in C variadic functions is skipped in the signature,
387389
// like during regular lowering.
@@ -406,6 +408,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
406408
parent_args_segment_id: generics.parent.args_segment_id,
407409
self_ty_id: generics.self_ty_id,
408410
propagate_self_ty: generics.propagate_self_ty,
411+
group_id: {
412+
let id = match source {
413+
DelegationSource::Single => None,
414+
DelegationSource::List(expn_id) => Some(expn_id),
415+
DelegationSource::Glob => {
416+
Some(self.tcx.expn_that_defined(self.owner.def_id).expect_local())
417+
}
418+
};
419+
420+
id.map(|id| (id, unused_target_expr))
421+
},
409422
})),
410423
)),
411424
span,
@@ -504,16 +517,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
504517
param_count: usize,
505518
generics: &mut GenericsGenerationResults<'hir>,
506519
span: Span,
507-
) -> (BodyId, HirId) {
520+
) -> (BodyId, HirId, bool) {
508521
let block = delegation.body.as_deref();
509522
let mut call_expr_id = HirId::INVALID;
523+
let mut unused_target_expr = false;
510524

511525
let block_id = self.lower_body(|this| {
512526
let mut parameters: Vec<hir::Param<'_>> = Vec::with_capacity(param_count);
513527
let mut args: Vec<hir::Expr<'_>> = Vec::with_capacity(param_count);
514528
let mut stmts: &[hir::Stmt<'hir>] = &[];
515529

516530
let is_method = this.is_method(sig_id, span);
531+
let should_generate_block = this.should_generate_block(delegation, sig_id, is_method);
532+
533+
// Consider non-specified target expression as generated,
534+
// as we do not want to emit error when target expression is
535+
// not specified.
536+
unused_target_expr = block.is_some() && (param_count == 0 || !should_generate_block);
517537

518538
for idx in 0..param_count {
519539
let (param, pat_node_id) = this.generate_param(is_method, idx, span);
@@ -524,7 +544,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
524544

525545
let arg = if let Some(block) = block
526546
&& idx == 0
527-
&& this.should_generate_block(delegation, sig_id, is_method)
547+
&& should_generate_block
528548
{
529549
let mut self_resolver = SelfResolver {
530550
ctxt: this,
@@ -565,7 +585,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
565585

566586
debug_assert_ne!(call_expr_id, HirId::INVALID);
567587

568-
(block_id, call_expr_id)
588+
(block_id, call_expr_id, unused_target_expr)
569589
}
570590

571591
fn finalize_body_lowering(

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use rustc_macros::extension;
6363
use rustc_middle::hir::{self as mid_hir};
6464
use rustc_middle::queries::Providers;
6565
use rustc_middle::span_bug;
66-
use rustc_middle::ty::{DelegationInfo, PerOwnerResolverData, ResolverAstLowering, TyCtxt};
66+
use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt};
6767
use rustc_session::errors::add_feature_diagnostics;
6868
use rustc_span::symbol::{Ident, Symbol, kw, sym};
6969
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
@@ -307,10 +307,6 @@ impl<'tcx> ResolverAstLowering<'tcx> {
307307
self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..])
308308
}
309309

310-
fn delegation_info(&self, id: LocalDefId) -> Option<&DelegationInfo> {
311-
self.delegation_infos.get(&id)
312-
}
313-
314310
fn owner_def_id(&self, id: NodeId) -> LocalDefId {
315311
self.owners[&id].def_id
316312
}

compiler/rustc_expand/src/expand.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use rustc_ast::tokenstream::TokenStream;
88
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
99
use rustc_ast::{
1010
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrItemKind, AttrStyle, AttrVec,
11-
DUMMY_NODE_ID, DelegationSuffixes, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs,
12-
HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId,
13-
PatKind, StmtKind, TyKind, token,
11+
DUMMY_NODE_ID, DelegationSource, DelegationSuffixes, EarlyParsedAttribute, ExprKind,
12+
ForeignItemKind, HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner,
13+
MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind, token,
1414
};
1515
use rustc_ast_pretty::pprust;
1616
use rustc_attr_parsing::parser::AllowExprMetavar;
@@ -992,7 +992,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
992992

993993
type Node = AstNodeWrapper<Box<ast::AssocItem>, ImplItemTag>;
994994
let single_delegations = build_single_delegations::<Node>(
995-
self.cx, deleg, &item, &suffixes, item.span, true,
995+
self.cx,
996+
deleg,
997+
&item,
998+
&suffixes,
999+
item.span,
1000+
DelegationSource::Glob,
9961001
);
9971002
// `-Zmacro-stats` ignores these because they don't seem important.
9981003
fragment_kind.expect_from_annotatables(single_delegations.map(|item| {
@@ -2041,8 +2046,12 @@ fn build_single_delegations<'a, Node: InvocationCollectorNode>(
20412046
item: &'a ast::Item<Node::ItemKind>,
20422047
suffixes: &'a [(Ident, Option<Ident>)],
20432048
item_span: Span,
2044-
from_glob: bool,
2049+
source: DelegationSource,
20452050
) -> impl Iterator<Item = ast::Item<Node::ItemKind>> + 'a {
2051+
debug_assert_ne!(source, DelegationSource::Single);
2052+
2053+
let from_glob = source == DelegationSource::Glob;
2054+
20462055
if suffixes.is_empty() {
20472056
// Report an error for now, to avoid keeping stem for resolution and
20482057
// stability checks.
@@ -2066,11 +2075,7 @@ fn build_single_delegations<'a, Node: InvocationCollectorNode>(
20662075
ident: rename.unwrap_or(ident),
20672076
rename,
20682077
body: deleg.body.clone(),
2069-
source: if from_glob {
2070-
ast::DelegationSource::Glob
2071-
} else {
2072-
ast::DelegationSource::List
2073-
},
2078+
source,
20742079
})),
20752080
tokens: None,
20762081
}
@@ -2414,7 +2419,12 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
24142419
};
24152420

24162421
let single_delegations = build_single_delegations::<Node>(
2417-
self.cx, deleg, item, suffixes, item.span, false,
2422+
self.cx,
2423+
deleg,
2424+
item,
2425+
suffixes,
2426+
item.span,
2427+
DelegationSource::List(LocalExpnId::fresh_empty()),
24182428
);
24192429
Node::flatten_outputs(single_delegations.map(|item| {
24202430
let mut item = Node::from_item(item);

compiler/rustc_hir/src/hir.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ use rustc_index::IndexVec;
2525
use rustc_macros::{Decodable, Encodable, StableHash};
2626
use rustc_span::def_id::LocalDefId;
2727
use rustc_span::{
28-
BytePos, DUMMY_SP, DesugaringKind, ErrorGuaranteed, Ident, Span, Spanned, Symbol, kw, sym,
28+
BytePos, DUMMY_SP, DesugaringKind, ErrorGuaranteed, Ident, LocalExpnId, Span, Spanned, Symbol,
29+
kw, sym,
2930
};
3031
use rustc_target::asm::InlineAsmRegOrRegClass;
3132
use smallvec::SmallVec;
@@ -3877,6 +3878,7 @@ pub struct DelegationInfo {
38773878
pub child_args_segment_id: Option<HirId>,
38783879
pub self_ty_id: Option<HirId>,
38793880
pub propagate_self_ty: bool,
3881+
pub group_id: Option<(LocalExpnId, bool /* unused_target_expr */)>,
38803882
}
38813883

38823884
#[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)]

compiler/rustc_hir_analysis/src/delegation.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
use std::debug_assert_matches;
66

77
use rustc_data_structures::fx::FxHashMap;
8+
use rustc_hir::PathSegment;
89
use rustc_hir::def::DefKind;
910
use rustc_hir::def_id::{DefId, LocalDefId};
10-
use rustc_hir::{DelegationInfo, PathSegment};
1111
use rustc_middle::ty::{
1212
self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
1313
};
@@ -71,19 +71,6 @@ enum SelfPositionKind {
7171
None,
7272
}
7373

74-
pub fn opt_get_delegation_info(
75-
tcx: TyCtxt<'_>,
76-
delegation_id: LocalDefId,
77-
) -> Option<&DelegationInfo> {
78-
tcx.hir_node(tcx.local_def_id_to_hir_id(delegation_id))
79-
.fn_sig()
80-
.and_then(|sig| sig.decl.opt_delegation_info())
81-
}
82-
83-
fn get_delegation_info(tcx: TyCtxt<'_>, delegation_id: LocalDefId) -> &DelegationInfo {
84-
opt_get_delegation_info(tcx, delegation_id).expect("processing delegation")
85-
}
86-
8774
fn create_self_position_kind(
8875
tcx: TyCtxt<'_>,
8976
delegation_id: LocalDefId,
@@ -96,7 +83,7 @@ fn create_self_position_kind(
9683
| (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero,
9784

9885
(FnKind::Free, FnKind::AssocTrait) => {
99-
let propagate_self_ty = get_delegation_info(tcx, delegation_id).propagate_self_ty;
86+
let propagate_self_ty = tcx.hir_delegation_info(delegation_id).propagate_self_ty;
10087
SelfPositionKind::AfterLifetimes(propagate_self_ty)
10188
}
10289

@@ -282,7 +269,7 @@ fn get_parent_and_inheritance_kind<'tcx>(
282269
}
283270

284271
fn get_delegation_self_ty_or_err(tcx: TyCtxt<'_>, delegation_id: LocalDefId) -> Ty<'_> {
285-
get_delegation_info(tcx, delegation_id)
272+
tcx.hir_delegation_info(delegation_id)
286273
.self_ty_id
287274
.map(|id| {
288275
let ctx = ItemCtxt::new(tcx, delegation_id);
@@ -644,7 +631,7 @@ pub(crate) fn delegation_user_specified_args<'tcx>(
644631
tcx: TyCtxt<'tcx>,
645632
delegation_id: LocalDefId,
646633
) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericArg<'tcx>]) {
647-
let info = get_delegation_info(tcx, delegation_id);
634+
let info = tcx.hir_delegation_info(delegation_id);
648635

649636
let get_segment = |hir_id| -> Option<(&'tcx PathSegment<'tcx>, DefId)> {
650637
let segment = tcx.hir_node(hir_id).expect_path_segment();

compiler/rustc_hir_typeck/src/callee.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use rustc_hir::def::{self, CtorKind, Namespace, Res};
77
use rustc_hir::def_id::DefId;
88
use rustc_hir::{self as hir, HirId, LangItem, find_attr};
99
use rustc_hir_analysis::autoderef::Autoderef;
10-
use rustc_hir_analysis::delegation::opt_get_delegation_info;
1110
use rustc_infer::infer::BoundRegionConversionTime;
1211
use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode};
1312
use rustc_middle::ty::adjustment::{
@@ -701,7 +700,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
701700
// by comparing their hir ids (otherwise we will encounter errors in nested delegations,
702701
// see tests\ui\delegation\impl-reuse-pass.rs:237).
703702
let parent_def = self.tcx.hir_get_parent_item(call_expr.hir_id).def_id;
704-
let Some(info) = opt_get_delegation_info(self.tcx, parent_def) else { return None };
703+
let Some(info) = self.tcx.hir_opt_delegation_info(parent_def) else {
704+
return None;
705+
};
705706

706707
if call_expr.hir_id != info.call_expr_id {
707708
return None;

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_hir::def_id::DefId;
1313
use rustc_hir::intravisit::Visitor;
1414
use rustc_hir::{Expr, ExprKind, FnRetTy, HirId, LangItem, Node, QPath, is_range_literal};
1515
use rustc_hir_analysis::check::potentially_plural_count;
16-
use rustc_hir_analysis::delegation::opt_get_delegation_info;
1716
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, ResolvedStructPath};
1817
use rustc_index::IndexVec;
1918
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TypeTrace};
@@ -341,7 +340,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
341340

342341
// If we are processing first arg of delegation then we could have adjusted it
343342
// in `execute_delegation_aware_arguments_check`.
344-
let checked_ty = opt_get_delegation_info(self.tcx, self.body_id)
343+
let checked_ty = self
344+
.tcx
345+
.hir_opt_delegation_info(self.body_id)
345346
.and_then(|_| self.typeck_results.borrow().node_type_opt(provided_arg.hir_id))
346347
.unwrap_or_else(|| self.check_expr_with_expectation(provided_arg, expectation));
347348

compiler/rustc_interface/src/passes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,8 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10831083
// to use `hir_crate_items`.
10841084
tcx.ensure_done().hir_crate_items(());
10851085

1086+
rustc_passes::delegation::check_glob_and_list_delegations_target_expr(tcx);
1087+
10861088
let sess = tcx.sess;
10871089
sess.time("misc_checking_1", || {
10881090
par_fns(&mut [

0 commit comments

Comments
 (0)