From 9058bf2100499649a285e49555e42fbe8fa3556d Mon Sep 17 00:00:00 2001
From: Tyler Mandry <tmandry@gmail.com>
Date: Fri, 2 Aug 2019 17:08:16 -0700
Subject: [PATCH] Make use of possibly uninitialized data a hard error

This is one of the behaviors we no longer allow in NLL. Since it can
lead to undefined behavior, I think it's definitely worth making it a
hard error without waiting to turn off migration mode (#58781).

Closes #60450.

My ulterior motive here is making it impossible to leave variables
partially initialized across a yield (see discussion at #63035), so
tests are included for that.
---
 .../borrow_check/conflict_errors.rs           |  3 ++
 src/librustc_mir/borrow_check/mod.rs          | 12 ++++-
 .../partial-initialization-across-await.rs    | 44 ++++++++++++++++++
 ...partial-initialization-across-await.stderr | 21 +++++++++
 .../disallow-possibly-uninitialized.rs        | 22 +++++++++
 .../disallow-possibly-uninitialized.stderr    | 27 +++++++++++
 .../ui/consts/const_let_refutable.nll.stderr  | 31 -------------
 src/test/ui/consts/const_let_refutable.rs     |  8 +---
 src/test/ui/consts/const_let_refutable.stderr | 14 ++----
 .../ui/empty/empty-never-array.nll.stderr     | 23 ----------
 src/test/ui/empty/empty-never-array.rs        |  4 +-
 src/test/ui/empty/empty-never-array.stderr    |  8 +---
 .../partial-initialization-across-yield.rs    | 46 +++++++++++++++++++
 ...partial-initialization-across-yield.stderr | 21 +++++++++
 src/test/ui/issues/issue-15381.nll.stderr     | 16 -------
 src/test/ui/issues/issue-15381.rs             |  4 +-
 src/test/ui/issues/issue-15381.stderr         |  8 +---
 ...rsive-types-are-not-uninhabited.nll.stderr | 16 -------
 .../recursive-types-are-not-uninhabited.rs    |  4 +-
 ...recursive-types-are-not-uninhabited.stderr |  8 +---
 20 files changed, 209 insertions(+), 131 deletions(-)
 create mode 100644 src/test/ui/async-await/partial-initialization-across-await.rs
 create mode 100644 src/test/ui/async-await/partial-initialization-across-await.stderr
 create mode 100644 src/test/ui/borrowck/disallow-possibly-uninitialized.rs
 create mode 100644 src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
 delete mode 100644 src/test/ui/consts/const_let_refutable.nll.stderr
 delete mode 100644 src/test/ui/empty/empty-never-array.nll.stderr
 create mode 100644 src/test/ui/generator/partial-initialization-across-yield.rs
 create mode 100644 src/test/ui/generator/partial-initialization-across-yield.stderr
 delete mode 100644 src/test/ui/issues/issue-15381.nll.stderr
 delete mode 100644 src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr

diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 5d0e490ebea5a..b7e15bd8f7423 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -105,6 +105,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
             );
 
+            // This error should not be downgraded to a warning,
+            // even in migrate mode.
+            self.disable_error_downgrading();
             err.buffer(&mut self.errors_buffer);
         } else {
             if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) {
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 92774bbb7a6b4..548514081d6bf 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -252,6 +252,7 @@ fn do_mir_borrowck<'a, 'tcx>(
         move_error_reported: BTreeMap::new(),
         uninitialized_error_reported: Default::default(),
         errors_buffer,
+        disable_error_downgrading: false,
         nonlexical_regioncx: regioncx,
         used_mut: Default::default(),
         used_mut_upvars: SmallVec::new(),
@@ -363,7 +364,7 @@ fn do_mir_borrowck<'a, 'tcx>(
     if !mbcx.errors_buffer.is_empty() {
         mbcx.errors_buffer.sort_by_key(|diag| diag.span.primary_span());
 
-        if tcx.migrate_borrowck() {
+        if !mbcx.disable_error_downgrading && tcx.migrate_borrowck() {
             // When borrowck=migrate, check if AST-borrowck would
             // error on the given code.
 
@@ -479,6 +480,9 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> {
     uninitialized_error_reported: FxHashSet<PlaceRef<'cx, 'tcx>>,
     /// Errors to be reported buffer
     errors_buffer: Vec<Diagnostic>,
+    /// If there are no errors reported by the HIR borrow checker, we downgrade
+    /// all NLL errors to warnings. Setting this flag disables downgrading.
+    disable_error_downgrading: bool,
     /// This field keeps track of all the local variables that are declared mut and are mutated.
     /// Used for the warning issued by an unused mutable local variable.
     used_mut: FxHashSet<Local>,
@@ -919,6 +923,12 @@ impl InitializationRequiringAction {
 }
 
 impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+    /// If there are no errors reported by the HIR borrow checker, we downgrade
+    /// all NLL errors to warnings. Calling this disables downgrading.
+    crate fn disable_error_downgrading(&mut self)  {
+        self.disable_error_downgrading = true;
+    }
+
     /// Checks an access to the given place to see if it is allowed. Examines the set of borrows
     /// that are in scope, as well as which paths have been initialized, to ensure that (a) the
     /// place is initialized and (b) it is not borrowed in some way that would prevent this
diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs
new file mode 100644
index 0000000000000..40f9f5202e77c
--- /dev/null
+++ b/src/test/ui/async-await/partial-initialization-across-await.rs
@@ -0,0 +1,44 @@
+// Test that we don't allow awaiting from an async fn while a local is partially
+// initialized.
+
+// edition:2018
+
+#![feature(async_await)]
+
+struct S { x: i32, y: i32 }
+struct T(i32, i32);
+
+async fn noop() {}
+
+async fn test_tuple() {
+    let mut t: (i32, i32);
+    t.0 = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.1 = 88;
+    let _ = t;
+}
+
+async fn test_tuple_struct() {
+    let mut t: T;
+    t.0 = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.1 = 88;
+    let _ = t;
+}
+
+async fn test_struct() {
+    let mut t: S;
+    t.x = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.y = 88;
+    let _ = t;
+}
+
+fn main() {
+    let _ = test_tuple();
+    let _ = test_tuple_struct();
+    let _ = test_struct();
+}
diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr
new file mode 100644
index 0000000000000..fe79eb08befaa
--- /dev/null
+++ b/src/test/ui/async-await/partial-initialization-across-await.stderr
@@ -0,0 +1,21 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:15:5
+   |
+LL |     t.0 = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:24:5
+   |
+LL |     t.0 = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:33:5
+   |
+LL |     t.x = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
new file mode 100644
index 0000000000000..a987c00b09191
--- /dev/null
+++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
@@ -0,0 +1,22 @@
+// Test that we don't allow partial initialization.
+// This may be relaxed in the future (see #54987).
+
+fn main() {
+    let mut t: (u64, u64);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    t.1 = 1;
+
+    let mut t: (u64, u64);
+    t.1 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    t.0 = 1;
+
+    let mut t: (u64, u64);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+
+    let mut t: (u64,);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+}
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
new file mode 100644
index 0000000000000..a32b17b165934
--- /dev/null
+++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
@@ -0,0 +1,27 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:6:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:11:5
+   |
+LL |     t.1 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:16:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:20:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/consts/const_let_refutable.nll.stderr b/src/test/ui/consts/const_let_refutable.nll.stderr
deleted file mode 100644
index a61c9b0c9fef9..0000000000000
--- a/src/test/ui/consts/const_let_refutable.nll.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0005]: refutable pattern in function argument: `&[]` not covered
-  --> $DIR/const_let_refutable.rs:3:16
-   |
-LL | const fn slice([a, b]: &[i32]) -> i32 {
-   |                ^^^^^^ pattern `&[]` not covered
-
-error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn`
-  --> $DIR/const_let_refutable.rs:4:5
-   |
-LL |     a + b
-   |     ^^^^^
-   |
-   = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
-
-error[E0381]: use of possibly uninitialized variable: `a`
-  --> $DIR/const_let_refutable.rs:4:5
-   |
-LL |     a + b
-   |     ^ use of possibly uninitialized `a`
-
-error[E0381]: use of possibly uninitialized variable: `b`
-  --> $DIR/const_let_refutable.rs:4:9
-   |
-LL |     a + b
-   |         ^ use of possibly uninitialized `b`
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0005, E0381, E0723.
-For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/consts/const_let_refutable.rs b/src/test/ui/consts/const_let_refutable.rs
index 322048c7fbf3f..7b3a591223025 100644
--- a/src/test/ui/consts/const_let_refutable.rs
+++ b/src/test/ui/consts/const_let_refutable.rs
@@ -2,10 +2,6 @@ fn main() {}
 
 const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
     a + b //~ ERROR can only call other `const fn` within a `const fn`
-    //~^ WARN use of possibly uninitialized variable: `a`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
-    //~| WARN use of possibly uninitialized variable: `b`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `a`
+    //~| ERROR use of possibly uninitialized variable: `b`
 }
diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr
index a848b20ed98f5..a61c9b0c9fef9 100644
--- a/src/test/ui/consts/const_let_refutable.stderr
+++ b/src/test/ui/consts/const_let_refutable.stderr
@@ -13,27 +13,19 @@ LL |     a + b
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-warning[E0381]: use of possibly uninitialized variable: `a`
+error[E0381]: use of possibly uninitialized variable: `a`
   --> $DIR/const_let_refutable.rs:4:5
    |
 LL |     a + b
    |     ^ use of possibly uninitialized `a`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-warning[E0381]: use of possibly uninitialized variable: `b`
+error[E0381]: use of possibly uninitialized variable: `b`
   --> $DIR/const_let_refutable.rs:4:9
    |
 LL |     a + b
    |         ^ use of possibly uninitialized `b`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0005, E0381, E0723.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/empty/empty-never-array.nll.stderr b/src/test/ui/empty/empty-never-array.nll.stderr
deleted file mode 100644
index 01ee1c3a4d7fa..0000000000000
--- a/src/test/ui/empty/empty-never-array.nll.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0005]: refutable pattern in local binding: `T(_, _)` not covered
-  --> $DIR/empty-never-array.rs:10:9
-   |
-LL | / enum Helper<T, U> {
-LL | |     T(T, [!; 0]),
-LL | |     #[allow(dead_code)]
-LL | |     U(U),
-LL | | }
-   | |_- `Helper<T, U>` defined here
-...
-LL |       let Helper::U(u) = Helper::T(t, []);
-   |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
-
-error[E0381]: use of possibly uninitialized variable: `u`
-  --> $DIR/empty-never-array.rs:12:5
-   |
-LL |     u
-   |     ^ use of possibly uninitialized `u`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/empty/empty-never-array.rs b/src/test/ui/empty/empty-never-array.rs
index ce781da7d47e1..ffd2545b291e2 100644
--- a/src/test/ui/empty/empty-never-array.rs
+++ b/src/test/ui/empty/empty-never-array.rs
@@ -10,9 +10,7 @@ fn transmute<T, U>(t: T) -> U {
     let Helper::U(u) = Helper::T(t, []);
     //~^ ERROR refutable pattern in local binding: `T(_, _)` not covered
     u
-    //~^ WARN use of possibly uninitialized variable: `u`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `u`
 }
 
 fn main() {
diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr
index 9911dd4683b66..01ee1c3a4d7fa 100644
--- a/src/test/ui/empty/empty-never-array.stderr
+++ b/src/test/ui/empty/empty-never-array.stderr
@@ -11,17 +11,13 @@ LL | | }
 LL |       let Helper::U(u) = Helper::T(t, []);
    |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
 
-warning[E0381]: use of possibly uninitialized variable: `u`
+error[E0381]: use of possibly uninitialized variable: `u`
   --> $DIR/empty-never-array.rs:12:5
    |
 LL |     u
    |     ^ use of possibly uninitialized `u`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/generator/partial-initialization-across-yield.rs b/src/test/ui/generator/partial-initialization-across-yield.rs
new file mode 100644
index 0000000000000..1e4593002cb9a
--- /dev/null
+++ b/src/test/ui/generator/partial-initialization-across-yield.rs
@@ -0,0 +1,46 @@
+// Test that we don't allow yielding from a generator while a local is partially
+// initialized.
+
+#![feature(generators)]
+
+struct S { x: i32, y: i32 }
+struct T(i32, i32);
+
+fn test_tuple() {
+    let _ = || {
+        let mut t: (i32, i32);
+        t.0 = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.1 = 88;
+        let _ = t;
+    };
+}
+
+fn test_tuple_struct() {
+    let _ = || {
+        let mut t: T;
+        t.0 = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.1 = 88;
+        let _ = t;
+    };
+}
+
+fn test_struct() {
+    let _ = || {
+        let mut t: S;
+        t.x = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.y = 88;
+        let _ = t;
+    };
+}
+
+fn main() {
+    test_tuple();
+    test_tuple_struct();
+    test_struct();
+}
diff --git a/src/test/ui/generator/partial-initialization-across-yield.stderr b/src/test/ui/generator/partial-initialization-across-yield.stderr
new file mode 100644
index 0000000000000..8bf0037e07009
--- /dev/null
+++ b/src/test/ui/generator/partial-initialization-across-yield.stderr
@@ -0,0 +1,21 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:12:9
+   |
+LL |         t.0 = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:23:9
+   |
+LL |         t.0 = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:34:9
+   |
+LL |         t.x = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/issues/issue-15381.nll.stderr b/src/test/ui/issues/issue-15381.nll.stderr
deleted file mode 100644
index a8495846b3610..0000000000000
--- a/src/test/ui/issues/issue-15381.nll.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
-  --> $DIR/issue-15381.rs:4:9
-   |
-LL |     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
-   |         ^^^^^^^^ pattern `&[]` not covered
-
-error[E0381]: borrow of possibly uninitialized variable: `y`
-  --> $DIR/issue-15381.rs:6:26
-   |
-LL |         println!("y={}", y);
-   |                          ^ use of possibly uninitialized `y`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/issues/issue-15381.rs b/src/test/ui/issues/issue-15381.rs
index 3dbd4e717a0db..d21c321b09399 100644
--- a/src/test/ui/issues/issue-15381.rs
+++ b/src/test/ui/issues/issue-15381.rs
@@ -4,8 +4,6 @@ fn main() {
     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
         //~^ ERROR refutable pattern in `for` loop binding: `&[]` not covered
         println!("y={}", y);
-        //~^ WARN borrow of possibly uninitialized variable: `y`
-        //~| WARN this error has been downgraded to a warning for backwards compatibility
-        //~| WARN this represents potential undefined behavior in your code and this warning will
+        //~^ ERROR borrow of possibly uninitialized variable: `y`
     }
 }
diff --git a/src/test/ui/issues/issue-15381.stderr b/src/test/ui/issues/issue-15381.stderr
index 7b11d85ead874..a8495846b3610 100644
--- a/src/test/ui/issues/issue-15381.stderr
+++ b/src/test/ui/issues/issue-15381.stderr
@@ -4,17 +4,13 @@ error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
 LL |     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
    |         ^^^^^^^^ pattern `&[]` not covered
 
-warning[E0381]: borrow of possibly uninitialized variable: `y`
+error[E0381]: borrow of possibly uninitialized variable: `y`
   --> $DIR/issue-15381.rs:6:26
    |
 LL |         println!("y={}", y);
    |                          ^ use of possibly uninitialized `y`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr
deleted file mode 100644
index eee331d95b9bc..0000000000000
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/recursive-types-are-not-uninhabited.rs:6:9
-   |
-LL |     let Ok(x) = res;
-   |         ^^^^^ pattern `Err(_)` not covered
-
-error[E0381]: use of possibly uninitialized variable: `x`
-  --> $DIR/recursive-types-are-not-uninhabited.rs:8:5
-   |
-LL |     x
-   |     ^ use of possibly uninitialized `x`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
index a618aba9413f0..45910c3c3a8c6 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
@@ -6,9 +6,7 @@ fn foo(res: Result<u32, &R>) -> u32 {
     let Ok(x) = res;
     //~^ ERROR refutable pattern
     x
-    //~^ WARN use of possibly uninitialized variable: `x`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `x`
 }
 
 fn main() {
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
index 9203f893fdbf7..eee331d95b9bc 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -4,17 +4,13 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered
 LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
 
-warning[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly uninitialized variable: `x`
   --> $DIR/recursive-types-are-not-uninhabited.rs:8:5
    |
 LL |     x
    |     ^ use of possibly uninitialized `x`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.