summaryrefslogtreecommitdiffstats
path: root/src/test/ui/rfcs/rfc-2005-default-binding-mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/rfcs/rfc-2005-default-binding-mode')
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs18
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs40
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs45
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs20
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs249
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs34
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs9
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs16
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs14
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs25
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs22
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs19
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs12
13 files changed, 523 insertions, 0 deletions
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs
new file mode 100644
index 000000000..0d1cded36
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs
@@ -0,0 +1,18 @@
+// run-pass
+#![allow(unreachable_patterns)]
+#![feature(box_patterns)]
+
+struct Foo{}
+
+pub fn main() {
+ let b = Box::new(Foo{});
+ let box f = &b;
+ let _: &Foo = f;
+
+ match &&&b {
+ box f => {
+ let _: &Foo = f;
+ },
+ _ => panic!(),
+ }
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs
new file mode 100644
index 000000000..d5bca6a24
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs
@@ -0,0 +1,40 @@
+// run-pass
+const CONST_REF: &[u8; 3] = b"foo";
+
+trait Foo {
+ const CONST_REF_DEFAULT: &'static [u8; 3] = b"bar";
+ const CONST_REF: &'static [u8; 3];
+}
+
+impl Foo for i32 {
+ const CONST_REF: &'static [u8; 3] = b"jjj";
+}
+
+impl Foo for i64 {
+ const CONST_REF_DEFAULT: &'static [u8; 3] = b"ggg";
+ const CONST_REF: &'static [u8; 3] = b"fff";
+}
+
+// Check that (associated and free) const references are not mistaken for a
+// non-reference pattern (in which case they would be auto-dereferenced, making
+// the types mismatched).
+
+fn const_ref() -> bool {
+ let f = b"foo";
+ match f {
+ CONST_REF => true,
+ _ => false,
+ }
+}
+
+fn associated_const_ref() -> bool {
+ match (b"bar", b"jjj", b"ggg", b"fff") {
+ (i32::CONST_REF_DEFAULT, i32::CONST_REF, i64::CONST_REF_DEFAULT, i64::CONST_REF) => true,
+ _ => false,
+ }
+}
+
+pub fn main() {
+ assert!(const_ref());
+ assert!(associated_const_ref());
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs
new file mode 100644
index 000000000..52fbb90ed
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs
@@ -0,0 +1,45 @@
+// run-pass
+enum Wrapper {
+ Wrap(i32),
+}
+
+use Wrapper::Wrap;
+
+pub fn main() {
+ let Wrap(x) = &Wrap(3);
+ println!("{}", *x);
+
+ let Wrap(x) = &mut Wrap(3);
+ println!("{}", *x);
+
+ if let Some(x) = &Some(3) {
+ println!("{}", *x);
+ } else {
+ panic!();
+ }
+
+ if let Some(x) = &mut Some(3) {
+ println!("{}", *x);
+ } else {
+ panic!();
+ }
+
+ if let Some(x) = &mut Some(3) {
+ *x += 1;
+ } else {
+ panic!();
+ }
+
+ while let Some(x) = &Some(3) {
+ println!("{}", *x);
+ break;
+ }
+ while let Some(x) = &mut Some(3) {
+ println!("{}", *x);
+ break;
+ }
+ while let Some(x) = &mut Some(3) {
+ *x += 1;
+ break;
+ }
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs
new file mode 100644
index 000000000..a5a24a806
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs
@@ -0,0 +1,20 @@
+// run-pass
+pub fn main() {
+ let mut tups = vec![(0u8, 1u8)];
+
+ for (n, m) in &tups {
+ let _: &u8 = n;
+ let _: &u8 = m;
+ }
+
+ for (n, m) in &mut tups {
+ *n += 1;
+ *m += 2;
+ }
+
+ assert_eq!(tups, vec![(1u8, 3u8)]);
+
+ for (n, m) in tups {
+ println!("{} {}", m, n);
+ }
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs
new file mode 100644
index 000000000..0207f607b
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs
@@ -0,0 +1,249 @@
+// run-pass
+#![allow(unused_variables)]
+fn some_or_wildcard(r: &Option<i32>, b: &i32) {
+ let _: &i32 = match r {
+ Some(a) => a,
+ _ => b,
+ };
+}
+
+fn none_or_wildcard(r: &Option<i32>, b: &i32) {
+ let _: &i32 = match r {
+ None => b,
+ _ => b,
+ };
+}
+
+fn some_or_ref_none(r: &Option<i32>, b: &i32) {
+ let _: &i32 = match r {
+ Some(a) => a,
+ &None => b,
+ };
+}
+
+fn ref_some_or_none(r: &Option<i32>, b: &i32) {
+ let _: &i32 = match r {
+ &Some(ref a) => a,
+ None => b,
+ };
+}
+
+fn some_or_self(r: &Option<i32>) {
+ let _: &Option<i32> = match r {
+ Some(n) => {
+ let _: &i32 = n;
+ r
+ },
+ x => x,
+ };
+}
+
+fn multiple_deref(r: &&&&&Option<i32>) {
+ let _: i32 = match r {
+ Some(a) => *a,
+ None => 5,
+ };
+}
+
+fn match_with_or() {
+ // FIXME(tschottdorf): #44912.
+ //
+ // let x = &Some((3, 3));
+ // let _: &i32 = match x {
+ // Some((x, 3)) | &Some((ref x, 5)) => x,
+ // _ => &5i32,
+ // };
+}
+
+fn nested_mixed() {
+ match (&Some(5), &Some(6)) {
+ (Some(a), &Some(mut b)) => {
+ // Here, the `a` will be `&i32`, because in the first half of the tuple
+ // we hit a non-reference pattern and shift into `ref` mode.
+ //
+ // In the second half of the tuple there's no non-reference pattern,
+ // so `b` will be `i32` (bound with `move` mode). Moreover, `b` is
+ // mutable.
+ let _: &i32 = a;
+ b = 7;
+ let _: i32 = b;
+ },
+ _ => {},
+ };
+}
+
+fn nested_mixed_multiple_deref_1() {
+ let x = (1, &Some(5));
+ let y = &Some(x);
+ match y {
+ Some((a, Some(b))) => {
+ let _: &i32 = a;
+ let _: &i32 = b;
+ },
+ _ => {},
+ };
+}
+
+fn nested_mixed_multiple_deref_2() {
+ let x = &Some(5);
+ let y = &x;
+ match y {
+ Some(z) => {
+ let _: &i32 = z;
+ },
+ _ => {},
+ }
+}
+
+fn new_mutable_reference() {
+ let mut x = &mut Some(5);
+ match &mut x {
+ Some(y) => {
+ *y = 5;
+ },
+ None => { },
+ }
+
+ match &mut x {
+ Some(y) => {
+ println!("{}", *y);
+ },
+ None => {},
+ }
+}
+
+fn let_implicit_ref_binding() {
+ struct Foo(i32);
+
+ // Note that these rules apply to any pattern matching
+ // whether it be in a `match` or a `let`.
+ // For example, `x` here is a `ref` binding:
+ let Foo(x) = &Foo(3);
+ let _: &i32 = x;
+}
+
+fn explicit_mut_binding() {
+ match &Some(5i32) {
+ Some(mut n) => {
+ n += 1;
+ let _ = n;
+ }
+ None => {},
+ };
+
+ match &mut Some(5i32) {
+ Some(n) => {
+ *n += 1;
+ let _ = n;
+ }
+ None => {},
+ };
+
+ match &mut &mut Some(5i32) {
+ Some(n) => {
+ let _: &mut i32 = n;
+ }
+ None => {},
+ };
+}
+
+fn tuple_mut_and_mut_mut() {
+ match (Some(5i32), &Some(5i32)) {
+ (Some(n), Some(m)) => {
+ // `n` and `m` are bound as immutable references. Make new references from them to
+ // assert that.
+ let r = n;
+ let _ = r;
+ let q = m;
+ let _ = q;
+
+ // Assert the types. Note that we use `n` and `m` here which would fail had they been
+ // moved due to the assignments above.
+ let _: i32 = n;
+ let _: &i32 = m;
+ }
+ (_, _) => {},
+ };
+
+ match (&Some(5i32), &&Some(5i32)) {
+ (Some(n), Some(m)) => {
+ let _: &i32 = n;
+ let _: &i32 = m;
+ }
+ (_, _) => {},
+ };
+
+ match &mut &mut (Some(5i32), Some(5i32)) {
+ (Some(n), Some(m)) => {
+ // Dereferenced through &mut &mut, so a mutable binding results.
+ let _: &mut i32 = n;
+ let _: &mut i32 = m;
+ }
+ (_, _) => {},
+ };
+
+ match (&mut Some(5i32), &mut &mut Some(5i32)) {
+ (Some(n), Some(m)) => {
+ let _: &mut i32 = n;
+ let _: &mut i32 = m;
+ }
+ (_, _) => {},
+ };
+}
+
+fn min_mir_embedded_type() {
+ // The reduced invocation that an ICE was diagnosed with (was consuming
+ // adjustments in wrong order).
+ match (0u8, &&Some(5i32)) {
+ (_, Some(m)) => {
+ let _: &i32 = m;
+ }
+ (_, _) => {},
+ };
+}
+
+fn no_autoderef() {
+ // Binding.
+ let x = &3;
+ println!("{}", *x);
+
+ // Wildcard.
+ let _ = &3;
+
+ // Constant of generic type (string)
+ const Y: &'static str = "foo";
+ assert_eq!(0, match "foo" {
+ Y => 0,
+ _ => 1,
+ });
+
+ // Reference pattern.
+ let &x = &3;
+}
+
+pub fn main() {
+ let r: &Option<i32> = &Some(3);
+ let b = &4i32;
+
+ none_or_wildcard(r, b);
+ some_or_wildcard(r, b);
+ some_or_ref_none(r, b);
+ ref_some_or_none(r, b);
+
+ some_or_self(r);
+ multiple_deref(&&&&r);
+ match_with_or();
+
+ nested_mixed();
+ nested_mixed_multiple_deref_1();
+ nested_mixed_multiple_deref_2();
+
+ new_mutable_reference();
+ explicit_mut_binding();
+ tuple_mut_and_mut_mut();
+ min_mir_embedded_type();
+
+ let_implicit_ref_binding();
+
+ no_autoderef();
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs
new file mode 100644
index 000000000..937975359
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs
@@ -0,0 +1,34 @@
+// run-pass
+#![allow(dead_code)]
+fn with_u8() {
+ let s = 5u8;
+ let r = match &s {
+ 4 => false,
+ 5 => true,
+ _ => false,
+ };
+ assert!(r);
+}
+
+// A string literal isn't mistaken for a non-ref pattern (in which case we'd
+// deref `s` and mess things up).
+fn with_str() {
+ let s: &'static str = "abc";
+ match s {
+ "abc" => true,
+ _ => panic!(),
+ };
+}
+
+// Ditto with byte strings.
+fn with_bytes() {
+ let s: &'static [u8] = b"abc";
+ match s {
+ b"abc" => true,
+ _ => panic!(),
+ };
+}
+
+pub fn main() {
+ with_str();
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs
new file mode 100644
index 000000000..f8abd1b96
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs
@@ -0,0 +1,9 @@
+// run-pass
+pub fn main() {
+ let i = 5;
+ match &&&&i {
+ 1 ..= 3 => panic!(),
+ 4 ..= 8 => {},
+ _ => panic!(),
+ }
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs
new file mode 100644
index 000000000..b74e45c93
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs
@@ -0,0 +1,16 @@
+// run-pass
+fn foo<'a, 'b>(x: &'a &'b Option<u32>) -> &'a u32 {
+ let x: &'a &'a Option<u32> = x;
+ match x {
+ Some(r) => {
+ let _: &u32 = r;
+ r
+ },
+ &None => panic!(),
+ }
+}
+
+pub fn main() {
+ let x = Some(5);
+ foo(&&x);
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs
new file mode 100644
index 000000000..3b9d07610
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs
@@ -0,0 +1,14 @@
+// run-pass
+// Test that we "reset" the mode as we pass through a `&` pattern.
+//
+// cc #46688
+
+fn surprise(x: i32) {
+ assert_eq!(x, 2);
+}
+
+fn main() {
+ let x = &(1, &2);
+ let (_, &b) = x;
+ surprise(b);
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
new file mode 100644
index 000000000..33229a205
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+fn slice_pat() {
+ let sl: &[u8] = b"foo";
+
+ match sl {
+ [first, remainder @ ..] => {
+ let _: &u8 = first;
+ assert_eq!(first, &b'f');
+ assert_eq!(remainder, b"oo");
+ }
+ [] => panic!(),
+ }
+}
+
+fn slice_pat_omission() {
+ match &[0, 1, 2] {
+ [..] => {}
+ };
+}
+
+fn main() {
+ slice_pat();
+ slice_pat_omission();
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs
new file mode 100644
index 000000000..5a00e5b68
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs
@@ -0,0 +1,22 @@
+// run-pass
+#[derive(Debug, PartialEq)]
+struct Foo {
+ x: u8,
+}
+
+pub fn main() {
+ let mut foo = Foo {
+ x: 1,
+ };
+
+ match &mut foo {
+ Foo{x: n} => {
+ *n += 1;
+ },
+ };
+
+ assert_eq!(foo, Foo{x: 2});
+
+ let Foo{x: n} = &foo;
+ assert_eq!(*n, 2);
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs
new file mode 100644
index 000000000..0cf9ba1b4
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs
@@ -0,0 +1,19 @@
+// run-pass
+#![allow(dead_code)]
+enum Foo {
+ Bar(Option<i8>, (), (), Vec<i32>),
+ Baz,
+}
+
+pub fn main() {
+ let foo = Foo::Bar(Some(1), (), (), vec![2, 3]);
+
+ match &foo {
+ Foo::Baz => panic!(),
+ Foo::Bar(None, ..) => panic!(),
+ Foo::Bar(Some(n), .., v) => {
+ assert_eq!((*v).len(), 2);
+ assert_eq!(*n, 1);
+ }
+ }
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs
new file mode 100644
index 000000000..4c22aa2d7
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs
@@ -0,0 +1,12 @@
+// run-pass
+pub fn main() {
+ let foo = (Some(1), (), (), vec![2, 3]);
+
+ match &foo {
+ (Some(n), .., v) => {
+ assert_eq!((*v).len(), 2);
+ assert_eq!(*n, 1);
+ }
+ (None, (), (), ..) => panic!(),
+ }
+}