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 ) .getAnAssocItem ( ) = 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,59 @@ class TypeParamTypeParameter extends TypeParameter, TTypeParamTypeParameter {
320333 }
321334}
322335
336+ /**
337+ * Gets the type alias that is the `i`th type parameter of `trait`. Type aliases
338+ * are numbered consecutively but in arbitrary order, starting from the index
339+ * following the last ordinary type parameter.
340+ */
341+ predicate traitAliasIndex ( Trait trait , int i , TypeAlias typeAlias ) {
342+ typeAlias =
343+ rank [ i + 1 - trait .getNumberOfGenericParams ( ) ] ( TypeAlias alias |
344+ trait .( TraitItemNode ) .getADescendant ( ) = alias
345+ |
346+ alias order by idOfTypeParameterAstNode ( alias )
347+ )
348+ }
349+
350+ /**
351+ * A type parameter corresponding to an associated type in a trait.
352+ *
353+ * We treat associated type declarations in traits as type parameters. E.g., a
354+ * trait such as
355+ * ```rust
356+ * trait ATrait {
357+ * type AssociatedType;
358+ * // ...
359+ * }
360+ * ```
361+ * is treated as if it was
362+ * ```rust
363+ * trait ATrait<AssociatedType> {
364+ * // ...
365+ * }
366+ * ```
367+ */
368+ class AssociatedTypeTypeParameter extends TypeParameter , TAssociatedTypeTypeParameter {
369+ private TypeAlias typeAlias ;
370+
371+ AssociatedTypeTypeParameter ( ) { this = TAssociatedTypeTypeParameter ( typeAlias ) }
372+
373+ TypeAlias getTypeAlias ( ) { result = typeAlias }
374+
375+ /** Gets the trait that contains this associated type declaration. */
376+ TraitItemNode getTrait ( ) { result .getAnAssocItem ( ) = typeAlias }
377+
378+ int getIndex ( ) { traitAliasIndex ( _, result , typeAlias ) }
379+
380+ override Function getMethod ( string name ) { none ( ) }
381+
382+ override string toString ( ) { result = typeAlias .getName ( ) .getText ( ) }
383+
384+ override Location getLocation ( ) { result = typeAlias .getLocation ( ) }
385+
386+ override TypeMention getABaseTypeMention ( ) { none ( ) }
387+ }
388+
323389/** An implicit reference type parameter. */
324390class RefTypeParameter extends TypeParameter , TRefTypeParameter {
325391 override Function getMethod ( string name ) { none ( ) }
0 commit comments