Skip to content

Commit 9b058ff

Browse files
authored
Unrolled build for #145903
Rollup merge of #145903 - Kivooeo:c-style-pointer, r=davidtwco Give correct suggestion for a typo in raw pointers This adds a check for when user wrote `const* T` instead of `*const T`, I just saw how a C-person made this typo and compiler suggests this ```rust --> src/main.rs:2:17 | 2 | let p: const* u8 = 0 as _; | ^ | help: add `mut` or `const` here | 2 | let p: const*mut u8 = 0 as _; | +++ 2 | let p: const*const u8 = 0 as _; | +++++ ``` which is very incorrect also fixes #136602 r? compiler
2 parents f5711a5 + ea96b79 commit 9b058ff

File tree

4 files changed

+567
-0
lines changed

4 files changed

+567
-0
lines changed

compiler/rustc_parse/src/parser/ty.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,10 @@ impl<'a> Parser<'a> {
407407
// Qualified path
408408
let (qself, path) = self.parse_qpath(PathStyle::Type)?;
409409
TyKind::Path(Some(qself), path)
410+
} else if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut))
411+
&& self.look_ahead(1, |t| *t == token::Star)
412+
{
413+
self.parse_ty_c_style_pointer()?
410414
} else if self.check_path() {
411415
self.parse_path_start_ty(lo, allow_plus, ty_generics)?
412416
} else if self.can_begin_bound() {
@@ -588,6 +592,41 @@ impl<'a> Parser<'a> {
588592
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
589593
}
590594

595+
/// Parses a raw pointer with a C-style typo
596+
fn parse_ty_c_style_pointer(&mut self) -> PResult<'a, TyKind> {
597+
let kw_span = self.token.span;
598+
let mutbl = self.parse_const_or_mut();
599+
600+
if let Some(mutbl) = mutbl
601+
&& self.eat(exp!(Star))
602+
{
603+
let star_span = self.prev_token.span;
604+
605+
let mutability = match mutbl {
606+
Mutability::Not => "const",
607+
Mutability::Mut => "mut",
608+
};
609+
610+
let ty = self.parse_ty_no_question_mark_recover()?;
611+
612+
self.dcx()
613+
.struct_span_err(
614+
kw_span,
615+
format!("raw pointer types must be written as `*{mutability} T`"),
616+
)
617+
.with_multipart_suggestion(
618+
format!("put the `*` before `{mutability}`"),
619+
vec![(star_span, String::new()), (kw_span.shrink_to_lo(), "*".to_string())],
620+
Applicability::MachineApplicable,
621+
)
622+
.emit();
623+
624+
return Ok(TyKind::Ptr(MutTy { ty, mutbl }));
625+
}
626+
// This is unreachable because we always get into if above and return from it
627+
unreachable!("this could never happen")
628+
}
629+
591630
/// Parses a raw pointer type: `*[const | mut] $type`.
592631
fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
593632
let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//@ run-rustfix
2+
3+
#![allow(unused)]
4+
5+
pub const P1: *const u8 = 0 as _;
6+
//~^ ERROR: raw pointer types must be written as `*const T`
7+
//~| HELP: put the `*` before `const`
8+
9+
pub const P2: *mut u8 = 1 as _;
10+
//~^ ERROR: raw pointer types must be written as `*mut T`
11+
//~| HELP: put the `*` before `mut`
12+
13+
pub const P3: *const i32 = std::ptr::null();
14+
//~^ ERROR: raw pointer types must be written as `*const T`
15+
//~| HELP: put the `*` before `const`
16+
17+
pub const P4: *const i32 = std::ptr::null();
18+
//~^ ERROR: raw pointer types must be written as `*const T`
19+
//~| HELP: put the `*` before `const`
20+
21+
pub const P5: *mut i32 = std::ptr::null_mut();
22+
//~^ ERROR: raw pointer types must be written as `*mut T`
23+
//~| HELP: put the `*` before `mut`
24+
25+
pub const P6: *mut i32 = std::ptr::null_mut();
26+
//~^ ERROR: raw pointer types must be written as `*mut T`
27+
//~| HELP: put the `*` before `mut`
28+
29+
pub const P7: *const Vec<u8> = std::ptr::null();
30+
//~^ ERROR: raw pointer types must be written as `*const T`
31+
//~| HELP: put the `*` before `const`
32+
33+
pub const P8: *const std::collections::HashMap<String, i32> = std::ptr::null();
34+
//~^ ERROR: raw pointer types must be written as `*const T`
35+
//~| HELP: put the `*` before `const`
36+
37+
fn func1(p: *const u8) {}
38+
//~^ ERROR: raw pointer types must be written as `*const T`
39+
//~| HELP: put the `*` before `const`
40+
41+
fn func2(p: *mut u8) {}
42+
//~^ ERROR: raw pointer types must be written as `*mut T`
43+
//~| HELP: put the `*` before `mut`
44+
45+
fn func3() -> *const u8 { std::ptr::null() }
46+
//~^ ERROR: raw pointer types must be written as `*const T`
47+
//~| HELP: put the `*` before `const`
48+
49+
fn func4() -> *mut u8 { std::ptr::null_mut() }
50+
//~^ ERROR: raw pointer types must be written as `*mut T`
51+
//~| HELP: put the `*` before `mut`
52+
53+
struct S1 {
54+
field: *const u8,
55+
//~^ ERROR: raw pointer types must be written as `*const T`
56+
//~| HELP: put the `*` before `const`
57+
}
58+
59+
struct S2 {
60+
field: *mut u8,
61+
//~^ ERROR: raw pointer types must be written as `*mut T`
62+
//~| HELP: put the `*` before `mut`
63+
}
64+
65+
type Tuple1 = (*const u8, i32);
66+
//~^ ERROR: raw pointer types must be written as `*const T`
67+
//~| HELP: put the `*` before `const`
68+
69+
type Tuple2 = (*mut u8, i32);
70+
//~^ ERROR: raw pointer types must be written as `*mut T`
71+
//~| HELP: put the `*` before `mut`
72+
73+
type Array1 = [*const u8; 10];
74+
//~^ ERROR: raw pointer types must be written as `*const T`
75+
//~| HELP: put the `*` before `const`
76+
77+
type Array2 = [*mut u8; 10];
78+
//~^ ERROR: raw pointer types must be written as `*mut T`
79+
//~| HELP: put the `*` before `mut`
80+
81+
type Alias1 = *const u8;
82+
//~^ ERROR: raw pointer types must be written as `*const T`
83+
//~| HELP: put the `*` before `const`
84+
85+
type Alias2 = *mut u8;
86+
//~^ ERROR: raw pointer types must be written as `*mut T`
87+
//~| HELP: put the `*` before `mut`
88+
89+
pub const P9: *const u8 = std::ptr::null();
90+
//~^ ERROR: raw pointer types must be written as `*const T`
91+
//~| HELP: put the `*` before `const`
92+
93+
pub const P10: *const u8 = std::ptr::null();
94+
//~^ ERROR: raw pointer types must be written as `*const T`
95+
//~| HELP: put the `*` before `const`
96+
97+
impl S1 {
98+
fn method(self, size: *const u32) {}
99+
//~^ ERROR: raw pointer types must be written as `*const T`
100+
//~| HELP: put the `*` before `const`
101+
}
102+
103+
trait Trait1 {
104+
fn method(p: *const u8);
105+
//~^ ERROR: raw pointer types must be written as `*const T`
106+
//~| HELP: put the `*` before `const`
107+
}
108+
109+
fn generic_func<T>() -> *const T { std::ptr::null() }
110+
//~^ ERROR: raw pointer types must be written as `*const T`
111+
//~| HELP: put the `*` before `const`
112+
113+
fn main() {}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//@ run-rustfix
2+
3+
#![allow(unused)]
4+
5+
pub const P1: const* u8 = 0 as _;
6+
//~^ ERROR: raw pointer types must be written as `*const T`
7+
//~| HELP: put the `*` before `const`
8+
9+
pub const P2: mut* u8 = 1 as _;
10+
//~^ ERROR: raw pointer types must be written as `*mut T`
11+
//~| HELP: put the `*` before `mut`
12+
13+
pub const P3: const* i32 = std::ptr::null();
14+
//~^ ERROR: raw pointer types must be written as `*const T`
15+
//~| HELP: put the `*` before `const`
16+
17+
pub const P4: const* i32 = std::ptr::null();
18+
//~^ ERROR: raw pointer types must be written as `*const T`
19+
//~| HELP: put the `*` before `const`
20+
21+
pub const P5: mut* i32 = std::ptr::null_mut();
22+
//~^ ERROR: raw pointer types must be written as `*mut T`
23+
//~| HELP: put the `*` before `mut`
24+
25+
pub const P6: mut* i32 = std::ptr::null_mut();
26+
//~^ ERROR: raw pointer types must be written as `*mut T`
27+
//~| HELP: put the `*` before `mut`
28+
29+
pub const P7: const* Vec<u8> = std::ptr::null();
30+
//~^ ERROR: raw pointer types must be written as `*const T`
31+
//~| HELP: put the `*` before `const`
32+
33+
pub const P8: const* std::collections::HashMap<String, i32> = std::ptr::null();
34+
//~^ ERROR: raw pointer types must be written as `*const T`
35+
//~| HELP: put the `*` before `const`
36+
37+
fn func1(p: const* u8) {}
38+
//~^ ERROR: raw pointer types must be written as `*const T`
39+
//~| HELP: put the `*` before `const`
40+
41+
fn func2(p: mut* u8) {}
42+
//~^ ERROR: raw pointer types must be written as `*mut T`
43+
//~| HELP: put the `*` before `mut`
44+
45+
fn func3() -> const* u8 { std::ptr::null() }
46+
//~^ ERROR: raw pointer types must be written as `*const T`
47+
//~| HELP: put the `*` before `const`
48+
49+
fn func4() -> mut* u8 { std::ptr::null_mut() }
50+
//~^ ERROR: raw pointer types must be written as `*mut T`
51+
//~| HELP: put the `*` before `mut`
52+
53+
struct S1 {
54+
field: const* u8,
55+
//~^ ERROR: raw pointer types must be written as `*const T`
56+
//~| HELP: put the `*` before `const`
57+
}
58+
59+
struct S2 {
60+
field: mut* u8,
61+
//~^ ERROR: raw pointer types must be written as `*mut T`
62+
//~| HELP: put the `*` before `mut`
63+
}
64+
65+
type Tuple1 = (const* u8, i32);
66+
//~^ ERROR: raw pointer types must be written as `*const T`
67+
//~| HELP: put the `*` before `const`
68+
69+
type Tuple2 = (mut* u8, i32);
70+
//~^ ERROR: raw pointer types must be written as `*mut T`
71+
//~| HELP: put the `*` before `mut`
72+
73+
type Array1 = [const* u8; 10];
74+
//~^ ERROR: raw pointer types must be written as `*const T`
75+
//~| HELP: put the `*` before `const`
76+
77+
type Array2 = [mut* u8; 10];
78+
//~^ ERROR: raw pointer types must be written as `*mut T`
79+
//~| HELP: put the `*` before `mut`
80+
81+
type Alias1 = const* u8;
82+
//~^ ERROR: raw pointer types must be written as `*const T`
83+
//~| HELP: put the `*` before `const`
84+
85+
type Alias2 = mut* u8;
86+
//~^ ERROR: raw pointer types must be written as `*mut T`
87+
//~| HELP: put the `*` before `mut`
88+
89+
pub const P9: const *u8 = std::ptr::null();
90+
//~^ ERROR: raw pointer types must be written as `*const T`
91+
//~| HELP: put the `*` before `const`
92+
93+
pub const P10: const * u8 = std::ptr::null();
94+
//~^ ERROR: raw pointer types must be written as `*const T`
95+
//~| HELP: put the `*` before `const`
96+
97+
impl S1 {
98+
fn method(self, size: const* u32) {}
99+
//~^ ERROR: raw pointer types must be written as `*const T`
100+
//~| HELP: put the `*` before `const`
101+
}
102+
103+
trait Trait1 {
104+
fn method(p: const* u8);
105+
//~^ ERROR: raw pointer types must be written as `*const T`
106+
//~| HELP: put the `*` before `const`
107+
}
108+
109+
fn generic_func<T>() -> const* T { std::ptr::null() }
110+
//~^ ERROR: raw pointer types must be written as `*const T`
111+
//~| HELP: put the `*` before `const`
112+
113+
fn main() {}

0 commit comments

Comments
 (0)