Skip to content

Commit 86b7749

Browse files
committed
add parser check for pointer typo
1 parent 54c5812 commit 86b7749

File tree

4 files changed

+568
-0
lines changed

4 files changed

+568
-0
lines changed

compiler/rustc_parse/src/parser/ty.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ impl<'a> Parser<'a> {
311311
} else if self.eat(exp!(Bang)) {
312312
// Never type `!`
313313
TyKind::Never
314+
} else if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut))
315+
&& self.look_ahead(1, |t| *t == token::Star)
316+
{
317+
self.parse_ty_c_style_pointer()?
314318
} else if self.eat(exp!(Star)) {
315319
self.parse_ty_ptr()?
316320
} else if self.eat(exp!(OpenBracket)) {
@@ -579,6 +583,42 @@ impl<'a> Parser<'a> {
579583
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
580584
}
581585

586+
/// Parses a raw pointer with a C-style typo
587+
fn parse_ty_c_style_pointer(&mut self) -> PResult<'a, TyKind> {
588+
let kw_span = self.token.span;
589+
let mutbl = self.parse_const_or_mut();
590+
591+
if let Some(mutbl) = mutbl
592+
&& self.eat(exp!(Star))
593+
{
594+
let star_span = self.prev_token.span;
595+
596+
let mutability = match mutbl {
597+
Mutability::Not => "const",
598+
Mutability::Mut => "mut",
599+
};
600+
601+
let ty = self.parse_ty_no_question_mark_recover()?;
602+
603+
let _guar = self
604+
.dcx()
605+
.struct_span_err(
606+
kw_span,
607+
format!("raw pointer types must be written as `*{mutability} T`"),
608+
)
609+
.with_multipart_suggestion(
610+
format!("put the `*` before `{mutability}`"),
611+
vec![(star_span, String::new()), (kw_span.shrink_to_lo(), "*".to_string())],
612+
Applicability::MachineApplicable,
613+
)
614+
.emit();
615+
616+
return Ok(TyKind::Ptr(MutTy { ty, mutbl }));
617+
}
618+
// This is unreachable because we always get into if above and return from it
619+
unreachable!("this should never happen happen")
620+
}
621+
582622
/// Parses a raw pointer type: `*[const | mut] $type`.
583623
fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
584624
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)