Skip to content

Commit dc6e411

Browse files
bors[bot]xFrednet
andauthored
Merge #57
57: Add item conversion backend for rustc r=xFrednet a=xFrednet This is still a rough diamond. I want to do some more cleanup, but prefer to do that in a follow-up PR, as this has again grown into a monster with ~1000 line changes. #56 lists some remaining TODOs. Some of these are also less related to items and more to the type system. Closes #53 Progress on #35 Co-authored-by: xFrednet <[email protected]>
2 parents 3a7cd8f + 6af69b7 commit dc6e411

21 files changed

+822
-254
lines changed

linter_adapter/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl<'ast> Adapter<'ast> {
3939
match item {
4040
ItemKind::Mod(data) => self.external_lint_crates.check_mod(cx, data),
4141
ItemKind::ExternCrate(data) => self.external_lint_crates.check_extern_crate(cx, data),
42-
ItemKind::UseDecl(data) => self.external_lint_crates.check_use_decl(cx, data),
42+
ItemKind::Use(data) => self.external_lint_crates.check_use_decl(cx, data),
4343
ItemKind::Static(data) => self.external_lint_crates.check_static_item(cx, data),
4444
_ => {},
4545
}

linter_api/src/ast/common.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,6 @@ impl<'ast, T> Spanned<'ast, T> {
9999
}
100100
}
101101

102-
#[non_exhaustive]
103-
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
104-
pub struct Symbol {
105-
index: u32,
106-
}
107-
108-
#[cfg(feature = "driver-api")]
109-
impl Symbol {
110-
#[must_use]
111-
pub fn new(index: u32) -> Self {
112-
Self { index }
113-
}
114-
}
115-
116-
pub type Ident<'ast> = Spanned<'ast, Symbol>;
117-
118102
pub trait Attribute<'ast>: Debug {
119103
// FIXME: Add attribute functions
120104
}

linter_api/src/ast/common/ast_path.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ pub struct AstPath<'ast> {
2323

2424
#[cfg(feature = "driver-api")]
2525
impl<'ast> AstPath<'ast> {
26-
pub fn new(segments: FfiSlice<'ast, AstPathSegment<'ast>>) -> Self {
27-
Self { segments }
26+
pub fn new(segments: &'ast [AstPathSegment<'ast>]) -> Self {
27+
Self {
28+
segments: segments.into(),
29+
}
2830
}
2931
}
3032

linter_api/src/ast/item.rs

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub use mod_item::ModItem;
1010
mod static_item;
1111
pub use self::static_item::StaticItem;
1212
mod use_decl_item;
13-
pub use self::use_decl_item::UseDeclItem;
13+
pub use self::use_decl_item::*;
1414
mod const_item;
1515
pub use self::const_item::ConstItem;
1616
mod fn_item;
@@ -25,6 +25,8 @@ mod impl_item;
2525
pub use impl_item::*;
2626
mod extern_block_item;
2727
pub use extern_block_item::*;
28+
mod unstable_item;
29+
pub use unstable_item::*;
2830

2931
pub trait ItemData<'ast>: Debug {
3032
/// Returns the [`ItemId`] of this item. This is a unique identifier used for comparison
@@ -55,7 +57,7 @@ pub trait ItemData<'ast>: Debug {
5557
pub enum ItemKind<'ast> {
5658
Mod(&'ast ModItem<'ast>),
5759
ExternCrate(&'ast ExternCrateItem<'ast>),
58-
UseDecl(&'ast UseDeclItem<'ast>),
60+
Use(&'ast UseItem<'ast>),
5961
Static(&'ast StaticItem<'ast>),
6062
Const(&'ast ConstItem<'ast>),
6163
Fn(&'ast FnItem<'ast>),
@@ -66,6 +68,7 @@ pub enum ItemKind<'ast> {
6668
Trait(&'ast TraitItem<'ast>),
6769
Impl(&'ast ImplItem<'ast>),
6870
ExternBlock(&'ast ExternBlockItem<'ast>),
71+
Unstable(&'ast UnstableItem<'ast>),
6972
}
7073

7174
impl<'ast> ItemKind<'ast> {
@@ -91,40 +94,85 @@ impl<'ast> AssocItemKind<'ast> {
9194
impl_item_type_fn!(AssocItemKind: name() -> Option<String>);
9295
impl_item_type_fn!(AssocItemKind: attrs() -> ());
9396
impl_item_type_fn!(AssocItemKind: as_item() -> ItemKind<'ast>);
97+
// FIXME: Potentualy add a field to the items to optionally store the owner id
98+
}
99+
100+
impl<'ast> From<AssocItemKind<'ast>> for ItemKind<'ast> {
101+
fn from(value: AssocItemKind<'ast>) -> Self {
102+
match value {
103+
AssocItemKind::TyAlias(item) => ItemKind::TyAlias(item),
104+
AssocItemKind::Const(item) => ItemKind::Const(item),
105+
AssocItemKind::Fn(item) => ItemKind::Fn(item),
106+
}
107+
}
108+
}
109+
110+
impl<'ast> TryFrom<&ItemKind<'ast>> for AssocItemKind<'ast> {
111+
type Error = ();
112+
113+
fn try_from(value: &ItemKind<'ast>) -> Result<Self, Self::Error> {
114+
match value {
115+
ItemKind::TyAlias(item) => Ok(AssocItemKind::TyAlias(item)),
116+
ItemKind::Const(item) => Ok(AssocItemKind::Const(item)),
117+
ItemKind::Fn(item) => Ok(AssocItemKind::Fn(item)),
118+
_ => Err(()),
119+
}
120+
}
94121
}
95122

96123
#[non_exhaustive]
97124
#[derive(Debug)]
98-
pub enum ExternalItemKind<'ast> {
125+
pub enum ExternItemKind<'ast> {
99126
Static(&'ast StaticItem<'ast>),
100127
Fn(&'ast FnItem<'ast>),
101128
}
102129

103-
impl<'ast> ExternalItemKind<'ast> {
104-
impl_item_type_fn!(ExternalItemKind: id() -> ItemId);
105-
impl_item_type_fn!(ExternalItemKind: span() -> &Span<'ast>);
106-
impl_item_type_fn!(ExternalItemKind: visibility() -> &Visibility<'ast>);
107-
impl_item_type_fn!(ExternalItemKind: name() -> Option<String>);
108-
impl_item_type_fn!(ExternalItemKind: attrs() -> ());
109-
impl_item_type_fn!(ExternalItemKind: as_item() -> ItemKind<'ast>);
130+
impl<'ast> ExternItemKind<'ast> {
131+
impl_item_type_fn!(ExternItemKind: id() -> ItemId);
132+
impl_item_type_fn!(ExternItemKind: span() -> &Span<'ast>);
133+
impl_item_type_fn!(ExternItemKind: visibility() -> &Visibility<'ast>);
134+
impl_item_type_fn!(ExternItemKind: name() -> Option<String>);
135+
impl_item_type_fn!(ExternItemKind: attrs() -> ());
136+
impl_item_type_fn!(ExternItemKind: as_item() -> ItemKind<'ast>);
137+
}
138+
139+
impl<'ast> From<ExternItemKind<'ast>> for ItemKind<'ast> {
140+
fn from(value: ExternItemKind<'ast>) -> Self {
141+
match value {
142+
ExternItemKind::Static(item) => ItemKind::Static(item),
143+
ExternItemKind::Fn(item) => ItemKind::Fn(item),
144+
}
145+
}
146+
}
147+
148+
impl<'ast> TryFrom<ItemKind<'ast>> for ExternItemKind<'ast> {
149+
type Error = ();
150+
151+
fn try_from(value: ItemKind<'ast>) -> Result<Self, Self::Error> {
152+
match value {
153+
ItemKind::Static(item) => Ok(ExternItemKind::Static(item)),
154+
ItemKind::Fn(item) => Ok(ExternItemKind::Fn(item)),
155+
_ => Err(()),
156+
}
157+
}
110158
}
111159

112160
/// Until [trait upcasting](https://github.com/rust-lang/rust/issues/65991) has been implemented
113161
/// and stabalized we need this to call [`ItemData`] functions for [`ItemKind`].
114162
macro_rules! impl_item_type_fn {
115163
(ItemKind: $method:ident () -> $return_ty:ty) => {
116164
impl_item_type_fn!((ItemKind) $method() -> $return_ty,
117-
Mod, ExternCrate, UseDecl, Static, Const, Fn,
118-
TyAlias, Struct, Enum, Union, Trait, Impl, ExternBlock
165+
Mod, ExternCrate, Use, Static, Const, Fn, TyAlias, Struct, Enum,
166+
Union, Trait, Impl, ExternBlock, Unstable
119167
);
120168
};
121169
(AssocItemKind: $method:ident () -> $return_ty:ty) => {
122170
impl_item_type_fn!((AssocItemKind) $method() -> $return_ty,
123171
TyAlias, Const, Fn
124172
);
125173
};
126-
(ExternalItemKind: $method:ident () -> $return_ty:ty) => {
127-
impl_item_type_fn!((ExternalItemKind) $method() -> $return_ty,
174+
(ExternItemKind: $method:ident () -> $return_ty:ty) => {
175+
impl_item_type_fn!((ExternItemKind) $method() -> $return_ty,
128176
Static, Fn
129177
);
130178
};
@@ -182,8 +230,12 @@ use impl_item_data;
182230

183231
#[cfg(feature = "driver-api")]
184232
impl<'ast> CommonItemData<'ast> {
185-
pub fn new(id: ItemId, vis: Visibility<'ast>, name: SymbolId) -> Self {
186-
Self { id, vis, name }
233+
pub fn new(id: ItemId, name: SymbolId) -> Self {
234+
Self {
235+
id,
236+
vis: Visibility::new(id),
237+
name,
238+
}
187239
}
188240
}
189241

linter_api/src/ast/item/adt_item.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ impl<'ast> StructItem<'ast> {
226226
}
227227
}
228228

229+
#[cfg(feature = "driver-api")]
230+
impl<'ast> StructItem<'ast> {
231+
pub fn new(data: CommonItemData<'ast>, generics: GenericParams<'ast>, kind: AdtKind<'ast>) -> Self {
232+
Self { data, generics, kind }
233+
}
234+
}
235+
229236
#[derive(Debug)]
230237
#[allow(clippy::exhaustive_enums)]
231238
#[cfg_attr(feature = "driver-api", visibility::make(pub))]
@@ -235,6 +242,17 @@ enum AdtKind<'ast> {
235242
Field(FfiSlice<'ast, Field<'ast>>),
236243
}
237244

245+
impl<'ast> AdtKind<'ast> {
246+
// The slice lifetime is here explicitly denoted, as this is used by the
247+
// driver for convenience and is not part of the public API
248+
pub fn fields(self) -> &'ast [Field<'ast>] {
249+
match self {
250+
AdtKind::Tuple(fields) | AdtKind::Field(fields) => fields.get(),
251+
AdtKind::Unit => &[],
252+
}
253+
}
254+
}
255+
238256
/// A single field inside a [`StructItem`] or [`UnionItem`] with an identifier
239257
/// type and span.
240258
#[repr(C)]

linter_api/src/ast/item/extern_block_item.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::ast::Abi;
22
use crate::ffi::FfiSlice;
33

4-
use super::{CommonItemData, ExternalItemKind};
4+
use super::{CommonItemData, ExternItemKind};
55

66
/// An extern block with items like this:
77
///
@@ -19,7 +19,7 @@ use super::{CommonItemData, ExternalItemKind};
1919
pub struct ExternBlockItem<'ast> {
2020
data: CommonItemData<'ast>,
2121
abi: Abi,
22-
items: FfiSlice<'ast, ExternalItemKind<'ast>>,
22+
items: FfiSlice<'ast, ExternItemKind<'ast>>,
2323
}
2424

2525
super::impl_item_data!(ExternBlockItem, ExternBlock);
@@ -29,14 +29,18 @@ impl<'ast> ExternBlockItem<'ast> {
2929
self.abi
3030
}
3131

32-
pub fn items(&self) -> &[ExternalItemKind<'ast>] {
32+
pub fn items(&self) -> &[ExternItemKind<'ast>] {
3333
self.items.get()
3434
}
3535
}
3636

3737
#[cfg(feature = "driver-api")]
3838
impl<'ast> ExternBlockItem<'ast> {
39-
pub fn new(data: CommonItemData<'ast>, abi: Abi, items: FfiSlice<'ast, ExternalItemKind<'ast>>) -> Self {
40-
Self { data, abi, items }
39+
pub fn new(data: CommonItemData<'ast>, abi: Abi, items: &'ast [ExternItemKind<'ast>]) -> Self {
40+
Self {
41+
data,
42+
abi,
43+
items: items.into(),
44+
}
4145
}
4246
}

linter_api/src/ast/item/extern_crate_item.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::ast::Symbol;
1+
use crate::ast::SymbolId;
2+
use crate::context::with_cx;
23

34
use super::CommonItemData;
45

@@ -18,7 +19,7 @@ use super::CommonItemData;
1819
#[derive(Debug)]
1920
pub struct ExternCrateItem<'ast> {
2021
data: CommonItemData<'ast>,
21-
crate_name: Symbol,
22+
crate_name: SymbolId,
2223
}
2324

2425
super::impl_item_data!(ExternCrateItem, ExternCrate);
@@ -29,14 +30,14 @@ impl<'ast> ExternCrateItem<'ast> {
2930
/// declared an alias with as.
3031
///
3132
/// In most cases, you want to use this over the `get_name()` function.
32-
pub fn crate_name(&self) -> Symbol {
33-
self.crate_name
33+
pub fn crate_name(&self) -> String {
34+
with_cx(self, |cx| cx.symbol_str(self.crate_name))
3435
}
3536
}
3637

3738
#[cfg(feature = "driver-api")]
3839
impl<'ast> ExternCrateItem<'ast> {
39-
pub fn new(data: CommonItemData<'ast>, crate_name: Symbol) -> Self {
40+
pub fn new(data: CommonItemData<'ast>, crate_name: SymbolId) -> Self {
4041
Self { data, crate_name }
4142
}
4243
}

linter_api/src/ast/item/fn_item.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ impl<'ast> FnItem<'ast> {
4949
data: CommonItemData<'ast>,
5050
generics: GenericParams<'ast>,
5151
callable_data: CommonCallableData<'ast>,
52-
body: FfiOption<BodyId>,
52+
body: Option<BodyId>,
5353
) -> Self {
5454
Self {
5555
data,
5656
generics,
5757
callable_data,
58-
body,
58+
body: body.into(),
5959
}
6060
}
6161
}

linter_api/src/ast/item/static_item.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::ast::{ty::TyKind, BodyId, Mutability};
1+
use crate::{
2+
ast::{ty::TyKind, BodyId, Mutability},
3+
ffi::FfiOption,
4+
};
25

36
use super::CommonItemData;
47

@@ -18,7 +21,7 @@ use super::CommonItemData;
1821
pub struct StaticItem<'ast> {
1922
data: CommonItemData<'ast>,
2023
mutability: Mutability,
21-
body_id: BodyId,
24+
body_id: FfiOption<BodyId>,
2225
ty: TyKind<'ast>,
2326
}
2427

@@ -36,18 +39,18 @@ impl<'ast> StaticItem<'ast> {
3639
}
3740

3841
/// This returns the [`BodyId`] of the initialization body.
39-
pub fn body_id(&self) -> BodyId {
40-
self.body_id
42+
pub fn body_id(&self) -> Option<BodyId> {
43+
self.body_id.get().copied()
4144
}
4245
}
4346

4447
#[cfg(feature = "driver-api")]
4548
impl<'ast> StaticItem<'ast> {
46-
pub fn new(data: CommonItemData<'ast>, mutability: Mutability, body_id: BodyId, ty: TyKind<'ast>) -> Self {
49+
pub fn new(data: CommonItemData<'ast>, mutability: Mutability, body_id: Option<BodyId>, ty: TyKind<'ast>) -> Self {
4750
Self {
4851
data,
4952
mutability,
50-
body_id,
53+
body_id: body_id.into(),
5154
ty,
5255
}
5356
}

0 commit comments

Comments
 (0)