mirror of
https://github.com/github/codeql.git
synced 2026-02-12 05:01:06 +01:00
Merge pull request #21172 from paldepind/rust/dyn-abs
Rust: Avoid unnecessary constraint satisfaction
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
private import rust
|
||||
private import codeql.rust.internal.PathResolution
|
||||
private import Type
|
||||
private import TypeAbstraction
|
||||
private import TypeMention
|
||||
private import TypeInference
|
||||
private import FunctionType
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
private import rust
|
||||
private import codeql.rust.internal.PathResolution
|
||||
private import TypeInference
|
||||
private import Type
|
||||
private import TypeAbstraction
|
||||
private import TypeMention
|
||||
private import TypeInference
|
||||
|
||||
private newtype TFunctionPosition =
|
||||
TArgumentFunctionPosition(ArgumentPosition pos) or
|
||||
|
||||
@@ -569,58 +569,6 @@ class ImplTraitTypeTypeParameter extends ImplTraitType, TypeParameter {
|
||||
override TypeParameter getPositionalTypeParameter(int i) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A type abstraction. I.e., a place in the program where type variables are
|
||||
* introduced.
|
||||
*
|
||||
* Example:
|
||||
* ```rust
|
||||
* impl<A, B> Foo<A, B> { }
|
||||
* // ^^^^^^ a type abstraction
|
||||
* ```
|
||||
*/
|
||||
abstract class TypeAbstraction extends AstNode {
|
||||
abstract TypeParameter getATypeParameter();
|
||||
}
|
||||
|
||||
final class ImplTypeAbstraction extends TypeAbstraction, Impl {
|
||||
override TypeParamTypeParameter getATypeParameter() {
|
||||
result.getTypeParam() = this.getGenericParamList().getATypeParam()
|
||||
}
|
||||
}
|
||||
|
||||
final class DynTypeAbstraction extends TypeAbstraction, DynTraitTypeRepr {
|
||||
override TypeParameter getATypeParameter() {
|
||||
result = any(DynTraitTypeParameter tp | tp.getTrait() = this.getTrait()).getTraitTypeParameter()
|
||||
}
|
||||
}
|
||||
|
||||
final class TraitTypeAbstraction extends TypeAbstraction, Trait {
|
||||
override TypeParameter getATypeParameter() {
|
||||
result.(TypeParamTypeParameter).getTypeParam() = this.getGenericParamList().getATypeParam()
|
||||
or
|
||||
result.(AssociatedTypeTypeParameter).getTrait() = this
|
||||
or
|
||||
result.(SelfTypeParameter).getTrait() = this
|
||||
}
|
||||
}
|
||||
|
||||
final class TypeBoundTypeAbstraction extends TypeAbstraction, TypeBound {
|
||||
override TypeParameter getATypeParameter() { none() }
|
||||
}
|
||||
|
||||
final class SelfTypeBoundTypeAbstraction extends TypeAbstraction, Name {
|
||||
SelfTypeBoundTypeAbstraction() { any(TraitTypeAbstraction trait).getName() = this }
|
||||
|
||||
override TypeParameter getATypeParameter() { none() }
|
||||
}
|
||||
|
||||
final class ImplTraitTypeReprAbstraction extends TypeAbstraction, ImplTraitTypeRepr {
|
||||
override TypeParameter getATypeParameter() {
|
||||
implTraitTypeParam(this, _, result.(TypeParamTypeParameter).getTypeParam())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `t` is a valid complex [`self` root type][1].
|
||||
*
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
private import rust
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import Type
|
||||
|
||||
/**
|
||||
* A type abstraction. I.e., a place in the program where type variables are
|
||||
* introduced.
|
||||
*
|
||||
* Example:
|
||||
* ```rust
|
||||
* impl<A, B> Foo<A, B> { }
|
||||
* // ^^^^^^ a type abstraction
|
||||
* ```
|
||||
*/
|
||||
abstract class TypeAbstraction extends AstNode {
|
||||
abstract TypeParameter getATypeParameter();
|
||||
}
|
||||
|
||||
final class ImplTypeAbstraction extends TypeAbstraction, Impl {
|
||||
override TypeParamTypeParameter getATypeParameter() {
|
||||
result.getTypeParam() = this.getGenericParamList().getATypeParam()
|
||||
}
|
||||
}
|
||||
|
||||
private predicate idDynTraitTypeRepr(Raw::DynTraitTypeRepr x, Raw::DynTraitTypeRepr y) { x = y }
|
||||
|
||||
private predicate idOfDynTraitTypeRepr(Raw::DynTraitTypeRepr x, int y) =
|
||||
equivalenceRelation(idDynTraitTypeRepr/2)(x, y)
|
||||
|
||||
private int idOfDynTraitTypeRepr(DynTraitTypeRepr node) {
|
||||
idOfDynTraitTypeRepr(Synth::convertAstNodeToRaw(node), result)
|
||||
}
|
||||
|
||||
/** Holds if `dt` is the (arbitrarily chosen) canonical dyn trait type abstraction for `trait`. */
|
||||
private predicate canonicalDynTraitTypeAbstraction(DynTraitTypeRepr dt) {
|
||||
exists(Trait trait |
|
||||
dt = min(DynTraitTypeRepr d | d.getTrait() = trait | d order by idOfDynTraitTypeRepr(d))
|
||||
)
|
||||
}
|
||||
|
||||
final class DynTypeAbstraction extends TypeAbstraction, DynTraitTypeRepr {
|
||||
DynTypeAbstraction() {
|
||||
// We pick a "canonical" `dyn Trait` in order to avoid including multiple
|
||||
// entries in `conditionSatisfiesConstraint` with the exact same effect when
|
||||
// `dyn Trait` occurs multiple times for the same trait.
|
||||
canonicalDynTraitTypeAbstraction(this)
|
||||
}
|
||||
|
||||
override TypeParameter getATypeParameter() {
|
||||
result = any(DynTraitTypeParameter tp | tp.getTrait() = this.getTrait()).getTraitTypeParameter()
|
||||
}
|
||||
}
|
||||
|
||||
final class TraitTypeAbstraction extends TypeAbstraction, Trait {
|
||||
override TypeParameter getATypeParameter() {
|
||||
result.(TypeParamTypeParameter).getTypeParam() = this.getGenericParamList().getATypeParam()
|
||||
or
|
||||
result.(AssociatedTypeTypeParameter).getTrait() = this
|
||||
or
|
||||
result.(SelfTypeParameter).getTrait() = this
|
||||
}
|
||||
}
|
||||
|
||||
final class TypeBoundTypeAbstraction extends TypeAbstraction, TypeBound {
|
||||
override TypeParameter getATypeParameter() { none() }
|
||||
}
|
||||
|
||||
final class SelfTypeBoundTypeAbstraction extends TypeAbstraction, Name {
|
||||
SelfTypeBoundTypeAbstraction() { any(TraitTypeAbstraction trait).getName() = this }
|
||||
|
||||
override TypeParameter getATypeParameter() { none() }
|
||||
}
|
||||
|
||||
final class ImplTraitTypeReprAbstraction extends TypeAbstraction, ImplTraitTypeRepr {
|
||||
override TypeParamTypeParameter getATypeParameter() {
|
||||
exists(TImplTraitTypeParameter(this, result.getTypeParam()))
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ private import codeql.util.Option
|
||||
private import rust
|
||||
private import codeql.rust.internal.PathResolution
|
||||
private import Type
|
||||
private import TypeAbstraction
|
||||
private import TypeAbstraction as TA
|
||||
private import Type as T
|
||||
private import TypeMention
|
||||
private import codeql.rust.internal.typeinference.DerefChain
|
||||
@@ -37,7 +39,7 @@ private module Input1 implements InputSig1<Location> {
|
||||
|
||||
class TypeParameter = T::TypeParameter;
|
||||
|
||||
class TypeAbstraction = T::TypeAbstraction;
|
||||
class TypeAbstraction = TA::TypeAbstraction;
|
||||
|
||||
class TypeArgumentPosition extends TTypeArgumentPosition {
|
||||
int asMethodTypeArgumentPosition() { this = TMethodTypeArgumentPosition(result) }
|
||||
|
||||
@@ -4,6 +4,7 @@ private import rust
|
||||
private import codeql.rust.internal.PathResolution
|
||||
private import codeql.rust.frameworks.stdlib.Stdlib
|
||||
private import Type
|
||||
private import TypeAbstraction
|
||||
private import TypeInference
|
||||
|
||||
/** An AST node that may mention a type. */
|
||||
@@ -563,7 +564,14 @@ class DynTypeBoundListMention extends TypeMention instanceof TypeBoundList {
|
||||
private Trait trait;
|
||||
|
||||
DynTypeBoundListMention() {
|
||||
exists(DynTraitTypeRepr dyn | this = dyn.getTypeBoundList() and trait = dyn.getTrait())
|
||||
exists(DynTraitTypeRepr dyn |
|
||||
// We only need this type mention when the `dyn Trait` is a type
|
||||
// abstraction, that is, when it's "canonical" and used in
|
||||
// `conditionSatisfiesConstraint`.
|
||||
dyn instanceof DynTypeAbstraction and
|
||||
this = dyn.getTypeBoundList() and
|
||||
trait = dyn.getTrait()
|
||||
)
|
||||
}
|
||||
|
||||
override Type resolveTypeAt(TypePath path) {
|
||||
|
||||
Reference in New Issue
Block a user