mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +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 name: Name,
|
||||||
pub type_ref: TypeRefId,
|
pub type_ref: TypeRefId,
|
||||||
pub visibility: RawVisibility,
|
pub visibility: RawVisibility,
|
||||||
|
pub is_unsafe: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn repr_from_value(
|
fn repr_from_value(
|
||||||
@ -329,14 +330,14 @@ impl EnumVariantData {
|
|||||||
impl VariantData {
|
impl VariantData {
|
||||||
pub fn fields(&self) -> &Arena<FieldData> {
|
pub fn fields(&self) -> &Arena<FieldData> {
|
||||||
const EMPTY: &Arena<FieldData> = &Arena::new();
|
const EMPTY: &Arena<FieldData> = &Arena::new();
|
||||||
match &self {
|
match self {
|
||||||
VariantData::Record { fields, .. } | VariantData::Tuple { fields, .. } => fields,
|
VariantData::Record { fields, .. } | VariantData::Tuple { fields, .. } => fields,
|
||||||
_ => EMPTY,
|
_ => EMPTY,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn types_map(&self) -> &TypesMap {
|
pub fn types_map(&self) -> &TypesMap {
|
||||||
match &self {
|
match self {
|
||||||
VariantData::Record { types_map, .. } | VariantData::Tuple { types_map, .. } => {
|
VariantData::Record { types_map, .. } | VariantData::Tuple { types_map, .. } => {
|
||||||
types_map
|
types_map
|
||||||
}
|
}
|
||||||
@ -405,5 +406,6 @@ fn lower_field(
|
|||||||
name: field.name.clone(),
|
name: field.name.clone(),
|
||||||
type_ref: field.type_ref,
|
type_ref: field.type_ref,
|
||||||
visibility: item_tree[override_visibility.unwrap_or(field.visibility)].clone(),
|
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 name: Name,
|
||||||
pub type_ref: TypeRefId,
|
pub type_ref: TypeRefId,
|
||||||
pub visibility: RawVisibilityId,
|
pub visibility: RawVisibilityId,
|
||||||
|
pub is_unsafe: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
@ -320,7 +320,7 @@ impl<'a> Ctx<'a> {
|
|||||||
let visibility = self.lower_visibility(field);
|
let visibility = self.lower_visibility(field);
|
||||||
let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty());
|
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(
|
fn lower_tuple_field(
|
||||||
@ -332,7 +332,7 @@ impl<'a> Ctx<'a> {
|
|||||||
let name = Name::new_tuple_field(idx);
|
let name = Name::new_tuple_field(idx);
|
||||||
let visibility = self.lower_visibility(field);
|
let visibility = self.lower_visibility(field);
|
||||||
let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty());
|
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>> {
|
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
|
||||||
|
@ -135,12 +135,17 @@ impl Printer<'_> {
|
|||||||
self.whitespace();
|
self.whitespace();
|
||||||
w!(self, "{{");
|
w!(self, "{{");
|
||||||
self.indented(|this| {
|
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(
|
this.print_attrs_of(
|
||||||
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
|
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
|
||||||
"\n",
|
"\n",
|
||||||
);
|
);
|
||||||
this.print_visibility(*visibility);
|
this.print_visibility(*visibility);
|
||||||
|
if *is_unsafe {
|
||||||
|
w!(this, "unsafe ");
|
||||||
|
}
|
||||||
w!(this, "{}: ", name.display(self.db.upcast(), edition));
|
w!(this, "{}: ", name.display(self.db.upcast(), edition));
|
||||||
this.print_type_ref(*type_ref, map);
|
this.print_type_ref(*type_ref, map);
|
||||||
wln!(this, ",");
|
wln!(this, ",");
|
||||||
@ -151,12 +156,17 @@ impl Printer<'_> {
|
|||||||
FieldsShape::Tuple => {
|
FieldsShape::Tuple => {
|
||||||
w!(self, "(");
|
w!(self, "(");
|
||||||
self.indented(|this| {
|
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(
|
this.print_attrs_of(
|
||||||
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
|
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
|
||||||
"\n",
|
"\n",
|
||||||
);
|
);
|
||||||
this.print_visibility(*visibility);
|
this.print_visibility(*visibility);
|
||||||
|
if *is_unsafe {
|
||||||
|
w!(this, "unsafe ");
|
||||||
|
}
|
||||||
w!(this, "{}: ", name.display(self.db.upcast(), edition));
|
w!(this, "{}: ", name.display(self.db.upcast(), edition));
|
||||||
this.print_type_ref(*type_ref, map);
|
this.print_type_ref(*type_ref, map);
|
||||||
wln!(this, ",");
|
wln!(this, ",");
|
||||||
|
@ -107,7 +107,7 @@ pub(crate) fn variant_list(p: &mut Parser<'_>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test record_field_list
|
// 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<'_>) {
|
pub(crate) fn record_field_list(p: &mut Parser<'_>) {
|
||||||
assert!(p.at(T!['{']));
|
assert!(p.at(T!['{']));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
@ -131,6 +131,7 @@ pub(crate) fn record_field_list(p: &mut Parser<'_>) {
|
|||||||
// struct S { #[attr] f: f32 }
|
// struct S { #[attr] f: f32 }
|
||||||
attributes::outer_attrs(p);
|
attributes::outer_attrs(p);
|
||||||
opt_visibility(p, false);
|
opt_visibility(p, false);
|
||||||
|
p.eat(T![unsafe]);
|
||||||
if p.at(IDENT) {
|
if p.at(IDENT) {
|
||||||
name(p);
|
name(p);
|
||||||
p.expect(T![:]);
|
p.expect(T![:]);
|
||||||
|
@ -30,6 +30,20 @@ SOURCE_FILE
|
|||||||
PATH_SEGMENT
|
PATH_SEGMENT
|
||||||
NAME_REF
|
NAME_REF
|
||||||
IDENT "f32"
|
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 " "
|
WHITESPACE " "
|
||||||
R_CURLY "}"
|
R_CURLY "}"
|
||||||
WHITESPACE "\n"
|
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)* ','?)? '}'
|
'{' fields:(RecordField (',' RecordField)* ','?)? '}'
|
||||||
|
|
||||||
RecordField =
|
RecordField =
|
||||||
Attr* Visibility?
|
Attr* Visibility? 'unsafe'?
|
||||||
Name ':' Type ('=' Expr)?
|
Name ':' Type ('=' Expr)?
|
||||||
|
|
||||||
TupleFieldList =
|
TupleFieldList =
|
||||||
|
@ -1337,6 +1337,8 @@ impl RecordField {
|
|||||||
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
|
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
|
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 struct RecordFieldList {
|
||||||
pub(crate) syntax: SyntaxNode,
|
pub(crate) syntax: SyntaxNode,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user