Rollup merge of #138278 - Bryanskiy:delegation-ice-1, r=petrochenkov

Delegation: fix ICE with invalid `MethodCall` generation

`ExprKind::MethodCall` is now generated instead of `ExprKind::Call` if
- the resolved function has a `&self` argument
- the resolved function is an associated item <- was missed before

Fixes https://github.com/rust-lang/rust/issues/128190
Fixes https://github.com/rust-lang/rust/issues/128119
Fixes https://github.com/rust-lang/rust/issues/127916

r? `@petrochenkov`
This commit is contained in:
Matthias Krüger 2025-03-10 15:57:14 +01:00 committed by GitHub
commit 0d6311931b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 37 additions and 54 deletions

View file

@ -60,25 +60,27 @@ pub(crate) struct DelegationResults<'hir> {
} }
impl<'hir> LoweringContext<'_, 'hir> { impl<'hir> LoweringContext<'_, 'hir> {
pub(crate) fn delegation_has_self(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool { /// Defines whether the delegatee is an associated function whose first parameter is `self`.
pub(crate) fn delegatee_is_method(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool {
let sig_id = self.get_delegation_sig_id(item_id, path_id, span); let sig_id = self.get_delegation_sig_id(item_id, path_id, span);
let Ok(sig_id) = sig_id else { let Ok(sig_id) = sig_id else {
return false; return false;
}; };
self.has_self(sig_id, span) self.is_method(sig_id, span)
} }
fn has_self(&self, def_id: DefId, span: Span) -> bool { fn is_method(&self, def_id: DefId, span: Span) -> bool {
if let Some(local_sig_id) = def_id.as_local() { match self.tcx.def_kind(def_id) {
// The value may be missing due to recursive delegation. DefKind::Fn => false,
// Error will be emitted later during HIR ty lowering. DefKind::AssocFn => match def_id.as_local() {
self.resolver.delegation_fn_sigs.get(&local_sig_id).is_some_and(|sig| sig.has_self) Some(local_def_id) => self
} else { .resolver
match self.tcx.def_kind(def_id) { .delegation_fn_sigs
DefKind::Fn => false, .get(&local_def_id)
DefKind::AssocFn => self.tcx.associated_item(def_id).fn_has_self_parameter, .is_some_and(|sig| sig.has_self),
_ => span_bug!(span, "unexpected DefKind for delegation item"), None => self.tcx.associated_item(def_id).fn_has_self_parameter,
} },
_ => span_bug!(span, "unexpected DefKind for delegation item"),
} }
} }
@ -324,7 +326,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let call = if self let call = if self
.get_resolution_id(delegation.id, span) .get_resolution_id(delegation.id, span)
.and_then(|def_id| Ok(self.has_self(def_id, span))) .and_then(|def_id| Ok(self.is_method(def_id, span)))
.unwrap_or_default() .unwrap_or_default()
&& delegation.qself.is_none() && delegation.qself.is_none()
&& !has_generic_args && !has_generic_args

View file

@ -871,7 +871,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
} }
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn { AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegation_has_self(i.id, delegation.id, i.span), has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
}, },
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now") panic!("macros should have been expanded by now")
@ -1000,7 +1000,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
} }
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn { AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegation_has_self(i.id, delegation.id, i.span), has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
}, },
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now") panic!("macros should have been expanded by now")

View file

@ -1,16 +0,0 @@
//@ known-bug: #127916
trait Trait {
fn foo(&self) -> u32 { 0 }
}
struct F;
struct S;
mod to_reuse {
pub fn foo(&self) -> u32 {}
}
impl Trait S {
reuse to_reuse::foo { self }
}

View file

@ -1,15 +0,0 @@
//@ known-bug: #128119
trait Trait {
reuse to_reuse::foo { self }
}
struct S;
mod to_reuse {
pub fn foo(&self) -> u32 {}
}
impl Trait S {
reuse to_reuse::foo { self }
}

View file

@ -1,7 +0,0 @@
//@ known-bug: rust-lang/rust#128190
fn a(&self) {
15
}
reuse a as b { struct S; }

View file

@ -0,0 +1,9 @@
#![feature(fn_delegation)]
#![allow(incomplete_features)]
fn a(&self) {}
//~^ ERROR `self` parameter is only allowed in associated functions
reuse a as b;
fn main() {}

View file

@ -0,0 +1,10 @@
error: `self` parameter is only allowed in associated functions
--> $DIR/ice-isssue-128190.rs:4:6
|
LL | fn a(&self) {}
| ^^^^^ not semantically valid as function parameter
|
= note: associated functions are those in `impl` or `trait` definitions
error: aborting due to 1 previous error