mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 11:20:54 +00:00
feat: parse unsafe
record fields
This commit is contained in:
parent
d3aeddfb77
commit
452e2ca031
@ -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(
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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(
|
||||
@ -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>> {
|
||||
|
@ -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, ",");
|
||||
@ -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, ",");
|
||||
|
@ -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();
|
||||
@ -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![:]);
|
||||
|
@ -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"
|
||||
|
@ -1 +1 @@
|
||||
struct S { a: i32, b: f32 }
|
||||
struct S { a: i32, b: f32, unsafe c: u8 }
|
||||
|
@ -240,7 +240,7 @@ RecordFieldList =
|
||||
'{' fields:(RecordField (',' RecordField)* ','?)? '}'
|
||||
|
||||
RecordField =
|
||||
Attr* Visibility?
|
||||
Attr* Visibility? 'unsafe'?
|
||||
Name ':' Type ('=' Expr)?
|
||||
|
||||
TupleFieldList =
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user