diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index a04ac33827424..cee657e9da244 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -255,10 +255,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { func: fun, args, cleanup: None, - // FIXME(varkor): replace this with an uninhabitedness-based check. - // This requires getting access to the current module to call - // `tcx.is_ty_uninhabited_from`, which is currently tricky to do. - destination: if expr.ty.is_never() { + // The presence or absence of a return edge affects control-flow sensitive + // MIR checks and ultimately whether code is accepted or not. We can only + // omit the return edge if a return type is visibly uninhabited to a module + // that makes the call. + destination: if this.tcx.is_ty_uninhabited_from( + this.parent_module, + expr.ty, + this.param_env, + ) { None } else { Some((destination, success)) diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 901635dc488a7..3c51f79186274 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -350,6 +350,7 @@ struct Builder<'a, 'tcx> { def_id: DefId, hir_id: hir::HirId, + parent_module: DefId, check_overflow: bool, fn_span: Span, arg_count: usize, @@ -807,15 +808,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); let lint_level = LintLevel::Explicit(hir_id); + let param_env = tcx.param_env(def.did); let mut builder = Builder { thir, tcx, infcx, typeck_results: tcx.typeck_opt_const_arg(def), region_scope_tree: tcx.region_scope_tree(def.did), - param_env: tcx.param_env(def.did), + param_env, def_id: def.did.to_def_id(), hir_id, + parent_module: tcx.parent_module(hir_id).to_def_id(), check_overflow, cfg: CFG { basic_blocks: IndexVec::new() }, fn_span: span, diff --git a/src/test/codegen/set-discriminant-invalid.rs b/src/test/codegen/set-discriminant-invalid.rs index d9614f062b7e9..bccb9e4c75862 100644 --- a/src/test/codegen/set-discriminant-invalid.rs +++ b/src/test/codegen/set-discriminant-invalid.rs @@ -28,7 +28,7 @@ impl IntoError for Api #[no_mangle] fn into_error(self, error: Self::Source) -> Error { Error::Api { - source: (|v| v)(error), + source: error, } } } diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff index bea33073366f7..3b890e4be2e29 100644 --- a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff @@ -4,21 +4,22 @@ fn h() -> () { let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:21:12: 21:12 let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 -+ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 -+ let mut _9: (); // in scope 0 at $DIR/inline-diverging.rs:27:13: 27:16 -+ let mut _10: (); // in scope 0 at $DIR/inline-diverging.rs:28:13: 28:16 ++ let mut _2: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _3: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _10: (); // in scope 0 at $DIR/inline-diverging.rs:27:13: 27:16 ++ let mut _11: (); // in scope 0 at $DIR/inline-diverging.rs:28:13: 28:16 + scope 1 (inlined call_twice:: ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22 -+ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37 -+ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 -+ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ let mut _6: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14 -+ let mut _7: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7 -+ let mut _8: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10 ++ debug f => _3; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37 ++ let _4: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 ++ let mut _5: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 ++ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14 ++ let mut _8: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7 ++ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10 + scope 2 { -+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10 -+ let _5: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10 ++ debug a => _4; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10 ++ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10 + scope 3 { -+ debug b => _5; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10 ++ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10 + } + scope 6 (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:28:13: 28:16 + scope 7 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -33,27 +34,25 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 -- _1 = call_twice:: ! {sleep}>(sleep) -> bb1; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 +- call_twice:: ! {sleep}>(sleep); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 + StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 -+ _2 = sleep; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ _3 = sleep; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 // mir::Constant - // + span: $DIR/inline-diverging.rs:22:5: 22:15 - // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice:: ! {sleep}>}, val: Value(Scalar()) } - // mir::Constant // + span: $DIR/inline-diverging.rs:22:16: 22:21 // + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar()) } -+ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 -+ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ StorageLive(_9); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 -+ _9 = const (); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 ++ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 ++ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 ++ _5 = &_3; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 ++ StorageLive(_10); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 ++ _10 = const (); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 + goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12 - } - - bb1: { -- StorageDead(_1); // scope 0 at $DIR/inline-diverging.rs:22:22: 22:23 -- _0 = const (); // scope 0 at $DIR/inline-diverging.rs:21:12: 23:2 -- return; // scope 0 at $DIR/inline-diverging.rs:23:2: 23:2 ++ } ++ ++ bb1: { + goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12 } } diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir index 5fb57c285beca..4aff444515809 100644 --- a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir @@ -21,7 +21,7 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10 StorageLive(_3); // scope 2 at $DIR/issue-72181-1.rs:17:41: 17:43 _3 = (); // scope 2 at $DIR/issue-72181-1.rs:17:41: 17:43 - _2 = transmute::<(), Void>(move _3) -> [return: bb1, unwind: bb4]; // scope 2 at $DIR/issue-72181-1.rs:17:9: 17:44 + transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue-72181-1.rs:17:9: 17:44 // mir::Constant // + span: $DIR/issue-72181-1.rs:17:9: 17:40 // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Void {transmute::<(), Void>}, val: Value(Scalar()) } diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr index 111d243959a13..b60bac541f4c8 100644 --- a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr @@ -119,27 +119,17 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran 78 00 00 00 ff ff ff ff │ x....... } -error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:92:1 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-enum.rs:92:77 | LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at ..0.1: encountered a value of uninhabited type Never - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - 00 00 00 00 00 00 00 00 │ ........ - } + | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type -error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:94:1 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-enum.rs:94:77 | LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at ..0.1: encountered a value of the never type `!` - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - 00 00 00 00 00 00 00 00 │ ........ - } + | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type error: aborting due to 13 previous errors diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr index eee132bae00bc..1d81e2b3eed86 100644 --- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr @@ -119,27 +119,17 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran 78 00 00 00 ff ff ff ff │ x....... } -error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:92:1 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-enum.rs:92:77 | LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at ..0.1: encountered a value of uninhabited type Never - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - 00 00 00 00 00 00 00 00 │ ........ - } + | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type -error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:94:1 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-enum.rs:94:77 | LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at ..0.1: encountered a value of the never type `!` - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - 00 00 00 00 00 00 00 00 │ ........ - } + | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type error: aborting due to 13 previous errors diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs index e408d8ec072e3..86288685303ca 100644 --- a/src/test/ui/consts/const-eval/ub-enum.rs +++ b/src/test/ui/consts/const-eval/ub-enum.rs @@ -90,9 +90,9 @@ const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute // All variants are uninhabited but also have data. // Use `0` as constant to make behavior endianess-independent. const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; -//~^ ERROR is undefined behavior +//~^ ERROR evaluation of constant value failed const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; -//~^ ERROR is undefined behavior +//~^ ERROR evaluation of constant value failed fn main() { } diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr index 7dc1ec865af8a..bbb8511a65410 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr @@ -10,14 +10,11 @@ LL | unsafe { std::mem::transmute(()) } LL | const FOO: [Empty; 3] = [foo(); 3]; | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:13:26 -error[E0080]: it is undefined behavior to use this value - --> $DIR/validate_uninhabited_zsts.rs:16:1 +error[E0080]: evaluation of constant value failed + --> $DIR/validate_uninhabited_zsts.rs:16:35 | LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0]: encountered a value of uninhabited type Empty - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 0, align: 1) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type warning: the type `!` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:4:14 diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr index 7dc1ec865af8a..bbb8511a65410 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr @@ -10,14 +10,11 @@ LL | unsafe { std::mem::transmute(()) } LL | const FOO: [Empty; 3] = [foo(); 3]; | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:13:26 -error[E0080]: it is undefined behavior to use this value - --> $DIR/validate_uninhabited_zsts.rs:16:1 +error[E0080]: evaluation of constant value failed + --> $DIR/validate_uninhabited_zsts.rs:16:35 | LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0]: encountered a value of uninhabited type Empty - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 0, align: 1) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type warning: the type `!` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:4:14 diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs index 346504845561d..990d5a308238f 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs @@ -14,7 +14,7 @@ const FOO: [Empty; 3] = [foo(); 3]; #[warn(const_err)] const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; -//~^ ERROR it is undefined behavior to use this value +//~^ ERROR evaluation of constant value failed //~| WARN the type `Empty` does not permit zero-initialization fn main() { diff --git a/src/test/ui/generator/issue-93161.rs b/src/test/ui/generator/issue-93161.rs index 9988acbcb73e1..92305609c835c 100644 --- a/src/test/ui/generator/issue-93161.rs +++ b/src/test/ui/generator/issue-93161.rs @@ -1,5 +1,6 @@ // edition:2021 // run-pass +// compile-flags: -Zdrop-tracking #![feature(never_type)] @@ -32,7 +33,7 @@ fn never() -> Never { } async fn includes_never(crash: bool, x: u32) -> u32 { - let mut result = async { x * x }.await; + let result = async { x * x }.await; if !crash { return result; } diff --git a/src/test/ui/statics/uninhabited-static.rs b/src/test/ui/statics/uninhabited-static.rs index d564547489106..f5c6f444317fe 100644 --- a/src/test/ui/statics/uninhabited-static.rs +++ b/src/test/ui/statics/uninhabited-static.rs @@ -11,11 +11,11 @@ extern { static VOID2: Void = unsafe { std::mem::transmute(()) }; //~ ERROR static of uninhabited type //~| WARN: previously accepted -//~| ERROR undefined behavior to use this value +//~| ERROR could not evaluate static initializer //~| WARN: type `Void` does not permit zero-initialization static NEVER2: Void = unsafe { std::mem::transmute(()) }; //~ ERROR static of uninhabited type //~| WARN: previously accepted -//~| ERROR undefined behavior to use this value +//~| ERROR could not evaluate static initializer //~| WARN: type `Void` does not permit zero-initialization fn main() {} diff --git a/src/test/ui/statics/uninhabited-static.stderr b/src/test/ui/statics/uninhabited-static.stderr index c38cf10d6e648..1e0becb7d5aa8 100644 --- a/src/test/ui/statics/uninhabited-static.stderr +++ b/src/test/ui/statics/uninhabited-static.stderr @@ -43,23 +43,17 @@ LL | static NEVER2: Void = unsafe { std::mem::transmute(()) }; = note: for more information, see issue #74840 = note: uninhabited statics cannot be initialized, and any access would be an immediate error -error[E0080]: it is undefined behavior to use this value - --> $DIR/uninhabited-static.rs:12:1 +error[E0080]: could not evaluate static initializer + --> $DIR/uninhabited-static.rs:12:31 | LL | static VOID2: Void = unsafe { std::mem::transmute(()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Void - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 0, align: 1) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type -error[E0080]: it is undefined behavior to use this value - --> $DIR/uninhabited-static.rs:16:1 +error[E0080]: could not evaluate static initializer + --> $DIR/uninhabited-static.rs:16:32 | LL | static NEVER2: Void = unsafe { std::mem::transmute(()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Void - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 0, align: 1) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type warning: the type `Void` does not permit zero-initialization --> $DIR/uninhabited-static.rs:12:31 diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs new file mode 100644 index 0000000000000..b37ec2696de2f --- /dev/null +++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs @@ -0,0 +1,29 @@ +// Verifies that MIR building for a call expression respects +// privacy when checking if a call return type is uninhabited. + +pub mod widget { + enum Unimplemented {} + pub struct Widget(Unimplemented); + + impl Widget { + pub fn new() -> Widget { + todo!(); + } + } + + pub fn f() { + let x: &mut u32; + Widget::new(); + // Ok. Widget type returned from new is known to be uninhabited + // and the following code is considered unreachable. + *x = 1; + } +} + +fn main() { + let y: &mut u32; + widget::Widget::new(); + // Error. Widget type is not known to be uninhabited here, + // so the following code is considered reachable. + *y = 2; //~ ERROR use of possibly-uninitialized variable +} diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr new file mode 100644 index 0000000000000..fb1953411685e --- /dev/null +++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr @@ -0,0 +1,9 @@ +error[E0381]: use of possibly-uninitialized variable: `y` + --> $DIR/privately-uninhabited-mir-call.rs:28:5 + | +LL | *y = 2; + | ^^^^^^ use of possibly-uninitialized `y` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr index 33f762ccf6301..e7960960774fc 100644 --- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr @@ -1,11 +1,27 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/issue-45087-unreachable-unsafe.rs:6:5 + --> $DIR/issue-45087-unreachable-unsafe.rs:7:5 | LL | *(1 as *mut u32) = 42; | ^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to previous error +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:17:5 + | +LL | *a = 1; + | ^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:29:5 + | +LL | *b = 1; + | ^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs index 071cea8fbd78b..3e3da667c0b08 100644 --- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs @@ -1,3 +1,4 @@ +// Verify that unreachable code undergoes unsafety checks. // revisions: mir thir // [thir]compile-flags: -Z thir-unsafeck @@ -6,3 +7,25 @@ fn main() { *(1 as *mut u32) = 42; //~^ ERROR dereference of raw pointer is unsafe } + +fn panic() -> ! { + panic!(); +} + +fn f(a: *mut u32) { + panic(); + *a = 1; + //~^ ERROR dereference of raw pointer is unsafe +} + +enum Void {} + +fn uninhabited() -> Void { + panic!(); +} + +fn g(b: *mut u32) { + uninhabited(); + *b = 1; + //~^ ERROR dereference of raw pointer is unsafe +} diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr index 73a113652b833..e81adad450750 100644 --- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr @@ -1,11 +1,27 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/issue-45087-unreachable-unsafe.rs:6:5 + --> $DIR/issue-45087-unreachable-unsafe.rs:7:5 | LL | *(1 as *mut u32) = 42; | ^^^^^^^^^^^^^^^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to previous error +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:17:5 + | +LL | *a = 1; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:29:5 + | +LL | *b = 1; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0133`.