Skip to content

Commit

Permalink
Auto merge of #49394 - cramertj:stable-match-bindings, r=nikomatsakis
Browse files Browse the repository at this point in the history
Stabilize match_default_bindings

This includes a submodule update to rustfmt
in order to allow a stable feature declaration.

r? @nikomatsakis

cc #42640

Many of the tests this PR touches are merely testing the current lack of desired future behavior around #44849 and #44848 (cc @tschottdorf). I noticed the bullets for those items were checked on the tracking issue-- I've unchecked them, as they don't appear to have been completed and I don't see any comments indicating that we don't want to pursue them further. Still, I think it's fine to stabilize the current behavior, as I think expanding it in the future should be backwards-compatible.
  • Loading branch information
bors committed Mar 28, 2018
2 parents d87c19d + 3c65f53 commit 1169541
Show file tree
Hide file tree
Showing 56 changed files with 55 additions and 389 deletions.
48 changes: 24 additions & 24 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

59 changes: 0 additions & 59 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,65 +887,6 @@ foo(3_i8);
// therefore the type-checker complains with this error code.
```
Here is a more subtle instance of the same problem, that can
arise with for-loops in Rust:
```compile_fail
let vs: Vec<i32> = vec![1, 2, 3, 4];
for v in &vs {
match v {
1 => {},
_ => {},
}
}
```
The above fails because of an analogous type mismatch,
though may be harder to see. Again, here are some
explanatory comments for the same example:
```compile_fail
{
let vs = vec![1, 2, 3, 4];
// `for`-loops use a protocol based on the `Iterator`
// trait. Each item yielded in a `for` loop has the
// type `Iterator::Item` -- that is, `Item` is the
// associated type of the concrete iterator impl.
for v in &vs {
// ~ ~~~
// | |
// | We borrow `vs`, iterating over a sequence of
// | *references* of type `&Elem` (where `Elem` is
// | vector's element type). Thus, the associated
// | type `Item` must be a reference `&`-type ...
// |
// ... and `v` has the type `Iterator::Item`, as dictated by
// the `for`-loop protocol ...
match v {
1 => {}
// ~
// |
// ... but *here*, `v` is forced to have some integral type;
// only types like `u8`,`i8`,`u16`,`i16`, et cetera can
// match the pattern `1` ...
_ => {}
}
// ... therefore, the compiler complains, because it sees
// an attempt to solve the equations
// `some integral-type` = type-of-`v`
// = `Iterator::Item`
// = `&Elem` (i.e. `some reference type`)
//
// which cannot possibly all be true.
}
}
```
To avoid those issues, you have to make the types match correctly.
So we can fix the previous examples like this:
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
#![cfg_attr(stage0, feature(i128_type, i128))]
#![cfg_attr(stage0, feature(inclusive_range_syntax))]
#![cfg_attr(windows, feature(libc))]
#![feature(match_default_bindings)]
#![cfg_attr(stage0, feature(match_default_bindings))]
#![feature(macro_lifetime_matcher)]
#![feature(macro_vis_matcher)]
#![feature(exhaustive_patterns)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_borrowck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#![allow(non_camel_case_types)]

#![feature(from_ref)]
#![feature(match_default_bindings)]
#![cfg_attr(stage0, feature(match_default_bindings))]
#![feature(quote)]

#[macro_use] extern crate log;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![cfg_attr(stage0, feature(i128_type))]
#![cfg_attr(stage0, feature(inclusive_range_syntax))]
#![feature(macro_vis_matcher)]
#![feature(match_default_bindings)]
#![cfg_attr(stage0, feature(match_default_bindings))]
#![feature(exhaustive_patterns)]
#![feature(range_contains)]
#![feature(rustc_diagnostic_macros)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_traits/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#![deny(warnings)]

#![feature(crate_visibility_modifier)]
#![feature(match_default_bindings)]
#![cfg_attr(stage0, feature(match_default_bindings))]
#![feature(underscore_lifetimes)]

#[macro_use]
Expand Down
41 changes: 4 additions & 37 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ 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 @@ -114,42 +113,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
};
if pat_adjustments.len() > 0 {
if tcx.features().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 ref_sp = pat.span;
let mut id = pat.id;
loop { // make span include all enclosing `&` to avoid confusing diag output
id = tcx.hir.get_parent_node(id);
let node = tcx.hir.find(id);
if let Some(hir::map::NodePat(pat)) = node {
if let hir::PatKind::Ref(..) = pat.node {
ref_sp = pat.span;
} else {
break;
}
} else {
break;
}
}
let sp = ref_sp.to(pat.span);
let mut err = feature_gate::feature_err(
&tcx.sess.parse_sess,
"match_default_bindings",
sp,
feature_gate::GateIssue::Language,
"non-reference pattern used to match a reference",
);
if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(sp) {
err.span_suggestion(sp,
"consider using a reference",
format!("&{}", &snippet));
}
err.emit();
}
debug!("default binding mode is now {:?}", def_bm);
self.inh.tables.borrow_mut()
.pat_adjustments_mut()
.insert(pat.hir_id, pat_adjustments);
}
} else if let PatKind::Ref(..) = pat.node {
// When you encounter a `&pat` pattern, reset to "by
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ This API is completely unstable and subject to change.
#![cfg_attr(stage0, feature(copy_closures, clone_closures))]
#![feature(crate_visibility_modifier)]
#![feature(from_ref)]
#![feature(match_default_bindings)]
#![cfg_attr(stage0, feature(match_default_bindings))]
#![feature(exhaustive_patterns)]
#![feature(option_filter)]
#![feature(quote)]
Expand Down
5 changes: 2 additions & 3 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,6 @@ declare_features! (
// allow `'_` placeholder lifetimes
(active, underscore_lifetimes, "1.22.0", Some(44524), None),

// Default match binding modes (RFC 2005)
(active, match_default_bindings, "1.22.0", Some(42640), None),

// Trait object syntax with `dyn` prefix
(active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)),

Expand Down Expand Up @@ -563,6 +560,8 @@ declare_features! (
(accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
// The `i128` type
(accepted, i128_type, "1.26.0", Some(35118), None),
// Default match binding modes (RFC 2005)
(accepted, match_default_bindings, "1.26.0", Some(42640), None),
);

// If you change this, please modify src/doc/unstable-book as well. You must
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#![feature(unicode)]
#![feature(rustc_diagnostic_macros)]
#![feature(match_default_bindings)]
#![cfg_attr(stage0, feature(match_default_bindings))]
#![feature(non_exhaustive)]
#![cfg_attr(stage0, feature(i128_type))]
#![feature(const_atomic_usize_new)]
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-16338.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,4 @@ fn main() {
let Slice { data: data, len: len } = "foo";
//~^ ERROR mismatched types
//~| found type `Slice<_>`
//~| ERROR non-reference pattern used to match a reference
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-20261.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
fn main() {
// NB: this (almost) typechecks when default binding modes are enabled.
for (ref i,) in [].iter() {
//~^ ERROR non-reference pattern used to match a reference
i.clone();
//~^ ERROR type annotations needed
}
}
2 changes: 0 additions & 2 deletions src/test/compile-fail/match-range-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ 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
Loading

0 comments on commit 1169541

Please sign in to comment.