Auto merge of #150228 - matthiaskrgr:rollup-ymp54q0, r=matthiaskrgr

Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#146377 (Don't strip shebang in expr-ctxt `include!(…)`)
 - rust-lang/rust#149812 (Add const default for OnceCell and OnceLock)
 - rust-lang/rust#149882 (miri: add -Zbinary-dep-depinfo to dependency builds)
 - rust-lang/rust#150009 (Enable llvm-libunwind by default for Hexagon targets)
 - rust-lang/rust#150035 (fix docustring on fetch_or)
 - rust-lang/rust#150082 (tests/ui/traits/fmt-pointer-trait.rs: Add HRTB fn pointer case)
 - rust-lang/rust#150160 (Fix ICE (rust-lang/rust#149980) for invalid EII in statement position)
 - rust-lang/rust#150184 (mir_build: Use the same length type for `TestableCase::Slice` and `TestKind::Len`)
 - rust-lang/rust#150185 ([rustdoc] Add missing close tags in extern crate reexports)
 - rust-lang/rust#150191 (change non-canonical clone impl to {*self}, fix some doc comments)
 - rust-lang/rust#150203 (Drop the From derive macro from the v1 prelude)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-12-22 01:58:47 +00:00
commit acfd264f4d
32 changed files with 175 additions and 64 deletions

View file

@ -60,12 +60,18 @@ fn eii_(
) -> Vec<Annotatable> {
let eii_attr_span = ecx.with_def_site_ctxt(eii_attr_span);
let (item, stmt) = if let Annotatable::Item(item) = item {
(item, false)
let (item, wrap_item): (_, &dyn Fn(_) -> _) = if let Annotatable::Item(item) = item {
(item, &Annotatable::Item)
} else if let Annotatable::Stmt(ref stmt) = item
&& let StmtKind::Item(ref item) = stmt.kind
{
(item.clone(), true)
(item.clone(), &|item| {
Annotatable::Stmt(Box::new(Stmt {
id: DUMMY_NODE_ID,
kind: StmtKind::Item(item),
span: eii_attr_span,
}))
})
} else {
ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
span: eii_attr_span,
@ -74,23 +80,25 @@ fn eii_(
return vec![item];
};
let orig_item = item.clone();
let item = *item;
let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } = item else {
let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } =
item.as_ref()
else {
ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
span: eii_attr_span,
name: path_to_string(&meta_item.path),
});
return vec![Annotatable::Item(Box::new(item))];
return vec![wrap_item(item)];
};
// only clone what we need
let attrs = attrs.clone();
let func = (**func).clone();
let vis = vis.clone();
let attrs_from_decl =
filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path);
let Ok(macro_name) = name_for_impl_macro(ecx, &func, &meta_item) else {
return vec![Annotatable::Item(orig_item)];
return vec![wrap_item(item)];
};
// span of the declaring item without attributes
@ -115,7 +123,7 @@ fn eii_(
ecx,
eii_attr_span,
item_span,
*func,
func,
vis,
&attrs_from_decl,
)));
@ -128,20 +136,7 @@ fn eii_(
decl_span,
)));
if stmt {
return_items
.into_iter()
.map(|i| {
Annotatable::Stmt(Box::new(Stmt {
id: DUMMY_NODE_ID,
kind: StmtKind::Item(i),
span: eii_attr_span,
}))
})
.collect()
} else {
return_items.into_iter().map(|i| Annotatable::Item(i)).collect()
}
return_items.into_iter().map(wrap_item).collect()
}
/// Decide on the name of the macro that can be used to implement the EII.

View file

@ -144,9 +144,7 @@ pub(crate) fn expand_include<'cx>(
let mut p = unwrap_or_emit_fatal(new_parser_from_file(
self.psess,
&self.path,
// Don't strip frontmatter for backward compatibility, `---` may be the start of a
// manifold negation. FIXME: Ideally, we wouldn't strip shebangs here either.
StripTokens::Shebang,
StripTokens::Nothing,
Some(self.span),
));
let expr = parse_expr(&mut p).ok()?;

View file

@ -416,7 +416,7 @@ impl<'a> Id<'a> {
/// it in the generated .dot file. They can also provide more
/// elaborate (and non-unique) label text that is used in the graphviz
/// rendered output.
///
/// The graph instance is responsible for providing the DOT compatible
/// identifiers for the nodes and (optionally) rendered labels for the nodes and
/// edges, as well as an identifier for the graph itself.

View file

@ -2654,7 +2654,7 @@ struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
fn clone(&self) -> Self {
InternedInSet(self.0)
*self
}
}

View file

@ -218,7 +218,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&TestKind::Len { len: test_len, op: BinOp::Eq },
&TestableCase::Slice { len, variable_length },
) => {
match (test_len.cmp(&(len as u64)), variable_length) {
match (test_len.cmp(&len), variable_length) {
(Ordering::Equal, false) => {
// on true, min_len = len = $actual_length,
// on false, len != $actual_length
@ -251,7 +251,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&TestableCase::Slice { len, variable_length },
) => {
// the test is `$actual_len >= test_len`
match (test_len.cmp(&(len as u64)), variable_length) {
match (test_len.cmp(&len), variable_length) {
(Ordering::Equal, true) => {
// $actual_len >= test_len = pat_len,
// so we can match.

View file

@ -256,7 +256,7 @@ impl<'tcx> MatchPairTree<'tcx> {
None
} else {
Some(TestableCase::Slice {
len: prefix.len() + suffix.len(),
len: u64::try_from(prefix.len() + suffix.len()).unwrap(),
variable_length: slice.is_some(),
})
}

View file

@ -1264,7 +1264,7 @@ enum TestableCase<'tcx> {
Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx },
Constant { value: ty::Value<'tcx> },
Range(Arc<PatRange<'tcx>>),
Slice { len: usize, variable_length: bool },
Slice { len: u64, variable_length: bool },
Deref { temp: Place<'tcx>, mutability: Mutability },
Never,
Or { pats: Box<[FlatPat<'tcx>]> },

View file

@ -47,7 +47,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
TestableCase::Slice { len, variable_length } => {
let op = if variable_length { BinOp::Ge } else { BinOp::Eq };
TestKind::Len { len: len as u64, op }
TestKind::Len { len, op }
}
TestableCase::Deref { temp, mutability } => TestKind::Deref { temp, mutability },

View file

@ -141,7 +141,7 @@ pub struct MatchArm<'p, Cx: PatCx> {
impl<'p, Cx: PatCx> Clone for MatchArm<'p, Cx> {
fn clone(&self) -> Self {
Self { pat: self.pat, has_guard: self.has_guard, arm_data: self.arm_data }
*self
}
}

View file

@ -174,10 +174,7 @@ pub(crate) enum PatOrWild<'p, Cx: PatCx> {
impl<'p, Cx: PatCx> Clone for PatOrWild<'p, Cx> {
fn clone(&self) -> Self {
match self {
PatOrWild::Wild => PatOrWild::Wild,
PatOrWild::Pat(pat) => PatOrWild::Pat(pat),
}
*self
}
}

View file

@ -824,7 +824,7 @@ struct PlaceCtxt<'a, Cx: PatCx> {
impl<'a, Cx: PatCx> Copy for PlaceCtxt<'a, Cx> {}
impl<'a, Cx: PatCx> Clone for PlaceCtxt<'a, Cx> {
fn clone(&self) -> Self {
Self { cx: self.cx, ty: self.ty }
*self
}
}

View file

@ -153,8 +153,8 @@ pub struct Registry {
terminate_count: AtomicUsize,
}
/// ////////////////////////////////////////////////////////////////////////
/// Initialization
///////////////////////////////////////////////////////////////////////////
// Initialization
static mut THE_REGISTRY: Option<Arc<Registry>> = None;
static THE_REGISTRY_SET: Once = Once::new();
@ -407,12 +407,12 @@ impl Registry {
}
}
/// ////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
/// MAIN LOOP
///
/// So long as all of the worker threads are hanging out in their
/// top-level loop, there is no work to be done.
///
/// Push a job into the given `registry`. If we are running on a
/// worker thread for the registry, this will push onto the
/// deque. Else, it will inject from the outside (which is slower).
@ -668,8 +668,8 @@ impl ThreadInfo {
}
}
/// ////////////////////////////////////////////////////////////////////////
/// WorkerThread identifiers
///////////////////////////////////////////////////////////////////////////
// WorkerThread identifiers
pub(super) struct WorkerThread {
/// the "worker" half of our local deque
@ -1019,8 +1019,6 @@ impl WorkerThread {
}
}
/// ////////////////////////////////////////////////////////////////////////
unsafe fn main_loop(thread: ThreadBuilder) {
let worker_thread = &WorkerThread::from(thread);
unsafe { WorkerThread::set_current(worker_thread) };

View file

@ -353,7 +353,8 @@ impl<T> OnceCell<T> {
}
#[stable(feature = "once_cell", since = "1.70.0")]
impl<T> Default for OnceCell<T> {
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T> const Default for OnceCell<T> {
#[inline]
fn default() -> Self {
Self::new()

View file

@ -118,13 +118,6 @@ pub use crate::macros::builtin::deref;
)]
pub use crate::macros::builtin::define_opaque;
#[unstable(
feature = "derive_from",
issue = "144889",
reason = "`derive(From)` is unstable"
)]
pub use crate::macros::builtin::From;
#[unstable(feature = "extern_item_impls", issue = "125418")]
pub use crate::macros::builtin::{eii, unsafe_eii};

View file

@ -1151,8 +1151,8 @@ impl AtomicBool {
/// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true);
/// assert_eq!(foo.load(Ordering::SeqCst), true);
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), true);
/// let foo = AtomicBool::new(false);
/// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), false);
/// assert_eq!(foo.load(Ordering::SeqCst), true);
///
/// let foo = AtomicBool::new(false);

View file

@ -30,6 +30,12 @@ fn test_format_flags() {
assert_eq!(format!("{:p} {:x}", p, 16), format!("{p:p} 10"));
assert_eq!(format!("{: >3}", 'a'), " a");
/// Regression test for <https://github.com/rust-lang/rust/issues/50280#issuecomment-626035934>.
fn show(a: fn() -> f32, b: fn(&Vec<i8>) -> f32) {
println!("the two pointers: {:p} {:p}", a, b);
}
show(|| 1.0, |_| 2.0);
}
#[test]

View file

@ -274,6 +274,7 @@
#![feature(cfg_sanitizer_cfi)]
#![feature(cfg_target_thread_local)]
#![feature(cfi_encoding)]
#![feature(const_default)]
#![feature(const_trait_impl)]
#![feature(core_float_math)]
#![feature(decl_macro)]

View file

@ -582,7 +582,8 @@ impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceLock<T> {}
impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {}
#[stable(feature = "once_cell", since = "1.70.0")]
impl<T> Default for OnceLock<T> {
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T> const Default for OnceLock<T> {
/// Creates a new uninitialized cell.
///
/// # Example

View file

@ -73,11 +73,28 @@ cfg_select! {
}
_ => {
#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
#[link(name = "gcc_s", cfg(all(not(target_feature = "crt-static"), not(target_arch = "hexagon"))))]
unsafe extern "C" {}
}
}
// Hexagon with musl uses llvm-libunwind by default
#[cfg(all(target_env = "musl", target_arch = "hexagon"))]
cfg_select! {
feature = "llvm-libunwind" => {
#[link(name = "unwind", kind = "static", modifiers = "-bundle")]
unsafe extern "C" {}
}
feature = "system-llvm-libunwind" => {
#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
unsafe extern "C" {}
}
_ => {
// Fallback: should not happen since hexagon defaults to llvm-libunwind
}
}
// This is the same as musl except that we default to using the system libunwind
// instead of libgcc.
#[cfg(target_env = "ohos")]

View file

@ -354,7 +354,10 @@ fn copy_third_party_objects(
if target == "x86_64-fortanix-unknown-sgx"
|| builder.config.llvm_libunwind(target) == LlvmLibunwind::InTree
&& (target.contains("linux") || target.contains("fuchsia") || target.contains("aix"))
&& (target.contains("linux")
|| target.contains("fuchsia")
|| target.contains("aix")
|| target.contains("hexagon"))
{
let libunwind_path =
copy_llvm_libunwind(builder, target, &builder.sysroot_target_libdir(*compiler, target));

View file

@ -1856,7 +1856,7 @@ impl Config {
.get(&target)
.and_then(|t| t.llvm_libunwind)
.or(self.llvm_libunwind_default)
.unwrap_or(if target.contains("fuchsia") {
.unwrap_or(if target.contains("fuchsia") || target.contains("hexagon") {
LlvmLibunwind::InTree
} else {
LlvmLibunwind::No

View file

@ -439,6 +439,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
)?;
}
}
write!(w, "</code></dt>")?
}
clean::ImportItem(ref import) => {
let stab_tags =

View file

@ -173,6 +173,10 @@ impl TestContext {
p.envs.push(("RUSTC_SNAPSHOT".into(), Some(rustc.into())));
p.envs.push(("RUSTC_SNAPSHOT_LIBDIR".into(), Some(libdir.into())));
p.envs.push(("RUSTC_SYSROOT".into(), Some(sysroot.into())));
// Ensure we rebuild the dependencies when the sysroot changes.
// (Bootstrap usually sets this automatically, but since we invoke cargo
// ourselves we have to do it.)
p.args.push("-Zbinary-dep-depinfo".into());
}
p
},

View file

@ -133,7 +133,11 @@ fn miri_config(
program: miri_path()
.with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
// There is no `cargo miri build` so we just use `cargo miri run`.
args: ["miri", "run"].into_iter().map(Into::into).collect(),
// Add `-Zbinary-dep-depinfo` since it is needed for bootstrap builds (and doesn't harm otherwise).
args: ["miri", "run", "--quiet", "-Zbinary-dep-depinfo"]
.into_iter()
.map(Into::into)
.collect(),
// Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
envs: vec![("RUSTFLAGS".into(), None)],
..CommandBuilder::cargo()

View file

@ -0,0 +1,9 @@
//@ aux-build:pub-extern-crate.rs
// A refactor had left us missing the closing tags,
// ensure that they are present.
// https://github.com/rust-lang/rust/issues/150176
//@ has pub_extern_crate_150176/index.html
//@ hasraw - '<dt><code>pub extern crate inner;</code></dt>'
pub extern crate inner;

View file

@ -0,0 +1,16 @@
#![feature(extern_item_impls)]
// EIIs can, despite not being super useful, be declared in statement position
// nested inside items. Items in statement position, when expanded as part of a macro,
// need to be wrapped slightly differently (in an `ast::Statement`).
// We did this on the happy path (no errors), but when there was an error, we'd
// replace it with *just* an `ast::Item` not wrapped in an `ast::Statement`.
// This caused an ICE (https://github.com/rust-lang/rust/issues/149980).
// this test fails to build, but demonstrates that no ICE is produced.
fn main() {
struct Bar;
#[eii]
//~^ ERROR `#[eii]` is only valid on functions
impl Bar {}
}

View file

@ -0,0 +1,8 @@
error: `#[eii]` is only valid on functions
--> $DIR/error_statement_position.rs:13:5
|
LL | #[eii]
| ^^^^^^
error: aborting due to 1 previous error

View file

@ -0,0 +1,3 @@
#!/usr/bin/env my-rust-expr-evaluator
2 * (1 + 3)

View file

@ -0,0 +1,3 @@
#!/usr/bin/env my-rust-script-runner
fn main() {}

View file

@ -0,0 +1,16 @@
// Check that we *don't* strip shebang in files that were `include`d in an expression or
// expression statement context.
// We do that to be consistent with frontmatter (see test `frontmatter/include-in-expr-ctxt.rs`).
// While there could be niche use cases for such shebang, it seems more confusing than beneficial.
fn main() {
// expr ctxt
_ = include!("auxiliary/shebang-expr.rs");
//~^ ERROR non-expression macro in expression position
//~? ERROR expected `[`, found `/`
// stmt ctxt (reuses expr expander)
include!("auxiliary/shebang-expr.rs");
//~^ ERROR non-statement macro in statement position
//~? ERROR expected `[`, found `/`
}

View file

@ -0,0 +1,33 @@
error: expected `[`, found `/`
--> $DIR/auxiliary/shebang-expr.rs:1:3
|
LL | #!/usr/bin/env my-rust-expr-evaluator
| ^ expected `[`
|
= note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not
= help: if you meant this to be a shebang interpreter directive, move it to the very start of the file
error: non-expression macro in expression position: include
--> $DIR/shebang-in-expr-ctxt.rs:8:9
|
LL | _ = include!("auxiliary/shebang-expr.rs");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: expected `[`, found `/`
--> $DIR/auxiliary/shebang-expr.rs:1:3
|
LL | #!/usr/bin/env my-rust-expr-evaluator
| ^ expected `[`
|
= note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not
= help: if you meant this to be a shebang interpreter directive, move it to the very start of the file
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: non-statement macro in statement position: include
--> $DIR/shebang-in-expr-ctxt.rs:13:5
|
LL | include!("auxiliary/shebang-expr.rs");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors

View file

@ -0,0 +1,4 @@
// Ensure that we strip shebang in files `include`d in item contexts.
//@ check-pass
include!("auxiliary/shebang-items.rs");