@@ -44,6 +44,9 @@ pub trait Pattern {
4444 /// Evaluates this pattern with a provided context.
4545 fn evaluate_with_context ( & self , context : & mut meta:: Context )
4646 -> diagnostic:: Result < Self :: Value > ;
47+
48+ /// Returns whether this pattern can be evaluated under ideal conditions.
49+ fn can_evaluate ( & self ) -> bool ;
4750}
4851
4952/// Patterns are used wherever a meta::Value is expected, such as for type
@@ -252,6 +255,21 @@ impl Value {
252255 meta:: Type :: DataType => Value :: DataType ( None ) ,
253256 }
254257 }
258+
259+ /// Returns what type this pattern matches or evaluates to. If unknown or
260+ /// multiple types can be matched, yield unresolved.
261+ pub fn determine_type ( & self ) -> meta:: Type {
262+ match self {
263+ Value :: Unresolved | Value :: Any => meta:: Type :: Unresolved ,
264+ Value :: Binding ( binding) => binding. determine_type ( ) ,
265+ Value :: Boolean ( _) => meta:: Type :: Boolean ,
266+ Value :: Integer ( _, _) => meta:: Type :: Integer ,
267+ Value :: Enum ( _) => meta:: Type :: Enum ,
268+ Value :: String ( _) => meta:: Type :: String ,
269+ Value :: DataType ( _) => meta:: Type :: DataType ,
270+ Value :: Function ( function, arguments) => function. determine_type ( arguments) ,
271+ }
272+ }
255273}
256274
257275impl Pattern for Value {
@@ -347,6 +365,21 @@ impl Pattern for Value {
347365 Value :: Function ( func, args) => func. evaluate ( context, args) ,
348366 }
349367 }
368+
369+ fn can_evaluate ( & self ) -> bool {
370+ match self {
371+ Value :: Unresolved => true ,
372+ Value :: Any => false ,
373+ Value :: Binding ( _) => true ,
374+ Value :: Boolean ( x) => x. is_some ( ) ,
375+ Value :: Integer ( a, b) => a == b,
376+ Value :: Enum ( x) => x. is_some ( ) ,
377+ Value :: String ( x) => x. is_some ( ) ,
378+ Value :: DataType ( None ) => false ,
379+ Value :: DataType ( Some ( x) ) => x. can_evaluate ( ) ,
380+ Value :: Function ( _, _) => true ,
381+ }
382+ }
350383}
351384
352385/// Binding matching structure. Four variations exist, as detailed below.
@@ -557,6 +590,16 @@ impl Binding {
557590 ) )
558591 }
559592 }
593+
594+ /// Returns what type this pattern matches or evaluates to. If unknown or
595+ /// multiple types can be matched, yield unresolved.
596+ pub fn determine_type ( & self ) -> meta:: Type {
597+ if self . nullability . is_some ( ) {
598+ meta:: Type :: DataType
599+ } else {
600+ meta:: Type :: Unresolved
601+ }
602+ }
560603}
561604
562605/// Data type matching structure.
@@ -639,13 +682,13 @@ impl DataType {
639682 return Ok ( false ) ;
640683 }
641684 if !ignore_nullability
642- && self
685+ && ! self
643686 . nullable
644687 . match_pattern_with_context ( context, & value. nullable ( ) . into ( ) ) ?
645688 {
646689 return Ok ( false ) ;
647690 }
648- if self . variation . match_pattern ( value. variation ( ) ) ? {
691+ if ! self . variation . match_pattern ( value. variation ( ) ) ? {
649692 return Ok ( false ) ;
650693 }
651694 if let Some ( expected) = & self . parameters {
@@ -716,6 +759,15 @@ impl Pattern for DataType {
716759 } ;
717760 data:: new_type ( class, nullable, variation, parameters)
718761 }
762+
763+ fn can_evaluate ( & self ) -> bool {
764+ if let Some ( parameters) = & self . parameters {
765+ if !parameters. iter ( ) . all ( |x| x. can_evaluate ( ) ) {
766+ return false ;
767+ }
768+ }
769+ self . nullable . can_evaluate ( ) && self . variation . can_evaluate ( )
770+ }
719771}
720772
721773/// Type variation matching structure.
@@ -779,6 +831,13 @@ impl Pattern for Variation {
779831 Variation :: Exactly ( expected) => Ok ( expected. clone ( ) ) ,
780832 }
781833 }
834+
835+ fn can_evaluate ( & self ) -> bool {
836+ match self {
837+ Variation :: Any => false ,
838+ Variation :: Compatible | Variation :: Exactly ( _) => true ,
839+ }
840+ }
782841}
783842
784843/// Pattern for parameters for parameterized types.
@@ -884,4 +943,13 @@ impl Pattern for Parameter {
884943 . transpose ( ) ?,
885944 } )
886945 }
946+
947+ fn can_evaluate ( & self ) -> bool {
948+ if let Some ( value) = & self . value {
949+ value. can_evaluate ( )
950+ } else {
951+ // Evaluates to null.
952+ true
953+ }
954+ }
887955}
0 commit comments