Rust: Adjust the inferred type of string literals

This commit is contained in:
Tom Hvitved
2025-07-08 10:15:08 +02:00
parent 411aa6d2e5
commit 73f854f073
3 changed files with 280 additions and 143 deletions

View File

@@ -1045,14 +1045,12 @@ private Type inferTryExprType(TryExpr te, TypePath path) {
}
pragma[nomagic]
private StructType inferLiteralType(LiteralExpr le) {
private Type inferLiteralType(LiteralExpr le, TypePath path) {
path.isEmpty() and
exists(Builtins::BuiltinType t | result = TStruct(t) |
le instanceof CharLiteralExpr and
t instanceof Builtins::Char
or
le instanceof StringLiteralExpr and
t instanceof Builtins::Str
or
le =
any(NumberLiteralExpr ne |
t.getName() = ne.getSuffix()
@@ -1070,6 +1068,14 @@ private StructType inferLiteralType(LiteralExpr le) {
le instanceof BooleanLiteralExpr and
t instanceof Builtins::Bool
)
or
le instanceof StringLiteralExpr and
(
path.isEmpty() and result = TRefType()
or
path = TypePath::singleton(TRefTypeParameter()) and
result = TStruct(any(Builtins::Str s))
)
}
pragma[nomagic]
@@ -1635,8 +1641,7 @@ private module Cached {
or
result = inferTryExprType(n, path)
or
result = inferLiteralType(n) and
path.isEmpty()
result = inferLiteralType(n, path)
or
result = inferAsyncBlockExprRootType(n) and
path.isEmpty()

View File

@@ -1413,7 +1413,7 @@ mod builtins {
let z = x + y; // $ type=z:i32 method=add
let z = x.abs(); // $ method=abs $ type=z:i32
let c = 'c'; // $ type=c:char
let hello = "Hello"; // $ type=hello:str
let hello = "Hello"; // $ type=hello:&T.str
let f = 123.0f64; // $ type=f:f64
let t = true; // $ type=t:bool
let f = false; // $ type=f:bool
@@ -2086,10 +2086,10 @@ mod loops {
let vals4: [u64; 3] = [1; 3]; // $ type=vals4:[T;...].u64
for u in vals4 {} // $ type=u:u64
let mut strings1 = ["foo", "bar", "baz"]; // $ type=strings1:[T;...].str
for s in &strings1 {} // $ type=s:&T.str
for s in &mut strings1 {} // $ type=s:&T.str
for s in strings1 {} // $ type=s:str
let mut strings1 = ["foo", "bar", "baz"]; // $ type=strings1:[T;...].&T.str
for s in &strings1 {} // $ type=s:&T.&T.str
for s in &mut strings1 {} // $ type=s:&T.&T.str
for s in strings1 {} // $ type=s:&T.str
let strings2 = // $ type=strings2:[T;...].String
[