@@ -226,7 +226,13 @@ module Consistency {
226
226
227
227
predicate nonUniqueCertainType ( AstNode n , TypePath path , Type t ) {
228
228
strictcount ( CertainTypeInference:: inferCertainType ( n , path ) ) > 1 and
229
- t = CertainTypeInference:: inferCertainType ( n , path )
229
+ t = CertainTypeInference:: inferCertainType ( n , path ) and
230
+ // Suppress the inconsistency if `n` is a self parameter and the type
231
+ // mention for the self type has multiple types for a path.
232
+ not exists ( ImplItemNode impl , TypePath selfTypePath |
233
+ n = impl .getAnAssocItem ( ) .( Function ) .getParamList ( ) .getSelfParam ( ) and
234
+ strictcount ( impl .( Impl ) .getSelfTy ( ) .( TypeMention ) .resolveTypeAt ( selfTypePath ) ) > 1
235
+ )
230
236
}
231
237
}
232
238
@@ -250,10 +256,62 @@ private TypeMention getTypeAnnotation(AstNode n) {
250
256
)
251
257
}
252
258
259
+ /**
260
+ * Gets the type of the implicitly typed `self` parameter, taking into account
261
+ * whether the parameter is passed by value or by reference.
262
+ */
263
+ bindingset [ self, suffix, t]
264
+ pragma [ inline_late]
265
+ private Type getRefAdjustShorthandSelfType ( SelfParam self , TypePath suffix , Type t , TypePath path ) {
266
+ not self .hasTypeRepr ( ) and
267
+ (
268
+ if self .isRef ( )
269
+ then
270
+ // `fn f(&self, ...)`
271
+ path .isEmpty ( ) and
272
+ result = TRefType ( )
273
+ or
274
+ path = TypePath:: cons ( TRefTypeParameter ( ) , suffix ) and
275
+ result = t
276
+ else (
277
+ // `fn f(self, ...)`
278
+ path = suffix and
279
+ result = t
280
+ )
281
+ )
282
+ }
283
+
284
+ pragma [ nomagic]
285
+ private Type resolveImplSelfType ( Impl i , TypePath path ) {
286
+ result = i .getSelfTy ( ) .( TypeMention ) .resolveTypeAt ( path )
287
+ }
288
+
289
+ /**
290
+ * Gets the type at `path` of the parameter `self` which uses the [shorthand
291
+ * syntax][1] which is sugar for an explicit annotation.
292
+ *
293
+ * [1]: https://doc.rust-lang.org/stable/reference/items/associated-items.html#r-associated.fn.method.self-pat-shorthands
294
+ */
295
+ pragma [ nomagic]
296
+ private Type inferShorthandSelfType ( SelfParam self , TypePath path ) {
297
+ exists ( ImplOrTraitItemNode i , TypePath suffix , Type t |
298
+ self = i .getAnAssocItem ( ) .( Function ) .getParamList ( ) .getSelfParam ( ) and
299
+ result = getRefAdjustShorthandSelfType ( self , suffix , t , path )
300
+ |
301
+ t = resolveImplSelfType ( i , suffix )
302
+ or
303
+ t = TSelfTypeParameter ( i ) and suffix .isEmpty ( )
304
+ )
305
+ }
306
+
253
307
/** Gets the type of `n`, which has an explicit type annotation. */
254
308
pragma [ nomagic]
255
309
private Type inferAnnotatedType ( AstNode n , TypePath path ) {
256
310
result = getTypeAnnotation ( n ) .resolveTypeAt ( path )
311
+ or
312
+ // The shorthand self syntax (i.e., a self parameter without a type
313
+ // annotation) is sugar for a self parameter with an annotation.
314
+ result = inferShorthandSelfType ( n , path )
257
315
}
258
316
259
317
/** Module for inferring certain type information. */
@@ -369,10 +427,7 @@ module CertainTypeInference {
369
427
*/
370
428
pragma [ nomagic]
371
429
Type inferCertainType ( AstNode n , TypePath path ) {
372
- exists ( TypeMention tm |
373
- tm = getTypeAnnotation ( n ) and
374
- result = tm .resolveTypeAt ( path )
375
- )
430
+ result = inferAnnotatedType ( n , path )
376
431
or
377
432
result = inferCertainCallExprType ( n , path )
378
433
or
@@ -602,50 +657,6 @@ private Type inferTypeEquality(AstNode n, TypePath path) {
602
657
)
603
658
}
604
659
605
- /**
606
- * Gets the type of the implicitly typed `self` parameter, taking into account
607
- * whether the parameter is passed by value or by reference.
608
- */
609
- bindingset [ self, suffix, t]
610
- pragma [ inline_late]
611
- private Type getRefAdjustImplicitSelfType ( SelfParam self , TypePath suffix , Type t , TypePath path ) {
612
- not self .hasTypeRepr ( ) and
613
- (
614
- if self .isRef ( )
615
- then
616
- // `fn f(&self, ...)`
617
- path .isEmpty ( ) and
618
- result = TRefType ( )
619
- or
620
- path = TypePath:: cons ( TRefTypeParameter ( ) , suffix ) and
621
- result = t
622
- else (
623
- // `fn f(self, ...)`
624
- path = suffix and
625
- result = t
626
- )
627
- )
628
- }
629
-
630
- pragma [ nomagic]
631
- private Type resolveImplSelfType ( Impl i , TypePath path ) {
632
- result = i .getSelfTy ( ) .( TypeMention ) .resolveTypeAt ( path )
633
- }
634
-
635
- /** Gets the type at `path` of the implicitly typed `self` parameter. */
636
- pragma [ nomagic]
637
- private Type inferImplicitSelfType ( SelfParam self , TypePath path ) {
638
- exists ( ImplOrTraitItemNode i , Function f , TypePath suffix , Type t |
639
- f = i .getAnAssocItem ( ) and
640
- self = f .getParamList ( ) .getSelfParam ( ) and
641
- result = getRefAdjustImplicitSelfType ( self , suffix , t , path )
642
- |
643
- t = resolveImplSelfType ( i , suffix )
644
- or
645
- t = TSelfTypeParameter ( i ) and suffix .isEmpty ( )
646
- )
647
- }
648
-
649
660
/**
650
661
* A matching configuration for resolving types of struct expressions
651
662
* like `Foo { bar = baz }`.
@@ -926,11 +937,8 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
926
937
or
927
938
exists ( SelfParam self |
928
939
self = pragma [ only_bind_into ] ( this .getParamList ( ) .getSelfParam ( ) ) and
929
- dpos .isSelf ( )
930
- |
940
+ dpos .isSelf ( ) and
931
941
result = inferAnnotatedType ( self , path ) // `self` parameter with type annotation
932
- or
933
- result = inferImplicitSelfType ( self , path ) // `self` parameter without type annotation
934
942
)
935
943
or
936
944
// For associated functions, we may also need to match type arguments against
@@ -2420,14 +2428,10 @@ private module Cached {
2420
2428
else any ( )
2421
2429
) and
2422
2430
(
2423
- result = inferAnnotatedType ( n , path )
2424
- or
2425
2431
result = inferAssignmentOperationType ( n , path )
2426
2432
or
2427
2433
result = inferTypeEquality ( n , path )
2428
2434
or
2429
- result = inferImplicitSelfType ( n , path )
2430
- or
2431
2435
result = inferStructExprType ( n , path )
2432
2436
or
2433
2437
result = inferPathExprType ( n , path )
@@ -2491,9 +2495,9 @@ private module Debug {
2491
2495
Input2:: conditionSatisfiesConstraint ( abs , condition , constraint )
2492
2496
}
2493
2497
2494
- predicate debugInferImplicitSelfType ( SelfParam self , TypePath path , Type t ) {
2498
+ predicate debugInferShorthandSelfType ( SelfParam self , TypePath path , Type t ) {
2495
2499
self = getRelevantLocatable ( ) and
2496
- t = inferImplicitSelfType ( self , path )
2500
+ t = inferShorthandSelfType ( self , path )
2497
2501
}
2498
2502
2499
2503
predicate debugInferCallExprBaseType ( AstNode n , TypePath path , Type t ) {
0 commit comments