2
0
Fork 0
mirror of https://github.com/rust-lang/rust-analyzer synced 2025-02-13 04:33:28 +00:00

Merge pull request from davidbarsky/davidbarsky/backout-struct-default-fields

internal: backout `hir-*` changes from 
This commit is contained in:
David Barsky 2025-01-28 16:45:45 +00:00 committed by GitHub
commit bc10a44798
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 78 additions and 625 deletions

View file

@ -85,7 +85,6 @@ pub struct FieldData {
pub name: Name,
pub type_ref: TypeRefId,
pub visibility: RawVisibility,
pub has_default: bool,
}
fn repr_from_value(
@ -479,6 +478,5 @@ fn lower_field(
name: field.name.clone(),
type_ref: field.type_ref,
visibility: item_tree[override_visibility.unwrap_or(field.visibility)].clone(),
has_default: field.has_default,
}
}

View file

@ -25,7 +25,7 @@ use crate::{
db::DefDatabase,
hir::{
Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat,
PatId, RecordFieldPat, Spread, Statement,
PatId, RecordFieldPat, Statement,
},
nameres::DefMap,
path::{ModPath, Path},
@ -362,7 +362,7 @@ impl ExpressionStore {
for field in fields.iter() {
f(field.expr);
}
if let &Spread::Base(expr) = spread {
if let &Some(expr) = spread {
f(expr);
}
}
@ -490,7 +490,7 @@ impl ExpressionStore {
for field in fields.iter() {
f(field.expr);
}
if let &Spread::Base(expr) = spread {
if let &Some(expr) = spread {
f(expr);
}
}

View file

@ -122,9 +122,6 @@ impl Body {
src.map(|it| it.expr())
}
DefWithBodyId::InTypeConstId(c) => c.lookup(db).id.map(|_| c.source(db).expr()),
DefWithBodyId::FieldId(f) => {
f.record_field_source(db).map(|it| it.and_then(|it| it.expr()))
}
}
};
let module = def.module(db);

View file

@ -45,7 +45,7 @@ use crate::{
},
Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind,
Expr, ExprId, Item, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability,
OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Spread, Statement,
OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
},
item_scope::BuiltinShadowMode,
lang_item::LangItem,
@ -90,7 +90,6 @@ pub(super) fn lower_body(
DefWithBodyId::ConstId(it) => db.attrs(it.into()),
DefWithBodyId::InTypeConstId(_) => Attrs::EMPTY,
DefWithBodyId::VariantId(it) => db.attrs(it.into()),
DefWithBodyId::FieldId(it) => db.attrs(it.into()),
}
.rust_analyzer_tool()
.any(|attr| *attr.path() == tool_path![skip]);
@ -169,7 +168,6 @@ pub(super) fn lower_body(
Awaitable::No("constant")
}
DefWithBodyId::VariantId(..) => Awaitable::No("enum variant"),
DefWithBodyId::FieldId(..) => Awaitable::No("field"),
}
},
);
@ -602,13 +600,10 @@ impl ExprCollector<'_> {
Some(RecordLitField { name, expr })
})
.collect();
let spread = nfl.spread().map(|s| self.collect_expr(s)).map_or_else(
|| if nfl.dotdot_token().is_some() { Spread::Yes } else { Spread::No },
Spread::Base,
);
let spread = nfl.spread().map(|s| self.collect_expr(s));
Expr::RecordLit { path, fields, spread }
} else {
Expr::RecordLit { path, fields: Box::default(), spread: Spread::No }
Expr::RecordLit { path, fields: Box::default(), spread: None }
};
self.alloc_expr(record_lit, syntax_ptr)

View file

@ -8,10 +8,9 @@ use span::Edition;
use crate::{
hir::{
Array, BindingAnnotation, CaptureBy, ClosureKind, Literal, LiteralOrConst, Movability,
Spread, Statement,
Statement,
},
pretty::{print_generic_args, print_path, print_type_ref},
VariantId,
};
use super::*;
@ -57,32 +56,6 @@ pub(super) fn print_body_hir(
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast(), edition),
)
}
DefWithBodyId::FieldId(it) => {
let parent_name: String = match it.parent {
VariantId::EnumVariantId(it) => {
let loc = it.lookup(db);
let enum_loc = loc.parent.lookup(db);
format!(
"{}::{}",
enum_loc.id.item_tree(db)[enum_loc.id.value]
.name
.display(db.upcast(), edition),
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast(), edition),
)
}
VariantId::StructId(it) => it
.lookup(db)
.id
.resolved(db, |it| it.name.display(db.upcast(), edition).to_string()),
VariantId::UnionId(it) => it
.lookup(db)
.id
.resolved(db, |it| it.name.display(db.upcast(), edition).to_string()),
};
let variant_data = it.parent.variant_data(db);
let field_name = &variant_data.fields()[it.local_id].name;
format!("field {}.{}", parent_name, field_name.display(db.upcast(), edition),)
}
};
let mut p = Printer {
@ -412,16 +385,10 @@ impl Printer<'_> {
p.print_expr(field.expr);
wln!(p, ",");
}
match spread {
Spread::No => {}
Spread::Yes => {
w!(p, "..");
}
Spread::Base(expr) => {
w!(p, "..");
p.print_expr(*expr);
wln!(p);
}
if let Some(spread) = spread {
w!(p, "..");
p.print_expr(*spread);
wln!(p);
}
});
w!(self, "}}");

View file

@ -251,7 +251,7 @@ pub enum Expr {
RecordLit {
path: Option<Box<Path>>,
fields: Box<[RecordLitField]>,
spread: Spread,
spread: Option<ExprId>,
},
Field {
expr: ExprId,
@ -478,13 +478,6 @@ pub struct RecordLitField {
pub expr: ExprId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Spread {
No,
Yes,
Base(ExprId),
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Statement {
Let {

View file

@ -1007,7 +1007,6 @@ pub struct Field {
pub name: Name,
pub type_ref: TypeRefId,
pub visibility: RawVisibilityId,
pub has_default: bool,
}
#[derive(Debug, Clone, Eq, PartialEq)]

View file

@ -319,9 +319,8 @@ impl<'a> Ctx<'a> {
};
let visibility = self.lower_visibility(field);
let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty());
let has_default = field.expr().is_some();
Field { name, type_ref, visibility, has_default }
Field { name, type_ref, visibility }
}
fn lower_tuple_field(
@ -333,7 +332,7 @@ impl<'a> Ctx<'a> {
let name = Name::new_tuple_field(idx);
let visibility = self.lower_visibility(field);
let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty());
Field { name, type_ref, visibility, has_default: false }
Field { name, type_ref, visibility }
}
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {

View file

@ -135,9 +135,7 @@ impl Printer<'_> {
self.whitespace();
w!(self, "{{");
self.indented(|this| {
for (idx, Field { name, type_ref, visibility, has_default: _ }) in
fields.iter().enumerate()
{
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",
@ -153,9 +151,7 @@ impl Printer<'_> {
FieldsShape::Tuple => {
w!(self, "(");
self.indented(|this| {
for (idx, Field { name, type_ref, visibility, has_default: _ }) in
fields.iter().enumerate()
{
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",

View file

@ -55,7 +55,6 @@ pub mod visibility;
use intern::Interned;
pub use rustc_abi as layout;
use src::HasSource;
use triomphe::Arc;
#[cfg(test)]
@ -78,7 +77,6 @@ use hir_expand::{
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
db::ExpandDatabase,
eager::expand_eager_macro_input,
files::InFileWrapper,
impl_intern_lookup,
name::Name,
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
@ -521,41 +519,6 @@ pub struct FieldId {
pub local_id: LocalFieldId,
}
impl FieldId {
pub fn record_field_source(
&self,
db: &dyn DefDatabase,
) -> InFileWrapper<HirFileId, Option<ast::RecordField>> {
let field_list = match self.parent {
crate::VariantId::EnumVariantId(it) => {
let s = it.lookup(db);
s.source(db).map(|it| {
it.field_list().and_then(|it| match it {
ast::FieldList::RecordFieldList(it) => Some(it),
_ => None,
})
})
}
crate::VariantId::StructId(it) => {
let s = it.lookup(db);
s.source(db).map(|it| {
it.field_list().and_then(|it| match it {
ast::FieldList::RecordFieldList(it) => Some(it),
_ => None,
})
})
}
crate::VariantId::UnionId(it) => {
let s = it.lookup(db);
s.source(db).map(|it| it.record_field_list())
}
};
field_list.map(|it| {
it.and_then(|it| it.fields().nth(self.local_id.into_raw().into_u32() as usize))
})
}
}
pub type LocalFieldId = Idx<data::adt::FieldData>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -723,7 +686,6 @@ pub enum TypeOwnerId {
TypeAliasId(TypeAliasId),
ImplId(ImplId),
EnumVariantId(EnumVariantId),
FieldId(FieldId),
}
impl TypeOwnerId {
@ -741,11 +703,6 @@ impl TypeOwnerId {
GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
}
TypeOwnerId::InTypeConstId(_) => return None,
TypeOwnerId::FieldId(it) => GenericDefId::AdtId(match it.parent {
VariantId::EnumVariantId(it) => AdtId::EnumId(it.lookup(db).parent),
VariantId::StructId(it) => it.into(),
VariantId::UnionId(it) => it.into(),
}),
})
}
}
@ -760,8 +717,7 @@ impl_from!(
TraitAliasId,
TypeAliasId,
ImplId,
EnumVariantId,
FieldId
EnumVariantId
for TypeOwnerId
);
@ -774,7 +730,6 @@ impl From<DefWithBodyId> for TypeOwnerId {
DefWithBodyId::ConstId(it) => it.into(),
DefWithBodyId::InTypeConstId(it) => it.into(),
DefWithBodyId::VariantId(it) => it.into(),
DefWithBodyId::FieldId(it) => it.into(),
}
}
}
@ -930,7 +885,6 @@ pub enum DefWithBodyId {
ConstId(ConstId),
InTypeConstId(InTypeConstId),
VariantId(EnumVariantId),
FieldId(FieldId),
}
impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId);
@ -951,7 +905,6 @@ impl DefWithBodyId {
// FIXME: stable rust doesn't allow generics in constants, but we should
// use `TypeOwnerId::as_generic_def_id` when it does.
DefWithBodyId::InTypeConstId(_) => None,
DefWithBodyId::FieldId(_) => None,
}
}
}
@ -1356,12 +1309,6 @@ impl HasModule for VariantId {
}
}
impl HasModule for FieldId {
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
self.parent.module(db)
}
}
impl HasModule for MacroId {
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
match *self {
@ -1385,7 +1332,6 @@ impl HasModule for TypeOwnerId {
TypeOwnerId::ImplId(it) => it.module(db),
TypeOwnerId::EnumVariantId(it) => it.module(db),
TypeOwnerId::InTypeConstId(it) => it.lookup(db).owner.module(db),
TypeOwnerId::FieldId(it) => it.module(db),
}
}
}
@ -1398,7 +1344,6 @@ impl HasModule for DefWithBodyId {
DefWithBodyId::ConstId(it) => it.module(db),
DefWithBodyId::VariantId(it) => it.module(db),
DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
DefWithBodyId::FieldId(it) => it.module(db),
}
}
}

View file

@ -211,20 +211,6 @@ enum Bar {
#[default]
Bar,
}
#[derive(Default)]
struct Baz {
field1: i32 = 2,
field2: bool = { false },
}
#[derive(Default)]
enum Qux {
#[default]
Foo {
field1: i32,
field2: bool = true,
field3: (),
}
}
"#,
expect![[r#"
#[derive(Default)]
@ -238,20 +224,6 @@ enum Bar {
#[default]
Bar,
}
#[derive(Default)]
struct Baz {
field1: i32 = 2,
field2: bool = { false },
}
#[derive(Default)]
enum Qux {
#[default]
Foo {
field1: i32,
field2: bool = true,
field3: (),
}
}
impl <> $crate::default::Default for Foo< > where {
fn default() -> Self {
@ -264,20 +236,6 @@ impl <> $crate::default::Default for Bar< > where {
fn default() -> Self {
Bar::Bar
}
}
impl <> $crate::default::Default for Baz< > where {
fn default() -> Self {
Baz {
..
}
}
}
impl <> $crate::default::Default for Qux< > where {
fn default() -> Self {
Qux::Foo {
field1: $crate::default::Default::default(), field3: $crate::default::Default::default(), ..
}
}
}"#]],
);
}

View file

@ -27,11 +27,10 @@ use crate::{
type_ref::{LifetimeRef, TypesMap},
visibility::{RawVisibility, Visibility},
AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
ExternBlockId, ExternCrateId, FieldId, FunctionId, FxIndexMap, GenericDefId, GenericParamId,
HasModule, ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup,
Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId,
TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId,
VariantId,
ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule,
ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id,
MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId,
TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
};
#[derive(Debug, Clone)]
@ -1228,7 +1227,6 @@ impl HasResolver for TypeOwnerId {
TypeOwnerId::TypeAliasId(it) => it.resolver(db),
TypeOwnerId::ImplId(it) => it.resolver(db),
TypeOwnerId::EnumVariantId(it) => it.resolver(db),
TypeOwnerId::FieldId(it) => it.resolver(db),
}
}
}
@ -1241,7 +1239,6 @@ impl HasResolver for DefWithBodyId {
DefWithBodyId::StaticId(s) => s.resolver(db),
DefWithBodyId::VariantId(v) => v.resolver(db),
DefWithBodyId::InTypeConstId(c) => c.lookup(db).owner.resolver(db),
DefWithBodyId::FieldId(f) => f.resolver(db),
}
}
}
@ -1288,12 +1285,6 @@ impl HasResolver for VariantId {
}
}
impl HasResolver for FieldId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
self.parent.resolver(db)
}
}
impl HasResolver for MacroId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
match self {

View file

@ -80,15 +80,9 @@ pub fn find_builtin_derive(ident: &name::Name) -> Option<BuiltinDeriveExpander>
BuiltinDeriveExpander::find_by_name(ident)
}
#[derive(Clone, Copy)]
enum HasDefault {
Yes,
No,
}
#[derive(Clone)]
enum VariantShape {
Struct(Vec<(tt::Ident, HasDefault)>),
Struct(Vec<tt::Ident>),
Tuple(usize),
Unit,
}
@ -104,7 +98,7 @@ impl VariantShape {
fn field_names(&self, span: Span) -> Vec<tt::Ident> {
match self {
VariantShape::Struct(s) => s.iter().map(|(ident, _)| ident.clone()).collect(),
VariantShape::Struct(s) => s.clone(),
VariantShape::Tuple(n) => tuple_field_iterator(span, *n).collect(),
VariantShape::Unit => vec![],
}
@ -118,7 +112,7 @@ impl VariantShape {
) -> tt::TopSubtree {
match self {
VariantShape::Struct(fields) => {
let fields = fields.iter().map(|(it, _)| {
let fields = fields.iter().map(|it| {
let mapped = field_map(it);
quote! {span => #it : #mapped , }
});
@ -141,63 +135,6 @@ impl VariantShape {
}
}
fn default_expand(
&self,
path: tt::TopSubtree,
span: Span,
field_map: impl Fn(&tt::Ident) -> tt::TopSubtree,
) -> tt::TopSubtree {
match self {
VariantShape::Struct(fields) => {
let contains_default = fields.iter().any(|it| matches!(it.1, HasDefault::Yes));
let fields = fields
.iter()
.filter_map(|(it, has_default)| match has_default {
HasDefault::Yes => None,
HasDefault::No => Some(it),
})
.map(|it| {
let mapped = field_map(it);
quote! {span => #it : #mapped , }
});
if contains_default {
let mut double_dots =
tt::TopSubtreeBuilder::new(tt::Delimiter::invisible_spanned(span));
double_dots.push(tt::Leaf::Punct(tt::Punct {
char: '.',
spacing: tt::Spacing::Joint,
span,
}));
double_dots.push(tt::Leaf::Punct(tt::Punct {
char: '.',
spacing: tt::Spacing::Alone,
span,
}));
let double_dots = double_dots.build();
quote! {span =>
#path { ##fields #double_dots }
}
} else {
quote! {span =>
#path { ##fields }
}
}
}
&VariantShape::Tuple(n) => {
let fields = tuple_field_iterator(span, n).map(|it| {
let mapped = field_map(&it);
quote! {span =>
#mapped ,
}
});
quote! {span =>
#path ( ##fields )
}
}
VariantShape::Unit => path,
}
}
fn from(
call_site: Span,
tm: &ExpansionSpanMap,
@ -207,15 +144,8 @@ impl VariantShape {
None => VariantShape::Unit,
Some(FieldList::RecordFieldList(it)) => VariantShape::Struct(
it.fields()
.map(|it| {
(
it.name(),
if it.expr().is_some() { HasDefault::Yes } else { HasDefault::No },
)
})
.map(|(it, has_default)| {
name_to_token(call_site, tm, it).map(|ident| (ident, has_default))
})
.map(|it| it.name())
.map(|it| name_to_token(call_site, tm, it))
.collect::<Result<_, _>>()?,
),
Some(FieldList::TupleFieldList(it)) => VariantShape::Tuple(it.fields().count()),
@ -671,7 +601,7 @@ fn default_expand(
let body = match &adt.shape {
AdtShape::Struct(fields) => {
let name = &adt.name;
fields.default_expand(
fields.as_pattern_map(
quote!(span =>#name),
span,
|_| quote!(span =>#krate::default::Default::default()),
@ -681,7 +611,7 @@ fn default_expand(
if let Some(d) = default_variant {
let (name, fields) = &variants[*d];
let adt_name = &adt.name;
fields.default_expand(
fields.as_pattern_map(
quote!(span =>#adt_name :: #name),
span,
|_| quote!(span =>#krate::default::Default::default()),
@ -713,7 +643,7 @@ fn debug_expand(
expand_simple_derive(db, span, tt, quote! {span => #krate::fmt::Debug }, |adt| {
let for_variant = |name: String, v: &VariantShape| match v {
VariantShape::Struct(fields) => {
let for_fields = fields.iter().map(|(it, _)| {
let for_fields = fields.iter().map(|it| {
let x_string = it.to_string();
quote! {span =>
.field(#x_string, & #it)

View file

@ -8,7 +8,6 @@ use base_db::CrateId;
use chalk_solve::rust_ir::AdtKind;
use either::Either;
use hir_def::{
hir::Spread,
lang_item::LangItem,
resolver::{HasResolver, ValueNs},
AdtId, AssocItemId, DefWithBodyId, HasModule, ItemContainerId, Lookup,
@ -547,11 +546,9 @@ pub fn record_literal_missing_fields(
infer: &InferenceResult,
id: ExprId,
expr: &Expr,
) -> Option<(VariantId, Vec<LocalFieldId>, /*has spread expr*/ bool)> {
let (fields, has_spread_expr, has_ellipsis) = match expr {
Expr::RecordLit { fields, spread, .. } => {
(fields, !matches!(spread, Spread::Base(_)), matches!(spread, Spread::Yes))
}
) -> Option<(VariantId, Vec<LocalFieldId>, /*exhaustive*/ bool)> {
let (fields, exhaustive) = match expr {
Expr::RecordLit { fields, spread, .. } => (fields, spread.is_none()),
_ => return None,
};
@ -566,18 +563,12 @@ pub fn record_literal_missing_fields(
let missed_fields: Vec<LocalFieldId> = variant_data
.fields()
.iter()
.filter_map(|(f, d)| {
if (has_ellipsis && d.has_default) || specified_fields.contains(&d.name) {
None
} else {
Some(f)
}
})
.filter_map(|(f, d)| if specified_fields.contains(&d.name) { None } else { Some(f) })
.collect();
if missed_fields.is_empty() {
return None;
}
Some((variant_def, missed_fields, has_spread_expr))
Some((variant_def, missed_fields, exhaustive))
}
pub fn record_pattern_missing_fields(

View file

@ -35,8 +35,7 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe
DefWithBodyId::StaticId(_)
| DefWithBodyId::ConstId(_)
| DefWithBodyId::VariantId(_)
| DefWithBodyId::InTypeConstId(_)
| DefWithBodyId::FieldId(_) => false,
| DefWithBodyId::InTypeConstId(_) => false,
};
let mut res = MissingUnsafeResult { fn_is_unsafe: is_unsafe, ..MissingUnsafeResult::default() };

View file

@ -134,9 +134,6 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
.unwrap()
.0;
}
DefWithBodyId::FieldId(f) => {
ctx.collect_field(f);
}
}
ctx.infer_body();
@ -913,19 +910,6 @@ impl<'a> InferenceContext<'a> {
self.return_ty = return_ty;
}
fn collect_field(&mut self, field: FieldId) {
let variant_data = field.parent.variant_data(self.db.upcast());
let field_data = &variant_data.fields()[field.local_id];
let types_map = variant_data.types_map();
let return_ty =
self.make_ty(field_data.type_ref, types_map, InferenceTyDiagnosticSource::Signature);
// Field default value exprs might be defining usage sites of TAITs.
self.make_tait_coercion_table(iter::once(&return_ty));
self.return_ty = return_ty;
}
fn collect_fn(&mut self, func: FunctionId) {
let data = self.db.function_data(func);
let mut param_tys =

View file

@ -12,7 +12,7 @@ use hir_def::{
data::adt::VariantData,
hir::{
Array, AsmOperand, BinaryOp, BindingId, CaptureBy, Expr, ExprId, ExprOrPatId, Pat, PatId,
Spread, Statement, UnaryOp,
Statement, UnaryOp,
},
lang_item::LangItem,
path::Path,
@ -796,7 +796,7 @@ impl InferenceContext<'_> {
self.consume_expr(expr);
}
Expr::RecordLit { fields, spread, .. } => {
if let &Spread::Base(expr) = spread {
if let &Some(expr) = spread {
self.consume_expr(expr);
}
self.consume_exprs(fields.iter().map(|it| it.expr));

View file

@ -10,7 +10,7 @@ use either::Either;
use hir_def::{
hir::{
ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, ClosureKind, Expr, ExprId, ExprOrPatId,
LabelId, Literal, Pat, PatId, Spread, Statement, UnaryOp,
LabelId, Literal, Pat, PatId, Statement, UnaryOp,
},
lang_item::{LangItem, LangItemTarget},
path::{GenericArg, GenericArgs, Path},
@ -775,7 +775,7 @@ impl InferenceContext<'_> {
}
}
}
if let Spread::Base(expr) = spread {
if let Some(expr) = spread {
self.infer_expr(*expr, &Expectation::has_type(ty.clone()), ExprIsRead::Yes);
}
ty
@ -1746,14 +1746,12 @@ impl InferenceContext<'_> {
});
}
TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
let vd = &self.db.struct_data(*s).variant_data;
let local_id = vd.field(name)?;
let local_id = self.db.struct_data(*s).variant_data.field(name)?;
let field = FieldId { parent: (*s).into(), local_id };
(field, parameters.clone())
}
TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
let vd = &self.db.union_data(*u).variant_data;
let local_id = vd.field(name)?;
let local_id = self.db.union_data(*u).variant_data.field(name)?;
let field = FieldId { parent: (*u).into(), local_id };
(field, parameters.clone())
}

View file

@ -4,8 +4,8 @@
use chalk_ir::{cast::Cast, Mutability};
use hir_def::{
hir::{
Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, Pat, PatId, Spread,
Statement, UnaryOp,
Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, Pat, PatId, Statement,
UnaryOp,
},
lang_item::LangItem,
};
@ -122,11 +122,7 @@ impl InferenceContext<'_> {
self.infer_mut_expr(*expr, Mutability::Not);
}
Expr::RecordLit { path: _, fields, spread } => {
let spread_expr = match spread {
Spread::Base(expr) => Some(*expr),
_ => None,
};
self.infer_mut_not_expr_iter(fields.iter().map(|it| it.expr).chain(spread_expr))
self.infer_mut_not_expr_iter(fields.iter().map(|it| it.expr).chain(*spread))
}
&Expr::Index { base, index } => {
if mutability == Mutability::Mut {

View file

@ -9,7 +9,7 @@ use hir_def::{
expr_store::{Body, HygieneId},
hir::{
ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal,
LiteralOrConst, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, Spread,
LiteralOrConst, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField,
},
lang_item::{LangItem, LangItemTarget},
path::Path,
@ -825,14 +825,14 @@ impl<'ctx> MirLowerCtx<'ctx> {
Expr::Yield { .. } => not_supported!("yield"),
Expr::RecordLit { fields, path, spread } => {
let spread_place = match spread {
&Spread::Base(it) => {
&Some(it) => {
let Some((p, c)) = self.lower_expr_as_place(current, it, true)? else {
return Ok(None);
};
current = c;
Some(p)
}
_ => None,
None => None,
};
let variant_id =
self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path {
@ -870,12 +870,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
.map(|(i, it)| match it {
Some(it) => it,
None => {
let local_id =
LocalFieldId::from_raw(RawIdx::from(i as u32));
let p = sp.project(
ProjectionElem::Field(Either::Left(FieldId {
parent: variant_id,
local_id,
local_id: LocalFieldId::from_raw(RawIdx::from(
i as u32,
)),
})),
&mut self.result.projection_store,
);
@ -2130,10 +2130,6 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi
db.enum_variant_data(it).name.display(db.upcast(), edition).to_string()
}
DefWithBodyId::InTypeConstId(it) => format!("in type const {it:?}"),
DefWithBodyId::FieldId(it) => it.parent.variant_data(db.upcast()).fields()[it.local_id]
.name
.display(db.upcast(), edition)
.to_string(),
};
let _p = tracing::info_span!("mir_body_query", ?detail).entered();
let body = db.body(def);

View file

@ -6,7 +6,7 @@ use std::{
};
use either::Either;
use hir_def::{expr_store::Body, hir::BindingId, VariantId};
use hir_def::{expr_store::Body, hir::BindingId};
use hir_expand::{name::Name, Lookup};
use la_arena::ArenaMap;
use span::Edition;
@ -79,38 +79,6 @@ impl MirBody {
hir_def::DefWithBodyId::InTypeConstId(id) => {
w!(this, "in type const {id:?} = ");
}
hir_def::DefWithBodyId::FieldId(id) => {
w!(this, "field ");
match id.parent {
VariantId::EnumVariantId(it) => {
let loc = it.lookup(db.upcast());
let enum_loc = loc.parent.lookup(db.upcast());
w!(
this,
"{}::{}",
enum_loc.id.item_tree(db.upcast())[enum_loc.id.value]
.name
.display(db.upcast(), Edition::LATEST),
loc.id.item_tree(db.upcast())[loc.id.value]
.name
.display(db.upcast(), Edition::LATEST),
);
}
VariantId::StructId(id) => {
id.lookup(db.upcast()).id.resolved(db.upcast(), |it| {
w!(this, "{}", it.name.display(db.upcast(), Edition::LATEST));
});
}
VariantId::UnionId(id) => {
id.lookup(db.upcast()).id.resolved(db.upcast(), |it| {
w!(this, "{}", it.name.display(db.upcast(), Edition::LATEST));
});
}
};
let variant_data = id.parent.variant_data(db.upcast());
let field_name = &variant_data.fields()[id.local_id].name;
w!(this, ".{}: _ = ", field_name.display(db.upcast(), Edition::LATEST));
}
});
ctx.result
}

View file

@ -16,7 +16,6 @@ use std::env;
use std::sync::LazyLock;
use base_db::SourceDatabaseFileInputExt as _;
use either::Either;
use expect_test::Expect;
use hir_def::{
db::DefDatabase,
@ -24,14 +23,12 @@ use hir_def::{
hir::{ExprId, Pat, PatId},
item_scope::ItemScope,
nameres::DefMap,
src::{HasChildSource, HasSource},
AdtId, AssocItemId, DefWithBodyId, FieldId, HasModule, LocalModuleId, Lookup, ModuleDefId,
SyntheticSyntax,
src::HasSource,
AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId, SyntheticSyntax,
};
use hir_expand::{db::ExpandDatabase, FileRange, InFile};
use itertools::Itertools;
use rustc_hash::FxHashMap;
use span::TextSize;
use stdx::format_to;
use syntax::{
ast::{self, AstNode, HasName},
@ -135,40 +132,14 @@ fn check_impl(
None => continue,
};
let def_map = module.def_map(&db);
visit_module(&db, &def_map, module.local_id, &mut |it| match it {
ModuleDefId::FunctionId(it) => defs.push(it.into()),
ModuleDefId::EnumVariantId(it) => {
defs.push(it.into());
let variant_id = it.into();
let vd = db.variant_data(variant_id);
defs.extend(vd.fields().iter().filter_map(|(local_id, fd)| {
if fd.has_default {
let field = FieldId { parent: variant_id, local_id };
Some(DefWithBodyId::FieldId(field))
} else {
None
}
}));
}
ModuleDefId::ConstId(it) => defs.push(it.into()),
ModuleDefId::StaticId(it) => defs.push(it.into()),
ModuleDefId::AdtId(it) => {
let variant_id = match it {
AdtId::StructId(it) => it.into(),
AdtId::UnionId(it) => it.into(),
AdtId::EnumId(_) => return,
};
let vd = db.variant_data(variant_id);
defs.extend(vd.fields().iter().filter_map(|(local_id, fd)| {
if fd.has_default {
let field = FieldId { parent: variant_id, local_id };
Some(DefWithBodyId::FieldId(field))
} else {
None
}
}));
}
_ => {}
visit_module(&db, &def_map, module.local_id, &mut |it| {
defs.push(match it {
ModuleDefId::FunctionId(it) => it.into(),
ModuleDefId::EnumVariantId(it) => it.into(),
ModuleDefId::ConstId(it) => it.into(),
ModuleDefId::StaticId(it) => it.into(),
_ => return,
})
});
}
defs.sort_by_key(|def| match def {
@ -189,14 +160,6 @@ fn check_impl(
loc.source(&db).value.syntax().text_range().start()
}
DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(),
DefWithBodyId::FieldId(it) => {
let cs = it.parent.child_source(&db);
match cs.value.get(it.local_id) {
Some(Either::Left(it)) => it.syntax().text_range().start(),
Some(Either::Right(it)) => it.syntax().text_range().end(),
None => TextSize::new(u32::MAX),
}
}
});
let mut unexpected_type_mismatches = String::new();
for def in defs {
@ -425,40 +388,14 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
let def_map = module.def_map(&db);
let mut defs: Vec<DefWithBodyId> = Vec::new();
visit_module(&db, &def_map, module.local_id, &mut |it| match it {
ModuleDefId::FunctionId(it) => defs.push(it.into()),
ModuleDefId::EnumVariantId(it) => {
defs.push(it.into());
let variant_id = it.into();
let vd = db.variant_data(variant_id);
defs.extend(vd.fields().iter().filter_map(|(local_id, fd)| {
if fd.has_default {
let field = FieldId { parent: variant_id, local_id };
Some(DefWithBodyId::FieldId(field))
} else {
None
}
}));
}
ModuleDefId::ConstId(it) => defs.push(it.into()),
ModuleDefId::StaticId(it) => defs.push(it.into()),
ModuleDefId::AdtId(it) => {
let variant_id = match it {
AdtId::StructId(it) => it.into(),
AdtId::UnionId(it) => it.into(),
AdtId::EnumId(_) => return,
};
let vd = db.variant_data(variant_id);
defs.extend(vd.fields().iter().filter_map(|(local_id, fd)| {
if fd.has_default {
let field = FieldId { parent: variant_id, local_id };
Some(DefWithBodyId::FieldId(field))
} else {
None
}
}));
}
_ => {}
visit_module(&db, &def_map, module.local_id, &mut |it| {
defs.push(match it {
ModuleDefId::FunctionId(it) => it.into(),
ModuleDefId::EnumVariantId(it) => it.into(),
ModuleDefId::ConstId(it) => it.into(),
ModuleDefId::StaticId(it) => it.into(),
_ => return,
})
});
defs.sort_by_key(|def| match def {
DefWithBodyId::FunctionId(it) => {
@ -478,14 +415,6 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
loc.source(&db).value.syntax().text_range().start()
}
DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(),
DefWithBodyId::FieldId(it) => {
let cs = it.parent.child_source(&db);
match cs.value.get(it.local_id) {
Some(Either::Left(it)) => it.syntax().text_range().start(),
Some(Either::Right(it)) => it.syntax().text_range().end(),
None => TextSize::new(u32::MAX),
}
}
});
for def in defs {
let (body, source_map) = db.body_with_source_map(def);
@ -546,7 +475,7 @@ pub(crate) fn visit_module(
let body = db.body(it.into());
visit_body(db, &body, cb);
}
ModuleDefId::AdtId(AdtId::EnumId(it)) => {
ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => {
db.enum_data(it).variants.iter().for_each(|&(it, _)| {
let body = db.body(it.into());
cb(it.into());

View file

@ -157,53 +157,5 @@ static ALIAS: i32 = {
217..218 '5': i32
205..211: expected impl Trait + ?Sized, got Struct
"#]],
);
}
#[test]
fn defining_type_alias_impl_trait_from_default_fields() {
check_no_mismatches(
r#"
trait Trait {}
struct Struct;
impl Trait for Struct {}
type AliasTy = impl Trait;
struct Foo {
foo: AliasTy = {
let x: AliasTy = Struct;
x
},
}
"#,
);
check_infer_with_mismatches(
r#"
trait Trait {}
struct Struct;
impl Trait for Struct {}
type AliasTy = impl Trait;
struct Foo {
foo: i32 = {
let x: AliasTy = Struct;
5
},
}
"#,
expect![[r#"
114..164 '{ ... }': i32
128..129 'x': impl Trait + ?Sized
141..147 'Struct': Struct
157..158 '5': i32
141..147: expected impl Trait + ?Sized, got Struct
"#]],
);
)
}

View file

@ -147,7 +147,6 @@ impl From<DefWithBody> for DefWithBodyId {
DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id),
DefWithBody::Variant(it) => DefWithBodyId::VariantId(it.into()),
DefWithBody::InTypeConst(it) => DefWithBodyId::InTypeConstId(it.id),
DefWithBody::Field(it) => DefWithBodyId::FieldId(it.into()),
}
}
}
@ -160,7 +159,6 @@ impl From<DefWithBodyId> for DefWithBody {
DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()),
DefWithBodyId::VariantId(it) => DefWithBody::Variant(it.into()),
DefWithBodyId::InTypeConstId(it) => DefWithBody::InTypeConst(it.into()),
DefWithBodyId::FieldId(it) => DefWithBody::Field(it.into()),
}
}
}

View file

@ -415,28 +415,6 @@ impl ModuleDef {
def.diagnostics(db, &mut acc);
}
let vd: Option<(VariantDef, Arc<VariantData>)> = match self {
ModuleDef::Adt(Adt::Struct(it)) => {
Some((it.into(), db.struct_data(it.id).variant_data.clone()))
}
ModuleDef::Adt(Adt::Union(it)) => {
Some((it.into(), db.union_data(it.id).variant_data.clone()))
}
ModuleDef::Variant(it) => {
Some((it.into(), db.enum_variant_data(it.id).variant_data.clone()))
}
_ => None,
};
if let Some((parent, vd)) = vd {
for (id, fd) in vd.fields().iter() {
if !fd.has_default {
continue;
}
let def: DefWithBody = DefWithBody::Field(Field { parent, id });
def.diagnostics(db, &mut acc, style_lints);
}
}
acc
}
@ -1248,12 +1226,6 @@ impl HasVisibility for Module {
}
}
impl From<&Field> for DefWithBodyId {
fn from(&f: &Field) -> Self {
DefWithBodyId::FieldId(f.into())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Field {
pub(crate) parent: VariantDef,
@ -1319,10 +1291,6 @@ impl AstNode for FieldSource {
}
impl Field {
pub fn module(self, db: &dyn HirDatabase) -> Module {
self.parent.module(db)
}
pub fn name(&self, db: &dyn HirDatabase) -> Name {
self.parent.variant_data(db).fields()[self.id].name.clone()
}
@ -1385,14 +1353,6 @@ impl Field {
pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
self.parent
}
pub fn default_value_source(
&self,
db: &dyn HirDatabase,
) -> Option<InFileWrapper<HirFileId, ast::Expr>> {
let id: hir_def::FieldId = (*self).into();
id.record_field_source(db.upcast()).map(|it| it.and_then(|it| it.expr())).transpose()
}
}
impl HasVisibility for Field {
@ -1829,9 +1789,8 @@ pub enum DefWithBody {
Const(Const),
Variant(Variant),
InTypeConst(InTypeConst),
Field(Field),
}
impl_from!(Function, Const, Static, Variant, InTypeConst, Field for DefWithBody);
impl_from!(Function, Const, Static, Variant, InTypeConst for DefWithBody);
impl DefWithBody {
pub fn module(self, db: &dyn HirDatabase) -> Module {
@ -1841,7 +1800,6 @@ impl DefWithBody {
DefWithBody::Static(s) => s.module(db),
DefWithBody::Variant(v) => v.module(db),
DefWithBody::InTypeConst(c) => c.module(db),
DefWithBody::Field(f) => f.module(db),
}
}
@ -1852,7 +1810,6 @@ impl DefWithBody {
DefWithBody::Const(c) => c.name(db),
DefWithBody::Variant(v) => Some(v.name(db)),
DefWithBody::InTypeConst(_) => None,
DefWithBody::Field(f) => Some(f.name(db)),
}
}
@ -1868,7 +1825,6 @@ impl DefWithBody {
&DefWithBodyId::from(it.id).resolver(db.upcast()),
TyKind::Error.intern(Interner),
),
DefWithBody::Field(it) => it.ty(db),
}
}
@ -1879,7 +1835,6 @@ impl DefWithBody {
DefWithBody::Const(it) => it.id.into(),
DefWithBody::Variant(it) => it.into(),
DefWithBody::InTypeConst(it) => it.id.into(),
DefWithBody::Field(it) => it.into(),
}
}
@ -1925,23 +1880,6 @@ impl DefWithBody {
item_tree_source_maps.konst(konst.value)
}
DefWithBody::Variant(_) | DefWithBody::InTypeConst(_) => &TypesSourceMap::EMPTY,
DefWithBody::Field(field) => match field.parent {
VariantDef::Struct(strukt) => {
let strukt = strukt.id.lookup(db.upcast()).id;
item_tree_source_maps = strukt.item_tree_with_source_map(db.upcast()).1;
item_tree_source_maps.strukt(strukt.value).item()
}
VariantDef::Union(union) => {
let union = union.id.lookup(db.upcast()).id;
item_tree_source_maps = union.item_tree_with_source_map(db.upcast()).1;
item_tree_source_maps.union(union.value).item()
}
VariantDef::Variant(variant) => {
let variant = variant.id.lookup(db.upcast()).id;
item_tree_source_maps = variant.item_tree_with_source_map(db.upcast()).1;
item_tree_source_maps.variant(variant.value)
}
},
};
for (_, def_map) in body.blocks(db.upcast()) {
@ -2197,8 +2135,8 @@ impl DefWithBody {
DefWithBody::Static(it) => it.into(),
DefWithBody::Const(it) => it.into(),
DefWithBody::Variant(it) => it.into(),
// FIXME: don't ignore diagnostics for in type const and default field value exprs
DefWithBody::InTypeConst(_) | DefWithBody::Field(_) => return,
// FIXME: don't ignore diagnostics for in type const
DefWithBody::InTypeConst(_) => return,
};
for diag in hir_ty::diagnostics::incorrect_case(db, def.into()) {
acc.push(diag.into())
@ -3331,10 +3269,7 @@ impl AsAssocItem for DefWithBody {
match self {
DefWithBody::Function(it) => it.as_assoc_item(db),
DefWithBody::Const(it) => it.as_assoc_item(db),
DefWithBody::Static(_)
| DefWithBody::Variant(_)
| DefWithBody::InTypeConst(_)
| DefWithBody::Field(_) => None,
DefWithBody::Static(_) | DefWithBody::Variant(_) | DefWithBody::InTypeConst(_) => None,
}
}
}

View file

@ -630,8 +630,7 @@ impl SourceAnalyzer {
let (adt, subst) = self.infer.as_ref()?.type_of_expr_or_pat(expr_id)?.as_adt()?;
let variant = self.infer.as_ref()?.variant_resolution_for_expr_or_pat(expr_id)?;
let variant_data = variant.variant_data(db.upcast());
let local_id = variant_data.field(&local_name)?;
let field = FieldId { parent: variant, local_id };
let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
let field_ty =
db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
Some((
@ -652,8 +651,7 @@ impl SourceAnalyzer {
let pat_id = self.pat_id(&record_pat.into())?;
let variant = self.infer.as_ref()?.variant_resolution_for_pat(pat_id)?;
let variant_data = variant.variant_data(db.upcast());
let local_id = variant_data.field(&field_name)?;
let field = FieldId { parent: variant, local_id };
let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? };
let (adt, subst) = self.infer.as_ref()?.type_of_pat.get(pat_id)?.as_adt()?;
let field_ty =
db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
@ -1025,7 +1023,7 @@ impl SourceAnalyzer {
let expr_id = self.expr_id(db, &literal.clone().into())?;
let substs = infer[expr_id].as_adt()?.1;
let (variant, missing_fields, _) = match expr_id {
let (variant, missing_fields, _exhaustive) = match expr_id {
ExprOrPatId::ExprId(expr_id) => {
record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?
}

View file

@ -972,7 +972,6 @@ impl TryFrom<DefWithBody> for Definition {
DefWithBody::Const(it) => Ok(it.into()),
DefWithBody::Variant(it) => Ok(it.into()),
DefWithBody::InTypeConst(_) => Err(()),
DefWithBody::Field(it) => Ok(it.into()),
}
}
}

View file

@ -310,9 +310,6 @@ impl Definition {
DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()),
// FIXME: implement
DefWithBody::InTypeConst(_) => return SearchScope::empty(),
DefWithBody::Field(f) => {
f.default_value_source(db).map(|src| src.syntax().cloned())
}
};
return match def {
Some(def) => SearchScope::file_range(
@ -330,9 +327,6 @@ impl Definition {
DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()),
// FIXME: implement
DefWithBody::InTypeConst(_) => return SearchScope::empty(),
DefWithBody::Field(f) => {
f.default_value_source(db).map(|src| src.syntax().cloned())
}
};
return match def {
Some(def) => SearchScope::file_range(

View file

@ -846,35 +846,4 @@ pub struct Claims {
"#,
);
}
#[test]
fn default_field_values() {
check_diagnostics(
r#"
struct F {
field1: i32 = 4,
field2: bool,
}
fn f() {
let _f = F {
field2: true,
..
};
let _f = F {
//^ 💡 error: missing structure fields:
//| - field1
field2: true,
};
let _f = F {
//^ 💡 error: missing structure fields:
//| - field2
..
};
}
"#,
);
}
}

View file

@ -1232,21 +1232,6 @@ fn f() {
let (_, _, _, ..) = (true, 42);
// ^^^^^^^^^^^^^ error: expected (bool, i32), found (bool, i32, {unknown})
}
"#,
);
}
#[test]
fn diagnostics_inside_field_default_expr() {
check_diagnostics(
r#"
struct Foo {
foo: i32 = {
let x = false;
x
// ^ error: expected i32, found bool
},
}
"#,
);
}

View file

@ -673,9 +673,6 @@ impl flags::AnalysisStats {
DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
DefWithBody::InTypeConst(_) => unimplemented!(),
DefWithBody::Field(it) => {
it.default_value_source(db).map(|it| it.syntax().cloned())
}
};
if let Some(src) = source {
let original_file = src.file_id.original_file(db);
@ -990,9 +987,6 @@ impl flags::AnalysisStats {
DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
DefWithBody::InTypeConst(_) => unimplemented!(),
DefWithBody::Field(it) => {
it.default_value_source(db).map(|it| it.syntax().cloned())
}
};
if let Some(src) = source {
let original_file = src.file_id.original_file(db);