Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/rustc_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
if def.variants.len() > 1 {
needs_to_be_read = true;
}
} else {
// If it is not ty::Adt, then it should be read
needs_to_be_read = true;
}
}
PatKind::Lit(_) | PatKind::Range(..) => {
Expand Down
19 changes: 19 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/issue-87988.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// run-pass
// edition:2021

const LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: i32 = 0x01;
const LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: i32 = 0x02;

pub fn hotplug_callback(event: i32) {
let _ = || {
match event {
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED => (),
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT => (),
_ => (),
};
};
}

fn main() {
hotplug_callback(1);
}
44 changes: 44 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// run-pass
// edition:2021

const PATTERN_REF: &str = "Hello World";
const NUMBER: i32 = 30;
const NUMBER_POINTER: *const i32 = &NUMBER;

pub fn edge_case_ref(event: &str) {
let _ = || {
match event {
PATTERN_REF => (),
_ => (),
};
};
}

pub fn edge_case_str(event: String) {
let _ = || {
match event.as_str() {
"hello" => (),
_ => (),
};
};
}

pub fn edge_case_raw_ptr(event: *const i32) {
let _ = || {
match event {
NUMBER_POINTER => (),
_ => (),
};
};
}

pub fn edge_case_char(event: char) {
let _ = || {
match event {
'a' => (),
_ => (),
};
};
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// check-pass
// edition:2021

const FOO: isize = 10;
const ZST: &() = unsafe { std::mem::transmute(FOO) };
fn main() {
|| {
match &() {
ZST => 9,
};
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// run-fail
// edition:2021
// error-pattern:explicit panic
// ignore-emscripten no processes

fn f() -> ! {
panic!()
}

fn g() -> isize {
let x = || {
match true {
true => f(),
false => 10,
}
};
return x();
}

fn main() {
g();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// run-fail
// edition:2021
// error-pattern:explicit panic
// ignore-emscripten no processes

fn main() {
let c = || {
let _x = match true {
false => 0,
true => panic!(),
};
};
c();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// edition:2021
const F: &'static dyn Send = &7u32;

fn main() {
|| {
let a: &dyn Send = &7u32;
match a {
F => panic!(),
//~^ ERROR `&dyn Send` cannot be used in patterns
_ => {}
};
};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: `&dyn Send` cannot be used in patterns
--> $DIR/issue-70972-dyn-trait.rs:8:13
|
LL | F => panic!(),
| ^

error: aborting due to previous error

76 changes: 76 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/match/issue-72680.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// run-pass
// edition:2021

fn main() {
assert!(f("", 0));
assert!(f("a", 1));
assert!(f("b", 1));

assert!(!f("", 1));
assert!(!f("a", 0));
assert!(!f("b", 0));

assert!(!f("asdf", 32));

////

assert!(!g(true, true, true));
assert!(!g(false, true, true));
assert!(!g(true, false, true));
assert!(!g(false, false, true));
assert!(!g(true, true, false));

assert!(g(false, true, false));
assert!(g(true, false, false));
assert!(g(false, false, false));

////

assert!(!h(true, true, true));
assert!(!h(false, true, true));
assert!(!h(true, false, true));
assert!(!h(false, false, true));
assert!(!h(true, true, false));

assert!(h(false, true, false));
assert!(h(true, false, false));
assert!(h(false, false, false));
}

fn f(s: &str, num: usize) -> bool {
let c = || {
match (s, num) {
("", 0) | ("a" | "b", 1) => true,

_ => false,
}
};
c()

}

fn g(x: bool, y: bool, z: bool) -> bool {
let c = || {
match (x, y, x, z) {
(true | false, false, true, false) => true,
(false, true | false, true | false, false) => true,
(true | false, true | false, true | false, true) => false,
(true, true | false, true | false, false) => false,
}
};
c()

}

fn h(x: bool, y: bool, z: bool) -> bool {
let c = || {
match (x, (y, (x, (z,)))) {
(true | false, (false, (true, (false,)))) => true,
(false, (true | false, (true | false, (false,)))) => true,
(true | false, (true | false, (true | false, (true,)))) => false,
(true, (true | false, (true | false, (false,)))) => false,
}
};
c()

}
28 changes: 28 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/match/issue-72896.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// run-pass
// edition:2021

trait EnumSetType {
type Repr;
}

enum Enum8 { }
impl EnumSetType for Enum8 {
type Repr = u8;
}

#[derive(PartialEq, Eq)]
struct EnumSet<T: EnumSetType> {
__enumset_underlying: T::Repr,
}

const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };

fn main() {
let _c = || {
match CONST_SET {
CONST_SET => { /* ok */ }
_ => panic!("match fell through?"),
}
};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// edition:2021

fn main() {
|| {
let mut args = std::env::args_os();
let _arg = match args.next() {
Some(arg) => {
match arg.to_str() {
//~^ ERROR `arg` does not live long enough
Some(s) => s,
None => return,
}
}
None => return,
};
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0597]: `arg` does not live long enough
--> $DIR/issue-74050-end-span.rs:8:23
|
LL | let _arg = match args.next() {
| ---- borrow later stored here
LL | Some(arg) => {
LL | match arg.to_str() {
| ^^^ borrowed value does not live long enough
...
LL | }
| - `arg` dropped here while still borrowed

error: aborting due to previous error

For more information about this error, try `rustc --explain E0597`.
12 changes: 12 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/match/issue-82392.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// https://github.com/rust-lang/rust/issues/82329
// compile-flags: -Zunpretty=hir,typed
// check-pass
// edition:2021

pub fn main() {
|| {
if true {
} else if let Some(a) = Some(3) {
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
// https://github.com/rust-lang/rust/issues/82329
// compile-flags: -Zunpretty=hir,typed
// check-pass
// edition:2021

pub fn main() ({
(||
({
(if (true as bool)
({ } as
()) else {match ((Some as
fn(i32) -> Option<i32> {Option::<i32>::Some})((3
as
i32))
as Option<i32>) {
Some(a) => { }
_ => { }
}} as ())
} as
()) as
[closure@$DIR/issue-82392.rs:7:5: 11:6]);
} as ())
22 changes: 22 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/match/issue-84434.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// https://github.com/rust-lang/rust/issues/84434
// check-pass
// edition:2021

use std::path::Path;
struct A {
pub func: fn(check: bool, a: &Path, b: Option<&Path>),
}
const MY_A: A = A {
func: |check, a, b| {
|| {
if check {
let _ = ();
} else if let Some(parent) = b.and_then(|p| p.parent()) {
let _ = ();
}
};

},
};

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// edition:2021

enum E {
A,
B,
C,
D,
E,
F,
}

fn main() {
let c = || {
match E::F {
E::A => 1,
E::B => 2,
E::C => 3,
E::D => 4,
E::E => unimplemented!(""),
E::F => "", //~ ERROR `match` arms have incompatible types
};
};

}
Loading