about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBryanskiy <ivakin.kir@gmail.com>2025-03-10 17:08:29 +0300
committerBryanskiy <ivakin.kir@gmail.com>2025-03-10 17:08:29 +0300
commit61122d18298d1b82829a4717db896003b7d14c4d (patch)
tree5357f9744747d019546da118697feed6d2e7e432
parent30f168ef811aec63124eac677e14699baa9395bd (diff)
downloadrust-61122d18298d1b82829a4717db896003b7d14c4d.tar.gz
rust-61122d18298d1b82829a4717db896003b7d14c4d.zip
Delegation: fix ICE with invalid MethodCall generation
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs30
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs4
-rw-r--r--tests/crashes/127916.rs16
-rw-r--r--tests/crashes/128119.rs15
-rw-r--r--tests/crashes/128190.rs7
-rw-r--r--tests/ui/delegation/ice-isssue-128190.rs9
-rw-r--r--tests/ui/delegation/ice-isssue-128190.stderr10
7 files changed, 37 insertions, 54 deletions
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index d8b7cb0c322..571172be4ed 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -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
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 5e89321e6ec..b01ca54fb6f 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -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")
diff --git a/tests/crashes/127916.rs b/tests/crashes/127916.rs
deleted file mode 100644
index 295c88df857..00000000000
--- a/tests/crashes/127916.rs
+++ /dev/null
@@ -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 }
-}
diff --git a/tests/crashes/128119.rs b/tests/crashes/128119.rs
deleted file mode 100644
index 7677b15a2f3..00000000000
--- a/tests/crashes/128119.rs
+++ /dev/null
@@ -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 }
-}
diff --git a/tests/crashes/128190.rs b/tests/crashes/128190.rs
deleted file mode 100644
index 0fa7027ae60..00000000000
--- a/tests/crashes/128190.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ known-bug: rust-lang/rust#128190
-
-fn a(&self) {
-    15
-}
-
-reuse a as b {  struct S; }
diff --git a/tests/ui/delegation/ice-isssue-128190.rs b/tests/ui/delegation/ice-isssue-128190.rs
new file mode 100644
index 00000000000..dab3bbee663
--- /dev/null
+++ b/tests/ui/delegation/ice-isssue-128190.rs
@@ -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() {}
diff --git a/tests/ui/delegation/ice-isssue-128190.stderr b/tests/ui/delegation/ice-isssue-128190.stderr
new file mode 100644
index 00000000000..18f676642c2
--- /dev/null
+++ b/tests/ui/delegation/ice-isssue-128190.stderr
@@ -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
+