Auto merge of #106409 - matthiaskrgr:rollup-b58z1hz, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #104552 (warn newer available version of the x tool) - #105681 (some fixes/improvements to mir::visit module) - #106005 (Test the borrowck behavior of if-let guards) - #106356 (clean: Remove `ctor_kind` from `VariantStruct`.) - #106365 (Grammar : Missing "is" in format specifier diagnostic) - #106388 (rustdoc: remove legacy box-sizing CSS) - #106392 (`has_overflow` only if value is *not* within limit) - #106402 (Fix dupe word typos) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
21
Cargo.lock
21
Cargo.lock
@@ -4805,18 +4805,18 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.12"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
|
||||
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.147"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@@ -4833,9 +4833,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.147"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -4853,9 +4853,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.85"
|
||||
version = "1.0.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
||||
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
@@ -5133,9 +5133,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.102"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5309,6 +5309,7 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"miropt-test-tools",
|
||||
"regex",
|
||||
"semver",
|
||||
"termcolor",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
@@ -638,7 +638,7 @@ fn report_missing_placeholders(
|
||||
if show_doc_note {
|
||||
diag.note(concat!(
|
||||
stringify!($kind),
|
||||
" formatting not supported; see the documentation for `std::fmt`",
|
||||
" formatting is not supported; see the documentation for `std::fmt`",
|
||||
));
|
||||
}
|
||||
if suggestions.len() > 0 {
|
||||
|
||||
@@ -1392,7 +1392,7 @@ declare_lint! {
|
||||
///
|
||||
/// The attribute must be used in conjunction with the
|
||||
/// [`closure_track_caller` feature flag]. Otherwise, the `#[track_caller]`
|
||||
/// annotation will function as as no-op.
|
||||
/// annotation will function as a no-op.
|
||||
///
|
||||
/// [`closure_track_caller` feature flag]: https://doc.rust-lang.org/beta/unstable-book/language-features/closure-track-caller.html
|
||||
UNGATED_ASYNC_FN_TRACK_CALLER,
|
||||
|
||||
@@ -29,7 +29,7 @@ macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
|
||||
$cx.pass.$f(&$cx.context, $($args),*);
|
||||
}) }
|
||||
|
||||
/// Implements the AST traversal for early lint passes. `T` provides the the
|
||||
/// Implements the AST traversal for early lint passes. `T` provides the
|
||||
/// `check_*` methods.
|
||||
pub struct EarlyContextAndPass<'a, T: EarlyLintPass> {
|
||||
context: EarlyContext<'a>,
|
||||
|
||||
@@ -40,7 +40,7 @@ macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
|
||||
$cx.pass.$f(&$cx.context, $($args),*);
|
||||
}) }
|
||||
|
||||
/// Implements the AST traversal for late lint passes. `T` provides the the
|
||||
/// Implements the AST traversal for late lint passes. `T` provides the
|
||||
/// `check_*` methods.
|
||||
pub struct LateContextAndPass<'tcx, T: LateLintPass<'tcx>> {
|
||||
context: LateContext<'tcx>,
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
//! ## Overview
|
||||
//!
|
||||
//! There are two visitors, one for immutable and one for mutable references,
|
||||
//! but both are generated by the following macro. The code is written according
|
||||
//! to the following conventions:
|
||||
//! but both are generated by the `make_mir_visitor` macro.
|
||||
//! The code is written according to the following conventions:
|
||||
//!
|
||||
//! - introduce a `visit_foo` and a `super_foo` method for every MIR type
|
||||
//! - `visit_foo`, by default, calls `super_foo`
|
||||
//! - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
|
||||
//!
|
||||
//! This allows you as a user to override `visit_foo` for types are
|
||||
//! interested in, and invoke (within that method) call
|
||||
//! This allows you to override `visit_foo` for types you are
|
||||
//! interested in, and invoke (within that method call)
|
||||
//! `self.super_foo` to get the default behavior. Just as in an OO
|
||||
//! language, you should never call `super` methods ordinarily except
|
||||
//! in that circumstance.
|
||||
|
||||
@@ -36,7 +36,7 @@ impl OverflowData {
|
||||
|
||||
#[inline]
|
||||
pub(super) fn has_overflow(&self, depth: usize) -> bool {
|
||||
self.current_limit.value_within_limit(depth + self.additional_depth)
|
||||
!self.current_limit.value_within_limit(depth + self.additional_depth)
|
||||
}
|
||||
|
||||
/// Updating the current limit when hitting overflow.
|
||||
|
||||
@@ -934,8 +934,7 @@ def main():
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'help':
|
||||
sys.argv = [sys.argv[0], '-h'] + sys.argv[2:]
|
||||
|
||||
help_triggered = (
|
||||
'-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1)
|
||||
help_triggered = len(sys.argv) == 1 or any(x in ["-h", "--help", "--version"] for x in sys.argv)
|
||||
try:
|
||||
bootstrap(help_triggered)
|
||||
if not help_triggered:
|
||||
|
||||
@@ -1960,7 +1960,6 @@ pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocCont
|
||||
variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
|
||||
),
|
||||
None => VariantKind::Struct(VariantStruct {
|
||||
ctor_kind: None,
|
||||
fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
|
||||
}),
|
||||
};
|
||||
@@ -1985,7 +1984,6 @@ fn clean_variant_data<'tcx>(
|
||||
|
||||
let kind = match variant {
|
||||
hir::VariantData::Struct(..) => VariantKind::Struct(VariantStruct {
|
||||
ctor_kind: None,
|
||||
fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(),
|
||||
}),
|
||||
hir::VariantData::Tuple(..) => {
|
||||
|
||||
@@ -2111,7 +2111,6 @@ impl Union {
|
||||
/// only as a variant in an enum.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct VariantStruct {
|
||||
pub(crate) ctor_kind: Option<CtorKind>,
|
||||
pub(crate) fields: Vec<Item>,
|
||||
}
|
||||
|
||||
|
||||
@@ -1229,16 +1229,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
|
||||
w.write_str(")");
|
||||
}
|
||||
clean::VariantKind::Struct(ref s) => {
|
||||
render_struct(
|
||||
w,
|
||||
v,
|
||||
None,
|
||||
s.ctor_kind,
|
||||
&s.fields,
|
||||
" ",
|
||||
false,
|
||||
cx,
|
||||
);
|
||||
render_struct(w, v, None, None, &s.fields, " ", false, cx);
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
|
||||
@@ -76,8 +76,6 @@
|
||||
}
|
||||
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
@@ -410,7 +410,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
|
||||
/// This method will create a new module and push it onto the "modules stack" then call
|
||||
/// `visit_mod_contents`. Once done, it'll remove it from the "modules stack" and instead
|
||||
/// add into into the list of modules of the current module.
|
||||
/// add into the list of modules of the current module.
|
||||
fn enter_mod(&mut self, id: hir::HirId, m: &'tcx hir::Mod<'tcx>, name: Symbol) {
|
||||
self.modules.push(Module::new(name, id, m.spans.inner_span));
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn foo(_:String) {}
|
||||
|
||||
fn main()
|
||||
@@ -8,4 +10,11 @@ fn main()
|
||||
Some(_) => {}
|
||||
None => { foo(my_str); } //~ ERROR [E0382]
|
||||
}
|
||||
|
||||
let my_str = "hello".to_owned();
|
||||
match Some(42) {
|
||||
Some(_) if let Some(()) = { drop(my_str); None } => {}
|
||||
Some(_) => {}
|
||||
None => { foo(my_str); } //~ ERROR [E0382]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0382]: use of moved value: `my_str`
|
||||
--> $DIR/borrowck-drop-from-guard.rs:9:23
|
||||
--> $DIR/borrowck-drop-from-guard.rs:11:23
|
||||
|
|
||||
LL | let my_str = "hello".to_owned();
|
||||
| ------ move occurs because `my_str` has type `String`, which does not implement the `Copy` trait
|
||||
@@ -15,6 +15,23 @@ help: consider cloning the value if the performance cost is acceptable
|
||||
LL | Some(_) if { drop(my_str.clone()); false } => {}
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0382]: use of moved value: `my_str`
|
||||
--> $DIR/borrowck-drop-from-guard.rs:18:23
|
||||
|
|
||||
LL | let my_str = "hello".to_owned();
|
||||
| ------ move occurs because `my_str` has type `String`, which does not implement the `Copy` trait
|
||||
LL | match Some(42) {
|
||||
LL | Some(_) if let Some(()) = { drop(my_str); None } => {}
|
||||
| ------ value moved here
|
||||
LL | Some(_) => {}
|
||||
LL | None => { foo(my_str); }
|
||||
| ^^^^^^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | Some(_) if let Some(()) = { drop(my_str.clone()); None } => {}
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
enum Enum<'a> {
|
||||
A(&'a isize),
|
||||
B(bool),
|
||||
}
|
||||
|
||||
fn foo() -> isize {
|
||||
fn if_guard() -> isize {
|
||||
let mut n = 42;
|
||||
let mut x = Enum::A(&mut n);
|
||||
match x {
|
||||
@@ -16,6 +18,17 @@ fn foo() -> isize {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo();
|
||||
fn if_let_guard() -> isize {
|
||||
let mut n = 42;
|
||||
let mut x = Enum::A(&mut n);
|
||||
match x {
|
||||
Enum::A(_) if let Some(()) = { x = Enum::B(false); None } => 1,
|
||||
//~^ ERROR cannot assign `x` in match guard
|
||||
Enum::A(_) if let Some(()) = { let y = &mut x; *y = Enum::B(false); None } => 1,
|
||||
//~^ ERROR cannot mutably borrow `x` in match guard
|
||||
Enum::A(p) => *p,
|
||||
Enum::B(_) => 2,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0510]: cannot assign `x` in match guard
|
||||
--> $DIR/borrowck-mutate-in-guard.rs:10:25
|
||||
--> $DIR/borrowck-mutate-in-guard.rs:12:25
|
||||
|
|
||||
LL | match x {
|
||||
| - value is immutable in match guard
|
||||
@@ -7,7 +7,7 @@ LL | Enum::A(_) if { x = Enum::B(false); false } => 1,
|
||||
| ^^^^^^^^^^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot mutably borrow `x` in match guard
|
||||
--> $DIR/borrowck-mutate-in-guard.rs:12:33
|
||||
--> $DIR/borrowck-mutate-in-guard.rs:14:33
|
||||
|
|
||||
LL | match x {
|
||||
| - value is immutable in match guard
|
||||
@@ -15,6 +15,23 @@ LL | match x {
|
||||
LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
|
||||
| ^^^^^^ cannot mutably borrow
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0510]: cannot assign `x` in match guard
|
||||
--> $DIR/borrowck-mutate-in-guard.rs:25:40
|
||||
|
|
||||
LL | match x {
|
||||
| - value is immutable in match guard
|
||||
LL | Enum::A(_) if let Some(()) = { x = Enum::B(false); None } => 1,
|
||||
| ^^^^^^^^^^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot mutably borrow `x` in match guard
|
||||
--> $DIR/borrowck-mutate-in-guard.rs:27:48
|
||||
|
|
||||
LL | match x {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | Enum::A(_) if let Some(()) = { let y = &mut x; *y = Enum::B(false); None } => 1,
|
||||
| ^^^^^^ cannot mutably borrow
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0510`.
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
let a = Some("...".to_owned());
|
||||
let b = match a {
|
||||
Some(_) if { drop(a); false } => None,
|
||||
x => x, //~ ERROR use of moved value: `a`
|
||||
};
|
||||
println!("{:?}", b);
|
||||
|
||||
let a = Some("...".to_owned());
|
||||
let b = match a {
|
||||
Some(_) if let Some(()) = { drop(a); None } => None,
|
||||
x => x, //~ ERROR use of moved value: `a`
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0382]: use of moved value: `a`
|
||||
--> $DIR/issue-31287-drop-in-guard.rs:5:9
|
||||
--> $DIR/issue-31287-drop-in-guard.rs:7:9
|
||||
|
|
||||
LL | let a = Some("...".to_owned());
|
||||
| - move occurs because `a` has type `Option<String>`, which does not implement the `Copy` trait
|
||||
@@ -14,6 +14,22 @@ help: consider cloning the value if the performance cost is acceptable
|
||||
LL | Some(_) if { drop(a.clone()); false } => None,
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0382]: use of moved value: `a`
|
||||
--> $DIR/issue-31287-drop-in-guard.rs:13:9
|
||||
|
|
||||
LL | let a = Some("...".to_owned());
|
||||
| - move occurs because `a` has type `Option<String>`, which does not implement the `Copy` trait
|
||||
LL | let b = match a {
|
||||
LL | Some(_) if let Some(()) = { drop(a); None } => None,
|
||||
| - value moved here
|
||||
LL | x => x,
|
||||
| ^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | Some(_) if let Some(()) = { drop(a.clone()); None } => None,
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
|
||||
@@ -170,7 +170,7 @@ LL | format!("foo %s baz", "bar");
|
||||
| |
|
||||
| help: format specifiers use curly braces: `{}`
|
||||
|
|
||||
= note: printf formatting not supported; see the documentation for `std::fmt`
|
||||
= note: printf formatting is not supported; see the documentation for `std::fmt`
|
||||
|
||||
error: invalid format string: expected `'}'`, found `'t'`
|
||||
--> $DIR/ifmt-bad-arg.rs:75:1
|
||||
|
||||
@@ -10,5 +10,5 @@ fn main() {
|
||||
//~| NOTE: argument never used
|
||||
//~| NOTE: argument never used
|
||||
//~| NOTE: format specifiers use curly braces, and you have to use a positional or named parameter for the width
|
||||
//~| NOTE: printf formatting not supported
|
||||
//~| NOTE: printf formatting is not supported
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ note: format specifiers use curly braces, and you have to use a positional or na
|
||||
|
|
||||
LL | print!("%0*x", width, num);
|
||||
| ^^^^
|
||||
= note: printf formatting not supported; see the documentation for `std::fmt`
|
||||
= note: printf formatting is not supported; see the documentation for `std::fmt`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// test for https://github.com/rust-lang/rust/issues/29723
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
let s = String::new();
|
||||
let _s = match 0 {
|
||||
@@ -11,4 +13,10 @@ fn main() {
|
||||
//~^ ERROR use of moved value: `s`
|
||||
}
|
||||
};
|
||||
|
||||
let s = String::new();
|
||||
let _s = match 0 {
|
||||
0 if let Some(()) = { drop(s); None } => String::from("oops"),
|
||||
_ => s //~ ERROR use of moved value: `s`
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0382]: use of moved value: `s`
|
||||
--> $DIR/issue-29723.rs:10:13
|
||||
--> $DIR/issue-29723.rs:12:13
|
||||
|
|
||||
LL | let s = String::new();
|
||||
| - move occurs because `s` has type `String`, which does not implement the `Copy` trait
|
||||
@@ -15,6 +15,22 @@ help: consider cloning the value if the performance cost is acceptable
|
||||
LL | 0 if { drop(s.clone()); false } => String::from("oops"),
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0382]: use of moved value: `s`
|
||||
--> $DIR/issue-29723.rs:20:14
|
||||
|
|
||||
LL | let s = String::new();
|
||||
| - move occurs because `s` has type `String`, which does not implement the `Copy` trait
|
||||
LL | let _s = match 0 {
|
||||
LL | 0 if let Some(()) = { drop(s); None } => String::from("oops"),
|
||||
| - value moved here
|
||||
LL | _ => s
|
||||
| ^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | 0 if let Some(()) = { drop(s.clone()); None } => String::from("oops"),
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
|
||||
@@ -8,7 +8,7 @@ LL | println!("%.*3$s %s!\n", "Hello,", "World", 4);
|
||||
| | argument never used
|
||||
| multiple missing formatting specifiers
|
||||
|
|
||||
= note: printf formatting not supported; see the documentation for `std::fmt`
|
||||
= note: printf formatting is not supported; see the documentation for `std::fmt`
|
||||
help: format specifiers use curly braces
|
||||
|
|
||||
LL | println!("{:.2$} {}!\n", "Hello,", "World", 4);
|
||||
@@ -22,7 +22,7 @@ LL | println!("%1$*2$.*3$f", 123.456);
|
||||
| |
|
||||
| help: format specifiers use curly braces: `{0:1$.2$}`
|
||||
|
|
||||
= note: printf formatting not supported; see the documentation for `std::fmt`
|
||||
= note: printf formatting is not supported; see the documentation for `std::fmt`
|
||||
|
||||
error: multiple unused formatting arguments
|
||||
--> $DIR/format-foreign.rs:6:7
|
||||
@@ -37,7 +37,7 @@ LL | | "###, "Hello,", "World", 4);
|
||||
| |____| argument never used
|
||||
| multiple missing formatting specifiers
|
||||
|
|
||||
= note: printf formatting not supported; see the documentation for `std::fmt`
|
||||
= note: printf formatting is not supported; see the documentation for `std::fmt`
|
||||
help: format specifiers use curly braces
|
||||
|
|
||||
LL ~ println!(r###"{:.2$}
|
||||
@@ -60,7 +60,7 @@ LL | println!("Hi there, $NAME.", NAME="Tim");
|
||||
| |
|
||||
| help: format specifiers use curly braces: `{NAME}`
|
||||
|
|
||||
= note: shell formatting not supported; see the documentation for `std::fmt`
|
||||
= note: shell formatting is not supported; see the documentation for `std::fmt`
|
||||
|
||||
error: multiple unused formatting arguments
|
||||
--> $DIR/format-foreign.rs:15:32
|
||||
@@ -72,7 +72,7 @@ LL | println!("$1 $0 $$ $NAME", 1, 2, NAME=3);
|
||||
| | argument never used
|
||||
| multiple missing formatting specifiers
|
||||
|
|
||||
= note: shell formatting not supported; see the documentation for `std::fmt`
|
||||
= note: shell formatting is not supported; see the documentation for `std::fmt`
|
||||
help: format specifiers use curly braces
|
||||
|
|
||||
LL | println!("{1} {0} $$ {NAME}", 1, 2, NAME=3);
|
||||
|
||||
@@ -44,7 +44,7 @@ LL | "things"
|
||||
LL | , UNUSED="args");
|
||||
| ^^^^^^ named argument never used
|
||||
|
|
||||
= note: shell formatting not supported; see the documentation for `std::fmt`
|
||||
= note: shell formatting is not supported; see the documentation for `std::fmt`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ note: format specifiers use curly braces, and the conversion specifier `
|
||||
|
|
||||
LL | pub fn main() { println!("🦀%%%", 0) }
|
||||
| ^^
|
||||
= note: printf formatting not supported; see the documentation for `std::fmt`
|
||||
= note: printf formatting is not supported; see the documentation for `std::fmt`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// See further discussion on rust-lang/rust#24535,
|
||||
// rust-lang/rfcs#1006, and rust-lang/rfcs#107
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
rust_issue_24535();
|
||||
rfcs_issue_1006_1();
|
||||
@@ -23,6 +25,12 @@ fn rust_issue_24535() {
|
||||
3 if compare(&a, &mut 3) => (),
|
||||
_ => panic!("nope"),
|
||||
}
|
||||
|
||||
match a {
|
||||
0 => panic!("nope"),
|
||||
3 if let true = compare(&a, &mut 3) => (),
|
||||
_ => panic!("nope"),
|
||||
}
|
||||
}
|
||||
|
||||
fn rfcs_issue_1006_1() {
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
// reaches the panic code when executed, despite the compiler warning
|
||||
// about that match arm being unreachable.
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
let b = &mut true;
|
||||
match b {
|
||||
@@ -17,4 +19,16 @@ fn main() {
|
||||
&mut true => { println!("You might think we should get here"); },
|
||||
_ => panic!("surely we could never get here, since rustc warns it is unreachable."),
|
||||
}
|
||||
|
||||
let b = &mut true;
|
||||
match b {
|
||||
//~^ ERROR use of moved value: `b` [E0382]
|
||||
&mut false => {}
|
||||
_ if let Some(()) = {
|
||||
(|| { let bar = b; *bar = false; })();
|
||||
None
|
||||
} => {}
|
||||
&mut true => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0382]: use of moved value: `b`
|
||||
--> $DIR/issue-27282-move-match-input-into-guard.rs:12:5
|
||||
--> $DIR/issue-27282-move-match-input-into-guard.rs:14:5
|
||||
|
|
||||
LL | let b = &mut true;
|
||||
| - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait
|
||||
@@ -11,6 +11,19 @@ LL | _ if { (|| { let bar = b; *bar = false; })();
|
||||
| |
|
||||
| value moved into closure here
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0382]: use of moved value: `b`
|
||||
--> $DIR/issue-27282-move-match-input-into-guard.rs:24:5
|
||||
|
|
||||
LL | let b = &mut true;
|
||||
| - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait
|
||||
LL | match b {
|
||||
| ^^^^^^^ value used here after move
|
||||
...
|
||||
LL | (|| { let bar = b; *bar = false; })();
|
||||
| -- - variable moved due to use in closure
|
||||
| |
|
||||
| value moved into closure here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// mutable borrows in match guards by hiding the mutable borrow in a
|
||||
// guard behind a move (of the ref mut pattern id) within a closure.
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
@@ -10,4 +12,12 @@ fn main() {
|
||||
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
ref mut foo
|
||||
if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {},
|
||||
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0507]: cannot move out of `foo` in pattern guard
|
||||
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:9:19
|
||||
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19
|
||||
|
|
||||
LL | if { (|| { let bar = foo; bar.take() })(); false } => {},
|
||||
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||
@@ -8,6 +8,16 @@ LL | if { (|| { let bar = foo; bar.take() })(); false } => {},
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0507]: cannot move out of `foo` in pattern guard
|
||||
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:19:34
|
||||
|
|
||||
LL | if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {},
|
||||
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| move out of `foo` occurs here
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
@@ -10,4 +12,15 @@ fn main() {
|
||||
Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
|
||||
_ => println!("Here is some supposedly unreachable code."),
|
||||
}
|
||||
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
ref mut foo
|
||||
if let Some(()) = {
|
||||
(|| { let bar = foo; bar.take() })();
|
||||
//~^ ERROR cannot move out of `foo` in pattern guard
|
||||
None
|
||||
} => {},
|
||||
Some(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0507]: cannot move out of `foo` in pattern guard
|
||||
--> $DIR/issue-27282-mutation-in-guard.rs:6:18
|
||||
--> $DIR/issue-27282-mutation-in-guard.rs:8:18
|
||||
|
|
||||
LL | (|| { let bar = foo; bar.take() })();
|
||||
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||
@@ -8,6 +8,16 @@ LL | (|| { let bar = foo; bar.take() })();
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0507]: cannot move out of `foo` in pattern guard
|
||||
--> $DIR/issue-27282-mutation-in-guard.rs:20:18
|
||||
|
|
||||
LL | (|| { let bar = foo; bar.take() })();
|
||||
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| move out of `foo` occurs here
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
// It reborrows instead of moving the `ref mut` pattern borrow. This
|
||||
// means that our conservative check for mutation in guards will
|
||||
// reject it. But I want to make sure that we continue to reject it
|
||||
// (under NLL) even when that conservaive check goes away.
|
||||
// (under NLL) even when that conservative check goes away.
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
let mut b = &mut true;
|
||||
@@ -15,4 +17,14 @@ fn main() {
|
||||
&mut true => { println!("You might think we should get here"); },
|
||||
_ => panic!("surely we could never get here, since rustc warns it is unreachable."),
|
||||
}
|
||||
|
||||
let mut b = &mut true;
|
||||
match b {
|
||||
&mut false => {},
|
||||
ref mut r if let Some(()) = { (|| { let bar = &mut *r; **bar = false; })();
|
||||
//~^ ERROR cannot borrow `r` as mutable, as it is immutable for the pattern guard
|
||||
None } => { &mut *r; },
|
||||
&mut true => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard
|
||||
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:12:25
|
||||
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:14:25
|
||||
|
|
||||
LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
|
||||
| ^^ -- mutable borrow occurs due to use of `r` in closure
|
||||
@@ -8,6 +8,16 @@ LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
|
||||
|
|
||||
= note: variables bound in patterns are immutable until the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard
|
||||
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:24:40
|
||||
|
|
||||
LL | ref mut r if let Some(()) = { (|| { let bar = &mut *r; **bar = false; })();
|
||||
| ^^ -- mutable borrow occurs due to use of `r` in closure
|
||||
| |
|
||||
| cannot borrow as mutable
|
||||
|
|
||||
= note: variables bound in patterns are immutable until the end of the pattern guard
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0596`.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Test that we have enough false edges to avoid exposing the exact matching
|
||||
// algorithm in borrow checking.
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn guard_always_precedes_arm(y: i32) {
|
||||
let mut x;
|
||||
// x should always be initialized, as the only way to reach the arm is
|
||||
@@ -9,6 +11,12 @@ fn guard_always_precedes_arm(y: i32) {
|
||||
0 | 2 if { x = 2; true } => x,
|
||||
_ => 2,
|
||||
};
|
||||
|
||||
let mut x;
|
||||
match y {
|
||||
0 | 2 if let Some(()) = { x = 2; Some(()) } => x,
|
||||
_ => 2,
|
||||
};
|
||||
}
|
||||
|
||||
fn guard_may_be_skipped(y: i32) {
|
||||
@@ -23,6 +31,16 @@ fn guard_may_be_skipped(y: i32) {
|
||||
} => 2,
|
||||
_ => 3,
|
||||
};
|
||||
|
||||
let x;
|
||||
match y {
|
||||
_ if let Some(()) = { x = 2; Some(()) } => 1,
|
||||
_ if let Some(()) = {
|
||||
x; //~ ERROR E0381
|
||||
None
|
||||
} => 2,
|
||||
_ => 3,
|
||||
};
|
||||
}
|
||||
|
||||
fn guard_may_be_taken(y: bool) {
|
||||
@@ -37,6 +55,16 @@ fn guard_may_be_taken(y: bool) {
|
||||
}
|
||||
false => 3,
|
||||
};
|
||||
|
||||
let x = String::new();
|
||||
match y {
|
||||
false if let Some(()) = { drop(x); Some(()) } => 1,
|
||||
true => {
|
||||
x; //~ ERROR use of moved value: `x`
|
||||
2
|
||||
}
|
||||
false => 3,
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/match-cfg-fake-edges.rs:21:13
|
||||
--> $DIR/match-cfg-fake-edges.rs:29:13
|
||||
|
|
||||
LL | let x;
|
||||
| - binding declared here but left uninitialized
|
||||
@@ -15,8 +15,25 @@ help: consider assigning a value
|
||||
LL | let x = 0;
|
||||
| +++
|
||||
|
||||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/match-cfg-fake-edges.rs:39:13
|
||||
|
|
||||
LL | let x;
|
||||
| - binding declared here but left uninitialized
|
||||
LL | match y {
|
||||
LL | _ if let Some(()) = { x = 2; Some(()) } => 1,
|
||||
| ----- binding initialized here in some conditions
|
||||
LL | _ if let Some(()) = {
|
||||
LL | x;
|
||||
| ^ `x` used here but it isn't initialized
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let x = 0;
|
||||
| +++
|
||||
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/match-cfg-fake-edges.rs:35:13
|
||||
--> $DIR/match-cfg-fake-edges.rs:53:13
|
||||
|
|
||||
LL | let x = String::new();
|
||||
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
|
||||
@@ -32,7 +49,24 @@ help: consider cloning the value if the performance cost is acceptable
|
||||
LL | false if { drop(x.clone()); true } => 1,
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/match-cfg-fake-edges.rs:63:13
|
||||
|
|
||||
LL | let x = String::new();
|
||||
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
|
||||
LL | match y {
|
||||
LL | false if let Some(()) = { drop(x); Some(()) } => 1,
|
||||
| - value moved here
|
||||
LL | true => {
|
||||
LL | x;
|
||||
| ^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | false if let Some(()) = { drop(x.clone()); Some(()) } => 1,
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0381, E0382.
|
||||
For more information about an error, try `rustc --explain E0381`.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
// Here is arielb1's basic example from rust-lang/rust#27282
|
||||
// that AST borrowck is flummoxed by:
|
||||
|
||||
@@ -10,6 +12,15 @@ fn should_reject_destructive_mutate_in_guard() {
|
||||
false } => { },
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
ref mut foo if let Some(()) = {
|
||||
(|| { let bar = foo; bar.take() })();
|
||||
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
|
||||
None } => { },
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
}
|
||||
|
||||
// Here below is a case that needs to keep working: we only use the
|
||||
@@ -18,7 +29,13 @@ fn should_reject_destructive_mutate_in_guard() {
|
||||
fn allow_mutate_in_arm_body() {
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
ref mut foo if foo.is_some() && false => { foo.take(); () }
|
||||
ref mut foo if foo.is_some() => { foo.take(); () }
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
ref mut foo if let Some(_) = foo => { foo.take(); () }
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
}
|
||||
@@ -29,7 +46,13 @@ fn allow_mutate_in_arm_body() {
|
||||
fn allow_move_into_arm_body() {
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
mut foo if foo.is_some() && false => { foo.take(); () }
|
||||
mut foo if foo.is_some() => { foo.unwrap(); () }
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
mut foo if let Some(_) = foo => { foo.unwrap(); () }
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0507]: cannot move out of `foo` in pattern guard
|
||||
--> $DIR/match-guards-always-borrow.rs:8:14
|
||||
--> $DIR/match-guards-always-borrow.rs:10:14
|
||||
|
|
||||
LL | (|| { let bar = foo; bar.take() })();
|
||||
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||
@@ -8,6 +8,16 @@ LL | (|| { let bar = foo; bar.take() })();
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0507]: cannot move out of `foo` in pattern guard
|
||||
--> $DIR/match-guards-always-borrow.rs:19:14
|
||||
|
|
||||
LL | (|| { let bar = foo; bar.take() })();
|
||||
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| move out of `foo` occurs here
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
// Test that we don't allow mutating the value being matched on in a way that
|
||||
// changes which patterns it matches, until we have chosen an arm.
|
||||
|
||||
fn ok_mutation_in_guard(mut q: i32) {
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn ok_mutation_in_if_guard(mut q: i32) {
|
||||
match q {
|
||||
// OK, mutation doesn't change which patterns g matches
|
||||
_ if { q = 1; false } => (),
|
||||
@@ -13,7 +15,15 @@ fn ok_mutation_in_guard(mut q: i32) {
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_mutation_in_guard2(mut u: bool) {
|
||||
fn ok_mutation_in_if_let_guard(mut q: i32) {
|
||||
match q {
|
||||
// OK, mutation doesn't change which patterns g matches
|
||||
_ if let Some(()) = { q = 1; None } => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_mutation_in_if_guard2(mut u: bool) {
|
||||
// OK value of u is unused before modification
|
||||
match u {
|
||||
_ => (),
|
||||
@@ -25,7 +35,19 @@ fn ok_mutation_in_guard2(mut u: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_mutation_in_guard4(mut w: (&mut bool,)) {
|
||||
fn ok_mutation_in_if_let_guard2(mut u: bool) {
|
||||
// OK value of u is unused before modification
|
||||
match u {
|
||||
_ => (),
|
||||
_ if let Some(()) = {
|
||||
u = true;
|
||||
None
|
||||
} => (),
|
||||
x => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_mutation_in_if_guard4(mut w: (&mut bool,)) {
|
||||
// OK value of u is unused before modification
|
||||
match w {
|
||||
_ => (),
|
||||
@@ -37,7 +59,19 @@ fn ok_mutation_in_guard4(mut w: (&mut bool,)) {
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_indirect_mutation_in_guard(mut p: &bool) {
|
||||
fn ok_mutation_in_if_let_guard4(mut w: (&mut bool,)) {
|
||||
// OK value of u is unused before modification
|
||||
match w {
|
||||
_ => (),
|
||||
_ if let Some(()) = {
|
||||
*w.0 = true;
|
||||
None
|
||||
} => (),
|
||||
x => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_indirect_mutation_in_if_guard(mut p: &bool) {
|
||||
match *p {
|
||||
// OK, mutation doesn't change which patterns s matches
|
||||
_ if {
|
||||
@@ -48,7 +82,18 @@ fn ok_indirect_mutation_in_guard(mut p: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn mutation_invalidates_pattern_in_guard(mut q: bool) {
|
||||
fn ok_indirect_mutation_in_if_let_guard(mut p: &bool) {
|
||||
match *p {
|
||||
// OK, mutation doesn't change which patterns s matches
|
||||
_ if let Some(()) = {
|
||||
p = &true;
|
||||
None
|
||||
} => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn mutation_invalidates_pattern_in_if_guard(mut q: bool) {
|
||||
match q {
|
||||
// q doesn't match the pattern with the guard by the end of the guard.
|
||||
false if {
|
||||
@@ -59,7 +104,18 @@ fn mutation_invalidates_pattern_in_guard(mut q: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn mutation_invalidates_previous_pattern_in_guard(mut r: bool) {
|
||||
fn mutation_invalidates_pattern_in_if_let_guard(mut q: bool) {
|
||||
match q {
|
||||
// q doesn't match the pattern with the guard by the end of the guard.
|
||||
false if let Some(()) = {
|
||||
q = true; //~ ERROR
|
||||
Some(())
|
||||
} => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn mutation_invalidates_previous_pattern_in_if_guard(mut r: bool) {
|
||||
match r {
|
||||
// r matches a previous pattern by the end of the guard.
|
||||
true => (),
|
||||
@@ -71,7 +127,19 @@ fn mutation_invalidates_previous_pattern_in_guard(mut r: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn match_on_borrowed_early_end(mut s: bool) {
|
||||
fn mutation_invalidates_previous_pattern_in_if_let_guard(mut r: bool) {
|
||||
match r {
|
||||
// r matches a previous pattern by the end of the guard.
|
||||
true => (),
|
||||
_ if let Some(()) = {
|
||||
r = true; //~ ERROR
|
||||
Some(())
|
||||
} => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn match_on_borrowed_early_end_if_guard(mut s: bool) {
|
||||
let h = &mut s;
|
||||
// OK value of s is unused before modification.
|
||||
match s {
|
||||
@@ -84,7 +152,20 @@ fn match_on_borrowed_early_end(mut s: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_guard(mut t: bool) {
|
||||
fn match_on_borrowed_early_end_if_let_guard(mut s: bool) {
|
||||
let h = &mut s;
|
||||
// OK value of s is unused before modification.
|
||||
match s {
|
||||
_ if let Some(()) = {
|
||||
*h = !*h;
|
||||
None
|
||||
} => (),
|
||||
true => (),
|
||||
false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_if_guard(mut t: bool) {
|
||||
match t {
|
||||
true => (),
|
||||
false if {
|
||||
@@ -95,7 +176,18 @@ fn bad_mutation_in_guard(mut t: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_guard2(mut x: Option<Option<&i32>>) {
|
||||
fn bad_mutation_in_if_let_guard(mut t: bool) {
|
||||
match t {
|
||||
true => (),
|
||||
false if let Some(()) = {
|
||||
t = true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_if_guard2(mut x: Option<Option<&i32>>) {
|
||||
// Check that nested patterns are checked.
|
||||
match x {
|
||||
None => (),
|
||||
@@ -111,7 +203,23 @@ fn bad_mutation_in_guard2(mut x: Option<Option<&i32>>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_guard3(mut t: bool) {
|
||||
fn bad_mutation_in_if_let_guard2(mut x: Option<Option<&i32>>) {
|
||||
// Check that nested patterns are checked.
|
||||
match x {
|
||||
None => (),
|
||||
Some(None) => (),
|
||||
_ if let Some(()) = {
|
||||
match x {
|
||||
Some(ref mut r) => *r = None, //~ ERROR
|
||||
_ => return,
|
||||
};
|
||||
None
|
||||
} => (),
|
||||
Some(Some(r)) => println!("{}", r),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_if_guard3(mut t: bool) {
|
||||
match t {
|
||||
s if {
|
||||
t = !t; //~ ERROR
|
||||
@@ -121,7 +229,17 @@ fn bad_mutation_in_guard3(mut t: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_guard(mut y: &bool) {
|
||||
fn bad_mutation_in_if_let_guard3(mut t: bool) {
|
||||
match t {
|
||||
s if let Some(()) = {
|
||||
t = !t; //~ ERROR
|
||||
None
|
||||
} => (), // What value should `s` have in the arm?
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_guard(mut y: &bool) {
|
||||
match *y {
|
||||
true => (),
|
||||
false if {
|
||||
@@ -132,7 +250,18 @@ fn bad_indirect_mutation_in_guard(mut y: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_guard2(mut z: &bool) {
|
||||
fn bad_indirect_mutation_in_if_let_guard(mut y: &bool) {
|
||||
match *y {
|
||||
true => (),
|
||||
false if let Some(()) = {
|
||||
y = &true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_guard2(mut z: &bool) {
|
||||
match z {
|
||||
&true => (),
|
||||
&false if {
|
||||
@@ -143,8 +272,19 @@ fn bad_indirect_mutation_in_guard2(mut z: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_guard3(mut a: &bool) {
|
||||
// Same as bad_indirect_mutation_in_guard2, but using match ergonomics
|
||||
fn bad_indirect_mutation_in_if_let_guard2(mut z: &bool) {
|
||||
match z {
|
||||
&true => (),
|
||||
&false if let Some(()) = {
|
||||
z = &true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
&false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_guard3(mut a: &bool) {
|
||||
// Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics
|
||||
match a {
|
||||
true => (),
|
||||
false if {
|
||||
@@ -155,7 +295,19 @@ fn bad_indirect_mutation_in_guard3(mut a: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_guard4(mut b: &bool) {
|
||||
fn bad_indirect_mutation_in_if_let_guard3(mut a: &bool) {
|
||||
// Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics
|
||||
match a {
|
||||
true => (),
|
||||
false if let Some(()) = {
|
||||
a = &true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_guard4(mut b: &bool) {
|
||||
match b {
|
||||
&_ => (),
|
||||
&_ if {
|
||||
@@ -166,4 +318,15 @@ fn bad_indirect_mutation_in_guard4(mut b: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_let_guard4(mut b: &bool) {
|
||||
match b {
|
||||
&_ => (),
|
||||
&_ if let Some(()) = {
|
||||
b = &true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
&b => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
error[E0510]: cannot assign `q` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:55:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:100:13
|
||||
|
|
||||
LL | match q {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | q = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `q` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:111:13
|
||||
|
|
||||
LL | match q {
|
||||
| - value is immutable in match guard
|
||||
@@ -8,7 +17,16 @@ LL | q = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `r` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:67:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:123:13
|
||||
|
|
||||
LL | match r {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | r = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `r` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:135:13
|
||||
|
|
||||
LL | match r {
|
||||
| - value is immutable in match guard
|
||||
@@ -17,7 +35,16 @@ LL | r = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `t` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:91:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:172:13
|
||||
|
|
||||
LL | match t {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | t = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `t` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:183:13
|
||||
|
|
||||
LL | match t {
|
||||
| - value is immutable in match guard
|
||||
@@ -26,7 +53,16 @@ LL | t = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot mutably borrow `x.0` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:105:22
|
||||
--> $DIR/match-guards-partially-borrow.rs:197:22
|
||||
|
|
||||
LL | match x {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | Some(ref mut r) => *r = None,
|
||||
| ^^^^^^^^^ cannot mutably borrow
|
||||
|
||||
error[E0510]: cannot mutably borrow `x.0` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:213:22
|
||||
|
|
||||
LL | match x {
|
||||
| - value is immutable in match guard
|
||||
@@ -35,7 +71,7 @@ LL | Some(ref mut r) => *r = None,
|
||||
| ^^^^^^^^^ cannot mutably borrow
|
||||
|
||||
error[E0506]: cannot assign to `t` because it is borrowed
|
||||
--> $DIR/match-guards-partially-borrow.rs:117:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:225:13
|
||||
|
|
||||
LL | s if {
|
||||
| - borrow of `t` occurs here
|
||||
@@ -45,8 +81,28 @@ LL | false
|
||||
LL | } => (), // What value should `s` have in the arm?
|
||||
| - borrow later used here
|
||||
|
||||
error[E0506]: cannot assign to `t` because it is borrowed
|
||||
--> $DIR/match-guards-partially-borrow.rs:235:13
|
||||
|
|
||||
LL | s if let Some(()) = {
|
||||
| - borrow of `t` occurs here
|
||||
LL | t = !t;
|
||||
| ^^^^^^ assignment to borrowed `t` occurs here
|
||||
LL | None
|
||||
LL | } => (), // What value should `s` have in the arm?
|
||||
| - borrow later used here
|
||||
|
||||
error[E0510]: cannot assign `y` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:128:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:246:13
|
||||
|
|
||||
LL | match *y {
|
||||
| -- value is immutable in match guard
|
||||
...
|
||||
LL | y = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `y` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:257:13
|
||||
|
|
||||
LL | match *y {
|
||||
| -- value is immutable in match guard
|
||||
@@ -55,7 +111,16 @@ LL | y = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `z` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:139:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:268:13
|
||||
|
|
||||
LL | match z {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | z = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `z` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:279:13
|
||||
|
|
||||
LL | match z {
|
||||
| - value is immutable in match guard
|
||||
@@ -64,7 +129,16 @@ LL | z = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `a` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:151:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:291:13
|
||||
|
|
||||
LL | match a {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | a = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `a` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:303:13
|
||||
|
|
||||
LL | match a {
|
||||
| - value is immutable in match guard
|
||||
@@ -73,7 +147,7 @@ LL | a = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `b` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:162:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:314:13
|
||||
|
|
||||
LL | match b {
|
||||
| - value is immutable in match guard
|
||||
@@ -81,7 +155,16 @@ LL | match b {
|
||||
LL | b = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error[E0510]: cannot assign `b` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:325:13
|
||||
|
|
||||
LL | match b {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | b = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0506, E0510.
|
||||
For more information about an error, try `rustc --explain E0506`.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
enum VecWrapper { A(Vec<i32>) }
|
||||
|
||||
fn foo(x: VecWrapper) -> usize {
|
||||
fn if_guard(x: VecWrapper) -> usize {
|
||||
match x {
|
||||
VecWrapper::A(v) if { drop(v); false } => 1,
|
||||
//~^ ERROR cannot move out of `v` in pattern guard
|
||||
@@ -8,6 +10,15 @@ fn foo(x: VecWrapper) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(VecWrapper::A(vec![107]));
|
||||
fn if_let_guard(x: VecWrapper) -> usize {
|
||||
match x {
|
||||
VecWrapper::A(v) if let Some(()) = { drop(v); None } => 1,
|
||||
//~^ ERROR cannot move out of `v` in pattern guard
|
||||
VecWrapper::A(v) => v.len()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if_guard(VecWrapper::A(vec![107]));
|
||||
if_let_guard(VecWrapper::A(vec![107]));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
error[E0507]: cannot move out of `v` in pattern guard
|
||||
--> $DIR/rfc-reject-double-move-across-arms.rs:5:36
|
||||
--> $DIR/rfc-reject-double-move-across-arms.rs:7:36
|
||||
|
|
||||
LL | VecWrapper::A(v) if { drop(v); false } => 1,
|
||||
| ^ move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0507]: cannot move out of `v` in pattern guard
|
||||
--> $DIR/rfc-reject-double-move-across-arms.rs:15:51
|
||||
|
|
||||
LL | VecWrapper::A(v) if let Some(()) = { drop(v); None } => 1,
|
||||
| ^ move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
struct A { a: Box<i32> }
|
||||
|
||||
fn foo(n: i32) {
|
||||
fn if_guard(n: i32) {
|
||||
let x = A { a: Box::new(n) };
|
||||
let _y = match x {
|
||||
A { a: v } if { drop(v); true } => v,
|
||||
@@ -9,6 +11,16 @@ fn foo(n: i32) {
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(107);
|
||||
fn if_let_guard(n: i32) {
|
||||
let x = A { a: Box::new(n) };
|
||||
let _y = match x {
|
||||
A { a: v } if let Some(()) = { drop(v); Some(()) } => v,
|
||||
//~^ ERROR cannot move out of `v` in pattern guard
|
||||
_ => Box::new(0),
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if_guard(107);
|
||||
if_let_guard(107);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
error[E0507]: cannot move out of `v` in pattern guard
|
||||
--> $DIR/rfc-reject-double-move-in-first-arm.rs:6:30
|
||||
--> $DIR/rfc-reject-double-move-in-first-arm.rs:8:30
|
||||
|
|
||||
LL | A { a: v } if { drop(v); true } => v,
|
||||
| ^ move occurs because `v` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0507]: cannot move out of `v` in pattern guard
|
||||
--> $DIR/rfc-reject-double-move-in-first-arm.rs:17:45
|
||||
|
|
||||
LL | A { a: v } if let Some(()) = { drop(v); Some(()) } => v,
|
||||
| ^ move occurs because `v` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
|
||||
@@ -11,6 +11,7 @@ miropt-test-tools = { path = "../miropt-test-tools" }
|
||||
lazy_static = "1"
|
||||
walkdir = "2"
|
||||
ignore = "0.4.18"
|
||||
semver = "1.0.14"
|
||||
termcolor = "1.1.3"
|
||||
|
||||
[[bin]]
|
||||
|
||||
@@ -69,3 +69,4 @@ pub mod ui_tests;
|
||||
pub mod unit_tests;
|
||||
pub mod unstable_book;
|
||||
pub mod walk;
|
||||
pub mod x_version;
|
||||
|
||||
@@ -58,7 +58,7 @@ fn main() {
|
||||
|
||||
let handle = s.spawn(|| {
|
||||
let mut flag = false;
|
||||
$p::check($($args),* , &mut flag);
|
||||
$p::check($($args, )* &mut flag);
|
||||
if (flag) {
|
||||
bad.store(true, Ordering::Relaxed);
|
||||
}
|
||||
@@ -107,6 +107,8 @@ fn main() {
|
||||
check!(alphabetical, &compiler_path);
|
||||
check!(alphabetical, &library_path);
|
||||
|
||||
check!(x_version, &root_path, &cargo);
|
||||
|
||||
let collected = {
|
||||
drain_handles(&mut handles);
|
||||
|
||||
|
||||
65
src/tools/tidy/src/x_version.rs
Normal file
65
src/tools/tidy/src/x_version.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
use semver::Version;
|
||||
use std::io::ErrorKind;
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
|
||||
let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn();
|
||||
// This runs the command inside a temporary directory.
|
||||
// This allows us to compare output of result to see if `--wrapper-version` is not a recognized argument to x.
|
||||
let temp_result = Command::new("x")
|
||||
.arg("--wrapper-version")
|
||||
.current_dir(std::env::temp_dir())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn();
|
||||
|
||||
let (child, temp_child) = match (result, temp_result) {
|
||||
(Ok(child), Ok(temp_child)) => (child, temp_child),
|
||||
(Err(e), _) | (_, Err(e)) => match e.kind() {
|
||||
ErrorKind::NotFound => return,
|
||||
_ => return tidy_error!(bad, "failed to run `x`: {}", e),
|
||||
},
|
||||
};
|
||||
|
||||
let output = child.wait_with_output().unwrap();
|
||||
let temp_output = temp_child.wait_with_output().unwrap();
|
||||
|
||||
if output != temp_output {
|
||||
return tidy_error!(
|
||||
bad,
|
||||
"Current version of x does not support the `--wrapper-version` argument\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`"
|
||||
);
|
||||
}
|
||||
|
||||
if output.status.success() {
|
||||
let version = String::from_utf8_lossy(&output.stdout);
|
||||
let version = Version::parse(version.trim_end()).unwrap();
|
||||
|
||||
if let Some(expected) = get_x_wrapper_version(root, cargo) {
|
||||
if version < expected {
|
||||
return tidy_error!(
|
||||
bad,
|
||||
"Current version of x is {version}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return tidy_error!(
|
||||
bad,
|
||||
"Unable to parse the latest version of `x` at `src/tools/x/Cargo.toml`"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return tidy_error!(bad, "failed to check version of `x`: {}", output.status);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse latest version out of `x` Cargo.toml
|
||||
fn get_x_wrapper_version(root: &Path, cargo: &Path) -> Option<Version> {
|
||||
let mut cmd = cargo_metadata::MetadataCommand::new();
|
||||
cmd.cargo_path(cargo)
|
||||
.manifest_path(root.join("src/tools/x/Cargo.toml"))
|
||||
.no_deps()
|
||||
.features(cargo_metadata::CargoOpt::AllFeatures);
|
||||
let mut metadata = t!(cmd.exec());
|
||||
metadata.packages.pop().map(|x| x.version)
|
||||
}
|
||||
@@ -52,6 +52,14 @@ fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match env::args().skip(1).next().as_deref() {
|
||||
Some("--wrapper-version") => {
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
println!("{}", version);
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let current = match env::current_dir() {
|
||||
Ok(dir) => dir,
|
||||
Err(err) => {
|
||||
|
||||
Reference in New Issue
Block a user