@@ -27,8 +27,7 @@ type AssociatedTyLookups = BTreeMap<(chalk_ir::TraitId<ChalkIr>, Ident), Associa
27
27
type AssociatedTyValueIds =
28
28
BTreeMap < ( chalk_ir:: ImplId < ChalkIr > , Ident ) , AssociatedTyValueId < ChalkIr > > ;
29
29
30
- type NamedGenericArg = chalk_ir:: WithKind < ChalkIr , Ident > ;
31
- type ParameterMap = BTreeMap < NamedGenericArg , BoundVar > ;
30
+ type ParameterMap = BTreeMap < Ident , chalk_ir:: WithKind < ChalkIr , BoundVar > > ;
32
31
33
32
pub type LowerResult < T > = Result < T , RustIrError > ;
34
33
@@ -70,85 +69,96 @@ struct AssociatedTyLookup {
70
69
addl_variable_kinds : Vec < chalk_ir:: VariableKind < ChalkIr > > ,
71
70
}
72
71
73
- enum TypeLookup {
74
- Struct ( chalk_ir:: StructId < ChalkIr > ) ,
75
- GenericArg ( BoundVar ) ,
76
- Opaque ( chalk_ir:: OpaqueTyId < ChalkIr > ) ,
77
- }
78
-
79
- enum LifetimeLookup {
80
- GenericArg ( BoundVar ) ,
81
- }
82
-
83
- enum ConstLookup {
84
- Parameter ( BoundVar ) ,
72
+ enum ApplyTypeLookup {
73
+ Struct ( StructId < ChalkIr > ) ,
85
74
}
86
75
87
76
const SELF : & str = "Self" ;
88
77
const FIXME_SELF : & str = "__FIXME_SELF__" ;
89
78
90
79
impl < ' k > Env < ' k > {
91
- fn lookup_type ( & self , name : & Identifier ) -> LowerResult < TypeLookup > {
92
- if let Some ( k) = self . parameter_map . get ( & NamedGenericArg :: new (
93
- chalk_ir:: VariableKind :: Ty ,
94
- name. str . clone ( ) ,
95
- ) ) {
96
- return Ok ( TypeLookup :: GenericArg ( * k) ) ;
80
+ fn lookup_generic_arg ( & self , name : Identifier ) -> LowerResult < chalk_ir:: GenericArg < ChalkIr > > {
81
+ let interner = self . interner ( ) ;
82
+
83
+ if let Some ( p) = self . parameter_map . get ( & name. str ) {
84
+ return match * p {
85
+ chalk_ir:: GenericArgData :: Ty ( b) => Ok ( chalk_ir:: TyData :: BoundVar ( b)
86
+ . intern ( interner)
87
+ . cast ( interner) ) ,
88
+ chalk_ir:: GenericArgData :: Lifetime ( b) => Ok ( chalk_ir:: LifetimeData :: BoundVar ( b)
89
+ . intern ( interner)
90
+ . cast ( interner) ) ,
91
+ chalk_ir:: GenericArgData :: Const ( b) => Ok ( chalk_ir:: ConstData :: BoundVar ( b)
92
+ . intern ( interner)
93
+ . cast ( interner) ) ,
94
+ } ;
97
95
}
98
96
99
97
if let Some ( id) = self . struct_ids . get ( & name. str ) {
100
- return Ok ( TypeLookup :: Struct ( * id) ) ;
98
+ let k = self . struct_kind ( * id) ;
99
+ if k. binders . len ( interner) > 0 {
100
+ return Err ( RustIrError :: IncorrectNumberOfTypeParameters {
101
+ identifier : name,
102
+ expected : k. binders . len ( interner) ,
103
+ actual : 0 ,
104
+ } ) ;
105
+ } else {
106
+ return Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
107
+ name : chalk_ir:: TypeName :: Struct ( * id) ,
108
+ substitution : chalk_ir:: Substitution :: empty ( interner) ,
109
+ } )
110
+ . intern ( interner)
111
+ . cast ( interner) ) ;
112
+ } ;
101
113
}
102
114
103
115
if let Some ( id) = self . opaque_ty_ids . get ( & name. str ) {
104
- return Ok ( TypeLookup :: Opaque ( * id) ) ;
116
+ return Ok (
117
+ chalk_ir:: TyData :: Alias ( chalk_ir:: AliasTy :: Opaque ( chalk_ir:: OpaqueTy {
118
+ opaque_ty_id : * id,
119
+ substitution : chalk_ir:: Substitution :: empty ( interner) ,
120
+ } ) )
121
+ . intern ( interner)
122
+ . cast ( interner) ,
123
+ ) ;
105
124
}
106
125
if let Some ( _) = self . trait_ids . get ( & name. str ) {
107
126
return Err ( RustIrError :: NotStruct ( name. clone ( ) ) ) ;
108
127
}
109
128
110
- Err ( RustIrError :: InvalidTypeName ( name. clone ( ) ) )
129
+ Err ( RustIrError :: InvalidParameterName ( name) )
111
130
}
112
131
113
- fn lookup_trait ( & self , name : & Identifier ) -> LowerResult < TraitId < ChalkIr > > {
114
- if let Some ( _) = self . parameter_map . get ( & NamedGenericArg :: new (
115
- chalk_ir:: VariableKind :: Ty ,
116
- name. str . clone ( ) ,
117
- ) ) {
118
- return Err ( RustIrError :: NotTrait ( name. clone ( ) ) ) ;
132
+ fn lookup_apply_type ( & self , name : Identifier ) -> LowerResult < ApplyTypeLookup > {
133
+ if let Some ( _) = self . parameter_map . get ( & name. str ) {
134
+ return Err ( RustIrError :: CannotApplyTypeParameter ( name) ) ;
119
135
}
120
136
121
- if let Some ( _) = self . struct_ids . get ( & name. str ) {
122
- return Err ( RustIrError :: NotTrait ( name. clone ( ) ) ) ;
137
+ if let Some ( _) = self . opaque_ty_ids . get ( & name. str ) {
138
+ return Err ( RustIrError :: CannotApplyTypeParameter ( name) ) ;
123
139
}
124
140
125
- if let Some ( id) = self . trait_ids . get ( & name. str ) {
126
- return Ok ( * id) ;
141
+ if let Some ( id) = self . struct_ids . get ( & name. str ) {
142
+ return Ok ( ApplyTypeLookup :: Struct ( * id) ) ;
127
143
}
128
144
129
- Err ( RustIrError :: InvalidTypeName ( name. clone ( ) ) )
145
+ Err ( RustIrError :: NotStruct ( name) )
130
146
}
131
147
132
- fn lookup_lifetime ( & self , name : & Identifier ) -> LowerResult < LifetimeLookup > {
133
- if let Some ( k) = self . parameter_map . get ( & NamedGenericArg :: new (
134
- chalk_ir:: VariableKind :: Lifetime ,
135
- name. str . clone ( ) ,
136
- ) ) {
137
- return Ok ( LifetimeLookup :: GenericArg ( * k) ) ;
148
+ fn lookup_trait ( & self , name : Identifier ) -> LowerResult < TraitId < ChalkIr > > {
149
+ if let Some ( _) = self . parameter_map . get ( & name. str ) {
150
+ return Err ( RustIrError :: NotTrait ( name) ) ;
138
151
}
139
152
140
- Err ( RustIrError :: InvalidLifetimeName ( name. clone ( ) ) )
141
- }
153
+ if let Some ( _) = self . struct_ids . get ( & name. str ) {
154
+ return Err ( RustIrError :: NotTrait ( name) ) ;
155
+ }
142
156
143
- fn lookup_const ( & self , name : Identifier ) -> LowerResult < ConstLookup > {
144
- if let Some ( k) = self
145
- . parameter_map
146
- . get ( & chalk_ir:: ParameterKind :: Const ( name. str ) )
147
- {
148
- return Ok ( ConstLookup :: Parameter ( * k) ) ;
157
+ if let Some ( id) = self . trait_ids . get ( & name. str ) {
158
+ return Ok ( * id) ;
149
159
}
150
160
151
- Err ( RustIrError :: InvalidConstName ( name) )
161
+ Err ( RustIrError :: InvalidTraitName ( name) )
152
162
}
153
163
154
164
fn struct_kind ( & self , id : chalk_ir:: StructId < ChalkIr > ) -> & TypeKind {
@@ -167,15 +177,23 @@ impl<'k> Env<'k> {
167
177
I : IntoIterator < Item = NamedGenericArg > ,
168
178
I :: IntoIter : ExactSizeIterator ,
169
179
{
180
+ // As binders to introduce we recieve `ParameterKind<Ident>`,
181
+ // which we need to transform into `(Ident, ParameterKind<BoundVar>)`,
182
+ // because that is the key-value pair for ParameterMap.
183
+ // `swap_inner` lets us do precisely that, replacing `Ident` inside
184
+ // `ParameterKind<Ident>` with a `BoundVar` and returning both.
170
185
let binders = binders
171
186
. into_iter ( )
172
187
. enumerate ( )
173
- . map ( |( i, k) | ( k , BoundVar :: new ( DebruijnIndex :: INNERMOST , i) ) ) ;
188
+ . map ( |( i, k) | k . swap_inner ( BoundVar :: new ( DebruijnIndex :: INNERMOST , i) ) ) ;
174
189
let len = binders. len ( ) ;
190
+
191
+ // For things already in the parameter map, we take each existing key-value pair
192
+ // `(Ident, ParameterKind<BoundVar>)` and shift in the inner `BoundVar`.
175
193
let parameter_map: ParameterMap = self
176
194
. parameter_map
177
195
. iter ( )
178
- . map ( |( k, v) | ( k. clone ( ) , v. shifted_in ( ) ) )
196
+ . map ( |( & k, & v) | ( k, v. map ( |b| b . shifted_in ( ) ) ) )
179
197
. chain ( binders)
180
198
. collect ( ) ;
181
199
if parameter_map. len ( ) != self . parameter_map . len ( ) + len {
@@ -535,6 +553,7 @@ trait LowerParameterMap {
535
553
self . all_parameters ( )
536
554
. into_iter ( )
537
555
. zip ( ( 0 ..) . map ( |i| BoundVar :: new ( DebruijnIndex :: INNERMOST , i) ) )
556
+ . map ( |( k, v) | k. swap_inner ( v) )
538
557
. collect ( )
539
558
}
540
559
@@ -808,17 +827,7 @@ impl LowerLeafGoal for LeafGoal {
808
827
LeafGoal :: DomainGoal { goal } => {
809
828
chalk_ir:: Goal :: all ( interner, goal. lower ( env) ?. into_iter ( ) . casted ( interner) )
810
829
}
811
- LeafGoal :: UnifyTys { a, b } => chalk_ir:: EqGoal {
812
- a : a. lower ( env) ?. cast ( interner) ,
813
- b : b. lower ( env) ?. cast ( interner) ,
814
- }
815
- . cast :: < chalk_ir:: Goal < ChalkIr > > ( interner) ,
816
- LeafGoal :: UnifyLifetimes { ref a, ref b } => chalk_ir:: EqGoal {
817
- a : a. lower ( env) ?. cast ( interner) ,
818
- b : b. lower ( env) ?. cast ( interner) ,
819
- }
820
- . cast :: < chalk_ir:: Goal < ChalkIr > > ( interner) ,
821
- LeafGoal :: UnifyConsts { ref a, ref b } => chalk_ir:: EqGoal {
830
+ LeafGoal :: UnifyGenericArgs { a, b } => chalk_ir:: EqGoal {
822
831
a : a. lower ( env) ?. cast ( interner) ,
823
832
b : b. lower ( env) ?. cast ( interner) ,
824
833
}
@@ -1122,34 +1131,17 @@ trait LowerTy {
1122
1131
impl LowerTy for Ty {
1123
1132
fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: Ty < ChalkIr > > {
1124
1133
let interner = env. interner ( ) ;
1125
- match self {
1126
- Ty :: Id { name } => match env. lookup_type ( name) ? {
1127
- TypeLookup :: Struct ( id) => {
1128
- let k = env. struct_kind ( id) ;
1129
- if k. binders . len ( interner) > 0 {
1130
- Err ( RustIrError :: IncorrectNumberOfTypeParameters {
1131
- identifier : name. clone ( ) ,
1132
- expected : k. binders . len ( interner) ,
1133
- actual : 0 ,
1134
- } )
1135
- } else {
1136
- Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
1137
- name : chalk_ir:: TypeName :: Struct ( id) ,
1138
- substitution : chalk_ir:: Substitution :: empty ( interner) ,
1139
- } )
1140
- . intern ( interner) )
1134
+ match * self {
1135
+ Ty :: Id { name } => {
1136
+ let parameter = env. lookup_parameter ( name) ?;
1137
+ parameter. ty ( interner) . map ( |ty| ty. clone ( ) ) . ok_or_else ( || {
1138
+ RustIrError :: IncorrectParameterKind {
1139
+ identifier : name,
1140
+ expected : Kind :: Ty ,
1141
+ actual : parameter. kind ( ) ,
1141
1142
}
1142
- }
1143
- TypeLookup :: GenericArg ( d) => Ok ( chalk_ir:: TyData :: BoundVar ( d) . intern ( interner) ) ,
1144
- TypeLookup :: Opaque ( id) => Ok ( chalk_ir:: TyData :: Alias ( chalk_ir:: AliasTy :: Opaque (
1145
- chalk_ir:: OpaqueTy {
1146
- opaque_ty_id : id,
1147
- substitution : chalk_ir:: Substitution :: empty ( interner) ,
1148
- } ,
1149
- ) )
1150
- . intern ( interner) ) ,
1151
- } ,
1152
-
1143
+ } )
1144
+ }
1153
1145
Ty :: Dyn { ref bounds } => Ok ( chalk_ir:: TyData :: Dyn ( chalk_ir:: DynTy {
1154
1146
bounds : env. in_binders (
1155
1147
// FIXME: Figure out a proper name for this type parameter
@@ -1177,11 +1169,8 @@ impl LowerTy for Ty {
1177
1169
. intern ( interner) ) ,
1178
1170
1179
1171
Ty :: Apply { name, ref args } => {
1180
- let id = match env. lookup_type ( name) ? {
1181
- TypeLookup :: Struct ( id) => id,
1182
- TypeLookup :: GenericArg ( _) | TypeLookup :: Opaque ( _) => {
1183
- Err ( RustIrError :: CannotApplyTypeParameter ( name. clone ( ) ) ) ?
1184
- }
1172
+ let id = match env. lookup_apply_type ( name) ? {
1173
+ ApplyTypeLookup :: Struct ( id) => id,
1185
1174
} ;
1186
1175
1187
1176
let k = env. struct_kind ( id) ;
@@ -1198,7 +1187,12 @@ impl LowerTy for Ty {
1198
1187
args. iter ( ) . map ( |t| Ok ( t. lower ( env) ?) ) ,
1199
1188
) ?;
1200
1189
1201
- for ( param, arg) in k. binders . binders . iter ( interner) . zip ( args. iter ( ) ) {
1190
+ for ( param, arg) in k
1191
+ . binders
1192
+ . binders
1193
+ . iter ( interner)
1194
+ . zip ( substitution. iter ( interner) )
1195
+ {
1202
1196
if param. kind ( ) != arg. kind ( ) {
1203
1197
Err ( RustIrError :: IncorrectParameterKind {
1204
1198
identifier : name. clone ( ) ,
@@ -1307,30 +1301,14 @@ impl LowerGenericArg for GenericArg {
1307
1301
fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: GenericArg < ChalkIr > > {
1308
1302
let interner = env. interner ( ) ;
1309
1303
match * self {
1310
- GenericArg :: Ty ( ref t) => Ok ( t. lower ( env) ?. cast ( interner) ) ,
1311
- GenericArg :: Lifetime ( ref l) => Ok ( l. lower ( env) ?. cast ( interner) ) ,
1312
- GenericArg :: Const ( ref c) => Ok ( c. lower ( env) ?. cast ( interner) ) ,
1313
- }
1314
- }
1315
- }
1316
-
1317
- trait LowerConst {
1318
- fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: Const < ChalkIr > > ;
1319
- }
1320
-
1321
- impl LowerConst for Const {
1322
- fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: Const < ChalkIr > > {
1323
- let interner = env. interner ( ) ;
1324
- match * self {
1325
- Const :: Id { name } => match env. lookup_const ( name) ? {
1326
- ConstLookup :: Parameter ( d) => Ok ( chalk_ir:: ConstData :: BoundVar ( d) . intern ( interner) ) ,
1327
- } ,
1328
- Const :: Value { value } => {
1329
- Ok (
1330
- chalk_ir:: ConstData :: Concrete ( chalk_ir:: ConcreteConst { interned : value } )
1331
- . intern ( interner) ,
1332
- )
1333
- }
1304
+ Parameter :: Ty ( ref t) => Ok ( t. lower ( env) ?. cast ( interner) ) ,
1305
+ Parameter :: Lifetime ( ref l) => Ok ( l. lower ( env) ?. cast ( interner) ) ,
1306
+ Parameter :: Id ( name) => env. lookup_parameter ( name) ,
1307
+ Parameter :: ConstValue ( value) => Ok ( chalk_ir:: ConstData :: Concrete (
1308
+ chalk_ir:: ConcreteConst { interned : value } ,
1309
+ )
1310
+ . intern ( interner)
1311
+ . cast ( interner) ) ,
1334
1312
}
1335
1313
}
1336
1314
}
@@ -1342,12 +1320,18 @@ trait LowerLifetime {
1342
1320
impl LowerLifetime for Lifetime {
1343
1321
fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: Lifetime < ChalkIr > > {
1344
1322
let interner = env. interner ( ) ;
1345
- match self {
1346
- Lifetime :: Id { name } => match env. lookup_lifetime ( name) ? {
1347
- LifetimeLookup :: GenericArg ( d) => {
1348
- Ok ( chalk_ir:: LifetimeData :: BoundVar ( d) . intern ( interner) )
1349
- }
1350
- } ,
1323
+ match * self {
1324
+ Lifetime :: Id { name } => {
1325
+ let parameter = env. lookup_parameter ( name) ?;
1326
+ parameter
1327
+ . lifetime ( interner)
1328
+ . map ( |l| l. clone ( ) )
1329
+ . ok_or_else ( || RustIrError :: IncorrectParameterKind {
1330
+ identifier : name,
1331
+ expected : Kind :: Lifetime ,
1332
+ actual : parameter. kind ( ) ,
1333
+ } )
1334
+ }
1351
1335
}
1352
1336
}
1353
1337
}
0 commit comments