fix: add a new assignment kind instead of using a boolean
This commit is contained in:
		
							parent
							
								
									f1cfc84e67
								
							
						
					
					
						commit
						5bdea11cc1
					
				|  | @ -1679,6 +1679,7 @@ pub type TypedAssignmentKind = AssignmentKind<()>; | |||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq, Copy, serde::Serialize, serde::Deserialize)] | ||||
| pub enum AssignmentKind<T> { | ||||
|     Is, | ||||
|     Let { backpassing: T }, | ||||
|     Expect { backpassing: T }, | ||||
| } | ||||
|  | @ -1686,6 +1687,7 @@ pub enum AssignmentKind<T> { | |||
| impl From<UntypedAssignmentKind> for TypedAssignmentKind { | ||||
|     fn from(kind: UntypedAssignmentKind) -> TypedAssignmentKind { | ||||
|         match kind { | ||||
|             AssignmentKind::Is => AssignmentKind::Is, | ||||
|             AssignmentKind::Let { .. } => AssignmentKind::Let { backpassing: () }, | ||||
|             AssignmentKind::Expect { .. } => AssignmentKind::Expect { backpassing: () }, | ||||
|         } | ||||
|  | @ -1701,8 +1703,13 @@ impl<T> AssignmentKind<T> { | |||
|         matches!(self, AssignmentKind::Expect { .. }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn if_is(&self) -> bool { | ||||
|         matches!(self, AssignmentKind::Is) | ||||
|     } | ||||
| 
 | ||||
|     pub fn location_offset(&self) -> usize { | ||||
|         match self { | ||||
|             AssignmentKind::Is => 2, | ||||
|             AssignmentKind::Let { .. } => 3, | ||||
|             AssignmentKind::Expect { .. } => 6, | ||||
|         } | ||||
|  | @ -1712,6 +1719,7 @@ impl<T> AssignmentKind<T> { | |||
| impl AssignmentKind<bool> { | ||||
|     pub fn is_backpassing(&self) -> bool { | ||||
|         match self { | ||||
|             Self::Is => unreachable!(), | ||||
|             Self::Let { backpassing } | Self::Expect { backpassing } => *backpassing, | ||||
|         } | ||||
|     } | ||||
|  | @ -1724,6 +1732,10 @@ impl<T: Default> AssignmentKind<T> { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn is() -> Self { | ||||
|         AssignmentKind::Is | ||||
|     } | ||||
| 
 | ||||
|     pub fn expect() -> Self { | ||||
|         AssignmentKind::Expect { | ||||
|             backpassing: Default::default(), | ||||
|  |  | |||
|  | @ -703,6 +703,7 @@ impl<'comments> Formatter<'comments> { | |||
|         kind: UntypedAssignmentKind, | ||||
|     ) -> Document<'a> { | ||||
|         let keyword = match kind { | ||||
|             AssignmentKind::Is => unreachable!(), | ||||
|             AssignmentKind::Let { .. } => "let", | ||||
|             AssignmentKind::Expect { .. } => "expect", | ||||
|         }; | ||||
|  |  | |||
|  | @ -2691,7 +2691,7 @@ fn if_soft_cast_unused_pattern() { | |||
|         } | ||||
|     "#;
 | ||||
| 
 | ||||
|     let (warnings, _ast) = dbg!(check(parse(source_code))).unwrap(); | ||||
|     let (warnings, _ast) = check(parse(source_code)).unwrap(); | ||||
| 
 | ||||
|     assert!(matches!( | ||||
|         warnings[0], | ||||
|  | @ -2716,7 +2716,7 @@ fn if_soft_cast_not_data() { | |||
|         } | ||||
|     "#;
 | ||||
| 
 | ||||
|     let (warnings, _ast) = dbg!(check(parse(source_code))).unwrap(); | ||||
|     let (warnings, _ast) = check(parse(source_code)).unwrap(); | ||||
| 
 | ||||
|     assert!(matches!(warnings[0], Warning::UseWhenInstead { .. })) | ||||
| } | ||||
|  |  | |||
|  | @ -510,7 +510,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | |||
|                     location: _, | ||||
|                 } = patterns.into_vec().swap_remove(0); | ||||
| 
 | ||||
|                 self.infer_assignment(pattern, *value, kind, &annotation, location, true) | ||||
|                 self.infer_assignment(pattern, *value, kind, &annotation, location) | ||||
|             } | ||||
| 
 | ||||
|             UntypedExpr::Trace { | ||||
|  | @ -1182,7 +1182,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | |||
|         kind: UntypedAssignmentKind, | ||||
|         annotation: &Option<Annotation>, | ||||
|         location: Span, | ||||
|         check_exhaustiveness: bool, | ||||
|     ) -> Result<TypedExpr, Error> { | ||||
|         let typed_value = self.infer(untyped_value.clone())?; | ||||
|         let mut value_typ = typed_value.tipo(); | ||||
|  | @ -1199,7 +1198,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | |||
|                 ann_typ.clone(), | ||||
|                 value_typ.clone(), | ||||
|                 typed_value.type_defining_location(), | ||||
|                 (kind.is_let() && ann_typ.is_data()) || kind.is_expect(), | ||||
|                 (kind.is_let() && ann_typ.is_data()) || kind.is_expect() || kind.if_is(), | ||||
|             )?; | ||||
| 
 | ||||
|             value_typ = ann_typ.clone(); | ||||
|  | @ -1240,11 +1239,13 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | |||
|         // If `expect` is explicitly used, we still check exhaustiveness but instead of returning an
 | ||||
|         // error we emit a warning which explains that using `expect` is unnecessary.
 | ||||
|         match kind { | ||||
|             AssignmentKind::Let { .. } if check_exhaustiveness => self | ||||
|                 .environment | ||||
|                 .check_exhaustiveness(&[&pattern], location, true)?, | ||||
|             AssignmentKind::Is => (), | ||||
|             AssignmentKind::Let { .. } => { | ||||
|                 self.environment | ||||
|                     .check_exhaustiveness(&[&pattern], location, true)? | ||||
|             } | ||||
| 
 | ||||
|             AssignmentKind::Expect { .. } if check_exhaustiveness => { | ||||
|             AssignmentKind::Expect { .. } => { | ||||
|                 let is_exaustive_pattern = self | ||||
|                     .environment | ||||
|                     .check_exhaustiveness(&[&pattern], location, false) | ||||
|  | @ -1292,7 +1293,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | |||
|                         }); | ||||
|                 } | ||||
|             } | ||||
|             _ => (), | ||||
|         } | ||||
| 
 | ||||
|         Ok(TypedExpr::Assignment { | ||||
|  | @ -1749,10 +1749,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | |||
|                 let TypedExpr::Assignment { value, pattern, .. } = typer.infer_assignment( | ||||
|                     pattern, | ||||
|                     branch.condition.clone(), | ||||
|                     AssignmentKind::expect(), | ||||
|                     AssignmentKind::is(), | ||||
|                     &annotation, | ||||
|                     location, | ||||
|                     false, | ||||
|                 )? | ||||
|                 else { | ||||
|                     unreachable!() | ||||
|  | @ -2104,6 +2103,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | |||
|                             .into(), | ||||
|                             // erase backpassing while preserving assignment kind.
 | ||||
|                             kind: match kind { | ||||
|                                 AssignmentKind::Is => unreachable!(), | ||||
|                                 AssignmentKind::Let { .. } => AssignmentKind::let_(), | ||||
|                                 AssignmentKind::Expect { .. } | ||||
|                                     if pattern_is_var && annotation.is_none() => | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 rvcas
						rvcas