Skip to content

Commit 804ffdb

Browse files
committed
Rust: Split PathTypeMention into an alias and a non-alias subclass
1 parent 0e8c137 commit 804ffdb

File tree

1 file changed

+71
-62
lines changed

1 file changed

+71
-62
lines changed

rust/ql/lib/codeql/rust/internal/TypeMention.qll

Lines changed: 71 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,46 @@ predicate relevantPathTypeMention(Path path) {
6262
]
6363
}
6464

65-
class PathTypeMention extends TypeMention, Path {
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 }
79+
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, _)
88+
or
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 {
66100
TypeItemNode resolved;
67101

68-
PathTypeMention() {
69-
relevantPathTypeMention(this) and
70-
resolved = [resolvePath(this), resolvePath(this).(Variant).getEnum().(TypeItemNode)]
102+
NonAliasPathTypeMention() {
103+
resolved = [resolvePath(this), resolvePath(this).(Variant).getEnum().(TypeItemNode)] and
104+
not exists(resolved.(TypeAlias).getTypeRepr())
71105
}
72106

73107
TypeItemNode getResolved() { result = resolved }
@@ -132,71 +166,46 @@ class PathTypeMention extends TypeMention, Path {
132166
this = any(PathTypeRepr ptp).getPath().getQualifier*()
133167
}
134168

135-
/**
136-
* Holds if this path resolved to a type alias with a rhs. that has the
137-
* resulting type at `typePath`.
138-
*/
139-
pragma[nomagic]
140-
private Type aliasResolveTypeAt(TypePath typePath) {
141-
exists(TypeAlias alias, TypeMention rhs | alias = resolved and rhs = alias.getTypeRepr() |
142-
result = rhs.resolveTypeAt(typePath) and
143-
not result = pathGetTypeParameter(alias, _)
144-
or
145-
exists(TypeParameter tp, TypeMention arg, TypePath prefix, TypePath suffix, int i |
146-
tp = rhs.resolveTypeAt(prefix) and
147-
tp = pathGetTypeParameter(alias, pragma[only_bind_into](i)) and
148-
arg = this.getSegment().getGenericArgList().getTypeArg(pragma[only_bind_into](i)) and
149-
result = arg.resolveTypeAt(suffix) and
150-
typePath = prefix.append(suffix)
151-
)
152-
)
153-
}
154-
155169
/** Gets the type mention in this path for the type parameter `tp`, if any. */
156170
pragma[nomagic]
157171
private TypeMention getTypeMentionForTypeParameter(TypeParameter tp) {
158-
not exists(resolved.(TypeAlias).getTypeRepr()) and
159-
(
160-
exists(int i |
161-
result = this.getPositionalTypeArgument(pragma[only_bind_into](i)) and
162-
tp = this.resolveType().getTypeParameter(pragma[only_bind_into](i))
163-
)
164-
or
165-
exists(TypeAlias alias |
166-
result = this.getAnAssocTypeArgument(alias) and
167-
tp = TAssociatedTypeTypeParameter(alias)
168-
)
169-
or
170-
// If `path` is the trait of an `impl` block then any associated types
171-
// defined in the `impl` block are type arguments to the trait.
172-
//
173-
// For instance, for a trait implementation like this
174-
// ```rust
175-
// impl MyTrait for MyType {
176-
// ^^^^^^^ path
177-
// type AssociatedType = i64
178-
// ^^^ result
179-
// // ...
180-
// }
181-
// ```
182-
// the rhs. of the type alias is a type argument to the trait.
183-
exists(ImplItemNode impl, AssociatedTypeTypeParameter param, TypeAlias alias, string name |
184-
this = impl.getTraitPath() and
185-
param.getTrait() = resolved and
186-
name = param.getTypeAlias().getName().getText() and
187-
alias = impl.getASuccessor(pragma[only_bind_into](name)) and
188-
result = alias.getTypeRepr() and
189-
tp =
190-
TAssociatedTypeTypeParameter(resolved
191-
.(TraitItemNode)
192-
.getAssocItem(pragma[only_bind_into](name)))
193-
)
172+
exists(int i |
173+
result = this.getPositionalTypeArgument(pragma[only_bind_into](i)) and
174+
tp = this.resolveType().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)))
194205
)
195206
}
196207

197208
override Type resolveTypeAt(TypePath typePath) {
198-
result = this.aliasResolveTypeAt(typePath)
199-
or
200209
typePath.isEmpty() and
201210
(
202211
result = TStruct(resolved)

0 commit comments

Comments
 (0)