typeck: suggest use of match_default_bindings feature
Fixes #45383. Updates #42640.
This commit is contained in:
parent
f0fe716dbc
commit
9844777a50
15 changed files with 74 additions and 21 deletions
|
|
@ -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..],
|
||||
|
|
|
|||
|
|
@ -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
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@
|
|||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
let false = "foo"; //~ error: mismatched types
|
||||
let false = 22; //~ error: mismatched types
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@
|
|||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
let true = "foo"; //~ error: mismatched types
|
||||
let true = 22; //~ error: mismatched types
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 => { }
|
||||
|
|
|
|||
|
|
@ -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] {
|
||||
|
|
|
|||
|
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
15
src/test/ui/rfc-2005-default-binding-mode/suggestion.rs
Normal file
15
src/test/ui/rfc-2005-default-binding-mode/suggestion.rs
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
10
src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
Normal file
10
src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
Normal file
|
|
@ -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
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue