@@ -61,6 +61,9 @@ impl<'a> From<DisambiguatedType<'a>> for ExpressionType<'a> {
6161pub ( super ) struct TypeMatcher < ' c , ' a > {
6262 // Allow implicit type conversion from universal real/integer to other integer types
6363 implicit_type_conversion : bool ,
64+
65+ // Allow implicit type conversion from abstract types to universal real/integer
66+ implicit_type_conversion_from_universal : bool ,
6467 context : & ' c AnalyzeContext < ' a > ,
6568}
6669
@@ -73,18 +76,28 @@ impl<'c, 'a> TypeMatcher<'c, 'a> {
7376 match ttyp. kind ( ) {
7477 Type :: Integer => types. match_type ( self . context . universal_integer ( ) ) ,
7578 Type :: Real => types. match_type ( self . context . universal_real ( ) ) ,
76- Type :: Universal ( UniversalType :: Integer ) => match types {
77- ExpressionType :: Unambiguous ( typ) => typ. base ( ) . is_any_integer ( ) ,
78- ExpressionType :: Ambiguous ( types) => {
79- types. iter ( ) . any ( |typ| typ. is_any_integer ( ) )
79+ Type :: Universal ( UniversalType :: Integer )
80+ if self . implicit_type_conversion_from_universal =>
81+ {
82+ match types {
83+ ExpressionType :: Unambiguous ( typ) => typ. base ( ) . is_any_integer ( ) ,
84+ ExpressionType :: Ambiguous ( types) => {
85+ types. iter ( ) . any ( |typ| typ. is_any_integer ( ) )
86+ }
87+ _ => false ,
88+ }
89+ }
90+ Type :: Universal ( UniversalType :: Real )
91+ if self . implicit_type_conversion_from_universal =>
92+ {
93+ match types {
94+ ExpressionType :: Unambiguous ( typ) => typ. base ( ) . is_any_real ( ) ,
95+ ExpressionType :: Ambiguous ( types) => {
96+ types. iter ( ) . any ( |typ| typ. is_any_real ( ) )
97+ }
98+ _ => false ,
8099 }
81- _ => false ,
82- } ,
83- Type :: Universal ( UniversalType :: Real ) => match types {
84- ExpressionType :: Unambiguous ( typ) => typ. base ( ) . is_any_real ( ) ,
85- ExpressionType :: Ambiguous ( types) => types. iter ( ) . any ( |typ| typ. is_any_real ( ) ) ,
86- _ => false ,
87- } ,
100+ }
88101 _ => false ,
89102 }
90103 } else {
@@ -112,32 +125,28 @@ impl<'c, 'a> TypeMatcher<'c, 'a> {
112125 pub fn disambiguate_by_assoc_types (
113126 & self ,
114127 actual_types : & [ Option < ExpressionType < ' a > > ] ,
115- candidates : & [ ResolvedCall < ' a > ] ,
116- ) -> Vec < OverloadedEnt < ' a > > {
117- candidates
118- . iter ( )
119- . filter ( |resolved| {
120- actual_types. iter ( ) . enumerate ( ) . all ( |( idx, actual_type) | {
121- if let Some ( actual_type) = actual_type {
122- self . is_possible ( actual_type, resolved. formals [ idx] . type_mark ( ) . base ( ) )
123- } else {
124- true
125- }
126- } )
128+ candidates : & mut Vec < ResolvedCall < ' a > > ,
129+ ) {
130+ candidates. retain ( |resolved| {
131+ actual_types. iter ( ) . enumerate ( ) . all ( |( idx, actual_type) | {
132+ if let Some ( actual_type) = actual_type {
133+ self . is_possible ( actual_type, resolved. formals [ idx] . type_mark ( ) . base ( ) )
134+ } else {
135+ true
136+ }
127137 } )
128- . map ( |resolved| resolved. subpgm )
129- . collect ( )
138+ } )
130139 }
131140
132141 pub fn disambiguate_op_by_return_type (
133142 & self ,
134- candidates : & mut Vec < OverloadedEnt < ' a > > ,
143+ candidates : & mut Vec < impl AsRef < OverloadedEnt < ' a > > > ,
135144 ttyp : Option < TypeEnt < ' a > > , // Optional target type constraint
136145 ) {
137146 let tbase = ttyp. map ( |ttyp| ttyp. base ( ) ) ;
138147 candidates. retain ( |ent| {
139148 if let Some ( tbase) = tbase {
140- self . can_be_target_type ( ent. return_type ( ) . unwrap ( ) , tbase)
149+ self . can_be_target_type ( ent. as_ref ( ) . return_type ( ) . unwrap ( ) , tbase)
141150 } else {
142151 true
143152 }
@@ -149,20 +158,30 @@ impl<'a> AnalyzeContext<'a> {
149158 pub fn strict_matcher ( & self ) -> TypeMatcher < ' _ , ' a > {
150159 TypeMatcher {
151160 implicit_type_conversion : false ,
161+ implicit_type_conversion_from_universal : false ,
162+ context : self ,
163+ }
164+ }
165+
166+ pub fn any_matcher ( & self ) -> TypeMatcher < ' _ , ' a > {
167+ TypeMatcher {
168+ implicit_type_conversion : true ,
169+ implicit_type_conversion_from_universal : true ,
152170 context : self ,
153171 }
154172 }
155173
156174 pub fn implicit_matcher ( & self ) -> TypeMatcher < ' _ , ' a > {
157175 TypeMatcher {
158176 implicit_type_conversion : true ,
177+ implicit_type_conversion_from_universal : false ,
159178 context : self ,
160179 }
161180 }
162181
163182 // Returns true if the expression types is possible given the target type
164183 pub fn is_possible ( & self , types : & ExpressionType < ' a > , ttyp : BaseType < ' a > ) -> bool {
165- self . implicit_matcher ( ) . is_possible ( types, ttyp)
184+ self . any_matcher ( ) . is_possible ( types, ttyp)
166185 }
167186
168187 pub fn common_type ( & self , typ1 : BaseType < ' a > , typ2 : BaseType < ' a > ) -> Option < BaseType < ' a > > {
@@ -189,7 +208,7 @@ impl<'a> AnalyzeContext<'a> {
189208 }
190209
191210 pub fn can_be_target_type ( & self , typ : TypeEnt < ' a > , ttyp : BaseType < ' a > ) -> bool {
192- self . implicit_matcher ( ) . can_be_target_type ( typ, ttyp)
211+ self . any_matcher ( ) . can_be_target_type ( typ, ttyp)
193212 }
194213
195214 pub fn expr_unknown_ttyp (
0 commit comments