Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: parse unsafe record fields #19388

Merged
merged 1 commit into from
Mar 25, 2025
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
6 changes: 4 additions & 2 deletions crates/hir-def/src/data/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ pub struct FieldData {
pub name: Name,
pub type_ref: TypeRefId,
pub visibility: RawVisibility,
pub is_unsafe: bool,
}

fn repr_from_value(
Expand Down Expand Up @@ -329,14 +330,14 @@ impl EnumVariantData {
impl VariantData {
pub fn fields(&self) -> &Arena<FieldData> {
const EMPTY: &Arena<FieldData> = &Arena::new();
match &self {
match self {
VariantData::Record { fields, .. } | VariantData::Tuple { fields, .. } => fields,
_ => EMPTY,
}
}

pub fn types_map(&self) -> &TypesMap {
match &self {
match self {
VariantData::Record { types_map, .. } | VariantData::Tuple { types_map, .. } => {
types_map
}
Expand Down Expand Up @@ -405,5 +406,6 @@ fn lower_field(
name: field.name.clone(),
type_ref: field.type_ref,
visibility: item_tree[override_visibility.unwrap_or(field.visibility)].clone(),
is_unsafe: field.is_unsafe,
}
}
1 change: 1 addition & 0 deletions crates/hir-def/src/item_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,7 @@ pub struct Field {
pub name: Name,
pub type_ref: TypeRefId,
pub visibility: RawVisibilityId,
pub is_unsafe: bool,
}

#[derive(Debug, Clone, Eq, PartialEq)]
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-def/src/item_tree/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ impl<'a> Ctx<'a> {
let visibility = self.lower_visibility(field);
let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty());

Field { name, type_ref, visibility }
Field { name, type_ref, visibility, is_unsafe: field.unsafe_token().is_some() }
}

fn lower_tuple_field(
Expand All @@ -332,7 +332,7 @@ impl<'a> Ctx<'a> {
let name = Name::new_tuple_field(idx);
let visibility = self.lower_visibility(field);
let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty());
Field { name, type_ref, visibility }
Field { name, type_ref, visibility, is_unsafe: false }
}

fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
Expand Down
14 changes: 12 additions & 2 deletions crates/hir-def/src/item_tree/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,17 @@ impl Printer<'_> {
self.whitespace();
w!(self, "{{");
self.indented(|this| {
for (idx, Field { name, type_ref, visibility }) in fields.iter().enumerate() {
for (idx, Field { name, type_ref, visibility, is_unsafe }) in
fields.iter().enumerate()
{
this.print_attrs_of(
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
"\n",
);
this.print_visibility(*visibility);
if *is_unsafe {
w!(this, "unsafe ");
}
w!(this, "{}: ", name.display(self.db.upcast(), edition));
this.print_type_ref(*type_ref, map);
wln!(this, ",");
Expand All @@ -151,12 +156,17 @@ impl Printer<'_> {
FieldsShape::Tuple => {
w!(self, "(");
self.indented(|this| {
for (idx, Field { name, type_ref, visibility }) in fields.iter().enumerate() {
for (idx, Field { name, type_ref, visibility, is_unsafe }) in
fields.iter().enumerate()
{
this.print_attrs_of(
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
"\n",
);
this.print_visibility(*visibility);
if *is_unsafe {
w!(this, "unsafe ");
}
w!(this, "{}: ", name.display(self.db.upcast(), edition));
this.print_type_ref(*type_ref, map);
wln!(this, ",");
Expand Down
3 changes: 2 additions & 1 deletion crates/parser/src/grammar/items/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub(crate) fn variant_list(p: &mut Parser<'_>) {
}

// test record_field_list
// struct S { a: i32, b: f32 }
// struct S { a: i32, b: f32, unsafe c: u8 }
pub(crate) fn record_field_list(p: &mut Parser<'_>) {
assert!(p.at(T!['{']));
let m = p.start();
Expand All @@ -131,6 +131,7 @@ pub(crate) fn record_field_list(p: &mut Parser<'_>) {
// struct S { #[attr] f: f32 }
attributes::outer_attrs(p);
opt_visibility(p, false);
p.eat(T![unsafe]);
if p.at(IDENT) {
name(p);
p.expect(T![:]);
Expand Down
14 changes: 14 additions & 0 deletions crates/parser/test_data/parser/inline/ok/record_field_list.rast
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "f32"
COMMA ","
WHITESPACE " "
RECORD_FIELD
UNSAFE_KW "unsafe"
WHITESPACE " "
NAME
IDENT "c"
COLON ":"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "u8"
WHITESPACE " "
R_CURLY "}"
WHITESPACE "\n"
Original file line number Diff line number Diff line change
@@ -1 +1 @@
struct S { a: i32, b: f32 }
struct S { a: i32, b: f32, unsafe c: u8 }
2 changes: 1 addition & 1 deletion crates/syntax/rust.ungram
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ RecordFieldList =
'{' fields:(RecordField (',' RecordField)* ','?)? '}'

RecordField =
Attr* Visibility?
Attr* Visibility? 'unsafe'?
Name ':' Type ('=' Expr)?

TupleFieldList =
Expand Down
2 changes: 2 additions & 0 deletions crates/syntax/src/ast/generated/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,8 @@ impl RecordField {
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
#[inline]
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
#[inline]
pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
}
pub struct RecordFieldList {
pub(crate) syntax: SyntaxNode,
Expand Down
Loading