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:
commit
2a023bf80a
47 changed files with 647 additions and 766 deletions
|
|
@ -384,15 +384,19 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
|
||||||
) {
|
) {
|
||||||
let asm_arch = self.tcx.sess.asm_arch.unwrap();
|
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
|
// Build the template string
|
||||||
let mut template_str = String::new();
|
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 {
|
for piece in template {
|
||||||
match *piece {
|
match *piece {
|
||||||
InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s),
|
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");
|
template_str.push_str("\n.att_syntax\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1980,12 +1980,12 @@ unsafe extern "C" {
|
||||||
pub(crate) fn LLVMRustBuildMinNum<'a>(
|
pub(crate) fn LLVMRustBuildMinNum<'a>(
|
||||||
B: &Builder<'a>,
|
B: &Builder<'a>,
|
||||||
LHS: &'a Value,
|
LHS: &'a Value,
|
||||||
LHS: &'a Value,
|
RHS: &'a Value,
|
||||||
) -> &'a Value;
|
) -> &'a Value;
|
||||||
pub(crate) fn LLVMRustBuildMaxNum<'a>(
|
pub(crate) fn LLVMRustBuildMaxNum<'a>(
|
||||||
B: &Builder<'a>,
|
B: &Builder<'a>,
|
||||||
LHS: &'a Value,
|
LHS: &'a Value,
|
||||||
LHS: &'a Value,
|
RHS: &'a Value,
|
||||||
) -> &'a Value;
|
) -> &'a Value;
|
||||||
|
|
||||||
// Atomic Operations
|
// Atomic Operations
|
||||||
|
|
|
||||||
|
|
@ -800,9 +800,7 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_windows = self.sess.target.is_like_windows;
|
let path = tmpdir.join(if self.sess.target.is_like_windows { "list.def" } else { "list" });
|
||||||
let path = tmpdir.join(if is_windows { "list.def" } else { "list" });
|
|
||||||
|
|
||||||
debug!("EXPORTED SYMBOLS:");
|
debug!("EXPORTED SYMBOLS:");
|
||||||
|
|
||||||
if self.sess.target.is_like_darwin {
|
if self.sess.target.is_like_darwin {
|
||||||
|
|
@ -817,7 +815,8 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
if let Err(error) = res {
|
if let Err(error) = res {
|
||||||
self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error });
|
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 res: io::Result<()> = try {
|
||||||
let mut f = File::create_buffered(&path)?;
|
let mut f = File::create_buffered(&path)?;
|
||||||
|
|
||||||
|
|
@ -835,6 +834,21 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
if let Err(error) = res {
|
if let Err(error) = res {
|
||||||
self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error });
|
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 {
|
} else {
|
||||||
// Write an LD version script
|
// Write an LD version script
|
||||||
let res: io::Result<()> = try {
|
let res: io::Result<()> = try {
|
||||||
|
|
@ -852,18 +866,13 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
if let Err(error) = res {
|
if let Err(error) = res {
|
||||||
self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
|
self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
|
||||||
}
|
}
|
||||||
}
|
if self.sess.target.is_like_solaris {
|
||||||
|
self.link_arg("-M").link_arg(path);
|
||||||
if self.sess.target.is_like_darwin {
|
} else {
|
||||||
self.link_arg("-exported_symbols_list").link_arg(path);
|
let mut arg = OsString::from("--version-script=");
|
||||||
} else if self.sess.target.is_like_solaris {
|
arg.push(path);
|
||||||
self.link_arg("-M").link_arg(path);
|
self.link_arg(arg).link_arg("--no-undefined-version");
|
||||||
} 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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,6 @@ hir_typeck_cast_unknown_pointer = cannot cast {$to ->
|
||||||
hir_typeck_const_continue_bad_label =
|
hir_typeck_const_continue_bad_label =
|
||||||
`#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
|
`#[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 =
|
hir_typeck_continue_labeled_block =
|
||||||
`continue` pointing to a labeled block
|
`continue` pointing to a labeled block
|
||||||
.label = labeled blocks cannot be `continue`'d
|
.label = labeled blocks cannot be `continue`'d
|
||||||
|
|
|
||||||
|
|
@ -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()
|
fn_sig.output()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_typeck_union_pat_multiple_fields)]
|
#[diag(hir_typeck_union_pat_multiple_fields)]
|
||||||
pub(crate) struct UnionPatMultipleFields {
|
pub(crate) struct UnionPatMultipleFields {
|
||||||
|
|
|
||||||
|
|
@ -529,7 +529,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// process any deferred resolutions.
|
// process any deferred resolutions.
|
||||||
let deferred_call_resolutions = self.remove_deferred_call_resolutions(closure_def_id);
|
let deferred_call_resolutions = self.remove_deferred_call_resolutions(closure_def_id);
|
||||||
for deferred_call_resolution in deferred_call_resolutions {
|
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,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use rustc_hir::{self as hir, LangItem};
|
use rustc_hir::{self as hir, LangItem};
|
||||||
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
|
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
|
||||||
use rustc_infer::traits::{
|
use rustc_infer::traits::{
|
||||||
ImplDerivedHostCause, ImplSource, Obligation, ObligationCauseCode, PredicateObligation,
|
ImplDerivedHostCause, ImplSource, Obligation, ObligationCause, ObligationCauseCode,
|
||||||
|
PredicateObligation,
|
||||||
};
|
};
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
|
|
@ -303,6 +304,9 @@ fn evaluate_host_effect_from_builtin_impls<'tcx>(
|
||||||
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
|
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
|
||||||
match selcx.tcx().as_lang_item(obligation.predicate.def_id()) {
|
match selcx.tcx().as_lang_item(obligation.predicate.def_id()) {
|
||||||
Some(LangItem::Destruct) => evaluate_host_effect_for_destruct_goal(selcx, obligation),
|
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),
|
_ => Err(EvaluationFailure::NoSolution),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -398,6 +402,51 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
|
||||||
.collect())
|
.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>(
|
fn evaluate_host_effect_from_selection_candidate<'tcx>(
|
||||||
selcx: &mut SelectionContext<'_, 'tcx>,
|
selcx: &mut SelectionContext<'_, 'tcx>,
|
||||||
obligation: &HostEffectObligation<'tcx>,
|
obligation: &HostEffectObligation<'tcx>,
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ links = "compiler-rt"
|
||||||
bench = false
|
bench = false
|
||||||
doctest = false
|
doctest = false
|
||||||
test = false
|
test = false
|
||||||
|
# make sure this crate isn't included in public standard library docs
|
||||||
|
doc = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
core = { path = "../../core", optional = true }
|
core = { path = "../../core", optional = true }
|
||||||
|
|
|
||||||
|
|
@ -2279,7 +2279,7 @@ pub const fn const_eval_select<ARG: Tuple, F, G, RET>(
|
||||||
) -> RET
|
) -> RET
|
||||||
where
|
where
|
||||||
G: FnOnce<ARG, Output = RET>,
|
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:
|
/// A macro to make it easier to invoke const_eval_select. Use as follows:
|
||||||
/// ```rust,ignore (just a macro example)
|
/// ```rust,ignore (just a macro example)
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,8 @@ use crate::marker::Tuple;
|
||||||
)]
|
)]
|
||||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||||
#[must_use = "closures are lazy and do nothing unless called"]
|
#[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> {
|
pub trait Fn<Args: Tuple>: FnMut<Args> {
|
||||||
/// Performs the call operation.
|
/// Performs the call operation.
|
||||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
#[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`
|
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||||
#[must_use = "closures are lazy and do nothing unless called"]
|
#[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> {
|
pub trait FnMut<Args: Tuple>: FnOnce<Args> {
|
||||||
/// Performs the call operation.
|
/// Performs the call operation.
|
||||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
#[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`
|
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||||
#[must_use = "closures are lazy and do nothing unless called"]
|
#[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> {
|
pub trait FnOnce<Args: Tuple> {
|
||||||
/// The returned type after the call operator is used.
|
/// The returned type after the call operator is used.
|
||||||
#[lang = "fn_once_output"]
|
#[lang = "fn_once_output"]
|
||||||
|
|
@ -254,9 +257,10 @@ mod impls {
|
||||||
use crate::marker::Tuple;
|
use crate::marker::Tuple;
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[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
|
where
|
||||||
F: Fn<A>,
|
F: ~const Fn<A>,
|
||||||
{
|
{
|
||||||
extern "rust-call" fn call(&self, args: A) -> F::Output {
|
extern "rust-call" fn call(&self, args: A) -> F::Output {
|
||||||
(**self).call(args)
|
(**self).call(args)
|
||||||
|
|
@ -264,9 +268,10 @@ mod impls {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[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
|
where
|
||||||
F: Fn<A>,
|
F: ~const Fn<A>,
|
||||||
{
|
{
|
||||||
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
|
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
|
||||||
(**self).call(args)
|
(**self).call(args)
|
||||||
|
|
@ -274,9 +279,10 @@ mod impls {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[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
|
where
|
||||||
F: Fn<A>,
|
F: ~const Fn<A>,
|
||||||
{
|
{
|
||||||
type Output = F::Output;
|
type Output = F::Output;
|
||||||
|
|
||||||
|
|
@ -286,9 +292,10 @@ mod impls {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[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
|
where
|
||||||
F: FnMut<A>,
|
F: ~const FnMut<A>,
|
||||||
{
|
{
|
||||||
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
|
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
|
||||||
(*self).call_mut(args)
|
(*self).call_mut(args)
|
||||||
|
|
@ -296,9 +303,10 @@ mod impls {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[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
|
where
|
||||||
F: FnMut<A>,
|
F: ~const FnMut<A>,
|
||||||
{
|
{
|
||||||
type Output = F::Output;
|
type Output = F::Output;
|
||||||
extern "rust-call" fn call_once(self, args: A) -> F::Output {
|
extern "rust-call" fn call_once(self, args: A) -> F::Output {
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ struct Exception {
|
||||||
// and its destructor is executed by the C++ runtime. When we take the Box
|
// 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
|
// out of the exception, we need to leave the exception in a valid state
|
||||||
// for its destructor to run without double-dropping the Box.
|
// 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>>,
|
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
|
// 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
|
// 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
|
// 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 {
|
macro_rules! define_cleanup {
|
||||||
($abi:tt $abi2:tt) => {
|
($abi:tt $abi2:tt) => {
|
||||||
unsafe extern $abi fn exception_cleanup(e: *mut Exception) {
|
unsafe extern $abi fn exception_cleanup(e: *mut Exception) {
|
||||||
|
|
@ -278,7 +283,9 @@ macro_rules! define_cleanup {
|
||||||
unsafe extern $abi2 fn exception_copy(
|
unsafe extern $abi2 fn exception_copy(
|
||||||
_dest: *mut Exception, _src: *mut Exception
|
_dest: *mut Exception, _src: *mut Exception
|
||||||
) -> *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 {
|
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};
|
use core::intrinsics::{AtomicOrdering, atomic_store};
|
||||||
|
|
||||||
// _CxxThrowException executes entirely on this stack frame, so there's no
|
// _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
|
// The ManuallyDrop is needed here since we don't want Exception to be
|
||||||
// dropped when unwinding. Instead it will be dropped by exception_cleanup
|
// dropped when unwinding. Instead it will be dropped by exception_cleanup
|
||||||
// which is invoked by the C++ runtime.
|
// which is invoked by the C++ runtime.
|
||||||
let mut exception =
|
let mut exception = ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data });
|
||||||
ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data: Some(data) });
|
|
||||||
let throw_ptr = (&raw mut exception) as *mut _;
|
let throw_ptr = (&raw mut exception) as *mut _;
|
||||||
|
|
||||||
// This... may seems surprising, and justifiably so. On 32-bit MSVC the
|
// This... may seems surprising, and justifiably so. On 32-bit MSVC the
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ name = "sysroot"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
edition = "2024"
|
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
|
# this is a dummy crate to ensure that all required crates appear in the sysroot
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc_macro = { path = "../proc_macro", public = true }
|
proc_macro = { path = "../proc_macro", public = true }
|
||||||
|
|
|
||||||
|
|
@ -449,26 +449,24 @@ fn copy_self_contained_objects(
|
||||||
target_deps
|
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> {
|
pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec<String> {
|
||||||
// FIXME: Extend builder tests to cover the `crates` field of `Std` instances.
|
let mut crates = run.make_run_crates(builder::Alias::Library);
|
||||||
if cfg!(test) {
|
|
||||||
return vec![];
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
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 {
|
if target_is_no_std {
|
||||||
vec![]
|
crates.retain(|c| c == "core" || c == "alloc");
|
||||||
}
|
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to find LLVM's `compiler-rt` source directory, for building `library/profiler_builtins`.
|
/// Tries to find LLVM's `compiler-rt` source directory, for building `library/profiler_builtins`.
|
||||||
|
|
|
||||||
|
|
@ -665,7 +665,11 @@ impl Step for Std {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Option<StepMetadata> {
|
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 {
|
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);
|
cargo.arg("-p").arg(krate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,8 @@ pub struct StepMetadata {
|
||||||
target: TargetSelection,
|
target: TargetSelection,
|
||||||
built_by: Option<Compiler>,
|
built_by: Option<Compiler>,
|
||||||
stage: Option<u32>,
|
stage: Option<u32>,
|
||||||
|
/// Additional opaque string printed in the metadata
|
||||||
|
metadata: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StepMetadata {
|
impl StepMetadata {
|
||||||
|
|
@ -170,7 +172,7 @@ impl StepMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(name: &'static str, target: TargetSelection, kind: Kind) -> Self {
|
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 {
|
pub fn built_by(mut self, compiler: Compiler) -> Self {
|
||||||
|
|
@ -183,6 +185,11 @@ impl StepMetadata {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_metadata(mut self, metadata: String) -> Self {
|
||||||
|
self.metadata = Some(metadata);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_stage(&self) -> Option<u32> {
|
pub fn get_stage(&self) -> Option<u32> {
|
||||||
self.stage.or(self
|
self.stage.or(self
|
||||||
.built_by
|
.built_by
|
||||||
|
|
|
||||||
|
|
@ -637,8 +637,8 @@ mod snapshot {
|
||||||
|
|
||||||
use crate::core::build_steps::{compile, dist, doc, test, tool};
|
use crate::core::build_steps::{compile, dist, doc, test, tool};
|
||||||
use crate::core::builder::tests::{
|
use crate::core::builder::tests::{
|
||||||
TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args, first,
|
RenderConfig, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args,
|
||||||
host_target, render_steps, run_build,
|
first, host_target, render_steps, run_build,
|
||||||
};
|
};
|
||||||
use crate::core::builder::{Builder, Kind, StepDescription, StepMetadata};
|
use crate::core::builder::{Builder, Kind, StepDescription, StepMetadata};
|
||||||
use crate::core::config::TargetSelection;
|
use crate::core::config::TargetSelection;
|
||||||
|
|
@ -994,7 +994,7 @@ mod snapshot {
|
||||||
[build] llvm <host>
|
[build] llvm <host>
|
||||||
[build] rustc 0 <host> -> rustc 1 <host>
|
[build] rustc 0 <host> -> rustc 1 <host>
|
||||||
[build] rustdoc 0 <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> -> std 1 <host>
|
||||||
[build] rustc 1 <host> -> rustc 2 <host>
|
[build] rustc 1 <host> -> rustc 2 <host>
|
||||||
[build] rustdoc 1 <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 2 <host> -> std 2 <host>
|
||||||
[build] rustc 0 <host> -> LintDocs 1 <host>
|
[build] rustc 0 <host> -> LintDocs 1 <host>
|
||||||
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
||||||
[dist] docs <host>
|
[dist] docs <host>
|
||||||
[doc] std 2 <host>
|
[doc] std 2 <host> crates=[]
|
||||||
[dist] mingw <host>
|
[dist] mingw <host>
|
||||||
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
||||||
[dist] rustc <host>
|
[dist] rustc <host>
|
||||||
|
|
@ -1075,12 +1075,12 @@ mod snapshot {
|
||||||
[build] rustc 1 <host> -> rustc 2 <host>
|
[build] rustc 1 <host> -> rustc 2 <host>
|
||||||
[build] rustc 1 <host> -> WasmComponentLd 2 <host>
|
[build] rustc 1 <host> -> WasmComponentLd 2 <host>
|
||||||
[build] rustdoc 1 <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 2 <host> -> std 2 <host>
|
||||||
[build] rustc 0 <host> -> LintDocs 1 <host>
|
[build] rustc 0 <host> -> LintDocs 1 <host>
|
||||||
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
||||||
[dist] docs <host>
|
[dist] docs <host>
|
||||||
[doc] std 2 <host>
|
[doc] std 2 <host> crates=[]
|
||||||
[dist] mingw <host>
|
[dist] mingw <host>
|
||||||
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
||||||
[dist] rustc <host>
|
[dist] rustc <host>
|
||||||
|
|
@ -1112,15 +1112,15 @@ mod snapshot {
|
||||||
[build] rustc 1 <host> -> std 1 <host>
|
[build] rustc 1 <host> -> std 1 <host>
|
||||||
[build] rustc 1 <host> -> rustc 2 <host>
|
[build] rustc 1 <host> -> rustc 2 <host>
|
||||||
[build] rustdoc 1 <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]
|
||||||
[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 2 <host> -> std 2 <host>
|
||||||
[build] rustc 0 <host> -> LintDocs 1 <host>
|
[build] rustc 0 <host> -> LintDocs 1 <host>
|
||||||
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
||||||
[dist] docs <host>
|
[dist] docs <host>
|
||||||
[dist] docs <target1>
|
[dist] docs <target1>
|
||||||
[doc] std 2 <host>
|
[doc] std 2 <host> crates=[]
|
||||||
[doc] std 2 <target1>
|
[doc] std 2 <target1> crates=[]
|
||||||
[dist] mingw <host>
|
[dist] mingw <host>
|
||||||
[dist] mingw <target1>
|
[dist] mingw <target1>
|
||||||
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
||||||
|
|
@ -1149,14 +1149,14 @@ mod snapshot {
|
||||||
[build] rustc 1 <host> -> std 1 <host>
|
[build] rustc 1 <host> -> std 1 <host>
|
||||||
[build] rustc 1 <host> -> rustc 2 <host>
|
[build] rustc 1 <host> -> rustc 2 <host>
|
||||||
[build] rustdoc 1 <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 2 <host> -> std 2 <host>
|
||||||
[build] rustc 0 <host> -> LintDocs 1 <host>
|
[build] rustc 0 <host> -> LintDocs 1 <host>
|
||||||
[build] rustc 1 <host> -> std 1 <target1>
|
[build] rustc 1 <host> -> std 1 <target1>
|
||||||
[build] rustc 2 <host> -> std 2 <target1>
|
[build] rustc 2 <host> -> std 2 <target1>
|
||||||
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
||||||
[dist] docs <host>
|
[dist] docs <host>
|
||||||
[doc] std 2 <host>
|
[doc] std 2 <host> crates=[]
|
||||||
[dist] mingw <host>
|
[dist] mingw <host>
|
||||||
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
||||||
[dist] rustc <host>
|
[dist] rustc <host>
|
||||||
|
|
@ -1186,8 +1186,8 @@ mod snapshot {
|
||||||
[build] rustc 1 <host> -> std 1 <host>
|
[build] rustc 1 <host> -> std 1 <host>
|
||||||
[build] rustc 1 <host> -> rustc 2 <host>
|
[build] rustc 1 <host> -> rustc 2 <host>
|
||||||
[build] rustdoc 1 <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]
|
||||||
[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 2 <host> -> std 2 <host>
|
||||||
[build] rustc 0 <host> -> LintDocs 1 <host>
|
[build] rustc 0 <host> -> LintDocs 1 <host>
|
||||||
[build] rustc 1 <host> -> std 1 <target1>
|
[build] rustc 1 <host> -> std 1 <target1>
|
||||||
|
|
@ -1195,8 +1195,8 @@ mod snapshot {
|
||||||
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
||||||
[dist] docs <host>
|
[dist] docs <host>
|
||||||
[dist] docs <target1>
|
[dist] docs <target1>
|
||||||
[doc] std 2 <host>
|
[doc] std 2 <host> crates=[]
|
||||||
[doc] std 2 <target1>
|
[doc] std 2 <target1> crates=[]
|
||||||
[dist] mingw <host>
|
[dist] mingw <host>
|
||||||
[dist] mingw <target1>
|
[dist] mingw <target1>
|
||||||
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
[build] rustc 0 <host> -> GenerateCopyright 1 <host>
|
||||||
|
|
@ -1228,11 +1228,11 @@ mod snapshot {
|
||||||
[build] rustc 1 <host> -> std 1 <host>
|
[build] rustc 1 <host> -> std 1 <host>
|
||||||
[build] rustc 1 <host> -> rustc 2 <host>
|
[build] rustc 1 <host> -> rustc 2 <host>
|
||||||
[build] rustdoc 1 <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 2 <host> -> std 2 <host>
|
||||||
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
||||||
[dist] docs <target1>
|
[dist] docs <target1>
|
||||||
[doc] std 2 <target1>
|
[doc] std 2 <target1> crates=[]
|
||||||
[dist] mingw <target1>
|
[dist] mingw <target1>
|
||||||
[build] rustc 2 <host> -> std 2 <target1>
|
[build] rustc 2 <host> -> std 2 <target1>
|
||||||
[dist] 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> -> rustc 2 <host>
|
||||||
[build] rustc 1 <host> -> WasmComponentLd 2 <host>
|
[build] rustc 1 <host> -> WasmComponentLd 2 <host>
|
||||||
[build] rustdoc 1 <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 2 <host> -> std 2 <host>
|
||||||
[build] rustc 1 <host> -> std 1 <target1>
|
[build] rustc 1 <host> -> std 1 <target1>
|
||||||
[build] rustc 2 <host> -> std 2 <target1>
|
[build] rustc 2 <host> -> std 2 <target1>
|
||||||
[build] rustc 0 <host> -> LintDocs 1 <host>
|
[build] rustc 0 <host> -> LintDocs 1 <host>
|
||||||
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
[build] rustc 0 <host> -> RustInstaller 1 <host>
|
||||||
[dist] docs <target1>
|
[dist] docs <target1>
|
||||||
[doc] std 2 <target1>
|
[doc] std 2 <target1> crates=[]
|
||||||
[dist] mingw <target1>
|
[dist] mingw <target1>
|
||||||
[build] llvm <target1>
|
[build] llvm <target1>
|
||||||
[build] rustc 1 <host> -> rustc 2 <target1>
|
[build] rustc 1 <host> -> rustc 2 <target1>
|
||||||
|
|
@ -1575,6 +1575,80 @@ mod snapshot {
|
||||||
steps.assert_contains(StepMetadata::test("CrateLibrustc", host));
|
steps.assert_contains(StepMetadata::test("CrateLibrustc", host));
|
||||||
steps.assert_contains_fuzzy(StepMetadata::build("rustc", 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 {
|
struct ExecutedSteps {
|
||||||
|
|
@ -1583,7 +1657,11 @@ struct ExecutedSteps {
|
||||||
|
|
||||||
impl ExecutedSteps {
|
impl ExecutedSteps {
|
||||||
fn render(&self) -> String {
|
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]
|
#[track_caller]
|
||||||
|
|
@ -1592,7 +1670,7 @@ impl ExecutedSteps {
|
||||||
if !self.contains(&metadata) {
|
if !self.contains(&metadata) {
|
||||||
panic!(
|
panic!(
|
||||||
"Metadata `{}` ({metadata:?}) not found in executed steps:\n{}",
|
"Metadata `{}` ({metadata:?}) not found in executed steps:\n{}",
|
||||||
render_metadata(&metadata),
|
render_metadata(&metadata, &RenderConfig::default()),
|
||||||
self.render()
|
self.render()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1607,7 +1685,7 @@ impl ExecutedSteps {
|
||||||
if !self.contains_fuzzy(&metadata) {
|
if !self.contains_fuzzy(&metadata) {
|
||||||
panic!(
|
panic!(
|
||||||
"Metadata `{}` ({metadata:?}) not found in executed steps:\n{}",
|
"Metadata `{}` ({metadata:?}) not found in executed steps:\n{}",
|
||||||
render_metadata(&metadata),
|
render_metadata(&metadata, &RenderConfig::default()),
|
||||||
self.render()
|
self.render()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1619,7 +1697,7 @@ impl ExecutedSteps {
|
||||||
if self.contains(&metadata) {
|
if self.contains(&metadata) {
|
||||||
panic!(
|
panic!(
|
||||||
"Metadata `{}` ({metadata:?}) found in executed steps (it should not be there):\n{}",
|
"Metadata `{}` ({metadata:?}) found in executed steps (it should not be there):\n{}",
|
||||||
render_metadata(&metadata),
|
render_metadata(&metadata, &RenderConfig::default()),
|
||||||
self.render()
|
self.render()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1641,7 +1719,7 @@ impl ExecutedSteps {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fuzzy_metadata_eq(executed: &StepMetadata, to_match: &StepMetadata) -> bool {
|
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
|
*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.
|
/// Renders the executed bootstrap steps for usage in snapshot tests with insta.
|
||||||
/// Only renders certain important steps.
|
/// Only renders certain important steps.
|
||||||
/// Each value in `steps` should be a tuple of (Step, step output).
|
/// 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`.
|
/// 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
|
/// This is similar to the output printed by bootstrap to stdout, but here it is
|
||||||
/// generated purely for the purpose of tests.
|
/// generated purely for the purpose of tests.
|
||||||
fn render_steps(steps: &[ExecutedStep]) -> String {
|
fn render_steps(steps: &[ExecutedStep], config: RenderConfig) -> String {
|
||||||
steps
|
steps
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|step| {
|
.filter_map(|step| {
|
||||||
|
|
@ -1689,32 +1777,35 @@ fn render_steps(steps: &[ExecutedStep]) -> String {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(render_metadata(&metadata))
|
Some(render_metadata(&metadata, &config))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("\n")
|
.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_metadata(metadata: &StepMetadata) -> String {
|
fn render_metadata(metadata: &StepMetadata, config: &RenderConfig) -> String {
|
||||||
let mut record = format!("[{}] ", metadata.kind.as_str());
|
let mut record = format!("[{}] ", metadata.kind.as_str());
|
||||||
if let Some(compiler) = metadata.built_by {
|
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();
|
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
|
record
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normalize_target(target: TargetSelection) -> String {
|
fn normalize_target(target: TargetSelection, config: &RenderConfig) -> String {
|
||||||
target
|
let mut target = target.to_string();
|
||||||
.to_string()
|
if config.normalize_host {
|
||||||
.replace(&host_target(), "host")
|
target = target.replace(&host_target(), "host");
|
||||||
.replace(TEST_TRIPLE_1, "target1")
|
}
|
||||||
.replace(TEST_TRIPLE_2, "target2")
|
target.replace(TEST_TRIPLE_1, "target1").replace(TEST_TRIPLE_2, "target2")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_compiler(compiler: Compiler) -> String {
|
fn render_compiler(compiler: Compiler, config: &RenderConfig) -> String {
|
||||||
format!("rustc {} <{}>", compiler.stage, normalize_target(compiler.host))
|
format!("rustc {} <{}>", compiler.stage, normalize_target(compiler.host, config))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn host_target() -> String {
|
fn host_target() -> String {
|
||||||
|
|
|
||||||
|
|
@ -48,17 +48,30 @@ impl ConfigBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path(mut self, path: &str) -> Self {
|
pub fn path(mut self, path: &str) -> Self {
|
||||||
self.args.push(path.to_string());
|
self.arg(path)
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paths(mut self, paths: &[&str]) -> Self {
|
pub fn paths(mut self, paths: &[&str]) -> Self {
|
||||||
for path in paths {
|
self.args(paths)
|
||||||
self = self.path(path);
|
}
|
||||||
|
|
||||||
|
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
|
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 {
|
pub fn hosts(mut self, targets: &[&str]) -> Self {
|
||||||
self.args.push("--host".to_string());
|
self.args.push("--host".to_string());
|
||||||
self.args.push(targets.join(","));
|
self.args.push(targets.join(","));
|
||||||
|
|
@ -77,13 +90,6 @@ impl ConfigBuilder {
|
||||||
self
|
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 {
|
pub fn create_config(mut self) -> Config {
|
||||||
// Run in dry-check, otherwise the test would be too slow
|
// Run in dry-check, otherwise the test would be too slow
|
||||||
self.args.push("--dry-run".to_string());
|
self.args.push("--dry-run".to_string());
|
||||||
|
|
|
||||||
|
|
@ -152,8 +152,14 @@ pub(crate) fn try_inline(
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.inlined.insert(did.into());
|
cx.inlined.insert(did.into());
|
||||||
let mut item =
|
let mut item = crate::clean::generate_item_with_correct_attrs(
|
||||||
crate::clean::generate_item_with_correct_attrs(cx, kind, did, name, import_def_id, None);
|
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.
|
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
|
||||||
item.inner.inline_stmt_id = import_def_id;
|
item.inner.inline_stmt_id = import_def_id;
|
||||||
ret.push(item);
|
ret.push(item);
|
||||||
|
|
|
||||||
|
|
@ -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,
|
// 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
|
// 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.
|
// 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.
|
// First, lower everything other than glob imports.
|
||||||
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
|
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
|
||||||
return Vec::new();
|
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 {
|
for item in &v {
|
||||||
if let Some(name) = item.name
|
if let Some(name) = item.name
|
||||||
&& (cx.render_options.document_hidden || !item.is_doc_hidden())
|
&& (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,
|
kind,
|
||||||
doc.def_id.to_def_id(),
|
doc.def_id.to_def_id(),
|
||||||
doc.name,
|
doc.name,
|
||||||
doc.import_id,
|
doc.import_id.as_slice(),
|
||||||
doc.renamed,
|
doc.renamed,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -182,22 +182,29 @@ fn generate_item_with_correct_attrs(
|
||||||
kind: ItemKind,
|
kind: ItemKind,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
name: Symbol,
|
name: Symbol,
|
||||||
import_id: Option<LocalDefId>,
|
import_ids: &[LocalDefId],
|
||||||
renamed: Option<Symbol>,
|
renamed: Option<Symbol>,
|
||||||
) -> Item {
|
) -> Item {
|
||||||
let target_attrs = inline::load_attrs(cx, def_id);
|
let target_attrs = inline::load_attrs(cx, def_id);
|
||||||
let attrs = if let Some(import_id) = import_id {
|
let attrs = if !import_ids.is_empty() {
|
||||||
// glob reexports are treated the same as `#[doc(inline)]` items.
|
let mut attrs = Vec::with_capacity(import_ids.len());
|
||||||
//
|
let mut is_inline = false;
|
||||||
// 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
|
for import_id in import_ids.iter().copied() {
|
||||||
// matter), for non-inlined re-exports see #85043.
|
// glob reexports are treated the same as `#[doc(inline)]` items.
|
||||||
let is_inline = hir_attr_lists(inline::load_attrs(cx, import_id.to_def_id()), sym::doc)
|
//
|
||||||
.get_word_attr(sym::inline)
|
// For glob re-exports the item may or may not exist to be re-exported (potentially the
|
||||||
.is_some()
|
// cfgs on the path up until the glob can be removed, and only cfgs on the globbed item
|
||||||
|| (is_glob_import(cx.tcx, import_id)
|
// itself matter), for non-inlined re-exports see #85043.
|
||||||
&& (cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id)));
|
let import_is_inline =
|
||||||
let mut attrs = get_all_import_attributes(cx, import_id, def_id, 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);
|
add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None);
|
||||||
attrs
|
attrs
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -216,7 +223,8 @@ fn generate_item_with_correct_attrs(
|
||||||
|
|
||||||
let name = renamed.or(Some(name));
|
let name = renamed.or(Some(name));
|
||||||
let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, attrs, cfg);
|
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
|
item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2754,7 +2762,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
item: &hir::Item<'tcx>,
|
item: &hir::Item<'tcx>,
|
||||||
renamed: Option<Symbol>,
|
renamed: Option<Symbol>,
|
||||||
import_id: Option<LocalDefId>,
|
import_ids: &[LocalDefId],
|
||||||
) -> Vec<Item> {
|
) -> Vec<Item> {
|
||||||
use hir::ItemKind;
|
use hir::ItemKind;
|
||||||
fn get_name(
|
fn get_name(
|
||||||
|
|
@ -2825,7 +2833,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
||||||
})),
|
})),
|
||||||
item.owner_id.def_id.to_def_id(),
|
item.owner_id.def_id.to_def_id(),
|
||||||
name,
|
name,
|
||||||
import_id,
|
import_ids,
|
||||||
renamed,
|
renamed,
|
||||||
));
|
));
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -2880,7 +2888,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
||||||
kind,
|
kind,
|
||||||
item.owner_id.def_id.to_def_id(),
|
item.owner_id.def_id.to_def_id(),
|
||||||
name,
|
name,
|
||||||
import_id,
|
import_ids,
|
||||||
renamed,
|
renamed,
|
||||||
)]
|
)]
|
||||||
})
|
})
|
||||||
|
|
@ -3151,7 +3159,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
|
||||||
kind,
|
kind,
|
||||||
item.owner_id.def_id.to_def_id(),
|
item.owner_id.def_id.to_def_id(),
|
||||||
item.ident.name,
|
item.ident.name,
|
||||||
import_id,
|
import_id.as_slice(),
|
||||||
renamed,
|
renamed,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,29 @@ pub(crate) struct Module<'hir> {
|
||||||
pub(crate) def_id: LocalDefId,
|
pub(crate) def_id: LocalDefId,
|
||||||
pub(crate) renamed: Option<Symbol>,
|
pub(crate) renamed: Option<Symbol>,
|
||||||
pub(crate) import_id: Option<LocalDefId>,
|
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.
|
/// 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<
|
pub(crate) items: FxIndexMap<
|
||||||
(LocalDefId, Option<Symbol>),
|
(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)
|
/// (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 item = self.cx.tcx.hir_expect_item(local_def_id);
|
||||||
let (ident, _, _) = item.expect_macro();
|
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 {
|
) -> bool {
|
||||||
debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}");
|
debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}");
|
||||||
|
|
||||||
let glob = renamed.is_none();
|
|
||||||
if renamed == Some(kw::Underscore) {
|
if renamed == Some(kw::Underscore) {
|
||||||
// We never inline `_` reexports.
|
// We never inline `_` reexports.
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -261,6 +280,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let is_glob = renamed.is_none();
|
||||||
let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did);
|
let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did);
|
||||||
let Some(res_did) = ori_res_did.as_local() else {
|
let Some(res_did) = ori_res_did.as_local() else {
|
||||||
// For cross-crate impl inlining we need to know whether items are
|
// 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.
|
// made reachable by cross-crate inlining which we're checking here.
|
||||||
// (this is done here because we need to know this upfront).
|
// (this is done here because we need to know this upfront).
|
||||||
crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did);
|
crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did);
|
||||||
if is_hidden || glob {
|
if is_hidden || is_glob {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// We store inlined foreign items otherwise, it'd mean that the `use` item would be kept
|
// 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
|
// 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
|
// compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
|
||||||
// `#[doc(inline)]`, then we don't inline it.
|
// `#[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;
|
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);
|
let prev = mem::replace(&mut self.inlining, true);
|
||||||
for &i in m.item_ids {
|
for &i in m.item_ids {
|
||||||
let i = tcx.hir_item(i);
|
let i = tcx.hir_item(i);
|
||||||
|
|
@ -328,13 +348,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
self.inlining = prev;
|
self.inlining = prev;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Node::Item(it) if !glob => {
|
Node::Item(it) if !is_glob => {
|
||||||
let prev = mem::replace(&mut self.inlining, true);
|
let prev = mem::replace(&mut self.inlining, true);
|
||||||
self.visit_item_inner(it, renamed, Some(def_id));
|
self.visit_item_inner(it, renamed, Some(def_id));
|
||||||
self.inlining = prev;
|
self.inlining = prev;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Node::ForeignItem(it) if !glob => {
|
Node::ForeignItem(it) if !is_glob => {
|
||||||
let prev = mem::replace(&mut self.inlining, true);
|
let prev = mem::replace(&mut self.inlining, true);
|
||||||
self.visit_foreign_item_inner(it, renamed, Some(def_id));
|
self.visit_foreign_item_inner(it, renamed, Some(def_id));
|
||||||
self.inlining = prev;
|
self.inlining = prev;
|
||||||
|
|
@ -378,8 +398,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
fn add_to_current_mod(
|
fn add_to_current_mod(
|
||||||
&mut self,
|
&mut self,
|
||||||
item: &'tcx hir::Item<'_>,
|
item: &'tcx hir::Item<'_>,
|
||||||
renamed: Option<Symbol>,
|
mut renamed: Option<Symbol>,
|
||||||
parent_id: Option<LocalDefId>,
|
import_id: Option<LocalDefId>,
|
||||||
) {
|
) {
|
||||||
if self.is_importable_from_parent
|
if self.is_importable_from_parent
|
||||||
// If we're inside an item, only impl blocks and `macro_rules!` with the `macro_export`
|
// 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,
|
_ => false,
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
self.modules
|
if renamed == item.kind.ident().map(|ident| ident.name) {
|
||||||
.last_mut()
|
renamed = None;
|
||||||
.unwrap()
|
}
|
||||||
.items
|
let key = (item.owner_id.def_id, renamed);
|
||||||
.insert((item.owner_id.def_id, renamed), (item, renamed, parent_id));
|
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,
|
_ => false,
|
||||||
});
|
});
|
||||||
let ident = match kind {
|
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::Glob => None,
|
||||||
hir::UseKind::ListStem => unreachable!(),
|
hir::UseKind::ListStem => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
75
tests/assembly/emit-intel-att-syntax.rs
Normal file
75
tests/assembly/emit-intel-att-syntax.rs
Normal 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(),
|
||||||
|
);
|
||||||
19
tests/rustdoc-json/visibility/doc_hidden_default.rs
Normal file
19
tests/rustdoc-json/visibility/doc_hidden_default.rs
Normal 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;
|
||||||
|
}
|
||||||
17
tests/rustdoc-json/visibility/doc_hidden_documented.rs
Normal file
17
tests/rustdoc-json/visibility/doc_hidden_documented.rs
Normal 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;
|
||||||
|
}
|
||||||
41
tests/rustdoc/reexport/merge-glob-and-non-glob.rs
Normal file
41
tests/rustdoc/reexport/merge-glob-and-non-glob.rs
Normal 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;
|
||||||
|
|
@ -4,151 +4,6 @@ error[E0635]: unknown feature `const_fn_trait_ref_impls`
|
||||||
LL | #![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
|
error[E0277]: the trait bound `(i32, i32, i32): const PartialEq` is not satisfied
|
||||||
--> $DIR/fn_trait_refs.rs:71:17
|
--> $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));
|
LL | assert!(test_two == (2, 2));
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error: aborting due to 3 previous errors
|
||||||
--> $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[E0015]: cannot call non-const closure in constant functions
|
Some errors have detailed explanations: E0277, E0635.
|
||||||
--> $DIR/fn_trait_refs.rs:23:5
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
||||||
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`.
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
error[E0493]: destructor of `F` cannot be evaluated at compile-time
|
||||||
--> $DIR/unstable-const-fn-in-libcore.rs:19:61
|
--> $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 | }
|
LL | }
|
||||||
| - value is dropped here
|
| - 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 this error, try `rustc --explain E0493`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
error: unconstrained opaque type
|
||||||
--> $DIR/normalize-tait-in-const.rs:14:26
|
--> $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> {
|
LL | pub const fn filter_positive<'a>() -> &'a Alias<'a> {
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error: aborting due to 2 previous errors
|
||||||
--> $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 5 previous errors
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0308.
|
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,10 @@ use std::intrinsics::const_eval_select;
|
||||||
|
|
||||||
const fn not_fn_items() {
|
const fn not_fn_items() {
|
||||||
const_eval_select((), || {}, || {});
|
const_eval_select((), || {}, || {});
|
||||||
//~^ ERROR this argument must be a function item
|
//~^ ERROR const FnOnce()` is not satisfied
|
||||||
//~| ERROR this argument must be a function item
|
|
||||||
const_eval_select((), 42, 0xDEADBEEF);
|
const_eval_select((), 42, 0xDEADBEEF);
|
||||||
//~^ ERROR expected a `FnOnce()` closure
|
//~^ ERROR expected a `FnOnce()` closure
|
||||||
//~| 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 {
|
const fn foo(n: i32) -> i32 {
|
||||||
|
|
@ -40,7 +37,7 @@ const fn args_ty_mismatch() {
|
||||||
|
|
||||||
const fn non_const_fn() {
|
const fn non_const_fn() {
|
||||||
const_eval_select((1,), bar, bar);
|
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() {}
|
fn main() {}
|
||||||
|
|
|
||||||
|
|
@ -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
|
--> $DIR/const-eval-select-bad.rs:7:27
|
||||||
|
|
|
|
||||||
LL | const_eval_select((), || {}, || {});
|
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}
|
note: required by a bound in `const_eval_select`
|
||||||
= help: consult the documentation on `const_eval_select` for more information
|
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
error[E0277]: expected a `FnOnce()` closure, found `{integer}`
|
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);
|
LL | const_eval_select((), 42, 0xDEADBEEF);
|
||||||
| ----------------- ^^ expected an `FnOnce()` closure, found `{integer}`
|
| ----------------- ^^ 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
|
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||||
|
|
||||||
error[E0277]: expected a `FnOnce()` closure, found `{integer}`
|
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);
|
LL | const_eval_select((), 42, 0xDEADBEEF);
|
||||||
| ----------------- ^^^^^^^^^^ expected an `FnOnce()` closure, found `{integer}`
|
| ----------------- ^^^^^^^^^^ 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`
|
note: required by a bound in `const_eval_select`
|
||||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
--> $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`
|
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);
|
LL | const_eval_select((1,), foo, bar);
|
||||||
| ----------------- ^^^ expected `i32`, found `bool`
|
| ----------------- ^^^ 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
|
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||||
|
|
||||||
error[E0631]: type mismatch in function arguments
|
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 {
|
LL | const fn foo(n: i32) -> i32 {
|
||||||
| --------------------------- found signature defined here
|
| --------------------------- 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);
|
LL | const_eval_select((true,), |arg0: bool| foo(/* i32 */), baz);
|
||||||
| ++++++++++++ +++++++++++
|
| ++++++++++++ +++++++++++
|
||||||
|
|
||||||
error: this argument must be a `const fn`
|
error[E0277]: the trait bound `fn(i32) -> bool {bar}: const FnOnce(i32)` is not satisfied
|
||||||
--> $DIR/const-eval-select-bad.rs:42:29
|
--> $DIR/const-eval-select-bad.rs:39:29
|
||||||
|
|
|
|
||||||
LL | const_eval_select((1,), bar, bar);
|
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.
|
Some errors have detailed explanations: E0271, E0277, E0631.
|
||||||
For more information about an error, try `rustc --explain E0271`.
|
For more information about an error, try `rustc --explain E0271`.
|
||||||
|
|
|
||||||
30
tests/ui/linking/export-executable-symbols.rs
Normal file
30
tests/ui/linking/export-executable-symbols.rs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
pub const _: () = {
|
pub const _: () = {
|
||||||
assert!((const || true)());
|
assert!((const || true)());
|
||||||
//~^ ERROR cannot call non-const closure in constants
|
//~^ ERROR }: [const] Fn()` is not satisfied
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
||||||
|
|
@ -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
|
--> $DIR/call.rs:7:13
|
||||||
|
|
|
|
||||||
LL | assert!((const || true)());
|
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
|
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`.
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,9 @@
|
||||||
error: `[const]` can only be applied to `#[const_trait]` traits
|
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:25
|
--> $DIR/const-closure-parse-not-item.rs:7:20
|
||||||
|
|
|
|
||||||
LL | const fn test() -> impl [const] Fn() {
|
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
|
error: aborting due to 1 previous error
|
||||||
--> $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
|
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,9 @@
|
||||||
error: `[const]` can only be applied to `#[const_trait]` traits
|
error[E0277]: the trait bound `(): const Tr` is not satisfied
|
||||||
--> $DIR/const-closure-trait-method-fail.rs:14:32
|
--> $DIR/const-closure-trait-method-fail.rs:18:23
|
||||||
|
|
|
|
||||||
LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
|
LL | const _: () = assert!(need_const_closure(Tr::a) == 42);
|
||||||
| ^^^^^^^ 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
|
error: aborting due to 1 previous error
|
||||||
--> $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[E0015]: cannot call non-const closure in constant functions
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
--> $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`.
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
//@ known-bug: #110395
|
//@ check-pass
|
||||||
// FIXME check-pass
|
//@ revisions: next old
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
|
|
|
||||||
|
|
@ -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`.
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
//@ known-bug: #110395
|
//@ check-pass
|
||||||
// FIXME check-pass
|
//@ revisions: next old
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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`.
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
//@ known-bug: #110395
|
||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
#![feature(const_closures, const_trait_impl)]
|
#![feature(const_closures, const_trait_impl)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
@ -11,7 +12,7 @@ impl Foo for () {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
(const || { (()).foo() })();
|
(const || (()).foo())();
|
||||||
//~^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions
|
// ^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions
|
||||||
// FIXME(const_trait_impl) this should probably say constant closures
|
// FIXME(const_trait_impl) this should probably say constant closures
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
error[E0015]: cannot call non-const method `<() as Foo>::foo` in constant functions
|
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:14:22
|
--> $DIR/const_closure-const_trait_impl-ice-113381.rs:15:5
|
||||||
|
|
|
|
||||||
LL | (const || { (()).foo() })();
|
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
|
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`.
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
const fn test() -> impl [const] Fn() {
|
const fn test() -> impl [const] Fn() {
|
||||||
//~^ ERROR `[const]` can only be applied to `#[const_trait]` traits
|
//~^ ERROR: }: [const] Fn()` is not satisfied
|
||||||
//~| ERROR `[const]` can only be applied to `#[const_trait]` traits
|
|
||||||
//~| ERROR `[const]` can only be applied to `#[const_trait]` traits
|
|
||||||
const move || { //~ ERROR const closures are experimental
|
const move || { //~ ERROR const closures are experimental
|
||||||
let sl: &[u8] = b"foo";
|
let sl: &[u8] = b"foo";
|
||||||
|
|
||||||
match sl {
|
match sl {
|
||||||
[first, remainder @ ..] => {
|
[first, remainder @ ..] => {
|
||||||
assert_eq!(first, &b'f');
|
assert_eq!(first, &b'f');
|
||||||
//~^ ERROR cannot call non-const function
|
// FIXME(const_closures) ^ ERROR cannot call non-const function
|
||||||
}
|
}
|
||||||
[] => panic!(),
|
[] => panic!(),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0658]: const closures are experimental
|
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 || {
|
LL | const move || {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
@ -8,45 +8,13 @@ LL | const move || {
|
||||||
= help: add `#![feature(const_closures)]` to the crate attributes to enable
|
= 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
|
= 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
|
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:25
|
--> $DIR/ice-112822-expected-type-for-param.rs:3:20
|
||||||
|
|
|
|
||||||
LL | const fn test() -> impl [const] Fn() {
|
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
|
error: aborting due to 2 previous errors
|
||||||
--> $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: `[const]` can only be applied to `#[const_trait]` traits
|
Some errors have detailed explanations: E0277, E0658.
|
||||||
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
||||||
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`.
|
|
||||||
|
|
|
||||||
|
|
@ -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() {}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -11,5 +11,5 @@ impl Foo for () {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
(const || { (()).foo() })();
|
(const || { (()).foo() })();
|
||||||
//~^ ERROR: cannot call non-const method
|
//~^ ERROR: }: [const] Fn()` is not satisfied
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
error[E0015]: cannot call non-const method `<() as Foo>::foo` in constant functions
|
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:22
|
--> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5
|
||||||
|
|
|
|
||||||
LL | (const || { (()).foo() })();
|
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
|
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`.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue