Skip to content

Commit e340996

Browse files
committed
Auto merge of #45409 - tamird:suggest-match-default-bindings, r=nikomatsakis
typeck: suggest use of match_default_bindings feature Fixes #45383. Updates #42640. r? @nikomatsakis cc @tschottdorf This needs a UI test, but thought I'd get some early feedback.
2 parents 5ce3d48 + 9844777 commit e340996

15 files changed

+74
-21
lines changed

src/librustc_typeck/check/_match.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
2323
use std::cmp;
2424
use syntax::ast;
2525
use syntax::codemap::Spanned;
26+
use syntax::feature_gate;
2627
use syntax::ptr::P;
2728
use syntax_pos::Span;
2829

@@ -68,7 +69,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
6869
PatKind::Binding(..) |
6970
PatKind::Ref(..) => false,
7071
};
71-
if is_non_ref_pat && tcx.sess.features.borrow().match_default_bindings {
72+
if is_non_ref_pat {
7273
debug!("pattern is non reference pattern");
7374
let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
7475

@@ -113,10 +114,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
113114
}
114115
};
115116
if pat_adjustments.len() > 0 {
116-
debug!("default binding mode is now {:?}", def_bm);
117-
self.inh.tables.borrow_mut()
118-
.pat_adjustments_mut()
119-
.insert(pat.hir_id, pat_adjustments);
117+
if tcx.sess.features.borrow().match_default_bindings {
118+
debug!("default binding mode is now {:?}", def_bm);
119+
self.inh.tables.borrow_mut()
120+
.pat_adjustments_mut()
121+
.insert(pat.hir_id, pat_adjustments);
122+
} else {
123+
let mut err = feature_gate::feature_err(
124+
&tcx.sess.parse_sess,
125+
"match_default_bindings",
126+
pat.span,
127+
feature_gate::GateIssue::Language,
128+
"non-reference pattern used to match a reference",
129+
);
130+
if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(pat.span) {
131+
err.span_suggestion(pat.span, "consider using", format!("&{}", &snippet));
132+
}
133+
err.emit();
134+
}
120135
}
121136
}
122137

@@ -325,8 +340,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
325340
if let Some(mut err) = err {
326341
if is_arg {
327342
if let PatKind::Binding(..) = inner.node {
328-
if let Ok(snippet) = self.sess().codemap()
329-
.span_to_snippet(pat.span)
343+
if let Ok(snippet) = tcx.sess.codemap()
344+
.span_to_snippet(pat.span)
330345
{
331346
err.help(&format!("did you mean `{}: &{}`?",
332347
&snippet[1..],

src/test/compile-fail/E0029.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn main() {
1717
//~| NOTE ranges require char or numeric types
1818
//~| NOTE start type: &'static str
1919
//~| NOTE end type: &'static str
20+
//~| ERROR non-reference pattern used to match a reference
2021
_ => {}
2122
}
2223
}

src/test/compile-fail/feature-gate-match_default_bindings.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
pub fn main() {
1212
match &Some(3) {
13-
Some(n) => {}, //~ ERROR mismatched types [E0308]
13+
Some(n) => {},
14+
//~^ ERROR non-reference pattern used to match a reference
1415
_ => panic!(),
1516
}
1617
}

src/test/compile-fail/issue-16338.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ struct Slice<T> {
1616
fn main() {
1717
let Slice { data: data, len: len } = "foo";
1818
//~^ ERROR mismatched types
19-
//~| expected type `&str`
2019
//~| found type `Slice<_>`
21-
//~| expected &str, found struct `Slice`
20+
//~| ERROR non-reference pattern used to match a reference
2221
}

src/test/compile-fail/issue-20261.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
fn main() {
1212
// NB: this (almost) typechecks when default binding modes are enabled.
13-
for (ref i,) in [].iter() { //~ ERROR mismatched types [E0308]
13+
for (ref i,) in [].iter() {
14+
//~^ ERROR non-reference pattern used to match a reference
1415
i.clone();
1516
}
1617
}

src/test/compile-fail/keyword-false-as-identifier.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
// except according to those terms.
1010

1111
fn main() {
12-
let false = "foo"; //~ error: mismatched types
12+
let false = 22; //~ error: mismatched types
1313
}

src/test/compile-fail/keyword-self-as-identifier.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
// except according to those terms.
1010

1111
fn main() {
12-
let Self = "foo"; //~ ERROR cannot find unit struct/variant or constant `Self` in this scope
12+
let Self = 22; //~ ERROR cannot find unit struct/variant or constant `Self` in this scope
1313
}

src/test/compile-fail/keyword-super-as-identifier.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
// except according to those terms.
1010

1111
fn main() {
12-
let super = "foo"; //~ ERROR failed to resolve. There are too many initial `super`s
12+
let super = 22; //~ ERROR failed to resolve. There are too many initial `super`s
1313
}

src/test/compile-fail/keyword-true-as-identifier.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
// except according to those terms.
1010

1111
fn main() {
12-
let true = "foo"; //~ error: mismatched types
12+
let true = 22; //~ error: mismatched types
1313
}

src/test/compile-fail/match-range-fail.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ fn main() {
1515
//~^^ ERROR only char and numeric types are allowed in range
1616
//~| start type: &'static str
1717
//~| end type: &'static str
18+
//~| ERROR non-reference pattern used to match a reference
1819

1920
match "wow" {
2021
10 ... "what" => ()
2122
};
2223
//~^^ ERROR only char and numeric types are allowed in range
2324
//~| start type: {integer}
2425
//~| end type: &'static str
26+
//~| ERROR non-reference pattern used to match a reference
2527

2628
match 5 {
2729
'c' ... 100 => { }

0 commit comments

Comments
 (0)