Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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(|| {
Expand Down
113 changes: 113 additions & 0 deletions tests/ui/did_you_mean/c-style-pointer-types.fixed
Original file line number Diff line number Diff line change
@@ -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() {}
113 changes: 113 additions & 0 deletions tests/ui/did_you_mean/c-style-pointer-types.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Loading
Loading