@@ -1123,17 +1123,27 @@ private Function getMethodSuccessor(ItemNode item, string name, int arity) {
11231123 arity = result .getParamList ( ) .getNumberOfParams ( )
11241124}
11251125
1126+ /**
1127+ * Holds if the type path `path` pointing to `type` is either empty, in which
1128+ * case `type` is not `&`, or `path` points to a type being referenced by `&`.
1129+ */
1130+ bindingset [ path, type]
1131+ predicate isRefStrippedRoot ( TypePath path , Type type ) {
1132+ path .isEmpty ( ) and
1133+ type != TRefType ( )
1134+ or
1135+ path = TypePath:: singleton ( TRefTypeParameter ( ) ) and
1136+ exists ( type )
1137+ }
1138+
11261139/** Provides logic for resolving method calls. */
11271140private module MethodCallResolution {
11281141 /**
11291142 * Holds if method `f` with the name `name` and the arity `arity` exists in
11301143 * `i`, and the type of the `self` parameter is `selfType`.
11311144 *
1132- * TODO
1133- * `rootType` is the root type of `selfType`, and `selfRootPath` points to
1134- * `selfRootType` inside `selfType`, where `selfRootType` is either the type
1135- * being implemented, when `i` is an `impl`, or the trait itself when `i` is
1136- * a trait.
1145+ * `rootTypePath` points to the type `rootType` inside `selfType`, which is
1146+ * the (possibly `&`-stripped) root type of `selfType`.
11371147 */
11381148 pragma [ nomagic]
11391149 predicate methodInfo (
@@ -1144,12 +1154,7 @@ private module MethodCallResolution {
11441154 f = i .getASuccessor ( name ) and
11451155 arity = f .getParamList ( ) .getNumberOfParams ( ) and
11461156 rootType = selfType .getTypeAt ( rootTypePath ) and
1147- (
1148- rootTypePath .isEmpty ( ) and
1149- rootType != TRefType ( )
1150- or
1151- rootTypePath = TypePath:: singleton ( TRefTypeParameter ( ) )
1152- ) and
1157+ isRefStrippedRoot ( rootTypePath , rootType ) and
11531158 selfType .appliesTo ( f , pos , i ) and
11541159 pos .isSelf ( ) and
11551160 not i .( ImplItemNode ) .isBlanket ( )
@@ -1284,6 +1289,14 @@ private module MethodCallResolution {
12841289 derefChainBorrow ) , i , _)
12851290 }
12861291
1292+ pragma [ nomagic]
1293+ private Type getACandidateReceiverRootTypeAtSubstituteTraitBounds (
1294+ TypePath rootTypePath , string derefChainBorrow
1295+ ) {
1296+ result = this .getACandidateReceiverTypeAtSubstituteTraitBounds ( rootTypePath , derefChainBorrow ) and
1297+ isRefStrippedRoot ( rootTypePath , result )
1298+ }
1299+
12871300 /**
12881301 * Holds if the candidate receiver type represented by `derefChain` does not
12891302 * have a matching method target.
@@ -1294,13 +1307,7 @@ private module MethodCallResolution {
12941307 derefChainBorrow = derefChain + ";" and
12951308 not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
12961309 rootType =
1297- this .getACandidateReceiverTypeAtSubstituteTraitBounds ( rootTypePath , derefChainBorrow ) and
1298- (
1299- rootTypePath .isEmpty ( ) and
1300- rootType != TRefType ( )
1301- or
1302- rootTypePath = TypePath:: singleton ( TRefTypeParameter ( ) )
1303- )
1310+ this .getACandidateReceiverRootTypeAtSubstituteTraitBounds ( rootTypePath , derefChainBorrow )
13041311 |
13051312 forall ( ImplOrTraitItemNode i | methodCallCandidate ( this , i , _, rootTypePath , rootType ) |
13061313 this .isNotCandidate ( i , derefChainBorrow )
@@ -1318,8 +1325,7 @@ private module MethodCallResolution {
13181325 derefChainBorrow = derefChain + ";borrow" and
13191326 this .noCandidateReceiverTypeAtNoBorrow ( derefChain ) and
13201327 rootType =
1321- this .getACandidateReceiverTypeAtSubstituteTraitBounds ( rootTypePath , derefChainBorrow ) and
1322- rootTypePath = TypePath:: singleton ( TRefTypeParameter ( ) )
1328+ this .getACandidateReceiverRootTypeAtSubstituteTraitBounds ( rootTypePath , derefChainBorrow )
13231329 |
13241330 forall ( ImplOrTraitItemNode i | methodCallCandidate ( this , i , _, rootTypePath , rootType ) |
13251331 this .isNotCandidate ( i , derefChainBorrow )
@@ -1463,12 +1469,7 @@ private module MethodCallResolution {
14631469 private predicate hasNoInherentTarget ( ) {
14641470 exists ( TypePath rootTypePath , Type rootType , string name , int arity |
14651471 this .isMethodCall ( _, rootTypePath , rootType , name , arity ) and
1466- (
1467- rootTypePath .isEmpty ( ) and
1468- rootType != TRefType ( )
1469- or
1470- rootTypePath = TypePath:: singleton ( TRefTypeParameter ( ) )
1471- ) and
1472+ isRefStrippedRoot ( rootTypePath , rootType ) and
14721473 forall ( Impl i |
14731474 methodInfo ( _, name , arity , i , _, rootTypePath , rootType ) and
14741475 not i .hasTrait ( )
@@ -2314,18 +2315,13 @@ private Type inferOperationType(AstNode n, TypePath path) {
23142315 )
23152316}
23162317
2317- pragma [ inline]
2318- private Type inferRootTypeDeref ( AstNode n ) {
2319- result = inferType ( n ) and
2320- result != TRefType ( )
2321- or
2322- // for reference types, lookup members in the type being referenced
2323- result = inferType ( n , TypePath:: singleton ( TRefTypeParameter ( ) ) )
2324- }
2325-
23262318pragma [ nomagic]
23272319private Type getFieldExprLookupType ( FieldExpr fe , string name ) {
2328- result = inferRootTypeDeref ( fe .getContainer ( ) ) and name = fe .getIdentifier ( ) .getText ( )
2320+ exists ( TypePath path |
2321+ result = inferType ( fe .getContainer ( ) , path ) and
2322+ name = fe .getIdentifier ( ) .getText ( ) and
2323+ isRefStrippedRoot ( path , result )
2324+ )
23292325}
23302326
23312327pragma [ nomagic]
0 commit comments