@@ -3,6 +3,15 @@ use std::{fmt::Debug, hash::Hash};
3
3
use ena:: unify:: { InPlaceUnificationTable , UnifyKey } ;
4
4
use rustc_hash:: FxHashMap ;
5
5
6
+ /// Represents a definition that contains a direct reference to itself.
7
+ ///
8
+ /// Recursive definitions are not valid and must be reported to the user.
9
+ /// It is preferable to group definitions together such that recursions
10
+ /// are reported in-whole rather than separately. `RecursiveDef` can be
11
+ /// used with `RecursiveDefHelper` to perform this grouping operation.
12
+ ///
13
+ /// The fields `from` and `to` are the relevant identifiers and `site` can
14
+ /// be used to carry diagnostic information.
6
15
#[ derive( Eq , PartialEq , Clone , Debug , Hash ) ]
7
16
pub struct RecursiveDef < T , U >
8
17
where
58
67
let mut table = InPlaceUnificationTable :: new ( ) ;
59
68
let keys: FxHashMap < _ , _ > = defs
60
69
. iter ( )
61
- . map ( |def : & RecursiveDef < T , U > | ( def. from , table. new_key ( ( ) ) ) )
70
+ . map ( |def| ( def. from , table. new_key ( ( ) ) ) )
62
71
. collect ( ) ;
63
72
64
73
for def in defs. iter ( ) {
68
77
Self { defs, table, keys }
69
78
}
70
79
80
+ /// Removes a disjoint set of recursive definitions from the helper
81
+ /// and returns it, if one exists.
71
82
pub fn remove_disjoint_set ( & mut self ) -> Option < Vec < RecursiveDef < T , U > > > {
72
83
let mut disjoint_set = vec ! [ ] ;
73
84
let mut remaining_set = vec ! [ ] ;
@@ -99,10 +110,7 @@ where
99
110
100
111
#[ test]
101
112
fn one_recursion ( ) {
102
- let defs = vec ! [
103
- RecursiveDef :: new( 0 , 1 , ( ( ) , ( ) ) ) ,
104
- RecursiveDef :: new( 1 , 0 , ( ( ) , ( ) ) ) ,
105
- ] ;
113
+ let defs = vec ! [ RecursiveDef :: new( 0 , 1 , ( ) ) , RecursiveDef :: new( 1 , 0 , ( ) ) ] ;
106
114
107
115
let mut helper = RecursiveDefHelper :: new ( defs) ;
108
116
let disjoint_constituents = helper. remove_disjoint_set ( ) ;
@@ -114,11 +122,11 @@ fn one_recursion() {
114
122
#[ test]
115
123
fn two_recursions ( ) {
116
124
let defs = vec ! [
117
- RecursiveDef :: new( 0 , 1 , ( ( ) , ( ) ) ) ,
118
- RecursiveDef :: new( 1 , 0 , ( ( ) , ( ) ) ) ,
119
- RecursiveDef :: new( 2 , 3 , ( ( ) , ( ) ) ) ,
120
- RecursiveDef :: new( 3 , 4 , ( ( ) , ( ) ) ) ,
121
- RecursiveDef :: new( 4 , 2 , ( ( ) , ( ) ) ) ,
125
+ RecursiveDef :: new( 0 , 1 , ( ) ) ,
126
+ RecursiveDef :: new( 1 , 0 , ( ) ) ,
127
+ RecursiveDef :: new( 2 , 3 , ( ) ) ,
128
+ RecursiveDef :: new( 3 , 4 , ( ) ) ,
129
+ RecursiveDef :: new( 4 , 2 , ( ) ) ,
122
130
] ;
123
131
124
132
let mut helper = RecursiveDefHelper :: new ( defs) ;
0 commit comments