@@ -431,7 +431,10 @@ module CertainTypeInference {
431431 or
432432 result = inferLiteralType ( n , path , true )
433433 or
434- result = inferRefNodeType ( n ) and
434+ result = inferRefPatType ( n ) and
435+ path .isEmpty ( )
436+ or
437+ result = inferRefExprType ( n ) and
435438 path .isEmpty ( )
436439 or
437440 result = inferLogicalOperationType ( n , path )
@@ -606,10 +609,14 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
606609 strictcount ( Expr e | bodyReturns ( n1 , e ) ) = 1
607610 )
608611 or
609- (
610- n1 = n2 .( RefExpr ) .getExpr ( ) or
611- n1 = n2 .( RefPat ) .getPat ( )
612- ) and
612+ exists ( RefExpr re |
613+ n2 = re and
614+ n1 = re .getExpr ( ) and
615+ prefix1 .isEmpty ( ) and
616+ prefix2 = TypePath:: singleton ( inferRefExprType ( re ) .getPositionalTypeParameter ( 0 ) )
617+ )
618+ or
619+ n1 = n2 .( RefPat ) .getPat ( ) and
613620 prefix1 .isEmpty ( ) and
614621 prefix2 = TypePath:: singleton ( getRefTypeParameter ( ) )
615622 or
@@ -709,9 +716,7 @@ private predicate lubCoercion(AstNode parent, AstNode child, TypePath prefix) {
709716 * of `n2` at `prefix2`, but type information should only propagate from `n1` to
710717 * `n2`.
711718 */
712- private predicate typeEqualityNonSymmetric (
713- AstNode n1 , TypePath prefix1 , AstNode n2 , TypePath prefix2
714- ) {
719+ private predicate typeEqualityAsymmetric ( AstNode n1 , TypePath prefix1 , AstNode n2 , TypePath prefix2 ) {
715720 lubCoercion ( n2 , n1 , prefix2 ) and
716721 prefix1 .isEmpty ( )
717722 or
@@ -723,6 +728,13 @@ private predicate typeEqualityNonSymmetric(
723728 not lubCoercion ( mid , n1 , _) and
724729 prefix1 = prefixMid .append ( suffix )
725730 )
731+ or
732+ // When `n2` is `*n1` propagate type information from a raw pointer type
733+ // parameter at `n1`. The other direction is handled in
734+ // `inferDereferencedExprPtrType`.
735+ n1 = n2 .( DerefExpr ) .getExpr ( ) and
736+ prefix1 = TypePath:: singleton ( getPtrTypeParameter ( ) ) and
737+ prefix2 .isEmpty ( )
726738}
727739
728740pragma [ nomagic]
@@ -735,7 +747,7 @@ private Type inferTypeEquality(AstNode n, TypePath path) {
735747 or
736748 typeEquality ( n2 , prefix2 , n , prefix1 )
737749 or
738- typeEqualityNonSymmetric ( n2 , prefix2 , n , prefix1 )
750+ typeEqualityAsymmetric ( n2 , prefix2 , n , prefix1 )
739751 )
740752}
741753
@@ -2952,16 +2964,21 @@ private Type inferFieldExprType(AstNode n, TypePath path) {
29522964 )
29532965}
29542966
2955- /** Gets the root type of the reference node `ref`. */
2967+ /** Gets the root type of the reference expression `ref`. */
29562968pragma [ nomagic]
2957- private Type inferRefNodeType ( AstNode ref ) {
2958- (
2959- ref = any ( IdentPat ip | ip .isRef ( ) ) .getName ( )
2960- or
2961- ref instanceof RefExpr
2969+ private Type inferRefExprType ( RefExpr ref ) {
2970+ if ref .isRaw ( )
2971+ then
2972+ ref .isMut ( ) and result instanceof PtrMutType
29622973 or
2963- ref instanceof RefPat
2964- ) and
2974+ ref .isConst ( ) and result instanceof PtrConstType
2975+ else result instanceof RefType
2976+ }
2977+
2978+ /** Gets the root type of the reference node `ref`. */
2979+ pragma [ nomagic]
2980+ private Type inferRefPatType ( AstNode ref ) {
2981+ ( ref = any ( IdentPat ip | ip .isRef ( ) ) .getName ( ) or ref instanceof RefPat ) and
29652982 result instanceof RefType
29662983}
29672984
@@ -3145,6 +3162,21 @@ private Type inferIndexExprType(IndexExpr ie, TypePath path) {
31453162 )
31463163}
31473164
3165+ /**
3166+ * Gets the inferred type of `n` at `path` when `n` occurs in a dereference
3167+ * expression `*n` and when `n` is known to have a raw pointer type.
3168+ *
3169+ * The other direction is handled in `typeEqualityAsymmetric`.
3170+ */
3171+ private Type inferDereferencedExprPtrType ( AstNode n , TypePath path ) {
3172+ exists ( DerefExpr de , PtrType type , TypePath suffix |
3173+ de .getExpr ( ) = n and
3174+ type = inferType ( de .getExpr ( ) ) and
3175+ result = inferType ( de , suffix ) and
3176+ path = TypePath:: cons ( type .getPositionalTypeParameter ( 0 ) , suffix )
3177+ )
3178+ }
3179+
31483180/**
31493181 * A matching configuration for resolving types of struct patterns
31503182 * like `let Foo { bar } = ...`.
@@ -3544,6 +3576,8 @@ private module Cached {
35443576 or
35453577 result = inferIndexExprType ( n , path )
35463578 or
3579+ result = inferDereferencedExprPtrType ( n , path )
3580+ or
35473581 result = inferForLoopExprType ( n , path )
35483582 or
35493583 result = inferDynamicCallExprType ( n , path )
0 commit comments