Rust: Infer range expressions certainly and support full ranges

This commit is contained in:
Simon Friis Vindum
2025-08-27 13:55:57 +02:00
parent 4c10f07d5f
commit 08f025f164
5 changed files with 34 additions and 4 deletions

View File

@@ -46,6 +46,20 @@ final class RangeFromToExpr extends RangeExpr {
}
}
/**
* A range-full expression. For example:
* ```rust
* let x = ..;
* ```
*/
final class RangeFullExpr extends RangeExpr {
RangeFullExpr() {
this.getOperatorName() = ".." and
not this.hasStart() and
not this.hasEnd()
}
}
/**
* A range-inclusive expression. For example:
* ```rust

View File

@@ -94,6 +94,16 @@ class RangeToStruct extends Struct {
StructField getEnd() { result = this.getStructField("end") }
}
/**
* The [`RangeFull` struct][1].
*
* [1]: https://doc.rust-lang.org/core/ops/struct.RangeFull.html
*/
class RangeFullStruct extends Struct {
pragma[nomagic]
RangeFullStruct() { this.getCanonicalPath() = "core::ops::range::RangeFull" }
}
/**
* The [`RangeInclusive` struct][1].
*

View File

@@ -385,6 +385,9 @@ private module CertainTypeInference {
or
result = inferLogicalOperationType(n, path)
or
result = inferRangeExprType(n) and
path.isEmpty()
or
result = inferTupleRootType(n) and
path.isEmpty()
or
@@ -463,6 +466,9 @@ private Struct getRangeType(RangeExpr re) {
re instanceof RangeToExpr and
result instanceof RangeToStruct
or
re instanceof RangeFullExpr and
result instanceof RangeFullStruct
or
re instanceof RangeFromToExpr and
result instanceof RangeStruct
or
@@ -2402,9 +2408,6 @@ private module Cached {
or
result = inferAwaitExprType(n, path)
or
result = inferRangeExprType(n) and
path.isEmpty()
or
result = inferIndexExprType(n, path)
or
result = inferForLoopExprType(n, path)

View File

@@ -2332,7 +2332,7 @@ mod loops {
for u in [0u8..10] {} // $ type=u:Range type=u:Idx.u8
let range = 0..10; // $ type=range:Range type=range:Idx.i32
for i in range {} // $ type=i:i32
let range_full = ..; // $ MISSING: type=range_full:RangeFull
let range_full = ..; // $ type=range_full:RangeFull
for i in &[1i64, 2i64, 3i64][range_full] {} // $ target=index MISSING: type=i:&T.i64
let range1 = // $ type=range1:Range type=range1:Idx.u16

View File

@@ -4367,6 +4367,8 @@ inferType
| main.rs:2334:13:2334:13 | i | | {EXTERNAL LOCATION} | i32 |
| main.rs:2334:18:2334:22 | range | | {EXTERNAL LOCATION} | Range |
| main.rs:2334:18:2334:22 | range | Idx | {EXTERNAL LOCATION} | i32 |
| main.rs:2335:13:2335:22 | range_full | | {EXTERNAL LOCATION} | RangeFull |
| main.rs:2335:26:2335:27 | .. | | {EXTERNAL LOCATION} | RangeFull |
| main.rs:2336:13:2336:13 | i | | {EXTERNAL LOCATION} | Item |
| main.rs:2336:18:2336:48 | &... | | file://:0:0:0:0 | & |
| main.rs:2336:19:2336:36 | [...] | | file://:0:0:0:0 | [] |
@@ -4374,6 +4376,7 @@ inferType
| main.rs:2336:20:2336:23 | 1i64 | | {EXTERNAL LOCATION} | i64 |
| main.rs:2336:26:2336:29 | 2i64 | | {EXTERNAL LOCATION} | i64 |
| main.rs:2336:32:2336:35 | 3i64 | | {EXTERNAL LOCATION} | i64 |
| main.rs:2336:38:2336:47 | range_full | | {EXTERNAL LOCATION} | RangeFull |
| main.rs:2338:13:2338:18 | range1 | | {EXTERNAL LOCATION} | Range |
| main.rs:2338:13:2338:18 | range1 | Idx | {EXTERNAL LOCATION} | u16 |
| main.rs:2339:9:2342:9 | ...::Range {...} | | {EXTERNAL LOCATION} | Range |