@@ -296,6 +296,27 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
296296 n1 .( ArrayRepeatExpr ) .getRepeatOperand ( ) = n2 and
297297 prefix1 = TypePath:: singleton ( TArrayTypeParameter ( ) ) and
298298 prefix2 .isEmpty ( )
299+ or
300+ exists ( Struct s |
301+ n2 = [ n1 .( RangeExpr ) .getStart ( ) , n1 .( RangeExpr ) .getEnd ( ) ] and
302+ prefix1 = TypePath:: singleton ( TTypeParamTypeParameter ( s .getGenericParamList ( ) .getATypeParam ( ) ) ) and
303+ prefix2 .isEmpty ( )
304+ |
305+ n1 instanceof RangeFromExpr and
306+ s instanceof RangeFromStruct
307+ or
308+ n1 instanceof RangeToExpr and
309+ s instanceof RangeToStruct
310+ or
311+ n1 instanceof RangeFromToExpr and
312+ s instanceof RangeStruct
313+ or
314+ n1 instanceof RangeInclusiveExpr and
315+ s instanceof RangeInclusiveStruct
316+ or
317+ n1 instanceof RangeToInclusiveExpr and
318+ s instanceof RangeToInclusiveStruct
319+ )
299320}
300321
301322pragma [ nomagic]
@@ -1062,7 +1083,7 @@ private TraitType inferAsyncBlockExprRootType(AsyncBlockExpr abe) {
10621083 result = getFutureTraitType ( )
10631084}
10641085
1065- final class AwaitTarget extends Expr {
1086+ final private class AwaitTarget extends Expr {
10661087 AwaitTarget ( ) { this = any ( AwaitExpr ae ) .getExpr ( ) }
10671088
10681089 Type getTypeAt ( TypePath path ) { result = inferType ( this , path ) }
@@ -1098,6 +1119,29 @@ private class Vec extends Struct {
10981119pragma [ nomagic]
10991120private Type inferArrayExprType ( ArrayExpr ae ) { exists ( ae ) and result = TArrayType ( ) }
11001121
1122+ /**
1123+ * Gets the root type of the range expression `re`.
1124+ */
1125+ pragma [ nomagic]
1126+ private Type inferRangeExprType ( RangeExpr re ) {
1127+ exists ( Struct s | result = TStruct ( s ) |
1128+ re instanceof RangeFromExpr and
1129+ s instanceof RangeFromStruct
1130+ or
1131+ re instanceof RangeToExpr and
1132+ s instanceof RangeToStruct
1133+ or
1134+ re instanceof RangeFromToExpr and
1135+ s instanceof RangeStruct
1136+ or
1137+ re instanceof RangeInclusiveExpr and
1138+ s instanceof RangeInclusiveStruct
1139+ or
1140+ re instanceof RangeToInclusiveExpr and
1141+ s instanceof RangeToInclusiveStruct
1142+ )
1143+ }
1144+
11011145/**
11021146 * According to [the Rust reference][1]: _"array and slice-typed expressions
11031147 * can be indexed with a `usize` index ... For other types an index expression
@@ -1134,23 +1178,49 @@ private Type inferIndexExprType(IndexExpr ie, TypePath path) {
11341178 )
11351179}
11361180
1181+ final private class ForIterableExpr extends Expr {
1182+ ForIterableExpr ( ) { this = any ( ForExpr fe ) .getIterable ( ) }
1183+
1184+ Type getTypeAt ( TypePath path ) { result = inferType ( this , path ) }
1185+ }
1186+
1187+ private module ForIterableSatisfiesConstraintInput implements
1188+ SatisfiesConstraintInputSig< ForIterableExpr >
1189+ {
1190+ predicate relevantConstraint ( ForIterableExpr term , Type constraint ) {
1191+ exists ( term ) and
1192+ exists ( Trait t | t = constraint .( TraitType ) .getTrait ( ) |
1193+ // TODO: Remove the line below once we can handle the `impl<I: Iterator> IntoIterator for I` implementation
1194+ t instanceof IteratorTrait or
1195+ t instanceof IntoIteratorTrait
1196+ )
1197+ }
1198+ }
1199+
1200+ pragma [ nomagic]
1201+ private AssociatedTypeTypeParameter getIteratorItemTypeParameter ( ) {
1202+ result .getTypeAlias ( ) = any ( IteratorTrait t ) .getItemType ( )
1203+ }
1204+
1205+ pragma [ nomagic]
1206+ private AssociatedTypeTypeParameter getIntoIteratorItemTypeParameter ( ) {
1207+ result .getTypeAlias ( ) = any ( IntoIteratorTrait t ) .getItemType ( )
1208+ }
1209+
11371210pragma [ nomagic]
11381211private Type inferForLoopExprType ( AstNode n , TypePath path ) {
11391212 // type of iterable -> type of pattern (loop variable)
1140- exists ( ForExpr fe , Type iterableType , TypePath iterablePath |
1213+ exists ( ForExpr fe , TypePath exprPath , AssociatedTypeTypeParameter tp |
11411214 n = fe .getPat ( ) and
1142- iterableType = inferType ( fe .getIterable ( ) , iterablePath ) and
1143- result = iterableType and
1144- (
1145- iterablePath .isCons ( any ( Vec v ) .getElementTypeParameter ( ) , path )
1146- or
1147- iterablePath .isCons ( any ( ArrayTypeParameter tp ) , path )
1148- or
1149- iterablePath
1150- .stripPrefix ( TypePath:: cons ( TRefTypeParameter ( ) ,
1151- TypePath:: singleton ( any ( SliceTypeParameter tp ) ) ) ) = path
1152- // TODO: iterables (general case for containers, ranges etc)
1153- )
1215+ SatisfiesConstraint< ForIterableExpr , ForIterableSatisfiesConstraintInput > :: satisfiesConstraintType ( fe .getIterable ( ) ,
1216+ _, exprPath , result ) and
1217+ exprPath .isCons ( tp , path )
1218+ |
1219+ tp = getIntoIteratorItemTypeParameter ( )
1220+ or
1221+ // TODO: Remove once we can handle the `impl<I: Iterator> IntoIterator for I` implementation
1222+ tp = getIteratorItemTypeParameter ( ) and
1223+ inferType ( fe .getIterable ( ) ) != TArrayType ( )
11541224 )
11551225}
11561226
@@ -1589,6 +1659,9 @@ private module Cached {
15891659 result = inferArrayExprType ( n ) and
15901660 path .isEmpty ( )
15911661 or
1662+ result = inferRangeExprType ( n ) and
1663+ path .isEmpty ( )
1664+ or
15921665 result = inferIndexExprType ( n , path )
15931666 or
15941667 result = inferForLoopExprType ( n , path )
0 commit comments