Skip to content

Commit e014ac8

Browse files
Rollup merge of rust-lang#153421 - GokhanKabar:fix-delegation-ice, r=petrochenkov
Fix ICE in fn_delegation when child segment resolves to a trait Fixes rust-lang#153420 When a delegation path like `reuse Trait::<> as bar4` has only one segment resolving to a trait (not a function), the child args processing in `get_delegation_user_specified_args` called `lower_generic_args_of_path` with `self_ty = None`. Since the trait's generics have `has_self = true`, this triggered `assert!(self_ty.is_some())`. Fix by computing and providing `self_ty` when the child segment's `def_id` has `has_self`. In valid delegation code the child segment always resolves to a function, so this only affects error recovery.
2 parents 7189b44 + 86880c9 commit e014ac8

3 files changed

Lines changed: 51 additions & 24 deletions

File tree

compiler/rustc_hir_analysis/src/delegation.rs

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -597,31 +597,35 @@ fn get_delegation_user_specified_args<'tcx>(
597597
.as_slice()
598598
});
599599

600-
let child_args = info.child_args_segment_id.and_then(get_segment).map(|(segment, def_id)| {
601-
let parent_args = if let Some(parent_args) = parent_args {
602-
parent_args
603-
} else {
604-
let parent = tcx.parent(def_id);
605-
if matches!(tcx.def_kind(parent), DefKind::Trait) {
606-
ty::GenericArgs::identity_for_item(tcx, parent).as_slice()
600+
let child_args = info
601+
.child_args_segment_id
602+
.and_then(get_segment)
603+
.filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Fn | DefKind::AssocFn))
604+
.map(|(segment, def_id)| {
605+
let parent_args = if let Some(parent_args) = parent_args {
606+
parent_args
607607
} else {
608-
&[]
609-
}
610-
};
611-
612-
let args = lowerer
613-
.lower_generic_args_of_path(
614-
segment.ident.span,
615-
def_id,
616-
parent_args,
617-
segment,
618-
None,
619-
GenericArgPosition::Value,
620-
)
621-
.0;
622-
623-
&args[parent_args.len()..]
624-
});
608+
let parent = tcx.parent(def_id);
609+
if matches!(tcx.def_kind(parent), DefKind::Trait) {
610+
ty::GenericArgs::identity_for_item(tcx, parent).as_slice()
611+
} else {
612+
&[]
613+
}
614+
};
615+
616+
let args = lowerer
617+
.lower_generic_args_of_path(
618+
segment.ident.span,
619+
def_id,
620+
parent_args,
621+
segment,
622+
None,
623+
GenericArgPosition::Value,
624+
)
625+
.0;
626+
627+
&args[parent_args.len()..]
628+
});
625629

626630
(parent_args.unwrap_or_default(), child_args.unwrap_or_default())
627631
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ needs-rustc-debug-assertions
2+
#![feature(fn_delegation)]
3+
#![allow(incomplete_features)]
4+
5+
trait Trait {
6+
fn bar4();
7+
}
8+
9+
impl Trait for () {
10+
reuse Trait::<> as bar4;
11+
//~^ ERROR expected function, found trait `Trait`
12+
}
13+
14+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0423]: expected function, found trait `Trait`
2+
--> $DIR/reuse-trait-path-with-empty-generics.rs:10:11
3+
|
4+
LL | reuse Trait::<> as bar4;
5+
| ^^^^^^^^^ not a function
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0423`.

0 commit comments

Comments
 (0)