about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBryanskiy <ivakin.kir@gmail.com>2024-03-16 21:03:36 +0300
committerBryanskiy <ivakin.kir@gmail.com>2024-03-16 21:03:36 +0300
commitb2ed9d0911d010cd6aef2d038a47cb6294f0a443 (patch)
tree5a9f0a7a154b520a8aacdd14df975253ab97924b
parent66396725541ac7920439876fc79cbc7b604b82e0 (diff)
downloadrust-b2ed9d0911d010cd6aef2d038a47cb6294f0a443.tar.gz
rust-b2ed9d0911d010cd6aef2d038a47cb6294f0a443.zip
Delegation: fix ICE on duplicated associative items
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs14
-rw-r--r--tests/ui/delegation/duplicate-definition-inside-trait-impl.rs23
-rw-r--r--tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr23
3 files changed, 52 insertions, 8 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 52300138186..2d03c854bd0 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -373,6 +373,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         (trait_ref, lowered_ty)
                     });
 
+                self.is_in_trait_impl = trait_ref.is_some();
                 let new_impl_items = self
                     .arena
                     .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
@@ -978,13 +979,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
-        let trait_item_def_id = self
-            .resolver
-            .get_partial_res(i.id)
-            .map(|r| r.expect_full_res().opt_def_id())
-            .unwrap_or(None);
-        self.is_in_trait_impl = trait_item_def_id.is_some();
-
         hir::ImplItemRef {
             id: hir::ImplItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
             ident: self.lower_ident(i.ident),
@@ -1000,7 +994,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 },
                 AssocItemKind::MacCall(..) => unimplemented!(),
             },
-            trait_item_def_id,
+            trait_item_def_id: self
+                .resolver
+                .get_partial_res(i.id)
+                .map(|r| r.expect_full_res().opt_def_id())
+                .unwrap_or(None),
         }
     }
 
diff --git a/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs b/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs
new file mode 100644
index 00000000000..bd685b40b2f
--- /dev/null
+++ b/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs
@@ -0,0 +1,23 @@
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+trait Trait {
+    fn foo(&self) -> u32 { 0 }
+}
+
+struct F;
+struct S;
+
+mod to_reuse {
+    use crate::S;
+
+    pub fn foo(_: &S) -> u32 { 0 }
+}
+
+impl Trait for S {
+    reuse to_reuse::foo { self }
+    reuse Trait::foo;
+    //~^ ERROR  duplicate definitions with name `foo`
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr b/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr
new file mode 100644
index 00000000000..a5f9e6ad0bf
--- /dev/null
+++ b/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr
@@ -0,0 +1,23 @@
+error[E0201]: duplicate definitions with name `foo`:
+  --> $DIR/duplicate-definition-inside-trait-impl.rs:19:5
+   |
+LL |     fn foo(&self) -> u32 { 0 }
+   |     -------------------------- item in trait
+...
+LL |     reuse to_reuse::foo { self }
+   |     ---------------------------- previous definition here
+LL |     reuse Trait::foo;
+   |     ^^^^^^^^^^^^^^^^^ duplicate definition
+
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/duplicate-definition-inside-trait-impl.rs:1:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0201`.