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:
bors
2023-01-03 17:08:17 +00:00
51 changed files with 758 additions and 112 deletions

View File

@@ -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",
]

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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>,

View File

@@ -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>,

View File

@@ -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.

View File

@@ -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.

View File

@@ -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:

View File

@@ -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(..) => {

View File

@@ -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>,
}

View File

@@ -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!(),

View File

@@ -76,8 +76,6 @@
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

View File

@@ -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));

View File

@@ -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]
}
}

View File

@@ -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`.

View File

@@ -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() {}

View File

@@ -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`.

View File

@@ -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`
};
}

View File

@@ -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`.

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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`
};
}

View File

@@ -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`.

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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() {

View File

@@ -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 => {}
_ => {}
}
}

View File

@@ -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`.

View File

@@ -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),
}
}

View File

@@ -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`.

View File

@@ -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(_) => {},
}
}

View File

@@ -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`.

View File

@@ -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 => {},
_ => {},
}
}

View File

@@ -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`.

View File

@@ -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() {}

View File

@@ -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`.

View File

@@ -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),
}
}

View File

@@ -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`.

View File

@@ -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() {}

View File

@@ -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`.

View File

@@ -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]));
}

View File

@@ -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`.

View File

@@ -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);
}

View File

@@ -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`.

View File

@@ -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]]

View File

@@ -69,3 +69,4 @@ pub mod ui_tests;
pub mod unit_tests;
pub mod unstable_book;
pub mod walk;
pub mod x_version;

View File

@@ -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);

View 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)
}

View File

@@ -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) => {