Fix missing fields not warning in structs
This commit is contained in:
parent
45d381f865
commit
4c9633132f
@ -53,7 +53,7 @@ Currently missing big features (TODOs) are:
|
|||||||
- Importable binops?
|
- Importable binops?
|
||||||
|
|
||||||
Big features that I want later but are not necessary:
|
Big features that I want later but are not necessary:
|
||||||
- Associated functions
|
- Associated functions (for e.g. sizeof)
|
||||||
- ~~User-defined binary operations~~ (DONE)
|
- ~~User-defined binary operations~~ (DONE)
|
||||||
- ~~Asymmetric binary operations (e.g. string + u32)~~ (DONE)
|
- ~~Asymmetric binary operations (e.g. string + u32)~~ (DONE)
|
||||||
- Error handling
|
- Error handling
|
||||||
|
@ -7,11 +7,10 @@ struct Test {
|
|||||||
|
|
||||||
fn main() -> u32 {
|
fn main() -> u32 {
|
||||||
let mut value = Test {
|
let mut value = Test {
|
||||||
field: 5,
|
|
||||||
second: 3,
|
second: 3,
|
||||||
|
field: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
value.second = 17;
|
|
||||||
|
|
||||||
return value.second;
|
return value.second;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,8 @@ pub enum ErrorKind {
|
|||||||
TriedAccessingNonStruct(TypeKind),
|
TriedAccessingNonStruct(TypeKind),
|
||||||
#[error("No such struct-field on type {0}")]
|
#[error("No such struct-field on type {0}")]
|
||||||
NoSuchField(String),
|
NoSuchField(String),
|
||||||
|
#[error("Missing definition for field \"{0}\"")]
|
||||||
|
MissingStructField(String),
|
||||||
#[error("Struct field declared twice {0}")]
|
#[error("Struct field declared twice {0}")]
|
||||||
DuplicateStructField(String),
|
DuplicateStructField(String),
|
||||||
#[error("Type declared twice {0}")]
|
#[error("Type declared twice {0}")]
|
||||||
|
@ -632,6 +632,13 @@ impl Expression {
|
|||||||
.get_struct_type(&type_key)
|
.get_struct_type(&type_key)
|
||||||
.ok_or(ErrorKind::NoSuchType(struct_name.clone(), type_key.1))?
|
.ok_or(ErrorKind::NoSuchType(struct_name.clone(), type_key.1))?
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
|
let mut expected_fields = if let Some(struct_ty) = state.scope.get_struct_type(&type_key) {
|
||||||
|
struct_ty.0.iter().map(|f| f.0.clone()).collect()
|
||||||
|
} else {
|
||||||
|
HashSet::new()
|
||||||
|
};
|
||||||
|
|
||||||
for (field_name, field_expr) in items {
|
for (field_name, field_expr) in items {
|
||||||
// Get expected type, or error if field does not exist
|
// Get expected type, or error if field does not exist
|
||||||
let expected_ty = state.or_else(
|
let expected_ty = state.or_else(
|
||||||
@ -641,6 +648,7 @@ impl Expression {
|
|||||||
&TypeKind::Vague(VagueType::Unknown),
|
&TypeKind::Vague(VagueType::Unknown),
|
||||||
field_expr.1,
|
field_expr.1,
|
||||||
);
|
);
|
||||||
|
expected_fields.remove(field_name);
|
||||||
|
|
||||||
// Typecheck the actual expression
|
// Typecheck the actual expression
|
||||||
let expr_res = field_expr.typecheck(state, typerefs, HintKind::Coerce(expected_ty.clone()));
|
let expr_res = field_expr.typecheck(state, typerefs, HintKind::Coerce(expected_ty.clone()));
|
||||||
@ -649,6 +657,15 @@ impl Expression {
|
|||||||
// Make sure both are the same type, report error if not
|
// Make sure both are the same type, report error if not
|
||||||
state.ok(expr_ty.narrow_into(&expr_ty), field_expr.1);
|
state.ok(expr_ty.narrow_into(&expr_ty), field_expr.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.note_errors(
|
||||||
|
&expected_fields
|
||||||
|
.into_iter()
|
||||||
|
.map(|v| ErrorKind::MissingStructField(v))
|
||||||
|
.collect(),
|
||||||
|
self.1,
|
||||||
|
);
|
||||||
|
|
||||||
Ok(TypeKind::CustomType(type_key))
|
Ok(TypeKind::CustomType(type_key))
|
||||||
}
|
}
|
||||||
ExprKind::Borrow(var_ref, mutable) => {
|
ExprKind::Borrow(var_ref, mutable) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user