@@ -1135,6 +1135,36 @@ private Type inferCallExprBaseType(AstNode n, TypePath path) {
1135
1135
)
1136
1136
}
1137
1137
1138
+ pragma [ inline]
1139
+ private Type inferRootTypeDeref ( AstNode n ) {
1140
+ result = inferType ( n ) and
1141
+ result != TRefType ( )
1142
+ or
1143
+ // for reference types, lookup members in the type being referenced
1144
+ result = inferType ( n , TypePath:: singleton ( TRefTypeParameter ( ) ) )
1145
+ }
1146
+
1147
+ pragma [ nomagic]
1148
+ private Type getFieldExprLookupType ( FieldExpr fe , string name ) {
1149
+ result = inferRootTypeDeref ( fe .getContainer ( ) ) and name = fe .getIdentifier ( ) .getText ( )
1150
+ }
1151
+
1152
+ pragma [ nomagic]
1153
+ private Type getTupleFieldExprLookupType ( FieldExpr fe , int pos ) {
1154
+ exists ( string name |
1155
+ result = getFieldExprLookupType ( fe , name ) and
1156
+ pos = name .toInt ( )
1157
+ )
1158
+ }
1159
+
1160
+ pragma [ nomagic]
1161
+ private TupleTypeParameter resolveTupleTypeFieldExpr ( FieldExpr fe ) {
1162
+ exists ( int arity , int i |
1163
+ TTuple ( arity ) = getTupleFieldExprLookupType ( fe , i ) and
1164
+ result = TTupleTypeParameter ( arity , i )
1165
+ )
1166
+ }
1167
+
1138
1168
/**
1139
1169
* A matching configuration for resolving types of field expressions
1140
1170
* like `x.field`.
@@ -1158,15 +1188,30 @@ private module FieldExprMatchingInput implements MatchingInputSig {
1158
1188
}
1159
1189
}
1160
1190
1161
- abstract class Declaration extends AstNode {
1191
+ private newtype TDeclaration =
1192
+ TStructFieldDecl ( StructField sf ) or
1193
+ TTupleFieldDecl ( TupleField tf ) or
1194
+ TTupleTypeParameterDecl ( TupleTypeParameter ttp )
1195
+
1196
+ abstract class Declaration extends TDeclaration {
1162
1197
TypeParameter getTypeParameter ( TypeParameterPosition ppos ) { none ( ) }
1163
1198
1199
+ abstract Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) ;
1200
+
1201
+ abstract string toString ( ) ;
1202
+
1203
+ abstract Location getLocation ( ) ;
1204
+ }
1205
+
1206
+ abstract private class StructOrTupleFieldDecl extends Declaration {
1207
+ abstract AstNode getAstNode ( ) ;
1208
+
1164
1209
abstract TypeRepr getTypeRepr ( ) ;
1165
1210
1166
- Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) {
1211
+ override Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) {
1167
1212
dpos .isSelf ( ) and
1168
1213
// no case for variants as those can only be destructured using pattern matching
1169
- exists ( Struct s | s .getStructField ( _) = this or s .getTupleField ( _) = this |
1214
+ exists ( Struct s | this . getAstNode ( ) = [ s .getStructField ( _) . ( AstNode ) , s .getTupleField ( _) ] |
1170
1215
result = TStruct ( s ) and
1171
1216
path .isEmpty ( )
1172
1217
or
@@ -1177,14 +1222,55 @@ private module FieldExprMatchingInput implements MatchingInputSig {
1177
1222
dpos .isField ( ) and
1178
1223
result = this .getTypeRepr ( ) .( TypeMention ) .resolveTypeAt ( path )
1179
1224
}
1225
+
1226
+ override string toString ( ) { result = this .getAstNode ( ) .toString ( ) }
1227
+
1228
+ override Location getLocation ( ) { result = this .getAstNode ( ) .getLocation ( ) }
1229
+ }
1230
+
1231
+ private class StructFieldDecl extends StructOrTupleFieldDecl , TStructFieldDecl {
1232
+ private StructField sf ;
1233
+
1234
+ StructFieldDecl ( ) { this = TStructFieldDecl ( sf ) }
1235
+
1236
+ override AstNode getAstNode ( ) { result = sf }
1237
+
1238
+ override TypeRepr getTypeRepr ( ) { result = sf .getTypeRepr ( ) }
1180
1239
}
1181
1240
1182
- private class StructFieldDecl extends Declaration instanceof StructField {
1183
- override TypeRepr getTypeRepr ( ) { result = StructField .super .getTypeRepr ( ) }
1241
+ private class TupleFieldDecl extends StructOrTupleFieldDecl , TTupleFieldDecl {
1242
+ private TupleField tf ;
1243
+
1244
+ TupleFieldDecl ( ) { this = TTupleFieldDecl ( tf ) }
1245
+
1246
+ override AstNode getAstNode ( ) { result = tf }
1247
+
1248
+ override TypeRepr getTypeRepr ( ) { result = tf .getTypeRepr ( ) }
1184
1249
}
1185
1250
1186
- private class TupleFieldDecl extends Declaration instanceof TupleField {
1187
- override TypeRepr getTypeRepr ( ) { result = TupleField .super .getTypeRepr ( ) }
1251
+ private class TupleTypeParameterDecl extends Declaration , TTupleTypeParameterDecl {
1252
+ private TupleTypeParameter ttp ;
1253
+
1254
+ TupleTypeParameterDecl ( ) { this = TTupleTypeParameterDecl ( ttp ) }
1255
+
1256
+ override Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) {
1257
+ dpos .isSelf ( ) and
1258
+ (
1259
+ result = ttp .getTupleType ( ) and
1260
+ path .isEmpty ( )
1261
+ or
1262
+ result = ttp and
1263
+ path = TypePath:: singleton ( ttp )
1264
+ )
1265
+ or
1266
+ dpos .isField ( ) and
1267
+ result = ttp and
1268
+ path .isEmpty ( )
1269
+ }
1270
+
1271
+ override string toString ( ) { result = ttp .toString ( ) }
1272
+
1273
+ override Location getLocation ( ) { result = ttp .getLocation ( ) }
1188
1274
}
1189
1275
1190
1276
class AccessPosition = DeclarationPosition ;
@@ -1206,7 +1292,12 @@ private module FieldExprMatchingInput implements MatchingInputSig {
1206
1292
1207
1293
Declaration getTarget ( ) {
1208
1294
// mutual recursion; resolving fields requires resolving types and vice versa
1209
- result = [ resolveStructFieldExpr ( this ) .( AstNode ) , resolveTupleFieldExpr ( this ) ]
1295
+ result =
1296
+ [
1297
+ TStructFieldDecl ( resolveStructFieldExpr ( this ) ) .( TDeclaration ) ,
1298
+ TTupleFieldDecl ( resolveTupleFieldExpr ( this ) ) ,
1299
+ TTupleTypeParameterDecl ( resolveTupleTypeFieldExpr ( this ) )
1300
+ ]
1210
1301
}
1211
1302
}
1212
1303
@@ -1266,42 +1357,6 @@ private Type inferFieldExprType(AstNode n, TypePath path) {
1266
1357
)
1267
1358
}
1268
1359
1269
- pragma [ nomagic]
1270
- private Type inferTupleIndexExprType ( FieldExpr fe , TypePath path ) {
1271
- exists ( int i , TypePath path0 |
1272
- fe .getIdentifier ( ) .getText ( ) = i .toString ( ) and
1273
- result = inferType ( fe .getContainer ( ) , path0 ) and
1274
- path0 .isCons ( TTupleTypeParameter ( _, i ) , path ) and
1275
- fe .getIdentifier ( ) .getText ( ) = i .toString ( )
1276
- )
1277
- }
1278
-
1279
- /** Infers the type of `t` in `t.n` when `t` is a tuple. */
1280
- private Type inferTupleContainerExprType ( Expr e , TypePath path ) {
1281
- // NOTE: For a field expression `t.n` where `n` is a number `t` might be a
1282
- // tuple as in:
1283
- // ```rust
1284
- // let t = (Default::default(), 2);
1285
- // let s: String = t.0;
1286
- // ```
1287
- // But it could also be a tuple struct as in:
1288
- // ```rust
1289
- // struct T(String, u32);
1290
- // let t = T(Default::default(), 2);
1291
- // let s: String = t.0;
1292
- // ```
1293
- // We need type information to flow from `t.n` to tuple type parameters of `t`
1294
- // in the former case but not the latter case. Hence we include the condition
1295
- // that the root type of `t` must be a tuple type.
1296
- exists ( int i , TypePath path0 , FieldExpr fe , int arity |
1297
- e = fe .getContainer ( ) and
1298
- fe .getIdentifier ( ) .getText ( ) = i .toString ( ) and
1299
- arity = inferType ( fe .getContainer ( ) ) .( TupleType ) .getArity ( ) and
1300
- result = inferType ( fe , path0 ) and
1301
- path = TypePath:: cons ( TTupleTypeParameter ( arity , i ) , path0 )
1302
- )
1303
- }
1304
-
1305
1360
/** Gets the root type of the reference node `ref`. */
1306
1361
pragma [ nomagic]
1307
1362
private Type inferRefNodeType ( AstNode ref ) {
@@ -2230,20 +2285,6 @@ private module Cached {
2230
2285
result = resolveFunctionCallTarget ( call )
2231
2286
}
2232
2287
2233
- pragma [ inline]
2234
- private Type inferRootTypeDeref ( AstNode n ) {
2235
- result = inferType ( n ) and
2236
- result != TRefType ( )
2237
- or
2238
- // for reference types, lookup members in the type being referenced
2239
- result = inferType ( n , TypePath:: singleton ( TRefTypeParameter ( ) ) )
2240
- }
2241
-
2242
- pragma [ nomagic]
2243
- private Type getFieldExprLookupType ( FieldExpr fe , string name ) {
2244
- result = inferRootTypeDeref ( fe .getContainer ( ) ) and name = fe .getIdentifier ( ) .getText ( )
2245
- }
2246
-
2247
2288
/**
2248
2289
* Gets the struct field that the field expression `fe` resolves to, if any.
2249
2290
*/
@@ -2252,14 +2293,6 @@ private module Cached {
2252
2293
exists ( string name | result = getFieldExprLookupType ( fe , name ) .getStructField ( name ) )
2253
2294
}
2254
2295
2255
- pragma [ nomagic]
2256
- private Type getTupleFieldExprLookupType ( FieldExpr fe , int pos ) {
2257
- exists ( string name |
2258
- result = getFieldExprLookupType ( fe , name ) and
2259
- pos = name .toInt ( )
2260
- )
2261
- }
2262
-
2263
2296
/**
2264
2297
* Gets the tuple field that the field expression `fe` resolves to, if any.
2265
2298
*/
@@ -2341,10 +2374,6 @@ private module Cached {
2341
2374
or
2342
2375
result = inferFieldExprType ( n , path )
2343
2376
or
2344
- result = inferTupleIndexExprType ( n , path )
2345
- or
2346
- result = inferTupleContainerExprType ( n , path )
2347
- or
2348
2377
result = inferRefNodeType ( n ) and
2349
2378
path .isEmpty ( )
2350
2379
or
0 commit comments