@@ -26,7 +26,7 @@ type TraitKinds = BTreeMap<chalk_ir::TraitId<ChalkIr>, TypeKind>;
26
26
type AssociatedTyLookups = BTreeMap < ( chalk_ir:: TraitId < ChalkIr > , Ident ) , AssociatedTyLookup > ;
27
27
type AssociatedTyValueIds =
28
28
BTreeMap < ( chalk_ir:: ImplId < ChalkIr > , Ident ) , AssociatedTyValueId < ChalkIr > > ;
29
- type ParameterMap = BTreeMap < chalk_ir:: ParameterKind < Ident > , BoundVar > ;
29
+ type ParameterMap = BTreeMap < Ident , chalk_ir:: ParameterKind < BoundVar > > ;
30
30
31
31
pub type LowerResult < T > = Result < T , RustIrError > ;
32
32
@@ -68,85 +68,96 @@ struct AssociatedTyLookup {
68
68
addl_parameter_kinds : Vec < chalk_ir:: ParameterKind < ( ) > > ,
69
69
}
70
70
71
- enum TypeLookup {
72
- Struct ( chalk_ir:: StructId < ChalkIr > ) ,
73
- Parameter ( BoundVar ) ,
74
- Opaque ( chalk_ir:: OpaqueTyId < ChalkIr > ) ,
75
- }
76
-
77
- enum LifetimeLookup {
78
- Parameter ( BoundVar ) ,
79
- }
80
-
81
- enum ConstLookup {
82
- Parameter ( BoundVar ) ,
71
+ enum ApplyTypeLookup {
72
+ Struct ( StructId < ChalkIr > ) ,
83
73
}
84
74
85
75
const SELF : & str = "Self" ;
86
76
const FIXME_SELF : & str = "__FIXME_SELF__" ;
87
77
88
78
impl < ' k > Env < ' k > {
89
- fn lookup_type ( & self , name : Identifier ) -> LowerResult < TypeLookup > {
90
- if let Some ( k) = self
91
- . parameter_map
92
- . get ( & chalk_ir:: ParameterKind :: Ty ( name. str ) )
93
- {
94
- return Ok ( TypeLookup :: Parameter ( * k) ) ;
79
+ fn lookup_parameter ( & self , name : Identifier ) -> LowerResult < chalk_ir:: Parameter < ChalkIr > > {
80
+ let interner = self . interner ( ) ;
81
+
82
+ if let Some ( p) = self . parameter_map . get ( & name. str ) {
83
+ return match * p {
84
+ chalk_ir:: ParameterKind :: Ty ( b) => Ok ( chalk_ir:: TyData :: BoundVar ( b)
85
+ . intern ( interner)
86
+ . cast ( interner) ) ,
87
+ chalk_ir:: ParameterKind :: Lifetime ( b) => Ok ( chalk_ir:: LifetimeData :: BoundVar ( b)
88
+ . intern ( interner)
89
+ . cast ( interner) ) ,
90
+ chalk_ir:: ParameterKind :: Const ( b) => Ok ( chalk_ir:: ConstData :: BoundVar ( b)
91
+ . intern ( interner)
92
+ . cast ( interner) ) ,
93
+ } ;
95
94
}
96
95
97
96
if let Some ( id) = self . struct_ids . get ( & name. str ) {
98
- return Ok ( TypeLookup :: Struct ( * id) ) ;
97
+ let k = self . struct_kind ( * id) ;
98
+ if k. binders . len ( interner) > 0 {
99
+ return Err ( RustIrError :: IncorrectNumberOfTypeParameters {
100
+ identifier : name,
101
+ expected : k. binders . len ( interner) ,
102
+ actual : 0 ,
103
+ } ) ;
104
+ } else {
105
+ return Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
106
+ name : chalk_ir:: TypeName :: Struct ( * id) ,
107
+ substitution : chalk_ir:: Substitution :: empty ( interner) ,
108
+ } )
109
+ . intern ( interner)
110
+ . cast ( interner) ) ;
111
+ } ;
99
112
}
100
113
101
114
if let Some ( id) = self . opaque_ty_ids . get ( & name. str ) {
102
- return Ok ( TypeLookup :: Opaque ( * id) ) ;
115
+ return Ok (
116
+ chalk_ir:: TyData :: Alias ( chalk_ir:: AliasTy :: Opaque ( chalk_ir:: OpaqueTy {
117
+ opaque_ty_id : * id,
118
+ substitution : chalk_ir:: Substitution :: empty ( interner) ,
119
+ } ) )
120
+ . intern ( interner)
121
+ . cast ( interner) ,
122
+ ) ;
103
123
}
104
124
if let Some ( _) = self . trait_ids . get ( & name. str ) {
105
125
return Err ( RustIrError :: NotStruct ( name) ) ;
106
126
}
107
127
108
- Err ( RustIrError :: InvalidTypeName ( name) )
128
+ Err ( RustIrError :: InvalidParameterName ( name) )
109
129
}
110
130
111
- fn lookup_trait ( & self , name : Identifier ) -> LowerResult < TraitId < ChalkIr > > {
112
- if let Some ( _) = self
113
- . parameter_map
114
- . get ( & chalk_ir:: ParameterKind :: Ty ( name. str ) )
115
- {
116
- return Err ( RustIrError :: NotTrait ( name) ) ;
131
+ fn lookup_apply_type ( & self , name : Identifier ) -> LowerResult < ApplyTypeLookup > {
132
+ if let Some ( _) = self . parameter_map . get ( & name. str ) {
133
+ return Err ( RustIrError :: CannotApplyTypeParameter ( name) ) ;
117
134
}
118
135
119
- if let Some ( _) = self . struct_ids . get ( & name. str ) {
120
- return Err ( RustIrError :: NotTrait ( name) ) ;
136
+ if let Some ( _) = self . opaque_ty_ids . get ( & name. str ) {
137
+ return Err ( RustIrError :: CannotApplyTypeParameter ( name) ) ;
121
138
}
122
139
123
- if let Some ( id) = self . trait_ids . get ( & name. str ) {
124
- return Ok ( * id) ;
140
+ if let Some ( id) = self . struct_ids . get ( & name. str ) {
141
+ return Ok ( ApplyTypeLookup :: Struct ( * id) ) ;
125
142
}
126
143
127
- Err ( RustIrError :: InvalidTypeName ( name) )
144
+ Err ( RustIrError :: NotStruct ( name) )
128
145
}
129
146
130
- fn lookup_lifetime ( & self , name : Identifier ) -> LowerResult < LifetimeLookup > {
131
- if let Some ( k) = self
132
- . parameter_map
133
- . get ( & chalk_ir:: ParameterKind :: Lifetime ( name. str ) )
134
- {
135
- return Ok ( LifetimeLookup :: Parameter ( * k) ) ;
147
+ fn lookup_trait ( & self , name : Identifier ) -> LowerResult < TraitId < ChalkIr > > {
148
+ if let Some ( _) = self . parameter_map . get ( & name. str ) {
149
+ return Err ( RustIrError :: NotTrait ( name) ) ;
136
150
}
137
151
138
- Err ( RustIrError :: InvalidLifetimeName ( name) )
139
- }
152
+ if let Some ( _) = self . struct_ids . get ( & name. str ) {
153
+ return Err ( RustIrError :: NotTrait ( name) ) ;
154
+ }
140
155
141
- fn lookup_const ( & self , name : Identifier ) -> LowerResult < ConstLookup > {
142
- if let Some ( k) = self
143
- . parameter_map
144
- . get ( & chalk_ir:: ParameterKind :: Const ( name. str ) )
145
- {
146
- return Ok ( ConstLookup :: Parameter ( * k) ) ;
156
+ if let Some ( id) = self . trait_ids . get ( & name. str ) {
157
+ return Ok ( * id) ;
147
158
}
148
159
149
- Err ( RustIrError :: InvalidConstName ( name) )
160
+ Err ( RustIrError :: InvalidTraitName ( name) )
150
161
}
151
162
152
163
fn struct_kind ( & self , id : chalk_ir:: StructId < ChalkIr > ) -> & TypeKind {
@@ -165,15 +176,23 @@ impl<'k> Env<'k> {
165
176
I : IntoIterator < Item = chalk_ir:: ParameterKind < Ident > > ,
166
177
I :: IntoIter : ExactSizeIterator ,
167
178
{
179
+ // As binders to introduce we recieve `ParameterKind<Ident>`,
180
+ // which we need to transform into `(Ident, ParameterKind<BoundVar>)`,
181
+ // because that is the key-value pair for ParameterMap.
182
+ // `swap_inner` lets us do precisely that, replacing `Ident` inside
183
+ // `ParameterKind<Ident>` with a `BoundVar` and returning both.
168
184
let binders = binders
169
185
. into_iter ( )
170
186
. enumerate ( )
171
- . map ( |( i, k) | ( k , BoundVar :: new ( DebruijnIndex :: INNERMOST , i) ) ) ;
187
+ . map ( |( i, k) | k . swap_inner ( BoundVar :: new ( DebruijnIndex :: INNERMOST , i) ) ) ;
172
188
let len = binders. len ( ) ;
189
+
190
+ // For things already in the parameter map, we take each existing key-value pair
191
+ // `(Ident, ParameterKind<BoundVar>)` and shift in the inner `BoundVar`.
173
192
let parameter_map: ParameterMap = self
174
193
. parameter_map
175
194
. iter ( )
176
- . map ( |( & k, & v) | ( k, v. shifted_in ( ) ) )
195
+ . map ( |( & k, & v) | ( k, v. map ( |b| b . shifted_in ( ) ) ) )
177
196
. chain ( binders)
178
197
. collect ( ) ;
179
198
if parameter_map. len ( ) != self . parameter_map . len ( ) + len {
@@ -521,6 +540,7 @@ trait LowerParameterMap {
521
540
self . all_parameters ( )
522
541
. into_iter ( )
523
542
. zip ( ( 0 ..) . map ( |i| BoundVar :: new ( DebruijnIndex :: INNERMOST , i) ) )
543
+ . map ( |( k, v) | k. swap_inner ( v) )
524
544
. collect ( )
525
545
}
526
546
@@ -787,17 +807,7 @@ impl LowerLeafGoal for LeafGoal {
787
807
LeafGoal :: DomainGoal { goal } => {
788
808
chalk_ir:: Goal :: all ( interner, goal. lower ( env) ?. into_iter ( ) . casted ( interner) )
789
809
}
790
- LeafGoal :: UnifyTys { a, b } => chalk_ir:: EqGoal {
791
- a : a. lower ( env) ?. cast ( interner) ,
792
- b : b. lower ( env) ?. cast ( interner) ,
793
- }
794
- . cast :: < chalk_ir:: Goal < ChalkIr > > ( interner) ,
795
- LeafGoal :: UnifyLifetimes { ref a, ref b } => chalk_ir:: EqGoal {
796
- a : a. lower ( env) ?. cast ( interner) ,
797
- b : b. lower ( env) ?. cast ( interner) ,
798
- }
799
- . cast :: < chalk_ir:: Goal < ChalkIr > > ( interner) ,
800
- LeafGoal :: UnifyConsts { ref a, ref b } => chalk_ir:: EqGoal {
810
+ LeafGoal :: UnifyParameters { a, b } => chalk_ir:: EqGoal {
801
811
a : a. lower ( env) ?. cast ( interner) ,
802
812
b : b. lower ( env) ?. cast ( interner) ,
803
813
}
@@ -1096,33 +1106,16 @@ impl LowerTy for Ty {
1096
1106
fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: Ty < ChalkIr > > {
1097
1107
let interner = env. interner ( ) ;
1098
1108
match * self {
1099
- Ty :: Id { name } => match env. lookup_type ( name) ? {
1100
- TypeLookup :: Struct ( id) => {
1101
- let k = env. struct_kind ( id) ;
1102
- if k. binders . len ( interner) > 0 {
1103
- Err ( RustIrError :: IncorrectNumberOfTypeParameters {
1104
- identifier : name,
1105
- expected : k. binders . len ( interner) ,
1106
- actual : 0 ,
1107
- } )
1108
- } else {
1109
- Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
1110
- name : chalk_ir:: TypeName :: Struct ( id) ,
1111
- substitution : chalk_ir:: Substitution :: empty ( interner) ,
1112
- } )
1113
- . intern ( interner) )
1109
+ Ty :: Id { name } => {
1110
+ let parameter = env. lookup_parameter ( name) ?;
1111
+ parameter. ty ( interner) . map ( |ty| ty. clone ( ) ) . ok_or_else ( || {
1112
+ RustIrError :: IncorrectParameterKind {
1113
+ identifier : name,
1114
+ expected : Kind :: Ty ,
1115
+ actual : parameter. kind ( ) ,
1114
1116
}
1115
- }
1116
- TypeLookup :: Parameter ( d) => Ok ( chalk_ir:: TyData :: BoundVar ( d) . intern ( interner) ) ,
1117
- TypeLookup :: Opaque ( id) => Ok ( chalk_ir:: TyData :: Alias ( chalk_ir:: AliasTy :: Opaque (
1118
- chalk_ir:: OpaqueTy {
1119
- opaque_ty_id : id,
1120
- substitution : chalk_ir:: Substitution :: empty ( interner) ,
1121
- } ,
1122
- ) )
1123
- . intern ( interner) ) ,
1124
- } ,
1125
-
1117
+ } )
1118
+ }
1126
1119
Ty :: Dyn { ref bounds } => Ok ( chalk_ir:: TyData :: Dyn ( chalk_ir:: DynTy {
1127
1120
bounds : env. in_binders (
1128
1121
// FIXME: Figure out a proper name for this type parameter
@@ -1147,11 +1140,8 @@ impl LowerTy for Ty {
1147
1140
. intern ( interner) ) ,
1148
1141
1149
1142
Ty :: Apply { name, ref args } => {
1150
- let id = match env. lookup_type ( name) ? {
1151
- TypeLookup :: Struct ( id) => id,
1152
- TypeLookup :: Parameter ( _) | TypeLookup :: Opaque ( _) => {
1153
- Err ( RustIrError :: CannotApplyTypeParameter ( name) ) ?
1154
- }
1143
+ let id = match env. lookup_apply_type ( name) ? {
1144
+ ApplyTypeLookup :: Struct ( id) => id,
1155
1145
} ;
1156
1146
1157
1147
let k = env. struct_kind ( id) ;
@@ -1168,7 +1158,12 @@ impl LowerTy for Ty {
1168
1158
args. iter ( ) . map ( |t| Ok ( t. lower ( env) ?) ) ,
1169
1159
) ?;
1170
1160
1171
- for ( param, arg) in k. binders . binders . iter ( interner) . zip ( args. iter ( ) ) {
1161
+ for ( param, arg) in k
1162
+ . binders
1163
+ . binders
1164
+ . iter ( interner)
1165
+ . zip ( substitution. iter ( interner) )
1166
+ {
1172
1167
if param. kind ( ) != arg. kind ( ) {
1173
1168
Err ( RustIrError :: IncorrectParameterKind {
1174
1169
identifier : name,
@@ -1237,28 +1232,12 @@ impl LowerParameter for Parameter {
1237
1232
match * self {
1238
1233
Parameter :: Ty ( ref t) => Ok ( t. lower ( env) ?. cast ( interner) ) ,
1239
1234
Parameter :: Lifetime ( ref l) => Ok ( l. lower ( env) ?. cast ( interner) ) ,
1240
- Parameter :: Const ( ref c) => Ok ( c. lower ( env) ?. cast ( interner) ) ,
1241
- }
1242
- }
1243
- }
1244
-
1245
- trait LowerConst {
1246
- fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: Const < ChalkIr > > ;
1247
- }
1248
-
1249
- impl LowerConst for Const {
1250
- fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: Const < ChalkIr > > {
1251
- let interner = env. interner ( ) ;
1252
- match * self {
1253
- Const :: Id { name } => match env. lookup_const ( name) ? {
1254
- ConstLookup :: Parameter ( d) => Ok ( chalk_ir:: ConstData :: BoundVar ( d) . intern ( interner) ) ,
1255
- } ,
1256
- Const :: Value { value } => {
1257
- Ok (
1258
- chalk_ir:: ConstData :: Concrete ( chalk_ir:: ConcreteConst { interned : value } )
1259
- . intern ( interner) ,
1260
- )
1261
- }
1235
+ Parameter :: Id ( name) => env. lookup_parameter ( name) ,
1236
+ Parameter :: ConstValue ( value) => Ok ( chalk_ir:: ConstData :: Concrete (
1237
+ chalk_ir:: ConcreteConst { interned : value } ,
1238
+ )
1239
+ . intern ( interner)
1240
+ . cast ( interner) ) ,
1262
1241
}
1263
1242
}
1264
1243
}
@@ -1271,11 +1250,17 @@ impl LowerLifetime for Lifetime {
1271
1250
fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: Lifetime < ChalkIr > > {
1272
1251
let interner = env. interner ( ) ;
1273
1252
match * self {
1274
- Lifetime :: Id { name } => match env. lookup_lifetime ( name) ? {
1275
- LifetimeLookup :: Parameter ( d) => {
1276
- Ok ( chalk_ir:: LifetimeData :: BoundVar ( d) . intern ( interner) )
1277
- }
1278
- } ,
1253
+ Lifetime :: Id { name } => {
1254
+ let parameter = env. lookup_parameter ( name) ?;
1255
+ parameter
1256
+ . lifetime ( interner)
1257
+ . map ( |l| l. clone ( ) )
1258
+ . ok_or_else ( || RustIrError :: IncorrectParameterKind {
1259
+ identifier : name,
1260
+ expected : Kind :: Lifetime ,
1261
+ actual : parameter. kind ( ) ,
1262
+ } )
1263
+ }
1279
1264
}
1280
1265
}
1281
1266
}
@@ -1575,16 +1560,6 @@ impl Kinded for ParameterKind {
1575
1560
}
1576
1561
}
1577
1562
1578
- impl Kinded for Parameter {
1579
- fn kind ( & self ) -> Kind {
1580
- match * self {
1581
- Parameter :: Ty ( _) => Kind :: Ty ,
1582
- Parameter :: Lifetime ( _) => Kind :: Lifetime ,
1583
- Parameter :: Const ( _) => Kind :: Const ,
1584
- }
1585
- }
1586
- }
1587
-
1588
1563
impl < T , L , C > Kinded for chalk_ir:: ParameterKind < T , L , C > {
1589
1564
fn kind ( & self ) -> Kind {
1590
1565
match * self {
0 commit comments