Skip to content

Commit 6f66e76

Browse files
committed
delegation: Give declaration of self syntax context of the whole item
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 abf79cf commit 6f66e76

File tree

4 files changed

+128
-30
lines changed

4 files changed

+128
-30
lines changed

compiler/rustc_resolve/src/late.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,7 +2989,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
29892989
item.id,
29902990
LifetimeBinderKind::Function,
29912991
span,
2992-
|this| this.resolve_delegation(delegation, item.id, false, &item.attrs),
2992+
|this| {
2993+
this.resolve_delegation(delegation, item.id, false, &item.attrs, item.span)
2994+
},
29932995
);
29942996
}
29952997

@@ -3335,7 +3337,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
33353337
item.id,
33363338
LifetimeBinderKind::Function,
33373339
delegation.path.segments.last().unwrap().ident.span,
3338-
|this| this.resolve_delegation(delegation, item.id, false, &item.attrs),
3340+
|this| {
3341+
this.resolve_delegation(
3342+
delegation,
3343+
item.id,
3344+
false,
3345+
&item.attrs,
3346+
item.span,
3347+
)
3348+
},
33393349
);
33403350
}
33413351
AssocItemKind::Type(box TyAlias { generics, .. }) => self
@@ -3649,7 +3659,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
36493659

36503660
// Here we don't use `trait_id`, as we can process unresolved trait, however
36513661
// in this case we are still in a trait impl, https://github.com/rust-lang/rust/issues/150152
3652-
this.resolve_delegation(delegation, item.id, is_in_trait_impl, &item.attrs);
3662+
this.resolve_delegation(
3663+
delegation,
3664+
item.id,
3665+
is_in_trait_impl,
3666+
&item.attrs,
3667+
item.span,
3668+
);
36533669
},
36543670
);
36553671
}
@@ -3805,6 +3821,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38053821
item_id: NodeId,
38063822
is_in_trait_impl: bool,
38073823
attrs: &[Attribute],
3824+
item_span: Span,
38083825
) {
38093826
self.smart_resolve_path(
38103827
delegation.id,
@@ -3829,8 +3846,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38293846

38303847
let Some(body) = &delegation.body else { return };
38313848
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
3832-
let span = delegation.path.segments.last().unwrap().ident.span;
3833-
let ident = Ident::new(kw::SelfLower, span.normalize_to_macro_rules());
3849+
let ident = Ident::new(kw::SelfLower, item_span.normalize_to_macro_rules());
38343850
let res = Res::Local(delegation.id);
38353851
this.innermost_rib_bindings(ValueNS).insert(ident, res);
38363852

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)