Skip to content

Commit 7b7a7fc

Browse files
authored
Rollup merge of #122564 - Bryanskiy:delegation-fixes, r=compiler-errors
Delegation: fix ICE on duplicated associative items Currently, functions delegation is only supported for delegation items with early resolved paths e.g. free functions and trait methods. During name resolution, information about function signatures is collected, including the number of parameters and whether there are self arguments. This information is then used when lowering from a delegation item into a regular function(`rustc_ast_lowering/src/delegation.rs`). The signature is usually inherited from path resolution id(`path_id`). However, in the case of trait impls `path_id` and `item_id` may be different: ```rust trait Trait { fn foo(&self) -> u32 { 0 } } struct S; mod to_reuse { use crate::S; pub fn foo(_: &S) -> u32 { 0 } } impl Trait for S { reuse to_reuse::foo { self } //~^ The signature should be inherited from item id instead of resolution id } ``` Let's now consider an example from [issue](#119920). Due to duplicated associative elements partial resolution for one of them will not be recorded: https://github.com/rust-lang/rust/blob/9023f908cfbe7a475f369717a61cb8eb865cfd25/compiler/rustc_resolve/src/late.rs#L3153-L3162 Which leads to an incorrect `is_in_trait_impl` https://github.com/rust-lang/rust/blob/9023f908cfbe7a475f369717a61cb8eb865cfd25/compiler/rustc_ast_lowering/src/item.rs#L981-L986 Which leads to an incorrect id for signature inheritance https://github.com/rust-lang/rust/blob/9023f908cfbe7a475f369717a61cb8eb865cfd25/compiler/rustc_ast_lowering/src/delegation.rs#L99-L105 Which lead to an ICE from original issue. This patch fixes wrong `is_in_trait_impl` calculation. fixes #119920
2 parents c2b7d77 + b2ed9d0 commit 7b7a7fc

File tree

3 files changed

+52
-8
lines changed

3 files changed

+52
-8
lines changed

compiler/rustc_ast_lowering/src/item.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
373373
(trait_ref, lowered_ty)
374374
});
375375

376+
self.is_in_trait_impl = trait_ref.is_some();
376377
let new_impl_items = self
377378
.arena
378379
.alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
@@ -978,13 +979,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
978979
}
979980

980981
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
981-
let trait_item_def_id = self
982-
.resolver
983-
.get_partial_res(i.id)
984-
.map(|r| r.expect_full_res().opt_def_id())
985-
.unwrap_or(None);
986-
self.is_in_trait_impl = trait_item_def_id.is_some();
987-
988982
hir::ImplItemRef {
989983
id: hir::ImplItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
990984
ident: self.lower_ident(i.ident),
@@ -1000,7 +994,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
1000994
},
1001995
AssocItemKind::MacCall(..) => unimplemented!(),
1002996
},
1003-
trait_item_def_id,
997+
trait_item_def_id: self
998+
.resolver
999+
.get_partial_res(i.id)
1000+
.map(|r| r.expect_full_res().opt_def_id())
1001+
.unwrap_or(None),
10041002
}
10051003
}
10061004

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![feature(fn_delegation)]
2+
//~^ WARN the feature `fn_delegation` is incomplete
3+
4+
trait Trait {
5+
fn foo(&self) -> u32 { 0 }
6+
}
7+
8+
struct F;
9+
struct S;
10+
11+
mod to_reuse {
12+
use crate::S;
13+
14+
pub fn foo(_: &S) -> u32 { 0 }
15+
}
16+
17+
impl Trait for S {
18+
reuse to_reuse::foo { self }
19+
reuse Trait::foo;
20+
//~^ ERROR duplicate definitions with name `foo`
21+
}
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0201]: duplicate definitions with name `foo`:
2+
--> $DIR/duplicate-definition-inside-trait-impl.rs:19:5
3+
|
4+
LL | fn foo(&self) -> u32 { 0 }
5+
| -------------------------- item in trait
6+
...
7+
LL | reuse to_reuse::foo { self }
8+
| ---------------------------- previous definition here
9+
LL | reuse Trait::foo;
10+
| ^^^^^^^^^^^^^^^^^ duplicate definition
11+
12+
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
13+
--> $DIR/duplicate-definition-inside-trait-impl.rs:1:12
14+
|
15+
LL | #![feature(fn_delegation)]
16+
| ^^^^^^^^^^^^^
17+
|
18+
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
19+
= note: `#[warn(incomplete_features)]` on by default
20+
21+
error: aborting due to 1 previous error; 1 warning emitted
22+
23+
For more information about this error, try `rustc --explain E0201`.

0 commit comments

Comments
 (0)