22
33private import rust
44private import PathResolution
5- private import TypeInference
65private import TypeMention
76private import codeql.rust.internal.CachedStages
7+ private import codeql.rust.elements.internal.generated.Raw
8+ private import codeql.rust.elements.internal.generated.Synth
89
910cached
1011newtype TType =
@@ -15,6 +16,7 @@ newtype TType =
1516 TArrayType ( ) or // todo: add size?
1617 TRefType ( ) or // todo: add mut?
1718 TTypeParamTypeParameter ( TypeParam t ) or
19+ TAssociatedTypeTypeParameter ( TypeAlias t ) { any ( TraitItemNode trait ) .getADescendant ( ) = t } or
1820 TRefTypeParameter ( ) or
1921 TSelfTypeParameter ( Trait t )
2022
@@ -144,6 +146,9 @@ class TraitType extends Type, TTrait {
144146
145147 override TypeParameter getTypeParameter ( int i ) {
146148 result = TTypeParamTypeParameter ( trait .getGenericParamList ( ) .getTypeParam ( i ) )
149+ or
150+ result =
151+ any ( AssociatedTypeTypeParameter param | param .getTrait ( ) = trait and param .getIndex ( ) = i )
147152 }
148153
149154 pragma [ nomagic]
@@ -297,6 +302,14 @@ abstract class TypeParameter extends Type {
297302 override TypeParameter getTypeParameter ( int i ) { none ( ) }
298303}
299304
305+ private class RawTypeParameter = @type_param or @trait or @type_alias;
306+
307+ private predicate id ( RawTypeParameter x , RawTypeParameter y ) { x = y }
308+
309+ private predicate idOfRaw ( RawTypeParameter x , int y ) = equivalenceRelation( id / 2 ) ( x , y )
310+
311+ int idOfTypeParameterAstNode ( AstNode node ) { idOfRaw ( Synth:: convertAstNodeToRaw ( node ) , result ) }
312+
300313/** A type parameter from source code. */
301314class TypeParamTypeParameter extends TypeParameter , TTypeParamTypeParameter {
302315 private TypeParam typeParam ;
@@ -320,6 +333,55 @@ class TypeParamTypeParameter extends TypeParameter, TTypeParamTypeParameter {
320333 }
321334}
322335
336+ /** Gets type alias that is the `i`th type parameter of `trait`. */
337+ predicate traitAliasIndex ( Trait trait , int i , TypeAlias typeAlias ) {
338+ typeAlias =
339+ rank [ i + 1 - trait .getNumberOfGenericParams ( ) ] ( TypeAlias alias |
340+ trait .( TraitItemNode ) .getADescendant ( ) = alias
341+ |
342+ alias order by idOfTypeParameterAstNode ( alias )
343+ )
344+ }
345+
346+ /**
347+ * A type parameter corresponding to an associated type in a trait.
348+ *
349+ * We treat associated type declarations in traits as type parameters. E.g., a
350+ * trait such as
351+ * ```rust
352+ * trait ATrait {
353+ * type AssociatedType;
354+ * // ...
355+ * }
356+ * ```
357+ * is treated as if it where
358+ * ```rust
359+ * trait ATrait<AssociatedType> {
360+ * // ...
361+ * }
362+ * ```
363+ */
364+ class AssociatedTypeTypeParameter extends TypeParameter , TAssociatedTypeTypeParameter {
365+ private TypeAlias typeAlias ;
366+
367+ AssociatedTypeTypeParameter ( ) { this = TAssociatedTypeTypeParameter ( typeAlias ) }
368+
369+ TypeAlias getTypeAlias ( ) { result = typeAlias }
370+
371+ /** Gets the trait that contains this associated type declaration. */
372+ TraitItemNode getTrait ( ) { result .getADescendant ( ) = typeAlias }
373+
374+ int getIndex ( ) { traitAliasIndex ( this .getTrait ( ) , result , typeAlias ) }
375+
376+ override Function getMethod ( string name ) { none ( ) }
377+
378+ override string toString ( ) { result = typeAlias .getName ( ) .getText ( ) }
379+
380+ override Location getLocation ( ) { result = typeAlias .getLocation ( ) }
381+
382+ override TypeMention getABaseTypeMention ( ) { none ( ) }
383+ }
384+
323385/** An implicit reference type parameter. */
324386class RefTypeParameter extends TypeParameter , TRefTypeParameter {
325387 override Function getMethod ( string name ) { none ( ) }
0 commit comments