mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #19927 from hvitved/rust/type-inference-overlap3
Rust: Disambiguate more method calls based on argument types
This commit is contained in:
@@ -1220,9 +1220,17 @@ private Function getTypeParameterMethod(TypeParameter tp, string name) {
|
|||||||
result = getMethodSuccessor(tp.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr(), name)
|
result = getMethodSuccessor(tp.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr(), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private Type resolveNonTypeParameterTypeAt(TypeMention tm, TypePath path) {
|
||||||
|
result = tm.resolveTypeAt(path) and
|
||||||
|
not result instanceof TypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
bindingset[t1, t2]
|
bindingset[t1, t2]
|
||||||
private predicate typeMentionEqual(TypeMention t1, TypeMention t2) {
|
private predicate typeMentionEqual(TypeMention t1, TypeMention t2) {
|
||||||
forex(TypePath path, Type type | t1.resolveTypeAt(path) = type | t2.resolveTypeAt(path) = type)
|
forex(TypePath path, Type type | resolveNonTypeParameterTypeAt(t1, path) = type |
|
||||||
|
resolveNonTypeParameterTypeAt(t2, path) = type
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
multipleCallTargets
|
multipleCallTargets
|
||||||
| dereference.rs:61:15:61:24 | e1.deref() |
|
| dereference.rs:61:15:61:24 | e1.deref() |
|
||||||
| main.rs:2032:13:2032:31 | ...::from(...) |
|
| main.rs:2076:13:2076:31 | ...::from(...) |
|
||||||
| main.rs:2033:13:2033:31 | ...::from(...) |
|
| main.rs:2077:13:2077:31 | ...::from(...) |
|
||||||
| main.rs:2034:13:2034:31 | ...::from(...) |
|
| main.rs:2078:13:2078:31 | ...::from(...) |
|
||||||
| main.rs:2040:13:2040:31 | ...::from(...) |
|
| main.rs:2084:13:2084:31 | ...::from(...) |
|
||||||
| main.rs:2041:13:2041:31 | ...::from(...) |
|
| main.rs:2085:13:2085:31 | ...::from(...) |
|
||||||
| main.rs:2042:13:2042:31 | ...::from(...) |
|
| main.rs:2086:13:2086:31 | ...::from(...) |
|
||||||
| main.rs:2078:21:2078:43 | ...::from(...) |
|
| main.rs:2122:21:2122:43 | ...::from(...) |
|
||||||
|
|||||||
@@ -937,7 +937,6 @@ mod method_supertraits {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod function_trait_bounds_2 {
|
mod function_trait_bounds_2 {
|
||||||
use std::convert::From;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -1957,36 +1956,81 @@ mod macros {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod method_determined_by_argument_type {
|
mod method_determined_by_argument_type {
|
||||||
trait MyAdd<T> {
|
trait MyAdd<Rhs = Self> {
|
||||||
fn my_add(&self, value: T) -> Self;
|
type Output;
|
||||||
|
|
||||||
|
// MyAdd::my_add
|
||||||
|
fn my_add(self, rhs: Rhs) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MyAdd<i64> for i64 {
|
impl MyAdd<i64> for i64 {
|
||||||
|
type Output = i64;
|
||||||
|
|
||||||
// MyAdd<i64>::my_add
|
// MyAdd<i64>::my_add
|
||||||
fn my_add(&self, value: i64) -> Self {
|
fn my_add(self, value: i64) -> Self {
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MyAdd<&i64> for i64 {
|
impl MyAdd<&i64> for i64 {
|
||||||
|
type Output = i64;
|
||||||
|
|
||||||
// MyAdd<&i64>::my_add
|
// MyAdd<&i64>::my_add
|
||||||
fn my_add(&self, value: &i64) -> Self {
|
fn my_add(self, value: &i64) -> Self {
|
||||||
*value // $ method=deref
|
*value // $ method=deref
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MyAdd<bool> for i64 {
|
impl MyAdd<bool> for i64 {
|
||||||
|
type Output = i64;
|
||||||
|
|
||||||
// MyAdd<bool>::my_add
|
// MyAdd<bool>::my_add
|
||||||
fn my_add(&self, value: bool) -> Self {
|
fn my_add(self, value: bool) -> Self {
|
||||||
if value { 1 } else { 0 }
|
if value { 1 } else { 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct S<T>(T);
|
||||||
|
|
||||||
|
impl<T: MyAdd> MyAdd for S<T> {
|
||||||
|
type Output = S<T::Output>;
|
||||||
|
|
||||||
|
// S::my_add1
|
||||||
|
fn my_add(self, other: Self) -> Self::Output {
|
||||||
|
S((self.0).my_add(other.0)) // $ method=MyAdd::my_add $ fieldof=S
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: MyAdd> MyAdd<T> for S<T> {
|
||||||
|
type Output = S<T::Output>;
|
||||||
|
|
||||||
|
// S::my_add2
|
||||||
|
fn my_add(self, other: T) -> Self::Output {
|
||||||
|
S((self.0).my_add(other)) // $ method=MyAdd::my_add $ fieldof=S
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> MyAdd<&'a T> for S<T>
|
||||||
|
where
|
||||||
|
T: MyAdd<&'a T>,
|
||||||
|
{
|
||||||
|
type Output = S<<T as MyAdd<&'a T>>::Output>;
|
||||||
|
|
||||||
|
// S::my_add3
|
||||||
|
fn my_add(self, other: &'a T) -> Self::Output {
|
||||||
|
S((self.0).my_add(other)) // $ method=MyAdd::my_add $ fieldof=S
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn f() {
|
pub fn f() {
|
||||||
let x: i64 = 73;
|
let x: i64 = 73;
|
||||||
x.my_add(5i64); // $ method=MyAdd<i64>::my_add
|
x.my_add(5i64); // $ method=MyAdd<i64>::my_add
|
||||||
x.my_add(&5i64); // $ method=MyAdd<&i64>::my_add
|
x.my_add(&5i64); // $ method=MyAdd<&i64>::my_add
|
||||||
x.my_add(true); // $ method=MyAdd<bool>::my_add
|
x.my_add(true); // $ method=MyAdd<bool>::my_add
|
||||||
|
|
||||||
|
S(1i64).my_add(S(2i64)); // $ method=S::my_add1
|
||||||
|
S(1i64).my_add(3i64); // $ MISSING: method=S::my_add2
|
||||||
|
S(1i64).my_add(&3i64); // $ method=S::my_add3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user