Merge pull request #21215 from paldepind/shared/type-mention-tree

Shared, Rust: Use `HasTypeTreeSig` for `TypeMention`
This commit is contained in:
Simon Friis Vindum
2026-01-26 12:00:02 +01:00
committed by GitHub
9 changed files with 139 additions and 164 deletions

View File

@@ -224,7 +224,7 @@ private module Debug {
sc.propagatesFlow(input, _, _, _) and
input.head() = SummaryComponent::argument(pos) and
p = pos.getParameterIn(sc.getParamList()) and
tm.resolveType() instanceof RefType and
tm.getType() instanceof RefType and
not input.tail().head() = SummaryComponent::content(TSingletonContentSet(TReferenceContent()))
|
tm = p.getTypeRepr()
@@ -239,7 +239,7 @@ private module Debug {
exists(TypeMention tm |
relevantManualModel(sc, can) and
sc.propagatesFlow(_, output, _, _) and
tm.resolveType() instanceof RefType and
tm.getType() instanceof RefType and
output.head() = SummaryComponent::return(_) and
not output.tail().head() =
SummaryComponent::content(TSingletonContentSet(TReferenceContent())) and

View File

@@ -47,8 +47,8 @@ predicate isBlanketLike(ImplItemNode i, TypePath blanketSelfPath, TypeParam blan
exists(TypeMention tm, Type root, TypeParameter tp |
tm = i.(Impl).getSelfTy() and
complexSelfRoot(root, tp) and
tm.resolveType() = root and
tm.resolveTypeAt(blanketSelfPath) = TTypeParamTypeParameter(blanketTypeParam) and
tm.getType() = root and
tm.getTypeAt(blanketSelfPath) = TTypeParamTypeParameter(blanketTypeParam) and
blanketSelfPath = TypePath::singleton(tp) and
hasFirstNonTrivialTraitBound(blanketTypeParam, _)
)

View File

@@ -25,8 +25,8 @@ class DerefImplItemNode extends ImplItemNode {
*/
pragma[nomagic]
predicate targetHasTypeParameterAt(TypePath path) {
this.getAssocItem("Target").(TypeAlias).getTypeRepr().(TypeMention).resolveTypeAt(path)
instanceof TypeParameter
this.getAssocItem("Target").(TypeAlias).getTypeRepr().(TypeMention).getTypeAt(path) instanceof
TypeParameter
}
/** Gets the first type parameter of the type being implemented, if any. */

View File

@@ -15,7 +15,7 @@ private import FunctionType
pragma[nomagic]
private Type resolveNonTypeParameterTypeAt(TypeMention tm, TypePath path) {
result = tm.resolveTypeAt(path) and
result = tm.getTypeAt(path) and
not result instanceof TypeParameter
}
@@ -32,7 +32,7 @@ private predicate implSiblingCandidate(
) {
trait = impl.(ImplItemNode).resolveTraitTy() and
selfTy = impl.getSelfTy() and
rootType = selfTy.resolveType()
rootType = selfTy.getType()
}
pragma[nomagic]

View File

@@ -103,12 +103,12 @@ Type getAssocFunctionTypeAt(Function f, ImplOrTraitItemNode i, FunctionPosition
// No specialization needed when the function is directly in the trait or
// impl block or the declared type is not a type parameter
(parent = i or not result instanceof TypeParameter) and
result = pos.getTypeMention(f).resolveTypeAt(path)
result = pos.getTypeMention(f).getTypeAt(path)
or
exists(TypePath prefix, TypePath suffix, TypeParameter tp, TypeMention constraint |
BaseTypes::rootTypesSatisfaction(_, TTrait(parent), i, _, constraint) and
path = prefix.append(suffix) and
tp = pos.getTypeMention(f).resolveTypeAt(prefix) and
tp = pos.getTypeMention(f).getTypeAt(prefix) and
if tp = TSelfTypeParameter(_)
then result = resolveImplOrTraitType(i, suffix)
else result = getTraitConstraintTypeAt(i, constraint, tp, suffix)

View File

@@ -134,15 +134,11 @@ class TypePath = M1::TypePath;
module TypePath = M1::TypePath;
private module Input2 implements InputSig2 {
private import TypeMention as TM
class TypeMention = TM::TypeMention;
private module Input2 implements InputSig2<TypeMention> {
TypeMention getABaseTypeMention(Type t) { none() }
Type getATypeParameterConstraint(TypeParameter tp, TypePath path) {
exists(TypeMention tm | result = tm.resolveTypeAt(path) |
exists(TypeMention tm | result = tm.getTypeAt(path) |
tm = tp.(TypeParamTypeParameter).getTypeParam().getATypeBound().getTypeRepr() or
tm = tp.(SelfTypeParameter).getTrait() or
tm =
@@ -212,7 +208,7 @@ private module Input2 implements InputSig2 {
}
}
private module M2 = Make2<Input2>;
private module M2 = Make2<TypeMention, Input2>;
import M2
@@ -231,7 +227,7 @@ module Consistency {
// mention for the self type has multiple types for a path.
not exists(ImplItemNode impl, TypePath selfTypePath |
n = impl.getAnAssocItem().(Function).getSelfParam() and
strictcount(impl.(Impl).getSelfTy().(TypeMention).resolveTypeAt(selfTypePath)) > 1
strictcount(impl.(Impl).getSelfTy().(TypeMention).getTypeAt(selfTypePath)) > 1
)
}
}
@@ -297,7 +293,7 @@ private class FunctionDeclaration extends Function {
result = getAssocFunctionTypeAt(this, i.asSome(), pos, path)
or
i.isNone() and
result = this.getParam(pos.asPosition()).getTypeRepr().(TypeMention).resolveTypeAt(path)
result = this.getParam(pos.asPosition()).getTypeRepr().(TypeMention).getTypeAt(path)
)
}
@@ -308,7 +304,7 @@ private class FunctionDeclaration extends Function {
getAssocFunctionTypeAt(this, i.asSome(), any(FunctionPosition pos | pos.isReturn()), path)
or
i.isNone() and
result = getReturnTypeMention(this).resolveTypeAt(path)
result = getReturnTypeMention(this).getTypeAt(path)
)
}
@@ -352,12 +348,12 @@ private TypeMention getCallExprTypeMentionArgument(CallExpr ce, TypeArgumentPosi
pragma[nomagic]
private Type getCallExprTypeArgument(CallExpr ce, TypeArgumentPosition apos, TypePath path) {
result = getCallExprTypeMentionArgument(ce, apos).resolveTypeAt(path)
result = getCallExprTypeMentionArgument(ce, apos).getTypeAt(path)
or
// Handle constructions that use `Self(...)` syntax
exists(Path p, TypePath path0 |
p = CallExprImpl::getFunctionPath(ce) and
result = p.(TypeMention).resolveTypeAt(path0) and
result = p.(TypeMention).getTypeAt(path0) and
path0.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path)
)
}
@@ -380,16 +376,16 @@ private TypeMention getTypeAnnotation(AstNode n) {
/** Gets the type of `n`, which has an explicit type annotation. */
pragma[nomagic]
private Type inferAnnotatedType(AstNode n, TypePath path) {
result = getTypeAnnotation(n).resolveTypeAt(path)
result = getTypeAnnotation(n).getTypeAt(path)
or
result = n.(ShorthandSelfParameterMention).resolveTypeAt(path)
result = n.(ShorthandSelfParameterMention).getTypeAt(path)
}
pragma[nomagic]
private Type inferFunctionBodyType(AstNode n, TypePath path) {
exists(Function f |
n = f.getFunctionBody() and
result = getReturnTypeMention(f).resolveTypeAt(path) and
result = getReturnTypeMention(f).getTypeAt(path) and
not exists(ImplTraitReturnType i | i.getFunction() = f |
result = i or result = i.getATypeParameter()
)
@@ -433,7 +429,7 @@ module CertainTypeInference {
private TypePath getPathToImplSelfTypeParam(TypeParam tp) {
exists(ImplItemNode impl |
tp = impl.getTypeParam(_) and
TTypeParamTypeParameter(tp) = impl.(Impl).getSelfTy().(TypeMention).resolveTypeAt(result)
TTypeParamTypeParameter(tp) = impl.(Impl).getSelfTy().(TypeMention).getTypeAt(result)
)
}
@@ -449,7 +445,7 @@ module CertainTypeInference {
// and the path `Foo<i64>::bar` we must resolve `A` to `i64`.
exists(TypePath pathToTp |
pathToTp = getPathToImplSelfTypeParam(tp) and
result = p.getQualifier().(TypeMention).resolveTypeAt(pathToTp.appendInverse(suffix))
result = p.getQualifier().(TypeMention).getTypeAt(pathToTp.appendInverse(suffix))
)
or
// For type parameters of the function we must resolve their
@@ -465,11 +461,11 @@ module CertainTypeInference {
}
private Type inferCertainStructExprType(StructExpr se, TypePath path) {
result = se.getPath().(TypeMention).resolveTypeAt(path)
result = se.getPath().(TypeMention).getTypeAt(path)
}
private Type inferCertainStructPatType(StructPat sp, TypePath path) {
result = sp.getPath().(TypeMention).resolveTypeAt(path)
result = sp.getPath().(TypeMention).getTypeAt(path)
}
predicate certainTypeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
@@ -905,7 +901,7 @@ private module StructExprMatchingInput implements MatchingInputSig {
// type of a field
exists(TypeMention tp |
tp = this.getField(dpos.asFieldPos()).getTypeRepr() and
result = tp.resolveTypeAt(path)
result = tp.getTypeAt(path)
)
or
// type parameter of the struct itself
@@ -958,7 +954,7 @@ private module StructExprMatchingInput implements MatchingInputSig {
// Handle constructions that use `Self {...}` syntax
exists(TypeMention tm, TypePath path0 |
tm = this.getStructPath() and
result = tm.resolveTypeAt(path0) and
result = tm.getTypeAt(path0) and
path0.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path)
)
}
@@ -1068,7 +1064,7 @@ pragma[nomagic]
private Type getCallExprTypeQualifier(CallExpr ce, TypePath path) {
exists(TypeMention tm |
tm = getCallExprPathQualifier(ce) and
result = tm.resolveTypeAt(path) and
result = tm.getTypeAt(path) and
not resolvePath(tm) instanceof Trait
)
}
@@ -2330,11 +2326,11 @@ private module MethodResolution {
* instance of the type being implemented.
*/
private module TypeQualifierIsInstantiationOfImplSelfInput implements
IsInstantiationOfInputSig<MethodCallCallExpr, TypeMentionTypeTree>
IsInstantiationOfInputSig<MethodCallCallExpr, TypeMention>
{
pragma[nomagic]
private predicate potentialInstantiationOf0(
MethodCallCallExpr ce, ImplItemNode impl, TypeMentionTypeTree constraint
MethodCallCallExpr ce, ImplItemNode impl, TypeMention constraint
) {
ce.hasTypeQualifiedCandidate(impl) and
constraint = impl.getSelfPath()
@@ -2342,7 +2338,7 @@ private module MethodResolution {
pragma[nomagic]
predicate potentialInstantiationOf(
MethodCallCallExpr ce, TypeAbstraction abs, TypeMentionTypeTree constraint
MethodCallCallExpr ce, TypeAbstraction abs, TypeMention constraint
) {
potentialInstantiationOf0(ce, abs, constraint) and
if abs.(Impl).hasTrait()
@@ -2353,14 +2349,13 @@ private module MethodResolution {
else any()
}
predicate relevantConstraint(TypeMentionTypeTree constraint) {
predicate relevantConstraint(TypeMention constraint) {
potentialInstantiationOf0(_, _, constraint)
}
}
private module TypeQualifierIsInstantiationOfImplSelf =
IsInstantiationOf<MethodCallCallExpr, TypeMentionTypeTree,
TypeQualifierIsInstantiationOfImplSelfInput>;
IsInstantiationOf<MethodCallCallExpr, TypeMention, TypeQualifierIsInstantiationOfImplSelfInput>;
/**
* A configuration for anti-matching the type of a receiver against the type of
@@ -2481,7 +2476,7 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
.getGenericArgList()
.getTypeArg(apos.asMethodTypeArgumentPosition())
.(TypeMention)
.resolveTypeAt(path)
.getTypeAt(path)
or
result = getCallExprTypeArgument(this, apos, path)
}
@@ -3012,7 +3007,7 @@ abstract private class TupleLikeConstructor extends Addressable {
}
Type getParameterType(FunctionPosition pos, TypePath path) {
result = this.getTupleField(pos.asPosition()).getTypeRepr().(TypeMention).resolveTypeAt(path)
result = this.getTupleField(pos.asPosition()).getTypeRepr().(TypeMention).getTypeAt(path)
}
}
@@ -3367,7 +3362,7 @@ private module FieldExprMatchingInput implements MatchingInputSig {
)
or
dpos.isField() and
result = this.getTypeRepr().(TypeMention).resolveTypeAt(path)
result = this.getTypeRepr().(TypeMention).getTypeAt(path)
}
override string toString() { result = this.getAstNode().toString() }
@@ -3719,7 +3714,7 @@ private module StructPatMatchingInput implements MatchingInputSig {
// The struct/enum type is supplied explicitly as a type qualifier, e.g.
// `let Foo<Bar>::Variant { ... } = ...`.
apos.isStructPos() and
result = this.getPath().(TypeMention).resolveTypeAt(path)
result = this.getPath().(TypeMention).getTypeAt(path)
}
Declaration getTarget() { result = resolvePath(this.getPath()) }
@@ -3769,7 +3764,7 @@ private module TupleStructPatMatchingInput implements MatchingInputSig {
// The struct/enum type is supplied explicitly as a type qualifier, e.g.
// `let Option::<Foo>::Some(x) = ...`.
apos.isSelf() and
result = this.getPath().(TypeMention).resolveTypeAt(path)
result = this.getPath().(TypeMention).getTypeAt(path)
}
Declaration getTarget() { result = resolvePath(this.getPath()) }
@@ -3958,13 +3953,13 @@ private Type inferClosureExprType(AstNode n, TypePath path) {
or
// Propagate return type annotation to body
n = ce.getClosureBody() and
result = ce.getRetType().getTypeRepr().(TypeMention).resolveTypeAt(path)
result = ce.getRetType().getTypeRepr().(TypeMention).getTypeAt(path)
)
}
pragma[nomagic]
private Type inferCastExprType(CastExpr ce, TypePath path) {
result = ce.getTypeRepr().(TypeMention).resolveTypeAt(path)
result = ce.getTypeRepr().(TypeMention).getTypeAt(path)
}
cached
@@ -4162,7 +4157,7 @@ private module Debug {
predicate debugInferShorthandSelfType(ShorthandSelfParameterMention self, TypePath path, Type t) {
self = getRelevantLocatable() and
t = self.resolveTypeAt(path)
t = self.getTypeAt(path)
}
predicate debugInferMethodCallType(AstNode n, TypePath path, Type t) {
@@ -4177,7 +4172,7 @@ private module Debug {
predicate debugTypeMention(TypeMention tm, TypePath path, Type type) {
tm = getRelevantLocatable() and
tm.resolveTypeAt(path) = type
tm.getTypeAt(path) = type
}
Type debugInferAnnotatedType(AstNode n, TypePath path) {

View File

@@ -17,7 +17,7 @@ query predicate illFormedTypeMention(TypeMention tm) {
not tm =
any(PathTypeMention ptm |
exists(ptm.resolvePathTypeAt(TypePath::nil())) and
not exists(ptm.resolveType())
not exists(ptm.getType())
or
ptm.(NonAliasPathTypeMention).getResolved() instanceof TypeAlias
) and

View File

@@ -11,44 +11,44 @@ private import TypeInference
abstract class TypeMention extends AstNode {
/** Gets the type at `path` that this mention resolves to, if any. */
pragma[nomagic]
abstract Type resolveTypeAt(TypePath path);
abstract Type getTypeAt(TypePath path);
/** Gets the type that this node resolves to, if any. */
pragma[nomagic]
final Type resolveType() { result = this.resolveTypeAt(TypePath::nil()) }
final Type getType() { result = this.getTypeAt(TypePath::nil()) }
}
class TupleTypeReprMention extends TypeMention instanceof TupleTypeRepr {
override Type resolveTypeAt(TypePath path) {
override Type getTypeAt(TypePath path) {
path.isEmpty() and
result.(TupleType).getArity() = super.getNumberOfFields()
or
exists(TypePath suffix, int i |
result = super.getField(i).(TypeMention).resolveTypeAt(suffix) and
result = super.getField(i).(TypeMention).getTypeAt(suffix) and
path = TypePath::cons(getTupleTypeParameter(super.getNumberOfFields(), i), suffix)
)
}
}
class ParenthesizedArgListMention extends TypeMention instanceof ParenthesizedArgList {
override Type resolveTypeAt(TypePath path) {
override Type getTypeAt(TypePath path) {
path.isEmpty() and
result.(TupleType).getArity() = super.getNumberOfTypeArgs()
or
exists(TypePath suffix, int index |
result = super.getTypeArg(index).getTypeRepr().(TypeMention).resolveTypeAt(suffix) and
result = super.getTypeArg(index).getTypeRepr().(TypeMention).getTypeAt(suffix) and
path = TypePath::cons(getTupleTypeParameter(super.getNumberOfTypeArgs(), index), suffix)
)
}
}
class ArrayTypeReprMention extends TypeMention instanceof ArrayTypeRepr {
override Type resolveTypeAt(TypePath path) {
override Type getTypeAt(TypePath path) {
path.isEmpty() and
result instanceof ArrayType
or
exists(TypePath suffix |
result = super.getElementTypeRepr().(TypeMention).resolveTypeAt(suffix) and
result = super.getElementTypeRepr().(TypeMention).getTypeAt(suffix) and
path = TypePath::cons(getArrayTypeParameter(), suffix)
)
}
@@ -59,23 +59,23 @@ class RefTypeReprMention extends TypeMention instanceof RefTypeRepr {
if super.isMut() then result instanceof RefMutType else result instanceof RefSharedType
}
override Type resolveTypeAt(TypePath path) {
override Type getTypeAt(TypePath path) {
path.isEmpty() and result = this.resolveRootType()
or
exists(TypePath suffix |
result = super.getTypeRepr().(TypeMention).resolveTypeAt(suffix) and
result = super.getTypeRepr().(TypeMention).getTypeAt(suffix) and
path = TypePath::cons(this.resolveRootType().getPositionalTypeParameter(0), suffix)
)
}
}
class SliceTypeReprMention extends TypeMention instanceof SliceTypeRepr {
override Type resolveTypeAt(TypePath path) {
override Type getTypeAt(TypePath path) {
path.isEmpty() and
result instanceof SliceType
or
exists(TypePath suffix |
result = super.getTypeRepr().(TypeMention).resolveTypeAt(suffix) and
result = super.getTypeRepr().(TypeMention).getTypeAt(suffix) and
path = TypePath::cons(getSliceTypeParameter(), suffix)
)
}
@@ -84,7 +84,7 @@ class SliceTypeReprMention extends TypeMention instanceof SliceTypeRepr {
abstract class PathTypeMention extends TypeMention, Path {
abstract Type resolvePathTypeAt(TypePath typePath);
final override Type resolveTypeAt(TypePath typePath) {
final override Type getTypeAt(TypePath typePath) {
result = this.resolvePathTypeAt(typePath) and
(
not result instanceof TypeParameter
@@ -111,14 +111,14 @@ class AliasPathTypeMention extends PathTypeMention {
* resulting type at `typePath`.
*/
override Type resolvePathTypeAt(TypePath typePath) {
result = rhs.resolveTypeAt(typePath) and
result = rhs.getTypeAt(typePath) and
not result = pathGetTypeParameter(resolved, _)
or
exists(TypeParameter tp, TypeMention arg, TypePath prefix, TypePath suffix, int i |
tp = rhs.resolveTypeAt(prefix) and
tp = rhs.getTypeAt(prefix) and
tp = pathGetTypeParameter(resolved, pragma[only_bind_into](i)) and
arg = this.getSegment().getGenericArgList().getTypeArg(pragma[only_bind_into](i)) and
result = arg.resolveTypeAt(suffix) and
result = arg.getTypeAt(suffix) and
typePath = prefix.append(suffix)
)
}
@@ -176,7 +176,7 @@ class NonAliasPathTypeMention extends PathTypeMention {
// Defaults only apply to type mentions in type annotations
this = any(PathTypeRepr ptp).getPath().getQualifier*() and
exists(Type ty, TypePath prefix |
ty = this.resolveRootType().getTypeParameterDefault(i).resolveTypeAt(prefix) and
ty = this.resolveRootType().getTypeParameterDefault(i).getTypeAt(prefix) and
if not ty = TSelfTypeParameter(resolved)
then result = ty and path = prefix
else
@@ -184,13 +184,13 @@ class NonAliasPathTypeMention extends PathTypeMention {
// be substituted for the type that implements the trait.
exists(TypePath suffix |
path = prefix.append(suffix) and
result = this.getSelfTraitBoundArg().resolveTypeAt(suffix)
result = this.getSelfTraitBoundArg().getTypeAt(suffix)
)
)
}
private Type getPositionalTypeArgument(int i, TypePath path) {
result = getPathTypeArgument(this, i).resolveTypeAt(path)
result = getPathTypeArgument(this, i).getTypeAt(path)
or
result = this.getDefaultPositionalTypeArgument(i, path)
}
@@ -219,11 +219,11 @@ class NonAliasPathTypeMention extends PathTypeMention {
s.hasParenthesizedArgList()
|
tp = TTypeParamTypeParameter(t.getTypeParam()) and
result = s.getParenthesizedArgList().(TypeMention).resolveTypeAt(path)
result = s.getParenthesizedArgList().(TypeMention).getTypeAt(path)
or
tp = TAssociatedTypeTypeParameter(t, any(FnOnceTrait tr).getOutputType()) and
(
result = s.getRetType().getTypeRepr().(TypeMention).resolveTypeAt(path)
result = s.getRetType().getTypeRepr().(TypeMention).getTypeAt(path)
or
// When the `-> ...` return type is omitted, it defaults to `()`.
not s.hasRetType() and
@@ -319,24 +319,24 @@ class NonAliasPathTypeMention extends PathTypeMention {
exists(TypeParameter tp, TypePath suffix | typePath = TypePath::cons(tp, suffix) |
result = this.getTypeForTypeParameterAt(tp, suffix)
or
result = this.getTypeMentionForTypeParameter(tp).resolveTypeAt(suffix)
result = this.getTypeMentionForTypeParameter(tp).getTypeAt(suffix)
)
or
// When the path refers to a trait, then the implicit `Self` type parameter
// should be instantiated from the context.
exists(TypePath suffix |
result = this.getSelfTraitBoundArg().resolveTypeAt(suffix) and
result = this.getSelfTraitBoundArg().getTypeAt(suffix) and
typePath = TypePath::cons(TSelfTypeParameter(resolved), suffix)
)
or
not this.getSegment().hasTraitTypeRepr() and
result = this.getSegment().getTypeRepr().(TypeMention).resolveTypeAt(typePath)
result = this.getSegment().getTypeRepr().(TypeMention).getTypeAt(typePath)
}
}
pragma[nomagic]
Type resolveImplSelfTypeAt(Impl i, TypePath path) {
result = i.getSelfTy().(TypeMention).resolveTypeAt(path)
result = i.getSelfTy().(TypeMention).getTypeAt(path)
}
class ImplSelfMention extends PathTypeMention {
@@ -354,11 +354,11 @@ class PathTypeReprMention extends TypeMention, PathTypeRepr {
PathTypeReprMention() { path = this.getPath() }
override Type resolveTypeAt(TypePath typePath) { result = path.resolveTypeAt(typePath) }
override Type getTypeAt(TypePath typePath) { result = path.getTypeAt(typePath) }
}
class ImplTraitTypeReprMention extends TypeMention instanceof ImplTraitTypeRepr {
override Type resolveTypeAt(TypePath typePath) {
override Type getTypeAt(TypePath typePath) {
typePath.isEmpty() and
result.(ImplTraitType).getImplTraitTypeRepr() = this
or
@@ -377,14 +377,14 @@ private TypeParameter pathGetTypeParameter(TypeAlias alias, int i) {
// Used to represent implicit `Self` type arguments in traits and `impl` blocks,
// see `PathMention` for details.
class TypeParamMention extends TypeMention instanceof TypeParam {
override Type resolveTypeAt(TypePath typePath) {
override Type getTypeAt(TypePath typePath) {
typePath.isEmpty() and
result = TTypeParamTypeParameter(this)
}
}
class TraitMention extends TypeMention instanceof TraitItemNode {
override Type resolveTypeAt(TypePath typePath) {
override Type getTypeAt(TypePath typePath) {
typePath.isEmpty() and
result = TTrait(this)
or
@@ -417,7 +417,7 @@ class SelfTypeParameterMention extends TypeMention instanceof Name {
Trait getTrait() { result = trait }
override Type resolveTypeAt(TypePath typePath) {
override Type getTypeAt(TypePath typePath) {
typePath.isEmpty() and
result = TSelfTypeParameter(trait)
}
@@ -467,7 +467,7 @@ class ShorthandSelfParameterMention extends TypeMention instanceof SelfParam {
if super.isMut() then result instanceof RefMutType else result instanceof RefSharedType
}
override Type resolveTypeAt(TypePath typePath) {
override Type getTypeAt(TypePath typePath) {
// `fn f(&self, ...)`
typePath.isEmpty() and
result = this.resolveSelfRefRootType()
@@ -505,7 +505,7 @@ class ShorthandReturnTypeMention extends TypeMention instanceof Name {
not f.getRetType().hasTypeRepr()
}
override Type resolveTypeAt(TypePath typePath) {
override Type getTypeAt(TypePath typePath) {
typePath.isEmpty() and
result instanceof UnitType
}
@@ -527,14 +527,14 @@ class DynTraitTypeReprMention extends TypeMention instanceof DynTraitTypeRepr {
dynType.getTrait() = super.getTrait()
}
override Type resolveTypeAt(TypePath path) {
override Type getTypeAt(TypePath path) {
path.isEmpty() and
result = dynType
or
exists(DynTraitTypeParameter tp, TypePath path0, TypePath suffix |
dynType = tp.getDynTraitType() and
path = TypePath::cons(tp, suffix) and
result = super.getTypeBoundList().getBound(0).getTypeRepr().(TypeMention).resolveTypeAt(path0) and
result = super.getTypeBoundList().getBound(0).getTypeRepr().(TypeMention).getTypeAt(path0) and
path0.isCons(tp.getTraitTypeParameter(), suffix)
)
}
@@ -574,7 +574,7 @@ class DynTypeBoundListMention extends TypeMention instanceof TypeBoundList {
)
}
override Type resolveTypeAt(TypePath path) {
override Type getTypeAt(TypePath path) {
path.isEmpty() and
result.(DynTraitType).getTrait() = trait
or
@@ -587,7 +587,7 @@ class DynTypeBoundListMention extends TypeMention instanceof TypeBoundList {
}
class NeverTypeReprMention extends TypeMention, NeverTypeRepr {
override Type resolveTypeAt(TypePath path) { result = TNeverType() and path.isEmpty() }
override Type getTypeAt(TypePath path) { result = TNeverType() and path.isEmpty() }
}
class PtrTypeReprMention extends TypeMention instanceof PtrTypeRepr {
@@ -597,11 +597,11 @@ class PtrTypeReprMention extends TypeMention instanceof PtrTypeRepr {
super.isMut() and result instanceof PtrMutType
}
override Type resolveTypeAt(TypePath path) {
override Type getTypeAt(TypePath path) {
path.isEmpty() and result = this.resolveRootType()
or
exists(TypePath suffix |
result = super.getTypeRepr().(TypeMention).resolveTypeAt(suffix) and
result = super.getTypeRepr().(TypeMention).getTypeAt(suffix) and
path = TypePath::cons(this.resolveRootType().getPositionalTypeParameter(0), suffix)
)
}

View File

@@ -281,43 +281,36 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
/** Gets the type at `path` in the type tree. */
Type getTypeAt(TypePath path);
/** Gets a textual representation of this type. */
/** Gets a textual representation of this type tree. */
string toString();
/** Gets the location of this type. */
/** Gets the location of this type tree. */
Location getLocation();
}
/** Provides the input to `Make2`. */
signature module InputSig2 {
/** A type mention, for example a type annotation in a local variable declaration. */
class TypeMention {
/**
* Gets the type being mentioned at `path` inside this type mention.
*
* For example, in
*
* ```csharp
* C<int> x = ...
* ```
*
* the type mention in the declaration of `x` resolves to the following
* types:
*
* `TypePath` | `Type`
* ---------- | -------
* `""` | ``C`1``
* `"0"` | `int`
*/
Type resolveTypeAt(TypePath path);
/** Gets a textual representation of this type mention. */
string toString();
/** Gets the location of this type mention. */
Location getLocation();
}
/**
* Provides the input to `Make2`.
*
* The `TypeMention` parameter is used to build the base type hierarchy based on
* `getABaseTypeMention` and to construct the constraint satisfaction
* hierarchy based on `conditionSatisfiesConstraint`.
*
* It will usually be based on syntactic occurrences of types in the source
* code. For example, in
*
* ```csharp
* class C<T> : Base<T>, Interface { }
* ```
*
* a type mention would exist for `Base<T>` and resolve to the following
* types:
*
* `TypePath` | `Type`
* ---------- | -------
* `""` | ``Base`1``
* `"0"` | `T`
*/
signature module InputSig2<HasTypeTreeSig TypeMention> {
/**
* Gets a base type mention of `t`, if any. Example:
*
@@ -394,22 +387,13 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
);
}
module Make2<InputSig2 Input2> {
module Make2<HasTypeTreeSig TypeMention, InputSig2<TypeMention> Input2> {
private import Input2
final private class FinalTypeMention = TypeMention;
/** An adapter for type mentions to implement `HasTypeTreeSig`. */
final class TypeMentionTypeTree extends FinalTypeMention {
Type getTypeAt(TypePath path) { result = this.resolveTypeAt(path) }
}
/** Gets the type at the empty path of `tm`. */
bindingset[tm]
pragma[inline_late]
private Type resolveTypeMentionRoot(TypeMention tm) {
result = tm.resolveTypeAt(TypePath::nil())
}
private Type getTypeMentionRoot(TypeMention tm) { result = tm.getTypeAt(TypePath::nil()) }
/** Provides the input to `IsInstantiationOf`. */
signature module IsInstantiationOfInputSig<HasTypeTreeSig App, HasTypeTreeSig Constraint> {
@@ -467,17 +451,17 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
}
pragma[nomagic]
private Type resolveTypeAt(App app, TypeAbstraction abs, Constraint constraint, TypePath path) {
private Type getTypeAt(App app, TypeAbstraction abs, Constraint constraint, TypePath path) {
potentialInstantiationOf(app, abs, constraint) and
result = constraint.getTypeAt(path)
}
pragma[nomagic]
private Type resolveNthTypeAt(
private Type getNthTypeAt(
App app, TypeAbstraction abs, Constraint constraint, int i, TypePath path
) {
path = getNthPath(constraint, i) and
result = resolveTypeAt(app, abs, constraint, path)
result = getTypeAt(app, abs, constraint, path)
}
pragma[nomagic]
@@ -485,7 +469,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
App app, TypeAbstraction abs, Constraint constraint, int i
) {
exists(Type t, TypePath path |
t = resolveNthTypeAt(app, abs, constraint, i, path) and
t = getNthTypeAt(app, abs, constraint, i, path) and
if t = abs.getATypeParameter() then any() else app.getTypeAt(path) = t
) and
// Recurse unless we are at the first path
@@ -622,7 +606,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
) {
// `app` and `constraint` differ on a concrete type
exists(Type t, Type t2 |
t = resolveTypeAt(app, abs, constraint, path) and
t = getTypeAt(app, abs, constraint, path) and
not t = abs.getATypeParameter() and
app.getTypeAt(path) = t2 and
t2 != t
@@ -645,29 +629,27 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
TypeMention tm1, TypeMention tm2, TypeParameter tp, TypePath path, Type t
) {
exists(TypePath prefix |
tm2.resolveTypeAt(prefix) = tp and t = tm1.resolveTypeAt(prefix.appendInverse(path))
tm2.getTypeAt(prefix) = tp and t = tm1.getTypeAt(prefix.appendInverse(path))
)
}
private module IsInstantiationOfInput implements
IsInstantiationOfInputSig<TypeMentionTypeTree, TypeMentionTypeTree>
IsInstantiationOfInputSig<TypeMention, TypeMention>
{
pragma[nomagic]
private predicate typeCondition(
Type type, TypeAbstraction abs, TypeMentionTypeTree condition
) {
private predicate typeCondition(Type type, TypeAbstraction abs, TypeMention condition) {
conditionSatisfiesConstraint(abs, condition, _, _) and
type = resolveTypeMentionRoot(condition)
type = getTypeMentionRoot(condition)
}
pragma[nomagic]
private predicate typeConstraint(Type type, TypeMentionTypeTree constraint) {
private predicate typeConstraint(Type type, TypeMention constraint) {
conditionSatisfiesConstraint(_, _, constraint, _) and
type = resolveTypeMentionRoot(constraint)
type = getTypeMentionRoot(constraint)
}
predicate potentialInstantiationOf(
TypeMentionTypeTree constraint, TypeAbstraction abs, TypeMentionTypeTree condition
TypeMention constraint, TypeAbstraction abs, TypeMention condition
) {
exists(Type type |
typeConstraint(type, constraint) and typeCondition(type, abs, condition)
@@ -684,14 +666,14 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
) {
// base case
conditionSatisfiesConstraint(abs, condition, constraint, _) and
constraint.resolveTypeAt(path) = t
constraint.getTypeAt(path) = t
or
// recursive case
exists(TypeAbstraction midAbs, TypeMention midConstraint, TypeMention midCondition |
conditionSatisfiesConstraint(abs, condition, midConstraint, true) and
// NOTE: `midAbs` describe the free type variables in `midCondition`, hence
// we use that for instantiation check.
IsInstantiationOf<TypeMentionTypeTree, TypeMentionTypeTree, IsInstantiationOfInput>::isInstantiationOf(midConstraint,
IsInstantiationOf<TypeMention, TypeMention, IsInstantiationOfInput>::isInstantiationOf(midConstraint,
midAbs, midCondition)
|
conditionSatisfiesConstraintTypeAt(midAbs, midCondition, constraint, path, t) and
@@ -716,8 +698,8 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
TypeMention constraint
) {
conditionSatisfiesConstraintTypeAt(abs, condition, constraint, _, _) and
conditionRoot = resolveTypeMentionRoot(condition) and
constraintRoot = resolveTypeMentionRoot(constraint)
conditionRoot = getTypeMentionRoot(condition) and
constraintRoot = getTypeMentionRoot(constraint)
}
/**
@@ -778,10 +760,10 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
|
// immediate base class
baseMention = immediateBaseMention and
t = immediateBaseMention.resolveTypeAt(path)
t = immediateBaseMention.getTypeAt(path)
or
// transitive base class
exists(Type immediateBase | immediateBase = resolveTypeMentionRoot(immediateBaseMention) |
exists(Type immediateBase | immediateBase = getTypeMentionRoot(immediateBaseMention) |
baseTypeMentionHasNonTypeParameterAt(immediateBase, baseMention, path, t)
or
exists(TypePath path0, TypePath prefix, TypePath suffix, TypeParameter tp |
@@ -811,7 +793,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
*/
baseTypeMentionHasTypeParameterAt(immediateBase, baseMention, prefix, tp) and
t = immediateBaseMention.resolveTypeAt(path0) and
t = immediateBaseMention.getTypeAt(path0) and
path0.isCons(tp, suffix) and
path = prefix.append(suffix)
)
@@ -862,11 +844,9 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
}
private module IsInstantiationOfInput implements
IsInstantiationOfInputSig<HasTypeTree, TypeMentionTypeTree>
IsInstantiationOfInputSig<HasTypeTree, TypeMention>
{
predicate potentialInstantiationOf(
HasTypeTree tt, TypeAbstraction abs, TypeMentionTypeTree cond
) {
predicate potentialInstantiationOf(HasTypeTree tt, TypeAbstraction abs, TypeMention cond) {
exists(Type constraint, Type type |
hasTypeConstraint(tt, type, constraint) and
rootTypesSatisfaction(type, constraint, abs, cond, _) and
@@ -875,13 +855,13 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
)
}
predicate relevantConstraint(TypeMentionTypeTree constraint) {
predicate relevantConstraint(TypeMention constraint) {
rootTypesSatisfaction(_, _, _, constraint, _)
}
}
private module SatisfiesConstraintIsInstantiationOf =
IsInstantiationOf<HasTypeTree, TypeMentionTypeTree, IsInstantiationOfInput>;
IsInstantiationOf<HasTypeTree, TypeMention, IsInstantiationOfInput>;
/**
* Holds if `tt` satisfies `constraint` through `abs`, `sub`, and `constraintMention`.
@@ -897,8 +877,8 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
//
// not exists(countConstraintImplementations(type, constraint)) and
// conditionSatisfiesConstraintTypeAt(abs, condition, constraintMention, _, _) and
// resolveTypeMentionRoot(condition) = abs.getATypeParameter() and
// constraint = resolveTypeMentionRoot(constraintMention)
// getTypeMentionRoot(condition) = abs.getATypeParameter() and
// constraint = getTypeMentionRoot(constraintMention)
// or
countConstraintImplementations(type, constraint) > 0 and
rootTypesSatisfaction(type, constraint, abs, condition, constraintMention) and
@@ -935,9 +915,9 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
// or
// forall(TypeAbstraction abs, TypeMention condition, TypeMention constraintMention |
// conditionSatisfiesConstraintTypeAt(abs, condition, constraintMention, _, _) and
// resolveTypeMentionRoot(condition) = abs.getATypeParameter()
// getTypeMentionRoot(condition) = abs.getATypeParameter()
// |
// not constraint = resolveTypeMentionRoot(constraintMention)
// not constraint = getTypeMentionRoot(constraintMention)
// )
// ) and
(
@@ -973,7 +953,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
exists(TypeMention sub, TypeParameter tp |
satisfiesConstraintTypeMention0(tt, constraint, abs, sub, path, tp) and
tp = abs.getATypeParameter() and
sub.resolveTypeAt(pathToTypeParamInSub) = tp
sub.getTypeAt(pathToTypeParamInSub) = tp
)
}
@@ -1265,7 +1245,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
Access a, AccessEnvironment e, AccessPosition apos, TypeMention baseMention,
TypePath path, Type t
) {
relevantAccess(a, e, apos, resolveTypeMentionRoot(baseMention)) and
relevantAccess(a, e, apos, getTypeMentionRoot(baseMention)) and
exists(Type sub | sub = a.getInferredType(e, apos, TypePath::nil()) |
baseTypeMentionHasNonTypeParameterAt(sub, baseMention, path, t)
or
@@ -1351,7 +1331,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
) {
exists(TypeMention tm |
AccessBaseType::hasBaseTypeMention(a, e, apos, tm, path, t) and
base = resolveTypeMentionRoot(tm)
base = getTypeMentionRoot(tm)
)
}
@@ -1680,7 +1660,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
}
query predicate illFormedTypeMention(TypeMention tm) {
not exists(tm.resolveTypeAt(TypePath::nil())) and exists(tm.getLocation())
not exists(tm.getTypeAt(TypePath::nil())) and exists(tm.getLocation())
}
}
}