about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-22 06:53:36 +0000
committerbors <bors@rust-lang.org>2023-01-22 06:53:36 +0000
commit940d00f2f64a0d1e11a546c13bd02ae58d699417 (patch)
tree7a25a6ec3b9a787d7394f1e7e7b2f0b2584351f6
parent85da15c016f74d7382f243cd92bb12515a8a518f (diff)
parent31f9f21412958d19de26a2079990ce7707fb7bd1 (diff)
downloadrust-940d00f2f64a0d1e11a546c13bd02ae58d699417.tar.gz
rust-940d00f2f64a0d1e11a546c13bd02ae58d699417.zip
Auto merge of #107185 - compiler-errors:rollup-wkomjma, r=compiler-errors
Rollup of 8 pull requests

Successful merges:

 - #103418 (Add `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` to future-incompat report)
 - #106113 (llvm-wrapper: adapt for LLVM API change)
 - #106144 (Improve the documentation of `black_box`)
 - #106578 (Label closure captures/generator locals that make opaque types recursive)
 - #106749 (Update cc to 1.0.77)
 - #106935 (Fix `SingleUseLifetime` ICE)
 - #107015 (Re-enable building rust-analyzer on riscv64)
 - #107029 (Add new bootstrap members to triagebot.toml)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs59
-rw-r--r--compiler/rustc_lint/src/context.rs47
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs1
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp20
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs22
-rw-r--r--library/core/src/hint.rs69
-rw-r--r--src/bootstrap/dist.rs6
-rw-r--r--tests/ui/impl-trait/recursive-generator.rs23
-rw-r--r--tests/ui/impl-trait/recursive-generator.stderr19
-rw-r--r--tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr4
-rw-r--r--tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr137
-rw-r--r--tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr15
-rw-r--r--tests/ui/macros/issue-84195-lint-anon-const.stderr19
-rw-r--r--tests/ui/macros/lint-trailing-macro-call.stderr17
-rw-r--r--tests/ui/macros/macro-context.stderr15
-rw-r--r--tests/ui/macros/macro-in-expression-context.stderr17
-rw-r--r--tests/ui/single-use-lifetime/issue-104440.rs100
-rw-r--r--tests/ui/single-use-lifetime/issue-104440.stderr28
-rw-r--r--triagebot.toml4
21 files changed, 577 insertions, 51 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 640d4d2ec26..cc1b5dcf6a7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -551,9 +551,9 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.76"
+version = "1.0.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f"
+checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
 dependencies = [
  "jobserver",
 ]
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index aa75132444a..abc1c2d7b8d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1391,11 +1391,15 @@ fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed
 ///
 /// If all the return expressions evaluate to `!`, then we explain that the error will go away
 /// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
-fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> ErrorGuaranteed {
+fn opaque_type_cycle_error(
+    tcx: TyCtxt<'_>,
+    opaque_def_id: LocalDefId,
+    span: Span,
+) -> ErrorGuaranteed {
     let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
 
     let mut label = false;
-    if let Some((def_id, visitor)) = get_owner_return_paths(tcx, def_id) {
+    if let Some((def_id, visitor)) = get_owner_return_paths(tcx, opaque_def_id) {
         let typeck_results = tcx.typeck(def_id);
         if visitor
             .returns
@@ -1431,21 +1435,30 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> E
                 .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
                 .filter(|(_, ty)| !matches!(ty.kind(), ty::Never))
             {
-                struct OpaqueTypeCollector(Vec<DefId>);
+                #[derive(Default)]
+                struct OpaqueTypeCollector {
+                    opaques: Vec<DefId>,
+                    closures: Vec<DefId>,
+                }
                 impl<'tcx> ty::visit::TypeVisitor<'tcx> for OpaqueTypeCollector {
                     fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
                         match *t.kind() {
                             ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
-                                self.0.push(def);
+                                self.opaques.push(def);
                                 ControlFlow::Continue(())
                             }
+                            ty::Closure(def_id, ..) | ty::Generator(def_id, ..) => {
+                                self.closures.push(def_id);
+                                t.super_visit_with(self)
+                            }
                             _ => t.super_visit_with(self),
                         }
                     }
                 }
-                let mut visitor = OpaqueTypeCollector(vec![]);
+
+                let mut visitor = OpaqueTypeCollector::default();
                 ty.visit_with(&mut visitor);
-                for def_id in visitor.0 {
+                for def_id in visitor.opaques {
                     let ty_span = tcx.def_span(def_id);
                     if !seen.contains(&ty_span) {
                         err.span_label(ty_span, &format!("returning this opaque type `{ty}`"));
@@ -1453,6 +1466,40 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> E
                     }
                     err.span_label(sp, &format!("returning here with type `{ty}`"));
                 }
+
+                for closure_def_id in visitor.closures {
+                    let Some(closure_local_did) = closure_def_id.as_local() else { continue; };
+                    let typeck_results = tcx.typeck(closure_local_did);
+
+                    let mut label_match = |ty: Ty<'_>, span| {
+                        for arg in ty.walk() {
+                            if let ty::GenericArgKind::Type(ty) = arg.unpack()
+                                && let ty::Alias(ty::Opaque, ty::AliasTy { def_id: captured_def_id, .. }) = *ty.kind()
+                                && captured_def_id == opaque_def_id.to_def_id()
+                            {
+                                err.span_label(
+                                    span,
+                                    format!(
+                                        "{} captures itself here",
+                                        tcx.def_kind(closure_def_id).descr(closure_def_id)
+                                    ),
+                                );
+                            }
+                        }
+                    };
+
+                    // Label any closure upvars that capture the opaque
+                    for capture in typeck_results.closure_min_captures_flattened(closure_local_did)
+                    {
+                        label_match(capture.place.ty(), capture.get_path_span(tcx));
+                    }
+                    // Label any generator locals that capture the opaque
+                    for interior_ty in
+                        typeck_results.generator_interior_types.as_ref().skip_binder()
+                    {
+                        label_match(interior_ty.ty, interior_ty.span);
+                    }
+                }
             }
         }
     }
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index c9b9a622571..8046cc21cea 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -825,21 +825,24 @@ pub trait LintContext: Sized {
                     debug!(?param_span, ?use_span, ?deletion_span);
                     db.span_label(param_span, "this lifetime...");
                     db.span_label(use_span, "...is used only here");
-                    let msg = "elide the single-use lifetime";
-                    let (use_span, replace_lt) = if elide {
-                        let use_span = sess.source_map().span_extend_while(
-                            use_span,
-                            char::is_whitespace,
-                        ).unwrap_or(use_span);
-                        (use_span, String::new())
-                    } else {
-                        (use_span, "'_".to_owned())
-                    };
-                    db.multipart_suggestion(
-                        msg,
-                        vec![(deletion_span, String::new()), (use_span, replace_lt)],
-                        Applicability::MachineApplicable,
-                    );
+                    if let Some(deletion_span) = deletion_span {
+                        let msg = "elide the single-use lifetime";
+                        let (use_span, replace_lt) = if elide {
+                            let use_span = sess.source_map().span_extend_while(
+                                use_span,
+                                char::is_whitespace,
+                            ).unwrap_or(use_span);
+                            (use_span, String::new())
+                        } else {
+                            (use_span, "'_".to_owned())
+                        };
+                        debug!(?deletion_span, ?use_span);
+                        db.multipart_suggestion(
+                            msg,
+                            vec![(deletion_span, String::new()), (use_span, replace_lt)],
+                            Applicability::MachineApplicable,
+                        );
+                    }
                 },
                 BuiltinLintDiagnostics::SingleUseLifetime {
                     param_span: _,
@@ -847,12 +850,14 @@ pub trait LintContext: Sized {
                     deletion_span,
                 } => {
                     debug!(?deletion_span);
-                    db.span_suggestion(
-                        deletion_span,
-                        "elide the unused lifetime",
-                        "",
-                        Applicability::MachineApplicable,
-                    );
+                    if let Some(deletion_span) = deletion_span {
+                        db.span_suggestion(
+                            deletion_span,
+                            "elide the unused lifetime",
+                            "",
+                            Applicability::MachineApplicable,
+                        );
+                    }
                 },
                 BuiltinLintDiagnostics::NamedArgumentUsedPositionally{ position_sp_to_replace, position_sp_for_msg, named_arg_sp, named_arg_name, is_formatting_arg} => {
                     db.span_label(named_arg_sp, "this named argument is referred to by position in formatting string");
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index e919baafe85..b6481d70bc8 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3015,6 +3015,7 @@ declare_lint! {
     "trailing semicolon in macro body used as expression",
     @future_incompatible = FutureIncompatibleInfo {
         reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>",
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
     };
 }
 
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 9aca485e502..7054d1e9f10 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -503,7 +503,7 @@ pub enum BuiltinLintDiagnostics {
         param_span: Span,
         /// Span of the code that should be removed when eliding this lifetime.
         /// This span should include leading or trailing comma.
-        deletion_span: Span,
+        deletion_span: Option<Span>,
         /// Span of the single use, or None if the lifetime is never used.
         /// If true, the lifetime will be fully elided.
         use_span: Option<(Span, bool)>,
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 8f94e8a4ab2..87b0e1273eb 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1349,18 +1349,16 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
     return LLVMBFloatTypeKind;
   case Type::X86_AMXTyID:
     return LLVMX86_AMXTypeKind;
-#if LLVM_VERSION_GE(15, 0) && LLVM_VERSION_LT(16, 0)
-  case Type::DXILPointerTyID:
-    report_fatal_error("Rust does not support DirectX typed pointers.");
-    break;
-#endif
-#if LLVM_VERSION_GE(16, 0)
-  case Type::TypedPointerTyID:
-    report_fatal_error("Rust does not support typed pointers.");
-    break;
-#endif
+  default:
+    {
+      std::string error;
+      llvm::raw_string_ostream stream(error);
+      stream << "Rust does not support the TypeID: " << unwrap(Ty)->getTypeID()
+             << " for the type: " << *unwrap(Ty);
+      stream.flush();
+      report_fatal_error(error.c_str());
+    }
   }
-  report_fatal_error("Unhandled TypeID.");
 }
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index d92b046d0b9..6d448433ee6 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2188,15 +2188,31 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
             let deletion_span = || {
                 if params.len() == 1 {
                     // if sole lifetime, remove the entire `<>` brackets
-                    generics_span
+                    Some(generics_span)
                 } else if param_index == 0 {
                     // if removing within `<>` brackets, we also want to
                     // delete a leading or trailing comma as appropriate
-                    param.span().to(params[param_index + 1].span().shrink_to_lo())
+                    match (
+                        param.span().find_ancestor_inside(generics_span),
+                        params[param_index + 1].span().find_ancestor_inside(generics_span),
+                    ) {
+                        (Some(param_span), Some(next_param_span)) => {
+                            Some(param_span.to(next_param_span.shrink_to_lo()))
+                        }
+                        _ => None,
+                    }
                 } else {
                     // if removing within `<>` brackets, we also want to
                     // delete a leading or trailing comma as appropriate
-                    params[param_index - 1].span().shrink_to_hi().to(param.span())
+                    match (
+                        param.span().find_ancestor_inside(generics_span),
+                        params[param_index - 1].span().find_ancestor_inside(generics_span),
+                    ) {
+                        (Some(param_span), Some(prev_param_span)) => {
+                            Some(prev_param_span.shrink_to_hi().to(param_span))
+                        }
+                        _ => None,
+                    }
                 }
             };
             match use_set {
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index e8d724ab1ef..5a76e866923 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -219,6 +219,75 @@ pub fn spin_loop() {
 /// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
 ///
 /// [`std::convert::identity`]: crate::convert::identity
+///
+/// # When is this useful?
+///
+/// First and foremost: `black_box` does _not_ guarantee any exact behavior and, in some cases, may
+/// do nothing at all. As such, it **must not be relied upon to control critical program behavior.**
+/// This _immediately_ precludes any direct use of this function for cryptographic or security
+/// purposes.
+///
+/// While not suitable in those mission-critical cases, `back_box`'s functionality can generally be
+/// relied upon for benchmarking, and should be used there. It will try to ensure that the
+/// compiler doesn't optimize away part of the intended test code based on context. For
+/// example:
+///
+/// ```
+/// fn contains(haystack: &[&str], needle: &str) -> bool {
+///     haystack.iter().any(|x| x == &needle)
+/// }
+///
+/// pub fn benchmark() {
+///     let haystack = vec!["abc", "def", "ghi", "jkl", "mno"];
+///     let needle = "ghi";
+///     for _ in 0..10 {
+///         contains(&haystack, needle);
+///     }
+/// }
+/// ```
+///
+/// The compiler could theoretically make optimizations like the following:
+///
+/// - `needle` and `haystack` are always the same, move the call to `contains` outside the loop and
+///   delete the loop
+/// - Inline `contains`
+/// - `needle` and `haystack` have values known at compile time, `contains` is always true. Remove
+///   the call and replace with `true`
+/// - Nothing is done with the result of `contains`: delete this function call entirely
+/// - `benchmark` now has no purpose: delete this function
+///
+/// It is not likely that all of the above happens, but the compiler is definitely able to make some
+/// optimizations that could result in a very inaccurate benchmark. This is where `black_box` comes
+/// in:
+///
+/// ```
+/// use std::hint::black_box;
+///
+/// // Same `contains` function
+/// fn contains(haystack: &[&str], needle: &str) -> bool {
+///     haystack.iter().any(|x| x == &needle)
+/// }
+///
+/// pub fn benchmark() {
+///     let haystack = vec!["abc", "def", "ghi", "jkl", "mno"];
+///     let needle = "ghi";
+///     for _ in 0..10 {
+///         // Adjust our benchmark loop contents
+///         black_box(contains(black_box(&haystack), black_box(needle)));
+///     }
+/// }
+/// ```
+///
+/// This essentially tells the compiler to block optimizations across any calls to `black_box`. So,
+/// it now:
+///
+/// - Treats both arguments to `contains` as unpredictable: the body of `contains` can no longer be
+///   optimized based on argument values
+/// - Treats the call to `contains` and its result as volatile: the body of `benchmark` cannot
+///   optimize this away
+///
+/// This makes our benchmark much more realistic to how the function would be used in situ, where
+/// arguments are usually not known at compile time and the result is used in some way.
 #[inline]
 #[stable(feature = "bench_black_box", since = "1.66.0")]
 #[rustc_const_unstable(feature = "const_black_box", issue = "none")]
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 68215790bed..2e4f753965d 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1130,12 +1130,6 @@ impl Step for RustAnalyzer {
         let compiler = self.compiler;
         let target = self.target;
 
-        if target.contains("riscv64") {
-            // riscv64 currently has an LLVM bug that makes rust-analyzer unable
-            // to build. See #74813 for details.
-            return None;
-        }
-
         let rust_analyzer = builder
             .ensure(tool::RustAnalyzer { compiler, target })
             .expect("rust-analyzer always builds");
diff --git a/tests/ui/impl-trait/recursive-generator.rs b/tests/ui/impl-trait/recursive-generator.rs
new file mode 100644
index 00000000000..e876f0fb43f
--- /dev/null
+++ b/tests/ui/impl-trait/recursive-generator.rs
@@ -0,0 +1,23 @@
+#![feature(generators, generator_trait)]
+
+use std::ops::{Generator, GeneratorState};
+
+fn foo() -> impl Generator<Yield = (), Return = ()> {
+    //~^ ERROR cannot resolve opaque type
+    //~| NOTE recursive opaque type
+    //~| NOTE in this expansion of desugaring of
+    || {
+    //~^ NOTE returning here
+        let mut gen = Box::pin(foo());
+        //~^ NOTE generator captures itself here
+        let mut r = gen.as_mut().resume(());
+        while let GeneratorState::Yielded(v) = r {
+            yield v;
+            r = gen.as_mut().resume(());
+        }
+    }
+}
+
+fn main() {
+    foo();
+}
diff --git a/tests/ui/impl-trait/recursive-generator.stderr b/tests/ui/impl-trait/recursive-generator.stderr
new file mode 100644
index 00000000000..e23fd4b4a85
--- /dev/null
+++ b/tests/ui/impl-trait/recursive-generator.stderr
@@ -0,0 +1,19 @@
+error[E0720]: cannot resolve opaque type
+  --> $DIR/recursive-generator.rs:5:13
+   |
+LL |   fn foo() -> impl Generator<Yield = (), Return = ()> {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type
+...
+LL | /     || {
+LL | |
+LL | |         let mut gen = Box::pin(foo());
+   | |             ------- generator captures itself here
+LL | |
+...  |
+LL | |         }
+LL | |     }
+   | |_____- returning here with type `[generator@$DIR/recursive-generator.rs:9:5: 9:7]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
index 2e34d3d4275..ebb231ae14f 100644
--- a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
+++ b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
@@ -53,6 +53,7 @@ LL |   fn closure_capture() -> impl Sized {
 ...
 LL | /     move || {
 LL | |         x;
+   | |         - closure captures itself here
 LL | |     }
    | |_____- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:35:5: 35:12]`
 
@@ -64,6 +65,7 @@ LL |   fn closure_ref_capture() -> impl Sized {
 ...
 LL | /     move || {
 LL | |         &x;
+   | |          - closure captures itself here
 LL | |     }
    | |_____- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:43:5: 43:12]`
 
@@ -94,6 +96,7 @@ LL |   fn generator_capture() -> impl Sized {
 LL | /     move || {
 LL | |         yield;
 LL | |         x;
+   | |         - generator captures itself here
 LL | |     }
    | |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:61:5: 61:12]`
 
@@ -114,6 +117,7 @@ LL |   fn generator_hold() -> impl Sized {
 LL |
 LL | /     move || {
 LL | |         let x = generator_hold();
+   | |             - generator captures itself here
 LL | |         yield;
 LL | |         x;
 LL | |     }
diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr
index 49608c20524..c6012006164 100644
--- a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr
+++ b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr
@@ -46,3 +46,140 @@ LL |     let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_
 
 warning: 3 warnings emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+   |
+LL |         true;
+   |             ^
+...
+LL |         foo!(first)
+   |         ----------- in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: macro invocations at the end of a block are treated as expressions
+   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+note: the lint level is defined here
+  --> $DIR/semicolon-in-expressions-from-macros.rs:24:13
+   |
+LL |     #[allow(semicolon_in_expressions_from_macros)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+   |
+LL |         true;
+   |             ^
+...
+LL |     let _ = foo!(second);
+   |             ------------ in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+  --> $DIR/semicolon-in-expressions-from-macros.rs:29:13
+   |
+LL |     #[allow(semicolon_in_expressions_from_macros)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+   |
+LL |         true;
+   |             ^
+...
+LL |         let _ = foo!(third);
+   |                 ----------- in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+  --> $DIR/semicolon-in-expressions-from-macros.rs:32:13
+   |
+LL |     #[allow(semicolon_in_expressions_from_macros)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+   |
+LL |         true;
+   |             ^
+...
+LL |         let _ = foo!(fourth);
+   |                 ------------ in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+  --> $DIR/semicolon-in-expressions-from-macros.rs:37:13
+   |
+LL |     #[allow(semicolon_in_expressions_from_macros)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+   |
+LL |         true;
+   |             ^
+...
+LL |         foo!(warn_in_block)
+   |         ------------------- in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: macro invocations at the end of a block are treated as expressions
+   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+note: the lint level is defined here
+  --> $DIR/semicolon-in-expressions-from-macros.rs:4:9
+   |
+LL | #![warn(semicolon_in_expressions_from_macros)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+   |
+LL |         true;
+   |             ^
+...
+LL |     let _ = foo!(warn_in_expr);
+   |             ------------------ in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+  --> $DIR/semicolon-in-expressions-from-macros.rs:4:9
+   |
+LL | #![warn(semicolon_in_expressions_from_macros)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+   |
+LL |         true;
+   |             ^
+...
+LL |     let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work);
+   |                                                            ------------------------- in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+  --> $DIR/semicolon-in-expressions-from-macros.rs:4:9
+   |
+LL | #![warn(semicolon_in_expressions_from_macros)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr b/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
index 16c152eb23c..0fec4996f1a 100644
--- a/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
+++ b/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
@@ -14,3 +14,18 @@ LL |         _ => foo!()
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/warn-semicolon-in-expressions-from-macros.rs:6:13
+   |
+LL |         true;
+   |             ^
+...
+LL |         _ => foo!()
+   |              ------ in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/macros/issue-84195-lint-anon-const.stderr b/tests/ui/macros/issue-84195-lint-anon-const.stderr
index 306c08b1357..29ccd17e069 100644
--- a/tests/ui/macros/issue-84195-lint-anon-const.stderr
+++ b/tests/ui/macros/issue-84195-lint-anon-const.stderr
@@ -18,3 +18,22 @@ LL | #![deny(semicolon_in_expressions_from_macros)]
 
 error: aborting due to previous error
 
+Future incompatibility report: Future breakage diagnostic:
+error: trailing semicolon in macro used in expression position
+  --> $DIR/issue-84195-lint-anon-const.rs:8:14
+   |
+LL |     () => { 0; };
+   |              ^
+...
+LL |     let val: [u8; len!()] = [];
+   |                   ------ in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+  --> $DIR/issue-84195-lint-anon-const.rs:5:9
+   |
+LL | #![deny(semicolon_in_expressions_from_macros)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in the macro `len` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/macros/lint-trailing-macro-call.stderr b/tests/ui/macros/lint-trailing-macro-call.stderr
index 6ab121f7c06..13cecc3a31d 100644
--- a/tests/ui/macros/lint-trailing-macro-call.stderr
+++ b/tests/ui/macros/lint-trailing-macro-call.stderr
@@ -16,3 +16,20 @@ LL |     expand_it!()
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/lint-trailing-macro-call.rs:9:25
+   |
+LL |         #[cfg(FALSE)] 25;
+   |                         ^
+...
+LL |     expand_it!()
+   |     ------------ in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: macro invocations at the end of a block are treated as expressions
+   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `expand_it`
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+   = note: this warning originates in the macro `expand_it` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/macros/macro-context.stderr b/tests/ui/macros/macro-context.stderr
index f597c398b7c..7785f415946 100644
--- a/tests/ui/macros/macro-context.stderr
+++ b/tests/ui/macros/macro-context.stderr
@@ -82,3 +82,18 @@ error: aborting due to 6 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0412, E0425.
 For more information about an error, try `rustc --explain E0412`.
+Future incompatibility report: Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/macro-context.rs:3:15
+   |
+LL |     () => ( i ; typeof );
+   |               ^
+...
+LL |     let i = m!();
+   |             ---- in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+   = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/macros/macro-in-expression-context.stderr b/tests/ui/macros/macro-in-expression-context.stderr
index 36aba8aa08a..3f492b141a5 100644
--- a/tests/ui/macros/macro-in-expression-context.stderr
+++ b/tests/ui/macros/macro-in-expression-context.stderr
@@ -31,3 +31,20 @@ LL |     foo!()
 
 error: aborting due to previous error; 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/macro-in-expression-context.rs:5:29
+   |
+LL |         assert_eq!("A", "A");
+   |                             ^
+...
+LL |     foo!()
+   |     ------ in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: macro invocations at the end of a block are treated as expressions
+   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/single-use-lifetime/issue-104440.rs b/tests/ui/single-use-lifetime/issue-104440.rs
new file mode 100644
index 00000000000..0795e95303a
--- /dev/null
+++ b/tests/ui/single-use-lifetime/issue-104440.rs
@@ -0,0 +1,100 @@
+#![feature(decl_macro, rustc_attrs)]
+#![deny(single_use_lifetimes)]
+
+mod type_params {
+    macro m($T:ident) {
+        fn f<$T: Clone, T: PartialEq>(t1: $T, t2: T) -> ($T, bool) {
+            (t1.clone(), t2 == t2)
+        }
+    }
+
+    #[rustc_macro_transparency = "semitransparent"]
+    macro n($T:ident) {
+        fn g<$T: Clone>(t1: $T, t2: T) -> (T, $T) {
+            (t1.clone(), t2.clone())
+        }
+        fn h<T: Clone>(t1: $T, t2: T) -> (T, $T) {
+            (t1.clone(), t2.clone())
+        }
+    }
+
+    #[rustc_macro_transparency = "transparent"]
+    macro p($T:ident) {
+        fn j<$T: Clone>(t1: $T, t2: T) -> (T, $T) {
+            (t1.clone(), t2.clone())
+        }
+        fn k<T: Clone>(t1: $T, t2: T) -> (T, $T) {
+            (t1.clone(), t2.clone())
+        }
+    }
+
+    m!(T);
+    n!(T);
+    p!(T);
+}
+
+mod lifetime_params {
+    macro m($a:lifetime) {
+        fn f<'b, 'c, $a: 'b, 'a: 'c>(t1: &$a(), t2: &'a ()) -> (&'b (), &'c ()) { //~ ERROR lifetime parameter `'a` only used once
+            (t1, t2)
+        }
+    }
+
+    #[rustc_macro_transparency = "semitransparent"]
+    macro n($a:lifetime) {
+        fn g<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
+            (t1, t2)
+        }
+        fn h<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
+            (t1, t2)
+        }
+    }
+
+    #[rustc_macro_transparency = "transparent"]
+    macro p($a:lifetime) {
+        fn j<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
+            (t1, t2)
+        }
+        fn k<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) {
+            (t1, t2)
+        }
+    }
+
+    m!('a); //~ ERROR lifetime parameter `'a` only used once
+    n!('a);
+    p!('a);
+}
+
+mod const_params {
+    macro m($C:ident) {
+        fn f<const $C: usize, const C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); $C], [(); C]) {
+            (t1, t2)
+        }
+    }
+
+    #[rustc_macro_transparency = "semitransparent"]
+    macro n($C:ident) {
+        fn g<const $C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) {
+            (t1, t2)
+        }
+        fn h<const C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) {
+            (t1, t2)
+        }
+    }
+
+    #[rustc_macro_transparency = "transparent"]
+    macro p($C:ident) {
+        fn j<const $C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) {
+            (t1, t2)
+        }
+        fn k<const C: usize>(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) {
+            (t1, t2)
+        }
+    }
+
+    m!(C);
+    n!(C);
+    p!(C);
+}
+
+fn main() {}
diff --git a/tests/ui/single-use-lifetime/issue-104440.stderr b/tests/ui/single-use-lifetime/issue-104440.stderr
new file mode 100644
index 00000000000..54ded31dcbe
--- /dev/null
+++ b/tests/ui/single-use-lifetime/issue-104440.stderr
@@ -0,0 +1,28 @@
+error: lifetime parameter `'a` only used once
+  --> $DIR/issue-104440.rs:63:8
+   |
+LL |     m!('a);
+   |        ^^
+   |        |
+   |        this lifetime...
+   |        ...is used only here
+   |
+note: the lint level is defined here
+  --> $DIR/issue-104440.rs:2:9
+   |
+LL | #![deny(single_use_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: lifetime parameter `'a` only used once
+  --> $DIR/issue-104440.rs:38:30
+   |
+LL |         fn f<'b, 'c, $a: 'b, 'a: 'c>(t1: &$a(), t2: &'a ()) -> (&'b (), &'c ()) {
+   |                              ^^ this lifetime...     -- ...is used only here
+...
+LL |     m!('a);
+   |     ------ in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
diff --git a/triagebot.toml b/triagebot.toml
index bfbbae6857f..16a31321513 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -175,7 +175,7 @@ exclude_labels = [
     "T-*",
 ]
 
-[autolabel."A-bootstrap"]
+[autolabel."T-bootstrap"]
 trigger_files = [
     "x.py",
     "x",
@@ -493,6 +493,8 @@ libs = [
 ]
 bootstrap = [
     "@Mark-Simulacrum",
+    "@albertlarsan68",
+    "@ozkanonur",
 ]
 infra-ci = [
     "@Mark-Simulacrum",