@@ -50,24 +50,70 @@ class SliceTypeReprMention extends TypeMention instanceof SliceTypeRepr {
50
50
}
51
51
}
52
52
53
- class PathTypeMention extends TypeMention , Path {
54
- TypeItemNode resolved ;
53
+ /** Holds if `path` is used as a type mention during type inference. */
54
+ predicate relevantPathTypeMention ( Path path ) {
55
+ path =
56
+ [
57
+ any ( PathTypeRepr r ) .getPath ( ) ,
58
+ any ( StructExpr s ) .getPath ( ) .getQualifier * ( ) ,
59
+ any ( CallExpr ce ) .getFunction ( ) .( PathExpr ) .getPath ( ) .getQualifier * ( ) ,
60
+ any ( StructPat p ) .getPath ( ) ,
61
+ any ( TupleStructPat p ) .getPath ( )
62
+ ]
63
+ }
64
+
65
+ abstract class PathTypeMention extends TypeMention , Path {
66
+ PathTypeMention ( ) { relevantPathTypeMention ( this ) }
67
+ }
68
+
69
+ class AliasPathTypeMention extends PathTypeMention {
70
+ TypeAlias resolved ;
71
+ TypeMention rhs ;
72
+
73
+ AliasPathTypeMention ( ) {
74
+ resolved = resolvePath ( this ) and
75
+ rhs = resolved .getTypeRepr ( )
76
+ }
77
+
78
+ TypeItemNode getResolved ( ) { result = resolved }
55
79
56
- PathTypeMention ( ) {
57
- resolved = resolvePath ( this )
80
+ /**
81
+ * Holds if this path resolved to a type alias with a rhs. that has the
82
+ * resulting type at `typePath`.
83
+ */
84
+ pragma [ nomagic]
85
+ override Type resolveTypeAt ( TypePath typePath ) {
86
+ result = rhs .resolveTypeAt ( typePath ) and
87
+ not result = pathGetTypeParameter ( resolved , _)
58
88
or
59
- resolved = resolvePath ( this ) .( Variant ) .getEnum ( )
89
+ exists ( TypeParameter tp , TypeMention arg , TypePath prefix , TypePath suffix , int i |
90
+ tp = rhs .resolveTypeAt ( prefix ) and
91
+ tp = pathGetTypeParameter ( resolved , pragma [ only_bind_into ] ( i ) ) and
92
+ arg = this .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( pragma [ only_bind_into ] ( i ) ) and
93
+ result = arg .resolveTypeAt ( suffix ) and
94
+ typePath = prefix .append ( suffix )
95
+ )
96
+ }
97
+ }
98
+
99
+ class NonAliasPathTypeMention extends PathTypeMention {
100
+ TypeItemNode resolved ;
101
+
102
+ NonAliasPathTypeMention ( ) {
103
+ resolved = [ resolvePath ( this ) , resolvePath ( this ) .( Variant ) .getEnum ( ) .( TypeItemNode ) ] and
104
+ not exists ( resolved .( TypeAlias ) .getTypeRepr ( ) )
60
105
}
61
106
62
107
TypeItemNode getResolved ( ) { result = resolved }
63
108
109
+ /**
110
+ * Gets a type alias with the name `name` of the trait that this path resolves
111
+ * to, if any.
112
+ */
64
113
pragma [ nomagic]
65
114
private TypeAlias getResolvedTraitAlias ( string name ) {
66
- exists ( TraitItemNode trait |
67
- trait = resolved and
68
- result = trait .getAnAssocItem ( ) and
69
- name = result .getName ( ) .getText ( )
70
- )
115
+ result = resolved .( TraitItemNode ) .getAnAssocItem ( ) and
116
+ name = result .getName ( ) .getText ( )
71
117
}
72
118
73
119
pragma [ nomagic]
@@ -115,92 +161,75 @@ class PathTypeMention extends TypeMention, Path {
115
161
// If a type argument is not given in the path, then we use the default for
116
162
// the type parameter if one exists for the type.
117
163
not exists ( this .getPositionalTypeArgument0 ( i ) ) and
118
- result = this .resolveType ( ) .getTypeParameterDefault ( i ) and
164
+ result = this .resolveRootType ( ) .getTypeParameterDefault ( i ) and
119
165
// Defaults only apply to type mentions in type annotations
120
166
this = any ( PathTypeRepr ptp ) .getPath ( ) .getQualifier * ( )
121
167
}
122
168
123
- /**
124
- * Holds if this path resolved to a type alias with a rhs. that has the
125
- * resulting type at `typePath`.
126
- */
169
+ /** Gets the type mention in this path for the type parameter `tp`, if any. */
127
170
pragma [ nomagic]
128
- private Type aliasResolveTypeAt ( TypePath typePath ) {
129
- exists ( TypeAlias alias , TypeMention rhs | alias = resolved and rhs = alias .getTypeRepr ( ) |
130
- result = rhs .resolveTypeAt ( typePath ) and
131
- not result = pathGetTypeParameter ( alias , _)
132
- or
133
- exists ( TypeParameter tp , TypeMention arg , TypePath prefix , TypePath suffix , int i |
134
- tp = rhs .resolveTypeAt ( prefix ) and
135
- tp = pathGetTypeParameter ( alias , pragma [ only_bind_into ] ( i ) ) and
136
- arg = this .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( pragma [ only_bind_into ] ( i ) ) and
137
- result = arg .resolveTypeAt ( suffix ) and
138
- typePath = prefix .append ( suffix )
139
- )
171
+ private TypeMention getTypeMentionForTypeParameter ( TypeParameter tp ) {
172
+ exists ( int i |
173
+ result = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) ) and
174
+ tp = this .resolveRootType ( ) .getTypeParameter ( pragma [ only_bind_into ] ( i ) )
175
+ )
176
+ or
177
+ exists ( TypeAlias alias |
178
+ result = this .getAnAssocTypeArgument ( alias ) and
179
+ tp = TAssociatedTypeTypeParameter ( alias )
180
+ )
181
+ or
182
+ // If `path` is the trait of an `impl` block then any associated types
183
+ // defined in the `impl` block are type arguments to the trait.
184
+ //
185
+ // For instance, for a trait implementation like this
186
+ // ```rust
187
+ // impl MyTrait for MyType {
188
+ // ^^^^^^^ path
189
+ // type AssociatedType = i64
190
+ // ^^^ result
191
+ // // ...
192
+ // }
193
+ // ```
194
+ // the rhs. of the type alias is a type argument to the trait.
195
+ exists ( ImplItemNode impl , AssociatedTypeTypeParameter param , TypeAlias alias , string name |
196
+ this = impl .getTraitPath ( ) and
197
+ param .getTrait ( ) = resolved and
198
+ name = param .getTypeAlias ( ) .getName ( ) .getText ( ) and
199
+ alias = impl .getASuccessor ( pragma [ only_bind_into ] ( name ) ) and
200
+ result = alias .getTypeRepr ( ) and
201
+ tp =
202
+ TAssociatedTypeTypeParameter ( resolved
203
+ .( TraitItemNode )
204
+ .getAssocItem ( pragma [ only_bind_into ] ( name ) ) )
140
205
)
141
206
}
142
207
143
- override Type resolveTypeAt ( TypePath typePath ) {
144
- result = this . aliasResolveTypeAt ( typePath )
208
+ Type resolveRootType ( ) {
209
+ result = TStruct ( resolved )
145
210
or
146
- typePath .isEmpty ( ) and
147
- (
148
- result = TStruct ( resolved )
149
- or
150
- result = TEnum ( resolved )
151
- or
152
- exists ( TraitItemNode trait | trait = resolved |
153
- // If this is a `Self` path, then it resolves to the implicit `Self`
154
- // type parameter, otherwise it is a trait bound.
155
- if this = trait .getASelfPath ( )
156
- then result = TSelfTypeParameter ( trait )
157
- else result = TTrait ( trait )
158
- )
159
- or
160
- result = TTypeParamTypeParameter ( resolved )
161
- or
162
- result = TAssociatedTypeTypeParameter ( resolved )
211
+ result = TEnum ( resolved )
212
+ or
213
+ exists ( TraitItemNode trait | trait = resolved |
214
+ // If this is a `Self` path, then it resolves to the implicit `Self`
215
+ // type parameter, otherwise it is a trait bound.
216
+ if this = trait .getASelfPath ( )
217
+ then result = TSelfTypeParameter ( trait )
218
+ else result = TTrait ( trait )
163
219
)
164
220
or
165
- not exists ( resolved .( TypeAlias ) .getTypeRepr ( ) ) and
166
- exists ( TypeParameter tp , TypeMention arg , TypePath suffix |
167
- result = arg .resolveTypeAt ( suffix ) and
221
+ result = TTypeParamTypeParameter ( resolved )
222
+ or
223
+ result = TAssociatedTypeTypeParameter ( resolved )
224
+ }
225
+
226
+ override Type resolveTypeAt ( TypePath typePath ) {
227
+ typePath .isEmpty ( ) and
228
+ result = this .resolveRootType ( )
229
+ or
230
+ exists ( TypeParameter tp , TypePath suffix |
231
+ result = this .getTypeMentionForTypeParameter ( tp ) .resolveTypeAt ( suffix ) and
168
232
typePath = TypePath:: cons ( tp , suffix )
169
- |
170
- exists ( int i |
171
- arg = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) ) and
172
- tp = this .resolveType ( ) .getTypeParameter ( pragma [ only_bind_into ] ( i ) )
173
- )
174
- or
175
- exists ( TypeAlias alias |
176
- arg = this .getAnAssocTypeArgument ( alias ) and
177
- tp = TAssociatedTypeTypeParameter ( alias )
178
- )
179
- or
180
- // If `path` is the trait of an `impl` block then any associated types
181
- // defined in the `impl` block are type arguments to the trait.
182
- //
183
- // For instance, for a trait implementation like this
184
- // ```rust
185
- // impl MyTrait for MyType {
186
- // ^^^^^^^ path
187
- // type AssociatedType = i64
188
- // ^^^ result
189
- // // ...
190
- // }
191
- // ```
192
- // the rhs. of the type alias is a type argument to the trait.
193
- exists ( ImplItemNode impl , AssociatedTypeTypeParameter param , TypeAlias alias , string name |
194
- this = impl .getTraitPath ( ) and
195
- param .getTrait ( ) = resolved and
196
- name = param .getTypeAlias ( ) .getName ( ) .getText ( ) and
197
- alias = impl .getASuccessor ( pragma [ only_bind_into ] ( name ) ) and
198
- arg = alias .getTypeRepr ( ) and
199
- tp =
200
- TAssociatedTypeTypeParameter ( resolved
201
- .( TraitItemNode )
202
- .getAssocItem ( pragma [ only_bind_into ] ( name ) ) )
203
- )
204
233
)
205
234
}
206
235
}
0 commit comments