@@ -40,13 +40,23 @@ pub enum Constant<T, RecordTag> {
4040 module : Option < ( EcoString , SrcSpan ) > ,
4141 name : EcoString ,
4242 arguments : Vec < CallArg < Self > > ,
43- spread : Option < Box < Self > > ,
4443 tag : RecordTag ,
4544 type_ : T ,
4645 field_map : Option < FieldMap > ,
4746 record_constructor : Option < Box < ValueConstructor > > ,
4847 } ,
4948
49+ RecordUpdate {
50+ location : SrcSpan ,
51+ module : Option < ( EcoString , SrcSpan ) > ,
52+ name : EcoString ,
53+ record : Box < Self > ,
54+ arguments : Vec < ConstantRecordUpdateArg < Self > > ,
55+ tag : RecordTag ,
56+ type_ : T ,
57+ field_map : Option < FieldMap > ,
58+ } ,
59+
5060 BitArray {
5161 location : SrcSpan ,
5262 segments : Vec < BitArraySegment < Self , T > > ,
@@ -86,6 +96,7 @@ impl TypedConstant {
8696 }
8797 Constant :: List { type_, .. }
8898 | Constant :: Record { type_, .. }
99+ | Constant :: RecordUpdate { type_, .. }
89100 | Constant :: Var { type_, .. }
90101 | Constant :: Invalid { type_, .. } => type_. clone ( ) ,
91102 }
@@ -105,12 +116,19 @@ impl TypedConstant {
105116 . iter ( )
106117 . find_map ( |element| element. find_node ( byte_index) )
107118 . unwrap_or ( Located :: Constant ( self ) ) ,
108- Constant :: Record {
109- arguments, spread, ..
110- } => arguments
119+ Constant :: Record { arguments, .. } => arguments
111120 . iter ( )
112121 . find_map ( |argument| argument. find_node ( byte_index) )
113- . or_else ( || spread. as_ref ( ) . and_then ( |s| s. find_node ( byte_index) ) )
122+ . unwrap_or ( Located :: Constant ( self ) ) ,
123+ Constant :: RecordUpdate {
124+ record, arguments, ..
125+ } => record
126+ . find_node ( byte_index)
127+ . or_else ( || {
128+ arguments
129+ . iter ( )
130+ . find_map ( |arg| arg. value . find_node ( byte_index) )
131+ } )
114132 . unwrap_or ( Located :: Constant ( self ) ) ,
115133 Constant :: BitArray { segments, .. } => segments
116134 . iter ( )
@@ -143,6 +161,7 @@ impl TypedConstant {
143161 } => value_constructor
144162 . as_ref ( )
145163 . map ( |constructor| constructor. definition_location ( ) ) ,
164+ Constant :: RecordUpdate { .. } => None ,
146165 }
147166 }
148167
@@ -160,17 +179,20 @@ impl TypedConstant {
160179 . map ( |element| element. referenced_variables ( ) )
161180 . fold ( im:: hashset![ ] , im:: HashSet :: union) ,
162181
163- Constant :: Record {
164- arguments, spread, ..
182+ Constant :: Record { arguments, .. } => arguments
183+ . iter ( )
184+ . map ( |argument| argument. value . referenced_variables ( ) )
185+ . fold ( im:: hashset![ ] , im:: HashSet :: union) ,
186+
187+ Constant :: RecordUpdate {
188+ record, arguments, ..
165189 } => {
190+ let record_vars = record. referenced_variables ( ) ;
166191 let arg_vars = arguments
167192 . iter ( )
168- . map ( |argument| argument . value . referenced_variables ( ) )
193+ . map ( |arg| arg . value . referenced_variables ( ) )
169194 . fold ( im:: hashset![ ] , im:: HashSet :: union) ;
170- match spread {
171- Some ( spread) => arg_vars. union ( spread. referenced_variables ( ) ) ,
172- None => arg_vars,
173- }
195+ record_vars. union ( arg_vars)
174196 }
175197
176198 Constant :: BitArray { segments, .. } => segments
@@ -258,6 +280,37 @@ impl TypedConstant {
258280 }
259281 ( Constant :: Record { .. } , _) => false ,
260282
283+ (
284+ Constant :: RecordUpdate {
285+ module,
286+ name,
287+ record,
288+ arguments,
289+ ..
290+ } ,
291+ Constant :: RecordUpdate {
292+ module : other_module,
293+ name : other_name,
294+ record : other_record,
295+ arguments : other_arguments,
296+ ..
297+ } ,
298+ ) => {
299+ let modules_are_equal = match ( module, other_module) {
300+ ( None , None ) => true ,
301+ ( None , Some ( _) ) | ( Some ( _) , None ) => false ,
302+ ( Some ( ( one, _) ) , Some ( ( other, _) ) ) => one == other,
303+ } ;
304+
305+ modules_are_equal
306+ && name == other_name
307+ && record. syntactically_eq ( other_record)
308+ && pairwise_all ( arguments, other_arguments, |( one, other) | {
309+ one. label == other. label && one. value . syntactically_eq ( & other. value )
310+ } )
311+ }
312+ ( Constant :: RecordUpdate { .. } , _) => false ,
313+
261314 (
262315 Constant :: BitArray { segments, .. } ,
263316 Constant :: BitArray {
@@ -317,6 +370,7 @@ impl<A, B> Constant<A, B> {
317370 | Constant :: Tuple { location, .. }
318371 | Constant :: String { location, .. }
319372 | Constant :: Record { location, .. }
373+ | Constant :: RecordUpdate { location, .. }
320374 | Constant :: BitArray { location, .. }
321375 | Constant :: Var { location, .. }
322376 | Constant :: Invalid { location, .. }
@@ -335,6 +389,7 @@ impl<A, B> Constant<A, B> {
335389 Constant :: Tuple { .. }
336390 | Constant :: List { .. }
337391 | Constant :: Record { .. }
392+ | Constant :: RecordUpdate { .. }
338393 | Constant :: BitArray { .. }
339394 | Constant :: StringConcatenation { .. }
340395 | Constant :: Invalid { .. } => false ,
@@ -357,3 +412,26 @@ impl<A, B> bit_array::GetLiteralValue for Constant<A, B> {
357412 }
358413 }
359414}
415+
416+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
417+ pub struct ConstantRecordUpdateArg < Constant > {
418+ pub label : EcoString ,
419+ pub location : SrcSpan ,
420+ pub value : Constant ,
421+ }
422+
423+ impl < Constant > ConstantRecordUpdateArg < Constant > {
424+ #[ must_use]
425+ pub fn uses_label_shorthand ( & self ) -> bool
426+ where
427+ Constant : HasLocation ,
428+ {
429+ self . value . location ( ) == self . location
430+ }
431+ }
432+
433+ impl < Constant > HasLocation for ConstantRecordUpdateArg < Constant > {
434+ fn location ( & self ) -> SrcSpan {
435+ self . location
436+ }
437+ }
0 commit comments