mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Compute diagnostics of a field body iff it has one
This commit is contained in:
parent
c134b20c9c
commit
b4d4d02db8
@ -519,6 +519,7 @@ pub type LocalModuleId = Idx<nameres::ModuleData>;
|
|||||||
pub struct FieldId {
|
pub struct FieldId {
|
||||||
pub parent: VariantId,
|
pub parent: VariantId,
|
||||||
pub local_id: LocalFieldId,
|
pub local_id: LocalFieldId,
|
||||||
|
pub has_default: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FieldId {
|
impl FieldId {
|
||||||
|
@ -1167,9 +1167,11 @@ impl InferenceContext<'_> {
|
|||||||
};
|
};
|
||||||
let mut p = place.clone();
|
let mut p = place.clone();
|
||||||
self.current_capture_span_stack.push(MirSpan::PatId(arg));
|
self.current_capture_span_stack.push(MirSpan::PatId(arg));
|
||||||
|
let has_default = vd.fields()[local_id].has_default;
|
||||||
p.projections.push(ProjectionElem::Field(Either::Left(FieldId {
|
p.projections.push(ProjectionElem::Field(Either::Left(FieldId {
|
||||||
parent: variant,
|
parent: variant,
|
||||||
local_id,
|
local_id,
|
||||||
|
has_default,
|
||||||
})));
|
})));
|
||||||
self.consume_with_pat(p, arg);
|
self.consume_with_pat(p, arg);
|
||||||
self.current_capture_span_stack.pop();
|
self.current_capture_span_stack.pop();
|
||||||
@ -1219,12 +1221,13 @@ impl InferenceContext<'_> {
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(fields.clone())
|
.zip(fields.clone())
|
||||||
.chain(ar.iter().rev().zip(fields.rev()));
|
.chain(ar.iter().rev().zip(fields.rev()));
|
||||||
for (&arg, (i, _)) in it {
|
for (&arg, (i, d)) in it {
|
||||||
let mut p = place.clone();
|
let mut p = place.clone();
|
||||||
self.current_capture_span_stack.push(MirSpan::PatId(arg));
|
self.current_capture_span_stack.push(MirSpan::PatId(arg));
|
||||||
p.projections.push(ProjectionElem::Field(Either::Left(FieldId {
|
p.projections.push(ProjectionElem::Field(Either::Left(FieldId {
|
||||||
parent: variant,
|
parent: variant,
|
||||||
local_id: i,
|
local_id: i,
|
||||||
|
has_default: d.has_default,
|
||||||
})));
|
})));
|
||||||
self.consume_with_pat(p, arg);
|
self.consume_with_pat(p, arg);
|
||||||
self.current_capture_span_stack.pop();
|
self.current_capture_span_stack.pop();
|
||||||
|
@ -1746,13 +1746,17 @@ impl InferenceContext<'_> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
|
TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
|
||||||
let local_id = self.db.struct_data(*s).variant_data.field(name)?;
|
let vd = &self.db.struct_data(*s).variant_data;
|
||||||
let field = FieldId { parent: (*s).into(), local_id };
|
let local_id = vd.field(name)?;
|
||||||
|
let has_default = vd.fields()[local_id].has_default;
|
||||||
|
let field = FieldId { parent: (*s).into(), local_id, has_default };
|
||||||
(field, parameters.clone())
|
(field, parameters.clone())
|
||||||
}
|
}
|
||||||
TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
|
TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
|
||||||
let local_id = self.db.union_data(*u).variant_data.field(name)?;
|
let vd = &self.db.union_data(*u).variant_data;
|
||||||
let field = FieldId { parent: (*u).into(), local_id };
|
let local_id = vd.field(name)?;
|
||||||
|
let has_default = vd.fields()[local_id].has_default;
|
||||||
|
let field = FieldId { parent: (*u).into(), local_id, has_default };
|
||||||
(field, parameters.clone())
|
(field, parameters.clone())
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
@ -870,12 +870,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
.map(|(i, it)| match it {
|
.map(|(i, it)| match it {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => {
|
None => {
|
||||||
|
let local_id =
|
||||||
|
LocalFieldId::from_raw(RawIdx::from(i as u32));
|
||||||
|
let has_default =
|
||||||
|
variant_data.fields()[local_id].has_default;
|
||||||
let p = sp.project(
|
let p = sp.project(
|
||||||
ProjectionElem::Field(Either::Left(FieldId {
|
ProjectionElem::Field(Either::Left(FieldId {
|
||||||
parent: variant_id,
|
parent: variant_id,
|
||||||
local_id: LocalFieldId::from_raw(RawIdx::from(
|
local_id,
|
||||||
i as u32,
|
has_default,
|
||||||
)),
|
|
||||||
})),
|
})),
|
||||||
&mut self.result.projection_store,
|
&mut self.result.projection_store,
|
||||||
);
|
);
|
||||||
@ -897,10 +900,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
};
|
};
|
||||||
let local_id =
|
let local_id =
|
||||||
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
|
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
|
||||||
|
let has_default = variant_data.fields()[local_id].has_default;
|
||||||
let place = place.project(
|
let place = place.project(
|
||||||
PlaceElem::Field(Either::Left(FieldId {
|
PlaceElem::Field(Either::Left(FieldId {
|
||||||
parent: union_id.into(),
|
parent: union_id.into(),
|
||||||
local_id,
|
local_id,
|
||||||
|
has_default,
|
||||||
})),
|
})),
|
||||||
&mut self.result.projection_store,
|
&mut self.result.projection_store,
|
||||||
);
|
);
|
||||||
|
@ -632,10 +632,12 @@ impl MirLowerCtx<'_> {
|
|||||||
.map(|x| {
|
.map(|x| {
|
||||||
let field_id =
|
let field_id =
|
||||||
variant_data.field(&x.name).ok_or(MirLowerError::UnresolvedField)?;
|
variant_data.field(&x.name).ok_or(MirLowerError::UnresolvedField)?;
|
||||||
|
let has_default = variant_data.fields()[field_id].has_default;
|
||||||
Ok((
|
Ok((
|
||||||
PlaceElem::Field(Either::Left(FieldId {
|
PlaceElem::Field(Either::Left(FieldId {
|
||||||
parent: v,
|
parent: v,
|
||||||
local_id: field_id,
|
local_id: field_id,
|
||||||
|
has_default,
|
||||||
})),
|
})),
|
||||||
x.pat,
|
x.pat,
|
||||||
))
|
))
|
||||||
@ -644,8 +646,12 @@ impl MirLowerCtx<'_> {
|
|||||||
self.pattern_match_adt(current, current_else, it.into_iter(), cond_place, mode)?
|
self.pattern_match_adt(current, current_else, it.into_iter(), cond_place, mode)?
|
||||||
}
|
}
|
||||||
AdtPatternShape::Tuple { args, ellipsis } => {
|
AdtPatternShape::Tuple { args, ellipsis } => {
|
||||||
let fields = variant_data.fields().iter().map(|(x, _)| {
|
let fields = variant_data.fields().iter().map(|(x, d)| {
|
||||||
PlaceElem::Field(Either::Left(FieldId { parent: v, local_id: x }))
|
PlaceElem::Field(Either::Left(FieldId {
|
||||||
|
parent: v,
|
||||||
|
local_id: x,
|
||||||
|
has_default: d.has_default,
|
||||||
|
}))
|
||||||
});
|
});
|
||||||
self.pattern_match_tuple_like(
|
self.pattern_match_tuple_like(
|
||||||
current,
|
current,
|
||||||
|
@ -252,8 +252,8 @@ impl HirDisplay for Struct {
|
|||||||
f.write_char('(')?;
|
f.write_char('(')?;
|
||||||
let mut it = variant_data.fields().iter().peekable();
|
let mut it = variant_data.fields().iter().peekable();
|
||||||
|
|
||||||
while let Some((id, _)) = it.next() {
|
while let Some((id, d)) = it.next() {
|
||||||
let field = Field { parent: (*self).into(), id };
|
let field = Field { parent: (*self).into(), id, has_default: d.has_default };
|
||||||
write_visibility(module_id, field.visibility(f.db), f)?;
|
write_visibility(module_id, field.visibility(f.db), f)?;
|
||||||
field.ty(f.db).hir_fmt(f)?;
|
field.ty(f.db).hir_fmt(f)?;
|
||||||
if it.peek().is_some() {
|
if it.peek().is_some() {
|
||||||
|
@ -237,13 +237,13 @@ impl From<VariantDef> for VariantId {
|
|||||||
|
|
||||||
impl From<Field> for FieldId {
|
impl From<Field> for FieldId {
|
||||||
fn from(def: Field) -> Self {
|
fn from(def: Field) -> Self {
|
||||||
FieldId { parent: def.parent.into(), local_id: def.id }
|
FieldId { parent: def.parent.into(), local_id: def.id, has_default: def.has_default }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FieldId> for Field {
|
impl From<FieldId> for Field {
|
||||||
fn from(def: FieldId) -> Self {
|
fn from(def: FieldId) -> Self {
|
||||||
Field { parent: def.parent.into(), id: def.local_id }
|
Field { parent: def.parent.into(), id: def.local_id, has_default: def.has_default }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,6 +423,9 @@ impl ModuleDef {
|
|||||||
};
|
};
|
||||||
if let Some(fields) = fields {
|
if let Some(fields) = fields {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
|
if !field.has_default {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let def: DefWithBody = field.into();
|
let def: DefWithBody = field.into();
|
||||||
def.diagnostics(db, &mut acc, style_lints);
|
def.diagnostics(db, &mut acc, style_lints);
|
||||||
}
|
}
|
||||||
@ -1249,6 +1252,7 @@ impl From<&Field> for DefWithBodyId {
|
|||||||
pub struct Field {
|
pub struct Field {
|
||||||
pub(crate) parent: VariantDef,
|
pub(crate) parent: VariantDef,
|
||||||
pub(crate) id: LocalFieldId,
|
pub(crate) id: LocalFieldId,
|
||||||
|
pub(crate) has_default: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
|
||||||
@ -1414,7 +1418,7 @@ impl Struct {
|
|||||||
.variant_data
|
.variant_data
|
||||||
.fields()
|
.fields()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(id, _)| Field { parent: self.into(), id })
|
.map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default })
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1476,7 +1480,7 @@ impl Union {
|
|||||||
.variant_data
|
.variant_data
|
||||||
.fields()
|
.fields()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(id, _)| Field { parent: self.into(), id })
|
.map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default })
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1606,7 +1610,7 @@ impl Variant {
|
|||||||
self.variant_data(db)
|
self.variant_data(db)
|
||||||
.fields()
|
.fields()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(id, _)| Field { parent: self.into(), id })
|
.map(|(id, d)| Field { parent: self.into(), id, has_default: d.has_default })
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5162,10 +5166,13 @@ impl Type {
|
|||||||
_ => return Vec::new(),
|
_ => return Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let var_data = db.variant_data(variant_id);
|
||||||
|
let fields = var_data.fields();
|
||||||
db.field_types(variant_id)
|
db.field_types(variant_id)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(local_id, ty)| {
|
.map(|(local_id, ty)| {
|
||||||
let def = Field { parent: variant_id.into(), id: local_id };
|
let has_default = fields[local_id].has_default;
|
||||||
|
let def = Field { parent: variant_id.into(), id: local_id, has_default };
|
||||||
let ty = ty.clone().substitute(Interner, substs);
|
let ty = ty.clone().substitute(Interner, substs);
|
||||||
(def, self.derived(ty))
|
(def, self.derived(ty))
|
||||||
})
|
})
|
||||||
|
@ -160,7 +160,11 @@ impl ChildBySource for VariantId {
|
|||||||
let arena_map = arena_map.as_ref();
|
let arena_map = arena_map.as_ref();
|
||||||
let parent = *self;
|
let parent = *self;
|
||||||
for (local_id, source) in arena_map.value.iter() {
|
for (local_id, source) in arena_map.value.iter() {
|
||||||
let id = FieldId { parent, local_id };
|
let has_default = match source {
|
||||||
|
Either::Left(_) => false,
|
||||||
|
Either::Right(rec) => rec.expr().is_some(),
|
||||||
|
};
|
||||||
|
let id = FieldId { parent, local_id, has_default };
|
||||||
match source.clone() {
|
match source.clone() {
|
||||||
Either::Left(source) => res[keys::TUPLE_FIELD].insert(AstPtr::new(&source), id),
|
Either::Left(source) => res[keys::TUPLE_FIELD].insert(AstPtr::new(&source), id),
|
||||||
Either::Right(source) => res[keys::RECORD_FIELD].insert(AstPtr::new(&source), id),
|
Either::Right(source) => res[keys::RECORD_FIELD].insert(AstPtr::new(&source), id),
|
||||||
|
@ -630,7 +630,10 @@ impl SourceAnalyzer {
|
|||||||
let (adt, subst) = self.infer.as_ref()?.type_of_expr_or_pat(expr_id)?.as_adt()?;
|
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 = self.infer.as_ref()?.variant_resolution_for_expr_or_pat(expr_id)?;
|
||||||
let variant_data = variant.variant_data(db.upcast());
|
let variant_data = variant.variant_data(db.upcast());
|
||||||
let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
|
let fields = variant_data.fields();
|
||||||
|
let local_id = variant_data.field(&local_name)?;
|
||||||
|
let field =
|
||||||
|
FieldId { parent: variant, local_id, has_default: fields[local_id].has_default };
|
||||||
let field_ty =
|
let field_ty =
|
||||||
db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
|
db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
|
||||||
Some((
|
Some((
|
||||||
@ -651,7 +654,10 @@ impl SourceAnalyzer {
|
|||||||
let pat_id = self.pat_id(&record_pat.into())?;
|
let pat_id = self.pat_id(&record_pat.into())?;
|
||||||
let variant = self.infer.as_ref()?.variant_resolution_for_pat(pat_id)?;
|
let variant = self.infer.as_ref()?.variant_resolution_for_pat(pat_id)?;
|
||||||
let variant_data = variant.variant_data(db.upcast());
|
let variant_data = variant.variant_data(db.upcast());
|
||||||
let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? };
|
let fields = variant_data.fields();
|
||||||
|
let local_id = variant_data.field(&field_name)?;
|
||||||
|
let field =
|
||||||
|
FieldId { parent: variant, local_id, has_default: fields[local_id].has_default };
|
||||||
let (adt, subst) = self.infer.as_ref()?.type_of_pat.get(pat_id)?.as_adt()?;
|
let (adt, subst) = self.infer.as_ref()?.type_of_pat.get(pat_id)?.as_adt()?;
|
||||||
let field_ty =
|
let field_ty =
|
||||||
db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
|
db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
|
||||||
@ -1060,11 +1066,17 @@ impl SourceAnalyzer {
|
|||||||
missing_fields: Vec<LocalFieldId>,
|
missing_fields: Vec<LocalFieldId>,
|
||||||
) -> Vec<(Field, Type)> {
|
) -> Vec<(Field, Type)> {
|
||||||
let field_types = db.field_types(variant);
|
let field_types = db.field_types(variant);
|
||||||
|
let var_data = db.variant_data(variant);
|
||||||
|
let fields = var_data.fields();
|
||||||
|
|
||||||
missing_fields
|
missing_fields
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|local_id| {
|
.map(|local_id| {
|
||||||
let field = FieldId { parent: variant, local_id };
|
let field = FieldId {
|
||||||
|
parent: variant,
|
||||||
|
local_id,
|
||||||
|
has_default: fields[local_id].has_default,
|
||||||
|
};
|
||||||
let ty = field_types[local_id].clone().substitute(Interner, substs);
|
let ty = field_types[local_id].clone().substitute(Interner, substs);
|
||||||
(field.into(), Type::new_with_resolver_inner(db, &self.resolver, ty))
|
(field.into(), Type::new_with_resolver_inner(db, &self.resolver, ty))
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user