@@ -226,7 +226,13 @@ module Consistency {
226226
227227 predicate nonUniqueCertainType ( AstNode n , TypePath path , Type t ) {
228228 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+ )
230236 }
231237}
232238
@@ -250,10 +256,62 @@ private TypeMention getTypeAnnotation(AstNode n) {
250256 )
251257}
252258
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+
253307/** Gets the type of `n`, which has an explicit type annotation. */
254308pragma [ nomagic]
255309private Type inferAnnotatedType ( AstNode n , TypePath path ) {
256310 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 )
257315}
258316
259317/** Module for inferring certain type information. */
@@ -369,10 +427,7 @@ module CertainTypeInference {
369427 */
370428 pragma [ nomagic]
371429 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 )
376431 or
377432 result = inferCertainCallExprType ( n , path )
378433 or
@@ -602,50 +657,6 @@ private Type inferTypeEquality(AstNode n, TypePath path) {
602657 )
603658}
604659
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-
649660/**
650661 * A matching configuration for resolving types of struct expressions
651662 * like `Foo { bar = baz }`.
@@ -926,11 +937,8 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
926937 or
927938 exists ( SelfParam self |
928939 self = pragma [ only_bind_into ] ( this .getParamList ( ) .getSelfParam ( ) ) and
929- dpos .isSelf ( )
930- |
940+ dpos .isSelf ( ) and
931941 result = inferAnnotatedType ( self , path ) // `self` parameter with type annotation
932- or
933- result = inferImplicitSelfType ( self , path ) // `self` parameter without type annotation
934942 )
935943 or
936944 // For associated functions, we may also need to match type arguments against
@@ -2420,14 +2428,10 @@ private module Cached {
24202428 else any ( )
24212429 ) and
24222430 (
2423- result = inferAnnotatedType ( n , path )
2424- or
24252431 result = inferAssignmentOperationType ( n , path )
24262432 or
24272433 result = inferTypeEquality ( n , path )
24282434 or
2429- result = inferImplicitSelfType ( n , path )
2430- or
24312435 result = inferStructExprType ( n , path )
24322436 or
24332437 result = inferPathExprType ( n , path )
@@ -2491,9 +2495,9 @@ private module Debug {
24912495 Input2:: conditionSatisfiesConstraint ( abs , condition , constraint )
24922496 }
24932497
2494- predicate debugInferImplicitSelfType ( SelfParam self , TypePath path , Type t ) {
2498+ predicate debugInferShorthandSelfType ( SelfParam self , TypePath path , Type t ) {
24952499 self = getRelevantLocatable ( ) and
2496- t = inferImplicitSelfType ( self , path )
2500+ t = inferShorthandSelfType ( self , path )
24972501 }
24982502
24992503 predicate debugInferCallExprBaseType ( AstNode n , TypePath path , Type t ) {
0 commit comments