Skip to content

Commit 1860cb7

Browse files
committed
delegation: Give declaration of self syntax context of the delegation body
Instead of the last segment of the delegation path. `self` is something that introduced by the whole delegation item, not some specific part of it, and the last segment may need to have a different context for path resolution purposes.
1 parent efb40b1 commit 1860cb7

4 files changed

Lines changed: 108 additions & 27 deletions

File tree

compiler/rustc_resolve/src/late.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3848,8 +3848,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38483848

38493849
let Some(body) = &delegation.body else { return };
38503850
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
3851-
let span = delegation.path.segments.last().unwrap().ident.span;
3852-
let ident = Ident::new(kw::SelfLower, span.normalize_to_macro_rules());
3851+
let ident = Ident::new(kw::SelfLower, body.span.normalize_to_macro_rules());
38533852
let res = Res::Local(delegation.id);
38543853
this.innermost_rib_bindings(ValueNS).insert(ident, res);
38553854

tests/ui/delegation/impl-reuse-pass.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -173,19 +173,6 @@ mod macros {
173173
macro_rules! m { () => { M } }
174174
reuse impl Trait for m!() { self_0_ref!(self) }
175175

176-
struct S1(u8);
177-
macro_rules! one_line_reuse { ($self:ident) => { reuse impl Trait for S1 { $self.0 } } }
178-
one_line_reuse!(self);
179-
180-
struct S2(u8);
181-
macro_rules! one_line_reuse_expr { ($x:expr) => { reuse impl Trait for S2 { $x } } }
182-
one_line_reuse_expr!(self.0);
183-
184-
struct S3(u8);
185-
macro_rules! s3 { () => { S3 } }
186-
macro_rules! one_line_reuse_expr2 { ($x:expr) => { reuse impl Trait for s3!() { $x } } }
187-
one_line_reuse_expr2!(self.0);
188-
189176
fn f() {
190177
let s = S(1);
191178
s.foo();
@@ -194,18 +181,6 @@ mod macros {
194181
let m = M(41);
195182
m.foo();
196183
m.bar();
197-
198-
let s1 = S1(2);
199-
s1.foo();
200-
s1.bar();
201-
202-
let s2 = S2(4);
203-
s2.foo();
204-
s2.bar();
205-
206-
let s3 = S3(5);
207-
s3.foo();
208-
s3.bar();
209184
}
210185
}
211186

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#![allow(incomplete_features)]
2+
#![feature(fn_delegation)]
3+
4+
trait Trait {
5+
fn foo(&self) -> u8 { 0 }
6+
fn bar(&self) -> u8 { 1 }
7+
}
8+
9+
// impl Trait for u8 {}
10+
// struct S(u8);
11+
12+
// macro_rules! self_0_ref { ($self:ident) => { &$self.0 } }
13+
14+
// reuse impl Trait for S { self_0_ref!(self) }
15+
16+
// struct M(u8);
17+
// macro_rules! m { () => { M } }
18+
// reuse impl Trait for m!() { self_0_ref!(self) }
19+
20+
struct S1(u8);
21+
macro_rules! one_line_reuse { ($self:ident) => { reuse impl Trait for S1 { $self.0 } } }
22+
//~^ ERROR expected value, found module `self`
23+
//~| ERROR expected value, found module `self`
24+
one_line_reuse!(self);
25+
26+
struct S2(u8);
27+
macro_rules! one_line_reuse_expr { ($x:expr) => { reuse impl Trait for S2 { $x } } }
28+
one_line_reuse_expr!(self.0);
29+
//~^ ERROR expected value, found module `self`
30+
//~| ERROR expected value, found module `self`
31+
32+
struct S3(u8);
33+
macro_rules! s3 { () => { S3 } }
34+
macro_rules! one_line_reuse_expr2 { ($x:expr) => { reuse impl Trait for s3!() { $x } } }
35+
one_line_reuse_expr2!(self.0);
36+
//~^ ERROR expected value, found module `self`
37+
//~| ERROR expected value, found module `self`
38+
39+
fn main() {}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
error[E0424]: expected value, found module `self`
2+
--> $DIR/impl-reuse-self-hygiene.rs:21:76
3+
|
4+
LL | macro_rules! one_line_reuse { ($self:ident) => { reuse impl Trait for S1 { $self.0 } } }
5+
| --------------------------^^^^^----
6+
| | |
7+
| | `self` value is a keyword only available in methods with a `self` parameter
8+
| `self` not allowed in an implementation
9+
...
10+
LL | one_line_reuse!(self);
11+
| --------------------- in this macro invocation
12+
|
13+
= note: this error originates in the macro `one_line_reuse` (in Nightly builds, run with -Z macro-backtrace for more info)
14+
15+
error[E0424]: expected value, found module `self`
16+
--> $DIR/impl-reuse-self-hygiene.rs:21:76
17+
|
18+
LL | macro_rules! one_line_reuse { ($self:ident) => { reuse impl Trait for S1 { $self.0 } } }
19+
| --------------------------^^^^^----
20+
| | |
21+
| | `self` value is a keyword only available in methods with a `self` parameter
22+
| `self` not allowed in an implementation
23+
...
24+
LL | one_line_reuse!(self);
25+
| --------------------- in this macro invocation
26+
|
27+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
28+
= note: this error originates in the macro `one_line_reuse` (in Nightly builds, run with -Z macro-backtrace for more info)
29+
30+
error[E0424]: expected value, found module `self`
31+
--> $DIR/impl-reuse-self-hygiene.rs:28:22
32+
|
33+
LL | macro_rules! one_line_reuse_expr { ($x:expr) => { reuse impl Trait for S2 { $x } } }
34+
| ------------------------------ `self` not allowed in an implementation
35+
LL | one_line_reuse_expr!(self.0);
36+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
37+
38+
error[E0424]: expected value, found module `self`
39+
--> $DIR/impl-reuse-self-hygiene.rs:28:22
40+
|
41+
LL | macro_rules! one_line_reuse_expr { ($x:expr) => { reuse impl Trait for S2 { $x } } }
42+
| ------------------------------ `self` not allowed in an implementation
43+
LL | one_line_reuse_expr!(self.0);
44+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
45+
|
46+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
47+
48+
error[E0424]: expected value, found module `self`
49+
--> $DIR/impl-reuse-self-hygiene.rs:35:23
50+
|
51+
LL | macro_rules! one_line_reuse_expr2 { ($x:expr) => { reuse impl Trait for s3!() { $x } } }
52+
| --------------------------------- `self` not allowed in an implementation
53+
LL | one_line_reuse_expr2!(self.0);
54+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
55+
56+
error[E0424]: expected value, found module `self`
57+
--> $DIR/impl-reuse-self-hygiene.rs:35:23
58+
|
59+
LL | macro_rules! one_line_reuse_expr2 { ($x:expr) => { reuse impl Trait for s3!() { $x } } }
60+
| --------------------------------- `self` not allowed in an implementation
61+
LL | one_line_reuse_expr2!(self.0);
62+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
63+
|
64+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
65+
66+
error: aborting due to 6 previous errors
67+
68+
For more information about this error, try `rustc --explain E0424`.

0 commit comments

Comments
 (0)