@@ -276,12 +276,6 @@ private Type inferStructPatType(StructPat sp, TypePath path) {
276276 result = sp .getPath ( ) .( TypeMention ) .getTypeAt ( path )
277277}
278278
279- private Type inferAssignmentOperationType ( AstNode n , TypePath path ) {
280- n instanceof AssignmentOperation and
281- path .isEmpty ( ) and
282- result instanceof UnitType
283- }
284-
285279pragma [ nomagic]
286280private Struct getRangeType ( RangeExpr re ) {
287281 re instanceof RangeFromExpr and
@@ -290,9 +284,6 @@ private Struct getRangeType(RangeExpr re) {
290284 re instanceof RangeToExpr and
291285 result instanceof RangeToStruct
292286 or
293- re instanceof RangeFullExpr and
294- result instanceof RangeFullStruct
295- or
296287 re instanceof RangeFromToExpr and
297288 result instanceof RangeStruct
298289 or
@@ -1972,30 +1963,28 @@ predicate isUnitBlockExpr(BlockExpr be) {
19721963}
19731964
19741965pragma [ nomagic]
1975- private Type inferBlockExprType ( BlockExpr be , TypePath path ) {
1976- // `typeEquality` handles the non-root case
1977- if be instanceof AsyncBlockExpr
1978- then (
1979- path .isEmpty ( ) and
1980- result = getFutureTraitType ( )
1981- or
1982- isUnitBlockExpr ( be ) and
1983- path = TypePath:: singleton ( getDynFutureOutputTypeParameter ( ) ) and
1984- result instanceof UnitType
1985- ) else (
1986- isUnitBlockExpr ( be ) and
1987- path .isEmpty ( ) and
1988- result instanceof UnitType
1989- )
1966+ private Type inferAsyncUnitBlockExprType ( AsyncBlockExpr be , TypePath path ) {
1967+ isUnitBlockExpr ( be ) and
1968+ path = TypePath:: singleton ( getDynFutureOutputTypeParameter ( ) ) and
1969+ result instanceof UnitType
19901970}
19911971
19921972pragma [ nomagic]
1993- private predicate exprHasUnitType ( Expr e ) {
1973+ private predicate exprHasUnitType ( AstNode e ) {
19941974 e = any ( IfExpr ie | not ie .hasElse ( ) )
19951975 or
19961976 e instanceof WhileExpr
19971977 or
19981978 e instanceof ForExpr
1979+ or
1980+ e instanceof AssignmentOperation
1981+ or
1982+ e = any ( BlockExpr be | isUnitBlockExpr ( be ) and not be .isAsync ( ) )
1983+ or
1984+ exists ( CallExprImpl:: DynamicCallExpr dce |
1985+ e = dce .getArgList ( ) and
1986+ dce .getNumberOfSyntacticArguments ( ) = 0
1987+ )
19991988}
20001989
20011990final private class AwaitTarget extends Expr {
@@ -2022,17 +2011,10 @@ private Type inferAwaitExprType(AstNode n, TypePath path) {
20222011 )
20232012}
20242013
2025- /**
2026- * Gets the root type of the array expression `ae`.
2027- */
2028- pragma [ nomagic]
2029- private Type inferArrayExprType ( ArrayExpr ae ) { exists ( ae ) and result instanceof ArrayType }
2030-
2031- /**
2032- * Gets the root type of the range expression `re`.
2033- */
20342014pragma [ nomagic]
2035- private Type inferRangeExprType ( RangeExpr re ) { result = TDataType ( getRangeType ( re ) ) }
2015+ private Type inferRangeFullExprType ( RangeFullExpr re ) {
2016+ exists ( re ) and result = TDataType ( any ( RangeFullStruct t ) )
2017+ }
20362018
20372019/**
20382020 * A matching configuration for resolving types of deconstruction patterns like
@@ -2144,15 +2126,6 @@ private Type inferForLoopExprType(AstNode n, TypePath path) {
21442126 )
21452127}
21462128
2147- pragma [ nomagic]
2148- private TupleType inferArgList ( ArgList args , TypePath path ) {
2149- exists ( CallExprImpl:: DynamicCallExpr dce |
2150- args = dce .getArgList ( ) and
2151- result .getArity ( ) = dce .getNumberOfSyntacticArguments ( ) and
2152- path .isEmpty ( )
2153- )
2154- }
2155-
21562129/** Holds if `n` is implicitly dereferenced and/or borrowed. */
21572130cached
21582131predicate implicitDerefChainBorrow ( Expr e , DerefChain derefChain , boolean borrow ) {
@@ -2943,72 +2916,12 @@ private module Input3 implements InputSig3 {
29432916 exists ( c )
29442917 }
29452918
2946- predicate stepCertainLanguageSpecific ( AstNode n1 , TypePath prefix1 , AstNode n2 , TypePath prefix2 ) {
2947- n1 =
2948- any ( IdentPat ip |
2949- n2 = ip .getName ( ) and
2950- prefix1 .isEmpty ( ) and
2951- if ip .isRef ( )
2952- then
2953- exists ( boolean isMutable | if ip .isMut ( ) then isMutable = true else isMutable = false |
2954- prefix2 = TypePath:: singleton ( getRefTypeParameter ( isMutable ) )
2955- )
2956- else prefix2 .isEmpty ( )
2957- )
2958- or
2959- // Rust closure types like `Fn<(A, B) -> C>` are syntactic sugar for `Fn<Args = (A, B), Output = C>`,
2960- // so in calls to a closure, we consider the entire argument list as a single tuple argument.
2961- exists ( CallExprImpl:: DynamicCallExpr dce , TupleType tt , int i |
2962- n1 = dce .getSyntacticPositionalArgument ( i ) and
2963- n2 = dce .getArgList ( ) and
2964- tt .getArity ( ) = dce .getNumberOfSyntacticArguments ( ) and
2965- prefix1 .isEmpty ( ) and
2966- prefix2 = TypePath:: singleton ( tt .getPositionalTypeParameter ( i ) )
2967- )
2968- }
2969-
29702919 pragma [ nomagic]
29712920 private Type inferClosureArgsType ( ClosureExpr ce , TypePath path ) {
29722921 path = TypePath:: singleton ( TDynTraitTypeParameter ( _, any ( FnTrait t ) .getTypeParam ( ) ) ) and
29732922 result .( TupleType ) .getArity ( ) = ce .getNumberOfParams ( )
29742923 }
29752924
2976- pragma [ nomagic]
2977- Type inferTypeCertainLanguageSpecific ( AstNode n , TypePath path ) {
2978- result = inferLiteralType ( n , path , true )
2979- or
2980- result = inferRefPatType ( n ) and
2981- path .isEmpty ( )
2982- or
2983- result = inferRefExprType ( n ) and
2984- path .isEmpty ( )
2985- or
2986- result = inferStructExprType ( n , path )
2987- or
2988- result = inferStructPatType ( n , path )
2989- or
2990- result = inferAssignmentOperationType ( n , path )
2991- or
2992- result = inferRangeExprType ( n ) and
2993- path .isEmpty ( )
2994- or
2995- result = inferTupleRootType ( n ) and
2996- path .isEmpty ( )
2997- or
2998- result = inferBlockExprType ( n , path )
2999- or
3000- result = inferArrayExprType ( n ) and
3001- path .isEmpty ( )
3002- or
3003- result = inferArgList ( n , path )
3004- or
3005- exprHasUnitType ( n ) and
3006- path .isEmpty ( ) and
3007- result instanceof UnitType
3008- or
3009- result = inferClosureArgsType ( n , path )
3010- }
3011-
30122925 predicate stepLanguageSpecific ( AstNode n1 , TypePath prefix1 , AstNode n2 , TypePath prefix2 ) {
30132926 // When `n2` is `*n1` propagate type information from a raw pointer type
30142927 // parameter at `n1` (all other deref expressions are handled as calls)
@@ -3046,6 +2959,26 @@ private module Input3 implements InputSig3 {
30462959 n2 .( ArrayRepeatExpr ) .getRepeatOperand ( ) = n1 and
30472960 prefix2 = TypePath:: singleton ( getArrayTypeParameter ( ) )
30482961 or
2962+ // Rust closure types like `Fn<(A, B) -> C>` are syntactic sugar for `Fn<Args = (A, B), Output = C>`,
2963+ // so in calls to a closure, we consider the entire argument list as a single tuple argument.
2964+ exists ( CallExprImpl:: DynamicCallExpr dce , TupleType tt , int i |
2965+ n1 = dce .getSyntacticPositionalArgument ( i ) and
2966+ n2 = dce .getArgList ( ) and
2967+ tt .getArity ( ) = dce .getNumberOfSyntacticArguments ( ) and
2968+ prefix2 = TypePath:: singleton ( tt .getPositionalTypeParameter ( i ) )
2969+ )
2970+ or
2971+ n1 =
2972+ any ( IdentPat ip |
2973+ n2 = ip .getName ( ) and
2974+ if ip .isRef ( )
2975+ then
2976+ exists ( boolean isMutable | if ip .isMut ( ) then isMutable = true else isMutable = false |
2977+ prefix2 = TypePath:: singleton ( getRefTypeParameter ( isMutable ) )
2978+ )
2979+ else prefix2 .isEmpty ( )
2980+ )
2981+ or
30492982 prefix2 .isEmpty ( ) and
30502983 (
30512984 n2 = n1 .( OrPat ) .getAPat ( )
@@ -3124,6 +3057,32 @@ private module Input3 implements InputSig3 {
31243057 or
31253058 result = inferUnknownType ( n , path )
31263059 }
3060+
3061+ pragma [ nomagic]
3062+ Type inferTypeCertainLanguageSpecific ( AstNode n , TypePath path ) {
3063+ result = inferLiteralType ( n , path , true )
3064+ or
3065+ result = inferRefPatType ( n ) and
3066+ path .isEmpty ( )
3067+ or
3068+ result = inferStructExprType ( n , path )
3069+ or
3070+ result = inferStructPatType ( n , path )
3071+ or
3072+ result = inferRangeFullExprType ( n ) and
3073+ path .isEmpty ( )
3074+ or
3075+ result = inferTupleRootType ( n ) and
3076+ path .isEmpty ( )
3077+ or
3078+ result = inferAsyncUnitBlockExprType ( n , path )
3079+ or
3080+ exprHasUnitType ( n ) and
3081+ path .isEmpty ( ) and
3082+ result instanceof UnitType
3083+ or
3084+ result = inferClosureArgsType ( n , path )
3085+ }
31273086}
31283087
31293088private module M3 = Make3< Input3 > ;
0 commit comments