Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typeck: suggest use of match_default_bindings feature #45409

Merged
merged 1 commit into from
Nov 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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();
}
}
}

Expand Down Expand Up @@ -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..],
Expand Down
1 change: 1 addition & 0 deletions src/test/compile-fail/E0029.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
_ => {}
}
}
3 changes: 2 additions & 1 deletion src/test/compile-fail/feature-gate-match_default_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
}
}
3 changes: 1 addition & 2 deletions src/test/compile-fail/issue-16338.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
3 changes: 2 additions & 1 deletion src/test/compile-fail/issue-20261.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/keyword-false-as-identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
// except according to those terms.

fn main() {
let false = "foo"; //~ error: mismatched types
let false = 22; //~ error: mismatched types
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/keyword-self-as-identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/keyword-super-as-identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/keyword-true-as-identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
// except according to those terms.

fn main() {
let true = "foo"; //~ error: mismatched types
let true = 22; //~ error: mismatched types
}
2 changes: 2 additions & 0 deletions src/test/compile-fail/match-range-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ 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" => ()
};
//~^^ 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 => { }
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/match-vec-mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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] {
Expand Down
5 changes: 3 additions & 2 deletions src/test/compile-fail/pat-slice-old-style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/test/ui/mismatched_types/closure-arg-count.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 changes: 15 additions & 0 deletions src/test/ui/rfc-2005-default-binding-mode/suggestion.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
Original file line number Diff line number Diff line change
@@ -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