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