Auto merge of #143746 - matthiaskrgr:rollup-yaojj7t, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang/rust#143446 (use `--dynamic-list` for exporting executable symbols)
 - rust-lang/rust#143590 (Fix weird rustdoc output when single and glob reexport conflict on a name)
 - rust-lang/rust#143599 (emit `.att_syntax` when global/naked asm use that option)
 - rust-lang/rust#143615 (Fix handling of no_std targets in `doc::Std` step)
 - rust-lang/rust#143632 (fix: correct parameter names in LLVMRustBuildMinNum and LLVMRustBuildMaxNum FFI declarations)
 - rust-lang/rust#143640 (Constify `Fn*` traits)
 - rust-lang/rust#143651 (Win: Use exceptions with empty data for SEH panic exception copies instead of a new panic)
 - rust-lang/rust#143660 (Disable docs for `compiler-builtins` and `sysroot`)
 - rust-lang/rust#143665 ([rustdoc-json] Add tests for `#[doc(hidden)]` handling of items.)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-07-10 19:56:08 +00:00
commit 2a023bf80a
47 changed files with 647 additions and 766 deletions

View file

@ -384,15 +384,19 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
) {
let asm_arch = self.tcx.sess.asm_arch.unwrap();
// Default to Intel syntax on x86
let intel_syntax = matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64)
&& !options.contains(InlineAsmOptions::ATT_SYNTAX);
// Build the template string
let mut template_str = String::new();
if intel_syntax {
template_str.push_str(".intel_syntax\n");
// On X86 platforms there are two assembly syntaxes. Rust uses intel by default,
// but AT&T can be specified explicitly.
if matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) {
if options.contains(InlineAsmOptions::ATT_SYNTAX) {
template_str.push_str(".att_syntax\n")
} else {
template_str.push_str(".intel_syntax\n")
}
}
for piece in template {
match *piece {
InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s),
@ -431,7 +435,11 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
}
}
}
if intel_syntax {
// Just to play it safe, if intel was used, reset the assembly syntax to att.
if matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64)
&& !options.contains(InlineAsmOptions::ATT_SYNTAX)
{
template_str.push_str("\n.att_syntax\n");
}

View file

@ -1980,12 +1980,12 @@ unsafe extern "C" {
pub(crate) fn LLVMRustBuildMinNum<'a>(
B: &Builder<'a>,
LHS: &'a Value,
LHS: &'a Value,
RHS: &'a Value,
) -> &'a Value;
pub(crate) fn LLVMRustBuildMaxNum<'a>(
B: &Builder<'a>,
LHS: &'a Value,
LHS: &'a Value,
RHS: &'a Value,
) -> &'a Value;
// Atomic Operations

View file

@ -800,9 +800,7 @@ impl<'a> Linker for GccLinker<'a> {
return;
}
let is_windows = self.sess.target.is_like_windows;
let path = tmpdir.join(if is_windows { "list.def" } else { "list" });
let path = tmpdir.join(if self.sess.target.is_like_windows { "list.def" } else { "list" });
debug!("EXPORTED SYMBOLS:");
if self.sess.target.is_like_darwin {
@ -817,7 +815,8 @@ impl<'a> Linker for GccLinker<'a> {
if let Err(error) = res {
self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error });
}
} else if is_windows {
self.link_arg("-exported_symbols_list").link_arg(path);
} else if self.sess.target.is_like_windows {
let res: io::Result<()> = try {
let mut f = File::create_buffered(&path)?;
@ -835,6 +834,21 @@ impl<'a> Linker for GccLinker<'a> {
if let Err(error) = res {
self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error });
}
self.link_arg(path);
} else if crate_type == CrateType::Executable && !self.sess.target.is_like_solaris {
let res: io::Result<()> = try {
let mut f = File::create_buffered(&path)?;
writeln!(f, "{{")?;
for (sym, _) in symbols {
debug!(sym);
writeln!(f, " {sym};")?;
}
writeln!(f, "}};")?;
};
if let Err(error) = res {
self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
}
self.link_arg("--dynamic-list").link_arg(path);
} else {
// Write an LD version script
let res: io::Result<()> = try {
@ -852,18 +866,13 @@ impl<'a> Linker for GccLinker<'a> {
if let Err(error) = res {
self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
}
}
if self.sess.target.is_like_darwin {
self.link_arg("-exported_symbols_list").link_arg(path);
} else if self.sess.target.is_like_solaris {
self.link_arg("-M").link_arg(path);
} else if is_windows {
self.link_arg(path);
} else {
let mut arg = OsString::from("--version-script=");
arg.push(path);
self.link_arg(arg).link_arg("--no-undefined-version");
if self.sess.target.is_like_solaris {
self.link_arg("-M").link_arg(path);
} else {
let mut arg = OsString::from("--version-script=");
arg.push(path);
self.link_arg(arg).link_arg("--no-undefined-version");
}
}
}

View file

@ -82,13 +82,6 @@ hir_typeck_cast_unknown_pointer = cannot cast {$to ->
hir_typeck_const_continue_bad_label =
`#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
hir_typeck_const_select_must_be_const = this argument must be a `const fn`
.help = consult the documentation on `const_eval_select` for more information
hir_typeck_const_select_must_be_fn = this argument must be a function item
.note = expected a function item, found {$ty}
.help = consult the documentation on `const_eval_select` for more information
hir_typeck_continue_labeled_block =
`continue` pointing to a labeled block
.label = labeled blocks cannot be `continue`'d

View file

@ -578,29 +578,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
if let Some(def_id) = def_id
&& self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
&& self.tcx.is_intrinsic(def_id, sym::const_eval_select)
{
let fn_sig = self.resolve_vars_if_possible(fn_sig);
for idx in 0..=1 {
let arg_ty = fn_sig.inputs()[idx + 1];
let span = arg_exprs.get(idx + 1).map_or(call_expr.span, |arg| arg.span);
// Check that second and third argument of `const_eval_select` must be `FnDef`, and additionally that
// the second argument must be `const fn`. The first argument must be a tuple, but this is already expressed
// in the function signature (`F: FnOnce<ARG>`), so I did not bother to add another check here.
//
// This check is here because there is currently no way to express a trait bound for `FnDef` types only.
if let ty::FnDef(def_id, _args) = *arg_ty.kind() {
if idx == 0 && !self.tcx.is_const_fn(def_id) {
self.dcx().emit_err(errors::ConstSelectMustBeConst { span });
}
} else {
self.dcx().emit_err(errors::ConstSelectMustBeFn { span, ty: arg_ty });
}
}
}
fn_sig.output()
}

View file

@ -605,24 +605,6 @@ impl Subdiagnostic for RemoveSemiForCoerce {
}
}
#[derive(Diagnostic)]
#[diag(hir_typeck_const_select_must_be_const)]
#[help]
pub(crate) struct ConstSelectMustBeConst {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_const_select_must_be_fn)]
#[note]
#[help]
pub(crate) struct ConstSelectMustBeFn<'a> {
#[primary_span]
pub span: Span,
pub ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_union_pat_multiple_fields)]
pub(crate) struct UnionPatMultipleFields {

View file

@ -529,7 +529,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// process any deferred resolutions.
let deferred_call_resolutions = self.remove_deferred_call_resolutions(closure_def_id);
for deferred_call_resolution in deferred_call_resolutions {
deferred_call_resolution.resolve(self);
deferred_call_resolution.resolve(&mut FnCtxt::new(
self,
self.param_env,
closure_def_id,
));
}
}

View file

@ -1,7 +1,8 @@
use rustc_hir::{self as hir, LangItem};
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
use rustc_infer::traits::{
ImplDerivedHostCause, ImplSource, Obligation, ObligationCauseCode, PredicateObligation,
ImplDerivedHostCause, ImplSource, Obligation, ObligationCause, ObligationCauseCode,
PredicateObligation,
};
use rustc_middle::span_bug;
use rustc_middle::traits::query::NoSolution;
@ -303,6 +304,9 @@ fn evaluate_host_effect_from_builtin_impls<'tcx>(
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
match selcx.tcx().as_lang_item(obligation.predicate.def_id()) {
Some(LangItem::Destruct) => evaluate_host_effect_for_destruct_goal(selcx, obligation),
Some(LangItem::Fn | LangItem::FnMut | LangItem::FnOnce) => {
evaluate_host_effect_for_fn_goal(selcx, obligation)
}
_ => Err(EvaluationFailure::NoSolution),
}
}
@ -398,6 +402,51 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
.collect())
}
// NOTE: Keep this in sync with `extract_fn_def_from_const_callable` in the new solver.
fn evaluate_host_effect_for_fn_goal<'tcx>(
selcx: &mut SelectionContext<'_, 'tcx>,
obligation: &HostEffectObligation<'tcx>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
let tcx = selcx.tcx();
let self_ty = obligation.predicate.self_ty();
let (def, args) = match *self_ty.kind() {
ty::FnDef(def, args) => (def, args),
// We may support function pointers at some point in the future
ty::FnPtr(..) => return Err(EvaluationFailure::NoSolution),
// Closures could implement `[const] Fn`,
// but they don't really need to right now.
ty::Closure(..) | ty::CoroutineClosure(_, _) => {
return Err(EvaluationFailure::NoSolution);
}
// Everything else needs explicit impls or cannot have an impl
_ => return Err(EvaluationFailure::NoSolution),
};
match tcx.constness(def) {
hir::Constness::Const => Ok(tcx
.const_conditions(def)
.instantiate(tcx, args)
.into_iter()
.map(|(c, span)| {
let code = ObligationCauseCode::WhereClause(def, span);
let cause =
ObligationCause::new(obligation.cause.span, obligation.cause.body_id, code);
Obligation::new(
tcx,
cause,
obligation.param_env,
c.to_host_effect_clause(tcx, obligation.predicate.constness),
)
})
.collect()),
hir::Constness::NotConst => Err(EvaluationFailure::NoSolution),
}
}
fn evaluate_host_effect_from_selection_candidate<'tcx>(
selcx: &mut SelectionContext<'_, 'tcx>,
obligation: &HostEffectObligation<'tcx>,

View file

@ -19,6 +19,8 @@ links = "compiler-rt"
bench = false
doctest = false
test = false
# make sure this crate isn't included in public standard library docs
doc = false
[dependencies]
core = { path = "../../core", optional = true }

View file

@ -2279,7 +2279,7 @@ pub const fn const_eval_select<ARG: Tuple, F, G, RET>(
) -> RET
where
G: FnOnce<ARG, Output = RET>,
F: FnOnce<ARG, Output = RET>;
F: const FnOnce<ARG, Output = RET>;
/// A macro to make it easier to invoke const_eval_select. Use as follows:
/// ```rust,ignore (just a macro example)

View file

@ -72,7 +72,8 @@ use crate::marker::Tuple;
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(const_trait_impl) #[const_trait]
#[const_trait]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
pub trait Fn<Args: Tuple>: FnMut<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
@ -159,7 +160,8 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(const_trait_impl) #[const_trait]
#[const_trait]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
pub trait FnMut<Args: Tuple>: FnOnce<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
@ -238,7 +240,8 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(const_trait_impl) #[const_trait]
#[const_trait]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
pub trait FnOnce<Args: Tuple> {
/// The returned type after the call operator is used.
#[lang = "fn_once_output"]
@ -254,9 +257,10 @@ mod impls {
use crate::marker::Tuple;
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> Fn<A> for &F
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
impl<A: Tuple, F: ?Sized> const Fn<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
extern "rust-call" fn call(&self, args: A) -> F::Output {
(**self).call(args)
@ -264,9 +268,10 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnMut<A> for &F
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
impl<A: Tuple, F: ?Sized> const FnMut<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(**self).call(args)
@ -274,9 +279,10 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnOnce<A> for &F
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
type Output = F::Output;
@ -286,9 +292,10 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnMut<A> for &mut F
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F
where
F: FnMut<A>,
F: ~const FnMut<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(*self).call_mut(args)
@ -296,9 +303,10 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnOnce<A> for &mut F
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F
where
F: FnMut<A>,
F: ~const FnMut<A>,
{
type Output = F::Output;
extern "rust-call" fn call_once(self, args: A) -> F::Output {

View file

@ -61,6 +61,7 @@ struct Exception {
// and its destructor is executed by the C++ runtime. When we take the Box
// out of the exception, we need to leave the exception in a valid state
// for its destructor to run without double-dropping the Box.
// We also construct this as None for copies of the exception.
data: Option<Box<dyn Any + Send>>,
}
@ -264,7 +265,11 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
// runtime under a try/catch block and the panic that we generate here will be
// used as the result of the exception copy. This is used by the C++ runtime to
// support capturing exceptions with std::exception_ptr, which we can't support
// because Box<dyn Any> isn't clonable.
// because Box<dyn Any> isn't clonable. Thus we throw an exception without data,
// which the C++ runtime will attempt to copy, which will once again fail, and
// a std::bad_exception instance ends up in the std::exception_ptr instance.
// The lack of data doesn't matter because the exception will never be rethrown
// - it is purely used to signal to the C++ runtime that copying failed.
macro_rules! define_cleanup {
($abi:tt $abi2:tt) => {
unsafe extern $abi fn exception_cleanup(e: *mut Exception) {
@ -278,7 +283,9 @@ macro_rules! define_cleanup {
unsafe extern $abi2 fn exception_copy(
_dest: *mut Exception, _src: *mut Exception
) -> *mut Exception {
panic!("Rust panics cannot be copied");
unsafe {
throw_exception(None);
}
}
}
}
@ -291,6 +298,10 @@ cfg_if::cfg_if! {
}
pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
unsafe { throw_exception(Some(data)) }
}
unsafe fn throw_exception(data: Option<Box<dyn Any + Send>>) -> ! {
use core::intrinsics::{AtomicOrdering, atomic_store};
// _CxxThrowException executes entirely on this stack frame, so there's no
@ -300,8 +311,7 @@ pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
// The ManuallyDrop is needed here since we don't want Exception to be
// dropped when unwinding. Instead it will be dropped by exception_cleanup
// which is invoked by the C++ runtime.
let mut exception =
ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data: Some(data) });
let mut exception = ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data });
let throw_ptr = (&raw mut exception) as *mut _;
// This... may seems surprising, and justifiably so. On 32-bit MSVC the

View file

@ -5,6 +5,10 @@ name = "sysroot"
version = "0.0.0"
edition = "2024"
[lib]
# make sure this crate isn't included in public standard library docs
doc = false
# this is a dummy crate to ensure that all required crates appear in the sysroot
[dependencies]
proc_macro = { path = "../proc_macro", public = true }

View file

@ -449,26 +449,24 @@ fn copy_self_contained_objects(
target_deps
}
/// Resolves standard library crates for `Std::run_make` for any build kind (like check, build, clippy, etc.).
/// Resolves standard library crates for `Std::run_make` for any build kind (like check, doc,
/// build, clippy, etc.).
pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec<String> {
// FIXME: Extend builder tests to cover the `crates` field of `Std` instances.
if cfg!(test) {
return vec![];
}
let mut crates = run.make_run_crates(builder::Alias::Library);
let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library"));
// For no_std targets, we only want to check core and alloc
// Regardless of core/alloc being selected explicitly or via the "library" default alias,
// we only want to keep these two crates.
// The set of no_std crates should be kept in sync with what `Builder::std_cargo` does.
// Note: an alternative design would be to return an enum from this function (Default vs Subset)
// of crates. However, several steps currently pass `-p <package>` even if all crates are
// selected, because Cargo behaves differently in that case. To keep that behavior without
// making further changes, we pre-filter the no-std crates here.
let target_is_no_std = run.builder.no_std(run.target).unwrap_or(false);
// For no_std targets, do not add any additional crates to the compilation other than what `compile::std_cargo` already adds for no_std targets.
if target_is_no_std {
vec![]
}
// If the paths include "library", build the entire standard library.
else if has_alias {
run.make_run_crates(builder::Alias::Library)
} else {
run.cargo_crates_in_set()
crates.retain(|c| c == "core" || c == "alloc");
}
crates
}
/// Tries to find LLVM's `compiler-rt` source directory, for building `library/profiler_builtins`.

View file

@ -665,7 +665,11 @@ impl Step for Std {
}
fn metadata(&self) -> Option<StepMetadata> {
Some(StepMetadata::doc("std", self.target).stage(self.stage))
Some(
StepMetadata::doc("std", self.target)
.stage(self.stage)
.with_metadata(format!("crates=[{}]", self.crates.join(","))),
)
}
}
@ -739,10 +743,6 @@ fn doc_std(
}
for krate in requested_crates {
if krate == "sysroot" {
// The sysroot crate is an implementation detail, don't include it in public docs.
continue;
}
cargo.arg("-p").arg(krate);
}

View file

@ -146,6 +146,8 @@ pub struct StepMetadata {
target: TargetSelection,
built_by: Option<Compiler>,
stage: Option<u32>,
/// Additional opaque string printed in the metadata
metadata: Option<String>,
}
impl StepMetadata {
@ -170,7 +172,7 @@ impl StepMetadata {
}
fn new(name: &'static str, target: TargetSelection, kind: Kind) -> Self {
Self { name, kind, target, built_by: None, stage: None }
Self { name, kind, target, built_by: None, stage: None, metadata: None }
}
pub fn built_by(mut self, compiler: Compiler) -> Self {
@ -183,6 +185,11 @@ impl StepMetadata {
self
}
pub fn with_metadata(mut self, metadata: String) -> Self {
self.metadata = Some(metadata);
self
}
pub fn get_stage(&self) -> Option<u32> {
self.stage.or(self
.built_by

View file

@ -637,8 +637,8 @@ mod snapshot {
use crate::core::build_steps::{compile, dist, doc, test, tool};
use crate::core::builder::tests::{
TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args, first,
host_target, render_steps, run_build,
RenderConfig, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args,
first, host_target, render_steps, run_build,
};
use crate::core::builder::{Builder, Kind, StepDescription, StepMetadata};
use crate::core::config::TargetSelection;
@ -994,7 +994,7 @@ mod snapshot {
[build] llvm <host>
[build] rustc 0 <host> -> rustc 1 <host>
[build] rustdoc 0 <host>
[doc] std 1 <host>
[doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
");
}
@ -1043,12 +1043,12 @@ mod snapshot {
[build] rustc 1 <host> -> std 1 <host>
[build] rustc 1 <host> -> rustc 2 <host>
[build] rustdoc 1 <host>
[doc] std 2 <host>
[doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[build] rustc 2 <host> -> std 2 <host>
[build] rustc 0 <host> -> LintDocs 1 <host>
[build] rustc 0 <host> -> RustInstaller 1 <host>
[dist] docs <host>
[doc] std 2 <host>
[doc] std 2 <host> crates=[]
[dist] mingw <host>
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
[dist] rustc <host>
@ -1075,12 +1075,12 @@ mod snapshot {
[build] rustc 1 <host> -> rustc 2 <host>
[build] rustc 1 <host> -> WasmComponentLd 2 <host>
[build] rustdoc 1 <host>
[doc] std 2 <host>
[doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[build] rustc 2 <host> -> std 2 <host>
[build] rustc 0 <host> -> LintDocs 1 <host>
[build] rustc 0 <host> -> RustInstaller 1 <host>
[dist] docs <host>
[doc] std 2 <host>
[doc] std 2 <host> crates=[]
[dist] mingw <host>
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
[dist] rustc <host>
@ -1112,15 +1112,15 @@ mod snapshot {
[build] rustc 1 <host> -> std 1 <host>
[build] rustc 1 <host> -> rustc 2 <host>
[build] rustdoc 1 <host>
[doc] std 2 <host>
[doc] std 2 <target1>
[doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[build] rustc 2 <host> -> std 2 <host>
[build] rustc 0 <host> -> LintDocs 1 <host>
[build] rustc 0 <host> -> RustInstaller 1 <host>
[dist] docs <host>
[dist] docs <target1>
[doc] std 2 <host>
[doc] std 2 <target1>
[doc] std 2 <host> crates=[]
[doc] std 2 <target1> crates=[]
[dist] mingw <host>
[dist] mingw <target1>
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
@ -1149,14 +1149,14 @@ mod snapshot {
[build] rustc 1 <host> -> std 1 <host>
[build] rustc 1 <host> -> rustc 2 <host>
[build] rustdoc 1 <host>
[doc] std 2 <host>
[doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[build] rustc 2 <host> -> std 2 <host>
[build] rustc 0 <host> -> LintDocs 1 <host>
[build] rustc 1 <host> -> std 1 <target1>
[build] rustc 2 <host> -> std 2 <target1>
[build] rustc 0 <host> -> RustInstaller 1 <host>
[dist] docs <host>
[doc] std 2 <host>
[doc] std 2 <host> crates=[]
[dist] mingw <host>
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
[dist] rustc <host>
@ -1186,8 +1186,8 @@ mod snapshot {
[build] rustc 1 <host> -> std 1 <host>
[build] rustc 1 <host> -> rustc 2 <host>
[build] rustdoc 1 <host>
[doc] std 2 <host>
[doc] std 2 <target1>
[doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[build] rustc 2 <host> -> std 2 <host>
[build] rustc 0 <host> -> LintDocs 1 <host>
[build] rustc 1 <host> -> std 1 <target1>
@ -1195,8 +1195,8 @@ mod snapshot {
[build] rustc 0 <host> -> RustInstaller 1 <host>
[dist] docs <host>
[dist] docs <target1>
[doc] std 2 <host>
[doc] std 2 <target1>
[doc] std 2 <host> crates=[]
[doc] std 2 <target1> crates=[]
[dist] mingw <host>
[dist] mingw <target1>
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
@ -1228,11 +1228,11 @@ mod snapshot {
[build] rustc 1 <host> -> std 1 <host>
[build] rustc 1 <host> -> rustc 2 <host>
[build] rustdoc 1 <host>
[doc] std 2 <target1>
[doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[build] rustc 2 <host> -> std 2 <host>
[build] rustc 0 <host> -> RustInstaller 1 <host>
[dist] docs <target1>
[doc] std 2 <target1>
[doc] std 2 <target1> crates=[]
[dist] mingw <target1>
[build] rustc 2 <host> -> std 2 <target1>
[dist] rustc 2 <host> -> std 2 <target1>
@ -1260,14 +1260,14 @@ mod snapshot {
[build] rustc 1 <host> -> rustc 2 <host>
[build] rustc 1 <host> -> WasmComponentLd 2 <host>
[build] rustdoc 1 <host>
[doc] std 2 <target1>
[doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
[build] rustc 2 <host> -> std 2 <host>
[build] rustc 1 <host> -> std 1 <target1>
[build] rustc 2 <host> -> std 2 <target1>
[build] rustc 0 <host> -> LintDocs 1 <host>
[build] rustc 0 <host> -> RustInstaller 1 <host>
[dist] docs <target1>
[doc] std 2 <target1>
[doc] std 2 <target1> crates=[]
[dist] mingw <target1>
[build] llvm <target1>
[build] rustc 1 <host> -> rustc 2 <target1>
@ -1575,6 +1575,80 @@ mod snapshot {
steps.assert_contains(StepMetadata::test("CrateLibrustc", host));
steps.assert_contains_fuzzy(StepMetadata::build("rustc", host));
}
#[test]
fn doc_library() {
let ctx = TestCtx::new();
insta::assert_snapshot!(
ctx.config("doc")
.path("library")
.render_steps(), @r"
[build] llvm <host>
[build] rustc 0 <host> -> rustc 1 <host>
[build] rustdoc 0 <host>
[doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
");
}
#[test]
fn doc_core() {
let ctx = TestCtx::new();
insta::assert_snapshot!(
ctx.config("doc")
.path("core")
.render_steps(), @r"
[build] llvm <host>
[build] rustc 0 <host> -> rustc 1 <host>
[build] rustdoc 0 <host>
[doc] std 1 <host> crates=[core]
");
}
#[test]
fn doc_core_no_std_target() {
let ctx = TestCtx::new();
insta::assert_snapshot!(
ctx.config("doc")
.path("core")
.override_target_no_std(&host_target())
.render_steps(), @r"
[build] llvm <host>
[build] rustc 0 <host> -> rustc 1 <host>
[build] rustdoc 0 <host>
[doc] std 1 <host> crates=[core]
");
}
#[test]
fn doc_library_no_std_target() {
let ctx = TestCtx::new();
insta::assert_snapshot!(
ctx.config("doc")
.path("library")
.override_target_no_std(&host_target())
.render_steps(), @r"
[build] llvm <host>
[build] rustc 0 <host> -> rustc 1 <host>
[build] rustdoc 0 <host>
[doc] std 1 <host> crates=[alloc,core]
");
}
#[test]
fn doc_library_no_std_target_cross_compile() {
let ctx = TestCtx::new();
insta::assert_snapshot!(
ctx.config("doc")
.path("library")
.targets(&[TEST_TRIPLE_1])
.override_target_no_std(TEST_TRIPLE_1)
.render_steps(), @r"
[build] llvm <host>
[build] rustc 0 <host> -> rustc 1 <host>
[build] rustdoc 0 <host>
[doc] std 1 <target1> crates=[alloc,core]
");
}
}
struct ExecutedSteps {
@ -1583,7 +1657,11 @@ struct ExecutedSteps {
impl ExecutedSteps {
fn render(&self) -> String {
render_steps(&self.steps)
self.render_with(RenderConfig::default())
}
fn render_with(&self, config: RenderConfig) -> String {
render_steps(&self.steps, config)
}
#[track_caller]
@ -1592,7 +1670,7 @@ impl ExecutedSteps {
if !self.contains(&metadata) {
panic!(
"Metadata `{}` ({metadata:?}) not found in executed steps:\n{}",
render_metadata(&metadata),
render_metadata(&metadata, &RenderConfig::default()),
self.render()
);
}
@ -1607,7 +1685,7 @@ impl ExecutedSteps {
if !self.contains_fuzzy(&metadata) {
panic!(
"Metadata `{}` ({metadata:?}) not found in executed steps:\n{}",
render_metadata(&metadata),
render_metadata(&metadata, &RenderConfig::default()),
self.render()
);
}
@ -1619,7 +1697,7 @@ impl ExecutedSteps {
if self.contains(&metadata) {
panic!(
"Metadata `{}` ({metadata:?}) found in executed steps (it should not be there):\n{}",
render_metadata(&metadata),
render_metadata(&metadata, &RenderConfig::default()),
self.render()
);
}
@ -1641,7 +1719,7 @@ impl ExecutedSteps {
}
fn fuzzy_metadata_eq(executed: &StepMetadata, to_match: &StepMetadata) -> bool {
let StepMetadata { name, kind, target, built_by: _, stage: _ } = executed;
let StepMetadata { name, kind, target, built_by: _, stage: _, metadata } = executed;
*name == to_match.name && *kind == to_match.kind && *target == to_match.target
}
@ -1672,6 +1750,16 @@ impl ConfigBuilder {
}
}
struct RenderConfig {
normalize_host: bool,
}
impl Default for RenderConfig {
fn default() -> Self {
Self { normalize_host: true }
}
}
/// Renders the executed bootstrap steps for usage in snapshot tests with insta.
/// Only renders certain important steps.
/// Each value in `steps` should be a tuple of (Step, step output).
@ -1679,7 +1767,7 @@ impl ConfigBuilder {
/// The arrow in the rendered output (`X -> Y`) means `X builds Y`.
/// This is similar to the output printed by bootstrap to stdout, but here it is
/// generated purely for the purpose of tests.
fn render_steps(steps: &[ExecutedStep]) -> String {
fn render_steps(steps: &[ExecutedStep], config: RenderConfig) -> String {
steps
.iter()
.filter_map(|step| {
@ -1689,32 +1777,35 @@ fn render_steps(steps: &[ExecutedStep]) -> String {
return None;
};
Some(render_metadata(&metadata))
Some(render_metadata(&metadata, &config))
})
.collect::<Vec<_>>()
.join("\n")
}
fn render_metadata(metadata: &StepMetadata) -> String {
fn render_metadata(metadata: &StepMetadata, config: &RenderConfig) -> String {
let mut record = format!("[{}] ", metadata.kind.as_str());
if let Some(compiler) = metadata.built_by {
write!(record, "{} -> ", render_compiler(compiler));
write!(record, "{} -> ", render_compiler(compiler, config));
}
let stage = metadata.get_stage().map(|stage| format!("{stage} ")).unwrap_or_default();
write!(record, "{} {stage}<{}>", metadata.name, normalize_target(metadata.target));
write!(record, "{} {stage}<{}>", metadata.name, normalize_target(metadata.target, config));
if let Some(metadata) = &metadata.metadata {
write!(record, " {metadata}");
}
record
}
fn normalize_target(target: TargetSelection) -> String {
target
.to_string()
.replace(&host_target(), "host")
.replace(TEST_TRIPLE_1, "target1")
.replace(TEST_TRIPLE_2, "target2")
fn normalize_target(target: TargetSelection, config: &RenderConfig) -> String {
let mut target = target.to_string();
if config.normalize_host {
target = target.replace(&host_target(), "host");
}
target.replace(TEST_TRIPLE_1, "target1").replace(TEST_TRIPLE_2, "target2")
}
fn render_compiler(compiler: Compiler) -> String {
format!("rustc {} <{}>", compiler.stage, normalize_target(compiler.host))
fn render_compiler(compiler: Compiler, config: &RenderConfig) -> String {
format!("rustc {} <{}>", compiler.stage, normalize_target(compiler.host, config))
}
fn host_target() -> String {

View file

@ -48,17 +48,30 @@ impl ConfigBuilder {
}
pub fn path(mut self, path: &str) -> Self {
self.args.push(path.to_string());
self
self.arg(path)
}
pub fn paths(mut self, paths: &[&str]) -> Self {
for path in paths {
self = self.path(path);
self.args(paths)
}
pub fn arg(mut self, arg: &str) -> Self {
self.args.push(arg.to_string());
self
}
pub fn args(mut self, args: &[&str]) -> Self {
for arg in args {
self = self.arg(arg);
}
self
}
/// Set the specified target to be treated as a no_std target.
pub fn override_target_no_std(mut self, target: &str) -> Self {
self.args(&["--set", &format!("target.{target}.no-std=true")])
}
pub fn hosts(mut self, targets: &[&str]) -> Self {
self.args.push("--host".to_string());
self.args.push(targets.join(","));
@ -77,13 +90,6 @@ impl ConfigBuilder {
self
}
pub fn args(mut self, args: &[&str]) -> Self {
for arg in args {
self.args.push(arg.to_string());
}
self
}
pub fn create_config(mut self) -> Config {
// Run in dry-check, otherwise the test would be too slow
self.args.push("--dry-run".to_string());

View file

@ -152,8 +152,14 @@ pub(crate) fn try_inline(
};
cx.inlined.insert(did.into());
let mut item =
crate::clean::generate_item_with_correct_attrs(cx, kind, did, name, import_def_id, None);
let mut item = crate::clean::generate_item_with_correct_attrs(
cx,
kind,
did,
name,
import_def_id.as_slice(),
None,
);
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
item.inner.inline_stmt_id = import_def_id;
ret.push(item);

View file

@ -94,12 +94,12 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
// This covers the case where somebody does an import which should pull in an item,
// but there's already an item with the same namespace and same name. Rust gives
// priority to the not-imported one, so we should, too.
items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| {
items.extend(doc.items.values().flat_map(|(item, renamed, import_ids)| {
// First, lower everything other than glob imports.
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
return Vec::new();
}
let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id);
let v = clean_maybe_renamed_item(cx, item, *renamed, import_ids);
for item in &v {
if let Some(name) = item.name
&& (cx.render_options.document_hidden || !item.is_doc_hidden())
@ -162,7 +162,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
kind,
doc.def_id.to_def_id(),
doc.name,
doc.import_id,
doc.import_id.as_slice(),
doc.renamed,
)
}
@ -182,22 +182,29 @@ fn generate_item_with_correct_attrs(
kind: ItemKind,
def_id: DefId,
name: Symbol,
import_id: Option<LocalDefId>,
import_ids: &[LocalDefId],
renamed: Option<Symbol>,
) -> Item {
let target_attrs = inline::load_attrs(cx, def_id);
let attrs = if let Some(import_id) = import_id {
// glob reexports are treated the same as `#[doc(inline)]` items.
//
// For glob re-exports the item may or may not exist to be re-exported (potentially the cfgs
// on the path up until the glob can be removed, and only cfgs on the globbed item itself
// matter), for non-inlined re-exports see #85043.
let is_inline = hir_attr_lists(inline::load_attrs(cx, import_id.to_def_id()), sym::doc)
.get_word_attr(sym::inline)
.is_some()
|| (is_glob_import(cx.tcx, import_id)
&& (cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id)));
let mut attrs = get_all_import_attributes(cx, import_id, def_id, is_inline);
let attrs = if !import_ids.is_empty() {
let mut attrs = Vec::with_capacity(import_ids.len());
let mut is_inline = false;
for import_id in import_ids.iter().copied() {
// glob reexports are treated the same as `#[doc(inline)]` items.
//
// For glob re-exports the item may or may not exist to be re-exported (potentially the
// cfgs on the path up until the glob can be removed, and only cfgs on the globbed item
// itself matter), for non-inlined re-exports see #85043.
let import_is_inline =
hir_attr_lists(inline::load_attrs(cx, import_id.to_def_id()), sym::doc)
.get_word_attr(sym::inline)
.is_some()
|| (is_glob_import(cx.tcx, import_id)
&& (cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id)));
attrs.extend(get_all_import_attributes(cx, import_id, def_id, is_inline));
is_inline = is_inline || import_is_inline;
}
add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None);
attrs
} else {
@ -216,7 +223,8 @@ fn generate_item_with_correct_attrs(
let name = renamed.or(Some(name));
let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, attrs, cfg);
item.inner.inline_stmt_id = import_id;
// FIXME (GuillaumeGomez): Should we also make `inline_stmt_id` a `Vec` instead of an `Option`?
item.inner.inline_stmt_id = import_ids.first().copied();
item
}
@ -2754,7 +2762,7 @@ fn clean_maybe_renamed_item<'tcx>(
cx: &mut DocContext<'tcx>,
item: &hir::Item<'tcx>,
renamed: Option<Symbol>,
import_id: Option<LocalDefId>,
import_ids: &[LocalDefId],
) -> Vec<Item> {
use hir::ItemKind;
fn get_name(
@ -2825,7 +2833,7 @@ fn clean_maybe_renamed_item<'tcx>(
})),
item.owner_id.def_id.to_def_id(),
name,
import_id,
import_ids,
renamed,
));
return ret;
@ -2880,7 +2888,7 @@ fn clean_maybe_renamed_item<'tcx>(
kind,
item.owner_id.def_id.to_def_id(),
name,
import_id,
import_ids,
renamed,
)]
})
@ -3151,7 +3159,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
kind,
item.owner_id.def_id.to_def_id(),
item.ident.name,
import_id,
import_id.as_slice(),
renamed,
)
})

View file

@ -32,11 +32,29 @@ pub(crate) struct Module<'hir> {
pub(crate) def_id: LocalDefId,
pub(crate) renamed: Option<Symbol>,
pub(crate) import_id: Option<LocalDefId>,
/// The key is the item `ItemId` and the value is: (item, renamed, import_id).
/// The key is the item `ItemId` and the value is: (item, renamed, Vec<import_id>).
/// We use `FxIndexMap` to keep the insert order.
///
/// `import_id` needs to be a `Vec` because we live in a dark world where you can have code
/// like:
///
/// ```
/// mod raw {
/// pub fn foo() {}
/// }
///
/// /// Foobar
/// pub use raw::foo;
///
/// pub use raw::*;
/// ```
///
/// So in this case, we don't want to have two items but just one with attributes from all
/// non-glob imports to be merged. Glob imports attributes are always ignored, whether they're
/// shadowed or not.
pub(crate) items: FxIndexMap<
(LocalDefId, Option<Symbol>),
(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>),
(&'hir hir::Item<'hir>, Option<Symbol>, Vec<LocalDefId>),
>,
/// (def_id, renamed) -> (res, local_import_id)
@ -154,7 +172,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
{
let item = self.cx.tcx.hir_expect_item(local_def_id);
let (ident, _, _) = item.expect_macro();
top_level_module.items.insert((local_def_id, Some(ident.name)), (item, None, None));
top_level_module
.items
.insert((local_def_id, Some(ident.name)), (item, None, Vec::new()));
}
}
@ -236,7 +256,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
) -> bool {
debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}");
let glob = renamed.is_none();
if renamed == Some(kw::Underscore) {
// We never inline `_` reexports.
return false;
@ -261,6 +280,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
return false;
}
let is_glob = renamed.is_none();
let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did);
let Some(res_did) = ori_res_did.as_local() else {
// For cross-crate impl inlining we need to know whether items are
@ -268,7 +288,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// made reachable by cross-crate inlining which we're checking here.
// (this is done here because we need to know this upfront).
crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did);
if is_hidden || glob {
if is_hidden || is_glob {
return false;
}
// We store inlined foreign items otherwise, it'd mean that the `use` item would be kept
@ -316,10 +336,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// Bang macros are handled a bit on their because of how they are handled by the
// compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
// `#[doc(inline)]`, then we don't inline it.
Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => {
Node::Item(_) if is_bang_macro && !please_inline && !is_glob && is_hidden => {
return false;
}
Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_, m), .. }) if glob => {
Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_, m), .. }) if is_glob => {
let prev = mem::replace(&mut self.inlining, true);
for &i in m.item_ids {
let i = tcx.hir_item(i);
@ -328,13 +348,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.inlining = prev;
true
}
Node::Item(it) if !glob => {
Node::Item(it) if !is_glob => {
let prev = mem::replace(&mut self.inlining, true);
self.visit_item_inner(it, renamed, Some(def_id));
self.inlining = prev;
true
}
Node::ForeignItem(it) if !glob => {
Node::ForeignItem(it) if !is_glob => {
let prev = mem::replace(&mut self.inlining, true);
self.visit_foreign_item_inner(it, renamed, Some(def_id));
self.inlining = prev;
@ -378,8 +398,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
fn add_to_current_mod(
&mut self,
item: &'tcx hir::Item<'_>,
renamed: Option<Symbol>,
parent_id: Option<LocalDefId>,
mut renamed: Option<Symbol>,
import_id: Option<LocalDefId>,
) {
if self.is_importable_from_parent
// If we're inside an item, only impl blocks and `macro_rules!` with the `macro_export`
@ -392,11 +412,21 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
_ => false,
}
{
self.modules
.last_mut()
.unwrap()
.items
.insert((item.owner_id.def_id, renamed), (item, renamed, parent_id));
if renamed == item.kind.ident().map(|ident| ident.name) {
renamed = None;
}
let key = (item.owner_id.def_id, renamed);
if let Some(import_id) = import_id {
self.modules
.last_mut()
.unwrap()
.items
.entry(key)
.and_modify(|v| v.2.push(import_id))
.or_insert_with(|| (item, renamed, vec![import_id]));
} else {
self.modules.last_mut().unwrap().items.insert(key, (item, renamed, Vec::new()));
}
}
}
@ -468,7 +498,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
_ => false,
});
let ident = match kind {
hir::UseKind::Single(ident) => Some(renamed.unwrap_or(ident.name)),
hir::UseKind::Single(ident) => Some(ident.name),
hir::UseKind::Glob => None,
hir::UseKind::ListStem => unreachable!(),
};

View file

@ -0,0 +1,75 @@
//@ assembly-output: emit-asm
//@ revisions: att intel
//@ [att] compile-flags: -Cllvm-args=-x86-asm-syntax=att
//@ [intel] compile-flags: -Cllvm-args=-x86-asm-syntax=intel
//@ only-x86_64
#![crate_type = "lib"]
// CHECK-LABEL: naked_att:
// intel-CHECK: mov rax, qword ptr [rdi]
// intel-CHECK: ret
// att-CHECK: movq (%rdi), %rax
// att-CHECK: retq
#[unsafe(naked)]
#[unsafe(no_mangle)]
extern "sysv64" fn naked_att() {
std::arch::naked_asm!(
"
movq (%rdi), %rax
retq
",
options(att_syntax),
);
}
// CHECK-LABEL: naked_intel:
// intel-CHECK: mov rax, rdi
// intel-CHECK: ret
// att-CHECK: movq (%rdi), %rax
// att-CHECK: retq
#[unsafe(naked)]
#[unsafe(no_mangle)]
extern "sysv64" fn naked_intel() {
std::arch::naked_asm!(
"
mov rax, rdi
ret
",
options(),
);
}
// CHECK-LABEL: global_att:
// intel-CHECK: mov rax, rdi
// intel-CHECK: ret
// att-CHECK: movq (%rdi), %rax
// att-CHECK: retq
core::arch::global_asm!(
"
.globl global_att
global_att:
movq (%rdi), %rax
retq
",
options(att_syntax),
);
// CHECK-LABEL: global_intel:
// intel-CHECK: mov rax, rdi
// intel-CHECK: ret
// att-CHECK: movq (%rdi), %rax
// att-CHECK: retq
core::arch::global_asm!(
"
.globl global_intel
global_intel:
mov rax, rdi
ret
",
options(),
);

View file

@ -0,0 +1,19 @@
#![no_std]
// Without `--document-hidden-items`,
// none of these items are present in rustdoc JSON.
//@ !has "$.index[?(@.name=='func')]"
#[doc(hidden)]
pub fn func() {}
//@ !has "$.index[?(@.name=='Unit')]"
#[doc(hidden)]
pub struct Unit;
//@ !has "$.index[?(@.name=='hidden')]"
#[doc(hidden)]
pub mod hidden {
//@ !has "$.index[?(@.name=='Inner')]"
pub struct Inner;
}

View file

@ -0,0 +1,17 @@
//@ compile-flags: --document-hidden-items
#![no_std]
//@ is "$.index[?(@.name=='func')].attrs" '["#[doc(hidden)]"]'
#[doc(hidden)]
pub fn func() {}
//@ is "$.index[?(@.name=='Unit')].attrs" '["#[doc(hidden)]"]'
#[doc(hidden)]
pub struct Unit;
//@ is "$.index[?(@.name=='hidden')].attrs" '["#[doc(hidden)]"]'
#[doc(hidden)]
pub mod hidden {
//@ is "$.index[?(@.name=='Inner')].attrs" '[]'
pub struct Inner;
}

View file

@ -0,0 +1,41 @@
// This test ensures that if an item is inlined from two different `use`,
// then it will use attributes from both of them.
// This is a regression test for <https://github.com/rust-lang/rust/issues/143107>.
#![feature(no_core)]
#![no_core]
#![no_std]
#![crate_name = "foo"]
// First we ensure we only have two items.
//@ has 'foo/index.html'
//@ count - '//dl[@class="item-table"]/dt' 2
// We should also only have one section (Structs).
//@ count - '//h2[@class="section-header"]' 1
// We now check the short docs.
//@ has - '//dl[@class="item-table"]/dd' 'Foobar Blob'
//@ has - '//dl[@class="item-table"]/dd' 'Tarte Tatin'
//@ has 'foo/struct.Foo.html'
//@ has - '//*[@class="docblock"]' 'Foobar Blob'
//@ has 'foo/struct.Another.html'
//@ has - '//*[@class="docblock"]' 'Tarte Tatin'
mod raw {
/// Blob
pub struct Foo;
/// Tatin
pub struct Another;
}
/// Foobar
pub use raw::Foo;
// Glob reexport attributes are ignored.
/// Baz
pub use raw::*;
/// Tarte
pub use raw::Another as Another;

View file

@ -4,151 +4,6 @@ error[E0635]: unknown feature `const_fn_trait_ref_impls`
LL | #![feature(const_fn_trait_ref_impls)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:14:8
|
LL | T: [const] Fn<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:14:8
|
LL | T: [const] Fn<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:14:8
|
LL | T: [const] Fn<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:21:8
|
LL | T: [const] FnMut<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `FnMut`
|
note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:21:8
|
LL | T: [const] FnMut<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `FnMut`
|
note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:21:8
|
LL | T: [const] FnMut<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `FnMut`
|
note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:28:8
|
LL | T: [const] FnOnce<()>,
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:28:8
|
LL | T: [const] FnOnce<()>,
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:28:8
|
LL | T: [const] FnOnce<()>,
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:35:8
|
LL | T: [const] Fn<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:35:8
|
LL | T: [const] Fn<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:35:8
|
LL | T: [const] Fn<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:49:8
|
LL | T: [const] FnMut<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `FnMut`
|
note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:49:8
|
LL | T: [const] FnMut<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `FnMut`
|
note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:49:8
|
LL | T: [const] FnMut<()> + [const] Destruct,
| ^^^^^^^ can't be applied to `FnMut`
|
note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0277]: the trait bound `(i32, i32, i32): const PartialEq` is not satisfied
--> $DIR/fn_trait_refs.rs:71:17
|
@ -161,31 +16,7 @@ error[E0277]: the trait bound `(i32, i32): const PartialEq` is not satisfied
LL | assert!(test_two == (2, 2));
| ^^^^^^^^^^^^^^^^^^
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/fn_trait_refs.rs:16:5
|
LL | f()
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 3 previous errors
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/fn_trait_refs.rs:23:5
|
LL | f()
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/fn_trait_refs.rs:30:5
|
LL | f()
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 21 previous errors
Some errors have detailed explanations: E0015, E0277, E0635.
For more information about an error, try `rustc --explain E0015`.
Some errors have detailed explanations: E0277, E0635.
For more information about an error, try `rustc --explain E0277`.

View file

@ -1,30 +1,3 @@
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/unstable-const-fn-in-libcore.rs:19:32
|
LL | const fn unwrap_or_else<F: [const] FnOnce() -> T>(self, f: F) -> T {
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/unstable-const-fn-in-libcore.rs:19:32
|
LL | const fn unwrap_or_else<F: [const] FnOnce() -> T>(self, f: F) -> T {
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/unstable-const-fn-in-libcore.rs:24:26
|
LL | Opt::None => f(),
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0493]: destructor of `F` cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:19:61
|
@ -43,7 +16,6 @@ LL | const fn unwrap_or_else<F: [const] FnOnce() -> T>(self, f: F) -> T {
LL | }
| - value is dropped here
error: aborting due to 5 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0015, E0493.
For more information about an error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0493`.

View file

@ -1,22 +1,3 @@
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/normalize-tait-in-const.rs:27:35
|
LL | const fn with_positive<F: for<'a> [const] Fn(&'a Alias<'a>) + [const] Destruct>(fun: F) {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/normalize-tait-in-const.rs:27:35
|
LL | const fn with_positive<F: for<'a> [const] Fn(&'a Alias<'a>) + [const] Destruct>(fun: F) {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: unconstrained opaque type
--> $DIR/normalize-tait-in-const.rs:14:26
|
@ -44,15 +25,6 @@ note: this item must have a `#[define_opaque(foo::Alias)]` attribute to be able
LL | pub const fn filter_positive<'a>() -> &'a Alias<'a> {
| ^^^^^^^^^^^^^^^
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/normalize-tait-in-const.rs:28:5
|
LL | fun(filter_positive());
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 2 previous errors
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0015, E0308.
For more information about an error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0308`.

View file

@ -5,13 +5,10 @@ use std::intrinsics::const_eval_select;
const fn not_fn_items() {
const_eval_select((), || {}, || {});
//~^ ERROR this argument must be a function item
//~| ERROR this argument must be a function item
//~^ ERROR const FnOnce()` is not satisfied
const_eval_select((), 42, 0xDEADBEEF);
//~^ ERROR expected a `FnOnce()` closure
//~| ERROR expected a `FnOnce()` closure
//~| ERROR this argument must be a function item
//~| ERROR this argument must be a function item
}
const fn foo(n: i32) -> i32 {
@ -40,7 +37,7 @@ const fn args_ty_mismatch() {
const fn non_const_fn() {
const_eval_select((1,), bar, bar);
//~^ ERROR this argument must be a `const fn`
//~^ ERROR the trait bound `fn(i32) -> bool {bar}: const FnOnce(i32)` is not satisfied
}
fn main() {}

View file

@ -1,23 +1,16 @@
error: this argument must be a function item
error[E0277]: the trait bound `{closure@$DIR/const-eval-select-bad.rs:7:27: 7:29}: const FnOnce()` is not satisfied
--> $DIR/const-eval-select-bad.rs:7:27
|
LL | const_eval_select((), || {}, || {});
| ^^^^^
| ----------------- ^^^^^
| |
| required by a bound introduced by this call
|
= note: expected a function item, found {closure@$DIR/const-eval-select-bad.rs:7:27: 7:29}
= help: consult the documentation on `const_eval_select` for more information
error: this argument must be a function item
--> $DIR/const-eval-select-bad.rs:7:34
|
LL | const_eval_select((), || {}, || {});
| ^^^^^
|
= note: expected a function item, found {closure@$DIR/const-eval-select-bad.rs:7:34: 7:36}
= help: consult the documentation on `const_eval_select` for more information
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
error[E0277]: expected a `FnOnce()` closure, found `{integer}`
--> $DIR/const-eval-select-bad.rs:10:27
--> $DIR/const-eval-select-bad.rs:9:27
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ----------------- ^^ expected an `FnOnce()` closure, found `{integer}`
@ -30,7 +23,7 @@ note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
error[E0277]: expected a `FnOnce()` closure, found `{integer}`
--> $DIR/const-eval-select-bad.rs:10:31
--> $DIR/const-eval-select-bad.rs:9:31
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ----------------- ^^^^^^^^^^ expected an `FnOnce()` closure, found `{integer}`
@ -42,26 +35,8 @@ LL | const_eval_select((), 42, 0xDEADBEEF);
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
error: this argument must be a function item
--> $DIR/const-eval-select-bad.rs:10:27
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ^^
|
= note: expected a function item, found {integer}
= help: consult the documentation on `const_eval_select` for more information
error: this argument must be a function item
--> $DIR/const-eval-select-bad.rs:10:31
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ^^^^^^^^^^
|
= note: expected a function item, found {integer}
= help: consult the documentation on `const_eval_select` for more information
error[E0271]: expected `bar` to return `i32`, but it returns `bool`
--> $DIR/const-eval-select-bad.rs:32:34
--> $DIR/const-eval-select-bad.rs:29:34
|
LL | const_eval_select((1,), foo, bar);
| ----------------- ^^^ expected `i32`, found `bool`
@ -72,7 +47,7 @@ note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
error[E0631]: type mismatch in function arguments
--> $DIR/const-eval-select-bad.rs:37:32
--> $DIR/const-eval-select-bad.rs:34:32
|
LL | const fn foo(n: i32) -> i32 {
| --------------------------- found signature defined here
@ -91,15 +66,18 @@ help: consider wrapping the function in a closure
LL | const_eval_select((true,), |arg0: bool| foo(/* i32 */), baz);
| ++++++++++++ +++++++++++
error: this argument must be a `const fn`
--> $DIR/const-eval-select-bad.rs:42:29
error[E0277]: the trait bound `fn(i32) -> bool {bar}: const FnOnce(i32)` is not satisfied
--> $DIR/const-eval-select-bad.rs:39:29
|
LL | const_eval_select((1,), bar, bar);
| ^^^
| ----------------- ^^^
| |
| required by a bound introduced by this call
|
= help: consult the documentation on `const_eval_select` for more information
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
error: aborting due to 9 previous errors
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0271, E0277, E0631.
For more information about an error, try `rustc --explain E0271`.

View file

@ -0,0 +1,30 @@
//@ run-pass
//@ only-linux
//@ only-gnu
//@ compile-flags: -Zexport-executable-symbols
//@ edition: 2024
// Regression test for <https://github.com/rust-lang/rust/issues/101610>.
#![feature(rustc_private)]
extern crate libc;
#[unsafe(no_mangle)]
fn hack() -> u64 {
998244353
}
fn main() {
unsafe {
let handle = libc::dlopen(std::ptr::null(), libc::RTLD_NOW);
let ptr = libc::dlsym(handle, c"hack".as_ptr());
let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr);
if let Some(f) = ptr {
assert!(f() == 998244353);
println!("symbol `hack` is found successfully");
} else {
panic!("symbol `hack` is not found");
}
}
}

View file

@ -5,7 +5,7 @@
pub const _: () = {
assert!((const || true)());
//~^ ERROR cannot call non-const closure in constants
//~^ ERROR }: [const] Fn()` is not satisfied
};
fn main() {}

View file

@ -1,12 +1,9 @@
error[E0015]: cannot call non-const closure in constants
error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] Fn()` is not satisfied
--> $DIR/call.rs:7:13
|
LL | assert!((const || true)());
| ^^^^^^^^^^^^^^^^^
|
= note: closures need an RFC before allowed to be called in constants
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,31 +1,9 @@
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closure-parse-not-item.rs:7:25
error[E0277]: the trait bound `{closure@$DIR/const-closure-parse-not-item.rs:8:5: 8:18}: [const] Fn()` is not satisfied
--> $DIR/const-closure-parse-not-item.rs:7:20
|
LL | const fn test() -> impl [const] Fn() {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
| ^^^^^^^^^^^^^^^^^
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closure-parse-not-item.rs:7:25
|
LL | const fn test() -> impl [const] Fn() {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closure-parse-not-item.rs:7:25
|
LL | const fn test() -> impl [const] Fn() {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 3 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,30 +1,9 @@
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closure-trait-method-fail.rs:14:32
error[E0277]: the trait bound `(): const Tr` is not satisfied
--> $DIR/const-closure-trait-method-fail.rs:18:23
|
LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
LL | const _: () = assert!(need_const_closure(Tr::a) == 42);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closure-trait-method-fail.rs:14:32
|
LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 1 previous error
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/const-closure-trait-method-fail.rs:15:5
|
LL | x(())
| ^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,5 +1,6 @@
//@ known-bug: #110395
// FIXME check-pass
//@ check-pass
//@ revisions: next old
//@[next] compile-flags: -Znext-solver
#![feature(const_trait_impl)]
#[const_trait]

View file

@ -1,30 +0,0 @@
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closure-trait-method.rs:14:32
|
LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closure-trait-method.rs:14:32
|
LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/const-closure-trait-method.rs:15:5
|
LL | x(())
| ^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0015`.

View file

@ -1,5 +1,6 @@
//@ known-bug: #110395
// FIXME check-pass
//@ check-pass
//@ revisions: next old
//@[next] compile-flags: -Znext-solver
#![feature(const_trait_impl)]

View file

@ -1,103 +0,0 @@
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closures.rs:8:12
|
LL | F: [const] FnOnce() -> u8,
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closures.rs:9:12
|
LL | F: [const] FnMut() -> u8,
| ^^^^^^^ can't be applied to `FnMut`
|
note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closures.rs:10:12
|
LL | F: [const] Fn() -> u8,
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closures.rs:8:12
|
LL | F: [const] FnOnce() -> u8,
| ^^^^^^^ can't be applied to `FnOnce`
|
note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closures.rs:9:12
|
LL | F: [const] FnMut() -> u8,
| ^^^^^^^ can't be applied to `FnMut`
|
note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closures.rs:10:12
|
LL | F: [const] Fn() -> u8,
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closures.rs:23:20
|
LL | const fn answer<F: [const] Fn() -> u8>(f: &F) -> u8 {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/const-closures.rs:23:20
|
LL | const fn answer<F: [const] Fn() -> u8>(f: &F) -> u8 {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/const-closures.rs:24:5
|
LL | f() + f()
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/const-closures.rs:24:11
|
LL | f() + f()
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/const-closures.rs:12:5
|
LL | f() * 7
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 11 previous errors
For more information about this error, try `rustc --explain E0015`.

View file

@ -1,3 +1,4 @@
//@ known-bug: #110395
//@ compile-flags: -Znext-solver
#![feature(const_closures, const_trait_impl)]
#![allow(incomplete_features)]
@ -11,7 +12,7 @@ impl Foo for () {
}
fn main() {
(const || { (()).foo() })();
//~^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions
(const || (()).foo())();
// ^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions
// FIXME(const_trait_impl) this should probably say constant closures
}

View file

@ -1,11 +1,9 @@
error[E0015]: cannot call non-const method `<() as Foo>::foo` in constant functions
--> $DIR/const_closure-const_trait_impl-ice-113381.rs:14:22
error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice-113381.rs:15:6: 15:14}: [const] Fn()` is not satisfied
--> $DIR/const_closure-const_trait_impl-ice-113381.rs:15:5
|
LL | (const || { (()).foo() })();
| ^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
LL | (const || (()).foo())();
| ^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,16 +1,14 @@
#![feature(const_trait_impl)]
const fn test() -> impl [const] Fn() {
//~^ ERROR `[const]` can only be applied to `#[const_trait]` traits
//~| ERROR `[const]` can only be applied to `#[const_trait]` traits
//~| ERROR `[const]` can only be applied to `#[const_trait]` traits
//~^ ERROR: }: [const] Fn()` is not satisfied
const move || { //~ ERROR const closures are experimental
let sl: &[u8] = b"foo";
match sl {
[first, remainder @ ..] => {
assert_eq!(first, &b'f');
//~^ ERROR cannot call non-const function
// FIXME(const_closures) ^ ERROR cannot call non-const function
}
[] => panic!(),
}

View file

@ -1,5 +1,5 @@
error[E0658]: const closures are experimental
--> $DIR/ice-112822-expected-type-for-param.rs:7:5
--> $DIR/ice-112822-expected-type-for-param.rs:5:5
|
LL | const move || {
| ^^^^^
@ -8,45 +8,13 @@ LL | const move || {
= help: add `#![feature(const_closures)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
error[E0277]: the trait bound `{closure@$DIR/ice-112822-expected-type-for-param.rs:5:5: 5:18}: [const] Fn()` is not satisfied
--> $DIR/ice-112822-expected-type-for-param.rs:3:20
|
LL | const fn test() -> impl [const] Fn() {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
| ^^^^^^^^^^^^^^^^^
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
|
LL | const fn test() -> impl [const] Fn() {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
|
LL | const fn test() -> impl [const] Fn() {
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0015]: cannot call non-const function `core::panicking::assert_failed::<&u8, &u8>` in constant functions
--> $DIR/ice-112822-expected-type-for-param.rs:12:17
|
LL | assert_eq!(first, &b'f');
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0015, E0658.
For more information about an error, try `rustc --explain E0015`.
Some errors have detailed explanations: E0277, E0658.
For more information about an error, try `rustc --explain E0277`.

View file

@ -1,8 +0,0 @@
#![allow(incomplete_features)]
#![feature(generic_const_exprs, const_trait_impl)]
const fn with_positive<F: [const] Fn()>() {}
//~^ ERROR `[const]` can only be applied to `#[const_trait]` traits
//~| ERROR `[const]` can only be applied to `#[const_trait]` traits
pub fn main() {}

View file

@ -1,21 +0,0 @@
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/ice-123664-unexpected-bound-var.rs:4:27
|
LL | const fn with_positive<F: [const] Fn()>() {}
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
error: `[const]` can only be applied to `#[const_trait]` traits
--> $DIR/ice-123664-unexpected-bound-var.rs:4:27
|
LL | const fn with_positive<F: [const] Fn()>() {}
| ^^^^^^^ can't be applied to `Fn`
|
note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors

View file

@ -11,5 +11,5 @@ impl Foo for () {
fn main() {
(const || { (()).foo() })();
//~^ ERROR: cannot call non-const method
//~^ ERROR: }: [const] Fn()` is not satisfied
}

View file

@ -1,11 +1,9 @@
error[E0015]: cannot call non-const method `<() as Foo>::foo` in constant functions
--> $DIR/non-const-op-const-closure-non-const-outer.rs:13:22
error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:13:6: 13:14}: [const] Fn()` is not satisfied
--> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5
|
LL | (const || { (()).foo() })();
| ^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0277`.