Auto merge of #17693 - Veykril:astidmap, r=Veykril

Remove Params and Fields from AstIdMap

These are too volatile, and the only reason for them seems to be for cfg diagnostics which does not carry the weight
This commit is contained in:
bors 2024-07-25 09:06:34 +00:00
commit 42facc20c6
21 changed files with 1147 additions and 466 deletions

View file

@ -20,7 +20,7 @@ use triomphe::Arc;
use crate::{
db::DefDatabase,
item_tree::{AttrOwner, Fields, ItemTreeNode},
item_tree::{AttrOwner, FieldParent, ItemTreeNode},
lang_item::LangItem,
nameres::{ModuleOrigin, ModuleSource},
src::{HasChildSource, HasSource},
@ -76,40 +76,36 @@ impl Attrs {
let mut res = ArenaMap::default();
let crate_graph = db.crate_graph();
let (fields, item_tree, krate) = match v {
let item_tree;
let (parent, fields, krate) = match v {
VariantId::EnumVariantId(it) => {
let loc = it.lookup(db);
let krate = loc.parent.lookup(db).container.krate;
let item_tree = loc.id.item_tree(db);
item_tree = loc.id.item_tree(db);
let variant = &item_tree[loc.id.value];
(variant.fields.clone(), item_tree, krate)
(FieldParent::Variant(loc.id.value), &variant.fields, krate)
}
VariantId::StructId(it) => {
let loc = it.lookup(db);
let krate = loc.container.krate;
let item_tree = loc.id.item_tree(db);
item_tree = loc.id.item_tree(db);
let struct_ = &item_tree[loc.id.value];
(struct_.fields.clone(), item_tree, krate)
(FieldParent::Struct(loc.id.value), &struct_.fields, krate)
}
VariantId::UnionId(it) => {
let loc = it.lookup(db);
let krate = loc.container.krate;
let item_tree = loc.id.item_tree(db);
item_tree = loc.id.item_tree(db);
let union_ = &item_tree[loc.id.value];
(union_.fields.clone(), item_tree, krate)
(FieldParent::Union(loc.id.value), &union_.fields, krate)
}
};
let fields = match fields {
Fields::Record(fields) | Fields::Tuple(fields) => fields,
Fields::Unit => return Arc::new(res),
};
let cfg_options = &crate_graph[krate].cfg_options;
let mut idx = 0;
for field in fields {
let attrs = item_tree.attrs(db, krate, field.into());
for (id, _field) in fields.iter().enumerate() {
let attrs = item_tree.attrs(db, krate, AttrOwner::make_field_indexed(parent, id));
if attrs.is_cfg_enabled(cfg_options) {
res.insert(Idx::from_raw(RawIdx::from(idx)), attrs);
idx += 1;

View file

@ -11,7 +11,7 @@ use std::ops::{Deref, Index};
use base_db::CrateId;
use cfg::{CfgExpr, CfgOptions};
use hir_expand::{name::Name, InFile};
use la_arena::{Arena, ArenaMap};
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use span::MacroFileId;
@ -24,6 +24,7 @@ use crate::{
hir::{
dummy_expr_id, Binding, BindingId, Expr, ExprId, Label, LabelId, Pat, PatId, RecordFieldPat,
},
item_tree::AttrOwner,
nameres::DefMap,
path::{ModPath, Path},
src::HasSource,
@ -136,16 +137,23 @@ impl Body {
let data = db.function_data(f);
let f = f.lookup(db);
let src = f.source(db);
params = src.value.param_list().map(|param_list| {
params = src.value.param_list().map(move |param_list| {
let item_tree = f.id.item_tree(db);
let func = &item_tree[f.id.value];
let krate = f.container.module(db).krate;
let crate_graph = db.crate_graph();
(
param_list,
func.params.clone().map(move |param| {
(0..func.params.len()).map(move |idx| {
item_tree
.attrs(db, krate, param.into())
.attrs(
db,
krate,
AttrOwner::Param(
f.id.value,
Idx::from_raw(RawIdx::from(idx as u32)),
),
)
.is_cfg_enabled(&crate_graph[krate].cfg_options)
}),
)

View file

@ -7,6 +7,7 @@ use hir_expand::{
name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind,
};
use intern::{sym, Interned, Symbol};
use la_arena::{Idx, RawIdx};
use smallvec::SmallVec;
use syntax::{ast, Parse};
use triomphe::Arc;
@ -58,37 +59,31 @@ impl FunctionData {
let crate_graph = db.crate_graph();
let cfg_options = &crate_graph[krate].cfg_options;
let enabled_params = func
.params
.clone()
.filter(|&param| item_tree.attrs(db, krate, param.into()).is_cfg_enabled(cfg_options));
// If last cfg-enabled param is a `...` param, it's a varargs function.
let is_varargs = enabled_params
.clone()
.next_back()
.map_or(false, |param| item_tree[param].type_ref.is_none());
let attr_owner = |idx| {
item_tree::AttrOwner::Param(loc.id.value, Idx::from_raw(RawIdx::from(idx as u32)))
};
let mut flags = func.flags;
if is_varargs {
flags |= FnFlags::IS_VARARGS;
}
if flags.contains(FnFlags::HAS_SELF_PARAM) {
// If there's a self param in the syntax, but it is cfg'd out, remove the flag.
let is_cfgd_out = match func.params.clone().next() {
Some(param) => {
!item_tree.attrs(db, krate, param.into()).is_cfg_enabled(cfg_options)
}
None => {
stdx::never!("fn HAS_SELF_PARAM but no parameters allocated");
true
}
};
let is_cfgd_out =
!item_tree.attrs(db, krate, attr_owner(0usize)).is_cfg_enabled(cfg_options);
if is_cfgd_out {
cov_mark::hit!(cfgd_out_self_param);
flags.remove(FnFlags::HAS_SELF_PARAM);
}
}
if flags.contains(FnFlags::IS_VARARGS) {
if let Some((_, param)) = func.params.iter().enumerate().rev().find(|&(idx, _)| {
item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options)
}) {
if param.type_ref.is_some() {
flags.remove(FnFlags::IS_VARARGS);
}
} else {
flags.remove(FnFlags::IS_VARARGS);
}
}
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
let legacy_const_generics_indices = attrs
@ -101,9 +96,14 @@ impl FunctionData {
Arc::new(FunctionData {
name: func.name.clone(),
params: enabled_params
.clone()
.filter_map(|id| item_tree[id].type_ref.clone())
params: func
.params
.iter()
.enumerate()
.filter(|&(idx, _)| {
item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options)
})
.filter_map(|(_, param)| param.type_ref.clone())
.collect(),
ret_type: func.ret_type.clone(),
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
@ -629,7 +629,8 @@ impl<'a> AssocItemCollector<'a> {
if !attrs.is_cfg_enabled(self.expander.cfg_options()) {
self.diagnostics.push(DefDiagnostic::unconfigured_code(
self.module_id.local_id,
InFile::new(self.expander.current_file_id(), item.ast_id(item_tree).erase()),
tree_id,
ModItem::from(item).into(),
attrs.cfg().unwrap(),
self.expander.cfg_options().clone(),
));

View file

@ -7,7 +7,7 @@ use either::Either;
use hir_expand::{
name::{AsName, Name},
HirFileId, InFile,
InFile,
};
use intern::{sym, Interned};
use la_arena::Arena;
@ -18,7 +18,9 @@ use triomphe::Arc;
use crate::{
builtin_type::{BuiltinInt, BuiltinUint},
db::DefDatabase,
item_tree::{AttrOwner, Field, FieldAstId, Fields, ItemTree, ModItem, RawVisibilityId},
item_tree::{
AttrOwner, Field, FieldParent, FieldsShape, ItemTree, ModItem, RawVisibilityId, TreeId,
},
lang_item::LangItem,
lower::LowerCtx,
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
@ -211,20 +213,25 @@ impl StructData {
}
let strukt = &item_tree[loc.id.value];
let (variant_data, diagnostics) = lower_fields(
let (data, diagnostics) = lower_fields(
db,
krate,
loc.id.file_id(),
loc.container.local_id,
loc.id.tree_id(),
&item_tree,
&db.crate_graph()[krate].cfg_options,
FieldParent::Struct(loc.id.value),
&strukt.fields,
None,
);
(
Arc::new(StructData {
name: strukt.name.clone(),
variant_data: Arc::new(variant_data),
variant_data: Arc::new(match strukt.shape {
FieldsShape::Record => VariantData::Record(data),
FieldsShape::Tuple => VariantData::Tuple(data),
FieldsShape::Unit => VariantData::Unit,
}),
repr,
visibility: item_tree[strukt.visibility].clone(),
flags,
@ -256,20 +263,21 @@ impl StructData {
}
let union = &item_tree[loc.id.value];
let (variant_data, diagnostics) = lower_fields(
let (data, diagnostics) = lower_fields(
db,
krate,
loc.id.file_id(),
loc.container.local_id,
loc.id.tree_id(),
&item_tree,
&db.crate_graph()[krate].cfg_options,
FieldParent::Union(loc.id.value),
&union.fields,
None,
);
(
Arc::new(StructData {
name: union.name.clone(),
variant_data: Arc::new(variant_data),
variant_data: Arc::new(VariantData::Record(data)),
repr,
visibility: item_tree[union.visibility].clone(),
flags,
@ -336,13 +344,14 @@ impl EnumVariantData {
let item_tree = loc.id.item_tree(db);
let variant = &item_tree[loc.id.value];
let (var_data, diagnostics) = lower_fields(
let (data, diagnostics) = lower_fields(
db,
krate,
loc.id.file_id(),
container.local_id,
loc.id.tree_id(),
&item_tree,
&db.crate_graph()[krate].cfg_options,
FieldParent::Variant(loc.id.value),
&variant.fields,
Some(item_tree[loc.parent.lookup(db).id.value].visibility),
);
@ -350,7 +359,11 @@ impl EnumVariantData {
(
Arc::new(EnumVariantData {
name: variant.name.clone(),
variant_data: Arc::new(var_data),
variant_data: Arc::new(match variant.shape {
FieldsShape::Record => VariantData::Record(data),
FieldsShape::Tuple => VariantData::Tuple(data),
FieldsShape::Unit => VariantData::Unit,
}),
}),
DefDiagnostics::new(diagnostics),
)
@ -396,21 +409,23 @@ pub enum StructKind {
Unit,
}
// FIXME This is only used for mapping back source now?
pub(crate) fn lower_struct(
db: &dyn DefDatabase,
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
ast: &InFile<ast::StructKind>,
krate: CrateId,
item_tree: &ItemTree,
fields: &Fields,
parent: FieldParent,
) -> StructKind {
let ctx = LowerCtx::new(db, ast.file_id);
match (&ast.value, fields) {
(ast::StructKind::Tuple(fl), Fields::Tuple(fields)) => {
match &ast.value {
ast::StructKind::Tuple(fl) => {
let cfg_options = &db.crate_graph()[krate].cfg_options;
for ((i, fd), item_tree_id) in fl.fields().enumerate().zip(fields.clone()) {
if !item_tree.attrs(db, krate, item_tree_id.into()).is_cfg_enabled(cfg_options) {
for (i, fd) in fl.fields().enumerate() {
let attrs = item_tree.attrs(db, krate, AttrOwner::make_field_indexed(parent, i));
if !attrs.is_cfg_enabled(cfg_options) {
continue;
}
@ -427,10 +442,11 @@ pub(crate) fn lower_struct(
}
StructKind::Tuple
}
(ast::StructKind::Record(fl), Fields::Record(fields)) => {
ast::StructKind::Record(fl) => {
let cfg_options = &db.crate_graph()[krate].cfg_options;
for (fd, item_tree_id) in fl.fields().zip(fields.clone()) {
if !item_tree.attrs(db, krate, item_tree_id.into()).is_cfg_enabled(cfg_options) {
for (i, fd) in fl.fields().enumerate() {
let attrs = item_tree.attrs(db, krate, AttrOwner::make_field_indexed(parent, i));
if !attrs.is_cfg_enabled(cfg_options) {
continue;
}
@ -454,65 +470,32 @@ pub(crate) fn lower_struct(
fn lower_fields(
db: &dyn DefDatabase,
krate: CrateId,
current_file_id: HirFileId,
container: LocalModuleId,
tree_id: TreeId,
item_tree: &ItemTree,
cfg_options: &CfgOptions,
fields: &Fields,
parent: FieldParent,
fields: &[Field],
override_visibility: Option<RawVisibilityId>,
) -> (VariantData, Vec<DefDiagnostic>) {
) -> (Arena<FieldData>, Vec<DefDiagnostic>) {
let mut diagnostics = Vec::new();
match fields {
Fields::Record(flds) => {
let mut arena = Arena::new();
for field_id in flds.clone() {
let attrs = item_tree.attrs(db, krate, field_id.into());
let field = &item_tree[field_id];
if attrs.is_cfg_enabled(cfg_options) {
arena.alloc(lower_field(item_tree, field, override_visibility));
} else {
diagnostics.push(DefDiagnostic::unconfigured_code(
container,
InFile::new(
current_file_id,
match field.ast_id {
FieldAstId::Record(it) => it.erase(),
FieldAstId::Tuple(it) => it.erase(),
},
),
attrs.cfg().unwrap(),
cfg_options.clone(),
))
}
}
(VariantData::Record(arena), diagnostics)
let mut arena = Arena::new();
for (idx, field) in fields.iter().enumerate() {
let attr_owner = AttrOwner::make_field_indexed(parent, idx);
let attrs = item_tree.attrs(db, krate, attr_owner);
if attrs.is_cfg_enabled(cfg_options) {
arena.alloc(lower_field(item_tree, field, override_visibility));
} else {
diagnostics.push(DefDiagnostic::unconfigured_code(
container,
tree_id,
attr_owner,
attrs.cfg().unwrap(),
cfg_options.clone(),
))
}
Fields::Tuple(flds) => {
let mut arena = Arena::new();
for field_id in flds.clone() {
let attrs = item_tree.attrs(db, krate, field_id.into());
let field = &item_tree[field_id];
if attrs.is_cfg_enabled(cfg_options) {
arena.alloc(lower_field(item_tree, field, override_visibility));
} else {
diagnostics.push(DefDiagnostic::unconfigured_code(
container,
InFile::new(
current_file_id,
match field.ast_id {
FieldAstId::Record(it) => it.erase(),
FieldAstId::Tuple(it) => it.erase(),
},
),
attrs.cfg().unwrap(),
cfg_options.clone(),
))
}
}
(VariantData::Tuple(arena), diagnostics)
}
Fields::Unit => (VariantData::Unit, diagnostics),
}
(arena, diagnostics)
}
fn lower_field(

View file

@ -47,7 +47,7 @@ use base_db::CrateId;
use either::Either;
use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile};
use intern::{Interned, Symbol};
use la_arena::{Arena, Idx, IdxRange, RawIdx};
use la_arena::{Arena, Idx, RawIdx};
use once_cell::sync::OnceCell;
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
@ -218,9 +218,7 @@ impl ItemTree {
extern_crates,
extern_blocks,
functions,
params,
structs,
fields,
unions,
enums,
variants,
@ -241,9 +239,7 @@ impl ItemTree {
extern_crates.shrink_to_fit();
extern_blocks.shrink_to_fit();
functions.shrink_to_fit();
params.shrink_to_fit();
structs.shrink_to_fit();
fields.shrink_to_fit();
unions.shrink_to_fit();
enums.shrink_to_fit();
variants.shrink_to_fit();
@ -295,9 +291,7 @@ struct ItemTreeData {
extern_crates: Arena<ExternCrate>,
extern_blocks: Arena<ExternBlock>,
functions: Arena<Function>,
params: Arena<Param>,
structs: Arena<Struct>,
fields: Arena<Field>,
unions: Arena<Union>,
enums: Arena<Enum>,
variants: Arena<Variant>,
@ -315,7 +309,7 @@ struct ItemTreeData {
vis: ItemVisibilities,
}
#[derive(Debug, Eq, PartialEq, Hash)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum AttrOwner {
/// Attributes on an item.
ModItem(ModItem),
@ -323,12 +317,28 @@ pub enum AttrOwner {
TopLevel,
Variant(FileItemTreeId<Variant>),
Field(Idx<Field>),
Param(Idx<Param>),
Field(FieldParent, ItemTreeFieldId),
Param(FileItemTreeId<Function>, ItemTreeParamId),
TypeOrConstParamData(GenericModItem, LocalTypeOrConstParamId),
LifetimeParamData(GenericModItem, LocalLifetimeParamId),
}
impl AttrOwner {
pub fn make_field_indexed(parent: FieldParent, idx: usize) -> Self {
AttrOwner::Field(parent, ItemTreeFieldId::from_raw(RawIdx::from_u32(idx as u32)))
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum FieldParent {
Struct(FileItemTreeId<Struct>),
Union(FileItemTreeId<Union>),
Variant(FileItemTreeId<Variant>),
}
pub type ItemTreeParamId = Idx<Param>;
pub type ItemTreeFieldId = Idx<Field>;
macro_rules! from_attrs {
( $( $var:ident($t:ty) ),+ $(,)? ) => {
$(
@ -341,12 +351,7 @@ macro_rules! from_attrs {
};
}
from_attrs!(
ModItem(ModItem),
Variant(FileItemTreeId<Variant>),
Field(Idx<Field>),
Param(Idx<Param>),
);
from_attrs!(ModItem(ModItem), Variant(FileItemTreeId<Variant>));
/// Trait implemented by all nodes in the item tree.
pub trait ItemTreeNode: Clone {
@ -365,7 +370,7 @@ pub trait GenericsItemTreeNode: ItemTreeNode {
pub struct FileItemTreeId<N>(Idx<N>);
impl<N> FileItemTreeId<N> {
pub fn range_iter(range: Range<Self>) -> impl Iterator<Item = Self> {
pub fn range_iter(range: Range<Self>) -> impl Iterator<Item = Self> + Clone {
(range.start.index().into_raw().into_u32()..range.end.index().into_raw().into_u32())
.map(RawIdx::from_u32)
.map(Idx::from_raw)
@ -417,18 +422,18 @@ impl TreeId {
Self { file, block }
}
pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
pub fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
match self.block {
Some(block) => db.block_item_tree(block),
None => db.file_item_tree(self.file),
}
}
pub(crate) fn file_id(self) -> HirFileId {
pub fn file_id(self) -> HirFileId {
self.file
}
pub(crate) fn is_block(self) -> bool {
pub fn is_block(self) -> bool {
self.block.is_some()
}
}
@ -505,6 +510,27 @@ macro_rules! mod_items {
)+
}
impl ModItem {
pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
match self {
$(ModItem::$typ(it) => tree[it.index()].ast_id().upcast()),+
}
}
}
impl GenericModItem {
pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::AnyHasGenericParams> {
match self {
$(
$(
#[cfg_attr(ignore_fragment, $generic_params)]
GenericModItem::$typ(it) => tree[it.index()].ast_id().upcast(),
)?
)+
}
}
}
impl From<GenericModItem> for ModItem {
fn from(id: GenericModItem) -> ModItem {
match id {
@ -596,22 +622,6 @@ mod_items! {
Macro2 in macro_defs -> ast::MacroDef,
}
macro_rules! impl_index {
( $($fld:ident: $t:ty),+ $(,)? ) => {
$(
impl Index<Idx<$t>> for ItemTree {
type Output = $t;
fn index(&self, index: Idx<$t>) -> &Self::Output {
&self.data().$fld[index]
}
}
)+
};
}
impl_index!(fields: Field, variants: Variant, params: Param);
impl Index<RawVisibilityId> for ItemTree {
type Output = RawVisibility;
fn index(&self, index: RawVisibilityId) -> &Self::Output {
@ -723,7 +733,7 @@ pub struct Function {
pub visibility: RawVisibilityId,
pub explicit_generic_params: Interned<GenericParams>,
pub abi: Option<Symbol>,
pub params: IdxRange<Param>,
pub params: Box<[Param]>,
pub ret_type: Interned<TypeRef>,
pub ast_id: FileAstId<ast::Fn>,
pub(crate) flags: FnFlags,
@ -731,15 +741,7 @@ pub struct Function {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Param {
/// This is [`None`] for varargs
pub type_ref: Option<Interned<TypeRef>>,
pub ast_id: ParamAstId,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ParamAstId {
Param(FileAstId<ast::Param>),
SelfParam(FileAstId<ast::SelfParam>),
}
bitflags::bitflags! {
@ -760,7 +762,8 @@ pub struct Struct {
pub name: Name,
pub visibility: RawVisibilityId,
pub generic_params: Interned<GenericParams>,
pub fields: Fields,
pub fields: Box<[Field]>,
pub shape: FieldsShape,
pub ast_id: FileAstId<ast::Struct>,
}
@ -769,7 +772,7 @@ pub struct Union {
pub name: Name,
pub visibility: RawVisibilityId,
pub generic_params: Interned<GenericParams>,
pub fields: Fields,
pub fields: Box<[Field]>,
pub ast_id: FileAstId<ast::Union>,
}
@ -782,6 +785,29 @@ pub struct Enum {
pub ast_id: FileAstId<ast::Enum>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Variant {
pub name: Name,
pub fields: Box<[Field]>,
pub shape: FieldsShape,
pub ast_id: FileAstId<ast::Variant>,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FieldsShape {
Record,
Tuple,
Unit,
}
/// A single field of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Field {
pub name: Name,
pub type_ref: Interned<TypeRef>,
pub visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Const {
/// `None` for `const _: () = ();`
@ -1039,28 +1065,6 @@ impl ModItem {
&ModItem::Function(func) => Some(AssocItem::Function(func)),
}
}
pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
match self {
ModItem::Use(it) => tree[it.index()].ast_id().upcast(),
ModItem::ExternCrate(it) => tree[it.index()].ast_id().upcast(),
ModItem::ExternBlock(it) => tree[it.index()].ast_id().upcast(),
ModItem::Function(it) => tree[it.index()].ast_id().upcast(),
ModItem::Struct(it) => tree[it.index()].ast_id().upcast(),
ModItem::Union(it) => tree[it.index()].ast_id().upcast(),
ModItem::Enum(it) => tree[it.index()].ast_id().upcast(),
ModItem::Const(it) => tree[it.index()].ast_id().upcast(),
ModItem::Static(it) => tree[it.index()].ast_id().upcast(),
ModItem::Trait(it) => tree[it.index()].ast_id().upcast(),
ModItem::TraitAlias(it) => tree[it.index()].ast_id().upcast(),
ModItem::Impl(it) => tree[it.index()].ast_id().upcast(),
ModItem::TypeAlias(it) => tree[it.index()].ast_id().upcast(),
ModItem::Mod(it) => tree[it.index()].ast_id().upcast(),
ModItem::MacroCall(it) => tree[it.index()].ast_id().upcast(),
ModItem::MacroRules(it) => tree[it.index()].ast_id().upcast(),
ModItem::Macro2(it) => tree[it.index()].ast_id().upcast(),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
@ -1099,32 +1103,3 @@ impl AssocItem {
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Variant {
pub name: Name,
pub fields: Fields,
pub ast_id: FileAstId<ast::Variant>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Fields {
Record(IdxRange<Field>),
Tuple(IdxRange<Field>),
Unit,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FieldAstId {
Record(FileAstId<ast::RecordField>),
Tuple(FileAstId<ast::TupleField>),
}
/// A single field of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Field {
pub name: Name,
pub type_ref: Interned<TypeRef>,
pub visibility: RawVisibilityId,
pub ast_id: FieldAstId,
}

View file

@ -17,12 +17,12 @@ use crate::{
db::DefDatabase,
generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance},
item_tree::{
AssocItem, AttrOwner, Const, Either, Enum, ExternBlock, ExternCrate, Field, FieldAstId,
Fields, FileItemTreeId, FnFlags, Function, GenericArgs, GenericModItem, Idx, IdxRange,
Impl, ImportAlias, Interned, ItemTree, ItemTreeData, ItemTreeNode, Macro2, MacroCall,
MacroRules, Mod, ModItem, ModKind, ModPath, Mutability, Name, Param, ParamAstId, Path,
Range, RawAttrs, RawIdx, RawVisibilityId, Static, Struct, StructKind, Trait, TraitAlias,
TypeAlias, Union, Use, UseTree, UseTreeKind, Variant,
AssocItem, AttrOwner, Const, Either, Enum, ExternBlock, ExternCrate, Field, FieldParent,
FieldsShape, FileItemTreeId, FnFlags, Function, GenericArgs, GenericModItem, Idx, Impl,
ImportAlias, Interned, ItemTree, ItemTreeData, Macro2, MacroCall, MacroRules, Mod, ModItem,
ModKind, ModPath, Mutability, Name, Param, Path, Range, RawAttrs, RawIdx, RawVisibilityId,
Static, Struct, StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
Variant,
},
path::AssociatedTypeBinding,
type_ref::{LifetimeRef, TraitBoundModifier, TraitRef, TypeBound, TypeRef},
@ -30,7 +30,7 @@ use crate::{
LocalLifetimeParamId, LocalTypeOrConstParamId,
};
fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> {
fn id<N>(index: Idx<N>) -> FileItemTreeId<N> {
FileItemTreeId(index)
}
@ -193,82 +193,98 @@ impl<'a> Ctx<'a> {
let visibility = self.lower_visibility(strukt);
let name = strukt.name()?.as_name();
let ast_id = self.source_ast_id_map.ast_id(strukt);
let fields = self.lower_fields(&strukt.kind());
let (fields, kind, attrs) = self.lower_fields(&strukt.kind());
let generic_params = self.lower_generic_params(HasImplicitSelf::No, strukt);
let res = Struct { name, visibility, generic_params, fields, ast_id };
let res = Struct { name, visibility, generic_params, fields, shape: kind, ast_id };
let id = id(self.data().structs.alloc(res));
for (idx, attr) in attrs {
self.add_attrs(
AttrOwner::Field(
FieldParent::Struct(id),
Idx::from_raw(RawIdx::from_u32(idx as u32)),
),
attr,
);
}
self.write_generic_params_attributes(id.into());
Some(id)
}
fn lower_fields(&mut self, strukt_kind: &ast::StructKind) -> Fields {
fn lower_fields(
&mut self,
strukt_kind: &ast::StructKind,
) -> (Box<[Field]>, FieldsShape, Vec<(usize, RawAttrs)>) {
match strukt_kind {
ast::StructKind::Record(it) => {
let range = self.lower_record_fields(it);
Fields::Record(range)
let mut fields = vec![];
let mut attrs = vec![];
for (i, field) in it.fields().enumerate() {
let data = self.lower_record_field(&field);
fields.push(data);
let attr = RawAttrs::new(self.db.upcast(), &field, self.span_map());
if !attr.is_empty() {
attrs.push((i, attr))
}
}
(fields.into(), FieldsShape::Record, attrs)
}
ast::StructKind::Tuple(it) => {
let range = self.lower_tuple_fields(it);
Fields::Tuple(range)
let mut fields = vec![];
let mut attrs = vec![];
for (i, field) in it.fields().enumerate() {
let data = self.lower_tuple_field(i, &field);
fields.push(data);
let attr = RawAttrs::new(self.db.upcast(), &field, self.span_map());
if !attr.is_empty() {
attrs.push((i, attr))
}
}
(fields.into(), FieldsShape::Tuple, attrs)
}
ast::StructKind::Unit => Fields::Unit,
ast::StructKind::Unit => (Box::default(), FieldsShape::Unit, Vec::default()),
}
}
fn lower_record_fields(&mut self, fields: &ast::RecordFieldList) -> IdxRange<Field> {
let start = self.next_field_idx();
for field in fields.fields() {
if let Some(data) = self.lower_record_field(&field) {
let idx = self.data().fields.alloc(data);
self.add_attrs(
idx.into(),
RawAttrs::new(self.db.upcast(), &field, self.span_map()),
);
}
}
let end = self.next_field_idx();
IdxRange::new(start..end)
}
fn lower_record_field(&mut self, field: &ast::RecordField) -> Option<Field> {
let name = field.name()?.as_name();
fn lower_record_field(&mut self, field: &ast::RecordField) -> Field {
let name = match field.name() {
Some(name) => name.as_name(),
None => Name::missing(),
};
let visibility = self.lower_visibility(field);
let type_ref = self.lower_type_ref_opt(field.ty());
let ast_id = FieldAstId::Record(self.source_ast_id_map.ast_id(field));
let res = Field { name, type_ref, visibility, ast_id };
Some(res)
}
fn lower_tuple_fields(&mut self, fields: &ast::TupleFieldList) -> IdxRange<Field> {
let start = self.next_field_idx();
for (i, field) in fields.fields().enumerate() {
let data = self.lower_tuple_field(i, &field);
let idx = self.data().fields.alloc(data);
self.add_attrs(idx.into(), RawAttrs::new(self.db.upcast(), &field, self.span_map()));
}
let end = self.next_field_idx();
IdxRange::new(start..end)
Field { name, type_ref, visibility }
}
fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleField) -> Field {
let name = Name::new_tuple_field(idx);
let visibility = self.lower_visibility(field);
let type_ref = self.lower_type_ref_opt(field.ty());
let ast_id = FieldAstId::Tuple(self.source_ast_id_map.ast_id(field));
Field { name, type_ref, visibility, ast_id }
Field { name, type_ref, visibility }
}
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
let visibility = self.lower_visibility(union);
let name = union.name()?.as_name();
let ast_id = self.source_ast_id_map.ast_id(union);
let fields = match union.record_field_list() {
let (fields, _, attrs) = match union.record_field_list() {
Some(record_field_list) => self.lower_fields(&StructKind::Record(record_field_list)),
None => Fields::Record(IdxRange::new(self.next_field_idx()..self.next_field_idx())),
None => (Box::default(), FieldsShape::Record, Vec::default()),
};
let generic_params = self.lower_generic_params(HasImplicitSelf::No, union);
let res = Union { name, visibility, generic_params, fields, ast_id };
let id = id(self.data().unions.alloc(res));
for (idx, attr) in attrs {
self.add_attrs(
AttrOwner::Field(
FieldParent::Union(id),
Idx::from_raw(RawIdx::from_u32(idx as u32)),
),
attr,
);
}
self.write_generic_params_attributes(id.into());
Some(id)
}
@ -293,24 +309,35 @@ impl<'a> Ctx<'a> {
fn lower_variants(&mut self, variants: &ast::VariantList) -> Range<FileItemTreeId<Variant>> {
let start = self.next_variant_idx();
for variant in variants.variants() {
if let Some(data) = self.lower_variant(&variant) {
let idx = self.data().variants.alloc(data);
self.add_attrs(
id(idx).into(),
RawAttrs::new(self.db.upcast(), &variant, self.span_map()),
);
}
let idx = self.lower_variant(&variant);
self.add_attrs(
id(idx).into(),
RawAttrs::new(self.db.upcast(), &variant, self.span_map()),
);
}
let end = self.next_variant_idx();
FileItemTreeId(start)..FileItemTreeId(end)
}
fn lower_variant(&mut self, variant: &ast::Variant) -> Option<Variant> {
let name = variant.name()?.as_name();
let fields = self.lower_fields(&variant.kind());
fn lower_variant(&mut self, variant: &ast::Variant) -> Idx<Variant> {
let name = match variant.name() {
Some(name) => name.as_name(),
None => Name::missing(),
};
let (fields, kind, attrs) = self.lower_fields(&variant.kind());
let ast_id = self.source_ast_id_map.ast_id(variant);
let res = Variant { name, fields, ast_id };
Some(res)
let res = Variant { name, fields, shape: kind, ast_id };
let id = self.data().variants.alloc(res);
for (idx, attr) in attrs {
self.add_attrs(
AttrOwner::Field(
FieldParent::Variant(FileItemTreeId(id)),
Idx::from_raw(RawIdx::from_u32(idx as u32)),
),
attr,
);
}
id
}
fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> {
@ -318,9 +345,20 @@ impl<'a> Ctx<'a> {
let name = func.name()?.as_name();
let mut has_self_param = false;
let start_param = self.next_param_idx();
let mut has_var_args = false;
let mut params = vec![];
let mut attrs = vec![];
let mut push_attr = |idx, attr: RawAttrs| {
if !attr.is_empty() {
attrs.push((idx, attr))
}
};
if let Some(param_list) = func.param_list() {
if let Some(self_param) = param_list.self_param() {
push_attr(
params.len(),
RawAttrs::new(self.db.upcast(), &self_param, self.span_map()),
);
let self_type = match self_param.ty() {
Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
None => {
@ -342,40 +380,25 @@ impl<'a> Ctx<'a> {
}
};
let type_ref = Interned::new(self_type);
let ast_id = self.source_ast_id_map.ast_id(&self_param);
let idx = self.data().params.alloc(Param {
type_ref: Some(type_ref),
ast_id: ParamAstId::SelfParam(ast_id),
});
self.add_attrs(
idx.into(),
RawAttrs::new(self.db.upcast(), &self_param, self.span_map()),
);
params.push(Param { type_ref: Some(type_ref) });
has_self_param = true;
}
for param in param_list.params() {
let ast_id = self.source_ast_id_map.ast_id(&param);
let idx = match param.dotdotdot_token() {
Some(_) => self
.data()
.params
.alloc(Param { type_ref: None, ast_id: ParamAstId::Param(ast_id) }),
push_attr(params.len(), RawAttrs::new(self.db.upcast(), &param, self.span_map()));
let param = match param.dotdotdot_token() {
Some(_) => {
has_var_args = true;
Param { type_ref: None }
}
None => {
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
let ty = Interned::new(type_ref);
self.data()
.params
.alloc(Param { type_ref: Some(ty), ast_id: ParamAstId::Param(ast_id) })
Param { type_ref: Some(ty) }
}
};
self.add_attrs(
idx.into(),
RawAttrs::new(self.db.upcast(), &param, self.span_map()),
);
params.push(param);
}
}
let end_param = self.next_param_idx();
let params = IdxRange::new(start_param..end_param);
let ret_type = match func.ret_type() {
Some(rt) => match rt.ty() {
@ -417,19 +440,25 @@ impl<'a> Ctx<'a> {
if func.unsafe_token().is_some() {
flags |= FnFlags::HAS_UNSAFE_KW;
}
if has_var_args {
flags |= FnFlags::IS_VARARGS;
}
let res = Function {
name,
visibility,
explicit_generic_params: self.lower_generic_params(HasImplicitSelf::No, func),
abi,
params,
params: params.into_boxed_slice(),
ret_type: Interned::new(ret_type),
ast_id,
flags,
};
let id = id(self.data().functions.alloc(res));
for (idx, attr) in attrs {
self.add_attrs(AttrOwner::Param(id, Idx::from_raw(RawIdx::from_u32(idx as u32))), attr);
}
self.write_generic_params_attributes(id.into());
Some(id)
}
@ -725,21 +754,11 @@ impl<'a> Ctx<'a> {
}
}
fn next_field_idx(&self) -> Idx<Field> {
Idx::from_raw(RawIdx::from(
self.tree.data.as_ref().map_or(0, |data| data.fields.len() as u32),
))
}
fn next_variant_idx(&self) -> Idx<Variant> {
Idx::from_raw(RawIdx::from(
self.tree.data.as_ref().map_or(0, |data| data.variants.len() as u32),
))
}
fn next_param_idx(&self) -> Idx<Param> {
Idx::from_raw(RawIdx::from(
self.tree.data.as_ref().map_or(0, |data| data.params.len() as u32),
))
}
}
fn desugar_future_path(orig: TypeRef) -> Path {

View file

@ -2,16 +2,17 @@
use std::fmt::{self, Write};
use la_arena::{Idx, RawIdx};
use span::ErasedFileAstId;
use crate::{
generics::{TypeOrConstParamData, WherePredicate, WherePredicateTypeTarget},
item_tree::{
AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, Field, FieldAstId, Fields,
FileItemTreeId, FnFlags, Function, GenericModItem, GenericParams, Impl, Interned, ItemTree,
Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, Param, ParamAstId, Path, RawAttrs,
RawVisibilityId, Static, Struct, Trait, TraitAlias, TypeAlias, TypeBound, TypeRef, Union,
Use, UseTree, UseTreeKind, Variant,
AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, Field, FieldParent,
FieldsShape, FileItemTreeId, FnFlags, Function, GenericModItem, GenericParams, Impl,
Interned, ItemTree, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, Param, Path,
RawAttrs, RawVisibilityId, Static, Struct, Trait, TraitAlias, TypeAlias, TypeBound,
TypeRef, Union, Use, UseTree, UseTreeKind, Variant,
},
pretty::{print_path, print_type_bounds, print_type_ref},
visibility::RawVisibility,
@ -118,19 +119,17 @@ impl Printer<'_> {
};
}
fn print_fields(&mut self, fields: &Fields) {
match fields {
Fields::Record(fields) => {
fn print_fields(&mut self, parent: FieldParent, kind: FieldsShape, fields: &[Field]) {
match kind {
FieldsShape::Record => {
self.whitespace();
w!(self, "{{");
self.indented(|this| {
for field in fields.clone() {
let Field { visibility, name, type_ref, ast_id } = &this.tree[field];
this.print_ast_id(match ast_id {
FieldAstId::Record(it) => it.erase(),
FieldAstId::Tuple(it) => it.erase(),
});
this.print_attrs_of(field, "\n");
for (idx, Field { name, type_ref, visibility }) in fields.iter().enumerate() {
this.print_attrs_of(
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
"\n",
);
this.print_visibility(*visibility);
w!(this, "{}: ", name.display(self.db.upcast()));
this.print_type_ref(type_ref);
@ -139,16 +138,14 @@ impl Printer<'_> {
});
w!(self, "}}");
}
Fields::Tuple(fields) => {
FieldsShape::Tuple => {
w!(self, "(");
self.indented(|this| {
for field in fields.clone() {
let Field { visibility, name, type_ref, ast_id } = &this.tree[field];
this.print_ast_id(match ast_id {
FieldAstId::Record(it) => it.erase(),
FieldAstId::Tuple(it) => it.erase(),
});
this.print_attrs_of(field, "\n");
for (idx, Field { name, type_ref, visibility }) in fields.iter().enumerate() {
this.print_attrs_of(
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
"\n",
);
this.print_visibility(*visibility);
w!(this, "{}: ", name.display(self.db.upcast()));
this.print_type_ref(type_ref);
@ -157,24 +154,30 @@ impl Printer<'_> {
});
w!(self, ")");
}
Fields::Unit => {}
FieldsShape::Unit => {}
}
}
fn print_fields_and_where_clause(&mut self, fields: &Fields, params: &GenericParams) {
match fields {
Fields::Record(_) => {
fn print_fields_and_where_clause(
&mut self,
parent: FieldParent,
kind: FieldsShape,
fields: &[Field],
params: &GenericParams,
) {
match kind {
FieldsShape::Record => {
if self.print_where_clause(params) {
wln!(self);
}
self.print_fields(fields);
self.print_fields(parent, kind, fields);
}
Fields::Unit => {
FieldsShape::Unit => {
self.print_where_clause(params);
self.print_fields(fields);
self.print_fields(parent, kind, fields);
}
Fields::Tuple(_) => {
self.print_fields(fields);
FieldsShape::Tuple => {
self.print_fields(parent, kind, fields);
self.print_where_clause(params);
}
}
@ -280,25 +283,20 @@ impl Printer<'_> {
w!(self, "(");
if !params.is_empty() {
self.indented(|this| {
for param in params.clone() {
this.print_attrs_of(param, "\n");
let Param { type_ref, ast_id } = &this.tree[param];
this.print_ast_id(match ast_id {
ParamAstId::Param(it) => it.erase(),
ParamAstId::SelfParam(it) => it.erase(),
});
match type_ref {
Some(ty) => {
if flags.contains(FnFlags::HAS_SELF_PARAM) {
w!(this, "self: ");
}
this.print_type_ref(ty);
wln!(this, ",");
}
None => {
wln!(this, "...");
}
};
for (idx, Param { type_ref }) in params.iter().enumerate() {
this.print_attrs_of(
AttrOwner::Param(it, Idx::from_raw(RawIdx::from(idx as u32))),
"\n",
);
if idx == 0 && flags.contains(FnFlags::HAS_SELF_PARAM) {
w!(this, "self: ");
}
if let Some(type_ref) = type_ref {
this.print_type_ref(type_ref);
} else {
wln!(this, "...");
}
wln!(this, ",");
}
});
}
@ -312,13 +310,19 @@ impl Printer<'_> {
}
}
ModItem::Struct(it) => {
let Struct { visibility, name, fields, generic_params, ast_id } = &self.tree[it];
let Struct { visibility, name, fields, shape: kind, generic_params, ast_id } =
&self.tree[it];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "struct {}", name.display(self.db.upcast()));
self.print_generic_params(generic_params, it.into());
self.print_fields_and_where_clause(fields, generic_params);
if matches!(fields, Fields::Record(_)) {
self.print_fields_and_where_clause(
FieldParent::Struct(it),
*kind,
fields,
generic_params,
);
if matches!(kind, FieldsShape::Record) {
wln!(self);
} else {
wln!(self, ";");
@ -330,12 +334,13 @@ impl Printer<'_> {
self.print_visibility(*visibility);
w!(self, "union {}", name.display(self.db.upcast()));
self.print_generic_params(generic_params, it.into());
self.print_fields_and_where_clause(fields, generic_params);
if matches!(fields, Fields::Record(_)) {
wln!(self);
} else {
wln!(self, ";");
}
self.print_fields_and_where_clause(
FieldParent::Union(it),
FieldsShape::Record,
fields,
generic_params,
);
wln!(self);
}
ModItem::Enum(it) => {
let Enum { name, visibility, variants, generic_params, ast_id } = &self.tree[it];
@ -346,11 +351,11 @@ impl Printer<'_> {
self.print_where_clause_and_opening_brace(generic_params);
self.indented(|this| {
for variant in FileItemTreeId::range_iter(variants.clone()) {
let Variant { name, fields, ast_id } = &this.tree[variant];
let Variant { name, fields, shape: kind, ast_id } = &this.tree[variant];
this.print_ast_id(ast_id.erase());
this.print_attrs_of(variant, "\n");
w!(this, "{}", name.display(self.db.upcast()));
this.print_fields(fields);
this.print_fields(FieldParent::Variant(variant), *kind, fields);
wln!(this, ",");
}
});

View file

@ -129,40 +129,34 @@ enum E {
#[derive(Debug)]
// AstId: 2
pub(self) struct Struct {
// AstId: 6
#[doc = " fld docs"]
pub(self) fld: (),
}
// AstId: 3
pub(self) struct Tuple(
// AstId: 7
#[attr]
pub(self) 0: u8,
);
// AstId: 4
pub(self) union Ize {
// AstId: 8
pub(self) a: (),
// AstId: 9
pub(self) b: (),
}
// AstId: 5
pub(self) enum E {
// AstId: 10
// AstId: 6
#[doc = " comment on Unit"]
Unit,
// AstId: 11
// AstId: 7
#[doc = " comment on Tuple"]
Tuple(
// AstId: 13
pub(self) 0: u8,
),
// AstId: 12
// AstId: 8
Struct {
// AstId: 14
#[doc = " comment on a: u8"]
pub(self) a: u8,
},
@ -201,9 +195,7 @@ trait Tr: SuperTrait + 'lifetime {
// AstId: 3
pub(self) fn f(
#[attr]
// AstId: 5
u8,
// AstId: 6
(),
) -> () { ... }
@ -213,12 +205,11 @@ trait Tr: SuperTrait + 'lifetime {
Self: SuperTrait,
Self: 'lifetime
{
// AstId: 8
// AstId: 6
pub(self) type Assoc: AssocBound = Default;
// AstId: 9
// AstId: 7
pub(self) fn method(
// AstId: 10
self: &Self,
) -> ();
}
@ -300,17 +291,11 @@ struct S {
expect![[r#"
// AstId: 1
pub(self) struct S {
// AstId: 2
pub(self) a: self::Ty,
// AstId: 3
pub(self) b: super::SuperTy,
// AstId: 4
pub(self) c: super::super::SuperSuperTy,
// AstId: 5
pub(self) d: ::abs::Path,
// AstId: 6
pub(self) e: crate::Crate,
// AstId: 7
pub(self) f: plain::path::Ty,
}
"#]],
@ -331,13 +316,9 @@ struct S {
expect![[r#"
// AstId: 1
pub(self) struct S {
// AstId: 2
pub(self) a: Mixed::<'a, T, Item = (), OtherItem = u8>,
// AstId: 3
pub(self) b: Qualified::<Self=Fully>::Syntax,
// AstId: 4
pub(self) c: <TypeAnchored>::Path::<'a>,
// AstId: 5
pub(self) d: dyn for<'a> Trait::<'a>,
}
"#]],
@ -371,15 +352,12 @@ trait Tr<'a, T: 'a>: Super where Self: for<'a> Tr<'a, T> {}
T: 'a,
T: 'b
{
// AstId: 8
pub(self) field: &'a &'b T,
}
// AstId: 2
pub(self) struct Tuple<T, U>(
// AstId: 9
pub(self) 0: T,
// AstId: 10
pub(self) 1: U,
)
where
@ -393,9 +371,8 @@ trait Tr<'a, T: 'a>: Super where Self: for<'a> Tr<'a, T> {}
T: 'a,
T: 'b
{
// AstId: 12
// AstId: 9
pub(self) fn f<G>(
// AstId: 13
impl Copy,
) -> impl Copy
where

View file

@ -23,7 +23,7 @@ use itertools::{izip, Itertools};
use la_arena::Idx;
use limit::Limit;
use rustc_hash::{FxHashMap, FxHashSet};
use span::{Edition, EditionedFileId, ErasedFileAstId, FileAstId, SyntaxContextId};
use span::{Edition, EditionedFileId, FileAstId, SyntaxContextId};
use syntax::ast;
use triomphe::Arc;
@ -32,8 +32,8 @@ use crate::{
db::DefDatabase,
item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
item_tree::{
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
self, AttrOwner, ExternCrate, FieldsShape, FileItemTreeId, ImportKind, ItemTree,
ItemTreeId, ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
},
macro_call_as_call_id, macro_call_as_call_id_with_eager,
nameres::{
@ -1580,10 +1580,7 @@ impl ModCollector<'_, '_> {
let attrs = self.item_tree.attrs(db, krate, item.into());
if let Some(cfg) = attrs.cfg() {
if !self.is_cfg_enabled(&cfg) {
self.emit_unconfigured_diagnostic(
InFile::new(self.file_id(), item.ast_id(self.item_tree).erase()),
&cfg,
);
self.emit_unconfigured_diagnostic(self.tree_id, item.into(), &cfg);
return;
}
}
@ -1699,7 +1696,7 @@ impl ModCollector<'_, '_> {
.into(),
&it.name,
vis,
!matches!(it.fields, Fields::Record(_)),
!matches!(it.shape, FieldsShape::Record),
);
}
ModItem::Union(id) => {
@ -1737,10 +1734,8 @@ impl ModCollector<'_, '_> {
match is_enabled {
Err(cfg) => {
self.emit_unconfigured_diagnostic(
InFile::new(
self.file_id(),
self.item_tree[variant.index()].ast_id.erase(),
),
self.tree_id,
variant.into(),
&cfg,
);
None
@ -1956,7 +1951,8 @@ impl ModCollector<'_, '_> {
match is_enabled {
Err(cfg) => {
self.emit_unconfigured_diagnostic(
ast_id.map(|it| it.erase()),
self.tree_id,
AttrOwner::TopLevel,
&cfg,
);
}
@ -2402,10 +2398,11 @@ impl ModCollector<'_, '_> {
self.def_collector.cfg_options.check(cfg) != Some(false)
}
fn emit_unconfigured_diagnostic(&mut self, ast_id: InFile<ErasedFileAstId>, cfg: &CfgExpr) {
fn emit_unconfigured_diagnostic(&mut self, tree_id: TreeId, item: AttrOwner, cfg: &CfgExpr) {
self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
self.module_id,
ast_id,
tree_id,
item,
cfg.clone(),
self.def_collector.cfg_options.clone(),
));

View file

@ -4,12 +4,12 @@ use std::ops::Not;
use base_db::CrateId;
use cfg::{CfgExpr, CfgOptions};
use hir_expand::{attrs::AttrId, ErasedAstId, MacroCallKind};
use hir_expand::{attrs::AttrId, MacroCallKind};
use la_arena::Idx;
use syntax::ast;
use crate::{
item_tree::{self, ItemTreeId},
item_tree::{self, AttrOwner, ItemTreeId, TreeId},
nameres::LocalModuleId,
path::ModPath,
AstId,
@ -29,7 +29,8 @@ pub enum DefDiagnosticKind {
index: Idx<ast::UseTree>,
},
UnconfiguredCode {
ast: ErasedAstId,
tree: TreeId,
item: AttrOwner,
cfg: CfgExpr,
opts: CfgOptions,
},
@ -116,11 +117,15 @@ impl DefDiagnostic {
pub fn unconfigured_code(
container: LocalModuleId,
ast: ErasedAstId,
tree: TreeId,
item: AttrOwner,
cfg: CfgExpr,
opts: CfgOptions,
) -> Self {
Self { in_module: container, kind: DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } }
Self {
in_module: container,
kind: DefDiagnosticKind::UnconfiguredCode { tree, item, cfg, opts },
}
}
pub fn unresolved_proc_macro(

View file

@ -17,7 +17,7 @@ use triomphe::Arc;
use crate::{
db::DefDatabase,
item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
item_tree::Fields,
item_tree::FieldsShape,
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
path::{ModPath, PathKind},
per_ns::PerNs,
@ -381,11 +381,11 @@ impl DefMap {
.iter()
.find_map(|&variant| {
let variant_data = &tree[variant.lookup(db).id.value];
(variant_data.name == *segment).then(|| match variant_data.fields {
Fields::Record(_) => {
(variant_data.name == *segment).then(|| match variant_data.shape {
FieldsShape::Record => {
PerNs::types(variant.into(), Visibility::Public, None)
}
Fields::Tuple(_) | Fields::Unit => PerNs::both(
FieldsShape::Tuple | FieldsShape::Unit => PerNs::both(
variant.into(),
variant.into(),
Visibility::Public,

View file

@ -6,9 +6,12 @@ use la_arena::ArenaMap;
use syntax::{ast, AstNode, AstPtr};
use crate::{
data::adt::lower_struct, db::DefDatabase, item_tree::ItemTreeNode, trace::Trace, GenericDefId,
ItemTreeLoc, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, UseId,
VariantId,
data::adt::lower_struct,
db::DefDatabase,
item_tree::{FieldParent, ItemTreeNode},
trace::Trace,
GenericDefId, ItemTreeLoc, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup,
UseId, VariantId,
};
pub trait HasSource {
@ -124,13 +127,13 @@ impl HasChildSource<LocalFieldId> for VariantId {
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
let item_tree;
let (src, fields, container) = match *self {
let (src, parent, container) = match *self {
VariantId::EnumVariantId(it) => {
let lookup = it.lookup(db);
item_tree = lookup.id.item_tree(db);
(
lookup.source(db).map(|it| it.kind()),
&item_tree[lookup.id.value].fields,
FieldParent::Variant(lookup.id.value),
lookup.parent.lookup(db).container,
)
}
@ -139,7 +142,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
item_tree = lookup.id.item_tree(db);
(
lookup.source(db).map(|it| it.kind()),
&item_tree[lookup.id.value].fields,
FieldParent::Struct(lookup.id.value),
lookup.container,
)
}
@ -148,13 +151,13 @@ impl HasChildSource<LocalFieldId> for VariantId {
item_tree = lookup.id.item_tree(db);
(
lookup.source(db).map(|it| it.kind()),
&item_tree[lookup.id.value].fields,
FieldParent::Union(lookup.id.value),
lookup.container,
)
}
};
let mut trace = Trace::new_for_map();
lower_struct(db, &mut trace, &src, container.krate, &item_tree, fields);
lower_struct(db, &mut trace, &src, container.krate, &item_tree, parent);
src.with_value(trace.into_map())
}
}

View file

@ -812,7 +812,7 @@ impl<'a> InferenceContext<'a> {
None => self.err_ty(),
};
param_tys.push(va_list_ty)
param_tys.push(va_list_ty);
}
let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
if let Some(self_param) = self.body.self_param {

View file

@ -1126,6 +1126,23 @@ fn var_args() {
pub struct VaListImpl<'f>;
fn my_fn(foo: ...) {}
//^^^ VaListImpl<'?>
fn my_fn2(bar: u32, foo: ...) {}
//^^^ VaListImpl<'?>
"#,
);
}
#[test]
fn var_args_cond() {
check_types(
r#"
#[lang = "va_list"]
pub struct VaListImpl<'f>;
fn my_fn(bar: u32, #[cfg(FALSE)] foo: ..., #[cfg(not(FALSE))] foo: u32) {
foo;
//^^^ u32
}
"#,
);
}

View file

@ -114,7 +114,10 @@ impl HirDisplay for Function {
}
if data.is_varargs() {
f.write_str(", ...")?;
if !first {
f.write_str(", ")?;
}
f.write_str("...")?;
}
f.write_char(')')?;

View file

@ -44,7 +44,7 @@ use hir_def::{
data::adt::VariantData,
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat},
item_tree::ItemTreeNode,
item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
lang_item::LangItemTarget,
layout::{self, ReprOptions, TargetDataLayout},
nameres::{self, diagnostics::DefDiagnostic},
@ -81,7 +81,7 @@ use rustc_hash::FxHashSet;
use span::{Edition, EditionedFileId, FileId, MacroCallId};
use stdx::{impl_from, never};
use syntax::{
ast::{self, HasAttrs as _, HasName},
ast::{self, HasAttrs as _, HasGenericParams, HasName},
format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, T,
};
use triomphe::Arc;
@ -906,12 +906,90 @@ fn emit_def_diagnostic_(
);
}
DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
let item = ast.to_ptr(db.upcast());
acc.push(
InactiveCode { node: ast.with_value(item), cfg: cfg.clone(), opts: opts.clone() }
DefDiagnosticKind::UnconfiguredCode { tree, item, cfg, opts } => {
let item_tree = tree.item_tree(db.upcast());
let ast_id_map = db.ast_id_map(tree.file_id());
// FIXME: This parses... We could probably store relative ranges for the children things
// here in the item tree?
(|| {
let process_field_list =
|field_list: Option<_>, idx: ItemTreeFieldId| match field_list? {
ast::FieldList::RecordFieldList(it) => Some(SyntaxNodePtr::new(
it.fields().nth(idx.into_raw().into_u32() as usize)?.syntax(),
)),
ast::FieldList::TupleFieldList(it) => Some(SyntaxNodePtr::new(
it.fields().nth(idx.into_raw().into_u32() as usize)?.syntax(),
)),
};
let ptr = match *item {
AttrOwner::ModItem(it) => {
ast_id_map.get(it.ast_id(&item_tree)).syntax_node_ptr()
}
AttrOwner::TopLevel => ast_id_map.root(),
AttrOwner::Variant(it) => {
ast_id_map.get(item_tree[it].ast_id).syntax_node_ptr()
}
AttrOwner::Field(FieldParent::Variant(parent), idx) => process_field_list(
ast_id_map
.get(item_tree[parent].ast_id)
.to_node(&db.parse_or_expand(tree.file_id()))
.field_list(),
idx,
)?,
AttrOwner::Field(FieldParent::Struct(parent), idx) => process_field_list(
ast_id_map
.get(item_tree[parent.index()].ast_id)
.to_node(&db.parse_or_expand(tree.file_id()))
.field_list(),
idx,
)?,
AttrOwner::Field(FieldParent::Union(parent), idx) => SyntaxNodePtr::new(
ast_id_map
.get(item_tree[parent.index()].ast_id)
.to_node(&db.parse_or_expand(tree.file_id()))
.record_field_list()?
.fields()
.nth(idx.into_raw().into_u32() as usize)?
.syntax(),
),
AttrOwner::Param(parent, idx) => SyntaxNodePtr::new(
ast_id_map
.get(item_tree[parent.index()].ast_id)
.to_node(&db.parse_or_expand(tree.file_id()))
.param_list()?
.params()
.nth(idx.into_raw().into_u32() as usize)?
.syntax(),
),
AttrOwner::TypeOrConstParamData(parent, idx) => SyntaxNodePtr::new(
ast_id_map
.get(parent.ast_id(&item_tree))
.to_node(&db.parse_or_expand(tree.file_id()))
.generic_param_list()?
.type_or_const_params()
.nth(idx.into_raw().into_u32() as usize)?
.syntax(),
),
AttrOwner::LifetimeParamData(parent, idx) => SyntaxNodePtr::new(
ast_id_map
.get(parent.ast_id(&item_tree))
.to_node(&db.parse_or_expand(tree.file_id()))
.generic_param_list()?
.lifetime_params()
.nth(idx.into_raw().into_u32() as usize)?
.syntax(),
),
};
acc.push(
InactiveCode {
node: InFile::new(tree.file_id(), ptr),
cfg: cfg.clone(),
opts: opts.clone(),
}
.into(),
);
);
Some(())
})();
}
DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
let (node, precise_location, macro_name, kind) = precise_macro_call_location(ast, db);

View file

@ -56,6 +56,7 @@ macro_rules! define_symbols {
define_symbols! {
@WITH_NAME:
dotdotdot = "...",
INTEGER_0 = "0",
INTEGER_1 = "1",
INTEGER_2 = "2",

View file

@ -80,13 +80,11 @@ macro_rules! register_ast_id_node {
}
register_ast_id_node! {
impl AstIdNode for
Item,
Item, AnyHasGenericParams,
Adt,
Enum,
Variant,
Struct,
RecordField,
TupleField,
Union,
AssocItem,
Const,
@ -104,7 +102,7 @@ register_ast_id_node! {
Trait,
TraitAlias,
Use,
BlockExpr, ConstArg, Param, SelfParam
BlockExpr, ConstArg
}
/// Maps items' `SyntaxNode`s to `ErasedFileAstId`s and back.

View file

@ -5106,6 +5106,14 @@ impl AstNode for AnyHasArgList {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<CallExpr> for AnyHasArgList {
#[inline]
fn from(node: CallExpr) -> AnyHasArgList { AnyHasArgList { syntax: node.syntax } }
}
impl From<MethodCallExpr> for AnyHasArgList {
#[inline]
fn from(node: MethodCallExpr) -> AnyHasArgList { AnyHasArgList { syntax: node.syntax } }
}
impl AnyHasAttrs {
#[inline]
pub fn new<T: ast::HasAttrs>(node: T) -> AnyHasAttrs {
@ -5198,6 +5206,294 @@ impl AstNode for AnyHasAttrs {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<ArrayExpr> for AnyHasAttrs {
#[inline]
fn from(node: ArrayExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<AsmExpr> for AnyHasAttrs {
#[inline]
fn from(node: AsmExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<AssocItemList> for AnyHasAttrs {
#[inline]
fn from(node: AssocItemList) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<AwaitExpr> for AnyHasAttrs {
#[inline]
fn from(node: AwaitExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<BecomeExpr> for AnyHasAttrs {
#[inline]
fn from(node: BecomeExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<BinExpr> for AnyHasAttrs {
#[inline]
fn from(node: BinExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<BlockExpr> for AnyHasAttrs {
#[inline]
fn from(node: BlockExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<BreakExpr> for AnyHasAttrs {
#[inline]
fn from(node: BreakExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<CallExpr> for AnyHasAttrs {
#[inline]
fn from(node: CallExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<CastExpr> for AnyHasAttrs {
#[inline]
fn from(node: CastExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ClosureExpr> for AnyHasAttrs {
#[inline]
fn from(node: ClosureExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Const> for AnyHasAttrs {
#[inline]
fn from(node: Const) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ConstParam> for AnyHasAttrs {
#[inline]
fn from(node: ConstParam) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ContinueExpr> for AnyHasAttrs {
#[inline]
fn from(node: ContinueExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Enum> for AnyHasAttrs {
#[inline]
fn from(node: Enum) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ExternBlock> for AnyHasAttrs {
#[inline]
fn from(node: ExternBlock) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ExternCrate> for AnyHasAttrs {
#[inline]
fn from(node: ExternCrate) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ExternItemList> for AnyHasAttrs {
#[inline]
fn from(node: ExternItemList) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<FieldExpr> for AnyHasAttrs {
#[inline]
fn from(node: FieldExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Fn> for AnyHasAttrs {
#[inline]
fn from(node: Fn) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ForExpr> for AnyHasAttrs {
#[inline]
fn from(node: ForExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<FormatArgsExpr> for AnyHasAttrs {
#[inline]
fn from(node: FormatArgsExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<IdentPat> for AnyHasAttrs {
#[inline]
fn from(node: IdentPat) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<IfExpr> for AnyHasAttrs {
#[inline]
fn from(node: IfExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Impl> for AnyHasAttrs {
#[inline]
fn from(node: Impl) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<IndexExpr> for AnyHasAttrs {
#[inline]
fn from(node: IndexExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ItemList> for AnyHasAttrs {
#[inline]
fn from(node: ItemList) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<LetExpr> for AnyHasAttrs {
#[inline]
fn from(node: LetExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<LetStmt> for AnyHasAttrs {
#[inline]
fn from(node: LetStmt) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<LifetimeParam> for AnyHasAttrs {
#[inline]
fn from(node: LifetimeParam) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Literal> for AnyHasAttrs {
#[inline]
fn from(node: Literal) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<LoopExpr> for AnyHasAttrs {
#[inline]
fn from(node: LoopExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<MacroCall> for AnyHasAttrs {
#[inline]
fn from(node: MacroCall) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<MacroDef> for AnyHasAttrs {
#[inline]
fn from(node: MacroDef) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<MacroRules> for AnyHasAttrs {
#[inline]
fn from(node: MacroRules) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<MatchArm> for AnyHasAttrs {
#[inline]
fn from(node: MatchArm) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<MatchArmList> for AnyHasAttrs {
#[inline]
fn from(node: MatchArmList) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<MatchExpr> for AnyHasAttrs {
#[inline]
fn from(node: MatchExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<MethodCallExpr> for AnyHasAttrs {
#[inline]
fn from(node: MethodCallExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Module> for AnyHasAttrs {
#[inline]
fn from(node: Module) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<OffsetOfExpr> for AnyHasAttrs {
#[inline]
fn from(node: OffsetOfExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Param> for AnyHasAttrs {
#[inline]
fn from(node: Param) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ParenExpr> for AnyHasAttrs {
#[inline]
fn from(node: ParenExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<PathExpr> for AnyHasAttrs {
#[inline]
fn from(node: PathExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<PrefixExpr> for AnyHasAttrs {
#[inline]
fn from(node: PrefixExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<RangeExpr> for AnyHasAttrs {
#[inline]
fn from(node: RangeExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<RecordExprField> for AnyHasAttrs {
#[inline]
fn from(node: RecordExprField) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<RecordExprFieldList> for AnyHasAttrs {
#[inline]
fn from(node: RecordExprFieldList) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<RecordField> for AnyHasAttrs {
#[inline]
fn from(node: RecordField) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<RecordPatField> for AnyHasAttrs {
#[inline]
fn from(node: RecordPatField) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<RefExpr> for AnyHasAttrs {
#[inline]
fn from(node: RefExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<RestPat> for AnyHasAttrs {
#[inline]
fn from(node: RestPat) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<ReturnExpr> for AnyHasAttrs {
#[inline]
fn from(node: ReturnExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<SelfParam> for AnyHasAttrs {
#[inline]
fn from(node: SelfParam) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<SourceFile> for AnyHasAttrs {
#[inline]
fn from(node: SourceFile) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Static> for AnyHasAttrs {
#[inline]
fn from(node: Static) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<StmtList> for AnyHasAttrs {
#[inline]
fn from(node: StmtList) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Struct> for AnyHasAttrs {
#[inline]
fn from(node: Struct) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Trait> for AnyHasAttrs {
#[inline]
fn from(node: Trait) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<TraitAlias> for AnyHasAttrs {
#[inline]
fn from(node: TraitAlias) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<TryExpr> for AnyHasAttrs {
#[inline]
fn from(node: TryExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<TupleExpr> for AnyHasAttrs {
#[inline]
fn from(node: TupleExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<TupleField> for AnyHasAttrs {
#[inline]
fn from(node: TupleField) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<TypeAlias> for AnyHasAttrs {
#[inline]
fn from(node: TypeAlias) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<TypeParam> for AnyHasAttrs {
#[inline]
fn from(node: TypeParam) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<UnderscoreExpr> for AnyHasAttrs {
#[inline]
fn from(node: UnderscoreExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Union> for AnyHasAttrs {
#[inline]
fn from(node: Union) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Use> for AnyHasAttrs {
#[inline]
fn from(node: Use) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<Variant> for AnyHasAttrs {
#[inline]
fn from(node: Variant) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<WhileExpr> for AnyHasAttrs {
#[inline]
fn from(node: WhileExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<YeetExpr> for AnyHasAttrs {
#[inline]
fn from(node: YeetExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl From<YieldExpr> for AnyHasAttrs {
#[inline]
fn from(node: YieldExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } }
}
impl AnyHasDocComments {
#[inline]
pub fn new<T: ast::HasDocComments>(node: T) -> AnyHasDocComments {
@ -5239,6 +5535,90 @@ impl AstNode for AnyHasDocComments {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<Const> for AnyHasDocComments {
#[inline]
fn from(node: Const) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Enum> for AnyHasDocComments {
#[inline]
fn from(node: Enum) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<ExternBlock> for AnyHasDocComments {
#[inline]
fn from(node: ExternBlock) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<ExternCrate> for AnyHasDocComments {
#[inline]
fn from(node: ExternCrate) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Fn> for AnyHasDocComments {
#[inline]
fn from(node: Fn) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Impl> for AnyHasDocComments {
#[inline]
fn from(node: Impl) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<MacroCall> for AnyHasDocComments {
#[inline]
fn from(node: MacroCall) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<MacroDef> for AnyHasDocComments {
#[inline]
fn from(node: MacroDef) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<MacroRules> for AnyHasDocComments {
#[inline]
fn from(node: MacroRules) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Module> for AnyHasDocComments {
#[inline]
fn from(node: Module) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<RecordField> for AnyHasDocComments {
#[inline]
fn from(node: RecordField) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<SourceFile> for AnyHasDocComments {
#[inline]
fn from(node: SourceFile) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Static> for AnyHasDocComments {
#[inline]
fn from(node: Static) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Struct> for AnyHasDocComments {
#[inline]
fn from(node: Struct) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Trait> for AnyHasDocComments {
#[inline]
fn from(node: Trait) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<TraitAlias> for AnyHasDocComments {
#[inline]
fn from(node: TraitAlias) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<TupleField> for AnyHasDocComments {
#[inline]
fn from(node: TupleField) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<TypeAlias> for AnyHasDocComments {
#[inline]
fn from(node: TypeAlias) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Union> for AnyHasDocComments {
#[inline]
fn from(node: Union) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Use> for AnyHasDocComments {
#[inline]
fn from(node: Use) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl From<Variant> for AnyHasDocComments {
#[inline]
fn from(node: Variant) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } }
}
impl AnyHasGenericArgs {
#[inline]
pub fn new<T: ast::HasGenericArgs>(node: T) -> AnyHasGenericArgs {
@ -5257,6 +5637,18 @@ impl AstNode for AnyHasGenericArgs {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<AssocTypeArg> for AnyHasGenericArgs {
#[inline]
fn from(node: AssocTypeArg) -> AnyHasGenericArgs { AnyHasGenericArgs { syntax: node.syntax } }
}
impl From<MethodCallExpr> for AnyHasGenericArgs {
#[inline]
fn from(node: MethodCallExpr) -> AnyHasGenericArgs { AnyHasGenericArgs { syntax: node.syntax } }
}
impl From<PathSegment> for AnyHasGenericArgs {
#[inline]
fn from(node: PathSegment) -> AnyHasGenericArgs { AnyHasGenericArgs { syntax: node.syntax } }
}
impl AnyHasGenericParams {
#[inline]
pub fn new<T: ast::HasGenericParams>(node: T) -> AnyHasGenericParams {
@ -5275,6 +5667,38 @@ impl AstNode for AnyHasGenericParams {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<Enum> for AnyHasGenericParams {
#[inline]
fn from(node: Enum) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
}
impl From<Fn> for AnyHasGenericParams {
#[inline]
fn from(node: Fn) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
}
impl From<Impl> for AnyHasGenericParams {
#[inline]
fn from(node: Impl) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
}
impl From<Struct> for AnyHasGenericParams {
#[inline]
fn from(node: Struct) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
}
impl From<Trait> for AnyHasGenericParams {
#[inline]
fn from(node: Trait) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
}
impl From<TraitAlias> for AnyHasGenericParams {
#[inline]
fn from(node: TraitAlias) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
}
impl From<TypeAlias> for AnyHasGenericParams {
#[inline]
fn from(node: TypeAlias) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
}
impl From<Union> for AnyHasGenericParams {
#[inline]
fn from(node: Union) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
}
impl AnyHasLoopBody {
#[inline]
pub fn new<T: ast::HasLoopBody>(node: T) -> AnyHasLoopBody {
@ -5291,6 +5715,18 @@ impl AstNode for AnyHasLoopBody {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<ForExpr> for AnyHasLoopBody {
#[inline]
fn from(node: ForExpr) -> AnyHasLoopBody { AnyHasLoopBody { syntax: node.syntax } }
}
impl From<LoopExpr> for AnyHasLoopBody {
#[inline]
fn from(node: LoopExpr) -> AnyHasLoopBody { AnyHasLoopBody { syntax: node.syntax } }
}
impl From<WhileExpr> for AnyHasLoopBody {
#[inline]
fn from(node: WhileExpr) -> AnyHasLoopBody { AnyHasLoopBody { syntax: node.syntax } }
}
impl AnyHasModuleItem {
#[inline]
pub fn new<T: ast::HasModuleItem>(node: T) -> AnyHasModuleItem {
@ -5307,6 +5743,18 @@ impl AstNode for AnyHasModuleItem {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<ItemList> for AnyHasModuleItem {
#[inline]
fn from(node: ItemList) -> AnyHasModuleItem { AnyHasModuleItem { syntax: node.syntax } }
}
impl From<MacroItems> for AnyHasModuleItem {
#[inline]
fn from(node: MacroItems) -> AnyHasModuleItem { AnyHasModuleItem { syntax: node.syntax } }
}
impl From<SourceFile> for AnyHasModuleItem {
#[inline]
fn from(node: SourceFile) -> AnyHasModuleItem { AnyHasModuleItem { syntax: node.syntax } }
}
impl AnyHasName {
#[inline]
pub fn new<T: ast::HasName>(node: T) -> AnyHasName {
@ -5347,6 +5795,86 @@ impl AstNode for AnyHasName {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<Const> for AnyHasName {
#[inline]
fn from(node: Const) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<ConstParam> for AnyHasName {
#[inline]
fn from(node: ConstParam) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Enum> for AnyHasName {
#[inline]
fn from(node: Enum) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Fn> for AnyHasName {
#[inline]
fn from(node: Fn) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<FormatArgsArg> for AnyHasName {
#[inline]
fn from(node: FormatArgsArg) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<IdentPat> for AnyHasName {
#[inline]
fn from(node: IdentPat) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<MacroDef> for AnyHasName {
#[inline]
fn from(node: MacroDef) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<MacroRules> for AnyHasName {
#[inline]
fn from(node: MacroRules) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Module> for AnyHasName {
#[inline]
fn from(node: Module) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<RecordField> for AnyHasName {
#[inline]
fn from(node: RecordField) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Rename> for AnyHasName {
#[inline]
fn from(node: Rename) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<SelfParam> for AnyHasName {
#[inline]
fn from(node: SelfParam) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Static> for AnyHasName {
#[inline]
fn from(node: Static) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Struct> for AnyHasName {
#[inline]
fn from(node: Struct) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Trait> for AnyHasName {
#[inline]
fn from(node: Trait) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<TraitAlias> for AnyHasName {
#[inline]
fn from(node: TraitAlias) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<TypeAlias> for AnyHasName {
#[inline]
fn from(node: TypeAlias) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<TypeParam> for AnyHasName {
#[inline]
fn from(node: TypeParam) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Union> for AnyHasName {
#[inline]
fn from(node: Union) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<Variant> for AnyHasName {
#[inline]
fn from(node: Variant) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl AnyHasTypeBounds {
#[inline]
pub fn new<T: ast::HasTypeBounds>(node: T) -> AnyHasTypeBounds {
@ -5368,6 +5896,30 @@ impl AstNode for AnyHasTypeBounds {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<AssocTypeArg> for AnyHasTypeBounds {
#[inline]
fn from(node: AssocTypeArg) -> AnyHasTypeBounds { AnyHasTypeBounds { syntax: node.syntax } }
}
impl From<LifetimeParam> for AnyHasTypeBounds {
#[inline]
fn from(node: LifetimeParam) -> AnyHasTypeBounds { AnyHasTypeBounds { syntax: node.syntax } }
}
impl From<Trait> for AnyHasTypeBounds {
#[inline]
fn from(node: Trait) -> AnyHasTypeBounds { AnyHasTypeBounds { syntax: node.syntax } }
}
impl From<TypeAlias> for AnyHasTypeBounds {
#[inline]
fn from(node: TypeAlias) -> AnyHasTypeBounds { AnyHasTypeBounds { syntax: node.syntax } }
}
impl From<TypeParam> for AnyHasTypeBounds {
#[inline]
fn from(node: TypeParam) -> AnyHasTypeBounds { AnyHasTypeBounds { syntax: node.syntax } }
}
impl From<WherePred> for AnyHasTypeBounds {
#[inline]
fn from(node: WherePred) -> AnyHasTypeBounds { AnyHasTypeBounds { syntax: node.syntax } }
}
impl AnyHasVisibility {
#[inline]
pub fn new<T: ast::HasVisibility>(node: T) -> AnyHasVisibility {
@ -5406,6 +5958,78 @@ impl AstNode for AnyHasVisibility {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl From<Const> for AnyHasVisibility {
#[inline]
fn from(node: Const) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Enum> for AnyHasVisibility {
#[inline]
fn from(node: Enum) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<ExternCrate> for AnyHasVisibility {
#[inline]
fn from(node: ExternCrate) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Fn> for AnyHasVisibility {
#[inline]
fn from(node: Fn) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Impl> for AnyHasVisibility {
#[inline]
fn from(node: Impl) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<MacroDef> for AnyHasVisibility {
#[inline]
fn from(node: MacroDef) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<MacroRules> for AnyHasVisibility {
#[inline]
fn from(node: MacroRules) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Module> for AnyHasVisibility {
#[inline]
fn from(node: Module) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<RecordField> for AnyHasVisibility {
#[inline]
fn from(node: RecordField) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Static> for AnyHasVisibility {
#[inline]
fn from(node: Static) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Struct> for AnyHasVisibility {
#[inline]
fn from(node: Struct) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Trait> for AnyHasVisibility {
#[inline]
fn from(node: Trait) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<TraitAlias> for AnyHasVisibility {
#[inline]
fn from(node: TraitAlias) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<TupleField> for AnyHasVisibility {
#[inline]
fn from(node: TupleField) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<TypeAlias> for AnyHasVisibility {
#[inline]
fn from(node: TypeAlias) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Union> for AnyHasVisibility {
#[inline]
fn from(node: Union) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Use> for AnyHasVisibility {
#[inline]
fn from(node: Use) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl From<Variant> for AnyHasVisibility {
#[inline]
fn from(node: Variant) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } }
}
impl std::fmt::Display for Adt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)

View file

@ -1127,21 +1127,3 @@ impl From<ast::AssocItem> for ast::AnyHasAttrs {
Self::new(node)
}
}
impl From<ast::Variant> for ast::AnyHasAttrs {
fn from(node: ast::Variant) -> Self {
Self::new(node)
}
}
impl From<ast::RecordField> for ast::AnyHasAttrs {
fn from(node: ast::RecordField) -> Self {
Self::new(node)
}
}
impl From<ast::TupleField> for ast::AnyHasAttrs {
fn from(node: ast::TupleField) -> Self {
Self::new(node)
}
}

View file

@ -261,7 +261,7 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
.iter()
.map(|name| format_ident!("{}", to_upper_snake_case(&name.name.to_string())))
.collect();
let nodes = nodes.iter().map(|node| format_ident!("{}", node.name));
(
quote! {
#[pretty_doc_comment_placeholder_workaround]
@ -294,6 +294,15 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
&self.syntax
}
}
#(
impl From<#nodes> for #name {
#[inline]
fn from(node: #nodes) -> #name {
#name { syntax: node.syntax }
}
}
)*
},
)
})