1
- //! An overload set represented as a static list .
1
+ //! An [`OverloadSet`] represented as a vector of rules .
2
2
3
3
use super :: one_bits_iter:: OneBitsIter ;
4
- use super :: { Conclusion , Rule } ;
4
+ use super :: Rule ;
5
5
6
6
use crate :: common:: DiagnosticDebug ;
7
7
use crate :: proc:: { GlobalCtx , TypeResolution } ;
8
8
9
+ use alloc:: sync:: Arc ;
9
10
use alloc:: vec:: Vec ;
10
11
use core:: fmt;
11
12
@@ -26,25 +27,19 @@ pub struct List {
26
27
/// is always more preferred than all subsequent rules in the
27
28
/// list. If there is no such arrangement of rules, then you
28
29
/// cannot use `List` to represent the overload set.
29
- rules : & ' static [ StaticRule ] ,
30
- }
31
-
32
- #[ derive( Clone ) ]
33
- pub struct StaticRule {
34
- pub subexpressions : & ' static [ crate :: TypeInner ] ,
35
- pub conclusion : crate :: TypeInner ,
30
+ rules : Arc < Vec < Rule > > ,
36
31
}
37
32
38
33
impl List {
39
34
#[ allow( dead_code) ]
40
- pub ( super ) const fn from_rules ( rules : & ' static [ StaticRule ] ) -> List {
35
+ pub ( super ) fn from_rules ( rules : Vec < Rule > ) -> List {
41
36
List {
42
37
members : len_to_full_mask ( rules. len ( ) ) ,
43
- rules,
38
+ rules : Arc :: new ( rules ) ,
44
39
}
45
40
}
46
41
47
- fn members ( & self ) -> impl Iterator < Item = ( u64 , & StaticRule ) > {
42
+ fn members ( & self ) -> impl Iterator < Item = ( u64 , & Rule ) > {
48
43
OneBitsIter :: new ( self . members ) . map ( |mask| {
49
44
let index = mask. trailing_zeros ( ) as usize ;
50
45
( mask, & self . rules [ index] )
@@ -53,7 +48,7 @@ impl List {
53
48
54
49
fn filter < F > ( & self , mut pred : F ) -> List
55
50
where
56
- F : FnMut ( & StaticRule ) -> bool ,
51
+ F : FnMut ( & Rule ) -> bool ,
57
52
{
58
53
let mut filtered_members = 0 ;
59
54
for ( mask, rule) in self . members ( ) {
@@ -64,20 +59,7 @@ impl List {
64
59
65
60
List {
66
61
members : filtered_members,
67
- rules : self . rules ,
68
- }
69
- }
70
- }
71
-
72
- impl StaticRule {
73
- fn to_rule ( & self ) -> Rule {
74
- Rule {
75
- subexpressions : self
76
- . subexpressions
77
- . iter ( )
78
- . map ( |inner| TypeResolution :: Value ( inner. clone ( ) ) )
79
- . collect ( ) ,
80
- conclusion : Conclusion :: Value ( self . conclusion . clone ( ) ) ,
62
+ rules : self . rules . clone ( ) ,
81
63
}
82
64
}
83
65
}
@@ -121,6 +103,7 @@ impl super::OverloadSet for List {
121
103
log:: debug!( " considering rule {:?}" , DiagnosticDebug ( ( rule, types) ) ) ;
122
104
match rule. subexpressions . get ( i) {
123
105
Some ( rule_ty) => {
106
+ let rule_ty = rule_ty. inner_with ( types) ;
124
107
if arg_ty. equivalent ( rule_ty, types) {
125
108
log:: debug!( " types are equivalent" ) ;
126
109
} else {
@@ -142,6 +125,7 @@ impl super::OverloadSet for List {
142
125
}
143
126
}
144
127
rule. subexpressions . get ( i) . is_some_and ( |rule_ty| {
128
+ let rule_ty = rule_ty. inner_with ( types) ;
145
129
arg_ty. equivalent ( rule_ty, types)
146
130
|| arg_ty. automatically_converts_to ( rule_ty, types) . is_some ( )
147
131
} )
@@ -152,27 +136,25 @@ impl super::OverloadSet for List {
152
136
self . filter ( |rule| {
153
137
rule. subexpressions
154
138
. iter ( )
155
- . all ( |arg_ty| !arg_ty. is_abstract ( types) )
139
+ . all ( |arg_ty| !arg_ty. inner_with ( types ) . is_abstract ( types) )
156
140
} )
157
141
}
158
142
159
143
fn most_preferred ( & self ) -> Option < Rule > {
160
144
// As documented for `Self::rules`, whatever rule is first is
161
145
// the most preferred. `OverloadSet` documents this method to
162
146
// panic if the set is empty.
163
- let ( _, static_rule ) = self . members ( ) . next ( ) . unwrap ( ) ;
164
- Some ( static_rule . to_rule ( ) )
147
+ let ( _, rule ) = self . members ( ) . next ( ) . unwrap ( ) ;
148
+ Some ( rule . clone ( ) )
165
149
}
166
150
167
151
fn overload_list ( & self , _gctx : & GlobalCtx < ' _ > ) -> Vec < Rule > {
168
- self . members ( )
169
- . map ( |( _, static_rule) | static_rule. to_rule ( ) )
170
- . collect ( )
152
+ self . members ( ) . map ( |( _, rule) | rule. clone ( ) ) . collect ( )
171
153
}
172
154
173
155
fn allowed_args ( & self , i : usize , _gctx : & GlobalCtx < ' _ > ) -> Vec < TypeResolution > {
174
156
self . members ( )
175
- . map ( |( _, rule) | TypeResolution :: Value ( rule. subexpressions [ i] . clone ( ) ) )
157
+ . map ( |( _, rule) | rule. subexpressions [ i] . clone ( ) )
176
158
. collect ( )
177
159
}
178
160
@@ -193,26 +175,11 @@ impl fmt::Debug for DiagnosticDebug<(&List, &GlobalCtx<'_>)> {
193
175
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
194
176
let ( list, ctx) = self . 0 ;
195
177
196
- f. debug_map ( )
178
+ f. debug_list ( )
197
179
. entries (
198
- list. members ( ) . map ( |( mask, rule) | {
199
- ( DiagnosticDebug ( ( rule, ctx. types ) ) , list. members & mask != 0 )
200
- } ) ,
180
+ list. members ( )
181
+ . map ( |( _mask, rule) | DiagnosticDebug ( ( rule, ctx. types ) ) ) ,
201
182
)
202
183
. finish ( )
203
184
}
204
185
}
205
-
206
- impl fmt:: Debug for DiagnosticDebug < ( & StaticRule , & crate :: UniqueArena < crate :: Type > ) > {
207
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
208
- let ( rule, arena) = self . 0 ;
209
- f. write_str ( "(" ) ?;
210
- for ( i, subexpression) in rule. subexpressions . iter ( ) . enumerate ( ) {
211
- if i > 0 {
212
- f. write_str ( ", " ) ?;
213
- }
214
- write ! ( f, "{:?}" , DiagnosticDebug ( ( subexpression, arena) ) ) ?;
215
- }
216
- write ! ( f, ") -> {:?}" , DiagnosticDebug ( ( & rule. conclusion, arena) ) )
217
- }
218
- }
0 commit comments