mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Rust: Improve handling of occurrences of the Self type parameter
This commit is contained in:
@@ -151,25 +151,61 @@ class NonAliasPathTypeMention extends PathTypeMention {
|
||||
result = this.getQualifier().getSegment().getGenericArgList().getTypeArg(i)
|
||||
}
|
||||
|
||||
private TypeMention getPositionalTypeArgument(int i) {
|
||||
result = this.getPositionalTypeArgument0(i)
|
||||
/**
|
||||
* Gets the type mention that instantiates the implicit `Self` type parameter
|
||||
* for this path, if it occurs in the position of a trait bound.
|
||||
*/
|
||||
private TypeMention getSelfTypeParameter() {
|
||||
exists(ImplItemNode impl | this = impl.getTraitPath() and result = impl.(Impl).getSelfTy())
|
||||
or
|
||||
exists(Trait subTrait |
|
||||
this = subTrait.getATypeBound().getTypeRepr().(PathTypeRepr).getPath() and
|
||||
result.(SelfTypeParameterMention).getTrait() = subTrait
|
||||
)
|
||||
or
|
||||
exists(TypeParamItemNode tp | this = tp.getABoundPath() and result = tp)
|
||||
}
|
||||
|
||||
private Type getPositionalTypeArgument(int i, TypePath path) {
|
||||
result = this.getPositionalTypeArgument0(i).resolveTypeAt(path)
|
||||
or
|
||||
result = this.getDefaultPositionalTypeArgument(i, path)
|
||||
}
|
||||
|
||||
private Type getDefaultPositionalTypeArgument(int i, TypePath path) {
|
||||
// If a type argument is not given in the path, then we use the default for
|
||||
// the type parameter if one exists for the type.
|
||||
not exists(this.getPositionalTypeArgument0(i)) and
|
||||
result = this.resolveRootType().getTypeParameterDefault(i) and
|
||||
// Defaults only apply to type mentions in type annotations
|
||||
this = any(PathTypeRepr ptp).getPath().getQualifier*()
|
||||
this = any(PathTypeRepr ptp).getPath().getQualifier*() and
|
||||
exists(Type ty, TypePath prefix |
|
||||
ty = this.resolveRootType().getTypeParameterDefault(i).resolveTypeAt(prefix) and
|
||||
if not ty = TSelfTypeParameter(resolved)
|
||||
then result = ty and path = prefix
|
||||
else
|
||||
// When a default contains an implicit `Self` type parameter, it should
|
||||
// be substituted for the type that implements the trait.
|
||||
exists(TypePath suffix |
|
||||
path = prefix.append(suffix) and
|
||||
result = this.getSelfTypeParameter().resolveTypeAt(suffix)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type for this path for the type parameter `tp` at `path`, when the
|
||||
* type parameter does not correspond directly to a type mention.
|
||||
*/
|
||||
private Type getTypeForTypeParameterAt(TypeParameter tp, TypePath path) {
|
||||
exists(int i |
|
||||
result = this.getPositionalTypeArgument(pragma[only_bind_into](i), path) and
|
||||
tp = this.resolveRootType().getPositionalTypeParameter(pragma[only_bind_into](i))
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the type mention in this path for the type parameter `tp`, if any. */
|
||||
pragma[nomagic]
|
||||
private TypeMention getTypeMentionForTypeParameter(TypeParameter tp) {
|
||||
exists(int i |
|
||||
result = this.getPositionalTypeArgument(pragma[only_bind_into](i)) and
|
||||
tp = this.resolveRootType().getPositionalTypeParameter(pragma[only_bind_into](i))
|
||||
)
|
||||
or
|
||||
exists(TypeAlias alias |
|
||||
result = this.getAnAssocTypeArgument(alias) and
|
||||
tp = TAssociatedTypeTypeParameter(alias)
|
||||
@@ -237,9 +273,17 @@ class NonAliasPathTypeMention extends PathTypeMention {
|
||||
typePath.isEmpty() and
|
||||
result = this.resolveRootType()
|
||||
or
|
||||
exists(TypeParameter tp, TypePath suffix |
|
||||
result = this.getTypeMentionForTypeParameter(tp).resolveTypeAt(suffix) and
|
||||
typePath = TypePath::cons(tp, suffix)
|
||||
exists(TypeParameter tp, TypePath suffix | typePath = TypePath::cons(tp, suffix) |
|
||||
result = this.getTypeForTypeParameterAt(tp, suffix)
|
||||
or
|
||||
result = this.getTypeMentionForTypeParameter(tp).resolveTypeAt(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.getSelfTypeParameter().resolveTypeAt(suffix) and
|
||||
typePath = TypePath::cons(TSelfTypeParameter(resolved), suffix)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -296,6 +340,11 @@ class TraitMention extends TypeMention instanceof TraitItemNode {
|
||||
typePath.isEmpty() and
|
||||
result = TTrait(this)
|
||||
or
|
||||
// The implicit `Self` type parameter occurs at the `Self` type parameter
|
||||
// position.
|
||||
typePath = TypePath::singleton(TSelfTypeParameter(this)) and
|
||||
result = TSelfTypeParameter(this)
|
||||
or
|
||||
exists(TypeAlias alias |
|
||||
alias = super.getAnAssocItem() and
|
||||
typePath = TypePath::singleton(result) and
|
||||
|
||||
@@ -666,7 +666,7 @@ mod trait_default_self_type_parameter {
|
||||
|
||||
// The trait bound on `T` uses the default for `A` which contains `Self`
|
||||
fn tp_uses_default<S: TraitWithSelfTp>(thing: S) -> i64 {
|
||||
let _ms = thing.get_a(); // $ target=TraitWithSelfTp::get_a MISSING: type=_ms:T.S
|
||||
let _ms = thing.get_a(); // $ target=TraitWithSelfTp::get_a type=_ms:T.S
|
||||
0
|
||||
}
|
||||
|
||||
@@ -675,7 +675,7 @@ mod trait_default_self_type_parameter {
|
||||
|
||||
fn get_a_through_tp<S: SubTraitOfTraitWithSelfTp>(thing: &S) {
|
||||
// `thing` is a `TraitWithSelfTp` through the trait hierarchy
|
||||
let _ms = get_a(thing); // $ target=get_a MISSING: type=_ms:T.S
|
||||
let _ms = get_a(thing); // $ target=get_a type=_ms:T.S
|
||||
}
|
||||
|
||||
struct MyStruct {
|
||||
@@ -693,7 +693,7 @@ mod trait_default_self_type_parameter {
|
||||
|
||||
pub fn test() {
|
||||
let s = MyStruct { value: 0 };
|
||||
let _ms = get_a(&s); // $ target=get_a MISSING: type=_ms:T.MyStruct
|
||||
let _ms = get_a(&s); // $ target=get_a type=_ms:T.MyStruct
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2013,18 +2013,18 @@ inferType
|
||||
| main.rs:668:44:668:48 | thing | | main.rs:668:24:668:41 | S |
|
||||
| main.rs:668:61:671:5 | { ... } | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:669:13:669:15 | _ms | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:669:13:669:15 | _ms | T | main.rs:656:5:661:5 | Self [trait TraitWithSelfTp] |
|
||||
| main.rs:669:13:669:15 | _ms | T | main.rs:668:24:668:41 | S |
|
||||
| main.rs:669:19:669:23 | thing | | main.rs:668:24:668:41 | S |
|
||||
| main.rs:669:19:669:31 | thing.get_a() | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:669:19:669:31 | thing.get_a() | T | main.rs:656:5:661:5 | Self [trait TraitWithSelfTp] |
|
||||
| main.rs:669:19:669:31 | thing.get_a() | T | main.rs:668:24:668:41 | S |
|
||||
| main.rs:670:9:670:9 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:670:9:670:9 | 0 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:676:55:676:59 | thing | | file://:0:0:0:0 | & |
|
||||
| main.rs:676:55:676:59 | thing | &T | main.rs:676:25:676:52 | S |
|
||||
| main.rs:678:13:678:15 | _ms | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:678:13:678:15 | _ms | T | main.rs:656:5:661:5 | Self [trait TraitWithSelfTp] |
|
||||
| main.rs:678:13:678:15 | _ms | T | main.rs:676:25:676:52 | S |
|
||||
| main.rs:678:19:678:30 | get_a(...) | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:678:19:678:30 | get_a(...) | T | main.rs:656:5:661:5 | Self [trait TraitWithSelfTp] |
|
||||
| main.rs:678:19:678:30 | get_a(...) | T | main.rs:676:25:676:52 | S |
|
||||
| main.rs:678:25:678:29 | thing | | file://:0:0:0:0 | & |
|
||||
| main.rs:678:25:678:29 | thing | &T | main.rs:676:25:676:52 | S |
|
||||
| main.rs:687:18:687:22 | SelfParam | | file://:0:0:0:0 | & |
|
||||
@@ -2041,9 +2041,9 @@ inferType
|
||||
| main.rs:695:17:695:37 | MyStruct {...} | | main.rs:681:5:683:5 | MyStruct |
|
||||
| main.rs:695:35:695:35 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:696:13:696:15 | _ms | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:696:13:696:15 | _ms | T | main.rs:656:5:661:5 | Self [trait TraitWithSelfTp] |
|
||||
| main.rs:696:13:696:15 | _ms | T | main.rs:681:5:683:5 | MyStruct |
|
||||
| main.rs:696:19:696:27 | get_a(...) | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:696:19:696:27 | get_a(...) | T | main.rs:656:5:661:5 | Self [trait TraitWithSelfTp] |
|
||||
| main.rs:696:19:696:27 | get_a(...) | T | main.rs:681:5:683:5 | MyStruct |
|
||||
| main.rs:696:25:696:26 | &s | | file://:0:0:0:0 | & |
|
||||
| main.rs:696:25:696:26 | &s | &T | main.rs:681:5:683:5 | MyStruct |
|
||||
| main.rs:696:26:696:26 | s | | main.rs:681:5:683:5 | MyStruct |
|
||||
@@ -4776,7 +4776,6 @@ inferType
|
||||
| main.rs:2312:16:2312:21 | self.0 | | main.rs:2307:10:2307:17 | T |
|
||||
| main.rs:2312:31:2312:35 | other | | main.rs:2305:5:2305:19 | S |
|
||||
| main.rs:2312:31:2312:35 | other | T | main.rs:2307:10:2307:17 | T |
|
||||
| main.rs:2312:31:2312:37 | other.0 | | main.rs:2267:5:2272:5 | Self [trait MyAdd] |
|
||||
| main.rs:2312:31:2312:37 | other.0 | | main.rs:2307:10:2307:17 | T |
|
||||
| main.rs:2320:19:2320:22 | SelfParam | | main.rs:2305:5:2305:19 | S |
|
||||
| main.rs:2320:19:2320:22 | SelfParam | T | main.rs:2316:10:2316:17 | T |
|
||||
|
||||
Reference in New Issue
Block a user