Skip to content

Commit 749fde9

Browse files
authored
Merge pull request #19388 from Veykril/push-oqysrnttwywu
feat: parse `unsafe` record fields
2 parents ed7e25a + 452e2ca commit 749fde9

File tree

9 files changed

+39
-9
lines changed

9 files changed

+39
-9
lines changed

crates/hir-def/src/data/adt.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ pub struct FieldData {
171171
pub name: Name,
172172
pub type_ref: TypeRefId,
173173
pub visibility: RawVisibility,
174+
pub is_unsafe: bool,
174175
}
175176

176177
fn repr_from_value(
@@ -329,14 +330,14 @@ impl EnumVariantData {
329330
impl VariantData {
330331
pub fn fields(&self) -> &Arena<FieldData> {
331332
const EMPTY: &Arena<FieldData> = &Arena::new();
332-
match &self {
333+
match self {
333334
VariantData::Record { fields, .. } | VariantData::Tuple { fields, .. } => fields,
334335
_ => EMPTY,
335336
}
336337
}
337338

338339
pub fn types_map(&self) -> &TypesMap {
339-
match &self {
340+
match self {
340341
VariantData::Record { types_map, .. } | VariantData::Tuple { types_map, .. } => {
341342
types_map
342343
}
@@ -405,5 +406,6 @@ fn lower_field(
405406
name: field.name.clone(),
406407
type_ref: field.type_ref,
407408
visibility: item_tree[override_visibility.unwrap_or(field.visibility)].clone(),
409+
is_unsafe: field.is_unsafe,
408410
}
409411
}

crates/hir-def/src/item_tree.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,7 @@ pub struct Field {
10321032
pub name: Name,
10331033
pub type_ref: TypeRefId,
10341034
pub visibility: RawVisibilityId,
1035+
pub is_unsafe: bool,
10351036
}
10361037

10371038
#[derive(Debug, Clone, Eq, PartialEq)]

crates/hir-def/src/item_tree/lower.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ impl<'a> Ctx<'a> {
320320
let visibility = self.lower_visibility(field);
321321
let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty());
322322

323-
Field { name, type_ref, visibility }
323+
Field { name, type_ref, visibility, is_unsafe: field.unsafe_token().is_some() }
324324
}
325325

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

338338
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {

crates/hir-def/src/item_tree/pretty.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,17 @@ impl Printer<'_> {
135135
self.whitespace();
136136
w!(self, "{{");
137137
self.indented(|this| {
138-
for (idx, Field { name, type_ref, visibility }) in fields.iter().enumerate() {
138+
for (idx, Field { name, type_ref, visibility, is_unsafe }) in
139+
fields.iter().enumerate()
140+
{
139141
this.print_attrs_of(
140142
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
141143
"\n",
142144
);
143145
this.print_visibility(*visibility);
146+
if *is_unsafe {
147+
w!(this, "unsafe ");
148+
}
144149
w!(this, "{}: ", name.display(self.db.upcast(), edition));
145150
this.print_type_ref(*type_ref, map);
146151
wln!(this, ",");
@@ -151,12 +156,17 @@ impl Printer<'_> {
151156
FieldsShape::Tuple => {
152157
w!(self, "(");
153158
self.indented(|this| {
154-
for (idx, Field { name, type_ref, visibility }) in fields.iter().enumerate() {
159+
for (idx, Field { name, type_ref, visibility, is_unsafe }) in
160+
fields.iter().enumerate()
161+
{
155162
this.print_attrs_of(
156163
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
157164
"\n",
158165
);
159166
this.print_visibility(*visibility);
167+
if *is_unsafe {
168+
w!(this, "unsafe ");
169+
}
160170
w!(this, "{}: ", name.display(self.db.upcast(), edition));
161171
this.print_type_ref(*type_ref, map);
162172
wln!(this, ",");

crates/parser/src/grammar/items/adt.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub(crate) fn variant_list(p: &mut Parser<'_>) {
107107
}
108108

109109
// test record_field_list
110-
// struct S { a: i32, b: f32 }
110+
// struct S { a: i32, b: f32, unsafe c: u8 }
111111
pub(crate) fn record_field_list(p: &mut Parser<'_>) {
112112
assert!(p.at(T!['{']));
113113
let m = p.start();
@@ -131,6 +131,7 @@ pub(crate) fn record_field_list(p: &mut Parser<'_>) {
131131
// struct S { #[attr] f: f32 }
132132
attributes::outer_attrs(p);
133133
opt_visibility(p, false);
134+
p.eat(T![unsafe]);
134135
if p.at(IDENT) {
135136
name(p);
136137
p.expect(T![:]);

crates/parser/test_data/parser/inline/ok/record_field_list.rast

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ SOURCE_FILE
3030
PATH_SEGMENT
3131
NAME_REF
3232
IDENT "f32"
33+
COMMA ","
34+
WHITESPACE " "
35+
RECORD_FIELD
36+
UNSAFE_KW "unsafe"
37+
WHITESPACE " "
38+
NAME
39+
IDENT "c"
40+
COLON ":"
41+
WHITESPACE " "
42+
PATH_TYPE
43+
PATH
44+
PATH_SEGMENT
45+
NAME_REF
46+
IDENT "u8"
3347
WHITESPACE " "
3448
R_CURLY "}"
3549
WHITESPACE "\n"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
struct S { a: i32, b: f32 }
1+
struct S { a: i32, b: f32, unsafe c: u8 }

crates/syntax/rust.ungram

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ RecordFieldList =
240240
'{' fields:(RecordField (',' RecordField)* ','?)? '}'
241241

242242
RecordField =
243-
Attr* Visibility?
243+
Attr* Visibility? 'unsafe'?
244244
Name ':' Type ('=' Expr)?
245245

246246
TupleFieldList =

crates/syntax/src/ast/generated/nodes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,8 @@ impl RecordField {
13371337
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
13381338
#[inline]
13391339
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
1340+
#[inline]
1341+
pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
13401342
}
13411343
pub struct RecordFieldList {
13421344
pub(crate) syntax: SyntaxNode,

0 commit comments

Comments
 (0)