@@ -640,34 +640,51 @@ impl<'a, C: EvaluationContext> ExprTypeEvaluator<'a, C> {
640
640
}
641
641
642
642
/// Checks a placeholder expression.
643
- pub ( crate ) fn check_placeholder ( & mut self , placeholder : & Placeholder ) {
644
- self . placeholders += 1 ;
645
- let expr = placeholder. expr ( ) ;
646
- /// Evaluate the placeholder expression and check that the resulting type is
647
- /// coercible to string for interpolation
648
- if let Some ( ty) = self . evaluate_expr ( & expr) {
649
- match ty {
650
- Type :: Primitive ( ..) | Type :: Union | Type :: None => { /* Already coercible */ }
651
- _ => {
652
- let coercible = match placeholder. option ( ) {
653
- Some ( PlaceholderOption :: Sep ( _) ) => matches ! ( ty, Type :: Compound ( CompoundType :: Array ( element_type) , _)
654
- if matches!( element_type. as_ref( ) , Type :: Primitive ( _, false ) ) ) ,
655
-
656
- Some ( PlaceholderOption :: Default ( _) ) => matches ! ( ty, Type :: Primitive ( _, true ) ) ,
657
-
658
- Some ( PlaceholderOption :: TrueFalse ( _) ) => matches ! ( ty, Type :: Primitive ( PrimitiveType :: Boolean , _) ) ,
659
-
660
- None => true , // Default case: Always coercible
661
- } ;
662
- if !coercible {
663
- self . context
664
- . add_diagnostic ( cannot_coerce_to_string ( & ty, expr. span ( ) ) ) ;
643
+ pub ( crate ) fn check_placeholder ( & mut self , placeholder : & Placeholder ) {
644
+ self . placeholders += 1 ; // Track placeholder processing count
645
+
646
+ let expr = placeholder. expr ( ) ; // Extract expression inside placeholder
647
+
648
+ // Evaluate the placeholder expression and check that the resulting type is
649
+ // coercible to string for interpolation
650
+ if let Some ( ty) = self . evaluate_expr ( & expr) {
651
+ match ty {
652
+ // If the type is already coercible, do nothing
653
+ Type :: Primitive ( ..) | Type :: Union | Type :: None => { }
654
+
655
+ // Otherwise, check placeholder options
656
+ _ => {
657
+ let coercible = match placeholder. option ( ) {
658
+ // `Sep` option: Only `Array[P]` where `P` is a non-optional primitive is valid
659
+ Some ( PlaceholderOption :: Sep ( _) ) => matches ! ( ty,
660
+ Type :: Compound ( CompoundType :: Array ( ref element_type) , _)
661
+ if matches!( element_type. element_type( ) , Type :: Primitive ( _, false ) ) ) ,
662
+
663
+ // `Default` option: Only optional primitive types are valid
664
+ Some ( PlaceholderOption :: Default ( _) ) => matches ! ( ty,
665
+ Type :: Primitive ( _, true ) ) ,
666
+
667
+ // `TrueFalse` option: Only Boolean type is valid
668
+ Some ( PlaceholderOption :: TrueFalse ( _) ) => matches ! ( ty,
669
+ Type :: Primitive ( PrimitiveType :: Boolean , _) ) ,
670
+
671
+ // If no option is specified, allow all types
672
+ None => true ,
673
+ } ;
674
+
675
+ // If coercion is not possible, add a diagnostic error
676
+ if !coercible {
677
+ self . context
678
+ . add_diagnostic ( cannot_coerce_to_string ( & ty, expr. span ( ) ) ) ;
679
+ }
665
680
}
666
681
}
667
682
}
683
+
684
+ self . placeholders -= 1 ; // Decrement placeholder tracking
668
685
}
669
- self . placeholders -= 1 ;
670
- }
686
+
687
+
671
688
/// Evaluates the type of a literal array expression.
672
689
fn evaluate_literal_array ( & mut self , expr : & LiteralArray ) -> Type {
673
690
// Look at the first array element to determine the element type
0 commit comments