Skip to content

Commit f9ff92a

Browse files
committed
Rust: Expand on type inference tests for associated types
1 parent 04d37c3 commit f9ff92a

File tree

2 files changed

+677
-543
lines changed

2 files changed

+677
-543
lines changed

rust/ql/test/library-tests/type-inference/main.rs

+86-6
Original file line numberDiff line numberDiff line change
@@ -329,38 +329,118 @@ mod function_trait_bounds {
329329
}
330330

331331
mod trait_associated_type {
332+
#[derive(Debug)]
333+
struct Wrapper<A> {
334+
field: A,
335+
}
336+
337+
impl<A> Wrapper<A> {
338+
fn unwrap(self) -> A {
339+
self.field // $ fieldof=Wrapper
340+
}
341+
}
342+
332343
trait MyTrait {
333344
type AssociatedType;
334345

346+
// MyTrait::m1
335347
fn m1(self) -> Self::AssociatedType;
336348

337349
fn m2(self) -> Self::AssociatedType
338350
where
339351
Self::AssociatedType: Default,
340352
Self: Sized,
341353
{
354+
self.m1(); // $ method=MyTrait::m1
342355
Self::AssociatedType::default()
343356
}
344357
}
345358

359+
trait MyTraitAssoc2 {
360+
type GenericAssociatedType<AssociatedParam>;
361+
362+
// MyTrait::put
363+
fn put<A>(&self, a: A) -> Self::GenericAssociatedType<A>;
364+
365+
fn putTwo<A>(&self, a: A, b: A) -> Self::GenericAssociatedType<A> {
366+
self.put(a); // $ method=MyTrait::put
367+
self.put(b) // $ method=MyTrait::put
368+
}
369+
}
370+
346371
#[derive(Debug, Default)]
347372
struct S;
348373

374+
#[derive(Debug, Default)]
375+
struct S2;
376+
377+
#[derive(Debug, Default)]
378+
struct AT;
379+
349380
impl MyTrait for S {
350-
type AssociatedType = S;
381+
type AssociatedType = AT;
351382

352383
// S::m1
353384
fn m1(self) -> Self::AssociatedType {
354-
S
385+
AT
386+
}
387+
}
388+
389+
impl MyTraitAssoc2 for S {
390+
// Associated type with a type parameter
391+
type GenericAssociatedType<AssociatedParam> = Wrapper<AssociatedParam>;
392+
393+
// S::put
394+
fn put<A>(&self, a: A) -> Wrapper<A> {
395+
Wrapper { field: a }
396+
}
397+
}
398+
399+
impl MyTrait for S2 {
400+
// Associated type definition with a type argument
401+
type AssociatedType = Wrapper<S2>;
402+
403+
fn m1(self) -> Self::AssociatedType {
404+
Wrapper { field: self }
405+
}
406+
}
407+
408+
// NOTE: This implementation is just to make it possible to call `m2` on `S2.`
409+
impl Default for Wrapper<S2> {
410+
fn default() -> Self {
411+
Wrapper { field: S2 }
355412
}
356413
}
357414

415+
// Function that returns an associated type from a trait bound
416+
fn g<T: MyTrait>(thing: T) -> <T as MyTrait>::AssociatedType {
417+
thing.m1() // $ method=MyTrait::m1
418+
}
419+
358420
pub fn f() {
359-
let x = S;
360-
println!("{:?}", x.m1()); // $ method=S::m1
421+
let x1 = S;
422+
// Call to method in `impl` block
423+
println!("{:?}", x1.m1()); // $ method=S::m1 type=x1.m1():AT
361424

362-
let x = S;
363-
println!("{:?}", x.m2()); // $ method=m2
425+
let x2 = S;
426+
// Call to default method in `trait` block
427+
let y = x2.m2(); // $ method=m2 MISSING: type=y:AT
428+
println!("{:?}", y);
429+
430+
let x3 = S;
431+
// Call to the method in `impl` block
432+
println!("{:?}", x3.put(1).unwrap()); // $ method=S::put method=unwrap
433+
434+
// Call to default implementation in `trait` block
435+
println!("{:?}", x3.putTwo(2, 3).unwrap()); // $ method=putTwo MISSING: method=unwrap
436+
437+
let x4 = g(S); // $ MISSING: type=x4:AT
438+
println!("{:?}", x4);
439+
440+
let x5 = S2;
441+
println!("{:?}", x5.m1()); // $ method=m1 MISSING: type=x5.m1():A.S2
442+
let x6 = S2;
443+
println!("{:?}", x6.m2()); // $ method=m2 MISSING: type=x6.m2():A.S2
364444
}
365445
}
366446

0 commit comments

Comments
 (0)