Skip to content

Commit 5d565d1

Browse files
authored
Unrolled build for rust-lang#122161
Rollup merge of rust-lang#122161 - compiler-errors:shorthand-self, r=fmease Fix suggestion when shorthand `self` has erroneous type Fixes rust-lang#122086 r? estebank
2 parents 5a0a5e6 + 05c34cc commit 5d565d1

File tree

6 files changed

+127
-1
lines changed

6 files changed

+127
-1
lines changed

compiler/rustc_ast/src/ast.rs

+12
Original file line numberDiff line numberDiff line change
@@ -2566,6 +2566,18 @@ pub enum SelfKind {
25662566
Explicit(P<Ty>, Mutability),
25672567
}
25682568

2569+
impl SelfKind {
2570+
pub fn to_ref_suggestion(&self) -> String {
2571+
match self {
2572+
SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2573+
SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2574+
SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2575+
unreachable!("if we had an explicit self, we wouldn't be here")
2576+
}
2577+
}
2578+
}
2579+
}
2580+
25692581
pub type ExplicitSelf = Spanned<SelfKind>;
25702582

25712583
impl Param {

compiler/rustc_parse/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ parse_incorrect_semicolon =
343343
.suggestion = remove this semicolon
344344
.help = {$name} declarations are not followed by a semicolon
345345
346+
parse_incorrect_type_on_self = type not allowed for shorthand `self` parameter
347+
.suggestion = move the modifiers on `self` to the type
348+
346349
parse_incorrect_use_of_await = incorrect use of `await`
347350
.parentheses_suggestion = `await` is not a method call, remove the parentheses
348351

compiler/rustc_parse/src/errors.rs

+19
Original file line numberDiff line numberDiff line change
@@ -3409,3 +3409,22 @@ pub(crate) struct PolarityAndModifiers {
34093409
pub polarity: &'static str,
34103410
pub modifiers_concatenated: String,
34113411
}
3412+
3413+
#[derive(Diagnostic)]
3414+
#[diag(parse_incorrect_type_on_self)]
3415+
pub(crate) struct IncorrectTypeOnSelf {
3416+
#[primary_span]
3417+
pub span: Span,
3418+
#[subdiagnostic]
3419+
pub move_self_modifier: MoveSelfModifier,
3420+
}
3421+
3422+
#[derive(Subdiagnostic)]
3423+
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3424+
pub(crate) struct MoveSelfModifier {
3425+
#[suggestion_part(code = "")]
3426+
pub removal_span: Span,
3427+
#[suggestion_part(code = "{modifier}")]
3428+
pub insertion_span: Span,
3429+
pub modifier: String,
3430+
}

compiler/rustc_parse/src/parser/item.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -2941,6 +2941,32 @@ impl<'a> Parser<'a> {
29412941
};
29422942
Ok((eself, eself_ident, eself_hi))
29432943
};
2944+
let expect_self_ident_not_typed =
2945+
|this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
2946+
let eself_ident = expect_self_ident(this);
2947+
2948+
// Recover `: Type` after a qualified self
2949+
if this.may_recover() && this.eat_noexpect(&token::Colon) {
2950+
let snap = this.create_snapshot_for_diagnostic();
2951+
match this.parse_ty() {
2952+
Ok(ty) => {
2953+
this.dcx().emit_err(errors::IncorrectTypeOnSelf {
2954+
span: ty.span,
2955+
move_self_modifier: errors::MoveSelfModifier {
2956+
removal_span: modifier_span,
2957+
insertion_span: ty.span.shrink_to_lo(),
2958+
modifier: modifier.to_ref_suggestion(),
2959+
},
2960+
});
2961+
}
2962+
Err(diag) => {
2963+
diag.cancel();
2964+
this.restore_snapshot(snap);
2965+
}
2966+
}
2967+
}
2968+
eself_ident
2969+
};
29442970
// Recover for the grammar `*self`, `*const self`, and `*mut self`.
29452971
let recover_self_ptr = |this: &mut Self| {
29462972
this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
@@ -2978,7 +3004,9 @@ impl<'a> Parser<'a> {
29783004
// `&not_self`
29793005
return Ok(None);
29803006
};
2981-
(eself, expect_self_ident(self), self.prev_token.span)
3007+
let hi = self.token.span;
3008+
let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3009+
(eself, self_ident, hi)
29823010
}
29833011
// `*self`
29843012
token::BinOp(token::Star) if is_isolated_self(self, 1) => {

tests/ui/parser/typed-self-param.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
struct S;
2+
3+
impl S {
4+
fn a(&self: Self) {}
5+
//~^ ERROR type not allowed for shorthand `self` parameter
6+
fn b(&mut self: Self) {}
7+
//~^ ERROR type not allowed for shorthand `self` parameter
8+
fn c<'c>(&'c mut self: Self) {}
9+
//~^ ERROR type not allowed for shorthand `self` parameter
10+
fn d<'d>(&'d self: Self) {}
11+
//~^ ERROR type not allowed for shorthand `self` parameter
12+
}
13+
14+
fn main() {}
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error: type not allowed for shorthand `self` parameter
2+
--> $DIR/typed-self-param.rs:4:17
3+
|
4+
LL | fn a(&self: Self) {}
5+
| ^^^^
6+
|
7+
help: move the modifiers on `self` to the type
8+
|
9+
LL - fn a(&self: Self) {}
10+
LL + fn a(self: &Self) {}
11+
|
12+
13+
error: type not allowed for shorthand `self` parameter
14+
--> $DIR/typed-self-param.rs:6:21
15+
|
16+
LL | fn b(&mut self: Self) {}
17+
| ^^^^
18+
|
19+
help: move the modifiers on `self` to the type
20+
|
21+
LL - fn b(&mut self: Self) {}
22+
LL + fn b(self: &mut Self) {}
23+
|
24+
25+
error: type not allowed for shorthand `self` parameter
26+
--> $DIR/typed-self-param.rs:8:28
27+
|
28+
LL | fn c<'c>(&'c mut self: Self) {}
29+
| ^^^^
30+
|
31+
help: move the modifiers on `self` to the type
32+
|
33+
LL - fn c<'c>(&'c mut self: Self) {}
34+
LL + fn c<'c>(self: &'c mut Self) {}
35+
|
36+
37+
error: type not allowed for shorthand `self` parameter
38+
--> $DIR/typed-self-param.rs:10:24
39+
|
40+
LL | fn d<'d>(&'d self: Self) {}
41+
| ^^^^
42+
|
43+
help: move the modifiers on `self` to the type
44+
|
45+
LL - fn d<'d>(&'d self: Self) {}
46+
LL + fn d<'d>(self: &'d Self) {}
47+
|
48+
49+
error: aborting due to 4 previous errors
50+

0 commit comments

Comments
 (0)