diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 77f95869e9dac..79cff0fbcd2ee 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1716,24 +1716,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `mut iter => { ... }`
let iter_arm = self.arm(iter_pat, loop_expr);
- let into_iter_expr = match loop_kind {
+ let match_expr = match loop_kind {
ForLoopKind::For => {
// `::std::iter::IntoIterator::into_iter(
)`
- self.expr_call_lang_item_fn(
+ let into_iter_expr = self.expr_call_lang_item_fn(
head_span,
hir::LangItem::IntoIterIntoIter,
arena_vec![self; head],
- )
+ );
+
+ self.arena.alloc(self.expr_match(
+ for_span,
+ into_iter_expr,
+ arena_vec![self; iter_arm],
+ hir::MatchSource::ForLoopDesugar,
+ ))
}
- // ` unsafe { Pin::new_unchecked(&mut into_async_iter()) }`
+ // `match into_async_iter() { ref mut iter => match unsafe { Pin::new_unchecked(iter) } { ... } }`
ForLoopKind::ForAwait => {
- // `::core::async_iter::IntoAsyncIterator::into_async_iter()`
- let iter = self.expr_call_lang_item_fn(
- head_span,
- hir::LangItem::IntoAsyncIterIntoIter,
- arena_vec![self; head],
- );
- let iter = self.expr_mut_addr_of(head_span, iter);
+ let iter_ident = iter;
+ let (async_iter_pat, async_iter_pat_id) =
+ self.pat_ident_binding_mode(head_span, iter_ident, hir::BindingMode::REF_MUT);
+ let iter = self.expr_ident_mut(head_span, iter_ident, async_iter_pat_id);
// `Pin::new_unchecked(...)`
let iter = self.arena.alloc(self.expr_call_lang_item_fn_mut(
head_span,
@@ -1742,17 +1746,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
));
// `unsafe { ... }`
let iter = self.arena.alloc(self.expr_unsafe(iter));
- iter
+ let inner_match_expr = self.arena.alloc(self.expr_match(
+ for_span,
+ iter,
+ arena_vec![self; iter_arm],
+ hir::MatchSource::ForLoopDesugar,
+ ));
+
+ // `::core::async_iter::IntoAsyncIterator::into_async_iter()`
+ let iter = self.expr_call_lang_item_fn(
+ head_span,
+ hir::LangItem::IntoAsyncIterIntoIter,
+ arena_vec![self; head],
+ );
+ let iter_arm = self.arm(async_iter_pat, inner_match_expr);
+ self.arena.alloc(self.expr_match(
+ for_span,
+ iter,
+ arena_vec![self; iter_arm],
+ hir::MatchSource::ForLoopDesugar,
+ ))
}
};
- let match_expr = self.arena.alloc(self.expr_match(
- for_span,
- into_iter_expr,
- arena_vec![self; iter_arm],
- hir::MatchSource::ForLoopDesugar,
- ));
-
// This is effectively `{ let _result = ...; _result }`.
// The construct was introduced in #21984 and is necessary to make sure that
// temporaries in the `head` expression are dropped and do not leak to the
diff --git a/compiler/rustc_data_structures/src/flock.rs b/compiler/rustc_data_structures/src/flock.rs
index 008565e4c7b97..e03962a54ecab 100644
--- a/compiler/rustc_data_structures/src/flock.rs
+++ b/compiler/rustc_data_structures/src/flock.rs
@@ -9,6 +9,10 @@ cfg_match! {
mod linux;
use linux as imp;
}
+ cfg(target_os = "redox") => {
+ mod linux;
+ use linux as imp;
+ }
cfg(unix) => {
mod unix;
use unix as imp;
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 2d13f430cfce1..61c06679b7c90 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -586,6 +586,8 @@ declare_features! (
(incomplete, return_type_notation, "1.70.0", Some(109417)),
/// Allows `extern "rust-cold"`.
(unstable, rust_cold_cc, "1.63.0", Some(97544)),
+ /// Shortern the tail expression lifetime
+ (unstable, shorter_tail_lifetimes, "1.79.0", Some(123739)),
/// Allows the use of SIMD types in functions declared in `extern` blocks.
(unstable, simd_ffi, "1.0.0", Some(27731)),
/// Allows specialization of implementations (RFC 1210).
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 72e431926ca32..2b5efd3b2f6f9 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -6,7 +6,6 @@
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
-use rustc_ast::visit::visit_opt;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@@ -168,7 +167,14 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => visitor.visit_stmt(statement),
}
}
- visit_opt!(visitor, visit_expr, &blk.expr);
+ if let Some(tail_expr) = blk.expr {
+ if visitor.tcx.features().shorter_tail_lifetimes
+ && blk.span.edition().at_least_rust_2024()
+ {
+ visitor.terminating_scopes.insert(tail_expr.hir_id.local_id);
+ }
+ visitor.visit_expr(tail_expr);
+ }
}
visitor.cx = prev_cx;
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 733c73bc3d078..043042a492b54 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -550,6 +550,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
.bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
.exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
.const_anon = use a const-anon item to suppress this lint
+ .macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed
lint_non_local_definitions_impl_move_help =
move the `impl` block outside of this {$body_kind_descr} {$depth ->
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index b377da31a581b..8059f5c1a2ea7 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1362,6 +1362,7 @@ pub enum NonLocalDefinitionsDiag {
has_trait: bool,
self_ty_str: String,
of_trait_str: Option,
+ macro_to_change: Option<(String, &'static str)>,
},
MacroRules {
depth: u32,
@@ -1387,6 +1388,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
has_trait,
self_ty_str,
of_trait_str,
+ macro_to_change,
} => {
diag.primary_message(fluent::lint_non_local_definitions_impl);
diag.arg("depth", depth);
@@ -1397,6 +1399,15 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
diag.arg("of_trait_str", of_trait_str);
}
+ if let Some((macro_to_change, macro_kind)) = macro_to_change {
+ diag.arg("macro_to_change", macro_to_change);
+ diag.arg("macro_kind", macro_kind);
+ diag.note(fluent::lint_macro_to_change);
+ }
+ if let Some(cargo_update) = cargo_update {
+ diag.subdiagnostic(&diag.dcx, cargo_update);
+ }
+
if has_trait {
diag.note(fluent::lint_bounds);
diag.note(fluent::lint_with_trait);
@@ -1422,9 +1433,6 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
);
}
- if let Some(cargo_update) = cargo_update {
- diag.subdiagnostic(&diag.dcx, cargo_update);
- }
if let Some(const_anon) = const_anon {
diag.note(fluent::lint_exception);
if let Some(const_anon) = const_anon {
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index d7ffc34d824fd..b0ec6e06658f3 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -258,6 +258,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
Some((cx.tcx.def_span(parent), may_move))
};
+ let macro_to_change =
+ if let ExpnKind::Macro(kind, name) = item.span.ctxt().outer_expn_data().kind {
+ Some((name.to_string(), kind.descr()))
+ } else {
+ None
+ };
+
cx.emit_span_lint(
NON_LOCAL_DEFINITIONS,
ms,
@@ -274,6 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
move_to,
may_remove,
has_trait: impl_.of_trait.is_some(),
+ macro_to_change,
},
)
}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index c89323b7f1691..5a1ea7245b03a 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1677,6 +1677,7 @@ symbols! {
shadow_call_stack,
shl,
shl_assign,
+ shorter_tail_lifetimes,
should_panic,
shr,
shr_assign,
diff --git a/compiler/rustc_target/src/spec/base/redox.rs b/compiler/rustc_target/src/spec/base/redox.rs
index 468fe478549b2..9070791e9dfc4 100644
--- a/compiler/rustc_target/src/spec/base/redox.rs
+++ b/compiler/rustc_target/src/spec/base/redox.rs
@@ -1,4 +1,4 @@
-use crate::spec::{cvs, RelroLevel, TargetOptions};
+use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelroLevel, TargetOptions};
pub fn opts() -> TargetOptions {
TargetOptions {
@@ -12,6 +12,8 @@ pub fn opts() -> TargetOptions {
has_thread_local: true,
crt_static_default: true,
crt_static_respected: true,
+ crt_static_allows_dylibs: true,
+ late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lgcc"]),
..Default::default()
}
}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index adea2caabbe75..42860b1059ed7 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1647,6 +1647,7 @@ supported_targets! {
("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),
("aarch64-unknown-redox", aarch64_unknown_redox),
+ ("i686-unknown-redox", i686_unknown_redox),
("x86_64-unknown-redox", x86_64_unknown_redox),
("i386-apple-ios", i386_apple_ios),
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs
new file mode 100644
index 0000000000000..83252fadb78ea
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs
@@ -0,0 +1,27 @@
+use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
+
+pub fn target() -> Target {
+ let mut base = base::redox::opts();
+ base.cpu = "pentiumpro".into();
+ base.plt_by_default = false;
+ base.max_atomic_width = Some(64);
+ base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
+ // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
+ base.stack_probes = StackProbeType::Call;
+
+ Target {
+ llvm_target: "i686-unknown-redox".into(),
+ metadata: crate::spec::TargetMetadata {
+ description: None,
+ tier: None,
+ host_tools: None,
+ std: None,
+ },
+ pointer_width: 32,
+ data_layout:
+ "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
+ .into(),
+ arch: "x86".into(),
+ options: base,
+ }
+}
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index c3561512c0579..2b7ab2f6e2590 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -3516,7 +3516,7 @@ fn data_offset_align(align: usize) -> usize {
layout.size() + layout.padding_needed_for(align)
}
-/// A uniquely owned `Rc`
+/// A uniquely owned [`Rc`].
///
/// This represents an `Rc` that is known to be uniquely owned -- that is, have exactly one strong
/// reference. Multiple weak pointers can be created, but attempts to upgrade those to strong
@@ -3554,13 +3554,24 @@ fn data_offset_align(align: usize) -> usize {
/// including fallible or async constructors.
#[unstable(feature = "unique_rc_arc", issue = "112566")]
#[derive(Debug)]
-pub struct UniqueRc {
+pub struct UniqueRc<
+ T: ?Sized,
+ #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
ptr: NonNull>,
phantom: PhantomData>,
+ alloc: A,
}
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl, U: ?Sized, A: Allocator> CoerceUnsized>
+ for UniqueRc
+{
+}
+
+// Depends on A = Global
impl UniqueRc {
- /// Creates a new `UniqueRc`
+ /// Creates a new `UniqueRc`.
///
/// Weak references to this `UniqueRc` can be created with [`UniqueRc::downgrade`]. Upgrading
/// these weak references will fail before the `UniqueRc` has been converted into an [`Rc`].
@@ -3569,34 +3580,36 @@ impl UniqueRc {
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "unique_rc_arc", issue = "112566")]
pub fn new(value: T) -> Self {
- Self {
- ptr: Box::leak(Box::new(RcBox {
+ Self::new_in(value, Global)
+ }
+}
+
+impl UniqueRc {
+ /// Creates a new `UniqueRc` in the provided allocator.
+ ///
+ /// Weak references to this `UniqueRc` can be created with [`UniqueRc::downgrade`]. Upgrading
+ /// these weak references will fail before the `UniqueRc` has been converted into an [`Rc`].
+ /// After converting the `UniqueRc` into an [`Rc`], any weak references created beforehand will
+ /// point to the new [`Rc`].
+ #[cfg(not(no_global_oom_handling))]
+ #[unstable(feature = "unique_rc_arc", issue = "112566")]
+ pub fn new_in(value: T, alloc: A) -> Self {
+ let (ptr, alloc) = Box::into_unique(Box::new_in(
+ RcBox {
strong: Cell::new(0),
// keep one weak reference so if all the weak pointers that are created are dropped
// the UniqueRc still stays valid.
weak: Cell::new(1),
value,
- }))
- .into(),
- phantom: PhantomData,
- }
- }
-
- /// Creates a new weak reference to the `UniqueRc`
- ///
- /// Attempting to upgrade this weak reference will fail before the `UniqueRc` has been converted
- /// to a [`Rc`] using [`UniqueRc::into_rc`].
- #[unstable(feature = "unique_rc_arc", issue = "112566")]
- pub fn downgrade(this: &Self) -> Weak {
- // SAFETY: This pointer was allocated at creation time and we guarantee that we only have
- // one strong reference before converting to a regular Rc.
- unsafe {
- this.ptr.as_ref().inc_weak();
- }
- Weak { ptr: this.ptr, alloc: Global }
+ },
+ alloc,
+ ));
+ Self { ptr: ptr.into(), phantom: PhantomData, alloc }
}
+}
- /// Converts the `UniqueRc` into a regular [`Rc`]
+impl UniqueRc {
+ /// Converts the `UniqueRc` into a regular [`Rc`].
///
/// This consumes the `UniqueRc` and returns a regular [`Rc`] that contains the `value` that
/// is passed to `into_rc`.
@@ -3604,19 +3617,41 @@ impl UniqueRc {
/// Any weak references created before this method is called can now be upgraded to strong
/// references.
#[unstable(feature = "unique_rc_arc", issue = "112566")]
- pub fn into_rc(this: Self) -> Rc {
+ pub fn into_rc(this: Self) -> Rc {
let mut this = ManuallyDrop::new(this);
+
+ // Move the allocator out.
+ // SAFETY: `this.alloc` will not be accessed again, nor dropped because it is in
+ // a `ManuallyDrop`.
+ let alloc: A = unsafe { ptr::read(&this.alloc) };
+
// SAFETY: This pointer was allocated at creation time so we know it is valid.
unsafe {
// Convert our weak reference into a strong reference
this.ptr.as_mut().strong.set(1);
- Rc::from_inner(this.ptr)
+ Rc::from_inner_in(this.ptr, alloc)
+ }
+ }
+}
+
+impl UniqueRc {
+ /// Creates a new weak reference to the `UniqueRc`.
+ ///
+ /// Attempting to upgrade this weak reference will fail before the `UniqueRc` has been converted
+ /// to a [`Rc`] using [`UniqueRc::into_rc`].
+ #[unstable(feature = "unique_rc_arc", issue = "112566")]
+ pub fn downgrade(this: &Self) -> Weak {
+ // SAFETY: This pointer was allocated at creation time and we guarantee that we only have
+ // one strong reference before converting to a regular Rc.
+ unsafe {
+ this.ptr.as_ref().inc_weak();
}
+ Weak { ptr: this.ptr, alloc: this.alloc.clone() }
}
}
#[unstable(feature = "unique_rc_arc", issue = "112566")]
-impl Deref for UniqueRc {
+impl Deref for UniqueRc {
type Target = T;
fn deref(&self) -> &T {
@@ -3626,7 +3661,7 @@ impl Deref for UniqueRc {
}
#[unstable(feature = "unique_rc_arc", issue = "112566")]
-impl DerefMut for UniqueRc {
+impl DerefMut for UniqueRc {
fn deref_mut(&mut self) -> &mut T {
// SAFETY: This pointer was allocated at creation time so we know it is valid. We know we
// have unique ownership and therefore it's safe to make a mutable reference because
@@ -3636,7 +3671,7 @@ impl DerefMut for UniqueRc {
}
#[unstable(feature = "unique_rc_arc", issue = "112566")]
-unsafe impl<#[may_dangle] T> Drop for UniqueRc {
+unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueRc {
fn drop(&mut self) {
unsafe {
// destroy the contained object
@@ -3646,7 +3681,7 @@ unsafe impl<#[may_dangle] T> Drop for UniqueRc {
self.ptr.as_ref().dec_weak();
if self.ptr.as_ref().weak() == 0 {
- Global.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr()));
+ self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr()));
}
}
}
diff --git a/library/alloc/src/rc/tests.rs b/library/alloc/src/rc/tests.rs
index c8a40603d9db2..0f09be7721fa9 100644
--- a/library/alloc/src/rc/tests.rs
+++ b/library/alloc/src/rc/tests.rs
@@ -606,6 +606,23 @@ fn test_unique_rc_drops_contents() {
assert!(dropped);
}
+/// Exercise the non-default allocator usage.
+#[test]
+fn test_unique_rc_with_alloc_drops_contents() {
+ let mut dropped = false;
+ struct DropMe<'a>(&'a mut bool);
+ impl Drop for DropMe<'_> {
+ fn drop(&mut self) {
+ *self.0 = true;
+ }
+ }
+ {
+ let rc = UniqueRc::new_in(DropMe(&mut dropped), std::alloc::System);
+ drop(rc);
+ }
+ assert!(dropped);
+}
+
#[test]
fn test_unique_rc_weak_clone_holding_ref() {
let mut v = UniqueRc::new(0u8);
@@ -614,3 +631,12 @@ fn test_unique_rc_weak_clone_holding_ref() {
let _ = w.clone(); // touch weak count
*r = 123;
}
+
+#[test]
+fn test_unique_rc_unsizing_coercion() {
+ let mut rc: UniqueRc<[u8]> = UniqueRc::new([0u8; 3]);
+ assert_eq!(rc.len(), 3);
+ rc[0] = 123;
+ let rc: Rc<[u8]> = UniqueRc::into_rc(rc);
+ assert_eq!(*rc, [123, 0, 0]);
+}
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index b5f17b9f54edc..043547d866fdc 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -40,6 +40,7 @@ pub struct Finder {
#[cfg(not(feature = "bootstrap-self-test"))]
const STAGE0_MISSING_TARGETS: &[&str] = &[
// just a dummy comment so the list doesn't get onelined
+ "i686-unknown-redox",
];
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
@@ -137,19 +138,20 @@ pub fn check(build: &mut Build) {
}
// We need cmake, but only if we're actually building LLVM or sanitizers.
- let building_llvm = build
- .hosts
- .iter()
- .map(|host| {
- build.config.llvm_enabled(*host)
- && build
- .config
- .target_config
- .get(host)
- .map(|config| config.llvm_config.is_none())
- .unwrap_or(true)
- })
- .any(|build_llvm_ourselves| build_llvm_ourselves);
+ let building_llvm = !build.config.llvm_from_ci
+ && build
+ .hosts
+ .iter()
+ .map(|host| {
+ build.config.llvm_enabled(*host)
+ && build
+ .config
+ .target_config
+ .get(host)
+ .map(|config| config.llvm_config.is_none())
+ .unwrap_or(true)
+ })
+ .any(|build_llvm_ourselves| build_llvm_ourselves);
let need_cmake = building_llvm || build.config.any_sanitizers_to_build();
if need_cmake && cmd_finder.maybe_have("cmake").is_none() {
diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
index 1704bef1e4ed0..414bcc52484c9 100644
--- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
@@ -6,8 +6,12 @@ FROM centos:7
WORKDIR /build
+# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault.
+RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \
+ -e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!'
+RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf
+
RUN yum upgrade -y && \
- yum install -y epel-release && \
yum install -y \
automake \
bzip2 \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index 4e1aae9822135..4aa1a3ccc2a5d 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -6,8 +6,12 @@ FROM centos:7
WORKDIR /build
+# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault.
+RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \
+ -e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!'
+RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf
+
RUN yum upgrade -y && \
- yum install -y epel-release && \
yum install -y \
automake \
bzip2 \
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 201ace5ce3a7b..e76ebb8f8aa8c 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -71,6 +71,7 @@
- [*-unknown-hermit](platform-support/hermit.md)
- [\*-unknown-netbsd\*](platform-support/netbsd.md)
- [*-unknown-openbsd](platform-support/openbsd.md)
+ - [*-unknown-redox](platform-support/redox.md)
- [\*-unknown-uefi](platform-support/unknown-uefi.md)
- [wasm32-wasip1](platform-support/wasm32-wasip1.md)
- [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index c672cff74526e..0ac69e4f07dfb 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -203,7 +203,7 @@ target | std | notes
`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
[`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony
[`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
-`x86_64-unknown-redox` | ✓ | Redox OS
+[`x86_64-unknown-redox`](platform-support/redox.md) | ✓ | Redox OS
[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 64-bit UEFI
[^x86_32-floats-x87]: Floating-point support on `i586` targets is non-compliant: the `x87` registers and instructions used for these targets do not provide IEEE-754-compliant behavior, in particular when it comes to rounding and NaN payload bits. See [issue #114479][x86-32-float-issue].
@@ -258,7 +258,7 @@ target | std | host | notes
`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
[`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD
[`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
-`aarch64-unknown-redox` | ? | | ARM64 Redox OS
+[`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS
`aarch64-uwp-windows-msvc` | ? | |
`aarch64-wrs-vxworks` | ? | |
`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
@@ -300,6 +300,7 @@ target | std | host | notes
[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI]
[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI]
[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI]
+[`i686-unknown-redox`](platform-support/redox.md) | ✓ | | i686 Redox OS
`i686-uwp-windows-gnu` | ? | | [^x86_32-floats-return-ABI]
`i686-uwp-windows-msvc` | ? | | [^x86_32-floats-return-ABI]
[`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
diff --git a/src/doc/rustc/src/platform-support/redox.md b/src/doc/rustc/src/platform-support/redox.md
new file mode 100644
index 0000000000000..1b3321956ef7b
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/redox.md
@@ -0,0 +1,53 @@
+# `*-unknown-redox`
+
+**Tier: 2/3**
+
+Targets for the [Redox OS](https://redox-os.org/) operating
+system.
+
+Target triplets available so far:
+
+- `x86_64-unknown-redox` (tier 2)
+- `aarch64-unknown-redox` (tier 3)
+- `i686-unknown-redox` (tier 3)
+
+## Target maintainers
+
+- Jeremy Soller ([@jackpot51](https://github.com/jackpot51))
+
+## Requirements
+
+These targets are natively compiled and can be cross-compiled. Std is fully supported.
+
+The targets are only expected to work with the latest version of Redox OS as the ABI is not yet stable.
+
+`extern "C"` uses the official calling convention of the respective architectures.
+
+Redox OS binaries use ELF as file format.
+
+## Building the target
+
+You can build Rust with support for the targets by adding it to the `target` list in `config.toml`. In addition a copy of [relibc] needs to be present in the linker search path.
+
+```toml
+[build]
+build-stage = 1
+target = [
+ "",
+ "x86_64-unknown-redox",
+ "aarch64-unknown-redox",
+ "i686-unknown-redox",
+]
+```
+
+[relibc]: https://gitlab.redox-os.org/redox-os/relibc
+
+## Building Rust programs and testing
+
+Rust does not yet ship pre-compiled artifacts for Redox OS except for x86_64-unknown-redox.
+
+The easiest way to build and test programs for Redox OS is using [redoxer](https://gitlab.redox-os.org/redox-os/redoxer) which sets up the required compiler toolchain for building as well as runs programs inside a Redox OS VM using QEMU.
+
+## Cross-compilation toolchains and C code
+
+The target supports C code. Pre-compiled C toolchains can be found at .
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index b4d47cba7c5bc..a709aab7ce220 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -103,6 +103,7 @@ static TARGETS: &[&str] = &[
"i686-unknown-freebsd",
"i686-unknown-linux-gnu",
"i686-unknown-linux-musl",
+ "i686-unknown-redox",
"i686-unknown-uefi",
"loongarch64-unknown-linux-gnu",
"loongarch64-unknown-none",
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index 4c54fe639e3e6..b069e667bf5d5 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -228,6 +228,9 @@
//@ revisions: i686_unknown_openbsd
//@ [i686_unknown_openbsd] compile-flags: --target i686-unknown-openbsd
//@ [i686_unknown_openbsd] needs-llvm-components: x86
+//@ revisions: i686_unknown_redox
+//@ [i686_unknown_redox] compile-flags: --target i686-unknown-redox
+//@ [i686_unknown_redox] needs-llvm-components: x86
//@ revisions: i686_wrs_vxworks
//@ [i686_wrs_vxworks] compile-flags: --target i686-wrs-vxworks
//@ [i686_wrs_vxworks] needs-llvm-components: x86
diff --git a/tests/ui/drop/auxiliary/edition-2021-macros.rs b/tests/ui/drop/auxiliary/edition-2021-macros.rs
new file mode 100644
index 0000000000000..8a6444f8614d4
--- /dev/null
+++ b/tests/ui/drop/auxiliary/edition-2021-macros.rs
@@ -0,0 +1,8 @@
+//@ edition:2021
+
+#[macro_export]
+macro_rules! edition_2021_block {
+ ($($c:tt)*) => {
+ { $($c)* }
+ }
+}
diff --git a/tests/ui/drop/auxiliary/edition-2024-macros.rs b/tests/ui/drop/auxiliary/edition-2024-macros.rs
new file mode 100644
index 0000000000000..236340bfed4f4
--- /dev/null
+++ b/tests/ui/drop/auxiliary/edition-2024-macros.rs
@@ -0,0 +1,9 @@
+//@ edition:2024
+//@ compile-flags: -Zunstable-options
+
+#[macro_export]
+macro_rules! edition_2024_block {
+ ($($c:tt)*) => {
+ { $($c)* }
+ }
+}
diff --git a/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr b/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr
new file mode 100644
index 0000000000000..75fc34e409b54
--- /dev/null
+++ b/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr
@@ -0,0 +1,16 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/tail-expr-drop-order-negative.rs:11:15
+ |
+LL | x.replace(std::cell::RefCell::new(123).borrow()).is_some()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
+ | |
+ | creates a temporary value which is freed while still in use
+LL |
+LL | }
+ | - borrow might be used here, when `x` is dropped and runs the destructor for type `Option[>`
+ |
+ = note: consider using a `let` binding to create a longer lived value
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/drop/tail-expr-drop-order-negative.rs b/tests/ui/drop/tail-expr-drop-order-negative.rs
new file mode 100644
index 0000000000000..c570b3a1ee235
--- /dev/null
+++ b/tests/ui/drop/tail-expr-drop-order-negative.rs
@@ -0,0 +1,17 @@
+//@ revisions: edition2021 edition2024
+//@ [edition2024] compile-flags: -Zunstable-options
+//@ [edition2024] edition: 2024
+//@ [edition2021] check-pass
+
+#![feature(shorter_tail_lifetimes)]
+
+fn why_would_you_do_this() -> bool {
+ let mut x = None;
+ // Make a temporary `RefCell` and put a `Ref` that borrows it in `x`.
+ x.replace(std::cell::RefCell::new(123).borrow()).is_some()
+ //[edition2024]~^ ERROR: temporary value dropped while borrowed
+}
+
+fn main() {
+ why_would_you_do_this();
+}
diff --git a/tests/ui/drop/tail-expr-drop-order.rs b/tests/ui/drop/tail-expr-drop-order.rs
new file mode 100644
index 0000000000000..5d87f980b1563
--- /dev/null
+++ b/tests/ui/drop/tail-expr-drop-order.rs
@@ -0,0 +1,108 @@
+//@ aux-build:edition-2021-macros.rs
+//@ aux-build:edition-2024-macros.rs
+//@ compile-flags: -Z validate-mir -Zunstable-options
+//@ edition: 2024
+//@ run-pass
+
+#![feature(shorter_tail_lifetimes)]
+#![allow(unused_imports)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+#[macro_use]
+extern crate edition_2021_macros;
+#[macro_use]
+extern crate edition_2024_macros;
+use std::cell::RefCell;
+use std::convert::TryInto;
+
+#[derive(Default)]
+struct DropOrderCollector(RefCell>);
+
+struct LoudDrop<'a>(&'a DropOrderCollector, u32);
+
+impl Drop for LoudDrop<'_> {
+ fn drop(&mut self) {
+ println!("{}", self.1);
+ self.0.0.borrow_mut().push(self.1);
+ }
+}
+
+impl DropOrderCollector {
+ fn option_loud_drop(&self, n: u32) -> Option {
+ Some(LoudDrop(self, n))
+ }
+
+ fn loud_drop(&self, n: u32) -> LoudDrop {
+ LoudDrop(self, n)
+ }
+
+ fn assert_sorted(&self, expected: usize) {
+ let result = self.0.borrow();
+ assert_eq!(result.len(), expected);
+ for i in 1..result.len() {
+ assert!(
+ result[i - 1] < result[i],
+ "inversion at {} ({} followed by {})",
+ i - 1,
+ result[i - 1],
+ result[i]
+ );
+ }
+ }
+}
+
+fn edition_2021_around_2021() {
+ let c = DropOrderCollector::default();
+ let _ = edition_2021_block! {
+ let a = c.loud_drop(1);
+ edition_2021_block! {
+ let b = c.loud_drop(0);
+ c.loud_drop(2).1
+ }
+ };
+ c.assert_sorted(3);
+}
+
+fn edition_2021_around_2024() {
+ let c = DropOrderCollector::default();
+ let _ = edition_2021_block! {
+ let a = c.loud_drop(2);
+ edition_2024_block! {
+ let b = c.loud_drop(1);
+ c.loud_drop(0).1
+ }
+ };
+ c.assert_sorted(3);
+}
+
+fn edition_2024_around_2021() {
+ let c = DropOrderCollector::default();
+ let _ = edition_2024_block! {
+ let a = c.loud_drop(2);
+ edition_2021_block! {
+ let b = c.loud_drop(0);
+ c.loud_drop(1).1
+ }
+ };
+ c.assert_sorted(3);
+}
+
+fn edition_2024_around_2024() {
+ let c = DropOrderCollector::default();
+ let _ = edition_2024_block! {
+ let a = c.loud_drop(2);
+ edition_2024_block! {
+ let b = c.loud_drop(1);
+ c.loud_drop(0).1
+ }
+ };
+ c.assert_sorted(3);
+}
+
+fn main() {
+ edition_2021_around_2021();
+ edition_2021_around_2024();
+ edition_2024_around_2021();
+ edition_2024_around_2024();
+}
diff --git a/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.rs b/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.rs
new file mode 100644
index 0000000000000..5292c44bb2d40
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.rs
@@ -0,0 +1,8 @@
+fn f() -> usize {
+ let c = std::cell::RefCell::new("..");
+ c.borrow().len() //~ ERROR: `c` does not live long enough
+}
+
+fn main() {
+ let _ = f();
+}
diff --git a/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.stderr b/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.stderr
new file mode 100644
index 0000000000000..648c3d5daa1c6
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.stderr
@@ -0,0 +1,26 @@
+error[E0597]: `c` does not live long enough
+ --> $DIR/feature-gate-shorter_tail_lifetimes.rs:3:5
+ |
+LL | let c = std::cell::RefCell::new("..");
+ | - binding `c` declared here
+LL | c.borrow().len()
+ | ^---------
+ | |
+ | borrowed value does not live long enough
+ | a temporary with access to the borrow is created here ...
+LL | }
+ | -
+ | |
+ | `c` dropped here while still borrowed
+ | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, &str>`
+ |
+ = note: the temporary is part of an expression at the end of a block;
+ consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
+help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
+ |
+LL | let x = c.borrow().len(); x
+ | +++++++ +++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr b/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr
new file mode 100644
index 0000000000000..858be42d54094
--- /dev/null
+++ b/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr
@@ -0,0 +1,26 @@
+error[E0597]: `cell` does not live long enough
+ --> $DIR/refcell-in-tail-expr.rs:12:27
+ |
+LL | let cell = std::cell::RefCell::new(0u8);
+ | ---- binding `cell` declared here
+LL |
+LL | if let Ok(mut byte) = cell.try_borrow_mut() {
+ | ^^^^-----------------
+ | |
+ | borrowed value does not live long enough
+ | a temporary with access to the borrow is created here ...
+...
+LL | }
+ | -
+ | |
+ | `cell` dropped here while still borrowed
+ | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Result, BorrowMutError>`
+ |
+help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
+ |
+LL | };
+ | +
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/lifetimes/refcell-in-tail-expr.rs b/tests/ui/lifetimes/refcell-in-tail-expr.rs
new file mode 100644
index 0000000000000..b1814c1e32713
--- /dev/null
+++ b/tests/ui/lifetimes/refcell-in-tail-expr.rs
@@ -0,0 +1,16 @@
+//@ revisions: edition2021 edition2024
+//@ [edition2021] edition: 2021
+//@ [edition2024] edition: 2024
+//@ [edition2024] compile-flags: -Zunstable-options
+//@ [edition2024] check-pass
+
+#![cfg_attr(edition2024, feature(shorter_tail_lifetimes))]
+
+fn main() {
+ let cell = std::cell::RefCell::new(0u8);
+
+ if let Ok(mut byte) = cell.try_borrow_mut() {
+ //[edition2021]~^ ERROR: `cell` does not live long enough
+ *byte = 1;
+ }
+}
diff --git a/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr b/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr
new file mode 100644
index 0000000000000..ad28ae2f80d66
--- /dev/null
+++ b/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr
@@ -0,0 +1,26 @@
+error[E0597]: `c` does not live long enough
+ --> $DIR/shorter-tail-expr-lifetime.rs:10:5
+ |
+LL | let c = std::cell::RefCell::new("..");
+ | - binding `c` declared here
+LL | c.borrow().len()
+ | ^---------
+ | |
+ | borrowed value does not live long enough
+ | a temporary with access to the borrow is created here ...
+LL | }
+ | -
+ | |
+ | `c` dropped here while still borrowed
+ | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, &str>`
+ |
+ = note: the temporary is part of an expression at the end of a block;
+ consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
+help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
+ |
+LL | let x = c.borrow().len(); x
+ | +++++++ +++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs b/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs
new file mode 100644
index 0000000000000..0392b6c6d9ada
--- /dev/null
+++ b/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs
@@ -0,0 +1,15 @@
+//@ revisions: edition2021 edition2024
+//@ [edition2024] compile-flags: -Zunstable-options
+//@ [edition2024] edition: 2024
+//@ [edition2024] run-pass
+
+#![cfg_attr(edition2024, feature(shorter_tail_lifetimes))]
+
+fn f() -> usize {
+ let c = std::cell::RefCell::new("..");
+ c.borrow().len() //[edition2021]~ ERROR: `c` does not live long enough
+}
+
+fn main() {
+ let _ = f();
+}
diff --git a/tests/ui/lifetimes/tail-expr-in-nested-expr.rs b/tests/ui/lifetimes/tail-expr-in-nested-expr.rs
new file mode 100644
index 0000000000000..a8989f22f4b5b
--- /dev/null
+++ b/tests/ui/lifetimes/tail-expr-in-nested-expr.rs
@@ -0,0 +1,9 @@
+//@ edition: 2024
+//@ compile-flags: -Zunstable-options
+
+#![feature(shorter_tail_lifetimes)]
+
+fn main() {
+ let _ = { String::new().as_str() }.len();
+ //~^ ERROR temporary value dropped while borrowed
+}
diff --git a/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr b/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr
new file mode 100644
index 0000000000000..f699d184bdb1d
--- /dev/null
+++ b/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr
@@ -0,0 +1,15 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/tail-expr-in-nested-expr.rs:7:15
+ |
+LL | let _ = { String::new().as_str() }.len();
+ | ^^^^^^^^^^^^^---------
+ | | |
+ | | temporary value is freed at the end of this statement
+ | creates a temporary value which is freed while still in use
+ | borrow later used here
+ |
+ = note: consider using a `let` binding to create a longer lived value
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/lifetimes/tail-expr-lock-poisoning.rs b/tests/ui/lifetimes/tail-expr-lock-poisoning.rs
new file mode 100644
index 0000000000000..08a062ec80c3d
--- /dev/null
+++ b/tests/ui/lifetimes/tail-expr-lock-poisoning.rs
@@ -0,0 +1,29 @@
+//@ revisions: edition2021 edition2024
+//@ [edition2024] compile-flags: -Zunstable-options
+//@ [edition2024] edition: 2024
+//@ [edition2024] run-pass
+//@ [edition2021] run-pass
+#![cfg_attr(edition2024, feature(shorter_tail_lifetimes))]
+
+use std::sync::Mutex;
+
+struct PanicOnDrop;
+impl Drop for PanicOnDrop {
+ fn drop(&mut self) {
+ panic!()
+ }
+}
+
+fn f(m: &Mutex) -> i32 {
+ let _x = PanicOnDrop;
+ *m.lock().unwrap()
+}
+
+fn main() {
+ let m = Mutex::new(0);
+ let _ = std::panic::catch_unwind(|| f(&m));
+ #[cfg(edition2024)]
+ assert!(m.lock().is_ok());
+ #[cfg(edition2021)]
+ assert!(m.lock().is_err());
+}
diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr
index 888fd2e61837f..afd37d03a231c 100644
--- a/tests/ui/lint/non-local-defs/cargo-update.stderr
+++ b/tests/ui/lint/non-local-defs/cargo-update.stderr
@@ -8,9 +8,10 @@ LL | non_local_macro::non_local_impl!(LocalStruct);
| `Debug` is not local
| move the `impl` block outside of this constant `_IMPL_DEBUG`
|
+ = note: the macro `non_local_macro::non_local_impl` defines the non-local `impl`, and may need to be changed
+ = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro`
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
- = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro`
= note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue
= note: `#[warn(non_local_definitions)]` on by default
diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
index b52301d1aa086..fa9ba2cb785d9 100644
--- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
@@ -12,6 +12,7 @@ LL | impl MacroTrait for OutsideStruct {}
LL | m!();
| ---- in this macro invocation
|
+ = note: the macro `m` defines the non-local `impl`, and may need to be changed
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue
diff --git a/tests/ui/nll/issue-52534-1.rs b/tests/ui/nll/issue-52534-1.rs
index d9ea3ae42c49e..526b81bb2d056 100644
--- a/tests/ui/nll/issue-52534-1.rs
+++ b/tests/ui/nll/issue-52534-1.rs
@@ -17,14 +17,14 @@ fn foo(x: &u32) -> &u32 {
fn baz(x: &u32) -> &&u32 {
let x = 22;
&&x
-//~^ ERROR cannot return value referencing local variable
+//~^ ERROR cannot return value referencing local variable `x`
//~| ERROR cannot return reference to temporary value
}
fn foobazbar<'a>(x: u32, y: &'a u32) -> &'a u32 {
let x = 22;
&x
-//~^ ERROR cannot return reference to local variable
+//~^ ERROR cannot return reference to local variable `x`
}
fn foobar<'a>(x: &'a u32) -> &'a u32 {
]