mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 21:54:42 +00:00
Remove Params and Fields from AstIdMap
This commit is contained in:
parent
200a01adc4
commit
9cbafa2d49
16 changed files with 494 additions and 449 deletions
|
@ -20,7 +20,7 @@ use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
item_tree::{AttrOwner, Fields, ItemTreeNode},
|
item_tree::{AttrOwner, FieldParent, ItemTreeNode},
|
||||||
lang_item::LangItem,
|
lang_item::LangItem,
|
||||||
nameres::{ModuleOrigin, ModuleSource},
|
nameres::{ModuleOrigin, ModuleSource},
|
||||||
src::{HasChildSource, HasSource},
|
src::{HasChildSource, HasSource},
|
||||||
|
@ -76,40 +76,36 @@ impl Attrs {
|
||||||
let mut res = ArenaMap::default();
|
let mut res = ArenaMap::default();
|
||||||
|
|
||||||
let crate_graph = db.crate_graph();
|
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) => {
|
VariantId::EnumVariantId(it) => {
|
||||||
let loc = it.lookup(db);
|
let loc = it.lookup(db);
|
||||||
let krate = loc.parent.lookup(db).container.krate;
|
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];
|
let variant = &item_tree[loc.id.value];
|
||||||
(variant.fields.clone(), item_tree, krate)
|
(FieldParent::Variant(loc.id.value), &variant.fields, krate)
|
||||||
}
|
}
|
||||||
VariantId::StructId(it) => {
|
VariantId::StructId(it) => {
|
||||||
let loc = it.lookup(db);
|
let loc = it.lookup(db);
|
||||||
let krate = loc.container.krate;
|
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];
|
let struct_ = &item_tree[loc.id.value];
|
||||||
(struct_.fields.clone(), item_tree, krate)
|
(FieldParent::Struct(loc.id.value), &struct_.fields, krate)
|
||||||
}
|
}
|
||||||
VariantId::UnionId(it) => {
|
VariantId::UnionId(it) => {
|
||||||
let loc = it.lookup(db);
|
let loc = it.lookup(db);
|
||||||
let krate = loc.container.krate;
|
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];
|
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 cfg_options = &crate_graph[krate].cfg_options;
|
||||||
|
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
for field in fields {
|
for (id, _field) in fields.iter().enumerate() {
|
||||||
let attrs = item_tree.attrs(db, krate, field.into());
|
let attrs = item_tree.attrs(db, krate, AttrOwner::make_field_indexed(parent, id));
|
||||||
if attrs.is_cfg_enabled(cfg_options) {
|
if attrs.is_cfg_enabled(cfg_options) {
|
||||||
res.insert(Idx::from_raw(RawIdx::from(idx)), attrs);
|
res.insert(Idx::from_raw(RawIdx::from(idx)), attrs);
|
||||||
idx += 1;
|
idx += 1;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use std::ops::{Deref, Index};
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use hir_expand::{name::Name, InFile};
|
use hir_expand::{name::Name, InFile};
|
||||||
use la_arena::{Arena, ArenaMap};
|
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use span::MacroFileId;
|
use span::MacroFileId;
|
||||||
|
@ -24,6 +24,7 @@ use crate::{
|
||||||
hir::{
|
hir::{
|
||||||
dummy_expr_id, Binding, BindingId, Expr, ExprId, Label, LabelId, Pat, PatId, RecordFieldPat,
|
dummy_expr_id, Binding, BindingId, Expr, ExprId, Label, LabelId, Pat, PatId, RecordFieldPat,
|
||||||
},
|
},
|
||||||
|
item_tree::AttrOwner,
|
||||||
nameres::DefMap,
|
nameres::DefMap,
|
||||||
path::{ModPath, Path},
|
path::{ModPath, Path},
|
||||||
src::HasSource,
|
src::HasSource,
|
||||||
|
@ -136,16 +137,23 @@ impl Body {
|
||||||
let data = db.function_data(f);
|
let data = db.function_data(f);
|
||||||
let f = f.lookup(db);
|
let f = f.lookup(db);
|
||||||
let src = f.source(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 item_tree = f.id.item_tree(db);
|
||||||
let func = &item_tree[f.id.value];
|
let func = &item_tree[f.id.value];
|
||||||
let krate = f.container.module(db).krate;
|
let krate = f.container.module(db).krate;
|
||||||
let crate_graph = db.crate_graph();
|
let crate_graph = db.crate_graph();
|
||||||
(
|
(
|
||||||
param_list,
|
param_list,
|
||||||
func.params.clone().map(move |param| {
|
(0..func.params.len()).map(move |idx| {
|
||||||
item_tree
|
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)
|
.is_cfg_enabled(&crate_graph[krate].cfg_options)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,6 +7,7 @@ use hir_expand::{
|
||||||
name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind,
|
name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind,
|
||||||
};
|
};
|
||||||
use intern::{sym, Interned, Symbol};
|
use intern::{sym, Interned, Symbol};
|
||||||
|
use la_arena::{Idx, RawIdx};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use syntax::{ast, Parse};
|
use syntax::{ast, Parse};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
@ -58,32 +59,15 @@ impl FunctionData {
|
||||||
|
|
||||||
let crate_graph = db.crate_graph();
|
let crate_graph = db.crate_graph();
|
||||||
let cfg_options = &crate_graph[krate].cfg_options;
|
let cfg_options = &crate_graph[krate].cfg_options;
|
||||||
let enabled_params = func
|
let attr_owner = |idx| {
|
||||||
.params
|
item_tree::AttrOwner::Param(loc.id.value, Idx::from_raw(RawIdx::from(idx as u32)))
|
||||||
.clone()
|
};
|
||||||
.filter(|¶m| 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 mut flags = func.flags;
|
let mut flags = func.flags;
|
||||||
if is_varargs {
|
|
||||||
flags |= FnFlags::IS_VARARGS;
|
|
||||||
}
|
|
||||||
if flags.contains(FnFlags::HAS_SELF_PARAM) {
|
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.
|
// 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() {
|
let is_cfgd_out =
|
||||||
Some(param) => {
|
!item_tree.attrs(db, krate, attr_owner(0usize)).is_cfg_enabled(cfg_options);
|
||||||
!item_tree.attrs(db, krate, param.into()).is_cfg_enabled(cfg_options)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
stdx::never!("fn HAS_SELF_PARAM but no parameters allocated");
|
|
||||||
true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if is_cfgd_out {
|
if is_cfgd_out {
|
||||||
cov_mark::hit!(cfgd_out_self_param);
|
cov_mark::hit!(cfgd_out_self_param);
|
||||||
flags.remove(FnFlags::HAS_SELF_PARAM);
|
flags.remove(FnFlags::HAS_SELF_PARAM);
|
||||||
|
@ -101,9 +85,14 @@ impl FunctionData {
|
||||||
|
|
||||||
Arc::new(FunctionData {
|
Arc::new(FunctionData {
|
||||||
name: func.name.clone(),
|
name: func.name.clone(),
|
||||||
params: enabled_params
|
params: func
|
||||||
.clone()
|
.params
|
||||||
.filter_map(|id| item_tree[id].type_ref.clone())
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|&(idx, _)| {
|
||||||
|
item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options)
|
||||||
|
})
|
||||||
|
.map(|(_, param)| param.type_ref.clone())
|
||||||
.collect(),
|
.collect(),
|
||||||
ret_type: func.ret_type.clone(),
|
ret_type: func.ret_type.clone(),
|
||||||
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
|
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
|
||||||
|
@ -629,7 +618,8 @@ impl<'a> AssocItemCollector<'a> {
|
||||||
if !attrs.is_cfg_enabled(self.expander.cfg_options()) {
|
if !attrs.is_cfg_enabled(self.expander.cfg_options()) {
|
||||||
self.diagnostics.push(DefDiagnostic::unconfigured_code(
|
self.diagnostics.push(DefDiagnostic::unconfigured_code(
|
||||||
self.module_id.local_id,
|
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(),
|
attrs.cfg().unwrap(),
|
||||||
self.expander.cfg_options().clone(),
|
self.expander.cfg_options().clone(),
|
||||||
));
|
));
|
||||||
|
|
|
@ -7,7 +7,7 @@ use either::Either;
|
||||||
|
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
name::{AsName, Name},
|
name::{AsName, Name},
|
||||||
HirFileId, InFile,
|
InFile,
|
||||||
};
|
};
|
||||||
use intern::{sym, Interned};
|
use intern::{sym, Interned};
|
||||||
use la_arena::Arena;
|
use la_arena::Arena;
|
||||||
|
@ -18,7 +18,9 @@ use triomphe::Arc;
|
||||||
use crate::{
|
use crate::{
|
||||||
builtin_type::{BuiltinInt, BuiltinUint},
|
builtin_type::{BuiltinInt, BuiltinUint},
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
item_tree::{AttrOwner, Field, FieldAstId, Fields, ItemTree, ModItem, RawVisibilityId},
|
item_tree::{
|
||||||
|
AttrOwner, Field, FieldParent, FieldsShape, ItemTree, ModItem, RawVisibilityId, TreeId,
|
||||||
|
},
|
||||||
lang_item::LangItem,
|
lang_item::LangItem,
|
||||||
lower::LowerCtx,
|
lower::LowerCtx,
|
||||||
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
|
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
|
||||||
|
@ -211,20 +213,25 @@ impl StructData {
|
||||||
}
|
}
|
||||||
|
|
||||||
let strukt = &item_tree[loc.id.value];
|
let strukt = &item_tree[loc.id.value];
|
||||||
let (variant_data, diagnostics) = lower_fields(
|
let (data, diagnostics) = lower_fields(
|
||||||
db,
|
db,
|
||||||
krate,
|
krate,
|
||||||
loc.id.file_id(),
|
|
||||||
loc.container.local_id,
|
loc.container.local_id,
|
||||||
|
loc.id.tree_id(),
|
||||||
&item_tree,
|
&item_tree,
|
||||||
&db.crate_graph()[krate].cfg_options,
|
&db.crate_graph()[krate].cfg_options,
|
||||||
|
FieldParent::Struct(loc.id.value),
|
||||||
&strukt.fields,
|
&strukt.fields,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
Arc::new(StructData {
|
Arc::new(StructData {
|
||||||
name: strukt.name.clone(),
|
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,
|
repr,
|
||||||
visibility: item_tree[strukt.visibility].clone(),
|
visibility: item_tree[strukt.visibility].clone(),
|
||||||
flags,
|
flags,
|
||||||
|
@ -256,20 +263,21 @@ impl StructData {
|
||||||
}
|
}
|
||||||
|
|
||||||
let union = &item_tree[loc.id.value];
|
let union = &item_tree[loc.id.value];
|
||||||
let (variant_data, diagnostics) = lower_fields(
|
let (data, diagnostics) = lower_fields(
|
||||||
db,
|
db,
|
||||||
krate,
|
krate,
|
||||||
loc.id.file_id(),
|
|
||||||
loc.container.local_id,
|
loc.container.local_id,
|
||||||
|
loc.id.tree_id(),
|
||||||
&item_tree,
|
&item_tree,
|
||||||
&db.crate_graph()[krate].cfg_options,
|
&db.crate_graph()[krate].cfg_options,
|
||||||
|
FieldParent::Union(loc.id.value),
|
||||||
&union.fields,
|
&union.fields,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
Arc::new(StructData {
|
Arc::new(StructData {
|
||||||
name: union.name.clone(),
|
name: union.name.clone(),
|
||||||
variant_data: Arc::new(variant_data),
|
variant_data: Arc::new(VariantData::Record(data)),
|
||||||
repr,
|
repr,
|
||||||
visibility: item_tree[union.visibility].clone(),
|
visibility: item_tree[union.visibility].clone(),
|
||||||
flags,
|
flags,
|
||||||
|
@ -336,13 +344,14 @@ impl EnumVariantData {
|
||||||
let item_tree = loc.id.item_tree(db);
|
let item_tree = loc.id.item_tree(db);
|
||||||
let variant = &item_tree[loc.id.value];
|
let variant = &item_tree[loc.id.value];
|
||||||
|
|
||||||
let (var_data, diagnostics) = lower_fields(
|
let (data, diagnostics) = lower_fields(
|
||||||
db,
|
db,
|
||||||
krate,
|
krate,
|
||||||
loc.id.file_id(),
|
|
||||||
container.local_id,
|
container.local_id,
|
||||||
|
loc.id.tree_id(),
|
||||||
&item_tree,
|
&item_tree,
|
||||||
&db.crate_graph()[krate].cfg_options,
|
&db.crate_graph()[krate].cfg_options,
|
||||||
|
FieldParent::Variant(loc.id.value),
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
Some(item_tree[loc.parent.lookup(db).id.value].visibility),
|
Some(item_tree[loc.parent.lookup(db).id.value].visibility),
|
||||||
);
|
);
|
||||||
|
@ -350,7 +359,11 @@ impl EnumVariantData {
|
||||||
(
|
(
|
||||||
Arc::new(EnumVariantData {
|
Arc::new(EnumVariantData {
|
||||||
name: variant.name.clone(),
|
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),
|
DefDiagnostics::new(diagnostics),
|
||||||
)
|
)
|
||||||
|
@ -396,21 +409,23 @@ pub enum StructKind {
|
||||||
Unit,
|
Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME This is only used for mapping back source now?
|
||||||
pub(crate) fn lower_struct(
|
pub(crate) fn lower_struct(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
|
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
|
||||||
ast: &InFile<ast::StructKind>,
|
ast: &InFile<ast::StructKind>,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
item_tree: &ItemTree,
|
item_tree: &ItemTree,
|
||||||
fields: &Fields,
|
parent: FieldParent,
|
||||||
) -> StructKind {
|
) -> StructKind {
|
||||||
let ctx = LowerCtx::new(db, ast.file_id);
|
let ctx = LowerCtx::new(db, ast.file_id);
|
||||||
|
|
||||||
match (&ast.value, fields) {
|
match &ast.value {
|
||||||
(ast::StructKind::Tuple(fl), Fields::Tuple(fields)) => {
|
ast::StructKind::Tuple(fl) => {
|
||||||
let cfg_options = &db.crate_graph()[krate].cfg_options;
|
let cfg_options = &db.crate_graph()[krate].cfg_options;
|
||||||
for ((i, fd), item_tree_id) in fl.fields().enumerate().zip(fields.clone()) {
|
for (i, fd) in fl.fields().enumerate() {
|
||||||
if !item_tree.attrs(db, krate, item_tree_id.into()).is_cfg_enabled(cfg_options) {
|
let attrs = item_tree.attrs(db, krate, AttrOwner::make_field_indexed(parent, i));
|
||||||
|
if !attrs.is_cfg_enabled(cfg_options) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,10 +442,11 @@ pub(crate) fn lower_struct(
|
||||||
}
|
}
|
||||||
StructKind::Tuple
|
StructKind::Tuple
|
||||||
}
|
}
|
||||||
(ast::StructKind::Record(fl), Fields::Record(fields)) => {
|
ast::StructKind::Record(fl) => {
|
||||||
let cfg_options = &db.crate_graph()[krate].cfg_options;
|
let cfg_options = &db.crate_graph()[krate].cfg_options;
|
||||||
for (fd, item_tree_id) in fl.fields().zip(fields.clone()) {
|
for (i, fd) in fl.fields().enumerate() {
|
||||||
if !item_tree.attrs(db, krate, item_tree_id.into()).is_cfg_enabled(cfg_options) {
|
let attrs = item_tree.attrs(db, krate, AttrOwner::make_field_indexed(parent, i));
|
||||||
|
if !attrs.is_cfg_enabled(cfg_options) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,65 +470,32 @@ pub(crate) fn lower_struct(
|
||||||
fn lower_fields(
|
fn lower_fields(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
current_file_id: HirFileId,
|
|
||||||
container: LocalModuleId,
|
container: LocalModuleId,
|
||||||
|
tree_id: TreeId,
|
||||||
item_tree: &ItemTree,
|
item_tree: &ItemTree,
|
||||||
cfg_options: &CfgOptions,
|
cfg_options: &CfgOptions,
|
||||||
fields: &Fields,
|
parent: FieldParent,
|
||||||
|
fields: &[Field],
|
||||||
override_visibility: Option<RawVisibilityId>,
|
override_visibility: Option<RawVisibilityId>,
|
||||||
) -> (VariantData, Vec<DefDiagnostic>) {
|
) -> (Arena<FieldData>, Vec<DefDiagnostic>) {
|
||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
match fields {
|
let mut arena = Arena::new();
|
||||||
Fields::Record(flds) => {
|
for (idx, field) in fields.iter().enumerate() {
|
||||||
let mut arena = Arena::new();
|
let attr_owner = AttrOwner::make_field_indexed(parent, idx);
|
||||||
for field_id in flds.clone() {
|
let attrs = item_tree.attrs(db, krate, attr_owner);
|
||||||
let attrs = item_tree.attrs(db, krate, field_id.into());
|
if attrs.is_cfg_enabled(cfg_options) {
|
||||||
let field = &item_tree[field_id];
|
arena.alloc(lower_field(item_tree, field, override_visibility));
|
||||||
if attrs.is_cfg_enabled(cfg_options) {
|
} else {
|
||||||
arena.alloc(lower_field(item_tree, field, override_visibility));
|
diagnostics.push(DefDiagnostic::unconfigured_code(
|
||||||
} else {
|
container,
|
||||||
diagnostics.push(DefDiagnostic::unconfigured_code(
|
tree_id,
|
||||||
container,
|
attr_owner,
|
||||||
InFile::new(
|
attrs.cfg().unwrap(),
|
||||||
current_file_id,
|
cfg_options.clone(),
|
||||||
match field.ast_id {
|
))
|
||||||
FieldAstId::Record(it) => it.erase(),
|
|
||||||
FieldAstId::Tuple(it) => it.erase(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
attrs.cfg().unwrap(),
|
|
||||||
cfg_options.clone(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(VariantData::Record(arena), diagnostics)
|
|
||||||
}
|
}
|
||||||
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(
|
fn lower_field(
|
||||||
|
|
|
@ -47,7 +47,7 @@ use base_db::CrateId;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile};
|
use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile};
|
||||||
use intern::{Interned, Symbol};
|
use intern::{Interned, Symbol};
|
||||||
use la_arena::{Arena, Idx, IdxRange, RawIdx};
|
use la_arena::{Arena, Idx, RawIdx};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -218,9 +218,7 @@ impl ItemTree {
|
||||||
extern_crates,
|
extern_crates,
|
||||||
extern_blocks,
|
extern_blocks,
|
||||||
functions,
|
functions,
|
||||||
params,
|
|
||||||
structs,
|
structs,
|
||||||
fields,
|
|
||||||
unions,
|
unions,
|
||||||
enums,
|
enums,
|
||||||
variants,
|
variants,
|
||||||
|
@ -241,9 +239,7 @@ impl ItemTree {
|
||||||
extern_crates.shrink_to_fit();
|
extern_crates.shrink_to_fit();
|
||||||
extern_blocks.shrink_to_fit();
|
extern_blocks.shrink_to_fit();
|
||||||
functions.shrink_to_fit();
|
functions.shrink_to_fit();
|
||||||
params.shrink_to_fit();
|
|
||||||
structs.shrink_to_fit();
|
structs.shrink_to_fit();
|
||||||
fields.shrink_to_fit();
|
|
||||||
unions.shrink_to_fit();
|
unions.shrink_to_fit();
|
||||||
enums.shrink_to_fit();
|
enums.shrink_to_fit();
|
||||||
variants.shrink_to_fit();
|
variants.shrink_to_fit();
|
||||||
|
@ -295,9 +291,7 @@ struct ItemTreeData {
|
||||||
extern_crates: Arena<ExternCrate>,
|
extern_crates: Arena<ExternCrate>,
|
||||||
extern_blocks: Arena<ExternBlock>,
|
extern_blocks: Arena<ExternBlock>,
|
||||||
functions: Arena<Function>,
|
functions: Arena<Function>,
|
||||||
params: Arena<Param>,
|
|
||||||
structs: Arena<Struct>,
|
structs: Arena<Struct>,
|
||||||
fields: Arena<Field>,
|
|
||||||
unions: Arena<Union>,
|
unions: Arena<Union>,
|
||||||
enums: Arena<Enum>,
|
enums: Arena<Enum>,
|
||||||
variants: Arena<Variant>,
|
variants: Arena<Variant>,
|
||||||
|
@ -315,7 +309,7 @@ struct ItemTreeData {
|
||||||
vis: ItemVisibilities,
|
vis: ItemVisibilities,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub enum AttrOwner {
|
pub enum AttrOwner {
|
||||||
/// Attributes on an item.
|
/// Attributes on an item.
|
||||||
ModItem(ModItem),
|
ModItem(ModItem),
|
||||||
|
@ -323,12 +317,28 @@ pub enum AttrOwner {
|
||||||
TopLevel,
|
TopLevel,
|
||||||
|
|
||||||
Variant(FileItemTreeId<Variant>),
|
Variant(FileItemTreeId<Variant>),
|
||||||
Field(Idx<Field>),
|
Field(FieldParent, ItemTreeFieldId),
|
||||||
Param(Idx<Param>),
|
Param(FileItemTreeId<Function>, ItemTreeParamId),
|
||||||
TypeOrConstParamData(GenericModItem, LocalTypeOrConstParamId),
|
TypeOrConstParamData(GenericModItem, LocalTypeOrConstParamId),
|
||||||
LifetimeParamData(GenericModItem, LocalLifetimeParamId),
|
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 {
|
macro_rules! from_attrs {
|
||||||
( $( $var:ident($t:ty) ),+ $(,)? ) => {
|
( $( $var:ident($t:ty) ),+ $(,)? ) => {
|
||||||
$(
|
$(
|
||||||
|
@ -341,12 +351,7 @@ macro_rules! from_attrs {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
from_attrs!(
|
from_attrs!(ModItem(ModItem), Variant(FileItemTreeId<Variant>));
|
||||||
ModItem(ModItem),
|
|
||||||
Variant(FileItemTreeId<Variant>),
|
|
||||||
Field(Idx<Field>),
|
|
||||||
Param(Idx<Param>),
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Trait implemented by all nodes in the item tree.
|
/// Trait implemented by all nodes in the item tree.
|
||||||
pub trait ItemTreeNode: Clone {
|
pub trait ItemTreeNode: Clone {
|
||||||
|
@ -365,7 +370,7 @@ pub trait GenericsItemTreeNode: ItemTreeNode {
|
||||||
pub struct FileItemTreeId<N>(Idx<N>);
|
pub struct FileItemTreeId<N>(Idx<N>);
|
||||||
|
|
||||||
impl<N> FileItemTreeId<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())
|
(range.start.index().into_raw().into_u32()..range.end.index().into_raw().into_u32())
|
||||||
.map(RawIdx::from_u32)
|
.map(RawIdx::from_u32)
|
||||||
.map(Idx::from_raw)
|
.map(Idx::from_raw)
|
||||||
|
@ -417,18 +422,18 @@ impl TreeId {
|
||||||
Self { file, block }
|
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 {
|
match self.block {
|
||||||
Some(block) => db.block_item_tree(block),
|
Some(block) => db.block_item_tree(block),
|
||||||
None => db.file_item_tree(self.file),
|
None => db.file_item_tree(self.file),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn file_id(self) -> HirFileId {
|
pub fn file_id(self) -> HirFileId {
|
||||||
self.file
|
self.file
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_block(self) -> bool {
|
pub fn is_block(self) -> bool {
|
||||||
self.block.is_some()
|
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 {
|
impl From<GenericModItem> for ModItem {
|
||||||
fn from(id: GenericModItem) -> ModItem {
|
fn from(id: GenericModItem) -> ModItem {
|
||||||
match id {
|
match id {
|
||||||
|
@ -596,22 +622,6 @@ mod_items! {
|
||||||
Macro2 in macro_defs -> ast::MacroDef,
|
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 {
|
impl Index<RawVisibilityId> for ItemTree {
|
||||||
type Output = RawVisibility;
|
type Output = RawVisibility;
|
||||||
fn index(&self, index: RawVisibilityId) -> &Self::Output {
|
fn index(&self, index: RawVisibilityId) -> &Self::Output {
|
||||||
|
@ -723,7 +733,7 @@ pub struct Function {
|
||||||
pub visibility: RawVisibilityId,
|
pub visibility: RawVisibilityId,
|
||||||
pub explicit_generic_params: Interned<GenericParams>,
|
pub explicit_generic_params: Interned<GenericParams>,
|
||||||
pub abi: Option<Symbol>,
|
pub abi: Option<Symbol>,
|
||||||
pub params: IdxRange<Param>,
|
pub params: Box<[Param]>,
|
||||||
pub ret_type: Interned<TypeRef>,
|
pub ret_type: Interned<TypeRef>,
|
||||||
pub ast_id: FileAstId<ast::Fn>,
|
pub ast_id: FileAstId<ast::Fn>,
|
||||||
pub(crate) flags: FnFlags,
|
pub(crate) flags: FnFlags,
|
||||||
|
@ -731,15 +741,7 @@ pub struct Function {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Param {
|
pub struct Param {
|
||||||
/// This is [`None`] for varargs
|
pub type_ref: Interned<TypeRef>,
|
||||||
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! {
|
bitflags::bitflags! {
|
||||||
|
@ -760,7 +762,8 @@ pub struct Struct {
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
pub visibility: RawVisibilityId,
|
pub visibility: RawVisibilityId,
|
||||||
pub generic_params: Interned<GenericParams>,
|
pub generic_params: Interned<GenericParams>,
|
||||||
pub fields: Fields,
|
pub fields: Box<[Field]>,
|
||||||
|
pub shape: FieldsShape,
|
||||||
pub ast_id: FileAstId<ast::Struct>,
|
pub ast_id: FileAstId<ast::Struct>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,7 +772,7 @@ pub struct Union {
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
pub visibility: RawVisibilityId,
|
pub visibility: RawVisibilityId,
|
||||||
pub generic_params: Interned<GenericParams>,
|
pub generic_params: Interned<GenericParams>,
|
||||||
pub fields: Fields,
|
pub fields: Box<[Field]>,
|
||||||
pub ast_id: FileAstId<ast::Union>,
|
pub ast_id: FileAstId<ast::Union>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,6 +785,29 @@ pub struct Enum {
|
||||||
pub ast_id: FileAstId<ast::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)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct Const {
|
pub struct Const {
|
||||||
/// `None` for `const _: () = ();`
|
/// `None` for `const _: () = ();`
|
||||||
|
@ -1039,28 +1065,6 @@ impl ModItem {
|
||||||
&ModItem::Function(func) => Some(AssocItem::Function(func)),
|
&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)]
|
#[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,
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,12 +17,12 @@ use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance},
|
generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance},
|
||||||
item_tree::{
|
item_tree::{
|
||||||
AssocItem, AttrOwner, Const, Either, Enum, ExternBlock, ExternCrate, Field, FieldAstId,
|
AssocItem, AttrOwner, Const, Either, Enum, ExternBlock, ExternCrate, Field, FieldParent,
|
||||||
Fields, FileItemTreeId, FnFlags, Function, GenericArgs, GenericModItem, Idx, IdxRange,
|
FieldsShape, FileItemTreeId, FnFlags, Function, GenericArgs, GenericModItem, Idx, Impl,
|
||||||
Impl, ImportAlias, Interned, ItemTree, ItemTreeData, ItemTreeNode, Macro2, MacroCall,
|
ImportAlias, Interned, ItemTree, ItemTreeData, Macro2, MacroCall, MacroRules, Mod, ModItem,
|
||||||
MacroRules, Mod, ModItem, ModKind, ModPath, Mutability, Name, Param, ParamAstId, Path,
|
ModKind, ModPath, Mutability, Name, Param, Path, Range, RawAttrs, RawIdx, RawVisibilityId,
|
||||||
Range, RawAttrs, RawIdx, RawVisibilityId, Static, Struct, StructKind, Trait, TraitAlias,
|
Static, Struct, StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
|
||||||
TypeAlias, Union, Use, UseTree, UseTreeKind, Variant,
|
Variant,
|
||||||
},
|
},
|
||||||
path::AssociatedTypeBinding,
|
path::AssociatedTypeBinding,
|
||||||
type_ref::{LifetimeRef, TraitBoundModifier, TraitRef, TypeBound, TypeRef},
|
type_ref::{LifetimeRef, TraitBoundModifier, TraitRef, TypeBound, TypeRef},
|
||||||
|
@ -30,7 +30,7 @@ use crate::{
|
||||||
LocalLifetimeParamId, LocalTypeOrConstParamId,
|
LocalLifetimeParamId, LocalTypeOrConstParamId,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> {
|
fn id<N>(index: Idx<N>) -> FileItemTreeId<N> {
|
||||||
FileItemTreeId(index)
|
FileItemTreeId(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,82 +193,98 @@ impl<'a> Ctx<'a> {
|
||||||
let visibility = self.lower_visibility(strukt);
|
let visibility = self.lower_visibility(strukt);
|
||||||
let name = strukt.name()?.as_name();
|
let name = strukt.name()?.as_name();
|
||||||
let ast_id = self.source_ast_id_map.ast_id(strukt);
|
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 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));
|
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());
|
self.write_generic_params_attributes(id.into());
|
||||||
Some(id)
|
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 {
|
match strukt_kind {
|
||||||
ast::StructKind::Record(it) => {
|
ast::StructKind::Record(it) => {
|
||||||
let range = self.lower_record_fields(it);
|
let mut fields = vec![];
|
||||||
Fields::Record(range)
|
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) => {
|
ast::StructKind::Tuple(it) => {
|
||||||
let range = self.lower_tuple_fields(it);
|
let mut fields = vec![];
|
||||||
Fields::Tuple(range)
|
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> {
|
fn lower_record_field(&mut self, field: &ast::RecordField) -> Field {
|
||||||
let start = self.next_field_idx();
|
let name = match field.name() {
|
||||||
for field in fields.fields() {
|
Some(name) => name.as_name(),
|
||||||
if let Some(data) = self.lower_record_field(&field) {
|
None => Name::missing(),
|
||||||
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();
|
|
||||||
let visibility = self.lower_visibility(field);
|
let visibility = self.lower_visibility(field);
|
||||||
let type_ref = self.lower_type_ref_opt(field.ty());
|
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> {
|
Field { name, type_ref, visibility }
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleField) -> Field {
|
fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleField) -> Field {
|
||||||
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 = self.lower_type_ref_opt(field.ty());
|
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 }
|
||||||
Field { name, type_ref, visibility, ast_id }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
|
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
|
||||||
let visibility = self.lower_visibility(union);
|
let visibility = self.lower_visibility(union);
|
||||||
let name = union.name()?.as_name();
|
let name = union.name()?.as_name();
|
||||||
let ast_id = self.source_ast_id_map.ast_id(union);
|
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)),
|
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 generic_params = self.lower_generic_params(HasImplicitSelf::No, union);
|
||||||
let res = Union { name, visibility, generic_params, fields, ast_id };
|
let res = Union { name, visibility, generic_params, fields, ast_id };
|
||||||
let id = id(self.data().unions.alloc(res));
|
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());
|
self.write_generic_params_attributes(id.into());
|
||||||
Some(id)
|
Some(id)
|
||||||
}
|
}
|
||||||
|
@ -293,24 +309,35 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_variants(&mut self, variants: &ast::VariantList) -> Range<FileItemTreeId<Variant>> {
|
fn lower_variants(&mut self, variants: &ast::VariantList) -> Range<FileItemTreeId<Variant>> {
|
||||||
let start = self.next_variant_idx();
|
let start = self.next_variant_idx();
|
||||||
for variant in variants.variants() {
|
for variant in variants.variants() {
|
||||||
if let Some(data) = self.lower_variant(&variant) {
|
let idx = self.lower_variant(&variant);
|
||||||
let idx = self.data().variants.alloc(data);
|
self.add_attrs(
|
||||||
self.add_attrs(
|
id(idx).into(),
|
||||||
id(idx).into(),
|
RawAttrs::new(self.db.upcast(), &variant, self.span_map()),
|
||||||
RawAttrs::new(self.db.upcast(), &variant, self.span_map()),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let end = self.next_variant_idx();
|
let end = self.next_variant_idx();
|
||||||
FileItemTreeId(start)..FileItemTreeId(end)
|
FileItemTreeId(start)..FileItemTreeId(end)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_variant(&mut self, variant: &ast::Variant) -> Option<Variant> {
|
fn lower_variant(&mut self, variant: &ast::Variant) -> Idx<Variant> {
|
||||||
let name = variant.name()?.as_name();
|
let name = match variant.name() {
|
||||||
let fields = self.lower_fields(&variant.kind());
|
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 ast_id = self.source_ast_id_map.ast_id(variant);
|
||||||
let res = Variant { name, fields, ast_id };
|
let res = Variant { name, fields, shape: kind, ast_id };
|
||||||
Some(res)
|
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>> {
|
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 name = func.name()?.as_name();
|
||||||
|
|
||||||
let mut has_self_param = false;
|
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(param_list) = func.param_list() {
|
||||||
if let Some(self_param) = param_list.self_param() {
|
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() {
|
let self_type = match self_param.ty() {
|
||||||
Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
|
Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
|
||||||
None => {
|
None => {
|
||||||
|
@ -342,40 +380,25 @@ impl<'a> Ctx<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let type_ref = Interned::new(self_type);
|
let type_ref = Interned::new(self_type);
|
||||||
let ast_id = self.source_ast_id_map.ast_id(&self_param);
|
params.push(Param { type_ref });
|
||||||
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()),
|
|
||||||
);
|
|
||||||
has_self_param = true;
|
has_self_param = true;
|
||||||
}
|
}
|
||||||
for param in param_list.params() {
|
for param in param_list.params() {
|
||||||
let ast_id = self.source_ast_id_map.ast_id(¶m);
|
push_attr(params.len(), RawAttrs::new(self.db.upcast(), ¶m, self.span_map()));
|
||||||
let idx = match param.dotdotdot_token() {
|
let param = match param.dotdotdot_token() {
|
||||||
Some(_) => self
|
Some(_) => {
|
||||||
.data()
|
has_var_args = true;
|
||||||
.params
|
Param { type_ref: Interned::new(TypeRef::Error) }
|
||||||
.alloc(Param { type_ref: None, ast_id: ParamAstId::Param(ast_id) }),
|
}
|
||||||
None => {
|
None => {
|
||||||
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
|
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
|
||||||
let ty = Interned::new(type_ref);
|
let ty = Interned::new(type_ref);
|
||||||
self.data()
|
Param { type_ref: ty }
|
||||||
.params
|
|
||||||
.alloc(Param { type_ref: Some(ty), ast_id: ParamAstId::Param(ast_id) })
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.add_attrs(
|
params.push(param);
|
||||||
idx.into(),
|
|
||||||
RawAttrs::new(self.db.upcast(), ¶m, self.span_map()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let end_param = self.next_param_idx();
|
|
||||||
let params = IdxRange::new(start_param..end_param);
|
|
||||||
|
|
||||||
let ret_type = match func.ret_type() {
|
let ret_type = match func.ret_type() {
|
||||||
Some(rt) => match rt.ty() {
|
Some(rt) => match rt.ty() {
|
||||||
|
@ -417,19 +440,25 @@ impl<'a> Ctx<'a> {
|
||||||
if func.unsafe_token().is_some() {
|
if func.unsafe_token().is_some() {
|
||||||
flags |= FnFlags::HAS_UNSAFE_KW;
|
flags |= FnFlags::HAS_UNSAFE_KW;
|
||||||
}
|
}
|
||||||
|
if has_var_args {
|
||||||
|
flags |= FnFlags::IS_VARARGS;
|
||||||
|
}
|
||||||
|
|
||||||
let res = Function {
|
let res = Function {
|
||||||
name,
|
name,
|
||||||
visibility,
|
visibility,
|
||||||
explicit_generic_params: self.lower_generic_params(HasImplicitSelf::No, func),
|
explicit_generic_params: self.lower_generic_params(HasImplicitSelf::No, func),
|
||||||
abi,
|
abi,
|
||||||
params,
|
params: params.into_boxed_slice(),
|
||||||
ret_type: Interned::new(ret_type),
|
ret_type: Interned::new(ret_type),
|
||||||
ast_id,
|
ast_id,
|
||||||
flags,
|
flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = id(self.data().functions.alloc(res));
|
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());
|
self.write_generic_params_attributes(id.into());
|
||||||
Some(id)
|
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> {
|
fn next_variant_idx(&self) -> Idx<Variant> {
|
||||||
Idx::from_raw(RawIdx::from(
|
Idx::from_raw(RawIdx::from(
|
||||||
self.tree.data.as_ref().map_or(0, |data| data.variants.len() as u32),
|
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 {
|
fn desugar_future_path(orig: TypeRef) -> Path {
|
||||||
|
|
|
@ -2,16 +2,17 @@
|
||||||
|
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
|
||||||
|
use la_arena::{Idx, RawIdx};
|
||||||
use span::ErasedFileAstId;
|
use span::ErasedFileAstId;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
generics::{TypeOrConstParamData, WherePredicate, WherePredicateTypeTarget},
|
generics::{TypeOrConstParamData, WherePredicate, WherePredicateTypeTarget},
|
||||||
item_tree::{
|
item_tree::{
|
||||||
AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, Field, FieldAstId, Fields,
|
AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, Field, FieldParent,
|
||||||
FileItemTreeId, FnFlags, Function, GenericModItem, GenericParams, Impl, Interned, ItemTree,
|
FieldsShape, FileItemTreeId, FnFlags, Function, GenericModItem, GenericParams, Impl,
|
||||||
Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, Param, ParamAstId, Path, RawAttrs,
|
Interned, ItemTree, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, Param, Path,
|
||||||
RawVisibilityId, Static, Struct, Trait, TraitAlias, TypeAlias, TypeBound, TypeRef, Union,
|
RawAttrs, RawVisibilityId, Static, Struct, Trait, TraitAlias, TypeAlias, TypeBound,
|
||||||
Use, UseTree, UseTreeKind, Variant,
|
TypeRef, Union, Use, UseTree, UseTreeKind, Variant,
|
||||||
},
|
},
|
||||||
pretty::{print_path, print_type_bounds, print_type_ref},
|
pretty::{print_path, print_type_bounds, print_type_ref},
|
||||||
visibility::RawVisibility,
|
visibility::RawVisibility,
|
||||||
|
@ -118,19 +119,17 @@ impl Printer<'_> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_fields(&mut self, fields: &Fields) {
|
fn print_fields(&mut self, parent: FieldParent, kind: FieldsShape, fields: &[Field]) {
|
||||||
match fields {
|
match kind {
|
||||||
Fields::Record(fields) => {
|
FieldsShape::Record => {
|
||||||
self.whitespace();
|
self.whitespace();
|
||||||
w!(self, "{{");
|
w!(self, "{{");
|
||||||
self.indented(|this| {
|
self.indented(|this| {
|
||||||
for field in fields.clone() {
|
for (idx, Field { name, type_ref, visibility }) in fields.iter().enumerate() {
|
||||||
let Field { visibility, name, type_ref, ast_id } = &this.tree[field];
|
this.print_attrs_of(
|
||||||
this.print_ast_id(match ast_id {
|
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
|
||||||
FieldAstId::Record(it) => it.erase(),
|
"\n",
|
||||||
FieldAstId::Tuple(it) => it.erase(),
|
);
|
||||||
});
|
|
||||||
this.print_attrs_of(field, "\n");
|
|
||||||
this.print_visibility(*visibility);
|
this.print_visibility(*visibility);
|
||||||
w!(this, "{}: ", name.display(self.db.upcast()));
|
w!(this, "{}: ", name.display(self.db.upcast()));
|
||||||
this.print_type_ref(type_ref);
|
this.print_type_ref(type_ref);
|
||||||
|
@ -139,16 +138,14 @@ impl Printer<'_> {
|
||||||
});
|
});
|
||||||
w!(self, "}}");
|
w!(self, "}}");
|
||||||
}
|
}
|
||||||
Fields::Tuple(fields) => {
|
FieldsShape::Tuple => {
|
||||||
w!(self, "(");
|
w!(self, "(");
|
||||||
self.indented(|this| {
|
self.indented(|this| {
|
||||||
for field in fields.clone() {
|
for (idx, Field { name, type_ref, visibility }) in fields.iter().enumerate() {
|
||||||
let Field { visibility, name, type_ref, ast_id } = &this.tree[field];
|
this.print_attrs_of(
|
||||||
this.print_ast_id(match ast_id {
|
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
|
||||||
FieldAstId::Record(it) => it.erase(),
|
"\n",
|
||||||
FieldAstId::Tuple(it) => it.erase(),
|
);
|
||||||
});
|
|
||||||
this.print_attrs_of(field, "\n");
|
|
||||||
this.print_visibility(*visibility);
|
this.print_visibility(*visibility);
|
||||||
w!(this, "{}: ", name.display(self.db.upcast()));
|
w!(this, "{}: ", name.display(self.db.upcast()));
|
||||||
this.print_type_ref(type_ref);
|
this.print_type_ref(type_ref);
|
||||||
|
@ -157,24 +154,30 @@ impl Printer<'_> {
|
||||||
});
|
});
|
||||||
w!(self, ")");
|
w!(self, ")");
|
||||||
}
|
}
|
||||||
Fields::Unit => {}
|
FieldsShape::Unit => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_fields_and_where_clause(&mut self, fields: &Fields, params: &GenericParams) {
|
fn print_fields_and_where_clause(
|
||||||
match fields {
|
&mut self,
|
||||||
Fields::Record(_) => {
|
parent: FieldParent,
|
||||||
|
kind: FieldsShape,
|
||||||
|
fields: &[Field],
|
||||||
|
params: &GenericParams,
|
||||||
|
) {
|
||||||
|
match kind {
|
||||||
|
FieldsShape::Record => {
|
||||||
if self.print_where_clause(params) {
|
if self.print_where_clause(params) {
|
||||||
wln!(self);
|
wln!(self);
|
||||||
}
|
}
|
||||||
self.print_fields(fields);
|
self.print_fields(parent, kind, fields);
|
||||||
}
|
}
|
||||||
Fields::Unit => {
|
FieldsShape::Unit => {
|
||||||
self.print_where_clause(params);
|
self.print_where_clause(params);
|
||||||
self.print_fields(fields);
|
self.print_fields(parent, kind, fields);
|
||||||
}
|
}
|
||||||
Fields::Tuple(_) => {
|
FieldsShape::Tuple => {
|
||||||
self.print_fields(fields);
|
self.print_fields(parent, kind, fields);
|
||||||
self.print_where_clause(params);
|
self.print_where_clause(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,25 +283,20 @@ impl Printer<'_> {
|
||||||
w!(self, "(");
|
w!(self, "(");
|
||||||
if !params.is_empty() {
|
if !params.is_empty() {
|
||||||
self.indented(|this| {
|
self.indented(|this| {
|
||||||
for param in params.clone() {
|
for (idx, Param { type_ref }) in params.iter().enumerate() {
|
||||||
this.print_attrs_of(param, "\n");
|
this.print_attrs_of(
|
||||||
let Param { type_ref, ast_id } = &this.tree[param];
|
AttrOwner::Param(it, Idx::from_raw(RawIdx::from(idx as u32))),
|
||||||
this.print_ast_id(match ast_id {
|
"\n",
|
||||||
ParamAstId::Param(it) => it.erase(),
|
);
|
||||||
ParamAstId::SelfParam(it) => it.erase(),
|
if idx == 0 && flags.contains(FnFlags::HAS_SELF_PARAM) {
|
||||||
});
|
w!(this, "self: ");
|
||||||
match type_ref {
|
}
|
||||||
Some(ty) => {
|
if idx != params.len() {
|
||||||
if flags.contains(FnFlags::HAS_SELF_PARAM) {
|
this.print_type_ref(type_ref);
|
||||||
w!(this, "self: ");
|
} else {
|
||||||
}
|
wln!(this, "...");
|
||||||
this.print_type_ref(ty);
|
}
|
||||||
wln!(this, ",");
|
wln!(this, ",");
|
||||||
}
|
|
||||||
None => {
|
|
||||||
wln!(this, "...");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -312,13 +310,19 @@ impl Printer<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModItem::Struct(it) => {
|
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_ast_id(ast_id.erase());
|
||||||
self.print_visibility(*visibility);
|
self.print_visibility(*visibility);
|
||||||
w!(self, "struct {}", name.display(self.db.upcast()));
|
w!(self, "struct {}", name.display(self.db.upcast()));
|
||||||
self.print_generic_params(generic_params, it.into());
|
self.print_generic_params(generic_params, it.into());
|
||||||
self.print_fields_and_where_clause(fields, generic_params);
|
self.print_fields_and_where_clause(
|
||||||
if matches!(fields, Fields::Record(_)) {
|
FieldParent::Struct(it),
|
||||||
|
*kind,
|
||||||
|
fields,
|
||||||
|
generic_params,
|
||||||
|
);
|
||||||
|
if matches!(kind, FieldsShape::Record) {
|
||||||
wln!(self);
|
wln!(self);
|
||||||
} else {
|
} else {
|
||||||
wln!(self, ";");
|
wln!(self, ";");
|
||||||
|
@ -330,12 +334,13 @@ impl Printer<'_> {
|
||||||
self.print_visibility(*visibility);
|
self.print_visibility(*visibility);
|
||||||
w!(self, "union {}", name.display(self.db.upcast()));
|
w!(self, "union {}", name.display(self.db.upcast()));
|
||||||
self.print_generic_params(generic_params, it.into());
|
self.print_generic_params(generic_params, it.into());
|
||||||
self.print_fields_and_where_clause(fields, generic_params);
|
self.print_fields_and_where_clause(
|
||||||
if matches!(fields, Fields::Record(_)) {
|
FieldParent::Union(it),
|
||||||
wln!(self);
|
FieldsShape::Record,
|
||||||
} else {
|
fields,
|
||||||
wln!(self, ";");
|
generic_params,
|
||||||
}
|
);
|
||||||
|
wln!(self);
|
||||||
}
|
}
|
||||||
ModItem::Enum(it) => {
|
ModItem::Enum(it) => {
|
||||||
let Enum { name, visibility, variants, generic_params, ast_id } = &self.tree[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.print_where_clause_and_opening_brace(generic_params);
|
||||||
self.indented(|this| {
|
self.indented(|this| {
|
||||||
for variant in FileItemTreeId::range_iter(variants.clone()) {
|
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_ast_id(ast_id.erase());
|
||||||
this.print_attrs_of(variant, "\n");
|
this.print_attrs_of(variant, "\n");
|
||||||
w!(this, "{}", name.display(self.db.upcast()));
|
w!(this, "{}", name.display(self.db.upcast()));
|
||||||
this.print_fields(fields);
|
this.print_fields(FieldParent::Variant(variant), *kind, fields);
|
||||||
wln!(this, ",");
|
wln!(this, ",");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -129,40 +129,34 @@ enum E {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
// AstId: 2
|
// AstId: 2
|
||||||
pub(self) struct Struct {
|
pub(self) struct Struct {
|
||||||
// AstId: 6
|
|
||||||
#[doc = " fld docs"]
|
#[doc = " fld docs"]
|
||||||
pub(self) fld: (),
|
pub(self) fld: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
// AstId: 3
|
// AstId: 3
|
||||||
pub(self) struct Tuple(
|
pub(self) struct Tuple(
|
||||||
// AstId: 7
|
|
||||||
#[attr]
|
#[attr]
|
||||||
pub(self) 0: u8,
|
pub(self) 0: u8,
|
||||||
);
|
);
|
||||||
|
|
||||||
// AstId: 4
|
// AstId: 4
|
||||||
pub(self) union Ize {
|
pub(self) union Ize {
|
||||||
// AstId: 8
|
|
||||||
pub(self) a: (),
|
pub(self) a: (),
|
||||||
// AstId: 9
|
|
||||||
pub(self) b: (),
|
pub(self) b: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
// AstId: 5
|
// AstId: 5
|
||||||
pub(self) enum E {
|
pub(self) enum E {
|
||||||
// AstId: 10
|
// AstId: 6
|
||||||
#[doc = " comment on Unit"]
|
#[doc = " comment on Unit"]
|
||||||
Unit,
|
Unit,
|
||||||
// AstId: 11
|
// AstId: 7
|
||||||
#[doc = " comment on Tuple"]
|
#[doc = " comment on Tuple"]
|
||||||
Tuple(
|
Tuple(
|
||||||
// AstId: 13
|
|
||||||
pub(self) 0: u8,
|
pub(self) 0: u8,
|
||||||
),
|
),
|
||||||
// AstId: 12
|
// AstId: 8
|
||||||
Struct {
|
Struct {
|
||||||
// AstId: 14
|
|
||||||
#[doc = " comment on a: u8"]
|
#[doc = " comment on a: u8"]
|
||||||
pub(self) a: u8,
|
pub(self) a: u8,
|
||||||
},
|
},
|
||||||
|
@ -201,9 +195,7 @@ trait Tr: SuperTrait + 'lifetime {
|
||||||
// AstId: 3
|
// AstId: 3
|
||||||
pub(self) fn f(
|
pub(self) fn f(
|
||||||
#[attr]
|
#[attr]
|
||||||
// AstId: 5
|
|
||||||
u8,
|
u8,
|
||||||
// AstId: 6
|
|
||||||
(),
|
(),
|
||||||
) -> () { ... }
|
) -> () { ... }
|
||||||
|
|
||||||
|
@ -213,12 +205,11 @@ trait Tr: SuperTrait + 'lifetime {
|
||||||
Self: SuperTrait,
|
Self: SuperTrait,
|
||||||
Self: 'lifetime
|
Self: 'lifetime
|
||||||
{
|
{
|
||||||
// AstId: 8
|
// AstId: 6
|
||||||
pub(self) type Assoc: AssocBound = Default;
|
pub(self) type Assoc: AssocBound = Default;
|
||||||
|
|
||||||
// AstId: 9
|
// AstId: 7
|
||||||
pub(self) fn method(
|
pub(self) fn method(
|
||||||
// AstId: 10
|
|
||||||
self: &Self,
|
self: &Self,
|
||||||
) -> ();
|
) -> ();
|
||||||
}
|
}
|
||||||
|
@ -300,17 +291,11 @@ struct S {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
// AstId: 1
|
// AstId: 1
|
||||||
pub(self) struct S {
|
pub(self) struct S {
|
||||||
// AstId: 2
|
|
||||||
pub(self) a: self::Ty,
|
pub(self) a: self::Ty,
|
||||||
// AstId: 3
|
|
||||||
pub(self) b: super::SuperTy,
|
pub(self) b: super::SuperTy,
|
||||||
// AstId: 4
|
|
||||||
pub(self) c: super::super::SuperSuperTy,
|
pub(self) c: super::super::SuperSuperTy,
|
||||||
// AstId: 5
|
|
||||||
pub(self) d: ::abs::Path,
|
pub(self) d: ::abs::Path,
|
||||||
// AstId: 6
|
|
||||||
pub(self) e: crate::Crate,
|
pub(self) e: crate::Crate,
|
||||||
// AstId: 7
|
|
||||||
pub(self) f: plain::path::Ty,
|
pub(self) f: plain::path::Ty,
|
||||||
}
|
}
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -331,13 +316,9 @@ struct S {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
// AstId: 1
|
// AstId: 1
|
||||||
pub(self) struct S {
|
pub(self) struct S {
|
||||||
// AstId: 2
|
|
||||||
pub(self) a: Mixed::<'a, T, Item = (), OtherItem = u8>,
|
pub(self) a: Mixed::<'a, T, Item = (), OtherItem = u8>,
|
||||||
// AstId: 3
|
|
||||||
pub(self) b: Qualified::<Self=Fully>::Syntax,
|
pub(self) b: Qualified::<Self=Fully>::Syntax,
|
||||||
// AstId: 4
|
|
||||||
pub(self) c: <TypeAnchored>::Path::<'a>,
|
pub(self) c: <TypeAnchored>::Path::<'a>,
|
||||||
// AstId: 5
|
|
||||||
pub(self) d: dyn for<'a> Trait::<'a>,
|
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: 'a,
|
||||||
T: 'b
|
T: 'b
|
||||||
{
|
{
|
||||||
// AstId: 8
|
|
||||||
pub(self) field: &'a &'b T,
|
pub(self) field: &'a &'b T,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AstId: 2
|
// AstId: 2
|
||||||
pub(self) struct Tuple<T, U>(
|
pub(self) struct Tuple<T, U>(
|
||||||
// AstId: 9
|
|
||||||
pub(self) 0: T,
|
pub(self) 0: T,
|
||||||
// AstId: 10
|
|
||||||
pub(self) 1: U,
|
pub(self) 1: U,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
@ -393,9 +371,8 @@ trait Tr<'a, T: 'a>: Super where Self: for<'a> Tr<'a, T> {}
|
||||||
T: 'a,
|
T: 'a,
|
||||||
T: 'b
|
T: 'b
|
||||||
{
|
{
|
||||||
// AstId: 12
|
// AstId: 9
|
||||||
pub(self) fn f<G>(
|
pub(self) fn f<G>(
|
||||||
// AstId: 13
|
|
||||||
impl Copy,
|
impl Copy,
|
||||||
) -> impl Copy
|
) -> impl Copy
|
||||||
where
|
where
|
||||||
|
|
|
@ -23,7 +23,7 @@ use itertools::{izip, Itertools};
|
||||||
use la_arena::Idx;
|
use la_arena::Idx;
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use span::{Edition, EditionedFileId, ErasedFileAstId, FileAstId, SyntaxContextId};
|
use span::{Edition, EditionedFileId, FileAstId, SyntaxContextId};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@ use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
|
item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
|
||||||
item_tree::{
|
item_tree::{
|
||||||
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
|
self, AttrOwner, ExternCrate, FieldsShape, FileItemTreeId, ImportKind, ItemTree,
|
||||||
Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
|
ItemTreeId, ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
|
||||||
},
|
},
|
||||||
macro_call_as_call_id, macro_call_as_call_id_with_eager,
|
macro_call_as_call_id, macro_call_as_call_id_with_eager,
|
||||||
nameres::{
|
nameres::{
|
||||||
|
@ -1580,10 +1580,7 @@ impl ModCollector<'_, '_> {
|
||||||
let attrs = self.item_tree.attrs(db, krate, item.into());
|
let attrs = self.item_tree.attrs(db, krate, item.into());
|
||||||
if let Some(cfg) = attrs.cfg() {
|
if let Some(cfg) = attrs.cfg() {
|
||||||
if !self.is_cfg_enabled(&cfg) {
|
if !self.is_cfg_enabled(&cfg) {
|
||||||
self.emit_unconfigured_diagnostic(
|
self.emit_unconfigured_diagnostic(self.tree_id, item.into(), &cfg);
|
||||||
InFile::new(self.file_id(), item.ast_id(self.item_tree).erase()),
|
|
||||||
&cfg,
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1696,7 @@ impl ModCollector<'_, '_> {
|
||||||
.into(),
|
.into(),
|
||||||
&it.name,
|
&it.name,
|
||||||
vis,
|
vis,
|
||||||
!matches!(it.fields, Fields::Record(_)),
|
!matches!(it.shape, FieldsShape::Record),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ModItem::Union(id) => {
|
ModItem::Union(id) => {
|
||||||
|
@ -1737,10 +1734,8 @@ impl ModCollector<'_, '_> {
|
||||||
match is_enabled {
|
match is_enabled {
|
||||||
Err(cfg) => {
|
Err(cfg) => {
|
||||||
self.emit_unconfigured_diagnostic(
|
self.emit_unconfigured_diagnostic(
|
||||||
InFile::new(
|
self.tree_id,
|
||||||
self.file_id(),
|
variant.into(),
|
||||||
self.item_tree[variant.index()].ast_id.erase(),
|
|
||||||
),
|
|
||||||
&cfg,
|
&cfg,
|
||||||
);
|
);
|
||||||
None
|
None
|
||||||
|
@ -1956,7 +1951,8 @@ impl ModCollector<'_, '_> {
|
||||||
match is_enabled {
|
match is_enabled {
|
||||||
Err(cfg) => {
|
Err(cfg) => {
|
||||||
self.emit_unconfigured_diagnostic(
|
self.emit_unconfigured_diagnostic(
|
||||||
ast_id.map(|it| it.erase()),
|
self.tree_id,
|
||||||
|
AttrOwner::TopLevel,
|
||||||
&cfg,
|
&cfg,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2402,10 +2398,11 @@ impl ModCollector<'_, '_> {
|
||||||
self.def_collector.cfg_options.check(cfg) != Some(false)
|
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.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
|
||||||
self.module_id,
|
self.module_id,
|
||||||
ast_id,
|
tree_id,
|
||||||
|
item,
|
||||||
cfg.clone(),
|
cfg.clone(),
|
||||||
self.def_collector.cfg_options.clone(),
|
self.def_collector.cfg_options.clone(),
|
||||||
));
|
));
|
||||||
|
|
|
@ -4,12 +4,12 @@ use std::ops::Not;
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use hir_expand::{attrs::AttrId, ErasedAstId, MacroCallKind};
|
use hir_expand::{attrs::AttrId, MacroCallKind};
|
||||||
use la_arena::Idx;
|
use la_arena::Idx;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
item_tree::{self, ItemTreeId},
|
item_tree::{self, AttrOwner, ItemTreeId, TreeId},
|
||||||
nameres::LocalModuleId,
|
nameres::LocalModuleId,
|
||||||
path::ModPath,
|
path::ModPath,
|
||||||
AstId,
|
AstId,
|
||||||
|
@ -29,7 +29,8 @@ pub enum DefDiagnosticKind {
|
||||||
index: Idx<ast::UseTree>,
|
index: Idx<ast::UseTree>,
|
||||||
},
|
},
|
||||||
UnconfiguredCode {
|
UnconfiguredCode {
|
||||||
ast: ErasedAstId,
|
tree: TreeId,
|
||||||
|
item: AttrOwner,
|
||||||
cfg: CfgExpr,
|
cfg: CfgExpr,
|
||||||
opts: CfgOptions,
|
opts: CfgOptions,
|
||||||
},
|
},
|
||||||
|
@ -116,11 +117,15 @@ impl DefDiagnostic {
|
||||||
|
|
||||||
pub fn unconfigured_code(
|
pub fn unconfigured_code(
|
||||||
container: LocalModuleId,
|
container: LocalModuleId,
|
||||||
ast: ErasedAstId,
|
tree: TreeId,
|
||||||
|
item: AttrOwner,
|
||||||
cfg: CfgExpr,
|
cfg: CfgExpr,
|
||||||
opts: CfgOptions,
|
opts: CfgOptions,
|
||||||
) -> Self {
|
) -> 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(
|
pub fn unresolved_proc_macro(
|
||||||
|
|
|
@ -17,7 +17,7 @@ use triomphe::Arc;
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
|
item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
|
||||||
item_tree::Fields,
|
item_tree::FieldsShape,
|
||||||
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
|
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
|
@ -381,11 +381,11 @@ impl DefMap {
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|&variant| {
|
.find_map(|&variant| {
|
||||||
let variant_data = &tree[variant.lookup(db).id.value];
|
let variant_data = &tree[variant.lookup(db).id.value];
|
||||||
(variant_data.name == *segment).then(|| match variant_data.fields {
|
(variant_data.name == *segment).then(|| match variant_data.shape {
|
||||||
Fields::Record(_) => {
|
FieldsShape::Record => {
|
||||||
PerNs::types(variant.into(), Visibility::Public, None)
|
PerNs::types(variant.into(), Visibility::Public, None)
|
||||||
}
|
}
|
||||||
Fields::Tuple(_) | Fields::Unit => PerNs::both(
|
FieldsShape::Tuple | FieldsShape::Unit => PerNs::both(
|
||||||
variant.into(),
|
variant.into(),
|
||||||
variant.into(),
|
variant.into(),
|
||||||
Visibility::Public,
|
Visibility::Public,
|
||||||
|
|
|
@ -6,9 +6,12 @@ use la_arena::ArenaMap;
|
||||||
use syntax::{ast, AstNode, AstPtr};
|
use syntax::{ast, AstNode, AstPtr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data::adt::lower_struct, db::DefDatabase, item_tree::ItemTreeNode, trace::Trace, GenericDefId,
|
data::adt::lower_struct,
|
||||||
ItemTreeLoc, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, UseId,
|
db::DefDatabase,
|
||||||
VariantId,
|
item_tree::{FieldParent, ItemTreeNode},
|
||||||
|
trace::Trace,
|
||||||
|
GenericDefId, ItemTreeLoc, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup,
|
||||||
|
UseId, VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait HasSource {
|
pub trait HasSource {
|
||||||
|
@ -124,13 +127,13 @@ impl HasChildSource<LocalFieldId> for VariantId {
|
||||||
|
|
||||||
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
|
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
|
||||||
let item_tree;
|
let item_tree;
|
||||||
let (src, fields, container) = match *self {
|
let (src, parent, container) = match *self {
|
||||||
VariantId::EnumVariantId(it) => {
|
VariantId::EnumVariantId(it) => {
|
||||||
let lookup = it.lookup(db);
|
let lookup = it.lookup(db);
|
||||||
item_tree = lookup.id.item_tree(db);
|
item_tree = lookup.id.item_tree(db);
|
||||||
(
|
(
|
||||||
lookup.source(db).map(|it| it.kind()),
|
lookup.source(db).map(|it| it.kind()),
|
||||||
&item_tree[lookup.id.value].fields,
|
FieldParent::Variant(lookup.id.value),
|
||||||
lookup.parent.lookup(db).container,
|
lookup.parent.lookup(db).container,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -139,7 +142,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
|
||||||
item_tree = lookup.id.item_tree(db);
|
item_tree = lookup.id.item_tree(db);
|
||||||
(
|
(
|
||||||
lookup.source(db).map(|it| it.kind()),
|
lookup.source(db).map(|it| it.kind()),
|
||||||
&item_tree[lookup.id.value].fields,
|
FieldParent::Struct(lookup.id.value),
|
||||||
lookup.container,
|
lookup.container,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -148,13 +151,13 @@ impl HasChildSource<LocalFieldId> for VariantId {
|
||||||
item_tree = lookup.id.item_tree(db);
|
item_tree = lookup.id.item_tree(db);
|
||||||
(
|
(
|
||||||
lookup.source(db).map(|it| it.kind()),
|
lookup.source(db).map(|it| it.kind()),
|
||||||
&item_tree[lookup.id.value].fields,
|
FieldParent::Union(lookup.id.value),
|
||||||
lookup.container,
|
lookup.container,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut trace = Trace::new_for_map();
|
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())
|
src.with_value(trace.into_map())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -812,7 +812,9 @@ impl<'a> InferenceContext<'a> {
|
||||||
None => self.err_ty(),
|
None => self.err_ty(),
|
||||||
};
|
};
|
||||||
|
|
||||||
param_tys.push(va_list_ty)
|
if let Some(ty) = param_tys.last_mut() {
|
||||||
|
*ty = va_list_ty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
|
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 {
|
if let Some(self_param) = self.body.self_param {
|
||||||
|
|
|
@ -99,7 +99,13 @@ impl HirDisplay for Function {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Use resolved `param.ty` once we no longer discard lifetimes
|
// FIXME: Use resolved `param.ty` once we no longer discard lifetimes
|
||||||
for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) {
|
for (type_ref, param) in data
|
||||||
|
.params
|
||||||
|
.iter()
|
||||||
|
.zip(self.assoc_fn_params(db))
|
||||||
|
.take(data.params.len() - data.is_varargs() as usize)
|
||||||
|
.skip(skip_self)
|
||||||
|
{
|
||||||
let local = param.as_local(db).map(|it| it.name(db));
|
let local = param.as_local(db).map(|it| it.name(db));
|
||||||
if !first {
|
if !first {
|
||||||
f.write_str(", ")?;
|
f.write_str(", ")?;
|
||||||
|
@ -114,7 +120,10 @@ impl HirDisplay for Function {
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.is_varargs() {
|
if data.is_varargs() {
|
||||||
f.write_str(", ...")?;
|
if !first {
|
||||||
|
f.write_str(", ")?;
|
||||||
|
}
|
||||||
|
f.write_str("...")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
f.write_char(')')?;
|
f.write_char(')')?;
|
||||||
|
|
|
@ -44,7 +44,7 @@ use hir_def::{
|
||||||
data::adt::VariantData,
|
data::adt::VariantData,
|
||||||
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
|
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
|
||||||
hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat},
|
hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat},
|
||||||
item_tree::ItemTreeNode,
|
item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
|
||||||
lang_item::LangItemTarget,
|
lang_item::LangItemTarget,
|
||||||
layout::{self, ReprOptions, TargetDataLayout},
|
layout::{self, ReprOptions, TargetDataLayout},
|
||||||
nameres::{self, diagnostics::DefDiagnostic},
|
nameres::{self, diagnostics::DefDiagnostic},
|
||||||
|
@ -81,7 +81,7 @@ use rustc_hash::FxHashSet;
|
||||||
use span::{Edition, EditionedFileId, FileId, MacroCallId};
|
use span::{Edition, EditionedFileId, FileId, MacroCallId};
|
||||||
use stdx::{impl_from, never};
|
use stdx::{impl_from, never};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, HasAttrs as _, HasName},
|
ast::{self, HasAttrs as _, HasGenericParams, HasName},
|
||||||
format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, T,
|
format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, T,
|
||||||
};
|
};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
@ -906,12 +906,90 @@ fn emit_def_diagnostic_(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
|
DefDiagnosticKind::UnconfiguredCode { tree, item, cfg, opts } => {
|
||||||
let item = ast.to_ptr(db.upcast());
|
let item_tree = tree.item_tree(db.upcast());
|
||||||
acc.push(
|
let ast_id_map = db.ast_id_map(tree.file_id());
|
||||||
InactiveCode { node: ast.with_value(item), cfg: cfg.clone(), opts: opts.clone() }
|
// 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(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
Some(())
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
|
DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
|
||||||
let (node, precise_location, macro_name, kind) = precise_macro_call_location(ast, db);
|
let (node, precise_location, macro_name, kind) = precise_macro_call_location(ast, db);
|
||||||
|
|
|
@ -80,13 +80,11 @@ macro_rules! register_ast_id_node {
|
||||||
}
|
}
|
||||||
register_ast_id_node! {
|
register_ast_id_node! {
|
||||||
impl AstIdNode for
|
impl AstIdNode for
|
||||||
Item,
|
Item, AnyHasGenericParams,
|
||||||
Adt,
|
Adt,
|
||||||
Enum,
|
Enum,
|
||||||
Variant,
|
Variant,
|
||||||
Struct,
|
Struct,
|
||||||
RecordField,
|
|
||||||
TupleField,
|
|
||||||
Union,
|
Union,
|
||||||
AssocItem,
|
AssocItem,
|
||||||
Const,
|
Const,
|
||||||
|
@ -104,7 +102,7 @@ register_ast_id_node! {
|
||||||
Trait,
|
Trait,
|
||||||
TraitAlias,
|
TraitAlias,
|
||||||
Use,
|
Use,
|
||||||
BlockExpr, ConstArg, Param, SelfParam
|
BlockExpr, ConstArg
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps items' `SyntaxNode`s to `ErasedFileAstId`s and back.
|
/// Maps items' `SyntaxNode`s to `ErasedFileAstId`s and back.
|
||||||
|
|
Loading…
Reference in a new issue