Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 97 additions & 27 deletions rust/ql/test/library-tests/type-inference/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,69 @@
mod m1 {
mod field_access {
#[derive(Debug)]
struct S;

#[derive(Debug)]
struct MyThing {
a: S,
}

#[derive(Debug)]
enum MyOption<T> {
MyNone(),
MySome(T),
}

#[derive(Debug)]
struct GenericThing<A> {
a: A,
}

struct OptionS {
a: MyOption<S>,
}

fn simple_field_access() {
let x = MyThing { a: S };
println!("{:?}", x.a);
}

fn generic_field_access() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do all the expressions in this test have correctly inferred types (I didn't bother to check the .expected file)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so, yes :)

// Explicit type argument
let x = GenericThing::<S> { a: S };
println!("{:?}", x.a);

// Implicit type argument
let y = GenericThing { a: S };
println!("{:?}", x.a);

// The type of the field `a` can only be infered from the concrete type
// in the struct declaration.
let x = OptionS {
a: MyOption::MyNone(),
};
println!("{:?}", x.a);

// The type of the field `a` can only be infered from the type argument
let x = GenericThing::<MyOption<S>> {
a: MyOption::MyNone(),
};
println!("{:?}", x.a);

let mut x = GenericThing {
a: MyOption::MyNone(),
};
// Only after this access can we infer the type parameter of `x`
let a: MyOption<S> = x.a;
println!("{:?}", a);
}

pub fn f() {
simple_field_access();
generic_field_access();
}
}

mod method_impl {
pub struct Foo {}

impl Foo {
Expand All @@ -25,7 +90,7 @@ mod m1 {
}
}

mod m2 {
mod method_non_parametric_impl {
#[derive(Debug)]
struct MyThing<A> {
a: A,
Expand Down Expand Up @@ -58,6 +123,10 @@ mod m2 {
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };

// simple field access
println!("{:?}", x.a);
println!("{:?}", y.a);

println!("{:?}", x.m1()); // missing call target
println!("{:?}", y.m1().a); // missing call target

Expand All @@ -69,7 +138,7 @@ mod m2 {
}
}

mod m3 {
mod method_non_parametric_trait_impl {
#[derive(Debug)]
struct MyThing<A> {
a: A,
Expand Down Expand Up @@ -122,7 +191,7 @@ mod m3 {
}
}

mod m4 {
mod function_trait_bounds {
#[derive(Debug)]
struct MyThing<A> {
a: A,
Expand Down Expand Up @@ -175,7 +244,7 @@ mod m4 {
}
}

mod m5 {
mod trait_associated_type {
trait MyTrait {
type AssociatedType;

Expand Down Expand Up @@ -210,7 +279,7 @@ mod m5 {
}
}

mod m6 {
mod generic_enum {
#[derive(Debug)]
enum MyEnum<A> {
C1(A),
Expand Down Expand Up @@ -240,7 +309,7 @@ mod m6 {
}
}

mod m7 {
mod method_supertraits {
#[derive(Debug)]
struct MyThing<A> {
a: A,
Expand Down Expand Up @@ -325,7 +394,7 @@ mod m7 {
}
}

mod m8 {
mod function_trait_bounds_2 {
use std::convert::From;
use std::fmt::Debug;

Expand Down Expand Up @@ -374,7 +443,7 @@ mod m8 {
}
}

mod m9 {
mod option_methods {
#[derive(Debug)]
enum MyOption<T> {
MyNone(),
Expand Down Expand Up @@ -456,7 +525,7 @@ mod m9 {
}
}

mod m10 {
mod method_call_type_conversion {

#[derive(Debug, Copy, Clone)]
struct S<T>(T);
Expand Down Expand Up @@ -508,7 +577,7 @@ mod m10 {
}
}

mod m11 {
mod trait_implicit_self_borrow {
trait MyTrait {
fn foo(&self) -> &Self;

Expand All @@ -531,7 +600,7 @@ mod m11 {
}
}

mod m12 {
mod implicit_self_borrow {
struct S;

struct MyStruct<T>(T);
Expand All @@ -548,7 +617,7 @@ mod m12 {
}
}

mod m13 {
mod borrowed_typed {
struct S;

impl S {
Expand Down Expand Up @@ -578,18 +647,19 @@ mod m13 {
}

fn main() {
m1::f();
m1::g(m1::Foo {}, m1::Foo {});
m2::f();
m3::f();
m4::f();
m5::f();
m6::f();
m7::f();
m8::f();
m9::f();
m10::f();
m11::f();
m12::f();
m13::f();
field_access::f();
method_impl::f();
method_impl::g(method_impl::Foo {}, method_impl::Foo {});
method_non_parametric_impl::f();
method_non_parametric_trait_impl::f();
function_trait_bounds::f();
trait_associated_type::f();
generic_enum::f();
method_supertraits::f();
function_trait_bounds_2::f();
option_methods::f();
method_call_type_conversion::f();
trait_implicit_self_borrow::f();
implicit_self_borrow::f();
borrowed_typed::f();
}
Loading