about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-09-22 21:46:07 +0000
committerbors <bors@rust-lang.org>2023-09-22 21:46:07 +0000
commite4133ba9b1a150ef624f5d189913a37405f4414c (patch)
tree8f46010bc46c0e63f1e8ce1a8935c4672ece17fd
parentaadb5718dd9a2f4b9c64893baedfe1f5991d6bbd (diff)
parentefee13ab33572c3f8ea2eb88886d15c8a13c4d0b (diff)
downloadrust-e4133ba9b1a150ef624f5d189913a37405f4414c.tar.gz
rust-e4133ba9b1a150ef624f5d189913a37405f4414c.zip
Auto merge of #116077 - matthiaskrgr:rollup-2y1buzg, r=matthiaskrgr
Rollup of 6 pull requests

Successful merges:

 - #115770 (Match on elem first while building move paths)
 - #115999 (Capture scrutinee of if let guards correctly)
 - #116056 (Make unsized casts illegal)
 - #116061 (Remove TaKO8Ki from review rotation)
 - #116062 (Change `start` to `#[start]` in some diagnosis)
 - #116067 (Open the FileEncoder file for reading and writing)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0647.md2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl20
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs145
-rw-r--r--compiler/rustc_serialize/src/opaque.rs7
-rw-r--r--tests/ui/async-await/issue-68523-start.rs2
-rw-r--r--tests/ui/async-await/issue-68523-start.stderr4
-rw-r--r--tests/ui/cast/unsized-struct-cast.rs6
-rw-r--r--tests/ui/cast/unsized-struct-cast.stderr9
-rw-r--r--tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2018.stderr33
-rw-r--r--tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2021.stderr33
-rw-r--r--tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.rs37
-rw-r--r--tests/ui/closures/2229_closure_analysis/match/if-let-guards.rs55
-rw-r--r--tests/ui/error-codes/E0132.stderr4
-rw-r--r--tests/ui/error-codes/E0647.stderr4
-rw-r--r--tests/ui/issues/issue-50714-1.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs2
-rw-r--r--tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs2
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr4
-rw-r--r--tests/ui/stats/meta-stats.rs7
-rw-r--r--triagebot.toml2
23 files changed, 334 insertions, 67 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0647.md b/compiler/rustc_error_codes/src/error_codes/E0647.md
index 8ca6e777f30..59bb47ba62a 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0647.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0647.md
@@ -7,7 +7,7 @@ Erroneous code example:
 
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
-    //^ error: start function is not allowed to have a where clause
+    //^ error: `#[start]` function is not allowed to have a where clause
     0
 }
 ```
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 1160290cdff..2a68d745c76 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -270,20 +270,20 @@ hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is hi
 hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
     .help = add `#![feature(min_specialization)]` to the crate attributes to enable
 
-hir_analysis_start_function_parameters = start function is not allowed to have type parameters
-    .label = start function cannot have type parameters
+hir_analysis_start_function_parameters = `#[start]` function is not allowed to have type parameters
+    .label = `#[start]` function cannot have type parameters
 
-hir_analysis_start_function_where = start function is not allowed to have a `where` clause
-    .label = start function cannot have a `where` clause
+hir_analysis_start_function_where = `#[start]` function is not allowed to have a `where` clause
+    .label = `#[start]` function cannot have a `where` clause
 
-hir_analysis_start_not_async = `start` is not allowed to be `async`
-    .label = `start` is not allowed to be `async`
+hir_analysis_start_not_async = `#[start]` function is not allowed to be `async`
+    .label = `#[start]` is not allowed to be `async`
 
-hir_analysis_start_not_target_feature = `start` is not allowed to have `#[target_feature]`
-    .label = `start` is not allowed to have `#[target_feature]`
+hir_analysis_start_not_target_feature = `#[start]` function is not allowed to have `#[target_feature]`
+    .label = `#[start]` function is not allowed to have `#[target_feature]`
 
-hir_analysis_start_not_track_caller = `start` is not allowed to be `#[track_caller]`
-    .label = `start` is not allowed to be `#[track_caller]`
+hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
+    .label = `#[start]` function is not allowed to be `#[track_caller]`
 
 hir_analysis_static_specialize = cannot specialize on `'static` lifetime
 
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index fa779701e61..57cd88afcdc 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -725,6 +725,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             },
                             // array-ptr-cast
                             Ptr(mt) => {
+                                if !fcx.type_is_sized_modulo_regions(fcx.param_env, mt.ty) {
+                                    return Err(CastError::IllegalCast);
+                                }
                                 self.check_ref_cast(fcx, TypeAndMut { mutbl, ty: inner_ty }, mt)
                             }
                             _ => Err(CastError::NonScalar),
@@ -735,7 +738,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             }
             _ => return Err(CastError::NonScalar),
         };
-
         if let ty::Adt(adt_def, _) = *self.expr_ty.kind() {
             if adt_def.did().krate != LOCAL_CRATE {
                 if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) {
@@ -743,7 +745,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 }
             }
         }
-
         match (t_from, t_cast) {
             // These types have invariants! can't cast into them.
             (_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 840910732d8..8bc66ac5509 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -664,10 +664,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         );
         self.walk_pat(discr_place, arm.pat, arm.guard.is_some());
 
-        if let Some(hir::Guard::If(e)) = arm.guard {
-            self.consume_expr(e)
-        } else if let Some(hir::Guard::IfLet(ref l)) = arm.guard {
-            self.consume_expr(l.init)
+        match arm.guard {
+            Some(hir::Guard::If(ref e)) => self.consume_expr(e),
+            Some(hir::Guard::IfLet(ref l)) => {
+                self.walk_local(l.init, l.pat, None, |t| t.borrow_expr(l.init, ty::ImmBorrow))
+            }
+            None => {}
         }
 
         self.consume_expr(arm.body);
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 2e3b9577b50..213b81eaac9 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -115,44 +115,125 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             let body = self.builder.body;
             let tcx = self.builder.tcx;
             let place_ty = place_ref.ty(body, tcx).ty;
-            match place_ty.kind() {
-                ty::Ref(..) | ty::RawPtr(..) => {
-                    return Err(MoveError::cannot_move_out_of(
-                        self.loc,
-                        BorrowedContent { target_place: place_ref.project_deeper(&[elem], tcx) },
-                    ));
-                }
-                ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
-                    return Err(MoveError::cannot_move_out_of(
-                        self.loc,
-                        InteriorOfTypeWithDestructor { container_ty: place_ty },
-                    ));
-                }
-                ty::Adt(adt, _) if adt.is_union() => {
-                    union_path.get_or_insert(base);
-                }
-                ty::Slice(_) => {
-                    return Err(MoveError::cannot_move_out_of(
-                        self.loc,
-                        InteriorOfSliceOrArray {
-                            ty: place_ty,
-                            is_index: matches!(elem, ProjectionElem::Index(..)),
-                        },
-                    ));
+            match elem {
+                ProjectionElem::Deref => match place_ty.kind() {
+                    ty::Ref(..) | ty::RawPtr(..) => {
+                        return Err(MoveError::cannot_move_out_of(
+                            self.loc,
+                            BorrowedContent {
+                                target_place: place_ref.project_deeper(&[elem], tcx),
+                            },
+                        ));
+                    }
+                    ty::Adt(adt, _) => {
+                        if !adt.is_box() {
+                            bug!("Adt should be a box type when Place is deref");
+                        }
+                    }
+                    ty::Bool
+                    | ty::Char
+                    | ty::Int(_)
+                    | ty::Uint(_)
+                    | ty::Float(_)
+                    | ty::Foreign(_)
+                    | ty::Str
+                    | ty::Array(_, _)
+                    | ty::Slice(_)
+                    | ty::FnDef(_, _)
+                    | ty::FnPtr(_)
+                    | ty::Dynamic(_, _, _)
+                    | ty::Closure(_, _)
+                    | ty::Generator(_, _, _)
+                    | ty::GeneratorWitness(_)
+                    | ty::GeneratorWitnessMIR(_, _)
+                    | ty::Never
+                    | ty::Tuple(_)
+                    | ty::Alias(_, _)
+                    | ty::Param(_)
+                    | ty::Bound(_, _)
+                    | ty::Infer(_)
+                    | ty::Error(_)
+                    | ty::Placeholder(_) => {
+                        bug!("When Place is Deref it's type shouldn't be {place_ty:#?}")
+                    }
+                },
+                ProjectionElem::Field(_, _) => match place_ty.kind() {
+                    ty::Adt(adt, _) => {
+                        if adt.has_dtor(tcx) {
+                            return Err(MoveError::cannot_move_out_of(
+                                self.loc,
+                                InteriorOfTypeWithDestructor { container_ty: place_ty },
+                            ));
+                        }
+                        if adt.is_union() {
+                            union_path.get_or_insert(base);
+                        }
+                    }
+                    ty::Closure(_, _) | ty::Generator(_, _, _) | ty::Tuple(_) => (),
+                    ty::Bool
+                    | ty::Char
+                    | ty::Int(_)
+                    | ty::Uint(_)
+                    | ty::Float(_)
+                    | ty::Foreign(_)
+                    | ty::Str
+                    | ty::Array(_, _)
+                    | ty::Slice(_)
+                    | ty::RawPtr(_)
+                    | ty::Ref(_, _, _)
+                    | ty::FnDef(_, _)
+                    | ty::FnPtr(_)
+                    | ty::Dynamic(_, _, _)
+                    | ty::GeneratorWitness(_)
+                    | ty::GeneratorWitnessMIR(_, _)
+                    | ty::Never
+                    | ty::Alias(_, _)
+                    | ty::Param(_)
+                    | ty::Bound(_, _)
+                    | ty::Infer(_)
+                    | ty::Error(_)
+                    | ty::Placeholder(_) => bug!(
+                        "When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
+                    ),
+                },
+                ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
+                    match place_ty.kind() {
+                        ty::Slice(_) => {
+                            return Err(MoveError::cannot_move_out_of(
+                                self.loc,
+                                InteriorOfSliceOrArray {
+                                    ty: place_ty,
+                                    is_index: matches!(elem, ProjectionElem::Index(..)),
+                                },
+                            ));
+                        }
+                        ty::Array(_, _) => (),
+                        _ => bug!("Unexpected type {:#?}", place_ty.is_array()),
+                    }
                 }
-
-                ty::Array(..) => {
-                    if let ProjectionElem::Index(..) = elem {
+                ProjectionElem::Index(_) => match place_ty.kind() {
+                    ty::Array(..) => {
                         return Err(MoveError::cannot_move_out_of(
                             self.loc,
                             InteriorOfSliceOrArray { ty: place_ty, is_index: true },
                         ));
                     }
-                }
-
-                _ => {}
-            };
-
+                    ty::Slice(_) => {
+                        return Err(MoveError::cannot_move_out_of(
+                            self.loc,
+                            InteriorOfSliceOrArray {
+                                ty: place_ty,
+                                is_index: matches!(elem, ProjectionElem::Index(..)),
+                            },
+                        ));
+                    }
+                    _ => bug!("Unexpected type {place_ty:#?}"),
+                },
+                // `OpaqueCast` only transmutes the type, so no moves there and
+                // `Downcast` only changes information about a `Place` without moving
+                // So it's safe to skip these.
+                ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (),
+            }
             if union_path.is_none() {
                 // inlined from add_move_path because of a borrowck conflict with the iterator
                 base =
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index 44855ae629c..55255439051 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -38,11 +38,16 @@ pub struct FileEncoder {
 
 impl FileEncoder {
     pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
+        // File::create opens the file for writing only. When -Zmeta-stats is enabled, the metadata
+        // encoder rewinds the file to inspect what was written. So we need to always open the file
+        // for reading and writing.
+        let file = File::options().read(true).write(true).create(true).truncate(true).open(path)?;
+
         Ok(FileEncoder {
             buf: vec![0u8; BUF_SIZE].into_boxed_slice().try_into().unwrap(),
             buffered: 0,
             flushed: 0,
-            file: File::create(path)?,
+            file,
             res: Ok(()),
         })
     }
diff --git a/tests/ui/async-await/issue-68523-start.rs b/tests/ui/async-await/issue-68523-start.rs
index 2ced88a16cc..5adc28b203a 100644
--- a/tests/ui/async-await/issue-68523-start.rs
+++ b/tests/ui/async-await/issue-68523-start.rs
@@ -4,6 +4,6 @@
 
 #[start]
 pub async fn start(_: isize, _: *const *const u8) -> isize {
-//~^ ERROR `start` is not allowed to be `async`
+//~^ ERROR `#[start]` function is not allowed to be `async`
     0
 }
diff --git a/tests/ui/async-await/issue-68523-start.stderr b/tests/ui/async-await/issue-68523-start.stderr
index 3a0a3b5dece..7c06fe3400e 100644
--- a/tests/ui/async-await/issue-68523-start.stderr
+++ b/tests/ui/async-await/issue-68523-start.stderr
@@ -1,8 +1,8 @@
-error[E0752]: `start` is not allowed to be `async`
+error[E0752]: `#[start]` function is not allowed to be `async`
   --> $DIR/issue-68523-start.rs:6:1
    |
 LL | pub async fn start(_: isize, _: *const *const u8) -> isize {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `start` is not allowed to be `async`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `#[start]` is not allowed to be `async`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/cast/unsized-struct-cast.rs b/tests/ui/cast/unsized-struct-cast.rs
new file mode 100644
index 00000000000..52bb6cedcd6
--- /dev/null
+++ b/tests/ui/cast/unsized-struct-cast.rs
@@ -0,0 +1,6 @@
+pub struct Data([u8]);
+
+fn main(){
+    const _: *const Data = &[] as *const Data;
+    //~^ ERROR: casting `&[_; 0]` as `*const Data` is invalid
+}
diff --git a/tests/ui/cast/unsized-struct-cast.stderr b/tests/ui/cast/unsized-struct-cast.stderr
new file mode 100644
index 00000000000..79b3d973c32
--- /dev/null
+++ b/tests/ui/cast/unsized-struct-cast.stderr
@@ -0,0 +1,9 @@
+error[E0606]: casting `&[_; 0]` as `*const Data` is invalid
+  --> $DIR/unsized-struct-cast.rs:4:28
+   |
+LL |     const _: *const Data = &[] as *const Data;
+   |                            ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0606`.
diff --git a/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2018.stderr b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2018.stderr
new file mode 100644
index 00000000000..394629c0001
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2018.stderr
@@ -0,0 +1,33 @@
+error[E0505]: cannot move out of `value` because it is borrowed
+  --> $DIR/if-let-guards-errors.rs:16:13
+   |
+LL |     let f = |x: &E| {
+   |             ------- borrow of `value` occurs here
+LL |         match &x {
+LL |             E::Number(_) if let E::Number(ref mut n) = *value => { }
+   |                                                        ------ borrow occurs due to use in closure
+...
+LL |     let x = value;
+   |             ^^^^^ move out of `value` occurs here
+LL |
+LL |     drop(f);
+   |          - borrow later used here
+
+error[E0382]: use of moved value: `value`
+  --> $DIR/if-let-guards-errors.rs:28:13
+   |
+LL | fn if_let_move(value: Box<E>) {
+   |                ----- move occurs because `value` has type `Box<E>`, which does not implement the `Copy` trait
+LL |     let f = |x: &E| {
+   |             ------- value moved into closure here
+LL |         match &x {
+LL |             E::Number(_) if let E::String(s) = *value => { }
+   |                                                ------ variable moved due to use in closure
+...
+LL |     let x = value;
+   |             ^^^^^ value used here after move
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0382, E0505.
+For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2021.stderr b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2021.stderr
new file mode 100644
index 00000000000..5672845019b
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.e2021.stderr
@@ -0,0 +1,33 @@
+error[E0505]: cannot move out of `value` because it is borrowed
+  --> $DIR/if-let-guards-errors.rs:16:13
+   |
+LL |     let f = |x: &E| {
+   |             ------- borrow of `*value` occurs here
+LL |         match &x {
+LL |             E::Number(_) if let E::Number(ref mut n) = *value => { }
+   |                                                        ------ borrow occurs due to use in closure
+...
+LL |     let x = value;
+   |             ^^^^^ move out of `value` occurs here
+LL |
+LL |     drop(f);
+   |          - borrow later used here
+
+error[E0382]: use of moved value: `value`
+  --> $DIR/if-let-guards-errors.rs:28:13
+   |
+LL | fn if_let_move(value: Box<E>) {
+   |                ----- move occurs because `value` has type `Box<E>`, which does not implement the `Copy` trait
+LL |     let f = |x: &E| {
+   |             ------- value moved into closure here
+LL |         match &x {
+LL |             E::Number(_) if let E::String(s) = *value => { }
+   |                                                ------ variable moved due to use in closure
+...
+LL |     let x = value;
+   |             ^^^^^ value used here after move
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0382, E0505.
+For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.rs b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.rs
new file mode 100644
index 00000000000..17e38c033b1
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/match/if-let-guards-errors.rs
@@ -0,0 +1,37 @@
+// Check the if let guards don't force capture by value
+// revisions: e2018 e2021
+//[e2018] edition:2018
+//[e2021] edition:2021
+
+#![feature(if_let_guard)]
+#![allow(irrefutable_let_patterns)]
+
+fn if_let_ref_mut(mut value: Box<E>) {
+    let f = |x: &E| {
+        match &x {
+            E::Number(_) if let E::Number(ref mut n) = *value => { }
+            _ => {}
+        }
+    };
+    let x = value;
+    //~^ ERROR cannot move out of `value` because it is borrowed
+    drop(f);
+}
+
+fn if_let_move(value: Box<E>) {
+    let f = |x: &E| {
+        match &x {
+            E::Number(_) if let E::String(s) = *value => { }
+            _ => {}
+        }
+    };
+    let x = value;
+    //~^ ERROR use of moved value: `value`
+}
+
+enum E {
+    String(String),
+    Number(i32),
+}
+
+fn main() {}
diff --git a/tests/ui/closures/2229_closure_analysis/match/if-let-guards.rs b/tests/ui/closures/2229_closure_analysis/match/if-let-guards.rs
new file mode 100644
index 00000000000..fa331707be4
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/match/if-let-guards.rs
@@ -0,0 +1,55 @@
+// Check the if let guards don't force capture by value
+// revisions: e2018 e2021
+// check-pass
+//[e2018] edition:2018
+//[e2021] edition:2021
+
+#![feature(if_let_guard)]
+#![allow(irrefutable_let_patterns)]
+
+fn if_let_underscore(value: Box<E>) {
+    |x: &E| {
+        match &x {
+            E::Number(_) if let _ = *value => { }
+            _ => {}
+        }
+    };
+    let x = value;
+}
+
+fn if_let_copy(value: Box<E>) {
+    |x: &E| {
+        match &x {
+            E::Number(_) if let E::Number(n) = *value => { }
+            _ => {}
+        }
+    };
+    let x = value;
+}
+
+fn if_let_ref(value: Box<E>) {
+    |x: &E| {
+        match &x {
+            E::Number(_) if let E::Number(ref n) = *value => { }
+            _ => {}
+        }
+    };
+    let x = value;
+}
+
+fn if_let_ref_mut(mut value: Box<E>) {
+    |x: &E| {
+        match &x {
+            E::Number(_) if let E::Number(ref mut n) = *value => { }
+            _ => {}
+        }
+    };
+    let x = value;
+}
+
+enum E {
+    String(String),
+    Number(i32),
+}
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0132.stderr b/tests/ui/error-codes/E0132.stderr
index c21363756b3..d4ddc07b521 100644
--- a/tests/ui/error-codes/E0132.stderr
+++ b/tests/ui/error-codes/E0132.stderr
@@ -1,8 +1,8 @@
-error[E0132]: start function is not allowed to have type parameters
+error[E0132]: `#[start]` function is not allowed to have type parameters
   --> $DIR/E0132.rs:4:5
    |
 LL | fn f< T >() {}
-   |     ^^^^^ start function cannot have type parameters
+   |     ^^^^^ `#[start]` function cannot have type parameters
 
 error: aborting due to previous error
 
diff --git a/tests/ui/error-codes/E0647.stderr b/tests/ui/error-codes/E0647.stderr
index 08cedfaef04..9d1ab967127 100644
--- a/tests/ui/error-codes/E0647.stderr
+++ b/tests/ui/error-codes/E0647.stderr
@@ -1,8 +1,8 @@
-error[E0647]: start function is not allowed to have a `where` clause
+error[E0647]: `#[start]` function is not allowed to have a `where` clause
   --> $DIR/E0647.rs:7:50
    |
 LL | fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
-   |                                                  ^^^^^^^^^^^^^^ start function cannot have a `where` clause
+   |                                                  ^^^^^^^^^^^^^^ `#[start]` function cannot have a `where` clause
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-50714-1.stderr b/tests/ui/issues/issue-50714-1.stderr
index 28469bee017..bacd09b2ae1 100644
--- a/tests/ui/issues/issue-50714-1.stderr
+++ b/tests/ui/issues/issue-50714-1.stderr
@@ -1,8 +1,8 @@
-error[E0647]: start function is not allowed to have a `where` clause
+error[E0647]: `#[start]` function is not allowed to have a `where` clause
   --> $DIR/issue-50714-1.rs:9:50
    |
 LL | fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq {
-   |                                                  ^^^^^^^^^^^^^^^^^ start function cannot have a `where` clause
+   |                                                  ^^^^^^^^^^^^^^^^^ `#[start]` function cannot have a `where` clause
 
 error: aborting due to previous error
 
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs
index 0cab4717063..f0e111b578f 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.rs
@@ -1,7 +1,7 @@
 #![feature(start)]
 
 #[start]
-#[track_caller] //~ ERROR `start` is not allowed to be `#[track_caller]`
+#[track_caller] //~ ERROR `#[start]` function is not allowed to be `#[track_caller]`
 fn start(_argc: isize, _argv: *const *const u8) -> isize {
     panic!("{}: oh no", std::panic::Location::caller());
 }
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr b/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr
index 454c98ff934..b6ef6215275 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-start.stderr
@@ -1,10 +1,10 @@
-error: `start` is not allowed to be `#[track_caller]`
+error: `#[start]` function is not allowed to be `#[track_caller]`
   --> $DIR/error-with-start.rs:4:1
    |
 LL | #[track_caller]
    | ^^^^^^^^^^^^^^^
 LL | fn start(_argc: isize, _argv: *const *const u8) -> isize {
-   | -------------------------------------------------------- `start` is not allowed to be `#[track_caller]`
+   | -------------------------------------------------------- `#[start]` function is not allowed to be `#[track_caller]`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs
index 50e8ce2fdd5..221c0416dbf 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs
@@ -5,5 +5,5 @@
 
 #[start]
 #[target_feature(enable = "avx2")]
-//~^ ERROR `start` is not allowed to have `#[target_feature]`
+//~^ ERROR `#[start]` function is not allowed to have `#[target_feature]`
 fn start(_argc: isize, _argv: *const *const u8) -> isize { 0 }
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr
index 07687f3c7f4..b49f8afd960 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.stderr
@@ -1,11 +1,11 @@
-error: `start` is not allowed to have `#[target_feature]`
+error: `#[start]` function is not allowed to have `#[target_feature]`
   --> $DIR/issue-108645-target-feature-on-start.rs:7:1
    |
 LL | #[target_feature(enable = "avx2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | fn start(_argc: isize, _argv: *const *const u8) -> isize { 0 }
-   | -------------------------------------------------------- `start` is not allowed to have `#[target_feature]`
+   | -------------------------------------------------------- `#[start]` function is not allowed to have `#[target_feature]`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/stats/meta-stats.rs b/tests/ui/stats/meta-stats.rs
new file mode 100644
index 00000000000..2d38e088286
--- /dev/null
+++ b/tests/ui/stats/meta-stats.rs
@@ -0,0 +1,7 @@
+// build-pass
+// dont-check-compiler-stderr
+// compile-flags: -Zmeta-stats
+
+#![crate_type = "lib"]
+
+pub fn a() {}
diff --git a/triagebot.toml b/triagebot.toml
index 4a84f3caa95..dbced481993 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -598,7 +598,6 @@ compiler-team = [
 compiler-team-contributors = [
     "@compiler-errors",
     "@jackh726",
-    "@TaKO8Ki",
     "@WaffleLapkin",
     "@b-naber",
 ]
@@ -645,7 +644,6 @@ diagnostics = [
     "@compiler-errors",
     "@davidtwco",
     "@oli-obk",
-    "@TaKO8Ki",
 ]
 parser = [
     "@compiler-errors",