-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Rust: Associated types are inherited as type parameters by traits and dyn traits #21165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e0c36c7
fd5658d
6219354
a19ad5e
4654001
ca3e2db
8cbe17a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,10 +9,17 @@ | |
| private import codeql.rust.frameworks.stdlib.Stdlib | ||
| private import codeql.rust.frameworks.stdlib.Builtins as Builtins | ||
|
|
||
| /** Gets a type alias of `trait` or of a supertrait of `trait`. */ | ||
| private TypeAlias getTraitTypeAlias(Trait trait) { | ||
| result = trait.getSupertrait*().getAssocItemList().getAnAssocItem() | ||
| } | ||
|
|
||
| /** | ||
| * Holds if a dyn trait type should have a type parameter associated with `n`. A | ||
| * dyn trait type inherits the type parameters of the trait it implements. That | ||
| * includes the type parameters corresponding to associated types. | ||
| * Holds if a dyn trait type for the trait `trait` should have a type parameter | ||
| * associated with `n`. | ||
| * | ||
| * A dyn trait type inherits the type parameters of the trait it implements. | ||
| * That includes the type parameters corresponding to associated types. | ||
| * | ||
| * For instance in | ||
| * ```rust | ||
|
|
@@ -24,10 +31,7 @@ | |
| */ | ||
| private predicate dynTraitTypeParameter(Trait trait, AstNode n) { | ||
| trait = any(DynTraitTypeRepr dt).getTrait() and | ||
| ( | ||
| n = trait.getGenericParamList().getATypeParam() or | ||
| n = trait.(TraitItemNode).getAnAssocItem().(TypeAlias) | ||
| ) | ||
| n = [trait.getGenericParamList().getATypeParam().(AstNode), getTraitTypeAlias(trait)] | ||
| } | ||
|
|
||
| cached | ||
|
|
@@ -39,8 +43,10 @@ | |
| TNeverType() or | ||
| TUnknownType() or | ||
| TTypeParamTypeParameter(TypeParam t) or | ||
| TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or | ||
| TDynTraitTypeParameter(AstNode n) { dynTraitTypeParameter(_, n) } or | ||
| TAssociatedTypeTypeParameter(Trait trait, TypeAlias typeAlias) { | ||
| getTraitTypeAlias(trait) = typeAlias | ||
| } or | ||
| TDynTraitTypeParameter(Trait trait, AstNode n) { dynTraitTypeParameter(trait, n) } or | ||
| TImplTraitTypeParameter(ImplTraitTypeRepr implTrait, TypeParam tp) { | ||
| implTraitTypeParam(implTrait, _, tp) | ||
| } or | ||
|
|
@@ -270,17 +276,10 @@ | |
| DynTraitType() { this = TDynTraitType(trait) } | ||
|
|
||
| override DynTraitTypeParameter getPositionalTypeParameter(int i) { | ||
| result = TDynTraitTypeParameter(trait.getGenericParamList().getTypeParam(i)) | ||
| result.getTypeParam() = trait.getGenericParamList().getTypeParam(i) | ||
| } | ||
|
|
||
| override TypeParameter getATypeParameter() { | ||
| result = super.getATypeParameter() | ||
| or | ||
| exists(AstNode n | | ||
| dynTraitTypeParameter(trait, n) and | ||
| result = TDynTraitTypeParameter(n) | ||
| ) | ||
| } | ||
| override DynTraitTypeParameter getATypeParameter() { result.getTrait() = trait } | ||
|
|
||
| Trait getTrait() { result = trait } | ||
|
|
||
|
|
@@ -427,30 +426,54 @@ | |
| * // ... | ||
| * } | ||
| * ``` | ||
| * Furthermore, associated types of a supertrait induce a corresponding type | ||
| * parameter in any subtraits. E.g., if we have a trait `SubTrait: ATrait` then | ||
| * `SubTrait` also has a type parameter for the associated type | ||
| * `AssociatedType`. | ||
| */ | ||
| class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypeParameter { | ||
| private Trait trait; | ||
| private TypeAlias typeAlias; | ||
|
|
||
| AssociatedTypeTypeParameter() { this = TAssociatedTypeTypeParameter(typeAlias) } | ||
| AssociatedTypeTypeParameter() { this = TAssociatedTypeTypeParameter(trait, typeAlias) } | ||
|
|
||
| TypeAlias getTypeAlias() { result = typeAlias } | ||
|
|
||
| /** Gets the trait that contains this associated type declaration. */ | ||
| TraitItemNode getTrait() { result.getAnAssocItem() = typeAlias } | ||
| TraitItemNode getTrait() { result = trait } | ||
|
|
||
| override ItemNode getDeclaringItem() { result = this.getTrait() } | ||
| /** | ||
| * Holds if this associated type type parameter corresponds directly its | ||
| * trait, that is, it is not inherited from a supertrait. | ||
| */ | ||
| predicate isDirect() { trait.(TraitItemNode).getAnAssocItem() = typeAlias } | ||
|
|
||
| override ItemNode getDeclaringItem() { result = trait } | ||
|
|
||
| override string toString() { result = typeAlias.getName().getText() } | ||
| override string toString() { | ||
| result = typeAlias.getName().getText() + "[" + trait.getName().toString() + "]" | ||
| } | ||
|
|
||
| override Location getLocation() { result = typeAlias.getLocation() } | ||
| } | ||
|
|
||
| /** Gets the associated type type parameter corresponding directly to `typeAlias`. */ | ||
Check warningCode scanning / CodeQL Comment has repeated word Warning
The comment repeats type.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, but it's the "associated-type" "type-parameter".
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest replacing |
||
| AssociatedTypeTypeParameter getAssociatedTypeTypeParameter(TypeAlias typeAlias) { | ||
| result.isDirect() and result.getTypeAlias() = typeAlias | ||
| } | ||
|
|
||
| /** Gets the dyn type type parameter corresponding directly to `typeAlias`. */ | ||
Check warningCode scanning / CodeQL Comment has repeated word Warning
The comment repeats type.
|
||
| DynTraitTypeParameter getDynTraitTypeParameter(TypeAlias typeAlias) { | ||
| result.getTraitTypeParameter() = getAssociatedTypeTypeParameter(typeAlias) | ||
| } | ||
|
|
||
| class DynTraitTypeParameter extends TypeParameter, TDynTraitTypeParameter { | ||
| private Trait trait; | ||
| private AstNode n; | ||
|
|
||
| DynTraitTypeParameter() { this = TDynTraitTypeParameter(n) } | ||
| DynTraitTypeParameter() { this = TDynTraitTypeParameter(trait, n) } | ||
|
|
||
| Trait getTrait() { dynTraitTypeParameter(result, n) } | ||
| Trait getTrait() { result = trait } | ||
|
|
||
| /** Gets the dyn trait type that this type parameter belongs to. */ | ||
| DynTraitType getDynTraitType() { result.getTrait() = this.getTrait() } | ||
|
|
@@ -465,7 +488,7 @@ | |
| TypeParameter getTraitTypeParameter() { | ||
| result.(TypeParamTypeParameter).getTypeParam() = n | ||
| or | ||
| result.(AssociatedTypeTypeParameter).getTypeAlias() = n | ||
| result = TAssociatedTypeTypeParameter(trait, n) | ||
| } | ||
|
|
||
| private string toStringInner() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -148,30 +148,11 @@ | |||||||||||
|
|
||||||||||||
| TypeItemNode getResolved() { result = resolved } | ||||||||||||
|
|
||||||||||||
| /** | ||||||||||||
| * Gets a type alias with the name `name` of the trait that this path resolves | ||||||||||||
| * to, if any. | ||||||||||||
| */ | ||||||||||||
| pragma[nomagic] | ||||||||||||
| private TypeAlias getResolvedTraitAlias(string name) { | ||||||||||||
| result = resolved.(TraitItemNode).getAnAssocItem() and | ||||||||||||
| name = result.getName().getText() | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| pragma[nomagic] | ||||||||||||
|
||||||||||||
| pragma[nomagic] | |
| pragma[nomagic] | |
| /** | |
| * Gets the associated type argument with the given `name` as a type mention. | |
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: inherited by
Check warning
Code scanning / CodeQL
Omittable 'exists' variable Warning
in this argument
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,2 @@ | ||
| multipleResolvedTargets | ||
| | main.rs:3087:13:3087:17 | x.f() | | ||
| | main.rs:2860:13:2860:17 | x.f() | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected grammar: 'corresponds directly its trait' should be 'corresponds directly to its trait'.