add parser check for pointer typo

This commit is contained in:
Kivooeo 2025-08-26 20:18:13 +00:00
parent 54c581243c
commit ea96b79056
4 changed files with 567 additions and 0 deletions

View file

@ -398,6 +398,10 @@ impl<'a> Parser<'a> {
// Qualified path
let (qself, path) = self.parse_qpath(PathStyle::Type)?;
TyKind::Path(Some(qself), path)
} else if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut))
&& self.look_ahead(1, |t| *t == token::Star)
{
self.parse_ty_c_style_pointer()?
} else if self.check_path() {
self.parse_path_start_ty(lo, allow_plus, ty_generics)?
} else if self.can_begin_bound() {
@ -579,6 +583,41 @@ impl<'a> Parser<'a> {
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
}
/// Parses a raw pointer with a C-style typo
fn parse_ty_c_style_pointer(&mut self) -> PResult<'a, TyKind> {
let kw_span = self.token.span;
let mutbl = self.parse_const_or_mut();
if let Some(mutbl) = mutbl
&& self.eat(exp!(Star))
{
let star_span = self.prev_token.span;
let mutability = match mutbl {
Mutability::Not => "const",
Mutability::Mut => "mut",
};
let ty = self.parse_ty_no_question_mark_recover()?;
self.dcx()
.struct_span_err(
kw_span,
format!("raw pointer types must be written as `*{mutability} T`"),
)
.with_multipart_suggestion(
format!("put the `*` before `{mutability}`"),
vec![(star_span, String::new()), (kw_span.shrink_to_lo(), "*".to_string())],
Applicability::MachineApplicable,
)
.emit();
return Ok(TyKind::Ptr(MutTy { ty, mutbl }));
}
// This is unreachable because we always get into if above and return from it
unreachable!("this could never happen")
}
/// Parses a raw pointer type: `*[const | mut] $type`.
fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {

View file

@ -0,0 +1,113 @@
//@ run-rustfix
#![allow(unused)]
pub const P1: *const u8 = 0 as _;
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P2: *mut u8 = 1 as _;
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
pub const P3: *const i32 = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P4: *const i32 = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P5: *mut i32 = std::ptr::null_mut();
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
pub const P6: *mut i32 = std::ptr::null_mut();
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
pub const P7: *const Vec<u8> = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P8: *const std::collections::HashMap<String, i32> = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
fn func1(p: *const u8) {}
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
fn func2(p: *mut u8) {}
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
fn func3() -> *const u8 { std::ptr::null() }
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
fn func4() -> *mut u8 { std::ptr::null_mut() }
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
struct S1 {
field: *const u8,
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
}
struct S2 {
field: *mut u8,
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
}
type Tuple1 = (*const u8, i32);
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
type Tuple2 = (*mut u8, i32);
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
type Array1 = [*const u8; 10];
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
type Array2 = [*mut u8; 10];
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
type Alias1 = *const u8;
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
type Alias2 = *mut u8;
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
pub const P9: *const u8 = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P10: *const u8 = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
impl S1 {
fn method(self, size: *const u32) {}
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
}
trait Trait1 {
fn method(p: *const u8);
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
}
fn generic_func<T>() -> *const T { std::ptr::null() }
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
fn main() {}

View file

@ -0,0 +1,113 @@
//@ run-rustfix
#![allow(unused)]
pub const P1: const* u8 = 0 as _;
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P2: mut* u8 = 1 as _;
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
pub const P3: const* i32 = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P4: const* i32 = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P5: mut* i32 = std::ptr::null_mut();
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
pub const P6: mut* i32 = std::ptr::null_mut();
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
pub const P7: const* Vec<u8> = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P8: const* std::collections::HashMap<String, i32> = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
fn func1(p: const* u8) {}
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
fn func2(p: mut* u8) {}
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
fn func3() -> const* u8 { std::ptr::null() }
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
fn func4() -> mut* u8 { std::ptr::null_mut() }
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
struct S1 {
field: const* u8,
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
}
struct S2 {
field: mut* u8,
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
}
type Tuple1 = (const* u8, i32);
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
type Tuple2 = (mut* u8, i32);
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
type Array1 = [const* u8; 10];
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
type Array2 = [mut* u8; 10];
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
type Alias1 = const* u8;
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
type Alias2 = mut* u8;
//~^ ERROR: raw pointer types must be written as `*mut T`
//~| HELP: put the `*` before `mut`
pub const P9: const *u8 = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
pub const P10: const * u8 = std::ptr::null();
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
impl S1 {
fn method(self, size: const* u32) {}
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
}
trait Trait1 {
fn method(p: const* u8);
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
}
fn generic_func<T>() -> const* T { std::ptr::null() }
//~^ ERROR: raw pointer types must be written as `*const T`
//~| HELP: put the `*` before `const`
fn main() {}

View file

@ -0,0 +1,302 @@
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:5:15
|
LL | pub const P1: const* u8 = 0 as _;
| ^^^^^
|
help: put the `*` before `const`
|
LL - pub const P1: const* u8 = 0 as _;
LL + pub const P1: *const u8 = 0 as _;
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:9:15
|
LL | pub const P2: mut* u8 = 1 as _;
| ^^^
|
help: put the `*` before `mut`
|
LL - pub const P2: mut* u8 = 1 as _;
LL + pub const P2: *mut u8 = 1 as _;
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:13:15
|
LL | pub const P3: const* i32 = std::ptr::null();
| ^^^^^
|
help: put the `*` before `const`
|
LL - pub const P3: const* i32 = std::ptr::null();
LL + pub const P3: *const i32 = std::ptr::null();
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:17:15
|
LL | pub const P4: const* i32 = std::ptr::null();
| ^^^^^
|
help: put the `*` before `const`
|
LL - pub const P4: const* i32 = std::ptr::null();
LL + pub const P4: *const i32 = std::ptr::null();
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:21:15
|
LL | pub const P5: mut* i32 = std::ptr::null_mut();
| ^^^
|
help: put the `*` before `mut`
|
LL - pub const P5: mut* i32 = std::ptr::null_mut();
LL + pub const P5: *mut i32 = std::ptr::null_mut();
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:25:15
|
LL | pub const P6: mut* i32 = std::ptr::null_mut();
| ^^^
|
help: put the `*` before `mut`
|
LL - pub const P6: mut* i32 = std::ptr::null_mut();
LL + pub const P6: *mut i32 = std::ptr::null_mut();
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:29:15
|
LL | pub const P7: const* Vec<u8> = std::ptr::null();
| ^^^^^
|
help: put the `*` before `const`
|
LL - pub const P7: const* Vec<u8> = std::ptr::null();
LL + pub const P7: *const Vec<u8> = std::ptr::null();
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:33:15
|
LL | pub const P8: const* std::collections::HashMap<String, i32> = std::ptr::null();
| ^^^^^
|
help: put the `*` before `const`
|
LL - pub const P8: const* std::collections::HashMap<String, i32> = std::ptr::null();
LL + pub const P8: *const std::collections::HashMap<String, i32> = std::ptr::null();
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:37:13
|
LL | fn func1(p: const* u8) {}
| ^^^^^
|
help: put the `*` before `const`
|
LL - fn func1(p: const* u8) {}
LL + fn func1(p: *const u8) {}
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:41:13
|
LL | fn func2(p: mut* u8) {}
| ^^^
|
help: put the `*` before `mut`
|
LL - fn func2(p: mut* u8) {}
LL + fn func2(p: *mut u8) {}
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:45:15
|
LL | fn func3() -> const* u8 { std::ptr::null() }
| ^^^^^
|
help: put the `*` before `const`
|
LL - fn func3() -> const* u8 { std::ptr::null() }
LL + fn func3() -> *const u8 { std::ptr::null() }
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:49:15
|
LL | fn func4() -> mut* u8 { std::ptr::null_mut() }
| ^^^
|
help: put the `*` before `mut`
|
LL - fn func4() -> mut* u8 { std::ptr::null_mut() }
LL + fn func4() -> *mut u8 { std::ptr::null_mut() }
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:54:12
|
LL | field: const* u8,
| ^^^^^
|
help: put the `*` before `const`
|
LL - field: const* u8,
LL + field: *const u8,
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:60:12
|
LL | field: mut* u8,
| ^^^
|
help: put the `*` before `mut`
|
LL - field: mut* u8,
LL + field: *mut u8,
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:65:16
|
LL | type Tuple1 = (const* u8, i32);
| ^^^^^
|
help: put the `*` before `const`
|
LL - type Tuple1 = (const* u8, i32);
LL + type Tuple1 = (*const u8, i32);
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:69:16
|
LL | type Tuple2 = (mut* u8, i32);
| ^^^
|
help: put the `*` before `mut`
|
LL - type Tuple2 = (mut* u8, i32);
LL + type Tuple2 = (*mut u8, i32);
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:73:16
|
LL | type Array1 = [const* u8; 10];
| ^^^^^
|
help: put the `*` before `const`
|
LL - type Array1 = [const* u8; 10];
LL + type Array1 = [*const u8; 10];
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:77:16
|
LL | type Array2 = [mut* u8; 10];
| ^^^
|
help: put the `*` before `mut`
|
LL - type Array2 = [mut* u8; 10];
LL + type Array2 = [*mut u8; 10];
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:81:15
|
LL | type Alias1 = const* u8;
| ^^^^^
|
help: put the `*` before `const`
|
LL - type Alias1 = const* u8;
LL + type Alias1 = *const u8;
|
error: raw pointer types must be written as `*mut T`
--> $DIR/c-style-pointer-types.rs:85:15
|
LL | type Alias2 = mut* u8;
| ^^^
|
help: put the `*` before `mut`
|
LL - type Alias2 = mut* u8;
LL + type Alias2 = *mut u8;
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:89:15
|
LL | pub const P9: const *u8 = std::ptr::null();
| ^^^^^
|
help: put the `*` before `const`
|
LL - pub const P9: const *u8 = std::ptr::null();
LL + pub const P9: *const u8 = std::ptr::null();
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:93:16
|
LL | pub const P10: const * u8 = std::ptr::null();
| ^^^^^
|
help: put the `*` before `const`
|
LL - pub const P10: const * u8 = std::ptr::null();
LL + pub const P10: *const u8 = std::ptr::null();
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:98:27
|
LL | fn method(self, size: const* u32) {}
| ^^^^^
|
help: put the `*` before `const`
|
LL - fn method(self, size: const* u32) {}
LL + fn method(self, size: *const u32) {}
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:104:18
|
LL | fn method(p: const* u8);
| ^^^^^
|
help: put the `*` before `const`
|
LL - fn method(p: const* u8);
LL + fn method(p: *const u8);
|
error: raw pointer types must be written as `*const T`
--> $DIR/c-style-pointer-types.rs:109:25
|
LL | fn generic_func<T>() -> const* T { std::ptr::null() }
| ^^^^^
|
help: put the `*` before `const`
|
LL - fn generic_func<T>() -> const* T { std::ptr::null() }
LL + fn generic_func<T>() -> *const T { std::ptr::null() }
|
error: aborting due to 25 previous errors