summaryrefslogtreecommitdiffstats
path: root/src/test/ui/autoref-autoderef
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/autoref-autoderef')
-rw-r--r--src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs29
-rw-r--r--src/test/ui/autoref-autoderef/auto-ref-sliceable.rs19
-rw-r--r--src/test/ui/autoref-autoderef/auto-ref.rs19
-rw-r--r--src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs18
-rw-r--r--src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs15
-rw-r--r--src/test/ui/autoref-autoderef/autoderef-method-priority.rs19
-rw-r--r--src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs15
-rw-r--r--src/test/ui/autoref-autoderef/autoderef-method-twice.rs15
-rw-r--r--src/test/ui/autoref-autoderef/autoderef-method.rs15
-rw-r--r--src/test/ui/autoref-autoderef/autoderef-privacy.rs51
-rw-r--r--src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs22
-rw-r--r--src/test/ui/autoref-autoderef/deref-into-array.rs17
-rw-r--r--src/test/ui/autoref-autoderef/issue-38940.rs52
-rw-r--r--src/test/ui/autoref-autoderef/issue-38940.stderr23
14 files changed, 329 insertions, 0 deletions
diff --git a/src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs b/src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs
new file mode 100644
index 000000000..2482e1878
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs
@@ -0,0 +1,29 @@
+// run-pass
+trait Foo {
+ fn f(&self);
+}
+
+struct Bar {
+ x: isize
+}
+
+trait Baz {
+ fn g(&self);
+}
+
+impl<T:Baz> Foo for T {
+ fn f(&self) {
+ self.g();
+ }
+}
+
+impl Baz for Bar {
+ fn g(&self) {
+ println!("{}", self.x);
+ }
+}
+
+pub fn main() {
+ let y = Bar { x: 42 };
+ y.f();
+}
diff --git a/src/test/ui/autoref-autoderef/auto-ref-sliceable.rs b/src/test/ui/autoref-autoderef/auto-ref-sliceable.rs
new file mode 100644
index 000000000..e5f79d780
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/auto-ref-sliceable.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+
+trait Pushable<T> {
+ fn push_val(&mut self, t: T);
+}
+
+impl<T> Pushable<T> for Vec<T> {
+ fn push_val(&mut self, t: T) {
+ self.push(t);
+ }
+}
+
+pub fn main() {
+ let mut v = vec![1];
+ v.push_val(2);
+ v.push_val(3);
+ assert_eq!(v, [1, 2, 3]);
+}
diff --git a/src/test/ui/autoref-autoderef/auto-ref.rs b/src/test/ui/autoref-autoderef/auto-ref.rs
new file mode 100644
index 000000000..b77f9c342
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/auto-ref.rs
@@ -0,0 +1,19 @@
+// run-pass
+struct Foo {
+ x: isize,
+}
+
+trait Stuff {
+ fn printme(&self);
+}
+
+impl Stuff for Foo {
+ fn printme(&self) {
+ println!("{}", self.x);
+ }
+}
+
+pub fn main() {
+ let x = Foo { x: 3 };
+ x.printme();
+}
diff --git a/src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs b/src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs
new file mode 100644
index 000000000..874f42282
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs
@@ -0,0 +1,18 @@
+// run-pass
+#![allow(dead_code)]
+// pretty-expanded FIXME #23616
+
+struct Foo {
+ x: isize,
+}
+
+impl Foo {
+ pub fn f(&self) {}
+}
+
+fn g(x: &mut Foo) {
+ x.f();
+}
+
+pub fn main() {
+}
diff --git a/src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs b/src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs
new file mode 100644
index 000000000..af747cc76
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+trait double {
+ fn double(self: Box<Self>) -> usize;
+}
+
+impl double for usize {
+ fn double(self: Box<usize>) -> usize { *self * 2 }
+}
+
+pub fn main() {
+ let x: Box<_> = Box::new(Box::new(3usize) as Box<dyn double>);
+ assert_eq!(x.double(), 6);
+}
diff --git a/src/test/ui/autoref-autoderef/autoderef-method-priority.rs b/src/test/ui/autoref-autoderef/autoderef-method-priority.rs
new file mode 100644
index 000000000..88a5140dc
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/autoderef-method-priority.rs
@@ -0,0 +1,19 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+trait double {
+ fn double(self) -> usize;
+}
+
+impl double for usize {
+ fn double(self) -> usize { self }
+}
+
+impl double for Box<usize> {
+ fn double(self) -> usize { *self * 2 }
+}
+
+pub fn main() {
+ let x: Box<_> = Box::new(3);
+ assert_eq!(x.double(), 6);
+}
diff --git a/src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs b/src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs
new file mode 100644
index 000000000..3657e61d4
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+trait double {
+ fn double(self: Box<Self>) -> usize;
+}
+
+impl double for Box<usize> {
+ fn double(self: Box<Box<usize>>) -> usize { **self * 2 }
+}
+
+pub fn main() {
+ let x: Box<Box<Box<Box<Box<_>>>>> = Box::new(Box::new(Box::new(Box::new(Box::new(3)))));
+ assert_eq!(x.double(), 6);
+}
diff --git a/src/test/ui/autoref-autoderef/autoderef-method-twice.rs b/src/test/ui/autoref-autoderef/autoderef-method-twice.rs
new file mode 100644
index 000000000..ed86b31b8
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/autoderef-method-twice.rs
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+trait double {
+ fn double(self: Box<Self>) -> usize;
+}
+
+impl double for usize {
+ fn double(self: Box<usize>) -> usize { *self * 2 }
+}
+
+pub fn main() {
+ let x: Box<Box<_>> = Box::new(Box::new(3));
+ assert_eq!(x.double(), 6);
+}
diff --git a/src/test/ui/autoref-autoderef/autoderef-method.rs b/src/test/ui/autoref-autoderef/autoderef-method.rs
new file mode 100644
index 000000000..5b7965e95
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/autoderef-method.rs
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+trait double {
+ fn double(self: Box<Self>) -> usize;
+}
+
+impl double for usize {
+ fn double(self: Box<usize>) -> usize { *self * 2 }
+}
+
+pub fn main() {
+ let x: Box<_> = Box::new(3);
+ assert_eq!(x.double(), 6);
+}
diff --git a/src/test/ui/autoref-autoderef/autoderef-privacy.rs b/src/test/ui/autoref-autoderef/autoderef-privacy.rs
new file mode 100644
index 000000000..841be930b
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/autoderef-privacy.rs
@@ -0,0 +1,51 @@
+// run-pass
+// Check we do not select a private method or field when computing autoderefs
+
+#![allow(unused)]
+
+#[derive(Default)]
+pub struct Bar2 { i: i32 }
+#[derive(Default)]
+pub struct Baz2(i32);
+
+impl Bar2 {
+ fn f(&self) -> bool { true }
+}
+
+mod foo {
+ #[derive(Default)]
+ pub struct Bar { i: ::Bar2 }
+ #[derive(Default)]
+ pub struct Baz(::Baz2);
+
+ impl Bar {
+ fn f(&self) -> bool { false }
+ }
+
+ impl ::std::ops::Deref for Bar {
+ type Target = ::Bar2;
+ fn deref(&self) -> &::Bar2 { &self.i }
+ }
+
+ impl ::std::ops::Deref for Baz {
+ type Target = ::Baz2;
+ fn deref(&self) -> &::Baz2 { &self.0 }
+ }
+
+ pub fn f(bar: &Bar, baz: &Baz) {
+ // Since the private fields and methods are visible here, there should be no autoderefs.
+ let _: &::Bar2 = &bar.i;
+ let _: &::Baz2 = &baz.0;
+ assert!(!bar.f());
+ }
+}
+
+fn main() {
+ let bar = foo::Bar::default();
+ let baz = foo::Baz::default();
+ foo::f(&bar, &baz);
+
+ let _: i32 = bar.i;
+ let _: i32 = baz.0;
+ assert!(bar.f());
+}
diff --git a/src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs b/src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs
new file mode 100644
index 000000000..3bdc248ff
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs
@@ -0,0 +1,22 @@
+// run-pass
+
+trait Foo {
+ fn foo(&self) -> String;
+}
+
+impl<T:Foo> Foo for Box<T> {
+ fn foo(&self) -> String {
+ format!("box {}", (**self).foo())
+ }
+}
+
+impl Foo for usize {
+ fn foo(&self) -> String {
+ format!("{}", *self)
+ }
+}
+
+pub fn main() {
+ let x: Box<_> = Box::new(3);
+ assert_eq!(x.foo(), "box 3".to_string());
+}
diff --git a/src/test/ui/autoref-autoderef/deref-into-array.rs b/src/test/ui/autoref-autoderef/deref-into-array.rs
new file mode 100644
index 000000000..855a82d2f
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/deref-into-array.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+struct Test<T>([T; 1]);
+
+impl<T> std::ops::Deref for Test<T> {
+ type Target = [T; 1];
+
+ fn deref(&self) -> &[T; 1] {
+ &self.0
+ }
+}
+
+fn main() {
+ let out = Test([(); 1]);
+ let blah = out.len();
+ println!("{}", blah);
+}
diff --git a/src/test/ui/autoref-autoderef/issue-38940.rs b/src/test/ui/autoref-autoderef/issue-38940.rs
new file mode 100644
index 000000000..d2f1c6e32
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/issue-38940.rs
@@ -0,0 +1,52 @@
+// issue-38940: error printed twice for deref recursion limit exceeded
+// Test that the recursion limit can be changed. In this case, we have
+// deeply nested types that will fail the `Send` check by overflow
+// when the recursion limit is set very low.
+// compile-flags: -Zdeduplicate-diagnostics=yes
+
+#![allow(dead_code)]
+#![recursion_limit = "10"]
+macro_rules! link {
+ ($outer:ident, $inner:ident) => {
+ struct $outer($inner);
+ impl $outer {
+ fn new() -> $outer {
+ $outer($inner::new())
+ }
+ }
+ impl std::ops::Deref for $outer {
+ type Target = $inner;
+ fn deref(&self) -> &$inner {
+ &self.0
+ }
+ }
+ };
+}
+
+struct Bottom;
+
+impl Bottom {
+ fn new() -> Bottom {
+ Bottom
+ }
+}
+
+link!(Top, A);
+link!(A, B);
+link!(B, C);
+link!(C, D);
+link!(D, E);
+link!(E, F);
+link!(F, G);
+link!(G, H);
+link!(H, I);
+link!(I, J);
+link!(J, K);
+link!(K, Bottom);
+
+fn main() {
+ let t = Top::new();
+ let x: &Bottom = &t;
+ //~^ ERROR mismatched types
+ //~| ERROR reached the recursion limit while auto-dereferencing `J`
+}
diff --git a/src/test/ui/autoref-autoderef/issue-38940.stderr b/src/test/ui/autoref-autoderef/issue-38940.stderr
new file mode 100644
index 000000000..f0b840577
--- /dev/null
+++ b/src/test/ui/autoref-autoderef/issue-38940.stderr
@@ -0,0 +1,23 @@
+error[E0055]: reached the recursion limit while auto-dereferencing `J`
+ --> $DIR/issue-38940.rs:49:22
+ |
+LL | let x: &Bottom = &t;
+ | ^^ deref recursion limit reached
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`issue_38940`)
+
+error[E0308]: mismatched types
+ --> $DIR/issue-38940.rs:49:22
+ |
+LL | let x: &Bottom = &t;
+ | ------- ^^ expected struct `Bottom`, found struct `Top`
+ | |
+ | expected due to this
+ |
+ = note: expected reference `&Bottom`
+ found reference `&Top`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0055, E0308.
+For more information about an error, try `rustc --explain E0055`.