about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTamir Duberstein <tamird@gmail.com>2017-10-20 08:59:55 -0400
committerTamir Duberstein <tamird@gmail.com>2017-10-30 19:09:23 -0400
commit9844777a508203b8faf8c09c3ec1a2023022da9b (patch)
tree47659cad6d3ec175930420fd1a77a83324023dc6 /src
parentf0fe716dbcbf2363ab8f929325d32a17e51039d0 (diff)
downloadrust-9844777a508203b8faf8c09c3ec1a2023022da9b.tar.gz
rust-9844777a508203b8faf8c09c3ec1a2023022da9b.zip
typeck: suggest use of match_default_bindings feature
Fixes #45383.
Updates #42640.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/_match.rs29
-rw-r--r--src/test/compile-fail/E0029.rs1
-rw-r--r--src/test/compile-fail/feature-gate-match_default_bindings.rs3
-rw-r--r--src/test/compile-fail/issue-16338.rs3
-rw-r--r--src/test/compile-fail/issue-20261.rs3
-rw-r--r--src/test/compile-fail/keyword-false-as-identifier.rs2
-rw-r--r--src/test/compile-fail/keyword-self-as-identifier.rs2
-rw-r--r--src/test/compile-fail/keyword-super-as-identifier.rs2
-rw-r--r--src/test/compile-fail/keyword-true-as-identifier.rs2
-rw-r--r--src/test/compile-fail/match-range-fail.rs2
-rw-r--r--src/test/compile-fail/match-vec-mismatch.rs2
-rw-r--r--src/test/compile-fail/pat-slice-old-style.rs5
-rw-r--r--src/test/ui/mismatched_types/closure-arg-count.stderr14
-rw-r--r--src/test/ui/rfc-2005-default-binding-mode/suggestion.rs15
-rw-r--r--src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr10
15 files changed, 74 insertions, 21 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index ab8994bcae2..e25f7d79668 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -23,6 +23,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::cmp;
 use syntax::ast;
 use syntax::codemap::Spanned;
+use syntax::feature_gate;
 use syntax::ptr::P;
 use syntax_pos::Span;
 
@@ -68,7 +69,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             PatKind::Binding(..) |
             PatKind::Ref(..) => false,
         };
-        if is_non_ref_pat && tcx.sess.features.borrow().match_default_bindings {
+        if is_non_ref_pat {
             debug!("pattern is non reference pattern");
             let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
 
@@ -113,10 +114,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }
             };
             if pat_adjustments.len() > 0 {
-                debug!("default binding mode is now {:?}", def_bm);
-                self.inh.tables.borrow_mut()
-                    .pat_adjustments_mut()
-                    .insert(pat.hir_id, pat_adjustments);
+                if tcx.sess.features.borrow().match_default_bindings {
+                    debug!("default binding mode is now {:?}", def_bm);
+                    self.inh.tables.borrow_mut()
+                        .pat_adjustments_mut()
+                        .insert(pat.hir_id, pat_adjustments);
+                } else {
+                    let mut err = feature_gate::feature_err(
+                        &tcx.sess.parse_sess,
+                        "match_default_bindings",
+                        pat.span,
+                        feature_gate::GateIssue::Language,
+                        "non-reference pattern used to match a reference",
+                    );
+                    if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(pat.span) {
+                        err.span_suggestion(pat.span, "consider using", format!("&{}", &snippet));
+                    }
+                    err.emit();
+                }
             }
         }
 
@@ -325,8 +340,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             if let Some(mut err) = err {
                                 if is_arg {
                                     if let PatKind::Binding(..) = inner.node {
-                                        if let Ok(snippet) = self.sess().codemap()
-                                                                        .span_to_snippet(pat.span)
+                                        if let Ok(snippet) = tcx.sess.codemap()
+                                                                     .span_to_snippet(pat.span)
                                         {
                                             err.help(&format!("did you mean `{}: &{}`?",
                                                               &snippet[1..],
diff --git a/src/test/compile-fail/E0029.rs b/src/test/compile-fail/E0029.rs
index ec84e2a3f8a..e43290bb154 100644
--- a/src/test/compile-fail/E0029.rs
+++ b/src/test/compile-fail/E0029.rs
@@ -17,6 +17,7 @@ fn main() {
         //~| NOTE ranges require char or numeric types
         //~| NOTE start type: &'static str
         //~| NOTE end type: &'static str
+        //~| ERROR non-reference pattern used to match a reference
         _ => {}
     }
 }
diff --git a/src/test/compile-fail/feature-gate-match_default_bindings.rs b/src/test/compile-fail/feature-gate-match_default_bindings.rs
index 2b3bf94eadc..4ee2c1e2936 100644
--- a/src/test/compile-fail/feature-gate-match_default_bindings.rs
+++ b/src/test/compile-fail/feature-gate-match_default_bindings.rs
@@ -10,7 +10,8 @@
 
 pub fn main() {
     match &Some(3) {
-        Some(n) => {}, //~ ERROR mismatched types [E0308]
+        Some(n) => {},
+        //~^ ERROR non-reference pattern used to match a reference
         _ => panic!(),
     }
 }
diff --git a/src/test/compile-fail/issue-16338.rs b/src/test/compile-fail/issue-16338.rs
index a4517e60d66..6fdf8802e38 100644
--- a/src/test/compile-fail/issue-16338.rs
+++ b/src/test/compile-fail/issue-16338.rs
@@ -16,7 +16,6 @@ struct Slice<T> {
 fn main() {
     let Slice { data: data, len: len } = "foo";
     //~^ ERROR mismatched types
-    //~| expected type `&str`
     //~| found type `Slice<_>`
-    //~| expected &str, found struct `Slice`
+    //~| ERROR non-reference pattern used to match a reference
 }
diff --git a/src/test/compile-fail/issue-20261.rs b/src/test/compile-fail/issue-20261.rs
index 7b5e61380f2..092aaa76955 100644
--- a/src/test/compile-fail/issue-20261.rs
+++ b/src/test/compile-fail/issue-20261.rs
@@ -10,7 +10,8 @@
 
 fn main() {
     // NB: this (almost) typechecks when default binding modes are enabled.
-    for (ref i,) in [].iter() { //~ ERROR mismatched types [E0308]
+    for (ref i,) in [].iter() {
+        //~^ ERROR non-reference pattern used to match a reference
         i.clone();
     }
 }
diff --git a/src/test/compile-fail/keyword-false-as-identifier.rs b/src/test/compile-fail/keyword-false-as-identifier.rs
index e8af94f16b1..f246d6e75df 100644
--- a/src/test/compile-fail/keyword-false-as-identifier.rs
+++ b/src/test/compile-fail/keyword-false-as-identifier.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let false = "foo"; //~ error: mismatched types
+    let false = 22; //~ error: mismatched types
 }
diff --git a/src/test/compile-fail/keyword-self-as-identifier.rs b/src/test/compile-fail/keyword-self-as-identifier.rs
index f01aab92356..b50fc68bed6 100644
--- a/src/test/compile-fail/keyword-self-as-identifier.rs
+++ b/src/test/compile-fail/keyword-self-as-identifier.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let Self = "foo"; //~ ERROR cannot find unit struct/variant or constant `Self` in this scope
+    let Self = 22; //~ ERROR cannot find unit struct/variant or constant `Self` in this scope
 }
diff --git a/src/test/compile-fail/keyword-super-as-identifier.rs b/src/test/compile-fail/keyword-super-as-identifier.rs
index 62649ba8a0f..54dac771f01 100644
--- a/src/test/compile-fail/keyword-super-as-identifier.rs
+++ b/src/test/compile-fail/keyword-super-as-identifier.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let super = "foo"; //~ ERROR failed to resolve. There are too many initial `super`s
+    let super = 22; //~ ERROR failed to resolve. There are too many initial `super`s
 }
diff --git a/src/test/compile-fail/keyword-true-as-identifier.rs b/src/test/compile-fail/keyword-true-as-identifier.rs
index 90414fa912d..b09d09db560 100644
--- a/src/test/compile-fail/keyword-true-as-identifier.rs
+++ b/src/test/compile-fail/keyword-true-as-identifier.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let true = "foo"; //~ error: mismatched types
+    let true = 22; //~ error: mismatched types
 }
diff --git a/src/test/compile-fail/match-range-fail.rs b/src/test/compile-fail/match-range-fail.rs
index f89b3e39390..355ff6404ce 100644
--- a/src/test/compile-fail/match-range-fail.rs
+++ b/src/test/compile-fail/match-range-fail.rs
@@ -15,6 +15,7 @@ fn main() {
     //~^^ ERROR only char and numeric types are allowed in range
     //~| start type: &'static str
     //~| end type: &'static str
+    //~| ERROR non-reference pattern used to match a reference
 
     match "wow" {
         10 ... "what" => ()
@@ -22,6 +23,7 @@ fn main() {
     //~^^ ERROR only char and numeric types are allowed in range
     //~| start type: {integer}
     //~| end type: &'static str
+    //~| ERROR non-reference pattern used to match a reference
 
     match 5 {
         'c' ... 100 => { }
diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs
index d72ec8ba408..fed68da0068 100644
--- a/src/test/compile-fail/match-vec-mismatch.rs
+++ b/src/test/compile-fail/match-vec-mismatch.rs
@@ -19,7 +19,7 @@ fn main() {
 
     // Note that this one works with default binding modes.
     match &[0, 1, 2] {
-        [..] => {} //~ ERROR expected an array or slice, found `&[{integer}; 3]` [E0529]
+        [..] => {} //~ ERROR non-reference pattern used to match a reference
     };
 
     match &[0, 1, 2] {
diff --git a/src/test/compile-fail/pat-slice-old-style.rs b/src/test/compile-fail/pat-slice-old-style.rs
index 54028ffa63f..d49ce56ccf6 100644
--- a/src/test/compile-fail/pat-slice-old-style.rs
+++ b/src/test/compile-fail/pat-slice-old-style.rs
@@ -17,8 +17,9 @@ fn slice_pat(x: &[u8]) {
     // OLD!
     match x {
         [a, b..] => {},
-        //~^ ERROR expected an array or slice, found `&[u8]`
-        //~| HELP the semantics of slice patterns changed recently; see issue #23121
+        //~^ ERROR non-reference pattern used to match a reference
+        //~| HELP add #![feature(match_default_bindings)] to the crate attributes to enable
+        //~| HELP consider using
         _ => panic!(),
     }
 }
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index 9d4ac630546..ca06825d0ad 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -14,13 +14,21 @@ error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument
    |               |
    |               expected closure that takes 2 arguments
 
+error: non-reference pattern used to match a reference (see issue #42640)
+  --> $DIR/closure-arg-count.rs:17:24
+   |
+17 |     [1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
+   |                        ^^^^^^^^^^^^^^^ help: consider using: `&(tuple, tuple2)`
+   |
+   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
+
 error[E0308]: mismatched types
   --> $DIR/closure-arg-count.rs:17:24
    |
 17 |     [1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
-   |                        ^^^^^^^^^^^^^^^ expected &{integer}, found tuple
+   |                        ^^^^^^^^^^^^^^^ expected integral variable, found tuple
    |
-   = note: expected type `&{integer}`
+   = note: expected type `{integer}`
               found type `(_, _)`
 
 error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument
@@ -65,5 +73,5 @@ error[E0593]: closure is expected to take a single 2-tuple as argument, but it t
    |                                                     |
    |                                                     expected closure that takes a single 2-tuple as argument
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs b/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs
new file mode 100644
index 00000000000..52ff817dff4
--- /dev/null
+++ b/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    if let Some(y) = &Some(22) {
+      println!("{}", y);
+    }
+}
diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
new file mode 100644
index 00000000000..0594f865f32
--- /dev/null
+++ b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
@@ -0,0 +1,10 @@
+error: non-reference pattern used to match a reference (see issue #42640)
+  --> $DIR/suggestion.rs:12:12
+   |
+12 |     if let Some(y) = &Some(22) {
+   |            ^^^^^^^ help: consider using: `&Some(y)`
+   |
+   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
+
+error: aborting due to previous error
+