Skip to content

Commit 3d375b7

Browse files
authored
Unrolled build for rust-lang#126497
Rollup merge of rust-lang#126497 - petrochenkov:delehyg, r=compiler-errors delegation: Fix hygiene for `self` And fix diagnostics for `self` from a macro. The missing rib caused `self` to be treated as a generic parameter and ignore `macro_rules` hygiene. Addresses this comment rust-lang#124135 (comment).
2 parents 1d1356d + cbc3bdb commit 3d375b7

File tree

5 files changed

+81
-22
lines changed

5 files changed

+81
-22
lines changed

compiler/rustc_resolve/src/late.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -3281,17 +3281,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32813281
}
32823282
self.visit_path(&delegation.path, delegation.id);
32833283
if let Some(body) = &delegation.body {
3284-
// `PatBoundCtx` is not necessary in this context
3285-
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
3286-
3287-
let span = delegation.path.segments.last().unwrap().ident.span;
3288-
self.fresh_binding(
3289-
Ident::new(kw::SelfLower, span),
3290-
delegation.id,
3291-
PatternSource::FnParam,
3292-
&mut bindings,
3293-
);
3294-
self.visit_block(body);
3284+
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
3285+
// `PatBoundCtx` is not necessary in this context
3286+
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
3287+
3288+
let span = delegation.path.segments.last().unwrap().ident.span;
3289+
this.fresh_binding(
3290+
Ident::new(kw::SelfLower, span),
3291+
delegation.id,
3292+
PatternSource::FnParam,
3293+
&mut bindings,
3294+
);
3295+
this.visit_block(body);
3296+
});
32953297
}
32963298
}
32973299

compiler/rustc_resolve/src/late/diagnostics.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -1021,12 +1021,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
10211021
},
10221022
);
10231023
let is_assoc_fn = self.self_type_is_available();
1024+
let self_from_macro = "a `self` parameter, but a macro invocation can only \
1025+
access identifiers it receives from parameters";
10241026
if let Some((fn_kind, span)) = &self.diag_metadata.current_function {
10251027
// The current function has a `self` parameter, but we were unable to resolve
10261028
// a reference to `self`. This can only happen if the `self` identifier we
10271029
// are resolving came from a different hygiene context.
10281030
if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
1029-
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
1031+
err.span_label(*span, format!("this function has {self_from_macro}"));
10301032
} else {
10311033
let doesnt = if is_assoc_fn {
10321034
let (span, sugg) = fn_kind
@@ -1068,14 +1070,18 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
10681070
}
10691071
}
10701072
} else if let Some(item_kind) = self.diag_metadata.current_item {
1071-
err.span_label(
1072-
item_kind.ident.span,
1073-
format!(
1074-
"`self` not allowed in {} {}",
1075-
item_kind.kind.article(),
1076-
item_kind.kind.descr()
1077-
),
1078-
);
1073+
if matches!(item_kind.kind, ItemKind::Delegation(..)) {
1074+
err.span_label(item_kind.span, format!("delegation supports {self_from_macro}"));
1075+
} else {
1076+
err.span_label(
1077+
item_kind.ident.span,
1078+
format!(
1079+
"`self` not allowed in {} {}",
1080+
item_kind.kind.article(),
1081+
item_kind.kind.descr()
1082+
),
1083+
);
1084+
}
10791085
}
10801086
true
10811087
}

tests/ui/delegation/macro-inside-list.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ struct S(u8);
1414

1515
// Macro expansion works inside delegation items.
1616
macro_rules! u8 { () => { u8 } }
17-
macro_rules! self_0 { () => { &self.0 } }
17+
macro_rules! self_0 { ($self:ident) => { &$self.0 } }
1818
impl Trait for S {
19-
reuse <u8!() as Trait>::{foo, bar} { self_0!() }
19+
reuse <u8!() as Trait>::{foo, bar} { self_0!(self) }
2020
}
2121

2222
fn main() {

tests/ui/delegation/self-hygiene.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![feature(fn_delegation)]
2+
#![allow(incomplete_features)]
3+
4+
macro_rules! emit_self { () => { self } }
5+
//~^ ERROR expected value, found module `self`
6+
//~| ERROR expected value, found module `self`
7+
8+
struct S;
9+
impl S {
10+
fn method(self) {
11+
emit_self!();
12+
}
13+
}
14+
15+
fn foo(arg: u8) {}
16+
reuse foo as bar {
17+
emit_self!()
18+
}
19+
20+
fn main() {}
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0424]: expected value, found module `self`
2+
--> $DIR/self-hygiene.rs:4:34
3+
|
4+
LL | macro_rules! emit_self { () => { self } }
5+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
6+
...
7+
LL | / fn method(self) {
8+
LL | | emit_self!();
9+
| | ------------ in this macro invocation
10+
LL | | }
11+
| |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters
12+
|
13+
= note: this error originates in the macro `emit_self` (in Nightly builds, run with -Z macro-backtrace for more info)
14+
15+
error[E0424]: expected value, found module `self`
16+
--> $DIR/self-hygiene.rs:4:34
17+
|
18+
LL | macro_rules! emit_self { () => { self } }
19+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
20+
...
21+
LL | / reuse foo as bar {
22+
LL | | emit_self!()
23+
| | ------------ in this macro invocation
24+
LL | | }
25+
| |_- delegation supports a `self` parameter, but a macro invocation can only access identifiers it receives from parameters
26+
|
27+
= note: this error originates in the macro `emit_self` (in Nightly builds, run with -Z macro-backtrace for more info)
28+
29+
error: aborting due to 2 previous errors
30+
31+
For more information about this error, try `rustc --explain E0424`.

0 commit comments

Comments
 (0)