Skip to content
Open
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
28 changes: 28 additions & 0 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,34 @@ impl<'a> Parser<'a> {
) -> PResult<'a, Box<Ty>> {
let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);

if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut))
// Comment that describes what we're trying to do here.
if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably should also be moved into a separate function and also moved way down into the actually if else chain below rather than being hit first on every call to parse_ty_common

&& self.look_ahead(1, |t| *t == token::Star)
{
let kw_span = self.token.span;
self.bump();

if self.eat(exp!(Star)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should try to parse a subsequent type via a snapshot. Or at least check that lookahead(2) can begin a type

Copy link
Member

@compiler-errors compiler-errors Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This eat is always true, since we checked the lookahead above

let star_span = self.prev_token.span;

let _ = self.parse_ty_no_question_mark_recover();

let guar = self
.dcx()
.struct_span_err(
kw_span,
"raw pointer type must have a star before the mutability keyword",
Copy link
Member

@compiler-errors compiler-errors Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"raw pointer type must have a star before the mutability keyword",
"raw pointer types are written like `*{...} T`",

I find the phrasing kind of awkward -- "must have a star before the mutability keyword" doesn't really point to the fact that there is a star, and it's just misplaced. And also I wouldn't call "const" to be a mutability keyword.

I'm not sure if what I suggested is any better, but I wonder if there's a way to suggest the change here that sounds more descriptive.

)
.with_multipart_suggestion(
"move it to the other side",
vec![(star_span, String::new()), (kw_span.shrink_to_lo(), "*".to_string())],
Applicability::MachineApplicable,
)
.emit();

return Ok(self.mk_ty(kw_span.to(star_span), TyKind::Err(guar)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not recover this like a TyKind::RawPtr? Recovering like TyKind::Err seems to be strictly worse.

}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
}

if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) {
let attrs_wrapper = self.parse_outer_attributes()?;
let raw_attrs = attrs_wrapper.take_for_recovery(self.psess);
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 type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P2: *mut u8 = 1 as _;
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P3: *const i32 = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P4: *const i32 = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P5: *mut i32 = std::ptr::null_mut();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P6: *mut i32 = std::ptr::null_mut();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P7: *const Vec<u8> = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P8: *const std::collections::HashMap<String, i32> = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn func1(p: *const u8) {}
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn func2(p: *mut u8) {}
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn func3() -> *const u8 { std::ptr::null() }
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn func4() -> *mut u8 { std::ptr::null_mut() }
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

struct S1 {
field: *const u8,
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side
}

struct S2 {
field: *mut u8,
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side
}

type Tuple1 = (*const u8, i32);
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Tuple2 = (*mut u8, i32);
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Array1 = [*const u8; 10];
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Array2 = [*mut u8; 10];
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Alias1 = *const u8;
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Alias2 = *mut u8;
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P9: *const u8 = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P10: *const u8 = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

impl S1 {
fn method(self, size: *const u32) {}
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side
}

trait Trait1 {
fn method(p: *const u8);
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side
}

fn generic_func<T>() -> *const T { std::ptr::null() }
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

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 type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P2: mut* u8 = 1 as _;
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P3: const* i32 = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P4: const* i32 = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P5: mut* i32 = std::ptr::null_mut();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P6: mut* i32 = std::ptr::null_mut();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P7: const* Vec<u8> = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P8: const* std::collections::HashMap<String, i32> = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn func1(p: const* u8) {}
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn func2(p: mut* u8) {}
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn func3() -> const* u8 { std::ptr::null() }
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn func4() -> mut* u8 { std::ptr::null_mut() }
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

struct S1 {
field: const* u8,
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side
}

struct S2 {
field: mut* u8,
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side
}

type Tuple1 = (const* u8, i32);
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Tuple2 = (mut* u8, i32);
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Array1 = [const* u8; 10];
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Array2 = [mut* u8; 10];
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Alias1 = const* u8;
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

type Alias2 = mut* u8;
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P9: const *u8 = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

pub const P10: const * u8 = std::ptr::null();
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

impl S1 {
fn method(self, size: const* u32) {}
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side
}

trait Trait1 {
fn method(p: const* u8);
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side
}

fn generic_func<T>() -> const* T { std::ptr::null() }
//~^ ERROR: raw pointer type must have a star before the mutability keyword
//~| HELP: move it to the other side

fn main() {}
Loading
Loading