@@ -72,28 +72,54 @@ module FunctionPositionMatchingInput {
7272}
7373
7474private newtype TAssocFunctionType =
75- MkAssocFunctionType ( Function f , FunctionPosition pos , ImplOrTraitItemNode i ) {
76- f = i .getAnAssocItem ( ) and
77- exists ( pos .getTypeMention ( f ) )
78- } or
79- MkInheritedAssocFunctionType (
80- Function f , FunctionPosition pos , TypeMention parentMention , TraitItemNode parent ,
81- ImplOrTraitItemNode i
82- ) {
83- exists ( AssocFunctionType inherited |
84- inherited .appliesTo ( f , pos , parent ) and
85- f = i .getASuccessor ( _)
75+ /** An associated function `f` that should be specialized for `i` at `pos`. */
76+ MkAssocFunctionType ( Function f , ImplOrTraitItemNode i , FunctionPosition pos ) {
77+ f = i .getASuccessor ( _) and exists ( pos .getTypeMention ( f ) )
78+ }
79+
80+ bindingset [ condition, constraint, tp]
81+ private Type traitConstraintTypeAt (
82+ TypeMention condition , TypeMention constraint , TypeParameter tp , TypePath path
83+ ) {
84+ BaseTypes:: conditionSatisfiesConstraintTypeAt ( _, condition , constraint ,
85+ TypePath:: singleton ( tp ) .appendInverse ( path ) , result )
86+ }
87+
88+ /**
89+ * Gets if the type of the function `f` when specialized for `i` at position
90+ * `pos` at path `path`
91+ */
92+ pragma [ nomagic]
93+ Type assocFunctionTypeAt ( Function f , ImplOrTraitItemNode i , FunctionPosition pos , TypePath path ) {
94+ exists ( MkAssocFunctionType ( f , i , pos ) ) and
95+ (
96+ // No specialization needed when the function is directly in the trait or
97+ // impl block or the declared type is not a type parameter
98+ ( i .getAnAssocItem ( ) = f or not result instanceof TypeParameter ) and
99+ result = pos .getTypeMention ( f ) .resolveTypeAt ( path )
100+ or
101+ not i .getAnAssocItem ( ) = f and
102+ exists ( TypePath prefix , TypePath suffix , TypeParameter tp |
103+ path = prefix .append ( suffix ) and
104+ tp = pos .getTypeMention ( f ) .resolveTypeAt ( prefix )
86105 |
87- parent = i .( ImplItemNode ) .resolveTraitTy ( ) and
88- parentMention = i .( ImplItemNode ) .getTraitPath ( )
89- or
90- parent = i .( TraitItemNode ) .resolveBound ( parentMention )
106+ if tp = TSelfTypeParameter ( _)
107+ then result = resolveImplOrTraitType ( i , suffix )
108+ else
109+ exists ( TraitItemNode trait , TypeMention condition , TypeMention constraint |
110+ trait .getAnAssocItem ( ) = f and
111+ BaseTypes:: rootTypesSatisfaction ( _, TTrait ( trait ) , _, condition , constraint ) and
112+ result = traitConstraintTypeAt ( condition , constraint , tp , suffix )
113+ |
114+ condition = i .( Trait ) or condition = i .( Impl ) .getSelfTy ( )
115+ )
91116 )
92- }
117+ )
118+ }
93119
94120/**
95- * The type of an associated function at a given position, when viewed as a member
96- * of a given trait or `impl` block.
121+ * The type of an associated function at a given position, when its implicit
122+ * `Self` type parameter is specialized to a given trait or `impl` block.
97123 *
98124 * Example:
99125 *
@@ -126,64 +152,13 @@ private newtype TAssocFunctionType =
126152 * `self4` | `impl T2 for X` | `X`
127153 * `self5` | `impl T2 for X` | `X`
128154 */
129- class AssocFunctionType extends TAssocFunctionType {
130- private predicate isFunctionType ( Function f , FunctionPosition pos , ImplOrTraitItemNode i ) {
131- this = MkAssocFunctionType ( f , pos , i )
132- }
133-
134- private predicate isInheritedFunctionType (
135- Function f , FunctionPosition pos , TypeMention parentMention , TraitItemNode parent ,
136- ImplOrTraitItemNode i
137- ) {
138- this = MkInheritedAssocFunctionType ( f , pos , parentMention , parent , i )
139- }
140-
155+ class AssocFunctionType extends MkAssocFunctionType {
141156 /**
142157 * Holds if this function type applies to the function `f` at position `pos`,
143158 * when viewed as a member of the `impl` or trait item `i`.
144159 */
145- predicate appliesTo ( Function f , FunctionPosition pos , ImplOrTraitItemNode i ) {
146- this .isFunctionType ( f , pos , i )
147- or
148- this .isInheritedFunctionType ( f , pos , _, _, i )
149- }
150-
151- /** Gets the type at the given path. */
152- pragma [ nomagic]
153- Type getDeclaredTypeAt ( TypePath path ) {
154- exists ( Function f , FunctionPosition pos |
155- this .isFunctionType ( f , pos , _) and
156- result = pos .getTypeMention ( f ) .resolveTypeAt ( path )
157- )
158- or
159- exists (
160- Function f , FunctionPosition pos , TypeMention parentMention , TraitItemNode parent ,
161- AssocFunctionType parentType , ImplOrTraitItemNode i
162- |
163- this .isInheritedFunctionType ( f , pos , parentMention , parent , i ) and
164- parentType .appliesTo ( f , pos , parent )
165- |
166- result = parentType .getDeclaredTypeAt ( path ) and
167- not result instanceof TypeParameter
168- or
169- exists ( TypePath prefix , TypePath suffix | path = prefix .append ( suffix ) |
170- parentType .hasSelfTypeParameterAt ( prefix ) and
171- result = resolveImplOrTraitType ( i , suffix )
172- or
173- exists ( TypeParameter tp |
174- tp = parentType .getTypeParameterAt ( prefix ) and
175- result = parentMention .resolveTypeAt ( TypePath:: singleton ( tp ) .appendInverse ( suffix ) )
176- )
177- )
178- )
179- }
180-
181- pragma [ nomagic]
182- private TypeParameter getTypeParameterAt ( TypePath path ) { result = this .getDeclaredTypeAt ( path ) }
183-
184- pragma [ nomagic]
185- private predicate hasSelfTypeParameterAt ( TypePath path ) {
186- this .getTypeParameterAt ( path ) = TSelfTypeParameter ( _)
160+ predicate appliesTo ( Function f , ImplOrTraitItemNode i , FunctionPosition pos ) {
161+ this = MkAssocFunctionType ( f , i , pos )
187162 }
188163
189164 /**
@@ -196,7 +171,10 @@ class AssocFunctionType extends TAssocFunctionType {
196171 * traits when matching.
197172 */
198173 Type getTypeAt ( TypePath path ) {
199- exists ( Type t | t = this .getDeclaredTypeAt ( path ) |
174+ exists ( Function f , FunctionPosition pos , ImplOrTraitItemNode i , Type t |
175+ this .appliesTo ( f , i , pos ) and
176+ t = assocFunctionTypeAt ( f , i , pos , path )
177+ |
200178 not t instanceof SelfTypeParameter and
201179 result = t
202180 or
@@ -206,7 +184,7 @@ class AssocFunctionType extends TAssocFunctionType {
206184
207185 private TypeMention getTypeMention ( ) {
208186 exists ( Function f , FunctionPosition pos |
209- this .appliesTo ( f , pos , _ ) and
187+ this .appliesTo ( f , _ , pos ) and
210188 result = pos .getTypeMention ( f )
211189 )
212190 }
@@ -216,20 +194,6 @@ class AssocFunctionType extends TAssocFunctionType {
216194 Location getLocation ( ) { result = this .getTypeMention ( ) .getLocation ( ) }
217195}
218196
219- /**
220- * Holds if the type of the function `f` at position `pos` and path `path` inside
221- * `i` is `type`.
222- */
223- pragma [ nomagic]
224- predicate assocFunctionTypeAt (
225- Function f , ImplOrTraitItemNode i , FunctionPosition pos , TypePath path , Type type
226- ) {
227- exists ( AssocFunctionType aft |
228- aft .appliesTo ( f , pos , i ) and
229- type = aft .getDeclaredTypeAt ( path )
230- )
231- }
232-
233197private Trait getALookupTrait ( Type t ) {
234198 result = t .( TypeParamTypeParameter ) .getTypeParam ( ) .( TypeParamItemNode ) .resolveABound ( )
235199 or
0 commit comments