Skip to content

Commit 904d77f

Browse files
committed
delegation: Implement multi-item delegation
```rust reuse prefix::{a, b, c} ```
1 parent 64743bc commit 904d77f

File tree

7 files changed

+137
-4
lines changed

7 files changed

+137
-4
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3108,12 +3108,19 @@ pub struct Fn {
31083108
pub body: Option<P<Block>>,
31093109
}
31103110

3111+
#[derive(Clone, Encodable, Decodable, Debug)]
3112+
pub enum DelegationKind {
3113+
Single,
3114+
List(ThinVec<Ident>),
3115+
}
3116+
31113117
#[derive(Clone, Encodable, Decodable, Debug)]
31123118
pub struct Delegation {
31133119
/// Path resolution id.
31143120
pub id: NodeId,
31153121
pub qself: Option<P<QSelf>>,
31163122
pub path: Path,
3123+
pub kind: DelegationKind,
31173124
pub body: Option<P<Block>>,
31183125
}
31193126

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,10 +1149,18 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
11491149
}
11501150
ItemKind::MacCall(m) => vis.visit_mac_call(m),
11511151
ItemKind::MacroDef(def) => vis.visit_macro_def(def),
1152-
ItemKind::Delegation(box Delegation { id, qself, path, body }) => {
1152+
ItemKind::Delegation(box Delegation { id, qself, path, kind, body }) => {
11531153
vis.visit_id(id);
11541154
vis.visit_qself(qself);
11551155
vis.visit_path(path);
1156+
match kind {
1157+
DelegationKind::Single => {}
1158+
DelegationKind::List(suffixes) => {
1159+
for ident in suffixes {
1160+
vis.visit_ident(ident);
1161+
}
1162+
}
1163+
}
11561164
if let Some(body) = body {
11571165
vis.visit_block(body);
11581166
}
@@ -1205,10 +1213,18 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
12051213
visit_opt(ty, |ty| visitor.visit_ty(ty));
12061214
}
12071215
AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
1208-
AssocItemKind::Delegation(box Delegation { id, qself, path, body }) => {
1216+
AssocItemKind::Delegation(box Delegation { id, qself, path, kind, body }) => {
12091217
visitor.visit_id(id);
12101218
visitor.visit_qself(qself);
12111219
visitor.visit_path(path);
1220+
match kind {
1221+
DelegationKind::Single => {}
1222+
DelegationKind::List(suffixes) => {
1223+
for ident in suffixes {
1224+
visitor.visit_ident(ident);
1225+
}
1226+
}
1227+
}
12121228
if let Some(body) = body {
12131229
visitor.visit_block(body);
12141230
}

compiler/rustc_ast/src/visit.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,19 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) -> V::Resu
382382
}
383383
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
384384
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
385-
ItemKind::Delegation(box Delegation { id, qself, path, body }) => {
385+
ItemKind::Delegation(box Delegation { id, qself, path, kind, body }) => {
386386
if let Some(qself) = qself {
387387
try_visit!(visitor.visit_ty(&qself.ty));
388388
}
389389
try_visit!(visitor.visit_path(path, *id));
390+
match kind {
391+
DelegationKind::Single => {}
392+
DelegationKind::List(suffixes) => {
393+
for ident in suffixes {
394+
visitor.visit_ident(*ident);
395+
}
396+
}
397+
}
390398
visit_opt!(visitor, visit_block, body);
391399
}
392400
ItemKind::DelegationList(box DelegationList { qself, prefix, suffixes, body }) => {
@@ -792,11 +800,19 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
792800
AssocItemKind::MacCall(mac) => {
793801
try_visit!(visitor.visit_mac_call(mac));
794802
}
795-
AssocItemKind::Delegation(box Delegation { id, qself, path, body }) => {
803+
AssocItemKind::Delegation(box Delegation { id, qself, path, kind, body }) => {
796804
if let Some(qself) = qself {
797805
try_visit!(visitor.visit_ty(&qself.ty));
798806
}
799807
try_visit!(visitor.visit_path(path, *id));
808+
match kind {
809+
DelegationKind::Single => {}
810+
DelegationKind::List(suffixes) => {
811+
for ident in suffixes {
812+
visitor.visit_ident(*ident);
813+
}
814+
}
815+
}
800816
visit_opt!(visitor, visit_block, body);
801817
}
802818
AssocItemKind::DelegationList(box DelegationList { qself, prefix, suffixes, body }) => {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//@ check-pass
2+
3+
#![feature(fn_delegation)]
4+
#![allow(incomplete_features)]
5+
6+
trait Trait {
7+
fn foo(&self) {}
8+
fn bar(&self) {}
9+
}
10+
11+
impl Trait for u8 {}
12+
13+
struct S(u8);
14+
15+
mod to_import {
16+
pub fn check(arg: &u8) -> &u8 { arg }
17+
}
18+
19+
impl Trait for S {
20+
reuse Trait::{foo, bar} {
21+
use to_import::check;
22+
23+
let _arr = Some(self.0).map(|x| [x * 2; 3]);
24+
check(&self.0)
25+
}
26+
}
27+
28+
fn main() {
29+
let s = S(0);
30+
s.foo();
31+
s.bar();
32+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![feature(fn_delegation)]
2+
#![allow(incomplete_features)]
3+
4+
mod m {}
5+
6+
reuse m::{}; //~ ERROR empty list delegation is not supported
7+
8+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: empty list delegation is not supported
2+
--> $DIR/multiple-names-empty.rs:6:1
3+
|
4+
LL | reuse m::{};
5+
| ^^^^^^^^^^^^
6+
7+
error: aborting due to 1 previous error
8+

tests/ui/delegation/multiple-names.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//@ check-pass
2+
3+
#![feature(fn_delegation)]
4+
#![allow(incomplete_features)]
5+
6+
trait Trait {
7+
fn foo(&self) -> u8 { 0 }
8+
fn bar(&self) -> u8 { 1 }
9+
}
10+
11+
impl Trait for u8 {}
12+
13+
struct S(u8);
14+
struct Z(u8);
15+
16+
impl Trait for S {
17+
reuse Trait::{foo, bar} { &self.0 }
18+
}
19+
20+
impl Trait for Z {
21+
reuse <u8 as Trait>::{foo, bar} { &self.0 }
22+
}
23+
24+
trait Trait2 where Self: Trait {
25+
reuse Trait::{foo, bar};
26+
}
27+
28+
mod to_reuse {
29+
pub fn a() {}
30+
pub fn b() {}
31+
}
32+
33+
reuse to_reuse::{a, b};
34+
35+
fn main() {
36+
let s = S(2);
37+
s.foo();
38+
s.bar();
39+
40+
let z = Z(3);
41+
z.foo();
42+
z.bar();
43+
44+
a();
45+
b();
46+
}

0 commit comments

Comments
 (0)