Skip to content

Commit 98da550

Browse files
authored
Rollup merge of #160853 - aerooneqq:delegation-fn-kind-matches, r=petrochenkov
delegation: simplify matches on `FnKind`, minor refactorings This PR refactors matches on `FnKind` making them smaller and more concise, next in all matches except `fn_kinds` function we no longer panic on delegation to inherent impls. And some minor renamings/refactorings. First step for #160505. Part of #118212. r? @petrochenkov
2 parents cc58c42 + d6e4a1d commit 98da550

1 file changed

Lines changed: 83 additions & 95 deletions

File tree

‎compiler/rustc_hir_analysis/src/delegation.rs‎

Lines changed: 83 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,23 @@ enum SelfPositionKind {
7171
None,
7272
}
7373

74-
fn create_self_position_kind(
74+
fn create_self_param_position_kind(
7575
tcx: TyCtxt<'_>,
76-
delegation_id: LocalDefId,
76+
def_id: LocalDefId,
7777
sig_id: DefId,
7878
) -> SelfPositionKind {
79-
match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) {
80-
(FnKind::AssocInherentImpl, FnKind::AssocTrait)
81-
| (FnKind::AssocTraitImpl, FnKind::AssocTrait)
82-
| (FnKind::AssocTrait, FnKind::AssocTrait)
83-
| (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero,
84-
79+
match fn_kinds(tcx, def_id, sig_id) {
8580
(FnKind::Free, FnKind::AssocTrait) => {
86-
let kind = tcx.hir_delegation_info(delegation_id).self_ty_propagation_kind;
81+
let kind = tcx.hir_delegation_info(def_id).self_ty_propagation_kind;
8782
SelfPositionKind::AfterLifetimes(kind)
8883
}
8984

85+
(_, FnKind::AssocTraitImpl) => unreachable!(),
86+
87+
(_, FnKind::AssocTrait) | (FnKind::AssocTrait, _) => SelfPositionKind::Zero,
88+
89+
(FnKind::AssocTraitImpl, _) => unreachable!(),
90+
9091
_ => SelfPositionKind::None,
9192
}
9293
}
@@ -116,6 +117,17 @@ fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> FnKind {
116117
}
117118
}
118119

120+
fn fn_kinds(tcx: TyCtxt<'_>, def_id: LocalDefId, sig_id: DefId) -> (FnKind, FnKind) {
121+
let kinds = (fn_kind(tcx, def_id), fn_kind(tcx, sig_id));
122+
123+
// For trait impl's `sig_id` is always equal to the corresponding trait method.
124+
assert!(!matches!(kinds, (_, FnKind::AssocTraitImpl)));
125+
// Delegation to inherent impls is not yet supported.
126+
assert!(!matches!(kinds, (_, FnKind::AssocInherentImpl)));
127+
128+
kinds
129+
}
130+
119131
/// Given the current context(caller and callee `FnKind`), it specifies
120132
/// the policy of predicates and generic parameters inheritance.
121133
#[derive(Clone, Copy, Debug, PartialEq)]
@@ -152,7 +164,7 @@ fn create_mapping<'tcx>(
152164
) -> FxHashMap<u32, u32> {
153165
let mut mapping: FxHashMap<u32, u32> = Default::default();
154166

155-
let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
167+
let self_pos_kind = create_self_param_position_kind(tcx, def_id, sig_id);
156168
let is_self_at_zero = matches!(self_pos_kind, SelfPositionKind::Zero);
157169

158170
// Is self at zero? If so insert mapping, self in sig parent is always at 0.
@@ -215,30 +227,24 @@ fn create_mapping<'tcx>(
215227

216228
fn get_delegation_parent_args_count_without_self<'tcx>(
217229
tcx: TyCtxt<'tcx>,
218-
delegation_id: LocalDefId,
230+
def_id: LocalDefId,
219231
sig_id: DefId,
220232
) -> usize {
221-
let delegation_parent_args_count = tcx.generics_of(delegation_id).parent_count;
233+
let kinds @ (def_kind, _) = fn_kinds(tcx, def_id, sig_id);
222234

223-
match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) {
224-
(FnKind::Free, FnKind::Free)
225-
| (FnKind::Free, FnKind::AssocTrait)
226-
| (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0,
235+
match kinds {
236+
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0,
227237

228-
(FnKind::AssocInherentImpl, FnKind::Free)
229-
| (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
230-
delegation_parent_args_count /* No Self in AssocInherentImpl */
231-
}
238+
(FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(),
232239

233-
(FnKind::AssocTrait, FnKind::Free) | (FnKind::AssocTrait, FnKind::AssocTrait) => {
234-
delegation_parent_args_count - 1 /* Without Self */
235-
}
240+
(FnKind::Free, _) => 0,
236241

237-
// For trait impl's `sig_id` is always equal to the corresponding trait method.
238-
// For inherent methods delegation is not yet supported.
239-
(FnKind::AssocTraitImpl, _)
240-
| (_, FnKind::AssocTraitImpl)
241-
| (_, FnKind::AssocInherentImpl) => unreachable!(),
242+
(_, _) => {
243+
let delegation_parent_args_count = tcx.generics_of(def_id).parent_count;
244+
let has_self = def_kind == FnKind::AssocTrait;
245+
246+
delegation_parent_args_count - usize::from(has_self)
247+
}
242248
}
243249
}
244250

@@ -247,75 +253,57 @@ fn get_parent_and_inheritance_kind<'tcx>(
247253
def_id: LocalDefId,
248254
sig_id: DefId,
249255
) -> (Option<DefId>, InheritanceKind) {
250-
match (fn_kind(tcx, def_id), fn_kind(tcx, sig_id)) {
251-
(FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
252-
(None, InheritanceKind::WithParent(true))
253-
}
256+
let kinds @ (_, sig_kind) = fn_kinds(tcx, def_id, sig_id);
254257

258+
match kinds {
255259
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
256260
(Some(tcx.parent(def_id.to_def_id())), InheritanceKind::Own)
257261
}
258262

259-
(FnKind::AssocInherentImpl, FnKind::AssocTrait)
260-
| (FnKind::AssocTrait, FnKind::AssocTrait)
261-
| (FnKind::AssocInherentImpl, FnKind::Free)
262-
| (FnKind::AssocTrait, FnKind::Free) => {
263-
(Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false))
263+
(FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(),
264+
265+
(FnKind::Free, _) => {
266+
let copy_self_clauses = sig_kind == FnKind::AssocTrait;
267+
(None, InheritanceKind::WithParent(copy_self_clauses))
264268
}
265269

266-
// For trait impl's `sig_id` is always equal to the corresponding trait method.
267-
// For inherent methods delegation is not yet supported.
268-
(FnKind::AssocTraitImpl, _)
269-
| (_, FnKind::AssocTraitImpl)
270-
| (_, FnKind::AssocInherentImpl) => unreachable!(),
270+
(_, _) => (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false)),
271271
}
272272
}
273273

274-
fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option<Ty<'tcx>> {
275-
let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id");
276-
let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
274+
fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Option<Ty<'tcx>> {
275+
let sig_id = tcx.hir_opt_delegation_sig_id(def_id).expect("processing delegation");
276+
let (caller_kind, callee_kind) = fn_kinds(tcx, def_id, sig_id);
277277

278278
match (caller_kind, callee_kind) {
279-
(FnKind::Free, FnKind::AssocTrait)
280-
| (FnKind::AssocInherentImpl, FnKind::Free)
281-
| (FnKind::Free, FnKind::Free)
282-
| (FnKind::AssocTrait, FnKind::Free)
283-
| (FnKind::AssocTrait, FnKind::AssocTrait) => {
284-
match create_self_position_kind(tcx, delegation_id, sig_id) {
285-
SelfPositionKind::None => None,
286-
SelfPositionKind::AfterLifetimes(propagation_kind) => {
287-
Some(match propagation_kind {
288-
Some(kind) => match kind {
289-
DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => {
290-
let ctx = ItemCtxt::new(tcx, delegation_id);
291-
ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty())
292-
}
293-
DelegationSelfTyPropagationKind::SelfParam => {
294-
let index = tcx.generics_of(delegation_id).own_counts().lifetimes;
295-
Ty::new_param(tcx, index as u32, kw::SelfUpper)
296-
}
297-
},
298-
None => Ty::new_error_with_message(
299-
tcx,
300-
tcx.def_span(delegation_id),
301-
"self propagation kind must be specified for `AfterLifetimes` variant",
302-
),
303-
})
304-
}
305-
SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)),
306-
}
279+
(FnKind::AssocTraitImpl, FnKind::AssocTrait) | (FnKind::AssocInherentImpl, _) => {
280+
Some(tcx.type_of(tcx.local_parent(def_id)).instantiate_identity().skip_norm_wip())
307281
}
308282

309-
(FnKind::AssocTraitImpl, FnKind::AssocTrait)
310-
| (FnKind::AssocInherentImpl, FnKind::AssocTrait) => Some(
311-
tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(),
312-
),
313-
314283
// For trait impl's `sig_id` is always equal to the corresponding trait method.
315-
// For inherent methods delegation is not yet supported.
316-
(FnKind::AssocTraitImpl, _)
317-
| (_, FnKind::AssocTraitImpl)
318-
| (_, FnKind::AssocInherentImpl) => unreachable!(),
284+
(FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(),
285+
286+
(_, _) => match create_self_param_position_kind(tcx, def_id, sig_id) {
287+
SelfPositionKind::None => None,
288+
SelfPositionKind::AfterLifetimes(propagation_kind) => Some(match propagation_kind {
289+
Some(kind) => match kind {
290+
DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => {
291+
let ctx = ItemCtxt::new(tcx, def_id);
292+
ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty())
293+
}
294+
DelegationSelfTyPropagationKind::SelfParam => {
295+
let index = tcx.generics_of(def_id).own_counts().lifetimes;
296+
Ty::new_param(tcx, index as u32, kw::SelfUpper)
297+
}
298+
},
299+
None => Ty::new_error_with_message(
300+
tcx,
301+
tcx.def_span(def_id),
302+
"self propagation kind must be specified for `AfterLifetimes` variant",
303+
),
304+
}),
305+
SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)),
306+
},
319307
}
320308
}
321309

@@ -337,12 +325,12 @@ fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) ->
337325
fn create_generic_args<'tcx>(
338326
tcx: TyCtxt<'tcx>,
339327
sig_id: DefId,
340-
delegation_id: LocalDefId,
328+
def_id: LocalDefId,
341329
mut parent_args: &[ty::GenericArg<'tcx>],
342330
mut child_args: &[ty::GenericArg<'tcx>],
343331
) -> (Vec<ty::GenericArg<'tcx>>, &'tcx [ty::GenericArg<'tcx>]) {
344-
let delegation_generics = tcx.generics_of(delegation_id);
345-
let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id);
332+
let delegation_generics = tcx.generics_of(def_id);
333+
let delegation_args = ty::GenericArgs::identity_for_item(tcx, def_id);
346334

347335
let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count();
348336
let synth_args = &delegation_args[real_args_count..];
@@ -352,12 +340,12 @@ fn create_generic_args<'tcx>(
352340

353341
let delegation_args = &delegation_args[delegation_generics.parent_count..];
354342

355-
let kinds = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
343+
let kinds = fn_kinds(tcx, def_id, sig_id);
356344
if matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) {
357345
// Special case, as user specifies Trait args in trait impl header, we want to treat
358346
// them as parent args. We always generate a function whose generics match
359347
// child generics in trait.
360-
let parent = tcx.local_parent(delegation_id);
348+
let parent = tcx.local_parent(def_id);
361349

362350
parent_args =
363351
tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args;
@@ -368,7 +356,7 @@ fn create_generic_args<'tcx>(
368356
delegation_parent_args = &[];
369357
}
370358

371-
let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into());
359+
let self_type = get_delegation_self_ty(tcx, def_id).map(ty::GenericArg::from);
372360

373361
// Remove `Self` from parent args (it is always at the `0th` index) as it is
374362
// added manually.
@@ -377,7 +365,7 @@ fn create_generic_args<'tcx>(
377365
}
378366

379367
let (zero_self, after_lifetimes_self) =
380-
match create_self_position_kind(tcx, delegation_id, sig_id) {
368+
match create_self_param_position_kind(tcx, def_id, sig_id) {
381369
SelfPositionKind::AfterLifetimes(_) => {
382370
assert!(self_type.is_some());
383371
(None, self_type)
@@ -505,7 +493,7 @@ pub(crate) fn inherit_clauses_for_delegation_item<'tcx>(
505493

506494
let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
507495
let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
508-
let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
496+
let self_pos_kind = create_self_param_position_kind(tcx, def_id, sig_id);
509497
let filter_self_clauses = matches!(
510498
self_pos_kind,
511499
SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..)))
@@ -584,7 +572,6 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
584572
) -> &'tcx [Ty<'tcx>] {
585573
let sig_id = tcx.hir_opt_delegation_sig_id(def_id).expect("Delegation must have sig_id");
586574
let caller_sig = tcx.fn_sig(sig_id);
587-
588575
if let Err(err) = check_constraints(tcx, def_id, sig_id) {
589576
let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1;
590577
let err_type = Ty::new_error(tcx, err);
@@ -606,23 +593,24 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
606593
// we want to extract [Self, 'static, i32, 1] for parent and [A, B] for child.
607594
pub(crate) fn delegation_user_specified_args<'tcx>(
608595
tcx: TyCtxt<'tcx>,
609-
delegation_id: LocalDefId,
596+
def_id: LocalDefId,
610597
) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericArg<'tcx>]) {
611-
let info = tcx.hir_delegation_info(delegation_id);
598+
let info = tcx.hir_delegation_info(def_id);
612599

613600
let get_segment = |hir_id| -> Option<(&'tcx PathSegment<'tcx>, DefId)> {
614601
let segment = tcx.hir_node(hir_id).expect_path_segment();
615602
segment.res.opt_def_id().map(|def_id| (segment, def_id))
616603
};
617604

618-
let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id);
605+
let ctx = ItemCtxt::new_for_delegation(tcx, def_id);
619606
let lowerer = ctx.lowerer();
620607
let parent_args = info
621608
.parent_seg_id_for_sig
622609
.and_then(get_segment)
623610
.filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Trait))
624611
.map(|(segment, def_id)| {
625-
let self_ty = get_delegation_self_ty(tcx, delegation_id);
612+
let self_ty = (tcx.def_kind(def_id) == DefKind::Trait)
613+
.then(|| Ty::new_param(tcx, 0, kw::SelfUpper));
626614

627615
lowerer
628616
.lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty)

0 commit comments

Comments
 (0)