summaryrefslogtreecommitdiffstats
path: root/tests/ui/traits/inheritance
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/traits/inheritance')
-rw-r--r--tests/ui/traits/inheritance/auto-xc-2.rs23
-rw-r--r--tests/ui/traits/inheritance/auto-xc.rs25
-rw-r--r--tests/ui/traits/inheritance/auto.rs29
-rw-r--r--tests/ui/traits/inheritance/auxiliary/auto_xc.rs7
-rw-r--r--tests/ui/traits/inheritance/auxiliary/auto_xc_2.rs9
-rw-r--r--tests/ui/traits/inheritance/auxiliary/overloading_xc.rs38
-rw-r--r--tests/ui/traits/inheritance/auxiliary/xc_call.rs11
-rw-r--r--tests/ui/traits/inheritance/basic.rs26
-rw-r--r--tests/ui/traits/inheritance/call-bound-inherited.rs20
-rw-r--r--tests/ui/traits/inheritance/call-bound-inherited2.rs23
-rw-r--r--tests/ui/traits/inheritance/cast-without-call-to-supertrait.rs33
-rw-r--r--tests/ui/traits/inheritance/cast.rs33
-rw-r--r--tests/ui/traits/inheritance/cross-trait-call-xc.rs20
-rw-r--r--tests/ui/traits/inheritance/cross-trait-call.rs19
-rw-r--r--tests/ui/traits/inheritance/diamond.rs28
-rw-r--r--tests/ui/traits/inheritance/multiple-inheritors.rs23
-rw-r--r--tests/ui/traits/inheritance/multiple-params.rs26
-rw-r--r--tests/ui/traits/inheritance/num.rs13
-rw-r--r--tests/ui/traits/inheritance/num0.rs24
-rw-r--r--tests/ui/traits/inheritance/num1.rs15
-rw-r--r--tests/ui/traits/inheritance/num2.rs86
-rw-r--r--tests/ui/traits/inheritance/num3.rs19
-rw-r--r--tests/ui/traits/inheritance/num5.rs26
-rw-r--r--tests/ui/traits/inheritance/overloading-simple.rs27
-rw-r--r--tests/ui/traits/inheritance/overloading-xc-exe.rs20
-rw-r--r--tests/ui/traits/inheritance/overloading.rs47
-rw-r--r--tests/ui/traits/inheritance/repeated-supertrait-ambig.rs43
-rw-r--r--tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr65
-rw-r--r--tests/ui/traits/inheritance/repeated-supertrait.rs48
-rw-r--r--tests/ui/traits/inheritance/self-in-supertype.rs62
-rw-r--r--tests/ui/traits/inheritance/self.rs29
-rw-r--r--tests/ui/traits/inheritance/simple.rs24
-rw-r--r--tests/ui/traits/inheritance/static.rs26
-rw-r--r--tests/ui/traits/inheritance/static2.rs29
-rw-r--r--tests/ui/traits/inheritance/subst.rs27
-rw-r--r--tests/ui/traits/inheritance/subst2.rs37
-rw-r--r--tests/ui/traits/inheritance/visibility.rs20
37 files changed, 1080 insertions, 0 deletions
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<T:Foo + Bar + Baz> Quux for T { }
+
+fn f<T:Quux>(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<T:Quux>(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<T:Foo + Bar + Baz> 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<T:Quux>(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<T:Foo + Bar + Baz> 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<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + 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<T:Quux + Foo + Bar + Baz>(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<T:Bar>(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<T:Baz>(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<T:D>(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<T:B + C>(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:A,Y:B,Z:C>(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<T: NumExt>(n: &T) -> bool { loop {} }
+fn greater_than_one_float<T: FloatExt>(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<Self>;
+}
+
+pub trait Num {
+ fn from_int(i: isize) -> Self;
+ fn gt(&self, other: &Self) -> bool;
+}
+
+pub trait NumExt: NumCast + PartialOrd { }
+
+fn greater_than_one<T:NumExt>(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<Self>;
+}
+
+pub trait NumExt: NumCast + PartialOrd { }
+
+fn greater_than_one<T:NumExt>(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<T:FloatExt>(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<Self>;
+}
+
+pub trait NumExt: PartialEq + PartialOrd + NumCast {}
+
+impl NumExt for f32 {}
+impl NumCast for f32 {
+ fn from(i: i32) -> Option<f32> { Some(i as f32) }
+}
+
+fn num_eq_one<T: NumExt>(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<Self>;
+}
+
+pub trait NumExt: PartialEq + NumCast {}
+
+impl NumExt for f32 {}
+impl NumExt for isize {}
+
+impl NumCast for f32 {
+ fn from(i: i32) -> Option<f32> { Some(i as f32) }
+}
+impl NumCast for isize {
+ fn from(i: i32) -> Option<isize> { Some(i as isize) }
+}
+
+fn num_eq_one<T:NumExt>() -> T {
+ NumCast::from(1).unwrap()
+}
+
+pub fn main() {
+ num_eq_one::<isize>(); // 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<T:MyNum>(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<T:MyNum>(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<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + 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<T:MyNum>(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<T> {
+ fn same_as(&self, t: T) -> bool;
+}
+
+trait CompareToInts : CompareTo<i64> + CompareTo<u64> {
+}
+
+impl CompareTo<i64> for i64 {
+ fn same_as(&self, t: i64) -> bool { *self == t }
+}
+
+impl CompareTo<u64> 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<i32>` is not satisfied
+}
+
+fn with_trait<C:CompareToInts>(c: &C) -> bool {
+ c.same_as(22) //~ ERROR `C: CompareTo<i32>` is not satisfied
+}
+
+fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
+ <dyn CompareToInts>::same_as(c, 22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfi
+}
+
+fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
+ CompareTo::same_as(c, 22) //~ ERROR `C: CompareTo<i32>` is not satisfied
+}
+
+fn main() {
+ assert_eq!(22_i64.same_as(22), true); //~ ERROR `i64: CompareTo<i32>` 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<i32>` is not satisfied
+ --> $DIR/repeated-supertrait-ambig.rs:26:15
+ |
+LL | c.same_as(22)
+ | ------- ^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the following other types implement trait `CompareTo<T>`:
+ <i64 as CompareTo<i64>>
+ <i64 as CompareTo<u64>>
+
+error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
+ --> $DIR/repeated-supertrait-ambig.rs:30:15
+ |
+LL | c.same_as(22)
+ | ------- ^^ the trait `CompareTo<i32>` is not implemented for `C`
+ | |
+ | required by a bound introduced by this call
+ |
+help: consider further restricting this bound
+ |
+LL | fn with_trait<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
+ | ++++++++++++++++
+
+error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfied
+ --> $DIR/repeated-supertrait-ambig.rs:34:37
+ |
+LL | <dyn CompareToInts>::same_as(c, 22)
+ | ---------------------------- ^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the following other types implement trait `CompareTo<T>`:
+ <i64 as CompareTo<i64>>
+ <i64 as CompareTo<u64>>
+
+error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
+ --> $DIR/repeated-supertrait-ambig.rs:38:27
+ |
+LL | CompareTo::same_as(c, 22)
+ | ------------------ ^^ the trait `CompareTo<i32>` is not implemented for `C`
+ | |
+ | required by a bound introduced by this call
+ |
+help: consider further restricting this bound
+ |
+LL | fn with_ufcs2<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
+ | ++++++++++++++++
+
+error[E0277]: the trait bound `i64: CompareTo<i32>` is not satisfied
+ --> $DIR/repeated-supertrait-ambig.rs:42:31
+ |
+LL | assert_eq!(22_i64.same_as(22), true);
+ | ------- ^^ the trait `CompareTo<i32>` is not implemented for `i64`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the following other types implement trait `CompareTo<T>`:
+ <i64 as CompareTo<i64>>
+ <i64 as CompareTo<u64>>
+
+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<T> {
+ fn same_as(&self, t: T) -> bool;
+}
+
+trait CompareToInts : CompareTo<i64> + CompareTo<u64> {
+}
+
+impl CompareTo<i64> for i64 {
+ fn same_as(&self, t: i64) -> bool { *self == t }
+}
+
+impl CompareTo<u64> 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:CompareToInts>(c: &C) -> bool {
+ c.same_as(22_i64) && c.same_as(22_u64)
+}
+
+fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
+ <dyn CompareToInts>::same_as(c, 22_i64) && <dyn CompareToInts>::same_as(c, 22_u64)
+}
+
+fn with_ufcs2<C:CompareToInts>(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<Eps> {
+ fn fuzzy_eq(&self, other: &Self) -> bool;
+ fn fuzzy_eq_eps(&self, other: &Self, epsilon: &Eps) -> bool;
+}
+
+trait Float: Sized+FuzzyEq<Self> {
+ fn two_pi() -> Self;
+}
+
+impl FuzzyEq<f32> 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<f64> 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<F:Float>(f1: F) -> bool {
+ let f2 = Float::two_pi();
+ f1.fuzzy_eq(&f2)
+}
+
+pub fn main() {
+ assert!(compare::<f32>(6.28318530717958647692528676655900576));
+ assert!(compare::<f32>(6.29));
+ assert!(compare::<f32>(6.3));
+ assert!(compare::<f32>(6.19));
+ assert!(!compare::<f32>(7.28318530717958647692528676655900576));
+ assert!(!compare::<f32>(6.18));
+
+ assert!(compare::<f64>(6.28318530717958647692528676655900576));
+ assert!(compare::<f64>(6.29));
+ assert!(compare::<f64>(6.3));
+ assert!(compare::<f64>(6.19));
+ assert!(!compare::<f64>(7.28318530717958647692528676655900576));
+ assert!(!compare::<f64>(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<T> {
+ fn f(&self, x: &T);
+}
+
+trait Bar : Sized + Foo<Self> {
+ fn g(&self);
+}
+
+struct S {
+ x: isize
+}
+
+impl Foo<S> 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<T:Foo>(a: &T) -> isize {
+ a.f()
+}
+
+fn gg<T:Bar>(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:NumExt>() -> 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:NumExt>() -> 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<RHS,Result> {
+ fn add(&self, rhs: &RHS) -> Result;
+}
+
+trait MyNum : Sized + Add<Self,Self> { }
+
+struct MyInt { val: isize }
+
+impl Add<MyInt, MyInt> for MyInt {
+ fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) }
+}
+
+impl MyNum for MyInt {}
+
+fn f<T:MyNum>(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<T> {
+ fn chomp(&self, bamboo: &T) -> T;
+}
+
+trait Add<RHS,Result>: Panda<RHS> {
+ fn add(&self, rhs: &RHS) -> Result;
+}
+
+trait MyNum : Sized + Add<Self,Self> { }
+
+struct MyInt { val: isize }
+
+impl Panda<MyInt> for MyInt {
+ fn chomp(&self, bamboo: &MyInt) -> MyInt {
+ mi(self.val + bamboo.val)
+ }
+}
+
+impl Add<MyInt, MyInt> for MyInt {
+ fn add(&self, other: &MyInt) -> MyInt { self.chomp(other) }
+}
+
+impl MyNum for MyInt {}
+
+fn f<T:MyNum>(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<T:traits::Foo> 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<T:Quux>(x: &T) {
+ assert_eq!(x.f(), 10);
+}
+
+pub fn main() {
+ f(&0)
+}