feat: allow assignments to be cast to other types
This commit is contained in:
		
							parent
							
								
									34d7a28351
								
							
						
					
					
						commit
						c07b9a1a81
					
				|  | @ -771,20 +771,36 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | ||||||
|         location: Span, |         location: Span, | ||||||
|     ) -> Result<TypedExpr, Error> { |     ) -> Result<TypedExpr, Error> { | ||||||
|         let value = self.in_new_scope(|value_typer| value_typer.infer(value))?; |         let value = self.in_new_scope(|value_typer| value_typer.infer(value))?; | ||||||
|         let value_typ = value.tipo(); |         let mut value_typ = value.tipo(); | ||||||
| 
 |  | ||||||
|         // Ensure the pattern matches the type of the value
 |  | ||||||
|         let pattern = PatternTyper::new(self.environment, &self.hydrator) |  | ||||||
|             .unify(pattern, value_typ.clone())?; |  | ||||||
| 
 | 
 | ||||||
|         // Check that any type annotation is accurate.
 |         // Check that any type annotation is accurate.
 | ||||||
|         if let Some(ann) = annotation { |         let pattern = if let Some(ann) = annotation { | ||||||
|             let ann_typ = self |             let ann_typ = self | ||||||
|                 .type_from_annotation(ann) |                 .type_from_annotation(ann) | ||||||
|                 .map(|t| self.instantiate(t, &mut HashMap::new()))?; |                 .map(|t| self.instantiate(t, &mut HashMap::new()))?; | ||||||
| 
 | 
 | ||||||
|             self.unify(ann_typ, value_typ.clone(), value.type_defining_location())?; |             self.unify( | ||||||
|         } |                 ann_typ.clone(), | ||||||
|  |                 value_typ.clone(), | ||||||
|  |                 value.type_defining_location(), | ||||||
|  |             )?; | ||||||
|  | 
 | ||||||
|  |             value_typ = ann_typ.clone(); | ||||||
|  | 
 | ||||||
|  |             // Ensure the pattern matches the type of the value
 | ||||||
|  |             PatternTyper::new(self.environment, &self.hydrator).unify( | ||||||
|  |                 pattern, | ||||||
|  |                 value_typ.clone(), | ||||||
|  |                 Some(ann_typ), | ||||||
|  |             )? | ||||||
|  |         } else { | ||||||
|  |             // Ensure the pattern matches the type of the value
 | ||||||
|  |             PatternTyper::new(self.environment, &self.hydrator).unify( | ||||||
|  |                 pattern, | ||||||
|  |                 value_typ.clone(), | ||||||
|  |                 None, | ||||||
|  |             )? | ||||||
|  |         }; | ||||||
| 
 | 
 | ||||||
|         // We currently only do limited exhaustiveness checking of custom types
 |         // We currently only do limited exhaustiveness checking of custom types
 | ||||||
|         // at the top level of patterns.
 |         // at the top level of patterns.
 | ||||||
|  | @ -1688,8 +1704,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         // Ensure the pattern matches the type of the value
 |         // Ensure the pattern matches the type of the value
 | ||||||
|         let pattern = PatternTyper::new(self.environment, &self.hydrator) |         let pattern = PatternTyper::new(self.environment, &self.hydrator).unify( | ||||||
|             .unify(pattern, value_type.clone())?; |             pattern, | ||||||
|  |             value_type.clone(), | ||||||
|  |             None, | ||||||
|  |         )?; | ||||||
| 
 | 
 | ||||||
|         // Check the type of the following code
 |         // Check the type of the following code
 | ||||||
|         let then = self.infer(then)?; |         let then = self.infer(then)?; | ||||||
|  |  | ||||||
|  | @ -144,7 +144,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|         // Unify each pattern in the multi-pattern with the corresponding subject
 |         // Unify each pattern in the multi-pattern with the corresponding subject
 | ||||||
|         let mut typed_multi = Vec::with_capacity(multi_pattern.len()); |         let mut typed_multi = Vec::with_capacity(multi_pattern.len()); | ||||||
|         for (pattern, subject_type) in multi_pattern.into_iter().zip(subjects) { |         for (pattern, subject_type) in multi_pattern.into_iter().zip(subjects) { | ||||||
|             let pattern = self.unify(pattern, subject_type.clone())?; |             let pattern = self.unify(pattern, subject_type.clone(), None)?; | ||||||
|             typed_multi.push(pattern); |             typed_multi.push(pattern); | ||||||
|         } |         } | ||||||
|         Ok(typed_multi) |         Ok(typed_multi) | ||||||
|  | @ -224,12 +224,13 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|         &mut self, |         &mut self, | ||||||
|         pattern: UntypedPattern, |         pattern: UntypedPattern, | ||||||
|         tipo: Arc<Type>, |         tipo: Arc<Type>, | ||||||
|  |         ann_type: Option<Arc<Type>>, | ||||||
|     ) -> Result<TypedPattern, Error> { |     ) -> Result<TypedPattern, Error> { | ||||||
|         match pattern { |         match pattern { | ||||||
|             Pattern::Discard { name, location } => Ok(Pattern::Discard { name, location }), |             Pattern::Discard { name, location } => Ok(Pattern::Discard { name, location }), | ||||||
| 
 | 
 | ||||||
|             Pattern::Var { name, location, .. } => { |             Pattern::Var { name, location } => { | ||||||
|                 self.insert_variable(&name, tipo, location, location)?; |                 self.insert_variable(&name, ann_type.unwrap_or(tipo), location, location)?; | ||||||
| 
 | 
 | ||||||
|                 Ok(Pattern::Var { name, location }) |                 Ok(Pattern::Var { name, location }) | ||||||
|             } |             } | ||||||
|  | @ -288,9 +289,14 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|                 pattern, |                 pattern, | ||||||
|                 location, |                 location, | ||||||
|             } => { |             } => { | ||||||
|                 self.insert_variable(&name, tipo.clone(), location, pattern.location())?; |                 self.insert_variable( | ||||||
|  |                     &name, | ||||||
|  |                     ann_type.clone().unwrap_or_else(|| tipo.clone()), | ||||||
|  |                     location, | ||||||
|  |                     pattern.location(), | ||||||
|  |                 )?; | ||||||
| 
 | 
 | ||||||
|                 let pattern = self.unify(*pattern, tipo)?; |                 let pattern = self.unify(*pattern, tipo, ann_type)?; | ||||||
| 
 | 
 | ||||||
|                 Ok(Pattern::Assign { |                 Ok(Pattern::Assign { | ||||||
|                     name, |                     name, | ||||||
|  | @ -324,11 +330,11 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
| 
 | 
 | ||||||
|                     let elements = elements |                     let elements = elements | ||||||
|                         .into_iter() |                         .into_iter() | ||||||
|                         .map(|element| self.unify(element, tipo.clone())) |                         .map(|element| self.unify(element, tipo.clone(), None)) | ||||||
|                         .try_collect()?; |                         .try_collect()?; | ||||||
| 
 | 
 | ||||||
|                     let tail = match tail { |                     let tail = match tail { | ||||||
|                         Some(tail) => Some(Box::new(self.unify(*tail, list(tipo))?)), |                         Some(tail) => Some(Box::new(self.unify(*tail, list(tipo), None)?)), | ||||||
|                         None => None, |                         None => None, | ||||||
|                     }; |                     }; | ||||||
| 
 | 
 | ||||||
|  | @ -397,12 +403,6 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|             //         })
 |             //         })
 | ||||||
|             //     }
 |             //     }
 | ||||||
|             // },
 |             // },
 | ||||||
|             // Pattern::BitString { location, segments } => {
 |  | ||||||
|             //     self.environment
 |  | ||||||
|             //         .unify(type_, bit_string())
 |  | ||||||
|             //         .map_err(|e| convert_unify_error(e, location))?;
 |  | ||||||
|             //     self.infer_pattern_bit_string(segments, location)
 |  | ||||||
|             // }
 |  | ||||||
|             Pattern::Constructor { |             Pattern::Constructor { | ||||||
|                 location, |                 location, | ||||||
|                 module, |                 module, | ||||||
|  | @ -506,7 +506,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|                                         label, |                                         label, | ||||||
|                                     } = arg; |                                     } = arg; | ||||||
| 
 | 
 | ||||||
|                                     let value = self.unify(value, typ.clone())?; |                                     let value = self.unify(value, typ.clone(), None)?; | ||||||
| 
 | 
 | ||||||
|                                     Ok(CallArg { |                                     Ok(CallArg { | ||||||
|                                         value, |                                         value, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 rvcas
						rvcas