Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delegation: fix ICE with invalid MethodCall generation #138278

Merged
merged 1 commit into from
Mar 10, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions compiler/rustc_ast_lowering/src/delegation.rs
Original file line number Diff line number Diff line change
@@ -60,25 +60,27 @@ pub(crate) struct DelegationResults<'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 Ok(sig_id) = sig_id else {
return false;
};
self.has_self(sig_id, span)
self.is_method(sig_id, span)
}

fn has_self(&self, def_id: DefId, span: Span) -> bool {
if let Some(local_sig_id) = def_id.as_local() {
// The value may be missing due to recursive delegation.
// Error will be emitted later during HIR ty lowering.
self.resolver.delegation_fn_sigs.get(&local_sig_id).is_some_and(|sig| sig.has_self)
} else {
match self.tcx.def_kind(def_id) {
DefKind::Fn => false,
DefKind::AssocFn => self.tcx.associated_item(def_id).fn_has_self_parameter,
_ => span_bug!(span, "unexpected DefKind for delegation item"),
}
fn is_method(&self, def_id: DefId, span: Span) -> bool {
match self.tcx.def_kind(def_id) {
DefKind::Fn => false,
DefKind::AssocFn => match def_id.as_local() {
Some(local_def_id) => self
.resolver
.delegation_fn_sigs
.get(&local_def_id)
.is_some_and(|sig| sig.has_self),
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
.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()
&& delegation.qself.is_none()
&& !has_generic_args
4 changes: 2 additions & 2 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
@@ -871,7 +871,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
}
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(..) => {
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() }
}
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(..) => {
panic!("macros should have been expanded by now")
16 changes: 0 additions & 16 deletions tests/crashes/127916.rs

This file was deleted.

15 changes: 0 additions & 15 deletions tests/crashes/128119.rs

This file was deleted.

7 changes: 0 additions & 7 deletions tests/crashes/128190.rs

This file was deleted.

9 changes: 9 additions & 0 deletions tests/ui/delegation/ice-isssue-128190.rs
Original file line number Diff line number Diff line change
@@ -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() {}
10 changes: 10 additions & 0 deletions tests/ui/delegation/ice-isssue-128190.stderr
Original file line number Diff line number Diff line change
@@ -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

Loading
Oops, something went wrong.