From a4b7ed7a42c716ab9f05e351f003d589124fd55d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:58 +0200 Subject: Adding upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/traits/inheritance/auto-xc-2.rs | 23 ++++++ tests/ui/traits/inheritance/auto-xc.rs | 25 +++++++ tests/ui/traits/inheritance/auto.rs | 29 ++++++++ tests/ui/traits/inheritance/auxiliary/auto_xc.rs | 7 ++ tests/ui/traits/inheritance/auxiliary/auto_xc_2.rs | 9 +++ .../traits/inheritance/auxiliary/overloading_xc.rs | 38 ++++++++++ tests/ui/traits/inheritance/auxiliary/xc_call.rs | 11 +++ tests/ui/traits/inheritance/basic.rs | 26 +++++++ .../ui/traits/inheritance/call-bound-inherited.rs | 20 +++++ .../ui/traits/inheritance/call-bound-inherited2.rs | 23 ++++++ .../inheritance/cast-without-call-to-supertrait.rs | 33 +++++++++ tests/ui/traits/inheritance/cast.rs | 33 +++++++++ tests/ui/traits/inheritance/cross-trait-call-xc.rs | 20 +++++ tests/ui/traits/inheritance/cross-trait-call.rs | 19 +++++ tests/ui/traits/inheritance/diamond.rs | 28 +++++++ tests/ui/traits/inheritance/multiple-inheritors.rs | 23 ++++++ tests/ui/traits/inheritance/multiple-params.rs | 26 +++++++ tests/ui/traits/inheritance/num.rs | 13 ++++ tests/ui/traits/inheritance/num0.rs | 24 ++++++ tests/ui/traits/inheritance/num1.rs | 15 ++++ tests/ui/traits/inheritance/num2.rs | 86 ++++++++++++++++++++++ tests/ui/traits/inheritance/num3.rs | 19 +++++ tests/ui/traits/inheritance/num5.rs | 26 +++++++ tests/ui/traits/inheritance/overloading-simple.rs | 27 +++++++ tests/ui/traits/inheritance/overloading-xc-exe.rs | 20 +++++ tests/ui/traits/inheritance/overloading.rs | 47 ++++++++++++ .../inheritance/repeated-supertrait-ambig.rs | 43 +++++++++++ .../inheritance/repeated-supertrait-ambig.stderr | 65 ++++++++++++++++ tests/ui/traits/inheritance/repeated-supertrait.rs | 48 ++++++++++++ tests/ui/traits/inheritance/self-in-supertype.rs | 62 ++++++++++++++++ tests/ui/traits/inheritance/self.rs | 29 ++++++++ tests/ui/traits/inheritance/simple.rs | 24 ++++++ tests/ui/traits/inheritance/static.rs | 26 +++++++ tests/ui/traits/inheritance/static2.rs | 29 ++++++++ tests/ui/traits/inheritance/subst.rs | 27 +++++++ tests/ui/traits/inheritance/subst2.rs | 37 ++++++++++ tests/ui/traits/inheritance/visibility.rs | 20 +++++ 37 files changed, 1080 insertions(+) create mode 100644 tests/ui/traits/inheritance/auto-xc-2.rs create mode 100644 tests/ui/traits/inheritance/auto-xc.rs create mode 100644 tests/ui/traits/inheritance/auto.rs create mode 100644 tests/ui/traits/inheritance/auxiliary/auto_xc.rs create mode 100644 tests/ui/traits/inheritance/auxiliary/auto_xc_2.rs create mode 100644 tests/ui/traits/inheritance/auxiliary/overloading_xc.rs create mode 100644 tests/ui/traits/inheritance/auxiliary/xc_call.rs create mode 100644 tests/ui/traits/inheritance/basic.rs create mode 100644 tests/ui/traits/inheritance/call-bound-inherited.rs create mode 100644 tests/ui/traits/inheritance/call-bound-inherited2.rs create mode 100644 tests/ui/traits/inheritance/cast-without-call-to-supertrait.rs create mode 100644 tests/ui/traits/inheritance/cast.rs create mode 100644 tests/ui/traits/inheritance/cross-trait-call-xc.rs create mode 100644 tests/ui/traits/inheritance/cross-trait-call.rs create mode 100644 tests/ui/traits/inheritance/diamond.rs create mode 100644 tests/ui/traits/inheritance/multiple-inheritors.rs create mode 100644 tests/ui/traits/inheritance/multiple-params.rs create mode 100644 tests/ui/traits/inheritance/num.rs create mode 100644 tests/ui/traits/inheritance/num0.rs create mode 100644 tests/ui/traits/inheritance/num1.rs create mode 100644 tests/ui/traits/inheritance/num2.rs create mode 100644 tests/ui/traits/inheritance/num3.rs create mode 100644 tests/ui/traits/inheritance/num5.rs create mode 100644 tests/ui/traits/inheritance/overloading-simple.rs create mode 100644 tests/ui/traits/inheritance/overloading-xc-exe.rs create mode 100644 tests/ui/traits/inheritance/overloading.rs create mode 100644 tests/ui/traits/inheritance/repeated-supertrait-ambig.rs create mode 100644 tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr create mode 100644 tests/ui/traits/inheritance/repeated-supertrait.rs create mode 100644 tests/ui/traits/inheritance/self-in-supertype.rs create mode 100644 tests/ui/traits/inheritance/self.rs create mode 100644 tests/ui/traits/inheritance/simple.rs create mode 100644 tests/ui/traits/inheritance/static.rs create mode 100644 tests/ui/traits/inheritance/static2.rs create mode 100644 tests/ui/traits/inheritance/subst.rs create mode 100644 tests/ui/traits/inheritance/subst2.rs create mode 100644 tests/ui/traits/inheritance/visibility.rs (limited to 'tests/ui/traits/inheritance') diff --git a/tests/ui/traits/inheritance/auto-xc-2.rs b/tests/ui/traits/inheritance/auto-xc-2.rs new file mode 100644 index 000000000..f2130228d --- /dev/null +++ b/tests/ui/traits/inheritance/auto-xc-2.rs @@ -0,0 +1,23 @@ +// run-pass +// aux-build:auto_xc_2.rs + + +extern crate auto_xc_2 as aux; + +// aux defines impls of Foo, Bar and Baz for A +use aux::{Foo, Bar, Baz, A}; + +// We want to extend all Foo, Bar, Bazes to Quuxes +pub trait Quux: Foo + Bar + Baz { } +impl Quux for T { } + +fn f(a: &T) { + assert_eq!(a.f(), 10); + assert_eq!(a.g(), 20); + assert_eq!(a.h(), 30); +} + +pub fn main() { + let a = &A { x: 3 }; + f(a); +} diff --git a/tests/ui/traits/inheritance/auto-xc.rs b/tests/ui/traits/inheritance/auto-xc.rs new file mode 100644 index 000000000..3d5ae182a --- /dev/null +++ b/tests/ui/traits/inheritance/auto-xc.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +// aux-build:auto_xc.rs + + +extern crate auto_xc as aux; + +use aux::{Foo, Bar, Baz, Quux}; + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } + +fn f(a: &T) { + assert_eq!(a.f(), 10); + assert_eq!(a.g(), 20); + assert_eq!(a.h(), 30); +} + +pub fn main() { + let a = &A { x: 3 }; + f(a); +} diff --git a/tests/ui/traits/inheritance/auto.rs b/tests/ui/traits/inheritance/auto.rs new file mode 100644 index 000000000..0be67a55e --- /dev/null +++ b/tests/ui/traits/inheritance/auto.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +// Testing that this impl turns A into a Quux, because +// A is already a Foo Bar Baz + +impl Quux for T { } + +trait Foo { fn f(&self) -> isize; } +trait Bar { fn g(&self) -> isize; } +trait Baz { fn h(&self) -> isize; } + +trait Quux: Foo + Bar + Baz { } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } + +fn f(a: &T) { + assert_eq!(a.f(), 10); + assert_eq!(a.g(), 20); + assert_eq!(a.h(), 30); +} + +pub fn main() { + let a = &A { x: 3 }; + f(a); +} diff --git a/tests/ui/traits/inheritance/auxiliary/auto_xc.rs b/tests/ui/traits/inheritance/auxiliary/auto_xc.rs new file mode 100644 index 000000000..9af26cb2e --- /dev/null +++ b/tests/ui/traits/inheritance/auxiliary/auto_xc.rs @@ -0,0 +1,7 @@ +pub trait Foo { fn f(&self) -> isize; } +pub trait Bar { fn g(&self) -> isize; } +pub trait Baz { fn h(&self) -> isize; } + +pub trait Quux: Foo + Bar + Baz { } + +impl Quux for T { } diff --git a/tests/ui/traits/inheritance/auxiliary/auto_xc_2.rs b/tests/ui/traits/inheritance/auxiliary/auto_xc_2.rs new file mode 100644 index 000000000..e9327676d --- /dev/null +++ b/tests/ui/traits/inheritance/auxiliary/auto_xc_2.rs @@ -0,0 +1,9 @@ +pub trait Foo { fn f(&self) -> isize; } +pub trait Bar { fn g(&self) -> isize; } +pub trait Baz { fn h(&self) -> isize; } + +pub struct A { pub x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } diff --git a/tests/ui/traits/inheritance/auxiliary/overloading_xc.rs b/tests/ui/traits/inheritance/auxiliary/overloading_xc.rs new file mode 100644 index 000000000..a25704412 --- /dev/null +++ b/tests/ui/traits/inheritance/auxiliary/overloading_xc.rs @@ -0,0 +1,38 @@ +use std::cmp::PartialEq; +use std::ops::{Add, Sub, Mul}; + +pub trait MyNum : Add + Sub + Mul + PartialEq + Clone { +} + +#[derive(Clone, Debug)] +pub struct MyInt { + pub val: isize +} + +impl Add for MyInt { + type Output = MyInt; + + fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) } +} + +impl Sub for MyInt { + type Output = MyInt; + + fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) } +} + +impl Mul for MyInt { + type Output = MyInt; + + fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) } +} + +impl PartialEq for MyInt { + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } +} + +impl MyNum for MyInt {} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } diff --git a/tests/ui/traits/inheritance/auxiliary/xc_call.rs b/tests/ui/traits/inheritance/auxiliary/xc_call.rs new file mode 100644 index 000000000..b76c52e62 --- /dev/null +++ b/tests/ui/traits/inheritance/auxiliary/xc_call.rs @@ -0,0 +1,11 @@ +pub trait Foo { + fn f(&self) -> isize; +} + +pub struct A { + pub x: isize +} + +impl Foo for A { + fn f(&self) -> isize { 10 } +} diff --git a/tests/ui/traits/inheritance/basic.rs b/tests/ui/traits/inheritance/basic.rs new file mode 100644 index 000000000..5bfa60b1a --- /dev/null +++ b/tests/ui/traits/inheritance/basic.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar { fn g(&self) -> isize; } +trait Baz { fn h(&self) -> isize; } + +trait Quux: Foo + Bar + Baz { } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } +impl Quux for A {} + +fn f(a: &T) { + assert_eq!(a.f(), 10); + assert_eq!(a.g(), 20); + assert_eq!(a.h(), 30); +} + +pub fn main() { + let a = &A { x: 3 }; + f(a); +} diff --git a/tests/ui/traits/inheritance/call-bound-inherited.rs b/tests/ui/traits/inheritance/call-bound-inherited.rs new file mode 100644 index 000000000..37c2ff63c --- /dev/null +++ b/tests/ui/traits/inheritance/call-bound-inherited.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar : Foo { fn g(&self) -> isize; } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } + +// Call a function on Foo, given a T: Bar +fn gg(a: &T) -> isize { + a.f() +} + +pub fn main() { + let a = &A { x: 3 }; + assert_eq!(gg(a), 10); +} diff --git a/tests/ui/traits/inheritance/call-bound-inherited2.rs b/tests/ui/traits/inheritance/call-bound-inherited2.rs new file mode 100644 index 000000000..8576d29f2 --- /dev/null +++ b/tests/ui/traits/inheritance/call-bound-inherited2.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar : Foo { fn g(&self) -> isize; } +trait Baz : Bar { fn h(&self) -> isize; } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } + +// Call a function on Foo, given a T: Baz, +// which is inherited via Bar +fn gg(a: &T) -> isize { + a.f() +} + +pub fn main() { + let a = &A { x: 3 }; + assert_eq!(gg(a), 10); +} diff --git a/tests/ui/traits/inheritance/cast-without-call-to-supertrait.rs b/tests/ui/traits/inheritance/cast-without-call-to-supertrait.rs new file mode 100644 index 000000000..25159c1ad --- /dev/null +++ b/tests/ui/traits/inheritance/cast-without-call-to-supertrait.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(dead_code)] +// Testing that we can cast to a subtrait and call subtrait +// methods. Not testing supertrait methods + + +trait Foo { + fn f(&self) -> isize; +} + +trait Bar : Foo { + fn g(&self) -> isize; +} + +struct A { + x: isize +} + +impl Foo for A { + fn f(&self) -> isize { 10 } +} + +impl Bar for A { + fn g(&self) -> isize { 20 } +} + +pub fn main() { + let a = &A { x: 3 }; + let afoo = a as &dyn Foo; + let abar = a as &dyn Bar; + assert_eq!(afoo.f(), 10); + assert_eq!(abar.g(), 20); +} diff --git a/tests/ui/traits/inheritance/cast.rs b/tests/ui/traits/inheritance/cast.rs new file mode 100644 index 000000000..9070b9d1f --- /dev/null +++ b/tests/ui/traits/inheritance/cast.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(dead_code)] +// Testing that supertrait methods can be called on subtrait object types + + +trait Foo { + fn f(&self) -> isize; +} + +trait Bar : Foo { + fn g(&self) -> isize; +} + +struct A { + x: isize +} + +impl Foo for A { + fn f(&self) -> isize { 10 } +} + +impl Bar for A { + fn g(&self) -> isize { 20 } +} + +pub fn main() { + let a = &A { x: 3 }; + let afoo = a as &dyn Foo; + let abar = a as &dyn Bar; + assert_eq!(afoo.f(), 10); + assert_eq!(abar.g(), 20); + assert_eq!(abar.f(), 10); +} diff --git a/tests/ui/traits/inheritance/cross-trait-call-xc.rs b/tests/ui/traits/inheritance/cross-trait-call-xc.rs new file mode 100644 index 000000000..99fbb5c61 --- /dev/null +++ b/tests/ui/traits/inheritance/cross-trait-call-xc.rs @@ -0,0 +1,20 @@ +// run-pass +// aux-build:xc_call.rs + + +extern crate xc_call as aux; + +use aux::Foo; + +trait Bar : Foo { + fn g(&self) -> isize; +} + +impl Bar for aux::A { + fn g(&self) -> isize { self.f() } +} + +pub fn main() { + let a = &aux::A { x: 3 }; + assert_eq!(a.g(), 10); +} diff --git a/tests/ui/traits/inheritance/cross-trait-call.rs b/tests/ui/traits/inheritance/cross-trait-call.rs new file mode 100644 index 000000000..512c928ca --- /dev/null +++ b/tests/ui/traits/inheritance/cross-trait-call.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar : Foo { fn g(&self) -> isize; } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } + +impl Bar for A { + // Testing that this impl can call the impl of Foo + fn g(&self) -> isize { self.f() } +} + +pub fn main() { + let a = &A { x: 3 }; + assert_eq!(a.g(), 10); +} diff --git a/tests/ui/traits/inheritance/diamond.rs b/tests/ui/traits/inheritance/diamond.rs new file mode 100644 index 000000000..32ad0fb4d --- /dev/null +++ b/tests/ui/traits/inheritance/diamond.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +// B and C both require A, so D does as well, twice, but that's just fine + + +trait A { fn a(&self) -> isize; } +trait B: A { fn b(&self) -> isize; } +trait C: A { fn c(&self) -> isize; } +trait D: B + C { fn d(&self) -> isize; } + +struct S { bogus: () } + +impl A for S { fn a(&self) -> isize { 10 } } +impl B for S { fn b(&self) -> isize { 20 } } +impl C for S { fn c(&self) -> isize { 30 } } +impl D for S { fn d(&self) -> isize { 40 } } + +fn f(x: &T) { + assert_eq!(x.a(), 10); + assert_eq!(x.b(), 20); + assert_eq!(x.c(), 30); + assert_eq!(x.d(), 40); +} + +pub fn main() { + let value = &S { bogus: () }; + f(value); +} diff --git a/tests/ui/traits/inheritance/multiple-inheritors.rs b/tests/ui/traits/inheritance/multiple-inheritors.rs new file mode 100644 index 000000000..77ecbd8eb --- /dev/null +++ b/tests/ui/traits/inheritance/multiple-inheritors.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] + +trait A { fn a(&self) -> isize; } +trait B: A { fn b(&self) -> isize; } +trait C: A { fn c(&self) -> isize; } + +struct S { bogus: () } + +impl A for S { fn a(&self) -> isize { 10 } } +impl B for S { fn b(&self) -> isize { 20 } } +impl C for S { fn c(&self) -> isize { 30 } } + +// Both B and C inherit from A +fn f(x: &T) { + assert_eq!(x.a(), 10); + assert_eq!(x.b(), 20); + assert_eq!(x.c(), 30); +} + +pub fn main() { + f(&S { bogus: () }) +} diff --git a/tests/ui/traits/inheritance/multiple-params.rs b/tests/ui/traits/inheritance/multiple-params.rs new file mode 100644 index 000000000..8ff5ba541 --- /dev/null +++ b/tests/ui/traits/inheritance/multiple-params.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] + +trait A { fn a(&self) -> isize; } +trait B: A { fn b(&self) -> isize; } +trait C: A { fn c(&self) -> isize; } + +struct S { bogus: () } + +impl A for S { fn a(&self) -> isize { 10 } } +impl B for S { fn b(&self) -> isize { 20 } } +impl C for S { fn c(&self) -> isize { 30 } } + +// Multiple type params, multiple levels of inheritance +fn f(x: &X, y: &Y, z: &Z) { + assert_eq!(x.a(), 10); + assert_eq!(y.a(), 10); + assert_eq!(y.b(), 20); + assert_eq!(z.a(), 10); + assert_eq!(z.c(), 30); +} + +pub fn main() { + let s = &S { bogus: () }; + f(s, s, s); +} diff --git a/tests/ui/traits/inheritance/num.rs b/tests/ui/traits/inheritance/num.rs new file mode 100644 index 000000000..3d63d78ca --- /dev/null +++ b/tests/ui/traits/inheritance/num.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +pub trait NumExt: PartialEq + PartialOrd {} + +pub trait FloatExt: NumExt {} + +fn greater_than_one(n: &T) -> bool { loop {} } +fn greater_than_one_float(n: &T) -> bool { loop {} } + +pub fn main() {} diff --git a/tests/ui/traits/inheritance/num0.rs b/tests/ui/traits/inheritance/num0.rs new file mode 100644 index 000000000..cee52542d --- /dev/null +++ b/tests/ui/traits/inheritance/num0.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] +// Extending Num and using inherited static methods + +// pretty-expanded FIXME #23616 + +use std::cmp::PartialOrd; + +pub trait NumCast: Sized { + fn from(i: i32) -> Option; +} + +pub trait Num { + fn from_int(i: isize) -> Self; + fn gt(&self, other: &Self) -> bool; +} + +pub trait NumExt: NumCast + PartialOrd { } + +fn greater_than_one(n: &T) -> bool { + n.gt(&NumCast::from(1).unwrap()) +} + +pub fn main() {} diff --git a/tests/ui/traits/inheritance/num1.rs b/tests/ui/traits/inheritance/num1.rs new file mode 100644 index 000000000..663dd3a5e --- /dev/null +++ b/tests/ui/traits/inheritance/num1.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub trait NumCast: Sized { + fn from(i: i32) -> Option; +} + +pub trait NumExt: NumCast + PartialOrd { } + +fn greater_than_one(n: &T) -> bool { + *n > NumCast::from(1).unwrap() +} + +pub fn main() {} diff --git a/tests/ui/traits/inheritance/num2.rs b/tests/ui/traits/inheritance/num2.rs new file mode 100644 index 000000000..b713c66a3 --- /dev/null +++ b/tests/ui/traits/inheritance/num2.rs @@ -0,0 +1,86 @@ +// run-pass +// A more complex example of numeric extensions + +pub trait TypeExt {} + +impl TypeExt for u8 {} +impl TypeExt for u16 {} +impl TypeExt for u32 {} +impl TypeExt for u64 {} +impl TypeExt for usize {} + +impl TypeExt for i8 {} +impl TypeExt for i16 {} +impl TypeExt for i32 {} +impl TypeExt for i64 {} +impl TypeExt for isize {} + +impl TypeExt for f32 {} +impl TypeExt for f64 {} + + +pub trait NumExt: TypeExt + PartialEq + PartialOrd {} + +impl NumExt for u8 {} +impl NumExt for u16 {} +impl NumExt for u32 {} +impl NumExt for u64 {} +impl NumExt for usize {} + +impl NumExt for i8 {} +impl NumExt for i16 {} +impl NumExt for i32 {} +impl NumExt for i64 {} +impl NumExt for isize {} + +impl NumExt for f32 {} +impl NumExt for f64 {} + + +pub trait UnSignedExt: NumExt {} + +impl UnSignedExt for u8 {} +impl UnSignedExt for u16 {} +impl UnSignedExt for u32 {} +impl UnSignedExt for u64 {} +impl UnSignedExt for usize {} + + +pub trait SignedExt: NumExt {} + +impl SignedExt for i8 {} +impl SignedExt for i16 {} +impl SignedExt for i32 {} +impl SignedExt for i64 {} +impl SignedExt for isize {} + +impl SignedExt for f32 {} +impl SignedExt for f64 {} + + +pub trait IntegerExt: NumExt {} + +impl IntegerExt for u8 {} +impl IntegerExt for u16 {} +impl IntegerExt for u32 {} +impl IntegerExt for u64 {} +impl IntegerExt for usize {} + +impl IntegerExt for i8 {} +impl IntegerExt for i16 {} +impl IntegerExt for i32 {} +impl IntegerExt for i64 {} +impl IntegerExt for isize {} + + +pub trait FloatExt: NumExt {} + +impl FloatExt for f32 {} +impl FloatExt for f64 {} + + +fn test_float_ext(n: T) { println!("{}", n < n) } + +pub fn main() { + test_float_ext(1f32); +} diff --git a/tests/ui/traits/inheritance/num3.rs b/tests/ui/traits/inheritance/num3.rs new file mode 100644 index 000000000..c40be6f83 --- /dev/null +++ b/tests/ui/traits/inheritance/num3.rs @@ -0,0 +1,19 @@ +// run-pass +pub trait NumCast: Sized { + fn from(i: i32) -> Option; +} + +pub trait NumExt: PartialEq + PartialOrd + NumCast {} + +impl NumExt for f32 {} +impl NumCast for f32 { + fn from(i: i32) -> Option { Some(i as f32) } +} + +fn num_eq_one(n: T) { + println!("{}", n == NumCast::from(1).unwrap()) +} + +pub fn main() { + num_eq_one(1f32); // you need to actually use the function to trigger the ICE +} diff --git a/tests/ui/traits/inheritance/num5.rs b/tests/ui/traits/inheritance/num5.rs new file mode 100644 index 000000000..f478618f7 --- /dev/null +++ b/tests/ui/traits/inheritance/num5.rs @@ -0,0 +1,26 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub trait NumCast: Sized { + fn from(i: i32) -> Option; +} + +pub trait NumExt: PartialEq + NumCast {} + +impl NumExt for f32 {} +impl NumExt for isize {} + +impl NumCast for f32 { + fn from(i: i32) -> Option { Some(i as f32) } +} +impl NumCast for isize { + fn from(i: i32) -> Option { Some(i as isize) } +} + +fn num_eq_one() -> T { + NumCast::from(1).unwrap() +} + +pub fn main() { + num_eq_one::(); // you need to actually use the function to trigger the ICE +} diff --git a/tests/ui/traits/inheritance/overloading-simple.rs b/tests/ui/traits/inheritance/overloading-simple.rs new file mode 100644 index 000000000..c306aa2cd --- /dev/null +++ b/tests/ui/traits/inheritance/overloading-simple.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +use std::cmp::PartialEq; + +trait MyNum : PartialEq { } + +#[derive(Debug)] +struct MyInt { val: isize } + +impl PartialEq for MyInt { + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } +} + +impl MyNum for MyInt {} + +fn f(x: T, y: T) -> bool { + return x == y; +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y, z) = (mi(3), mi(5), mi(3)); + assert!(x != y); + assert_eq!(x, z); +} diff --git a/tests/ui/traits/inheritance/overloading-xc-exe.rs b/tests/ui/traits/inheritance/overloading-xc-exe.rs new file mode 100644 index 000000000..08778061b --- /dev/null +++ b/tests/ui/traits/inheritance/overloading-xc-exe.rs @@ -0,0 +1,20 @@ +// run-pass +// aux-build:overloading_xc.rs + + +extern crate overloading_xc; +use overloading_xc::{MyNum, MyInt}; + +fn f(x: T, y: T) -> (T, T, T) { + return (x.clone() + y.clone(), x.clone() - y.clone(), x * y); +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y) = (mi(3), mi(5)); + let (a, b, c) = f(x, y); + assert_eq!(a, mi(8)); + assert_eq!(b, mi(-2)); + assert_eq!(c, mi(15)); +} diff --git a/tests/ui/traits/inheritance/overloading.rs b/tests/ui/traits/inheritance/overloading.rs new file mode 100644 index 000000000..083643e82 --- /dev/null +++ b/tests/ui/traits/inheritance/overloading.rs @@ -0,0 +1,47 @@ +// run-pass +use std::cmp::PartialEq; +use std::ops::{Add, Sub, Mul}; + +trait MyNum : Add + Sub + Mul + PartialEq + Clone { } + +#[derive(Clone, Debug)] +struct MyInt { val: isize } + +impl Add for MyInt { + type Output = MyInt; + + fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) } +} + +impl Sub for MyInt { + type Output = MyInt; + + fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) } +} + +impl Mul for MyInt { + type Output = MyInt; + + fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) } +} + +impl PartialEq for MyInt { + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } +} + +impl MyNum for MyInt {} + +fn f(x: T, y: T) -> (T, T, T) { + return (x.clone() + y.clone(), x.clone() - y.clone(), x * y); +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y) = (mi(3), mi(5)); + let (a, b, c) = f(x, y); + assert_eq!(a, mi(8)); + assert_eq!(b, mi(-2)); + assert_eq!(c, mi(15)); +} diff --git a/tests/ui/traits/inheritance/repeated-supertrait-ambig.rs b/tests/ui/traits/inheritance/repeated-supertrait-ambig.rs new file mode 100644 index 000000000..727897d20 --- /dev/null +++ b/tests/ui/traits/inheritance/repeated-supertrait-ambig.rs @@ -0,0 +1,43 @@ +// Test a case of a trait which extends the same supertrait twice, but +// with difference type parameters. Test then that when we don't give +// enough information to pick between these, no selection is made. In +// this particular case, the two choices are i64/u64 -- so when we use +// an integer literal, we wind up falling this literal back to i32. +// See also `run-pass/trait-repeated-supertrait.rs`. + +trait CompareTo { + fn same_as(&self, t: T) -> bool; +} + +trait CompareToInts : CompareTo + CompareTo { +} + +impl CompareTo for i64 { + fn same_as(&self, t: i64) -> bool { *self == t } +} + +impl CompareTo for i64 { + fn same_as(&self, t: u64) -> bool { *self == (t as i64) } +} + +impl CompareToInts for i64 { } + +fn with_obj(c: &dyn CompareToInts) -> bool { + c.same_as(22) //~ ERROR `dyn CompareToInts: CompareTo` is not satisfied +} + +fn with_trait(c: &C) -> bool { + c.same_as(22) //~ ERROR `C: CompareTo` is not satisfied +} + +fn with_ufcs1(c: &C) -> bool { + ::same_as(c, 22) //~ ERROR `dyn CompareToInts: CompareTo` is not satisfi +} + +fn with_ufcs2(c: &C) -> bool { + CompareTo::same_as(c, 22) //~ ERROR `C: CompareTo` is not satisfied +} + +fn main() { + assert_eq!(22_i64.same_as(22), true); //~ ERROR `i64: CompareTo` is not satisfied +} diff --git a/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr new file mode 100644 index 000000000..656e0d0bf --- /dev/null +++ b/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr @@ -0,0 +1,65 @@ +error[E0277]: the trait bound `dyn CompareToInts: CompareTo` is not satisfied + --> $DIR/repeated-supertrait-ambig.rs:26:15 + | +LL | c.same_as(22) + | ------- ^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `CompareTo`: + > + > + +error[E0277]: the trait bound `C: CompareTo` is not satisfied + --> $DIR/repeated-supertrait-ambig.rs:30:15 + | +LL | c.same_as(22) + | ------- ^^ the trait `CompareTo` is not implemented for `C` + | | + | required by a bound introduced by this call + | +help: consider further restricting this bound + | +LL | fn with_trait>(c: &C) -> bool { + | ++++++++++++++++ + +error[E0277]: the trait bound `dyn CompareToInts: CompareTo` is not satisfied + --> $DIR/repeated-supertrait-ambig.rs:34:37 + | +LL | ::same_as(c, 22) + | ---------------------------- ^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `CompareTo`: + > + > + +error[E0277]: the trait bound `C: CompareTo` is not satisfied + --> $DIR/repeated-supertrait-ambig.rs:38:27 + | +LL | CompareTo::same_as(c, 22) + | ------------------ ^^ the trait `CompareTo` is not implemented for `C` + | | + | required by a bound introduced by this call + | +help: consider further restricting this bound + | +LL | fn with_ufcs2>(c: &C) -> bool { + | ++++++++++++++++ + +error[E0277]: the trait bound `i64: CompareTo` is not satisfied + --> $DIR/repeated-supertrait-ambig.rs:42:31 + | +LL | assert_eq!(22_i64.same_as(22), true); + | ------- ^^ the trait `CompareTo` is not implemented for `i64` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `CompareTo`: + > + > + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/inheritance/repeated-supertrait.rs b/tests/ui/traits/inheritance/repeated-supertrait.rs new file mode 100644 index 000000000..cb2581ffa --- /dev/null +++ b/tests/ui/traits/inheritance/repeated-supertrait.rs @@ -0,0 +1,48 @@ +// run-pass +// Test a case of a trait which extends the same supertrait twice, but +// with difference type parameters. Test that we can invoke the +// various methods in various ways successfully. +// See also `ui/traits/trait-repeated-supertrait-ambig.rs`. + + +trait CompareTo { + fn same_as(&self, t: T) -> bool; +} + +trait CompareToInts : CompareTo + CompareTo { +} + +impl CompareTo for i64 { + fn same_as(&self, t: i64) -> bool { *self == t } +} + +impl CompareTo for i64 { + fn same_as(&self, t: u64) -> bool { *self == (t as i64) } +} + +impl CompareToInts for i64 { } + +fn with_obj(c: &dyn CompareToInts) -> bool { + c.same_as(22_i64) && c.same_as(22_u64) +} + +fn with_trait(c: &C) -> bool { + c.same_as(22_i64) && c.same_as(22_u64) +} + +fn with_ufcs1(c: &C) -> bool { + ::same_as(c, 22_i64) && ::same_as(c, 22_u64) +} + +fn with_ufcs2(c: &C) -> bool { + CompareTo::same_as(c, 22_i64) && CompareTo::same_as(c, 22_u64) +} + +fn main() { + assert_eq!(22_i64.same_as(22_i64), true); + assert_eq!(22_i64.same_as(22_u64), true); + assert_eq!(with_trait(&22), true); + assert_eq!(with_obj(&22), true); + assert_eq!(with_ufcs1(&22), true); + assert_eq!(with_ufcs2(&22), true); +} diff --git a/tests/ui/traits/inheritance/self-in-supertype.rs b/tests/ui/traits/inheritance/self-in-supertype.rs new file mode 100644 index 000000000..e8a2bd791 --- /dev/null +++ b/tests/ui/traits/inheritance/self-in-supertype.rs @@ -0,0 +1,62 @@ +// run-pass +// Test for issue #4183: use of Self in supertraits. + +pub static FUZZY_EPSILON: f64 = 0.1; + +pub trait FuzzyEq { + fn fuzzy_eq(&self, other: &Self) -> bool; + fn fuzzy_eq_eps(&self, other: &Self, epsilon: &Eps) -> bool; +} + +trait Float: Sized+FuzzyEq { + fn two_pi() -> Self; +} + +impl FuzzyEq for f32 { + fn fuzzy_eq(&self, other: &f32) -> bool { + self.fuzzy_eq_eps(other, &(FUZZY_EPSILON as f32)) + } + + fn fuzzy_eq_eps(&self, other: &f32, epsilon: &f32) -> bool { + (*self - *other).abs() < *epsilon + } +} + +impl Float for f32 { + fn two_pi() -> f32 { 6.28318530717958647692528676655900576_f32 } +} + +impl FuzzyEq for f64 { + fn fuzzy_eq(&self, other: &f64) -> bool { + self.fuzzy_eq_eps(other, &(FUZZY_EPSILON as f64)) + } + + fn fuzzy_eq_eps(&self, other: &f64, epsilon: &f64) -> bool { + (*self - *other).abs() < *epsilon + } +} + +impl Float for f64 { + fn two_pi() -> f64 { 6.28318530717958647692528676655900576_f64 } +} + +fn compare(f1: F) -> bool { + let f2 = Float::two_pi(); + f1.fuzzy_eq(&f2) +} + +pub fn main() { + assert!(compare::(6.28318530717958647692528676655900576)); + assert!(compare::(6.29)); + assert!(compare::(6.3)); + assert!(compare::(6.19)); + assert!(!compare::(7.28318530717958647692528676655900576)); + assert!(!compare::(6.18)); + + assert!(compare::(6.28318530717958647692528676655900576)); + assert!(compare::(6.29)); + assert!(compare::(6.3)); + assert!(compare::(6.19)); + assert!(!compare::(7.28318530717958647692528676655900576)); + assert!(!compare::(6.18)); +} diff --git a/tests/ui/traits/inheritance/self.rs b/tests/ui/traits/inheritance/self.rs new file mode 100644 index 000000000..5f2559f48 --- /dev/null +++ b/tests/ui/traits/inheritance/self.rs @@ -0,0 +1,29 @@ +// run-pass +trait Foo { + fn f(&self, x: &T); +} + +trait Bar : Sized + Foo { + fn g(&self); +} + +struct S { + x: isize +} + +impl Foo for S { + fn f(&self, x: &S) { + println!("{}", x.x); + } +} + +impl Bar for S { + fn g(&self) { + self.f(self); + } +} + +pub fn main() { + let s = S { x: 1 }; + s.g(); +} diff --git a/tests/ui/traits/inheritance/simple.rs b/tests/ui/traits/inheritance/simple.rs new file mode 100644 index 000000000..ca3a284e5 --- /dev/null +++ b/tests/ui/traits/inheritance/simple.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar : Foo { fn g(&self) -> isize; } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } + +fn ff(a: &T) -> isize { + a.f() +} + +fn gg(a: &T) -> isize { + a.g() +} + +pub fn main() { + let a = &A { x: 3 }; + assert_eq!(ff(a), 10); + assert_eq!(gg(a), 20); +} diff --git a/tests/ui/traits/inheritance/static.rs b/tests/ui/traits/inheritance/static.rs new file mode 100644 index 000000000..16218fbd2 --- /dev/null +++ b/tests/ui/traits/inheritance/static.rs @@ -0,0 +1,26 @@ +// run-pass + +pub trait MyNum { + fn from_int(_: isize) -> Self; +} + +pub trait NumExt: MyNum { } + +struct S { v: isize } + +impl MyNum for S { + fn from_int(i: isize) -> S { + S { + v: i + } + } +} + +impl NumExt for S { } + +fn greater_than_one() -> T { MyNum::from_int(1) } + +pub fn main() { + let v: S = greater_than_one(); + assert_eq!(v.v, 1); +} diff --git a/tests/ui/traits/inheritance/static2.rs b/tests/ui/traits/inheritance/static2.rs new file mode 100644 index 000000000..bc78e1e23 --- /dev/null +++ b/tests/ui/traits/inheritance/static2.rs @@ -0,0 +1,29 @@ +// run-pass +pub trait MyEq {} + +pub trait MyNum { + fn from_int(_: isize) -> Self; +} + +pub trait NumExt: MyEq + MyNum { } + +struct S { v: isize } + +impl MyEq for S { } + +impl MyNum for S { + fn from_int(i: isize) -> S { + S { + v: i + } + } +} + +impl NumExt for S { } + +fn greater_than_one() -> T { MyNum::from_int(1) } + +pub fn main() { + let v: S = greater_than_one(); + assert_eq!(v.v, 1); +} diff --git a/tests/ui/traits/inheritance/subst.rs b/tests/ui/traits/inheritance/subst.rs new file mode 100644 index 000000000..b2b650366 --- /dev/null +++ b/tests/ui/traits/inheritance/subst.rs @@ -0,0 +1,27 @@ +// run-pass + +pub trait Add { + fn add(&self, rhs: &RHS) -> Result; +} + +trait MyNum : Sized + Add { } + +struct MyInt { val: isize } + +impl Add for MyInt { + fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } +} + +impl MyNum for MyInt {} + +fn f(x: T, y: T) -> T { + return x.add(&y); +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y) = (mi(3), mi(5)); + let z = f(x, y); + assert_eq!(z.val, 8) +} diff --git a/tests/ui/traits/inheritance/subst2.rs b/tests/ui/traits/inheritance/subst2.rs new file mode 100644 index 000000000..ccc9628c7 --- /dev/null +++ b/tests/ui/traits/inheritance/subst2.rs @@ -0,0 +1,37 @@ +// run-pass + +trait Panda { + fn chomp(&self, bamboo: &T) -> T; +} + +trait Add: Panda { + fn add(&self, rhs: &RHS) -> Result; +} + +trait MyNum : Sized + Add { } + +struct MyInt { val: isize } + +impl Panda for MyInt { + fn chomp(&self, bamboo: &MyInt) -> MyInt { + mi(self.val + bamboo.val) + } +} + +impl Add for MyInt { + fn add(&self, other: &MyInt) -> MyInt { self.chomp(other) } +} + +impl MyNum for MyInt {} + +fn f(x: T, y: T) -> T { + return x.add(&y).chomp(&y); +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y) = (mi(3), mi(5)); + let z = f(x, y); + assert_eq!(z.val, 13); +} diff --git a/tests/ui/traits/inheritance/visibility.rs b/tests/ui/traits/inheritance/visibility.rs new file mode 100644 index 000000000..6ad864926 --- /dev/null +++ b/tests/ui/traits/inheritance/visibility.rs @@ -0,0 +1,20 @@ +// run-pass + +mod traits { + pub trait Foo { fn f(&self) -> isize; } + + impl Foo for isize { fn f(&self) -> isize { 10 } } +} + +trait Quux: traits::Foo { } +impl Quux for T { } + +// Foo is not in scope but because Quux is we can still access +// Foo's methods on a Quux bound typaram +fn f(x: &T) { + assert_eq!(x.f(), 10); +} + +pub fn main() { + f(&0) +} -- cgit v1.2.3